+ qword/int64 -> floating point type cast

This commit is contained in:
florian 1999-07-04 16:37:08 +00:00
parent f29122d706
commit f011b3bdca
2 changed files with 83 additions and 23 deletions

View File

@ -590,9 +590,12 @@ implementation
procedure second_int_to_real(pto,pfrom : ptree;convtyp : tconverttype);
var
r : preference;
hregister : tregister;
hregister,hregister2 : tregister;
l1,l2 : pasmlabel;
begin
{ for u32bit a solution is to push $0 and to load a comp }
{ does this first, it destroys maybe EDI }
@ -608,7 +611,12 @@ implementation
s16bit : exprasmlist^.concat(new(pai386,op_reg_reg(A_MOVSX,S_WL,pfrom^.location.register,R_EDI)));
u16bit : exprasmlist^.concat(new(pai386,op_reg_reg(A_MOVZX,S_WL,pfrom^.location.register,R_EDI)));
u32bit,s32bit:
hregister:=pfrom^.location.register
hregister:=pfrom^.location.register;
u64bit,s64bitint:
begin
exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_L,pfrom^.location.registerhigh)));
hregister:=pfrom^.location.registerlow;
end;
end;
ungetregister(pfrom^.location.register);
end
@ -616,27 +624,74 @@ implementation
begin
r:=newreference(pfrom^.location.reference);
case porddef(pfrom^.resulttype)^.typ of
s8bit : exprasmlist^.concat(new(pai386,op_ref_reg(A_MOVSX,S_BL,r,R_EDI)));
u8bit : exprasmlist^.concat(new(pai386,op_ref_reg(A_MOVZX,S_BL,r,R_EDI)));
s16bit : exprasmlist^.concat(new(pai386,op_ref_reg(A_MOVSX,S_WL,r,R_EDI)));
u16bit : exprasmlist^.concat(new(pai386,op_ref_reg(A_MOVZX,S_WL,r,R_EDI)));
u32bit,s32bit : exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,r,R_EDI)));
s8bit:
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOVSX,S_BL,r,R_EDI)));
u8bit:
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOVZX,S_BL,r,R_EDI)));
s16bit:
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOVSX,S_WL,r,R_EDI)));
u16bit:
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOVZX,S_WL,r,R_EDI)));
u32bit,s32bit:
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,r,R_EDI)));
u64bit,s64bitint:
begin
inc(r^.offset,4);
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,r,R_EDI)));
exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_L,R_EDI)));
r:=newreference(pfrom^.location.reference);
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,r,R_EDI)));
end;
end;
del_reference(pfrom^.location.reference);
ungetiftemp(pfrom^.location.reference);
end;
exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_L,hregister)));
r:=new_reference(R_ESP,0);
if porddef(pfrom^.resulttype)^.typ=u32bit then
exprasmlist^.concat(new(pai386,op_ref(A_FILD,S_IQ,r)))
else
exprasmlist^.concat(new(pai386,op_ref(A_FILD,S_IL,r)));
{ better than an add on all processors }
if porddef(pfrom^.resulttype)^.typ=u32bit then
exprasmlist^.concat(new(pai386,op_const_reg(A_ADD,S_L,8,R_ESP)))
else
exprasmlist^.concat(new(pai386,op_reg(A_POP,S_L,R_EDI)));
end;
{ for 64 bit integers, the high dword is already pushed }
exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_L,hregister)));
r:=new_reference(R_ESP,0);
case porddef(pfrom^.resulttype)^.typ of
u32bit:
begin
exprasmlist^.concat(new(pai386,op_ref(A_FILD,S_IQ,r)));
exprasmlist^.concat(new(pai386,op_const_reg(A_ADD,S_L,8,R_ESP)));
end;
s64bitint:
begin
exprasmlist^.concat(new(pai386,op_ref(A_FILD,S_IQ,r)));
exprasmlist^.concat(new(pai386,op_const_reg(A_ADD,S_L,8,R_ESP)));
end;
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(r^.offset,4);
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,r,R_EDI)));
r:=new_reference(R_ESP,4);
exprasmlist^.concat(new(pai386,op_const_ref(A_AND,S_L,$7fffffff,r)));
exprasmlist^.concat(new(pai386,op_const_reg(A_AND,S_L,$80000000,R_EDI)));
r:=new_reference(R_ESP,0);
exprasmlist^.concat(new(pai386,op_ref(A_FILD,S_IQ,r)));
getdatalabel(l1);
getlabel(l2);
emitjmp(C_Z,l2);
consts^.concat(new(pai_label,init(l1)));
{ I got this constant from a test progtram (FK) }
consts^.concat(new(pai_const,init_32bit(0)));
consts^.concat(new(pai_const,init_32bit(1138753536)));
r:=new_reference(R_NO,0);
r^.symbol:=l1;
exprasmlist^.concat(new(pai386,op_ref(A_FADD,S_FL,r)));
emitlab(l2);
exprasmlist^.concat(new(pai386,op_const_reg(A_ADD,S_L,8,R_ESP)));
end
else
begin
exprasmlist^.concat(new(pai386,op_ref(A_FILD,S_IL,r)));
exprasmlist^.concat(new(pai386,op_reg(A_POP,S_L,R_EDI)));
end;
end;
clear_location(pto^.location);
pto^.location.loc:=LOC_FPU;
@ -1337,7 +1392,10 @@ implementation
end.
{
$Log$
Revision 1.76 1999-06-28 22:29:10 florian
Revision 1.77 1999-07-04 16:37:08 florian
+ qword/int64 -> floating point type cast
Revision 1.76 1999/06/28 22:29:10 florian
* qword division fixed
+ code for qword/int64 type casting added:
range checking isn't implemented yet

View File

@ -62,8 +62,10 @@ compiler version and your short cut.
- case
- for
- inc/dec
- read/write
- val/str
- read
- write ................................................. 0.99.13 (FK)
- str ................................................... 0.99.13 (FK)
- val
- range checking
- type cast QWord -> real
- lo/hi testing ......................................... 0.99.13 (FK)