mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 14:39:36 +01:00 
			
		
		
		
	+ Support for ARM CPS/CPSIE/CPSID instructions and mode flag bitfield
operand (patch by Jeppe Johansen, mantis #18334) git-svn-id: trunk@16750 -
This commit is contained in:
		
							parent
							
								
									d76ddcabe6
								
							
						
					
					
						commit
						bbf0e35a51
					
				
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@ -10946,6 +10946,7 @@ tests/webtbs/tw1820.pp svneol=native#text/plain
 | 
				
			|||||||
tests/webtbs/tw18222.pp svneol=native#text/pascal
 | 
					tests/webtbs/tw18222.pp svneol=native#text/pascal
 | 
				
			||||||
tests/webtbs/tw1825.pp svneol=native#text/plain
 | 
					tests/webtbs/tw1825.pp svneol=native#text/plain
 | 
				
			||||||
tests/webtbs/tw18266.pp svneol=native#text/plain
 | 
					tests/webtbs/tw18266.pp svneol=native#text/plain
 | 
				
			||||||
 | 
					tests/webtbs/tw18334.pp svneol=native#text/plain
 | 
				
			||||||
tests/webtbs/tw18443.pp svneol=native#text/pascal
 | 
					tests/webtbs/tw18443.pp svneol=native#text/pascal
 | 
				
			||||||
tests/webtbs/tw1850.pp svneol=native#text/plain
 | 
					tests/webtbs/tw1850.pp svneol=native#text/plain
 | 
				
			||||||
tests/webtbs/tw1851.pp svneol=native#text/plain
 | 
					tests/webtbs/tw1851.pp svneol=native#text/plain
 | 
				
			||||||
 | 
				
			|||||||
@ -179,6 +179,7 @@ interface
 | 
				
			|||||||
       ,top_regset
 | 
					       ,top_regset
 | 
				
			||||||
       ,top_shifterop
 | 
					       ,top_shifterop
 | 
				
			||||||
       ,top_conditioncode
 | 
					       ,top_conditioncode
 | 
				
			||||||
 | 
					       ,top_modeflags
 | 
				
			||||||
{$endif arm}
 | 
					{$endif arm}
 | 
				
			||||||
{$ifdef m68k}
 | 
					{$ifdef m68k}
 | 
				
			||||||
       { m68k only }
 | 
					       { m68k only }
 | 
				
			||||||
@ -214,7 +215,8 @@ interface
 | 
				
			|||||||
      {$ifdef arm}
 | 
					      {$ifdef arm}
 | 
				
			||||||
          top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister);
 | 
					          top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister);
 | 
				
			||||||
          top_shifterop : (shifterop : pshifterop);
 | 
					          top_shifterop : (shifterop : pshifterop);
 | 
				
			||||||
          top_conditioncode: (cc: TAsmCond);
 | 
					          top_conditioncode : (cc : TAsmCond);
 | 
				
			||||||
 | 
					          top_modeflags : (modeflags : tcpumodeflags);
 | 
				
			||||||
      {$endif arm}
 | 
					      {$endif arm}
 | 
				
			||||||
      {$ifdef m68k}
 | 
					      {$ifdef m68k}
 | 
				
			||||||
          top_regset : (regset:^tcpuregisterset);
 | 
					          top_regset : (regset:^tcpuregisterset);
 | 
				
			||||||
 | 
				
			|||||||
