Ver código fonte

* arm thumb1: several fixes for the internal assembler writer

git-svn-id: trunk@48675 -
florian 4 anos atrás
pai
commit
0316a7697f

+ 12 - 5
compiler/arm/agarmgas.pas

@@ -371,7 +371,7 @@ unit agarmgas;
 
     Procedure TArmInstrWriter.WriteInstruction(hp : tai);
     var op: TAsmOp;
-        postfix,s: string;
+        postfix,s,oppostfixstr: string;
         i: byte;
         sep: string[3];
     begin
@@ -382,17 +382,24 @@ unit agarmgas;
           if cf_wideformat in taicpu(hp).flags then
             postfix:='.w';
         end;
+      { GNU AS does not like an S postfix for several instructions in thumb mode though it is the only
+        valid encoding of mvn in thumb mode according to the arm docs }
+      if GenerateThumbCode and (taicpu(hp).oppostfix=PF_S) and
+        ((op=A_MVN) or (op=A_ORR) or (op=A_AND) or (op=A_LSL) or (op=A_ADC) or (op=A_LSR) or (op=A_SBC) or (op=A_EOR) or (op=A_ROR)) then
+        oppostfixstr:=''
+      else
+        oppostfixstr:=oppostfix2str[taicpu(hp).oppostfix];
       if unified_syntax then
         begin
           if taicpu(hp).ops = 0 then
-            s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix]
+            s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfixstr
           else if taicpu(hp).oppostfix in [PF_8..PF_U32F64] then
-            s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix]
+            s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfixstr
           else
-            s:=#9+gas_op2str[op]+oppostfix2str[taicpu(hp).oppostfix]+cond2str[taicpu(hp).condition]+postfix; // Conditional infixes are deprecated in unified syntax
+            s:=#9+gas_op2str[op]+oppostfixstr+cond2str[taicpu(hp).condition]+postfix; // Conditional infixes are deprecated in unified syntax
         end
       else
-        s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix];
+        s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfixstr;
       if taicpu(hp).ops<>0 then
         begin
           sep:=#9;

+ 4 - 4
compiler/arm/armins.dat

@@ -215,7 +215,7 @@ reg32                    \3\x01\x2F\xFF\x10            ARM32,ARMv4T
 reg8,reg8                \300\1\x10\101                ARM32,ARMv4
 
 [CMNcc]
-reglo,reglo             \x6B\x42\xC0                     THUMB,ARMv4T
+reglo,reglo             \x6F\x42\xC0                     THUMB,ARMv4T
 
 reg32,immshifter        \x80\xF1\x10\x0F\x00             THUMB32,ARMv6T2
 reg32,reg32             \x80\xEB\x10\x0F\x00             THUMB32,WIDE,ARMv6T2
@@ -226,10 +226,10 @@ reg32,reg32,shifterop   \xE\x1\x60                       ARM32,ARMv4
 reg32,immshifter        \xF\x1\x60                       ARM32,ARMv4
 
 [CMPcc]
-reglo,reglo             \x6B\x42\x80                     THUMB,ARMv4T
+reglo,reglo             \x6F\x42\x80                     THUMB,ARMv4T
 reg32,reg32             \x61\x45\x0                      THUMB,ARMv4T
 
-reglo,immshifter        \x6B\x28\x0                      THUMB,ARMv4T
+reglo,immshifter        \x6F\x28\x0                      THUMB,ARMv4T
 
 reg32,immshifter         \x80\xF1\xB0\x0F\x00           THUMB32,WIDE,ARMv6T2
 reg32,reg32              \x80\xEB\xB0\x0F\x00           THUMB32,WIDE,ARMv6T2
@@ -612,7 +612,7 @@ reg32,reg32,shifterop \xE\x1\x20                     ARM32,ARMv4
 reg32,immshifter      \xF\x3\x20                     ARM32,ARMv4
 
 [TSTcc]
-reglo,reglo           \x6B\x42\x00                   THUMB,ARMv4T
+reglo,reglo           \x6F\x42\x00                   THUMB,ARMv4T
 
 reg32,immshifter      \x80\xF0\x10\x0F\x00           THUMB32,ARMv6T2
 reg32,reg32           \x80\xEA\x10\x0F\x00           THUMB32,WIDE,ARMv6T2

+ 4 - 4
compiler/arm/armtab.inc

@@ -592,7 +592,7 @@
     opcode  : A_CMN;
     ops     : 2;
     optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none);
-    code    : #107#66#192;
+    code    : #111#66#192;
     flags   : if_thumb or if_armv4t
   ),
   (
@@ -641,7 +641,7 @@
     opcode  : A_CMP;
     ops     : 2;
     optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none);
-    code    : #107#66#128;
+    code    : #111#66#128;
     flags   : if_thumb or if_armv4t
   ),
   (
@@ -655,7 +655,7 @@
     opcode  : A_CMP;
     ops     : 2;
     optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none);
