* fixed longint -> real, was broken in 6153

git-svn-id: trunk@6257 -
This commit is contained in:
florian 2007-01-28 21:27:21 +00:00
parent 31636e3887
commit 0fd3498892

View File

@ -122,47 +122,57 @@ implementation
l1,l2 : tasmlabel; l1,l2 : tasmlabel;
hregister : tregister; hregister : tregister;
begin begin
current_asmdata.getdatalabel(l1);
current_asmdata.getjumplabel(l2);
reference_reset_symbol(href,l1,0);
{ convert first to double to avoid precision loss } { convert first to double to avoid precision loss }
location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef)); location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
location_force_reg(current_asmdata.CurrAsmList,left.location,OS_32,true); location_force_reg(current_asmdata.CurrAsmList,left.location,OS_32,true);
location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size); location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
instr:=taicpu.op_reg_reg(A_FLT,location.register,left.location.register); instr:=taicpu.op_reg_reg(A_FLT,location.register,left.location.register);
instr.oppostfix:=PF_D; if is_signed(left.resultdef) then
current_asmdata.CurrAsmList.concat(instr); begin
instr.oppostfix:=cgsize2fpuoppostfix[def_cgsize(resultdef)];;
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_const(A_CMP,left.location.register,0)); current_asmdata.CurrAsmList.concat(instr);
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_GE,l2); end
else
case tfloatdef(resultdef).floattype of begin
{ converting dword to s64real first and cut off at the end avoids precision loss } { flt does a signed load, fix this }
s32real, case tfloatdef(resultdef).floattype of
s64real: s32real,
begin s64real:
hregister:=cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);
current_asmdata.asmlists[al_typedconsts].concat(tai_align.create(const_align(8)));
current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1));
{ I got this constant from a test program (FK) }
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit($41f00000));
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit(0));
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,OS_F64,href,hregister);
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADF,location.register,hregister,location.register),PF_D));
cg.a_label(current_asmdata.CurrAsmList,l2);
{ cut off if we should convert to single }
if tfloatdef(resultdef).floattype=s32real then
begin begin
hregister:=location.register; { converting dword to s64real first and cut off at the end avoids precision loss }
location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size); instr.oppostfix:=PF_D;
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_MVF,location.register,hregister),PF_S)); current_asmdata.CurrAsmList.concat(instr);
current_asmdata.getdatalabel(l1);
current_asmdata.getjumplabel(l2);
reference_reset_symbol(href,l1,0);
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_const(A_CMP,left.location.register,0));
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_GE,l2);
hregister:=cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);
current_asmdata.asmlists[al_typedconsts].concat(tai_align.create(const_align(8)));
current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1));
{ I got this constant from a test program (FK) }
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit($41f00000));
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit(0));
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,OS_F64,href,hregister);
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADF,location.register,hregister,location.register),PF_D));
cg.a_label(current_asmdata.CurrAsmList,l2);
{ cut off if we should convert to single }
if tfloatdef(resultdef).floattype=s32real then
begin
hregister:=location.register;
location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_MVF,location.register,hregister),PF_S));
end;
end; end;
else
internalerror(200410031);
end; end;
else
internalerror(200410031);
end; end;
end; end;