mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 22:14:25 +02:00
* MIPS: overflow checking added in r24445 works only when source and destination of operation are different registers. Fixed cases of operations on same register.
git-svn-id: trunk@24507 -
This commit is contained in:
parent
2ec85e9705
commit
bfd7401541
@ -862,6 +862,8 @@ procedure TCGMIPS.overflowcheck_internal(list: tasmlist; arg1, arg2: tregister);
|
|||||||
var
|
var
|
||||||
carry, hreg: tregister;
|
carry, hreg: tregister;
|
||||||
begin
|
begin
|
||||||
|
if (arg1=arg2) then
|
||||||
|
InternalError(2013050501);
|
||||||
carry:=GetIntRegister(list,OS_INT);
|
carry:=GetIntRegister(list,OS_INT);
|
||||||
hreg:=GetIntRegister(list,OS_INT);
|
hreg:=GetIntRegister(list,OS_INT);
|
||||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU,carry,arg1,arg2));
|
list.concat(taicpu.op_reg_reg_reg(A_SLTU,carry,arg1,arg2));
|
||||||
@ -945,6 +947,10 @@ begin
|
|||||||
ovloc.loc := LOC_VOID;
|
ovloc.loc := LOC_VOID;
|
||||||
optimize_op_const(op,a);
|
optimize_op_const(op,a);
|
||||||
signed:=(size in [OS_S8,OS_S16,OS_S32]);
|
signed:=(size in [OS_S8,OS_S16,OS_S32]);
|
||||||
|
if (setflags and (not signed) and (src=dst) and (op in [OP_ADD,OP_SUB])) then
|
||||||
|
hreg:=GetIntRegister(list,OS_INT)
|
||||||
|
else
|
||||||
|
hreg:=dst;
|
||||||
case op of
|
case op of
|
||||||
OP_NONE:
|
OP_NONE:
|
||||||
a_load_reg_reg(list,size,size,src,dst);
|
a_load_reg_reg(list,size,size,src,dst);
|
||||||
@ -954,16 +960,19 @@ begin
|
|||||||
|
|
||||||
OP_ADD:
|
OP_ADD:
|
||||||
begin
|
begin
|
||||||
handle_reg_const_reg(list,ops_add[setflags and signed],src,a,dst);
|
handle_reg_const_reg(list,ops_add[setflags and signed],src,a,hreg);
|
||||||
if setflags and (not signed) then
|
if setflags and (not signed) then
|
||||||
overflowcheck_internal(list,dst,src);
|
overflowcheck_internal(list,hreg,src);
|
||||||
|
{ does nothing if hreg=dst }
|
||||||
|
a_load_reg_reg(list,OS_INT,OS_INT,hreg,dst);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
OP_SUB:
|
OP_SUB:
|
||||||
begin
|
begin
|
||||||
handle_reg_const_reg(list,ops_sub[setflags and signed],src,a,dst);
|
handle_reg_const_reg(list,ops_sub[setflags and signed],src,a,hreg);
|
||||||
if setflags and (not signed) then
|
if setflags and (not signed) then
|
||||||
overflowcheck_internal(list,src,dst);
|
overflowcheck_internal(list,src,hreg);
|
||||||
|
a_load_reg_reg(list,OS_INT,OS_INT,hreg,dst);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
OP_MUL,OP_IMUL:
|
OP_MUL,OP_IMUL:
|
||||||
@ -1009,21 +1018,28 @@ end;
|
|||||||
procedure TCGMIPS.a_op_reg_reg_reg_checkoverflow(list: tasmlist; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation);
|
procedure TCGMIPS.a_op_reg_reg_reg_checkoverflow(list: tasmlist; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation);
|
||||||
var
|
var
|
||||||
signed: boolean;
|
signed: boolean;
|
||||||
|
hreg: TRegister;
|
||||||
begin
|
begin
|
||||||
ovloc.loc := LOC_VOID;
|
ovloc.loc := LOC_VOID;
|
||||||
signed:=(size in [OS_S8,OS_S16,OS_S32]);
|
signed:=(size in [OS_S8,OS_S16,OS_S32]);
|
||||||
|
if (setflags and (not signed) and (src2=dst) and (op in [OP_ADD,OP_SUB])) then
|
||||||
|
hreg:=GetIntRegister(list,OS_INT)
|
||||||
|
else
|
||||||
|
hreg:=dst;
|
||||||
case op of
|
case op of
|
||||||
OP_ADD:
|
OP_ADD:
|
||||||
begin
|
begin
|
||||||
list.concat(taicpu.op_reg_reg_reg(ops_add[setflags and signed], dst, src2, src1));
|
list.concat(taicpu.op_reg_reg_reg(ops_add[setflags and signed], hreg, src2, src1));
|
||||||
if setflags and (not signed) then
|
if setflags and (not signed) then
|
||||||
overflowcheck_internal(list, dst, src2);
|
overflowcheck_internal(list, hreg, src2);
|
||||||
|
a_load_reg_reg(list, OS_INT, OS_INT, hreg, dst);
|
||||||
end;
|
end;
|
||||||
OP_SUB:
|
OP_SUB:
|
||||||
begin
|
begin
|
||||||
list.concat(taicpu.op_reg_reg_reg(ops_sub[setflags and signed], dst, src2, src1));
|
list.concat(taicpu.op_reg_reg_reg(ops_sub[setflags and signed], hreg, src2, src1));
|
||||||
if setflags and (not signed) then
|
if setflags and (not signed) then
|
||||||
overflowcheck_internal(list, src2, dst);
|
overflowcheck_internal(list, src2, hreg);
|
||||||
|
a_load_reg_reg(list, OS_INT, OS_INT, hreg, dst);
|
||||||
end;
|
end;
|
||||||
OP_MUL,OP_IMUL:
|
OP_MUL,OP_IMUL:
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user