* some bugs in the qword code generation fixed

This commit is contained in:
florian 1999-05-25 20:36:11 +00:00
parent 6e032e30d5
commit 8d99f7a098
2 changed files with 170 additions and 30 deletions

View File

@ -585,6 +585,70 @@ implementation
pushedreg : tpushed;
hloc : tlocation;
procedure firstjmp64bitcmp;
var
oldtreetype : ttreetyp;
begin
{ the jump the sequence is a little bit hairy }
case p^.treetype of
ltn,gtn:
begin
emitjmp(flag_2_cond[getresflags(p,unsigned)],truelabel);
{ cheat a little bit for the negative test }
p^.swaped:=not(p^.swaped);
emitjmp(flag_2_cond[getresflags(p,unsigned)],falselabel);
p^.swaped:=not(p^.swaped);
end;
lten,gten:
begin
oldtreetype:=p^.treetype;
if p^.treetype=lten then
p^.treetype:=ltn
else
p^.treetype:=gtn;
emitjmp(flag_2_cond[getresflags(p,unsigned)],truelabel);
{ cheat for the negative test }
if p^.treetype=ltn then
p^.treetype:=gtn
else
p^.treetype:=ltn;
emitjmp(flag_2_cond[getresflags(p,unsigned)],falselabel);
p^.treetype:=oldtreetype;
end;
equaln:
emitjmp(C_NE,falselabel);
unequaln:
emitjmp(C_NE,truelabel);
end;
end;
procedure secondjmp64bitcmp;
begin
{ the jump the sequence is a little bit hairy }
case p^.treetype of
ltn,gtn,lten,gten:
begin
{ the comparisaion of the low dword have to be }
{ always unsigned! }
emitjmp(flag_2_cond[getresflags(p,true)],truelabel);
emitjmp(C_None,falselabel);
end;
equaln:
begin
emitjmp(C_NE,falselabel);
emitjmp(C_None,truelabel);
end;
unequaln:
begin
emitjmp(C_NE,truelabel);
emitjmp(C_None,falselabel);
end;
end;
end;
begin
{ to make it more readable, string and set (not smallset!) have their
own procedures }
@ -1601,27 +1665,23 @@ implementation
begin
emit_reg_reg(A_CMP,S_L,p^.right^.location.registerhigh,
p^.location.registerhigh);
emitjmp(flag_2_cond[getresflags(p,unsigned)],truelabel);
firstjmp64bitcmp;
emit_reg_reg(A_CMP,S_L,p^.right^.location.registerlow,
p^.location.registerlow);
emitjmp(flag_2_cond[getresflags(p,unsigned)],truelabel);
emitjmp(C_None,falselabel);
secondjmp64bitcmp;
end
else
begin
hr:=newreference(p^.right^.location.reference);
inc(hr^.offset,4);
exprasmlist^.concat(new(pai386,op_ref_reg(A_CMP,S_L,
hr,p^.location.registerhigh)));
emitjmp(flag_2_cond[getresflags(p,unsigned)],truelabel);
firstjmp64bitcmp;
exprasmlist^.concat(new(pai386,op_ref_reg(A_CMP,S_L,newreference(
p^.right^.location.reference),p^.location.registerlow)));
emitjmp(flag_2_cond[getresflags(p,unsigned)],truelabel);
emitjmp(C_None,falselabel);
secondjmp64bitcmp;
ungetiftemp(p^.right^.location.reference);
del_reference(p^.right^.location.reference);
@ -1689,12 +1749,11 @@ implementation
exprasmlist^.concat(new(pai386,op_reg_reg(A_CMP,S_L,
p^.right^.location.registerhigh,
p^.location.registerhigh)));
emitjmp(flag_2_cond[getresflags(p,unsigned)],truelabel);
firstjmp64bitcmp;
exprasmlist^.concat(new(pai386,op_reg_reg(A_CMP,S_L,
p^.right^.location.registerlow,
p^.location.registerlow)));
emitjmp(flag_2_cond[getresflags(p,unsigned)],truelabel);
emitjmp(C_None,falselabel);
secondjmp64bitcmp;
end
else
begin
@ -2053,7 +2112,10 @@ implementation
end.
{
$Log$
Revision 1.60 1999-05-23 19:55:10 florian
Revision 1.61 1999-05-25 20:36:11 florian
* some bugs in the qword code generation fixed
Revision 1.60 1999/05/23 19:55:10 florian
* qword/int64 multiplication fixed
+ qword/int64 subtraction

View File

@ -244,6 +244,7 @@ implementation
pushed,popecx : boolean;
op : tasmop;
hr : preference;
l1,l2,l3 : plabel;
begin
popecx:=false;
@ -256,7 +257,7 @@ implementation
if is_64bitint(p^.left^.resulttype) then
begin
{ load left operators in a register }
{ load left operator in a register }
if p^.left^.location.loc<>LOC_REGISTER then
begin
if p^.left^.location.loc=LOC_CREGISTER then
@ -290,23 +291,46 @@ implementation
{ shifting by a constant directly coded: }
if (p^.right^.treetype=ordconstn) then
begin
if p^.treetype=shln then
{ shrd/shl works only for values <=31 !! }
if p^.right^.value>31 then
begin
exprasmlist^.concat(new(pai386,op_const_reg_reg(A_SHLD,S_L,p^.right^.location.reference.offset and 31,
hregisterlow,hregisterhigh)));
exprasmlist^.concat(new(pai386,op_const_reg(A_SHL,S_L,p^.right^.location.reference.offset and 31,
hregisterlow)));
if p^.treetype=shln then
begin
exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,hregisterhigh,
hregisterhigh)));
exprasmlist^.concat(new(pai386,op_const_reg(A_SHL,S_L,p^.right^.value and 31,
hregisterlow)));
end
else
begin
exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,hregisterlow,
hregisterlow)));
exprasmlist^.concat(new(pai386,op_const_reg(A_SHR,S_L,p^.right^.value and 31,
hregisterhigh)));
end;
p^.location.registerhigh:=hregisterlow;
p^.location.registerlow:=hregisterhigh;
end
else
begin
exprasmlist^.concat(new(pai386,op_const_reg_reg(A_SHRD,S_L,p^.right^.location.reference.offset and 31,
hregisterhigh,hregisterlow)));
exprasmlist^.concat(new(pai386,op_const_reg(A_SHR,S_L,p^.right^.location.reference.offset and 31,
hregisterhigh)));
if p^.treetype=shln then
begin
exprasmlist^.concat(new(pai386,op_const_reg_reg(A_SHLD,S_L,p^.right^.value and 31,
hregisterlow,hregisterhigh)));
exprasmlist^.concat(new(pai386,op_const_reg(A_SHL,S_L,p^.right^.value and 31,
hregisterlow)));
end
else
begin
exprasmlist^.concat(new(pai386,op_const_reg_reg(A_SHRD,S_L,p^.right^.value and 31,
hregisterhigh,hregisterlow)));
exprasmlist^.concat(new(pai386,op_const_reg(A_SHR,S_L,p^.right^.value and 31,
hregisterhigh)));
end;
p^.location.registerlow:=hregisterlow;
p^.location.registerhigh:=hregisterhigh;
end;
p^.location.loc:=LOC_REGISTER;
p^.location.registerlow:=hregisterlow;
p^.location.registerhigh:=hregisterhigh;
end
else
begin
@ -364,19 +388,60 @@ implementation
ungetregister32(hregister2);
{ the damned shift instructions work only til a count of 32 }
{ so we've to do some tricks here }
if p^.treetype=shln then
begin
getlabel(l1);
getlabel(l2);
getlabel(l3);
exprasmlist^.concat(new(pai386,op_const_reg(A_CMP,S_L,64,R_ECX)));
emitjmp(C_L,l1);
exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,hregisterlow,hregisterlow)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,hregisterhigh,hregisterhigh)));
emitjmp(C_None,l3);
emitlab(l1);
exprasmlist^.concat(new(pai386,op_const_reg(A_CMP,S_L,32,R_ECX)));
emitjmp(C_L,l2);
exprasmlist^.concat(new(pai386,op_const_reg(A_SUB,S_L,32,R_ECX)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_SHL,S_L,R_CL,
hregisterlow)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_MOV,S_L,hregisterlow,hregisterhigh)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,hregisterlow,hregisterlow)));
emitjmp(C_None,l3);
emitlab(l2);
exprasmlist^.concat(new(pai386,op_reg_reg_reg(A_SHLD,S_L,R_CL,
hregisterlow,hregisterhigh)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_SHL,S_L,R_CL,
hregisterlow)));
emitlab(l3);
end
else
begin
getlabel(l1);
getlabel(l2);
getlabel(l3);
exprasmlist^.concat(new(pai386,op_const_reg(A_CMP,S_L,64,R_ECX)));
emitjmp(C_L,l1);
exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,hregisterlow,hregisterlow)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,hregisterhigh,hregisterhigh)));
emitjmp(C_None,l3);
emitlab(l1);
exprasmlist^.concat(new(pai386,op_const_reg(A_CMP,S_L,32,R_ECX)));
emitjmp(C_L,l2);
exprasmlist^.concat(new(pai386,op_const_reg(A_SUB,S_L,32,R_ECX)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_SHR,S_L,R_CL,
hregisterhigh)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_MOV,S_L,hregisterhigh,hregisterlow)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,hregisterhigh,hregisterhigh)));
emitjmp(C_None,l3);
emitlab(l2);
exprasmlist^.concat(new(pai386,op_reg_reg_reg(A_SHRD,S_L,R_CL,
hregisterhigh,hregisterlow)));
exprasmlist^.concat(new(pai386,op_reg_reg(A_SHR,S_L,R_CL,
hregisterhigh)));
emitlab(l3);
end;
{ maybe put ECX back }
@ -418,8 +483,16 @@ implementation
{ shifting by a constant directly coded: }
if (p^.right^.treetype=ordconstn) then
begin
exprasmlist^.concat(new(pai386,op_const_reg(op,S_L,p^.right^.location.reference.offset and 31,
hregister1)));
{ l shl 32 should 0 imho, but neither TP nor Delphi do it in this way (FK)
if p^.right^.value<=31 then
}
exprasmlist^.concat(new(pai386,op_const_reg(op,S_L,p^.right^.value and 31,
hregister1)));
{
else
exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,hregister1,
hregister1)));
}
p^.location.loc:=LOC_REGISTER;
p^.location.register:=hregister1;
end
@ -817,9 +890,14 @@ implementation
end.
{
$Log$
Revision 1.23 1999-05-08 20:41:08 jonas
+ positive number MOD power of 2 now done with AND instruction
* fix to division of positive numbers by power of 2
Revision 1.24 1999-05-25 20:36:13 florian
* some bugs in the qword code generation fixed
Revision 1.23 1999/05/08 20:41:08 jonas
+ positive number MOD power of 2 now done with AND instruction
* fix to division of positive numbers by power of 2
* the result of a MOD is left in EDX if possible
Revision 1.22 1999/05/01 13:24:11 peter