소스 검색

Add missing NOP, and B instruction forms.
Move ThumbFunc flag from section to symbol.
Make .w forms optional the other way around. If .w is explicitly put on an instruction the assembler should always chose a wide form.

git-svn-id: branches/laksen/armiw@29341 -

Jeppe Johansen 10 년 전
부모
커밋
71cdedea82
9개의 변경된 파일107개의 추가작업 그리고 30개의 파일을 삭제
  1. 72 12
      compiler/arm/aasmcpu.pas
  2. 5 2
      compiler/arm/armins.dat
  3. 1 1
      compiler/arm/armnop.inc
  4. 16 2
      compiler/arm/armtab.inc
  5. 1 2
      compiler/arm/cpubase.pas
  6. 9 7
      compiler/ogbase.pas
  7. 1 2
      compiler/ogelf.pas
  8. 1 1
      rtl/arm/arm.inc
  9. 1 1
      rtl/arm/thumb2.inc

+ 72 - 12
compiler/arm/aasmcpu.pas

@@ -93,6 +93,7 @@ uses
       OT_REG64     = $00201008;
       OT_REG64     = $00201008;
       OT_VREG      = $00201010;  { vector register }
       OT_VREG      = $00201010;  { vector register }
       OT_REGF      = $00201020;  { coproc register }
       OT_REGF      = $00201020;  { coproc register }
+      OT_REGS      = $00201040;  { special register with mask }
       OT_MEMORY    = $00204000;  { register number in 'basereg'  }
       OT_MEMORY    = $00204000;  { register number in 'basereg'  }
       OT_MEM8      = $00204001;
       OT_MEM8      = $00204001;
       OT_MEM16     = $00204002;
       OT_MEM16     = $00204002;
@@ -1453,10 +1454,6 @@ implementation
 
 
 
 
     procedure gather_it_info(list: TAsmList);
     procedure gather_it_info(list: TAsmList);
-      const
-        opCount: array[A_IT..A_ITTTT] of longint =
-          (1,2,2,3,3,3,3,
-           4,4,4,4,4,4,4,4);
       var
       var
         curtai: tai;
         curtai: tai;
         in_it: boolean;
         in_it: boolean;
@@ -1479,7 +1476,7 @@ implementation
                         else
                         else
                           begin
                           begin
                             in_it:=true;
                             in_it:=true;
-                            it_count:=opCount[taicpu(curtai).opcode];
+                            it_count:=GetITLevels(taicpu(curtai).opcode);
                           end;
                           end;
                       end;
                       end;
                     else
                     else
@@ -1502,8 +1499,51 @@ implementation
           end;
           end;
       end;
       end;
 
 
