* fixed usigned overflow checking

This commit is contained in:
Jonas Maebe 2003-12-08 21:18:44 +00:00
parent fd8625f3eb
commit e4312930d1

View File

@ -55,7 +55,7 @@ interface
symconst,symdef,paramgr,
aasmbase,aasmtai,aasmcpu,defutil,htypechk,
cgbase,cpuinfo,pass_1,pass_2,regvars,
cpupara,
cpupara,cgcpu,
ncon,nset,
ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32;
@ -1022,24 +1022,47 @@ interface
end
else
begin
case nodetype of
addn:
begin
op1 := A_ADDC;
op2 := A_ADDEO_;
if is_signed(resulttype.def) then
begin
case nodetype of
addn:
begin
op1 := A_ADDC;
op2 := A_ADDEO;
end;
subn:
begin
op1 := A_SUBC;
op2 := A_SUBFEO;
end;
else
internalerror(2002072806);
end
end
else
begin
case nodetype of
addn:
begin
op1 := A_ADDC;
op2 := A_ADDE;
end;
subn:
begin
op1 := A_SUBC;
op2 := A_SUBFE;
end;
end;
subn:
begin
op1 := A_SUBC;
op2 := A_SUBFEO_;
end;
else
internalerror(2002072806);
end;
end;
exprasmlist.concat(taicpu.op_reg_reg_reg(op1,location.registerlow,
left.location.registerlow,right.location.registerlow));
exprasmlist.concat(taicpu.op_reg_reg_reg(op2,location.registerhigh,
right.location.registerhigh,left.location.registerhigh));
if not(is_signed(resulttype.def)) then
if nodetype = addn then
exprasmlist.concat(taicpu.op_reg_reg(A_CMPLW,location.registerhigh,left.location.registerhigh))
else
exprasmlist.concat(taicpu.op_reg_reg(A_CMPLW,left.location.registerhigh,location.registerhigh));
cg.g_overflowcheck(exprasmlist,location,resulttype.def);
end;
@ -1249,10 +1272,11 @@ interface
{ is also being used for xor, and "mul", "sub, or and comparative }
{ operators }
var
cmpop : boolean;
cgop : topcg;
op : tasmop;
tmpreg : tregister;
hl : tasmlabel;
cmpop : boolean;
{ true, if unsigned types are compared }
unsigned : boolean;
@ -1407,19 +1431,54 @@ interface
else
// overflow checking is on and we have an addn, subn or muln
begin
case nodetype of
addn:
op := A_ADDO_;
subn:
op := A_SUBO_;
muln:
op := A_MULLWO_;
else
internalerror(2002072601);
end;
exprasmlist.concat(taicpu.op_reg_reg_reg(op,location.register,
left.location.register,right.location.register));
cg.g_overflowcheck(exprasmlist,location,resulttype.def);
if is_signed(resulttype.def) then
begin
case nodetype of
addn:
op := A_ADDO;
subn:
op := A_SUBO;
muln:
op := A_MULLWO;
else
internalerror(2002072601);
end;
exprasmlist.concat(taicpu.op_reg_reg_reg(op,location.register,
left.location.register,right.location.register));
end
else
begin
case nodetype of
addn:
begin
exprasmlist.concat(taicpu.op_reg_reg_reg(A_ADD,location.register,
left.location.register,right.location.register));
exprasmlist.concat(taicpu.op_reg_reg(A_CMPLW,location.register,left.location.register));
cg.g_overflowcheck(exprasmlist,location,resulttype.def);
end;
subn:
begin
exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUB,location.register,
left.location.register,right.location.register));
exprasmlist.concat(taicpu.op_reg_reg(A_CMPLW,left.location.register,location.register));
cg.g_overflowcheck(exprasmlist,location,resulttype.def);
end;
muln:
begin
{ calculate the upper 32 bits of the product, = 0 if no overflow }
exprasmlist.concat(taicpu.op_reg_reg_reg(A_MULHWU_,location.register,
left.location.register,right.location.register));
{ calculate the real result }
exprasmlist.concat(taicpu.op_reg_reg_reg(A_MULLW,location.register,
left.location.register,right.location.register));
{ g_overflowcheck generates a OC_AE instead of OC_EQ :/ }
objectlibrary.getlabel(hl);
tcgppc(cg).a_jmp_cond(exprasmlist,OC_EQ,hl);
cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
cg.a_label(exprasmlist,hl);
end;
end;
end;
end;
release_reg_left_right;
@ -1430,7 +1489,10 @@ begin
end.
{
$Log$
Revision 1.38 2003-10-17 14:52:07 peter
Revision 1.39 2003-12-08 21:18:44 jonas
* fixed usigned overflow checking
Revision 1.38 2003/10/17 14:52:07 peter
* fixed ppc build
Revision 1.37 2003/10/17 01:22:08 florian