mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-24 04:02:09 +02:00
MIPS, improved integer to real conversions:
* Use fpc_[int64|qword]_to_double instead of [int64|qword]_to_float64, makes RTL no longer dependent on softfloat code. * Move 32-bit values from integer registers to FPU registers without using memory. * Fixed branching, was still using a macro and delay slot was missing. git-svn-id: trunk@25071 -
This commit is contained in:
parent
6b34c84704
commit
1ca2a253e8
@ -71,12 +71,27 @@ uses
|
|||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
function tmipseltypeconvnode.first_int_to_real: tnode;
|
function tmipseltypeconvnode.first_int_to_real: tnode;
|
||||||
|
var
|
||||||
|
fname: string[19];
|
||||||
begin
|
begin
|
||||||
{ converting a 64bit integer to a float requires a helper }
|
{ converting a 64bit integer to a float requires a helper }
|
||||||
if is_64bitint(left.resultdef) or
|
if is_64bitint(left.resultdef) or
|
||||||
is_currency(left.resultdef) then
|
is_currency(left.resultdef) then
|
||||||
begin
|
begin
|
||||||
result:=inherited first_int_to_real;
|
{ hack to avoid double division by 10000, as it's
|
||||||
|
already done by typecheckpass.resultdef_int_to_real }
|
||||||
|
if is_currency(left.resultdef) then
|
||||||
|
left.resultdef := s64inttype;
|
||||||
|
if is_signed(left.resultdef) then
|
||||||
|
fname := 'fpc_int64_to_double'
|
||||||
|
else
|
||||||
|
fname := 'fpc_qword_to_double';
|
||||||
|
result := ccallnode.createintern(fname,ccallparanode.create(
|
||||||
|
left,nil));
|
||||||
|
left:=nil;
|
||||||
|
if (tfloatdef(resultdef).floattype=s32real) then
|
||||||
|
inserttypeconv(result,s32floattype);
|
||||||
|
firstpass(result);
|
||||||
exit;
|
exit;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -105,11 +120,18 @@ procedure tMIPSELtypeconvnode.second_int_to_real;
|
|||||||
|
|
||||||
procedure loadsigned;
|
procedure loadsigned;
|
||||||
begin
|
begin
|
||||||
hlcg.location_force_mem(current_asmdata.CurrAsmList, left.location, left.resultdef);
|
|
||||||
location.Register := cg.getfpuregister(current_asmdata.CurrAsmList, location.size);
|
location.Register := cg.getfpuregister(current_asmdata.CurrAsmList, location.size);
|
||||||
{ Load memory in fpu register }
|
if (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
|
||||||
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList, OS_F32, OS_F32, left.location.reference, location.Register);
|
{ 32-bit values can be loaded directly }
|
||||||
tg.ungetiftemp(current_asmdata.CurrAsmList, left.location.reference);
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_MTC1, left.location.register, location.register))
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ Load memory in fpu register }
|
||||||
|
hlcg.location_force_mem(current_asmdata.CurrAsmList, left.location, left.resultdef);
|
||||||
|
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);
|
||||||
|
end;
|
||||||
|
|
||||||
{ Convert value in fpu register from integer to float }
|
{ Convert value in fpu register from integer to float }
|
||||||
case tfloatdef(resultdef).floattype of
|
case tfloatdef(resultdef).floattype of
|
||||||
s32real:
|
s32real:
|
||||||
@ -125,7 +147,6 @@ var
|
|||||||
href: treference;
|
href: treference;
|
||||||
hregister: tregister;
|
hregister: tregister;
|
||||||
l1, l2: tasmlabel;
|
l1, l2: tasmlabel;
|
||||||
ai : TaiCpu;
|
|
||||||
addend: array[boolean] of longword;
|
addend: array[boolean] of longword;
|
||||||
bigendian: boolean;
|
bigendian: boolean;
|
||||||
begin
|
begin
|
||||||
@ -148,9 +169,7 @@ begin
|
|||||||
{ Convert value in fpu register from integer to float }
|
{ 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));
|
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);
|
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, OS_INT, OC_GTE, 0, hregister, l2);
|
||||||
ai.setCondition(C_GE);
|
|
||||||
current_asmdata.CurrAsmList.concat(ai);
|
|
||||||
|
|
||||||
case tfloatdef(resultdef).floattype of
|
case tfloatdef(resultdef).floattype of
|
||||||
{ converting dword to s64real first and cut off at the end avoids precision loss }
|
{ converting dword to s64real first and cut off at the end avoids precision loss }
|
||||||
|
Loading…
Reference in New Issue
Block a user