@ -163,6 +163,7 @@ uses
 | 
				
			|||||||
         procedure loadshifterop(opidx:longint;const so:tshifterop);
 | 
					         procedure loadshifterop(opidx:longint;const so:tshifterop);
 | 
				
			||||||
         procedure loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset);
 | 
					         procedure loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset);
 | 
				
			||||||
         procedure loadconditioncode(opidx:longint;const cond:tasmcond);
 | 
					         procedure loadconditioncode(opidx:longint;const cond:tasmcond);
 | 
				
			||||||
 | 
					         procedure loadmodeflags(opidx:longint;const flags:tcpumodeflags);
 | 
				
			||||||
         constructor op_none(op : tasmop);
 | 
					         constructor op_none(op : tasmop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
         constructor op_reg(op : tasmop;_op1 : tregister);
 | 
					         constructor op_reg(op : tasmop;_op1 : tregister);
 | 
				
			||||||
@ -187,6 +188,10 @@ uses
 | 
				
			|||||||
         { ITxxx }
 | 
					         { ITxxx }
 | 
				
			||||||
         constructor op_cond(op: tasmop; cond: tasmcond);
 | 
					         constructor op_cond(op: tasmop; cond: tasmcond);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         { CPSxx }
 | 
				
			||||||
 | 
					         constructor op_modeflags(op: tasmop; flags: tcpumodeflags);
 | 
				
			||||||
 | 
					         constructor op_modeflags_const(op: tasmop; flags: tcpumodeflags; a: aint);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
         { *M*LL }
 | 
					         { *M*LL }
 | 
				
			||||||
         constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
 | 
					         constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -328,6 +333,17 @@ implementation
 | 
				
			|||||||
         end;
 | 
					         end;
 | 
				
			||||||
      end;
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    procedure taicpu.loadmodeflags(opidx: longint; const flags: tcpumodeflags);
 | 
				
			||||||
 | 
					      begin
 | 
				
			||||||
 | 
					        allocate_oper(opidx+1);
 | 
				
			||||||
 | 
					        with oper[opidx]^ do
 | 
				
			||||||
 | 
					         begin
 | 
				
			||||||
 | 
					           if typ<>top_modeflags then
 | 
				
			||||||
 | 
					             clearop(opidx);
 | 
				
			||||||
 | 
					           modeflags:=flags;
 | 
				
			||||||
 | 
					           typ:=top_modeflags;
 | 
				
			||||||
 | 
					         end;
 | 
				
			||||||
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{*****************************************************************************
 | 
					{*****************************************************************************
 | 
				
			||||||
                                 taicpu Constructors
 | 
					                                 taicpu Constructors
 | 
				
			||||||
@ -448,6 +464,21 @@ implementation
 | 
				
			|||||||
        condition := cond;
 | 
					        condition := cond;
 | 
				
			||||||
      end;
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor taicpu.op_modeflags(op: tasmop; flags: tcpumodeflags);
 | 
				
			||||||
 | 
					      begin
 | 
				
			||||||
 | 
					        inherited create(op);
 | 
				
			||||||
 | 
					        ops := 1;
 | 
				
			||||||
 | 
					        loadmodeflags(0,flags);
 | 
				
			||||||
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor taicpu.op_modeflags_const(op: tasmop; flags: tcpumodeflags; a: aint);
 | 
				
			||||||
 | 
					      begin
 | 
				
			||||||
 | 
					        inherited create(op);
 | 
				
			||||||
 | 
					        ops := 2;
 | 
				
			||||||
 | 
					        loadmodeflags(0,flags);
 | 
				
			||||||
 | 
					        loadconst(1,a);
 | 
				
			||||||
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
 | 
					     constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
 | 
				
			||||||
       begin
 | 
					       begin
 | 
				
			||||||
 | 
				
			|||||||
@ -204,6 +204,13 @@ unit agarmgas;
 | 
				
			|||||||
            end;
 | 
					            end;
 | 
				
			||||||
          top_conditioncode:
 | 
					          top_conditioncode:
 | 
				
			||||||
            getopstr:=cond2str[o.cc];
 | 
					            getopstr:=cond2str[o.cc];
 | 
				
			||||||
 | 
					          top_modeflags:
 | 
				
			||||||
 | 
					            begin
 | 
				
			||||||
 | 
					              getopstr:='';
 | 
				
			||||||
 | 
					              if mfA in o.modeflags then getopstr:=getopstr+'a';
 | 
				
			||||||
 | 
					              if mfI in o.modeflags then getopstr:=getopstr+'i';
 | 
				
			||||||
 | 
					              if mfF in o.modeflags then getopstr:=getopstr+'f';
 | 
				
			||||||
 | 
					            end;
 | 
				
			||||||
          top_ref:
 | 
					          top_ref:
 | 
				
			||||||
            if o.ref^.refaddr=addr_full then
 | 
					            if o.ref^.refaddr=addr_full then
 | 
				
			||||||
              begin
 | 
					              begin
 | 
				
			||||||
 | 
				
			|||||||
@ -23,6 +23,9 @@
 | 
				
			|||||||
'clz',
 | 
					'clz',
 | 
				
			||||||
'cnf',
 | 
					'cnf',
 | 
				
			||||||
'cos',
 | 
					'cos',
 | 
				
			||||||
 | 
					'cps',
 | 
				
			||||||
 | 
					'cpsid',
 | 
				
			||||||
 | 
					'cpsie',
 | 
				
			||||||
'dvf',
 | 
					'dvf',
 | 
				
			||||||
'eor',
 | 
					'eor',
 | 
				
			||||||
'exp',
 | 
					'exp',
 | 
				
			||||||
 | 
				
			|||||||
@ -199,5 +199,8 @@ attsufNONE,
 | 
				
			|||||||
attsufNONE,
 | 
					attsufNONE,
 | 
				
			||||||
attsufNONE,
 | 
					attsufNONE,
 | 
				
			||||||
attsufNONE,
 | 
					attsufNONE,
 | 
				
			||||||
 | 
					attsufNONE,
 | 
				
			||||||
 | 
					attsufNONE,
 | 
				
			||||||
 | 
					attsufNONE,
 | 
				
			||||||
attsufNONE
 | 
					attsufNONE
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
@ -162,6 +162,10 @@ reg32,reg32              \x27\x01\x01                   ARM7
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[COScc]
 | 
					[COScc]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[CPS]
 | 
				
			||||||
 | 
					[CPSID]
 | 
				
			||||||
 | 
					[CPSIE]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[DVFcc]
 | 
					[DVFcc]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[EORcc]
 | 
					[EORcc]
 | 
				
			||||||
 | 
				
			|||||||
@ -23,6 +23,9 @@ A_CMP,
 | 
				
			|||||||
A_CLZ,
 | 
					A_CLZ,
 | 
				
			||||||
A_CNF,
 | 
					A_CNF,
 | 
				
			||||||
A_COS,
 | 
					A_COS,
 | 
				
			||||||
 | 
					A_CPS,
 | 
				
			||||||
 | 
					A_CPSID,
 | 
				
			||||||
 | 
					A_CPSIE,
 | 
				
			||||||
A_DVF,
 | 
					A_DVF,
 | 
				
			||||||
A_EOR,
 | 
					A_EOR,
 | 
				
			||||||
A_EXP,
 | 
					A_EXP,
 | 
				
			||||||
 | 
				
			|||||||
@ -203,6 +203,9 @@ unit cpubase;
 | 
				
			|||||||
        shiftimm : byte;
 | 
					        shiftimm : byte;
 | 
				
			||||||
      end;
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      tcpumodeflag = (mfA, mfI, mfF);
 | 
				
			||||||
 | 
					      tcpumodeflags = set of tcpumodeflag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{*****************************************************************************
 | 
					{*****************************************************************************
 | 
				
			||||||
                                 Constants
 | 
					                                 Constants
 | 
				
			||||||
*****************************************************************************}
 | 
					*****************************************************************************}
 | 
				
			||||||
 | 
				
			|||||||
@ -672,6 +672,38 @@ Unit raarmgas;
 | 
				
			|||||||
              end;
 | 
					              end;
 | 
				
			||||||
          end;
 | 
					          end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function is_modeflag(hs : string): boolean;
 | 
				
			||||||
 | 
					          var
 | 
				
			||||||
 | 
					            i: longint;
 | 
				
			||||||
 | 
					            flags: tcpumodeflags;
 | 
				
			||||||
 | 
					          begin
 | 
				
			||||||
 | 
					            is_modeflag := false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            flags:=[];
 | 
				
			||||||
 | 
					            hs:=lower(hs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (actopcode in [A_CPSID,A_CPSIE]) and (length(hs) >= 1) then
 | 
				
			||||||
 | 
					              begin
 | 
				
			||||||
 | 
					                for i:=1 to length(hs) do
 | 
				
			||||||
 | 
					                  begin
 | 
				
			||||||
 | 
					                    case hs[i] of
 | 
				
			||||||
 | 
					                      'a':
 | 
				
			||||||
 | 
					                        Include(flags,mfA);
 | 
				
			||||||
 | 
					                      'f':
 | 
				
			||||||
 | 
					                        Include(flags,mfF);
 | 
				
			||||||
 | 
					                      'i':
 | 
				
			||||||
 | 
					                        Include(flags,mfI);
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                      exit;
 | 
				
			||||||
 | 
					                    end;
 | 
				
			||||||
 | 
					                  end;
 | 
				
			||||||
 | 
					                oper.opr.typ := OPR_MODEFLAGS;
 | 
				
			||||||
 | 
					                oper.opr.flags := flags;
 | 
				
			||||||
 | 
					                exit(true);
 | 
				
			||||||
 | 
					              end;
 | 
				
			||||||
 | 
					          end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      var
 | 
					      var
 | 
				
			||||||
        tempreg : tregister;
 | 
					        tempreg : tregister;
 | 
				
			||||||
        ireg : tsuperregister;
 | 
					        ireg : tsuperregister;
 | 
				
			||||||
@ -716,11 +748,16 @@ Unit raarmgas;
 | 
				
			|||||||
          *)
 | 
					          *)
 | 
				
			||||||
          AS_ID: { A constant expression, or a Variable ref.  }
 | 
					          AS_ID: { A constant expression, or a Variable ref.  }
 | 
				
			||||||
            Begin
 | 
					            Begin
 | 
				
			||||||
 | 
					              if is_modeflag(actasmpattern) then
 | 
				
			||||||
 | 
					                begin
 | 
				
			||||||
 | 
					                  consume(AS_ID);
 | 
				
			||||||
 | 
					                end
 | 
				
			||||||
 | 
					              else
 | 
				
			||||||
              { Condition code? }
 | 
					              { Condition code? }
 | 
				
			||||||
              if is_conditioncode(actasmpattern) then
 | 
					              if is_conditioncode(actasmpattern) then
 | 
				
			||||||
              begin
 | 
					                begin
 | 
				
			||||||
                consume(AS_ID);
 | 
					                  consume(AS_ID);
 | 
				
			||||||
              end
 | 
					                end
 | 
				
			||||||
              else
 | 
					              else
 | 
				
			||||||
              { Local Label ? }
 | 
					              { Local Label ? }
 | 
				
			||||||
              if is_locallabel(actasmpattern) then
 | 
					              if is_locallabel(actasmpattern) then
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,7 @@ Function SearchLabel(const s: string; var hl: tasmlabel;emit:boolean): boolean;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type
 | 
					type
 | 
				
			||||||
  TOprType=(OPR_NONE,OPR_CONSTANT,OPR_SYMBOL,OPR_LOCAL,
 | 
					  TOprType=(OPR_NONE,OPR_CONSTANT,OPR_SYMBOL,OPR_LOCAL,
 | 
				
			||||||
            OPR_REFERENCE,OPR_REGISTER,OPR_REGLIST,OPR_COND,OPR_REGSET,OPR_SHIFTEROP);
 | 
					            OPR_REFERENCE,OPR_REGISTER,OPR_REGLIST,OPR_COND,OPR_REGSET,OPR_SHIFTEROP,OPR_MODEFLAGS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TOprRec = record
 | 
					  TOprRec = record
 | 
				
			||||||
    case typ:TOprType of
 | 
					    case typ:TOprType of
 | 
				
			||||||
@ -88,6 +88,7 @@ type
 | 
				
			|||||||
      OPR_REGSET    : (regset : tcpuregisterset; regtype: tregistertype; subreg: tsubregister);
 | 
					      OPR_REGSET    : (regset : tcpuregisterset; regtype: tregistertype; subreg: tsubregister);
 | 
				
			||||||
      OPR_SHIFTEROP : (shifterop : tshifterop);
 | 
					      OPR_SHIFTEROP : (shifterop : tshifterop);
 | 
				
			||||||
      OPR_COND      : (cc : tasmcond);
 | 
					      OPR_COND      : (cc : tasmcond);
 | 
				
			||||||
 | 
					      OPR_MODEFLAGS : (flags : tcpumodeflags);
 | 
				
			||||||
{$endif arm}
 | 
					{$endif arm}
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1067,6 +1068,8 @@ end;
 | 
				
			|||||||
                ai.loadshifterop(i-1,shifterop);
 | 
					                ai.loadshifterop(i-1,shifterop);
 | 
				
			||||||
              OPR_COND:
 | 
					              OPR_COND:
 | 
				
			||||||
                ai.loadconditioncode(i-1,cc);
 | 
					                ai.loadconditioncode(i-1,cc);
 | 
				
			||||||
 | 
					              OPR_MODEFLAGS:
 | 
				
			||||||
 | 
					                ai.loadmodeflags(i-1,flags);
 | 
				
			||||||
{$endif ARM}
 | 
					{$endif ARM}
 | 
				
			||||||
              { ignore wrong operand }
 | 
					              { ignore wrong operand }
 | 
				
			||||||
              OPR_NONE:
 | 
					              OPR_NONE:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								tests/webtbs/tw18334.pp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								tests/webtbs/tw18334.pp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					{ %cpu=arm }
 | 
				
			||||||
 | 
					{ %norun }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure test; assembler;
 | 
				
			||||||
 | 
					  asm
 | 
				
			||||||
 | 
					    cps #0
 | 
				
			||||||
 | 
					    cpsie aif, #0
 | 
				
			||||||
 | 
					    cpsid aif, #0
 | 
				
			||||||
 | 
					    cpsie aif
 | 
				
			||||||
 | 
					    cpsid aif
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					end.
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user