+
+    { Expands pseudo instructions ( mov r1,r2,lsl #4 -> lsl r1,r2,#4) }
+    procedure expand_instructions(list: TAsmList);
+      var
+        curtai: tai;
+      begin
+        curtai:=tai(list.First);
+        while assigned(curtai) do
+          begin
+            case curtai.typ of
+              ait_instruction:
+                begin
+                  case taicpu(curtai).opcode of
+                    A_MOV:
+                      begin
+                        if (taicpu(curtai).ops=3) and
+                           (taicpu(curtai).oper[2]^.typ=top_shifterop) then
+                          begin
+                            case taicpu(curtai).oper[2]^.shifterop^.shiftmode of
+                              SM_LSL: taicpu(curtai).opcode:=A_LSL;
+                              SM_LSR: taicpu(curtai).opcode:=A_LSR;
+                              SM_ASR: taicpu(curtai).opcode:=A_ASR;
+                              SM_ROR: taicpu(curtai).opcode:=A_ROR;
+                              SM_RRX: taicpu(curtai).opcode:=A_RRX;
+                            end;
+
+                            if taicpu(curtai).oper[2]^.shifterop^.rs=NR_NO then
+                              taicpu(curtai).loadconst(2, taicpu(curtai).oper[2]^.shifterop^.shiftimm)
+                            else
+                              taicpu(curtai).loadreg(2, taicpu(curtai).oper[2]^.shifterop^.rs);
+                          end;
+                      end;
+                  end;
+                end;
+            end;
+
+            curtai:=tai(curtai.Next);
+          end;
+      end;
+
+
     procedure finalizearmcode(list, listtoinsert: TAsmList);
     procedure finalizearmcode(list, listtoinsert: TAsmList);
       begin
       begin
+        expand_instructions(list);
+
         { Do Thumb-2 16bit -> 32bit transformations }
         { Do Thumb-2 16bit -> 32bit transformations }
         if GenerateThumb2Code then
         if GenerateThumb2Code then
           begin
           begin
@@ -1712,6 +1752,9 @@ implementation
                else
                else
                  if (ot and OT_FPUREG)=OT_FPUREG then
                  if (ot and OT_FPUREG)=OT_FPUREG then
                   s:=s+'fpureg'
                   s:=s+'fpureg'
+               else
+                 if (ot and OT_REGS)=OT_REGS then
+                  s:=s+'sreg'
                else
                else
                  if (ot and OT_REGF)=OT_REGF then
                  if (ot and OT_REGF)=OT_REGF then
                   s:=s+'creg'
                   s:=s+'creg'
@@ -2109,6 +2152,10 @@ implementation
                 begin
                 begin
                   ot:=OT_CONDITION;
                   ot:=OT_CONDITION;
                 end;
                 end;
+              top_specialreg:
+                begin
+                  ot:=OT_REGS;
+                end;
               else
               else
                 begin writeln(typ);
                 begin writeln(typ);
                 internalerror(200402261); end;
                 internalerror(200402261); end;
@@ -2166,10 +2213,10 @@ implementation
           end;
           end;
 
 
         { Check wideformat flag }
         { Check wideformat flag }
-        if ((p^.flags and IF_WIDE)<>0) <> wideformat then
+        if wideformat and ((p^.flags and IF_WIDE)=0) then
           begin
           begin
-            {matches:=0;
-            exit;}
+            matches:=0;
+            exit;
           end;
           end;
 
 
         { Check that no spurious colons or TOs are present }
         { Check that no spurious colons or TOs are present }
@@ -4079,14 +4126,27 @@ implementation
               if oper[0]^.typ=top_const then
               if oper[0]^.typ=top_const then
                 begin
                 begin
                   if insentry^.code[0]=#$63 then
                   if insentry^.code[0]=#$63 then
-                    bytes:=bytes or ((oper[0]^.val shr 1) and $FF)
+                    bytes:=bytes or (((oper[0]^.val shr 1)-1) and $FF)
                   else
                   else
-                    bytes:=bytes or ((oper[0]^.val shr 1) and $3FF);
+                    bytes:=bytes or (((oper[0]^.val shr 1)-1) and $3FF);
                 end
                 end
               else if oper[0]^.typ=top_reg then
               else if oper[0]^.typ=top_reg then
                 begin
                 begin
                   bytes:=bytes or (getsupreg(oper[0]^.reg) shl 3);
                   bytes:=bytes or (getsupreg(oper[0]^.reg) shl 3);
-                end;
+                end
+              else if oper[0]^.typ=top_ref then
+                begin
+                  offset:=0;
+                  currsym:=objdata.symbolref(oper[0]^.ref^.symbol);
+                  if assigned(currsym) then
+                    offset:=currsym.offset-insoffset-8;
+                  offset:=offset+oper[0]^.ref^.offset;
+
+                  if insentry^.code[0]=#$63 then
+                    bytes:=bytes or (((offset+4) shr 1) and $FF)
+                  else
+                    bytes:=bytes or (((offset+4) shr 1) and $7FF);
+                end
             end;
             end;
           #$64: { Thumb: Special encodings }
           #$64: { Thumb: Special encodings }
             begin
             begin
@@ -4171,7 +4231,7 @@ implementation
               else
               else
                 bytes:=bytes or ((oper[1]^.val shr ord(insentry^.code[3])) and $FF);
                 bytes:=bytes or ((oper[1]^.val shr ord(insentry^.code[3])) and $FF);
             end;
             end;
-          #$68: { Thumb CB{N}Z }
+          #$68: { Thumb CB[N]Z }
             begin
             begin
               bytelen:=2;
               bytelen:=2;
               bytes:=0;
               bytes:=0;

+ 5 - 2
compiler/arm/armins.dat

@@ -145,11 +145,11 @@ reg32,reg32,reg32,shifterop \x6\x0\x00                    ARM32,ARMv4
 reg32,reg32,immshifter      \x7\x2\x00                    ARM32,ARMv4
 reg32,reg32,immshifter      \x7\x2\x00                    ARM32,ARMv4
 
 
 [Bcc]
 [Bcc]
-imm32                       \x62\xE0\x0                   THUMB,ARMv4T
+imm24                       \x62\xE0\x0                   THUMB,ARMv4T
 immshifter                  \x62\xE0\x0                   THUMB,ARMv4T
 immshifter                  \x62\xE0\x0                   THUMB,ARMv4T
 mem32                       \x62\xE0\x0                   THUMB,ARMv4T
 mem32                       \x62\xE0\x0                   THUMB,ARMv4T
 
 
-imm32                       \x63\xD0\x0                   THUMB,ARMv4T
+imm24                       \x63\xD0\x0                   THUMB,ARMv4T
 immshifter                  \x63\xD0\x0                   THUMB,ARMv4T
 immshifter                  \x63\xD0\x0                   THUMB,ARMv4T
 mem32                       \x63\xD0\x0                   THUMB,ARMv4T
 mem32                       \x63\xD0\x0                   THUMB,ARMv4T
 
 
@@ -361,6 +361,7 @@ reg32,regf          \x10\x01\x0F                        ARM32,ARMv4
 [MSRcc]
 [MSRcc]
 regf,reg32          \x12\x01\x28\xF0                    ARM32,ARMv4
 regf,reg32          \x12\x01\x28\xF0                    ARM32,ARMv4
 regf,immshifter     \x13\x03\x28\xF0                    ARM32,ARMv4
 regf,immshifter     \x13\x03\x28\xF0                    ARM32,ARMv4
+regs,immshifter     \x13\x03\x28\xF0                    ARM32,ARMv4
 
 
 [MULcc]
 [MULcc]
 reglo,reglo,reglo      \x64\x43\x40              THUMB,ARMv4T
 reglo,reglo,reglo      \x64\x43\x40              THUMB,ARMv4T
@@ -396,6 +397,8 @@ vreg,reg32,reg32      \x40\xC\x40\xB\x10        ARM32,VFPv2
 [NOP]
 [NOP]
 void                    \x61\xBF\x0                  THUMB,ARMv6T2
 void                    \x61\xBF\x0                  THUMB,ARMv6T2
 void                    \x2F\x03\x20\xF0\x0          ARM32,ARMv6K
 void                    \x2F\x03\x20\xF0\x0          ARM32,ARMv6K
+; Before ARMv6K use mov r0,r0
+void                    \x2F\xE1\xA0\x0\x0           ARM32,ARMv4
 
 
 [ORNcc]
 [ORNcc]
 reg32,reg32,immshifter      \x80\xF0\x60\x0\x0            THUMB32,ARMv6T2
 reg32,reg32,immshifter      \x80\xF0\x60\x0\x0            THUMB32,ARMv6T2

+ 1 - 1
compiler/arm/armnop.inc

@@ -1,2 +1,2 @@
 { don't edit, this file is generated from armins.dat }
 { don't edit, this file is generated from armins.dat }
-651;
+653;

+ 16 - 2
compiler/arm/armtab.inc

@@ -255,7 +255,7 @@
   (
   (
     opcode  : A_B;
     opcode  : A_B;
     ops     : 1;
     ops     : 1;
-    optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none);
+    optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none);
     code    : #98#224#0;
     code    : #98#224#0;
     flags   : if_thumb or if_armv4t
     flags   : if_thumb or if_armv4t
   ),
   ),
@@ -276,7 +276,7 @@
   (
   (
     opcode  : A_B;
     opcode  : A_B;
     ops     : 1;
     ops     : 1;
-    optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none);
+    optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none);
     code    : #99#208#0;
     code    : #99#208#0;
     flags   : if_thumb or if_armv4t
     flags   : if_thumb or if_armv4t
   ),
   ),
