Browse Source

Added unified assembler syntax mode so it can be selected with $ASMMODE.
Fixed bug in Mov instruction.
Added initial scanning of IT/LastInIT detection for proper instruction selection.
Disabled "wide" format flag detection again for now.

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

Jeppe Johansen 10 years ago
parent
commit
cc418eef74

+ 78 - 4
compiler/arm/aasmcpu.pas

@@ -260,6 +260,10 @@ uses
          procedure ppubuildderefimploper(var o:toper);override;
          procedure ppuderefoper(var o:toper);override;
       private
+         { pass1 info }
+         inIT,
+         lastinIT: boolean;
+         { arm version info }
          fArmVMask,
          fArmMask  : longint;
          { next fields are filled in pass1, so pass2 is faster }
@@ -1447,6 +1451,57 @@ implementation
           end;
       end;
 
+
+    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
+        curtai: tai;
+        in_it: boolean;
+        it_count: longint;
+      begin
+        in_it:=false;
+        it_count:=0;
+
+        curtai:=tai(list.First);
+        while assigned(curtai) do
+          begin
+            case curtai.typ of
+              ait_instruction:
+                begin
+                  case taicpu(curtai).opcode of
+                    A_IT..A_ITTTT:
+                      begin
+                        if in_it then
+                          Message1(asmw_e_invalid_opcode_and_operands, 'ITxx instruction is inside another ITxx instruction')
+                        else
+                          begin
+                            in_it:=true;
+                            it_count:=opCount[taicpu(curtai).opcode];
+                          end;
+                      end;
+                    else
+                      begin
+                        taicpu(curtai).inIT:=in_it;
+                        taicpu(curtai).lastinIT:=in_it and (it_count=1);
+
+                        if in_it then
+                          begin
+                            dec(it_count);
+                            if it_count <= 0 then
+                              in_it:=false;
+                          end;
+                      end;
+                  end;
+                end;
+            end;
+
+            curtai:=tai(curtai.Next);
+          end;
+      end;
+
     procedure finalizearmcode(list, listtoinsert: TAsmList);
       begin
         { Do Thumb-2 16bit -> 32bit transformations }
@@ -1459,6 +1514,8 @@ implementation
         else if GenerateThumbCode then
           ensurethumbencodings(list);
 
+        gather_it_info(list);
+
         fix_invalid_imms(list);
 
         insertpcrelativedata(list, listtoinsert);
@@ -2111,8 +2168,8 @@ implementation
         { Check wideformat flag }
         if ((p^.flags and IF_WIDE)<>0) <> wideformat then
           begin
-            matches:=0;
-            exit;
+            {matches:=0;
+            exit;}
           end;
 
         { Check that no spurious colons or TOs are present }
