Sfoglia il codice sorgente

+ a_op_const_reg_reg for arm thumb taking care of availability of add sp,sp, ...
* handle references with base and index on arm thumb correctly

git-svn-id: trunk@24196 -

florian 12 anni fa
parent
commit
f9ef8e90da
1 ha cambiato i file con 37 aggiunte e 9 eliminazioni
  1. 37 9
      compiler/arm/cgcpu.pas

+ 37 - 9
compiler/arm/cgcpu.pas

@@ -165,6 +165,7 @@ unit cgcpu;
 
         procedure a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src,dst: TRegister);override;
         procedure a_op_const_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; dst: tregister);override;
+        procedure a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister); override;
 
         procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister); override;
 
@@ -1122,23 +1123,41 @@ unit cgcpu;
            ) or
            ((current_settings.cputype in cpu_thumb) and
             (((oppostfix in [PF_SB,PF_SH]) and (ref.offset<>0)) or
-             ((oppostfix=PF_None) and ((ref.offset<0) or (ref.offset>124) or ((ref.offset mod 4)<>0))) or
+             ((oppostfix=PF_None) and ((ref.offset<0) or ((ref.base<>NR_STACK_POINTER_REG) and (ref.offset>124)) or
+               ((ref.base=NR_STACK_POINTER_REG) and (ref.offset>1020)) or ((ref.offset mod 4)<>0))) or
              ((oppostfix=PF_H) and ((ref.offset<0) or (ref.offset>62) or ((ref.offset mod 2)<>0))) or
-             ((oppostfix=PF_B) and ((ref.offset<0) or (ref.offset>31)))
+             ((oppostfix=PF_B) and ((ref.offset<0) or (ref.offset>31) or ((getsupreg(ref.base) in [RS_R8..RS_R15]) and (ref.offset<>0))))
             )
            ) then
           begin
             fixref(list,ref);
           end;
 
-        { certain thumb load require base and index }
-        if (current_settings.cputype in cpu_thumb) and
-          (oppostfix in [PF_SB,PF_SH]) and
-          (ref.base<>NR_NO) and (ref.index=NR_NO) then
+        if current_settings.cputype in cpu_thumb then
           begin
-            tmpreg:=getintregister(list,OS_ADDR);
-            a_load_const_reg(list,OS_INT,0,tmpreg);
-            ref.index:=tmpreg;
+            { certain thumb load require base and index }
+            if (oppostfix in [PF_SB,PF_SH]) and
+              (ref.base<>NR_NO) and (ref.index=NR_NO) then
+              begin
+                tmpreg:=getintregister(list,OS_ADDR);
+                a_load_const_reg(list,OS_ADDR,0,tmpreg);
+                ref.index:=tmpreg;
+              end;
+
+            { "hi" registers cannot be used as base or index }
+            if (getsupreg(ref.base) in [RS_R8..RS_R12,RS_R14]) or
+              ((ref.base=NR_R13) and (ref.index<>NR_NO)) then
+              begin
+                tmpreg:=getintregister(list,OS_ADDR);
+                a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.base,tmpreg);
+                ref.base:=tmpreg;
+              end;
+            if getsupreg(ref.index) in [RS_R8..RS_R14] then
+              begin
+                tmpreg:=getintregister(list,OS_ADDR);
+                a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.index,tmpreg);
+                ref.index:=tmpreg;
+              end;
           end;
 
         { fold if there is base, index and offset, however, don't fold
@@ -3849,6 +3868,15 @@ unit cgcpu;
       end;
 
 
+    procedure tthumbcgarm.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
+      begin
+        if (op=OP_ADD) and (src=NR_R13) and (dst<>NR_R13) and ((a mod 4)=0) and (a>0) and (a<=1020) then
+          list.concat(taicpu.op_reg_reg_const(A_ADD,dst,src,a))
+        else
+          inherited a_op_const_reg_reg(list,op,size,a,src,dst);
+      end;
+
+
     procedure tthumbcgarm.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister);
       var
         l : tasmlabel;