Browse Source

* handle non-multiple-of-4 offsets with 64 bit loads/stores for
darwin/ppc64

git-svn-id: branches/fpc_2_3@6433 -

Jonas Maebe 18 years ago
parent
commit
92d521131c
1 changed files with 31 additions and 22 deletions
  1. 31 22
      compiler/powerpc64/cgcpu.pas

+ 31 - 22
compiler/powerpc64/cgcpu.pas

@@ -663,11 +663,11 @@ procedure tcgppc.a_load_const_reg(list: TAsmList; size: TCGSize; a: aint;
   begin
     if (lo(a) = 0) and (hi(a) <> 0) then begin
       { load only upper 32 bits, and shift }
-      load32bitconstant(list, size, hi(a), reg);
+      load32bitconstant(list, size, longint(hi(a)), reg);
       list.concat(taicpu.op_reg_reg_const(A_SLDI, reg, reg, 32));
     end else begin
       { load lower 32 bits }
-      extendssign := load32bitconstant(list, size, lo(a), reg);
+      extendssign := load32bitconstant(list, size, longint(lo(a)), reg);
       if (extendssign) and (hi(a) = 0) then
         { if upper 32 bits are zero, but loading the lower 32 bit resulted in automatic
           sign extension, clear those bits }
@@ -683,7 +683,7 @@ procedure tcgppc.a_load_const_reg(list: TAsmList; size: TCGSize; a: aint;
           - loading the lower 32 bits resulted in 0 in the upper 32 bits, and the upper
            32 bits should contain 0 }
         a_reg_alloc(list, NR_R0);
-        load32bitconstantR0(list, size, hi(a));
+        load32bitconstantR0(list, size, longint(hi(a)));
         { combine both registers }
         list.concat(taicpu.op_reg_reg_const_const(A_RLDIMI, reg, NR_R0, 32, 0));
         a_reg_dealloc(list, NR_R0);
@@ -954,7 +954,7 @@ var
       end else begin
         getmagic_unsignedN(sizeof(aWord)*8, a, u_magic, u_add, u_shift);
         { load magic in divreg }
-        cg.a_load_const_reg(current_asmdata.CurrAsmList, OS_INT, u_magic, divreg);
+        cg.a_load_const_reg(current_asmdata.CurrAsmList, OS_INT, aint(u_magic), divreg);
         current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_MULHDU, dst, src, divreg));
         if (u_add) then begin
           cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_SUB, OS_INT, dst, src, divreg);
@@ -1982,6 +1982,31 @@ end;
 
 procedure tcgppc.a_load_store(list: TAsmList; op: tasmop; reg: tregister;
   ref: treference);
+
+  procedure maybefixup64bitoffset;
+    var
+      tmpreg: tregister;
+    begin
+      { for some instructions we need to check that the offset is divisible by at
+       least four. If not, add the bytes which are "off" to the base register and
+       adjust the offset accordingly }
+      case op of
+        A_LD, A_LDU, A_STD, A_STDU, A_LWA :
+           if ((ref.offset mod 4) <> 0) then begin
+            tmpreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
+    
+            if (ref.base <> NR_NO) then begin
+              a_op_const_reg_reg(list, OP_ADD, OS_ADDR, ref.offset mod 4, ref.base, tmpreg);
+              ref.base := tmpreg;
+            end else begin
+              list.concat(taicpu.op_reg_const(A_LI, tmpreg, ref.offset mod 4));
+              ref.base := tmpreg;
+            end;
+            ref.offset := (ref.offset div 4) * 4;
+          end;
+      end;
+    end;
+
 var
   tmpreg, tmpreg2: tregister;
   tmpref: treference;
@@ -1990,6 +2015,7 @@ begin
   if (target_info.system = system_powerpc64_darwin) then
     begin
       { darwin/ppc64 works with 32 bit relocatable symbol addresses }
+      maybefixup64bitoffset;
       inherited a_load_store(list,op,reg,ref);
       exit
     end;
@@ -2011,24 +2037,7 @@ begin
     exit;
   end;
 
-  { for some instructions we need to check that the offset is divisible by at
-   least four. If not, add the bytes which are "off" to the base register and
-   adjust the offset accordingly }
-  case op of
-    A_LD, A_LDU, A_STD, A_STDU, A_LWA :
-       if ((ref.offset mod 4) <> 0) then begin
-        tmpreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
-
-        if (ref.base <> NR_NO) then begin
-          a_op_const_reg_reg(list, OP_ADD, OS_ADDR, ref.offset mod 4, ref.base, tmpreg);
-          ref.base := tmpreg;
-        end else begin
-          list.concat(taicpu.op_reg_const(A_LI, tmpreg, ref.offset mod 4));
-          ref.base := tmpreg;
-        end;
-        ref.offset := (ref.offset div 4) * 4;
-      end;
-  end;
+  maybefixup64bitoffset;
   {$IFDEF EXTDEBUG}
   list.concat(tai_comment.create(strpnew('a_load_store1 ' + BoolToStr(ref.refaddr = addr_pic))));
   {$ENDIF EXTDEBUG}