@@ -2200,8 +2257,8 @@ implementation
       if p^.code[0] in [#$60..#$61] then
         begin
           if (p^.code[0]=#$60) and
-             ((oppostfix<>PF_S) and
-              (condition<>C_None)) then
+             (((not inIT) and (oppostfix<>PF_S)) or
+              (inIT and (condition=C_None))) then
             begin
               Matches:=0;
               exit;
@@ -4189,6 +4246,23 @@ implementation
                   end;
               end;
             end;
+          #$6A: { Thumb: IT }
+            begin
+              bytelen:=2;
+              bytes:=0;
+
+              { set opcode }
+              bytes:=bytes or (ord(insentry^.code[1]) shl 8);
+              bytes:=bytes or (ord(insentry^.code[2]) shl 0);
+
+              bytes:=bytes or (CondVal[oper[0]^.cc] shl 4);
+
+              i_field:=(bytes shr 4) and 1;
+              i_field:=(i_field shl 1) or i_field;
+              i_field:=(i_field shl 2) or i_field;
+
+              bytes:=bytes or ((i_field and ord(insentry^.code[3])) xor (ord(insentry^.code[3]) shr 4));
+            end;
           #$80: { Thumb-2: Dataprocessing }
             begin
               bytes:=0;

+ 17 - 2
compiler/arm/armins.dat

@@ -343,7 +343,7 @@ reg32,reg32,reg32,reg32  \x15\x00\x20\x9                ARM32,ARMv4
 
 [MOVcc]
 reglo,reglo             \x60\x0\x0                       THUMB,ARMv4T
-reg32,reg32             \x61\x46\xC0                     THUMB,ARMv4T
+reg32,reg32             \x61\x46\x00                     THUMB,ARMv4T
 
 reglo,immshifter        \x60\x20\x0                      THUMB,ARMv4T
 
@@ -839,7 +839,7 @@ reg32,reg32,immshifter     \x30\x1\xA0\x0\x20                  ARM32,ARMv4
 reglo,reglo,immshifter     \x60\x0\x0                          THUMB,ARMv4T
 reglo,reglo                \x60\x40\x80                        THUMB,ARMv4T
 
-reg32,reg32,immshifter     \x82\xEA\x4F\x0\x20                 THUMB32,ARMv6T2
+reg32,reg32,immshifter     \x82\xEA\x4F\x0\x00                 THUMB32,WIDE,ARMv6T2
 reg32,reg32,reg32          \x80\xFA\x60\xF0\x0                 THUMB32,WIDE,ARMv6T2
 
 reg32,reg32,reg32          \x30\x1\xA0\x0\x10                  ARM32,ARMv4
@@ -1292,48 +1292,63 @@ reg32,imm                     \x2C\x3\x40                ARM32,ARMv6T2
 reg32,immshifter              \x2C\x3\x40                ARM32,ARMv6T2
 
 [IT]
+condition                     \x6A\xBF\x08\x00           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITE]
+condition                     \x6A\xBF\x04\x88           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITT]
+condition                     \x6A\xBF\x04\x08           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITEE]
+condition                     \x6A\xBF\x02\xCC           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITTE]
+condition                     \x6A\xBF\x02\x4C           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITET]
+condition                     \x6A\xBF\x02\x8C           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITTT]
+condition                     \x6A\xBF\x02\x0C           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITEEE]
+condition                     \x6A\xBF\x01\xEE           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITTEE]
+condition                     \x6A\xBF\x01\x6E           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITETE]
+condition                     \x6A\xBF\x01\xAE           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITTTE]
+condition                     \x6A\xBF\x01\x2E           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITEET]
+condition                     \x6A\xBF\x01\xCE           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITTET]
+condition                     \x6A\xBF\x01\x4E           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITETT]
+condition                     \x6A\xBF\x01\x8E           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [ITTTT]
+condition                     \x6A\xBF\x01\x0E           THUMB,ARMv6T2
 condition                     \xFE                       ARM32,ARMv4
 
 [TBB]

+ 1 - 1
compiler/arm/armnop.inc

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

+ 108 - 3
compiler/arm/armtab.inc

@@ -1019,7 +1019,7 @@
     opcode  : A_MOV;
     ops     : 2;
     optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none);
-    code    : #97#70#192;
+    code    : #97#70#0;
     flags   : if_thumb or if_armv4t
   ),
   (
@@ -2832,8 +2832,8 @@
     opcode  : A_LSL;
     ops     : 3;
     optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none);
-    code    : #130#234#79#0#32;
-    flags   : if_thumb32 or if_armv6t2
+    code    : #130#234#79#0#0;
+    flags   : if_thumb32 or if_wide or if_armv6t2
   ),
   (
     opcode  : A_LSL;
@@ -4039,6 +4039,13 @@
     code    : #44#3#64;
     flags   : if_arm32 or if_armv6t2
   ),
+  (
+    opcode  : A_IT;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#8#0;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_IT;
     ops     : 1;
@@ -4046,6 +4053,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITE;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#4#136;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITE;
     ops     : 1;
@@ -4053,6 +4067,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITT;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#4#8;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITT;
     ops     : 1;
@@ -4060,6 +4081,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITEE;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#2#204;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITEE;
     ops     : 1;
@@ -4067,6 +4095,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITTE;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#2#76;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITTE;
     ops     : 1;
@@ -4074,6 +4109,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITET;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#2#140;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITET;
     ops     : 1;
@@ -4081,6 +4123,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITTT;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#2#12;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITTT;
     ops     : 1;
@@ -4088,6 +4137,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITEEE;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#1#238;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITEEE;
     ops     : 1;
@@ -4095,6 +4151,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITTEE;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#1#110;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITTEE;
     ops     : 1;
@@ -4102,6 +4165,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITETE;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#1#174;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITETE;
     ops     : 1;
@@ -4109,6 +4179,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITTTE;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#1#46;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITTTE;
     ops     : 1;
@@ -4116,6 +4193,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITEET;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#1#206;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITEET;
     ops     : 1;
@@ -4123,6 +4207,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITTET;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#1#78;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITTET;
     ops     : 1;
@@ -4130,6 +4221,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITETT;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#1#142;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITETT;
     ops     : 1;
@@ -4137,6 +4235,13 @@
     code    : #254;
     flags   : if_arm32 or if_armv4
   ),