-    code    : #107#40#0;
+    code    : #111#40#0;
     flags   : if_thumb or if_armv4t
   ),
   (
@@ -2328,7 +2328,7 @@
     opcode  : A_TST;
     ops     : 2;
     optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none);
-    code    : #107#66#0;
+    code    : #111#66#0;
     flags   : if_thumb or if_armv4t
   ),
   (

+ 23 - 23
compiler/arm/cgcpu.pas

@@ -746,9 +746,9 @@ unit cgcpu;
         (A_NONE,A_MOV,A_ADD,A_AND,A_NONE,A_NONE,A_MUL,A_MUL,A_NONE,A_NONE,A_ORR,
          A_ASR,A_LSL,A_LSR,A_SUB,A_EOR,A_NONE,A_ROR);
 
-      op_reg_postfix: array[TOpCG] of TOpPostfix =
-        (PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,
-         PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None);
+      op_reg_postfix_thumb: array[TOpCG] of TOpPostfix =
+        (PF_None,PF_None,PF_None,PF_S,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_S,
+         PF_None,PF_S,PF_S,PF_None,PF_S,PF_None,PF_S);
 
     procedure tcgarm.a_op_const_reg_reg(list: TAsmList; op: TOpCg;
       size: tcgsize; a: tcgint; src, dst: tregister);
@@ -3925,7 +3925,7 @@ unit cgcpu;
                      a_internal_load_ref_reg(list,OS_S8,OS_S8,usedtmpref,tmpreg);
                    list.concat(taicpu.op_reg_const(A_LSL,tmpreg,8));
 
-                   list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                   list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                  end;
                OS_32,OS_S32:
                  begin
@@ -3955,7 +3955,7 @@ unit cgcpu;
                        inc(usedtmpref.offset,dir*2);
                        a_internal_load_ref_reg(list,OS_16,OS_16,usedtmpref,tmpreg);
                        list.concat(taicpu.op_reg_const(A_LSL,tmpreg,16));
-                       list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                       list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                      end
                    else
                      begin
@@ -3965,15 +3965,15 @@ unit cgcpu;
                        inc(usedtmpref.offset,dir);
                        a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
                        list.concat(taicpu.op_reg_const(A_LSL,tmpreg,8));
-                       list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                       list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                        inc(usedtmpref.offset,dir);
                        a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
                        list.concat(taicpu.op_reg_const(A_LSL,tmpreg,16));
-                       list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                       list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                        inc(usedtmpref.offset,dir);
                        a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
                        list.concat(taicpu.op_reg_const(A_LSL,tmpreg,24));
-                       list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                       list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                      end;
                  end
                else
@@ -3996,7 +3996,7 @@ unit cgcpu;
           if not(size in [OS_8,OS_S8,OS_16,OS_S16,OS_32,OS_S32]) then
             internalerror(2002090908);
           if is_thumb_imm(a) then
-            list.concat(taicpu.op_reg_const(A_MOV,reg,a))
+            list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,reg,a),PF_S))
           else
             begin
               reference_reset(hr,4,[]);
@@ -4157,7 +4157,7 @@ unit cgcpu;
           OP_NEG:
             list.concat(taicpu.op_reg_reg(A_NEG,dst,src));
           OP_NOT:
-            list.concat(taicpu.op_reg_reg(A_MVN,dst,src));
+            list.concat(setoppostfix(taicpu.op_reg_reg(A_MVN,dst,src),PF_S));
           OP_DIV,OP_IDIV:
             internalerror(200308284);
           OP_ROL:
@@ -4168,13 +4168,13 @@ unit cgcpu;
               tmpreg:=getintregister(list,OS_32);
               a_load_const_reg(list,OS_32,32,tmpreg);
               list.concat(taicpu.op_reg_reg(A_SUB,tmpreg,src));
-              list.concat(taicpu.op_reg_reg(A_ROR,dst,src));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_ROR,dst,src),PF_S));
             end;
           else
             begin
               a_reg_alloc(list,NR_DEFAULTFLAGS);
               list.concat(setoppostfix(
-                taicpu.op_reg_reg(op_reg_opcg2asmop[op],dst,src),op_reg_postfix[op]));
+                taicpu.op_reg_reg(op_reg_opcg2asmop[op],dst,src),op_reg_postfix_thumb[op]));
             end;
         end;
         maybeadjustresult(list,op,size,dst);
@@ -4210,7 +4210,7 @@ unit cgcpu;
              // if cgsetflags or setflags then
              a_reg_alloc(list,NR_DEFAULTFLAGS);
             list.concat(setoppostfix(
-              taicpu.op_reg_const(op_reg_opcg2asmop[op],dst,a),op_reg_postfix[op]));
+              taicpu.op_reg_const(op_reg_opcg2asmop[op],dst,a),op_reg_postfix_thumb[op]));
 
             if (cgsetflags {!!! or setflags }) and (size in [OS_8,OS_16,OS_32]) then
               begin
@@ -4269,7 +4269,7 @@ unit cgcpu;
             { x := y and 0; just clears a register, this sometimes gets generated on 64bit ops.
               Just using mov x, #0 might allow some easier optimizations down the line. }
             else if (op = OP_AND) and (dword(a)=0) then
-              list.concat(taicpu.op_reg_const(A_MOV,dst,0))
+              list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,dst,0),PF_S))
             { x := y AND $FFFFFFFF just copies the register, so use mov for better optimizations }
             else if (op = OP_AND) and (not(dword(a))=0) then
               // do nothing
@@ -4325,10 +4325,10 @@ unit cgcpu;
         ai:=setcondition(taicpu.op_sym(A_B,l1),flags_to_cond(f));
         ai.is_jmp:=true;
         list.concat(ai);
-        list.concat(taicpu.op_reg_const(A_MOV,reg,0));
+        list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,reg,0),PF_S));
         list.concat(taicpu.op_sym(A_B,l2));
         cg.a_label(list,l1);
-        list.concat(taicpu.op_reg_const(A_MOV,reg,1));
+        list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,reg,1),PF_S));
         a_reg_dealloc(list,NR_DEFAULTFLAGS);
         cg.a_label(list,l2);
       end;
@@ -5355,11 +5355,11 @@ unit cgcpu;
         case op of
           OP_NEG:
             begin
-              list.concat(taicpu.op_reg_const(A_MOV,regdst.reglo,0));
-              list.concat(taicpu.op_reg_const(A_MOV,regdst.reghi,0));
+              list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,regdst.reglo,0),PF_S));
+              list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,regdst.reghi,0),PF_S));
               cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
               list.concat(taicpu.op_reg_reg(A_SUB,regdst.reglo,regsrc.reglo));
-              list.concat(taicpu.op_reg_reg(A_SBC,regdst.reghi,regsrc.reghi));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_SBC,regdst.reghi,regsrc.reghi),PF_S));
               cg.a_reg_dealloc(list,NR_DEFAULTFLAGS);
             end;
           OP_NOT:
@@ -5376,13 +5376,13 @@ unit cgcpu;
             begin
               cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
               list.concat(taicpu.op_reg_reg(A_ADD,regdst.reglo,regsrc.reglo));
-              list.concat(taicpu.op_reg_reg(A_ADC,regdst.reghi,regsrc.reghi));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_ADC,regdst.reghi,regsrc.reghi),PF_S));
             end;
           OP_SUB:
             begin
               cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
               list.concat(taicpu.op_reg_reg(A_SUB,regdst.reglo,regsrc.reglo));
-              list.concat(taicpu.op_reg_reg(A_SBC,regdst.reghi,regsrc.reghi));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_SBC,regdst.reghi,regsrc.reghi),PF_S));
             end;
           else
             internalerror(2003083105);
@@ -5417,7 +5417,7 @@ unit cgcpu;
 
                tmpreg:=cg.getintregister(list,OS_32);
                cg.a_load_const_reg(list,OS_32,aint(hi(value)),tmpreg);
-               list.concat(taicpu.op_reg_reg(A_ADC,reg.reghi,tmpreg));
+               list.concat(setoppostfix(taicpu.op_reg_reg(A_ADC,reg.reghi,tmpreg),PF_S));
             end;
           OP_SUB:
             begin
@@ -5436,7 +5436,7 @@ unit cgcpu;
 
               tmpreg:=cg.getintregister(list,OS_32);
               cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
-              list.concat(taicpu.op_reg_reg(A_SBC,reg.reghi,tmpreg));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_SBC,reg.reghi,tmpreg),PF_S));
             end;
           else
             internalerror(2003083106);

+ 2 - 2
compiler/arm/narmset.pas

@@ -112,11 +112,11 @@ implementation
              right.resultdef, right.resultdef, true);
 
             hregister:=hlcg.getintregister(current_asmdata.CurrAsmList, opdef);
-            current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_MOV,hregister,1));
+            hlcg.a_load_const_reg(current_asmdata.CurrAsmList,opdef,1,hregister);
 
             if GenerateThumbCode or GenerateThumb2Code then
               begin
-                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_LSL,hregister,left.location.register));
+                hlcg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_SHL,opdef,left.location.register,hregister);
                 cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
                 current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_TST,right.location.register,hregister));
               end

+ 5 - 0
compiler/arm/raarm.pas

@@ -43,6 +43,8 @@ unit raarm;
   implementation
 
     uses
+      globals,
+      cpuinfo,
       aasmcpu;
 
     function TARMInstruction.ConcatInstruction(p:TAsmList) : tai;
@@ -53,6 +55,9 @@ unit raarm;
           include((result as taicpu).flags,cf_wideformat)
         else
           exclude((result as taicpu).flags,cf_wideformat);
+        { GNU As assumes implicit S postfix for some instructions in thumb mode }
+        if (current_settings.instructionset=is_thumb) and (((result as taicpu).oppostfix=PF_None) and ((opcode=A_MOV) and ((result as taicpu).oper[1]^.typ=top_const)) or (opcode=A_MVN)) then
+          (result as taicpu).oppostfix:=PF_S
       end;