@@ -1085,6 +1085,13 @@
     code    : #19#3#40#240;
     code    : #19#3#40#240;
     flags   : if_arm32 or if_armv4
     flags   : if_arm32 or if_armv4
   ),
   ),
+  (
+    opcode  : A_MSR;
+    ops     : 2;
+    optypes : (ot_regs,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none);
+    code    : #19#3#40#240;
+    flags   : if_arm32 or if_armv4
+  ),
   (
   (
     opcode  : A_MUL;
     opcode  : A_MUL;
     ops     : 3;
     ops     : 3;
@@ -1225,6 +1232,13 @@
     code    : #47#3#32#240#0;
     code    : #47#3#32#240#0;
     flags   : if_arm32 or if_armv6k
     flags   : if_arm32 or if_armv6k
   ),
   ),
+  (
+    opcode  : A_NOP;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #47#225#160#0#0;
+    flags   : if_arm32 or if_armv4
+  ),
   (
   (
     opcode  : A_ORN;
     opcode  : A_ORN;
     ops     : 3;
     ops     : 3;

+ 1 - 2
compiler/arm/cpubase.pas

@@ -591,7 +591,6 @@ unit cpubase;
       var
       var
         t : aint;
         t : aint;
         i : longint;
         i : longint;
-        imm : byte;
       begin
       begin
         {Loading 0-255 is simple}
         {Loading 0-255 is simple}
         if (d and $FF) = d then
         if (d and $FF) = d then
@@ -611,7 +610,7 @@ unit cpubase;
             result:=false;
             result:=false;
             for i:=1 to 31 do
             for i:=1 to 31 do
               begin
               begin
-                t:=RolDWord(imm,i);
+                t:=RolDWord(d,i);
                 if ((t and $FF)=t) and
                 if ((t and $FF)=t) and
                    ((t and $80)=$80) then
                    ((t and $80)=$80) then
                   begin
                   begin

+ 9 - 7
compiler/ogbase.pas

@@ -172,6 +172,10 @@ interface
        { Darwin asm is using indirect symbols resolving }
        { Darwin asm is using indirect symbols resolving }
        indsymbol  : TObjSymbol;
        indsymbol  : TObjSymbol;
 
 
+{$ifdef ARM}
+       ThumbFunc : boolean;
+{$endif ARM}
+
        constructor create(AList:TFPHashObjectList;const AName:string);
        constructor create(AList:TFPHashObjectList;const AName:string);
        function  address:aword;
        function  address:aword;
        procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype);
        procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype);