+  (
+    opcode  : A_ITTTT;
+    ops     : 1;
+    optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
+    code    : #106#191#1#14;
+    flags   : if_thumb or if_armv6t2
+  ),
   (
     opcode  : A_ITTTT;
     ops     : 1;

+ 30 - 7
compiler/arm/raarmgas.pas

@@ -30,10 +30,8 @@ Unit raarmgas;
       cpubase;
 
     type
-      tarmsyntax = (asm_legacy, asm_unified);
 
       tarmattreader = class(tattreader)
-        asmsyntax : tarmsyntax;
         actoppostfix : TOpPostfix;
         actwideformat : boolean;
         function is_asmopcode(const s: string):boolean;override;
@@ -48,6 +46,13 @@ Unit raarmgas;
         procedure ReadSym(oper : tarmoperand);
         procedure ConvertCalljmp(instr : tarminstruction);
         procedure HandleTargetDirective; override;
+      protected
+        function is_unified: boolean; virtual;
+      end;
+
+      tarmunifiedattreader = class(tarmattreader)
+      protected
+        function is_unified: boolean; override;
       end;
 
 
@@ -66,6 +71,12 @@ Unit raarmgas;
       cgbase,cgutils;
 
 
+    function tarmunifiedattreader.is_unified: boolean;
+      begin
+        result:=true;
+      end;
+
+
     function tarmattreader.is_register(const s:string):boolean;
       type
         treg2str = record
@@ -1294,10 +1305,11 @@ Unit raarmgas;
                   end;
                 dec(j2);
               end;
+
             if actopcode=A_NONE then
               exit;
 
-            if asmsyntax=asm_unified then
+            if is_unified then
               begin
                 { check for postfix }
                 if (length(hs)>0) and (actoppostfix=PF_None) then
@@ -1431,12 +1443,17 @@ Unit raarmgas;
         else if actasmpattern='.thumb_func' then
           begin
             consume(AS_TARGET_DIRECTIVE);
-            curList.concat(tai_thumb_func.create);
+            curList.concat(tai_directive.create(asd_thumb_func,''));
           end
         else
           inherited HandleTargetDirective;
       end;
 
+    function tarmattreader.is_unified: boolean;
+      begin
+        result:=false;
+      end;
+
 
     procedure tarmattreader.handleopcode;
       var
@@ -1455,8 +1472,6 @@ Unit raarmgas;
         instr.Free;
         actoppostfix:=PF_None;
         actwideformat:=false;
-
-        asmsyntax:=asm_legacy;
       end;
 
 
@@ -1468,10 +1483,17 @@ const
   asmmode_arm_att_info : tasmmodeinfo =
           (
             id    : asmmode_arm_gas;
-            idtxt : 'GAS';
+            idtxt : 'DIVIDED';
             casmreader : tarmattreader;
           );
 
+  asmmode_arm_att_unified_info : tasmmodeinfo =
+          (
+            id    : asmmode_arm_gas_unified;
+            idtxt : 'UNIFIED';
+            casmreader : tarmunifiedattreader;
+          );
+
   asmmode_arm_standard_info : tasmmodeinfo =
           (
             id    : asmmode_standard;
@@ -1481,5 +1503,6 @@ const
 
 initialization
   RegisterAsmMode(asmmode_arm_att_info);
+  RegisterAsmMode(asmmode_arm_att_unified_info);
   RegisterAsmMode(asmmode_arm_standard_info);
 end.

+ 1 - 0
compiler/systems.inc

@@ -68,6 +68,7 @@
             ,asmmode_avr_gas
             ,asmmode_i8086_intel
             ,asmmode_i8086_att
+            ,asmmode_arm_gas_unified
        );
 
      (* IMPORTANT NOTE: