mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-06 07:30:54 +02:00
* qword/int64 multiplication fixed
+ qword/int64 subtraction
This commit is contained in:
parent
6b33f4d87d
commit
59c6d9f289
@ -583,6 +583,7 @@ implementation
|
||||
mmxbase : tmmxtype;
|
||||
{$endif SUPPORT_MMX}
|
||||
pushedreg : tpushed;
|
||||
hloc : tlocation;
|
||||
|
||||
begin
|
||||
{ to make it more readable, string and set (not smallset!) have their
|
||||
@ -1451,7 +1452,9 @@ implementation
|
||||
|
||||
if p^.treetype=muln then
|
||||
begin
|
||||
release_qword_loc(p^.left^.location);
|
||||
{ save p^.lcoation, because we change it now }
|
||||
set_location(hloc,p^.location);
|
||||
release_qword_loc(p^.location);
|
||||
release_qword_loc(p^.right^.location);
|
||||
p^.location.registerlow:=getexplicitregister32(R_EAX);
|
||||
p^.location.registerhigh:=getexplicitregister32(R_EDX);
|
||||
@ -1462,7 +1465,12 @@ implementation
|
||||
push_int(1)
|
||||
else
|
||||
push_int(0);
|
||||
emit_pushq_loc(p^.left^.location);
|
||||
{ the left operand is in hloc, because the
|
||||
location of left is p^.location but p^.location
|
||||
is already destroyed
|
||||
}
|
||||
emit_pushq_loc(hloc);
|
||||
clear_location(hloc);
|
||||
emit_pushq_loc(p^.right^.location);
|
||||
if porddef(p^.resulttype)^.typ=u64bit then
|
||||
emitcall('FPC_MUL_QWORD',true)
|
||||
@ -1555,7 +1563,7 @@ implementation
|
||||
{ and p^.location.register should be a valid register }
|
||||
{ containing the left result }
|
||||
|
||||
if p^.right^.location.loc<>LOC_REGISTER then
|
||||
if p^.right^.location.loc<>LOC_REGISTER then
|
||||
begin
|
||||
if (p^.treetype=subn) and p^.swaped then
|
||||
begin
|
||||
@ -1564,13 +1572,25 @@ implementation
|
||||
emit_reg_reg(A_MOV,opsize,p^.right^.location.register,R_EDI);
|
||||
emit_reg_reg(op,opsize,p^.location.register,R_EDI);
|
||||
emit_reg_reg(A_MOV,opsize,R_EDI,p^.location.register);
|
||||
emit_reg_reg(A_MOV,opsize,p^.right^.location.registerhigh,R_EDI);
|
||||
{ the carry flag is still ok }
|
||||
emit_reg_reg(op2,opsize,p^.location.registerhigh,R_EDI);
|
||||
emit_reg_reg(A_MOV,opsize,R_EDI,p^.location.registerhigh);
|
||||
end
|
||||
else
|
||||
begin
|
||||
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,opsize,
|
||||
newreference(p^.right^.location.reference),R_EDI)));
|
||||
exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,p^.location.register,R_EDI)));
|
||||
exprasmlist^.concat(new(pai386,op_reg_reg(A_MOV,opsize,R_EDI,p^.location.register)));
|
||||
exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,p^.location.registerlow,R_EDI)));
|
||||
exprasmlist^.concat(new(pai386,op_reg_reg(A_MOV,opsize,R_EDI,p^.location.registerlow)));
|
||||
hr:=newreference(p^.right^.location.reference);
|
||||
inc(hr^.offset,4);
|
||||
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,opsize,
|
||||
hr,R_EDI)));
|
||||
{ here the carry flag is still preserved }
|
||||
exprasmlist^.concat(new(pai386,op_reg_reg(op2,opsize,p^.location.registerhigh,R_EDI)));
|
||||
exprasmlist^.concat(new(pai386,op_reg_reg(A_MOV,opsize,R_EDI,
|
||||
p^.location.registerhigh)));
|
||||
ungetiftemp(p^.right^.location.reference);
|
||||
del_reference(p^.right^.location.reference);
|
||||
end;
|
||||
@ -1653,12 +1673,16 @@ implementation
|
||||
{ when swapped another result register }
|
||||
if (p^.treetype=subn) and p^.swaped then
|
||||
begin
|
||||
exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,
|
||||
p^.location.register,p^.right^.location.register)));
|
||||
swap_location(p^.location,p^.right^.location);
|
||||
{ newly swapped also set swapped flag }
|
||||
{ just to maintain ordering }
|
||||
p^.swaped:=not(p^.swaped);
|
||||
exprasmlist^.concat(new(pai386,op_reg_reg(op,S_L,
|
||||
p^.location.registerlow,
|
||||
p^.right^.location.registerlow)));
|
||||
exprasmlist^.concat(new(pai386,op_reg_reg(op2,S_L,
|
||||
p^.location.registerhigh,
|
||||
p^.right^.location.registerhigh)));
|
||||
swap_location(p^.location,p^.right^.location);
|
||||
{ newly swapped also set swapped flag }
|
||||
{ just to maintain ordering }
|
||||
p^.swaped:=not(p^.swaped);
|
||||
end
|
||||
else if cmpop then
|
||||
begin
|
||||
@ -2029,7 +2053,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.59 1999-05-19 10:31:53 florian
|
||||
Revision 1.60 1999-05-23 19:55:10 florian
|
||||
* qword/int64 multiplication fixed
|
||||
+ qword/int64 subtraction
|
||||
|
||||
Revision 1.59 1999/05/19 10:31:53 florian
|
||||
* two bugs reported by Romio (bugs 13) are fixed:
|
||||
- empty array constructors are now handled correctly (e.g. for sysutils.format)
|
||||
- comparsion of ansistrings was sometimes coded wrong
|
||||
|
@ -92,53 +92,60 @@ implementation
|
||||
floatstore(PFloatDef(dest^.resulttype)^.typ,dest^.location.reference);
|
||||
orddef:
|
||||
begin
|
||||
Case dest^.resulttype^.size of
|
||||
1 : hreg:=regtoreg8(accumulator);
|
||||
2 : hreg:=regtoreg16(accumulator);
|
||||
4 : hreg:=accumulator;
|
||||
End;
|
||||
emit_mov_reg_loc(hreg,dest^.location);
|
||||
If (cs_check_range in aktlocalswitches) and
|
||||
{no need to rangecheck longints or cardinals on 32bit processors}
|
||||
not((porddef(dest^.resulttype)^.typ = s32bit) and
|
||||
(porddef(dest^.resulttype)^.low = $80000000) and
|
||||
(porddef(dest^.resulttype)^.high = $7fffffff)) and
|
||||
not((porddef(dest^.resulttype)^.typ = u32bit) and
|
||||
(porddef(dest^.resulttype)^.low = 0) and
|
||||
(porddef(dest^.resulttype)^.high = $ffffffff)) then
|
||||
Begin
|
||||
{do not register this temporary def}
|
||||
OldRegisterDef := RegisterDef;
|
||||
RegisterDef := False;
|
||||
hdef:=nil;
|
||||
Case PordDef(dest^.resulttype)^.typ of
|
||||
u8bit,u16bit,u32bit:
|
||||
begin
|
||||
new(hdef,init(u32bit,0,$ffffffff));
|
||||
hreg:=accumulator;
|
||||
end;
|
||||
s8bit,s16bit,s32bit:
|
||||
begin
|
||||
new(hdef,init(s32bit,$80000000,$7fffffff));
|
||||
hreg:=accumulator;
|
||||
end;
|
||||
end;
|
||||
{ create a fake node }
|
||||
hp := genzeronode(nothingn);
|
||||
hp^.location.loc := LOC_REGISTER;
|
||||
hp^.location.register := hreg;
|
||||
if assigned(hdef) then
|
||||
hp^.resulttype:=hdef
|
||||
else
|
||||
hp^.resulttype:=dest^.resulttype;
|
||||
{ emit the range check }
|
||||
emitrangecheck(hp,dest^.resulttype);
|
||||
hp^.right := nil;
|
||||
if assigned(hdef) then
|
||||
Dispose(hdef, Done);
|
||||
RegisterDef := OldRegisterDef;
|
||||
disposetree(hp);
|
||||
End;
|
||||
if porddef(dest^.resulttype)^.typ in [u64bit,s64bitint] then
|
||||
begin
|
||||
emit_movq_reg_loc(R_EDX,R_EAX,dest^.location);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Case dest^.resulttype^.size of
|
||||
1 : hreg:=regtoreg8(accumulator);
|
||||
2 : hreg:=regtoreg16(accumulator);
|
||||
4 : hreg:=accumulator;
|
||||
End;
|
||||
emit_mov_reg_loc(hreg,dest^.location);
|
||||
If (cs_check_range in aktlocalswitches) and
|
||||
{no need to rangecheck longints or cardinals on 32bit processors}
|
||||
not((porddef(dest^.resulttype)^.typ = s32bit) and
|
||||
(porddef(dest^.resulttype)^.low = $80000000) and
|
||||
(porddef(dest^.resulttype)^.high = $7fffffff)) and
|
||||
not((porddef(dest^.resulttype)^.typ = u32bit) and
|
||||
(porddef(dest^.resulttype)^.low = 0) and
|
||||
(porddef(dest^.resulttype)^.high = $ffffffff)) then
|
||||
Begin
|
||||
{do not register this temporary def}
|
||||
OldRegisterDef := RegisterDef;
|
||||
RegisterDef := False;
|
||||
hdef:=nil;
|
||||
Case PordDef(dest^.resulttype)^.typ of
|
||||
u8bit,u16bit,u32bit:
|
||||
begin
|
||||
new(hdef,init(u32bit,0,$ffffffff));
|
||||
hreg:=accumulator;
|
||||
end;
|
||||
s8bit,s16bit,s32bit:
|
||||
begin
|
||||
new(hdef,init(s32bit,$80000000,$7fffffff));
|
||||
hreg:=accumulator;
|
||||
end;
|
||||
end;
|
||||
{ create a fake node }
|
||||
hp := genzeronode(nothingn);
|
||||
hp^.location.loc := LOC_REGISTER;
|
||||
hp^.location.register := hreg;
|
||||
if assigned(hdef) then
|
||||
hp^.resulttype:=hdef
|
||||
else
|
||||
hp^.resulttype:=dest^.resulttype;
|
||||
{ emit the range check }
|
||||
emitrangecheck(hp,dest^.resulttype);
|
||||
hp^.right := nil;
|
||||
if assigned(hdef) then
|
||||
Dispose(hdef, Done);
|
||||
RegisterDef := OldRegisterDef;
|
||||
disposetree(hp);
|
||||
End;
|
||||
end;
|
||||
End;
|
||||
else
|
||||
internalerror(66766766);
|
||||
@ -1240,7 +1247,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.53 1999-05-23 18:42:01 florian
|
||||
Revision 1.54 1999-05-23 19:55:11 florian
|
||||
* qword/int64 multiplication fixed
|
||||
+ qword/int64 subtraction
|
||||
|
||||
Revision 1.53 1999/05/23 18:42:01 florian
|
||||
* better error recovering in typed constants
|
||||
* some problems with arrays of const fixed, some problems
|
||||
due my previous
|
||||
|
Loading…
Reference in New Issue
Block a user