@@ -233,9 +237,6 @@ interface
        ExeSection  : TExeSection;
        ExeSection  : TExeSection;
        USed        : Boolean;
        USed        : Boolean;
        VTRefList : TFPObjectList;
        VTRefList : TFPObjectList;
-{$ifdef ARM}
-       ThumbFunc : boolean;
-{$endif ARM}
        constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);virtual;
        constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);virtual;
        destructor  destroy;override;
        destructor  destroy;override;
        function  write(const d;l:aword):aword;
        function  write(const d;l:aword):aword;
@@ -1140,10 +1141,6 @@ implementation
           begin
           begin
             result:=CObjSection.create(FObjSectionList,aname,aalign,aoptions);
             result:=CObjSection.create(FObjSectionList,aname,aalign,aoptions);
             result.ObjData:=self;
             result.ObjData:=self;
-{$ifdef ARM}
-            result.ThumbFunc:=ThumbFunc;
-            ThumbFunc:=false;
-{$endif ARM}
           end;
           end;
         FCurrObjSec:=result;
         FCurrObjSec:=result;
       end;
       end;
@@ -1181,6 +1178,11 @@ implementation
         result:=TObjSymbol(FObjSymbolList.Find(aname));
         result:=TObjSymbol(FObjSymbolList.Find(aname));
         if not assigned(result) then
         if not assigned(result) then
           result:=TObjSymbol.Create(FObjSymbolList,aname);
           result:=TObjSymbol.Create(FObjSymbolList,aname);
+
+{$ifdef ARM}
+        result.ThumbFunc:=ThumbFunc;
+        ThumbFunc:=false;
+{$endif ARM}
       end;
       end;
 
 
 
 

+ 1 - 2
compiler/ogelf.pas

@@ -970,8 +970,7 @@ implementation
         elfsym.st_value:=objsym.address;
         elfsym.st_value:=objsym.address;
 
 
 {$ifdef ARM}
 {$ifdef ARM}
-        if (objsym.typ=AT_FUNCTION) and
-           objsym.objsection.ThumbFunc then
+        if objsym.ThumbFunc then
           inc(elfsym.st_value);
           inc(elfsym.st_value);
 {$endif ARM}
 {$endif ARM}
 
 

+ 1 - 1
rtl/arm/arm.inc

@@ -15,7 +15,7 @@
 
 
  **********************************************************************}
  **********************************************************************}
 
 
-{$asmmode gas}
+{$asmmode divided}
 
 
 {$ifndef FPC_SYSTEM_HAS_MOVE}
 {$ifndef FPC_SYSTEM_HAS_MOVE}
 {$define FPC_SYSTEM_FPC_MOVE}
 {$define FPC_SYSTEM_FPC_MOVE}

+ 1 - 1
rtl/arm/thumb2.inc

@@ -15,7 +15,7 @@
 
 
  **********************************************************************}
  **********************************************************************}
 
 
-{$asmmode gas}
+{$asmmode divided}
 
 
 {$ifndef FPC_SYSTEM_HAS_MOVE}
 {$ifndef FPC_SYSTEM_HAS_MOVE}
 {$define FPC_SYSTEM_FPC_MOVE}
 {$define FPC_SYSTEM_FPC_MOVE}