* fixed qword -> <real> type cast

This commit is contained in:
florian 2004-05-10 20:57:45 +00:00
parent 95f77d08e2
commit 39f5874341

View File

@ -205,79 +205,104 @@ implementation
href : treference; href : treference;
hregister : tregister; hregister : tregister;
l1,l2 : tasmlabel; l1,l2 : tasmlabel;
signtested : boolean;
begin begin
location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def)); {
if use_sse(resulttype.def) then
begin
{ We need to load from a reference } end
location_force_mem(exprasmlist,left.location); else
}
begin
location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
if (left.location.loc=LOC_REGISTER) and (torddef(left.resulttype.def).typ=u64bit) then
begin
{$ifdef cpu64bit}
emit_const_reg(A_BT,S_Q,63,left.location.register);
{$else cpu64bit}
emit_const_reg(A_BT,S_L,31,left.location.register64.reghi);
{$endif cpu64bit}
signtested:=true;
end
else
signtested:=false;
{ We need to load from a reference }
location_force_mem(exprasmlist,left.location);
{ For u32bit we need to load it as comp and need to { For u32bit we need to load it as comp and need to
make it 64bits } make it 64bits }
if (torddef(left.resulttype.def).typ=u32bit) then if (torddef(left.resulttype.def).typ=u32bit) then
begin begin
tg.GetTemp(exprasmlist,8,tt_normal,href); tg.GetTemp(exprasmlist,8,tt_normal,href);
location_release(exprasmlist,left.location); location_release(exprasmlist,left.location);
location_freetemp(exprasmlist,left.location); location_freetemp(exprasmlist,left.location);
cg.a_load_ref_ref(exprasmlist,left.location.size,OS_32,left.location.reference,href); cg.a_load_ref_ref(exprasmlist,left.location.size,OS_32,left.location.reference,href);
inc(href.offset,4); inc(href.offset,4);
cg.a_load_const_ref(exprasmlist,OS_32,0,href); cg.a_load_const_ref(exprasmlist,OS_32,0,href);
dec(href.offset,4); dec(href.offset,4);
left.location.reference:=href; left.location.reference:=href;
end; end;
{ Load from reference to fpu reg } { Load from reference to fpu reg }
location_release(exprasmlist,left.location); location_release(exprasmlist,left.location);
case torddef(left.resulttype.def).typ of case torddef(left.resulttype.def).typ of
u32bit, u32bit,
scurrency, scurrency,
s64bit: s64bit:
exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
u64bit:
begin
{ unsigned 64 bit ints are harder to handle: }
{ we load bits 0..62 and then check bit 63: }
{ if it is 1 then we add $80000000 000000000 }
{ as double }
inc(left.location.reference.offset,4);
hregister:=cg.getintregister(exprasmlist,OS_32);
cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,left.location.reference,hregister);
emit_const_ref(A_AND,S_L,$7fffffff,left.location.reference);
emit_const_reg(A_TEST,S_L,longint($80000000),hregister);
cg.ungetregister(exprasmlist,hregister);
dec(left.location.reference.offset,4);
exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference)); exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
objectlibrary.getdatalabel(l1); u64bit:
objectlibrary.getlabel(l2); begin
cg.a_jmp_flags(exprasmlist,F_E,l2); { unsigned 64 bit ints are harder to handle:
Consts.concat(Tai_label.Create(l1)); we load bits 0..62 and then check bit 63:
{ I got this constant from a test progtram (FK) } if it is 1 then we add $80000000 000000000
Consts.concat(Tai_const.Create_32bit(0)); as double }
Consts.concat(Tai_const.Create_32bit(1138753536)); objectlibrary.getdatalabel(l1);
reference_reset_symbol(href,l1,0); objectlibrary.getlabel(l2);
emit_ref(A_FADD,S_FL,href);
cg.a_label(exprasmlist,l2); if not(signtested) then
end begin
else inc(left.location.reference.offset,4);
begin emit_const_ref(A_BT,S_L,31,left.location.reference);
if left.resulttype.def.size<4 then dec(left.location.reference.offset,4);
begin end;
tg.GetTemp(exprasmlist,4,tt_normal,href);
location_freetemp(exprasmlist,left.location); exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
cg.a_load_ref_ref(exprasmlist,left.location.size,OS_32,left.location.reference,href); cg.a_jmp_flags(exprasmlist,F_NC,l2);
left.location.reference:=href; Consts.concat(Tai_label.Create(l1));
end; { I got this constant from a test program (FK) }
exprasmlist.concat(taicpu.op_ref(A_FILD,S_IL,left.location.reference)); Consts.concat(Tai_const.Create_32bit(0));
end; Consts.concat(Tai_const.Create_32bit(1138753536));
end; reference_reset_symbol(href,l1,0);
location_freetemp(exprasmlist,left.location); exprasmList.concat(Taicpu.Op_ref(A_FADD,S_FL,href));
tcgx86(cg).inc_fpu_stack; cg.a_label(exprasmlist,l2);
location.register:=NR_ST; end
else
begin
if left.resulttype.def.size<4 then
begin
tg.GetTemp(exprasmlist,4,tt_normal,href);
location_freetemp(exprasmlist,left.location);
cg.a_load_ref_ref(exprasmlist,left.location.size,OS_32,left.location.reference,href);
left.location.reference:=href;
end;
exprasmlist.concat(taicpu.op_ref(A_FILD,S_IL,left.location.reference));
end;
end;
location_freetemp(exprasmlist,left.location);
tcgx86(cg).inc_fpu_stack;
location.register:=NR_ST;
end;
end; end;
end. end.
{ {
$Log$ $Log$
Revision 1.10 2004-02-27 10:21:06 florian Revision 1.11 2004-05-10 20:57:45 florian
* fixed qword -> <real> type cast
Revision 1.10 2004/02/27 10:21:06 florian
* top_symbol killed * top_symbol killed
+ refaddr to treference added + refaddr to treference added
+ refsymbol to treference added + refsymbol to treference added