Selaa lähdekoodia

* MIPS int->real conversion: When converting unsigned to single, load it into 64-bit FP register, otherwise further subtracting a 64-bit offset leads to invalid result. Fixes tw17714.pp.
* The addend is endian-dependent, fixes tcnvint4.pp on big-endian targets.

git-svn-id: trunk@23388 -

sergei 12 vuotta sitten
vanhempi
commit
d2758265e3
1 muutettua tiedostoa jossa 15 lisäystä ja 4 poistoa
  1. 15 4
      compiler/mips/ncpucnv.pas

+ 15 - 4
compiler/mips/ncpucnv.pas

@@ -124,7 +124,8 @@ var
   hregister: tregister;
   l1, l2:    tasmlabel;
   ai : TaiCpu;
-
+  addend: array[boolean] of longword;
+  bigendian: boolean;
 begin
   location_reset(location, LOC_FPUREGISTER, def_cgsize(resultdef));
   if is_signed(left.resultdef) then
@@ -137,7 +138,13 @@ begin
     hregister := cg.getintregister(current_asmdata.CurrAsmList, OS_32);
     hlcg.a_load_loc_reg(current_asmdata.CurrAsmList, left.resultdef, u32inttype, left.location, hregister);
 
-    loadsigned;
+    { Always load into 64-bit FPU register }
+    hlcg.location_force_mem(current_asmdata.CurrAsmList, left.location, left.resultdef);
+    location.Register := cg.getfpuregister(current_asmdata.CurrAsmList, OS_F64);
+    cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList, OS_F32, OS_F32, left.location.reference, location.Register);
+    tg.ungetiftemp(current_asmdata.CurrAsmList, left.location.reference);
+    { Convert value in fpu register from integer to float }
+    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CVT_D_W, location.Register, location.Register));
 
     ai := Taicpu.op_reg_reg_sym(A_BC, hregister, NR_R0, l2);
     ai.setCondition(C_GE);
@@ -152,9 +159,13 @@ begin
         new_section(current_asmdata.asmlists[al_typedconsts],sec_rodata_norel,l1.name,const_align(8));
         current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1));
 
+        addend[false]:=0;
+        addend[true]:=$41f00000;
+        bigendian:=(target_info.endian=endian_big);
+
         { add double number 4294967296.0 = (1ull^32) = 0x41f00000,00000000 in little endian hex}
-        current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit(0));
-        current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit($41f00000));
+        current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit(addend[bigendian]));
+        current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit(addend[not bigendian]));
 
         cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList, OS_F64, OS_F64, href, hregister);
         current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_ADD_D, location.Register, hregister, location.Register));