+ overflow checking for the arm

This commit is contained in:
florian 2005-02-13 18:55:19 +00:00
parent fc8542ad94
commit 22d9294ab3
17 changed files with 663 additions and 330 deletions

View File

@ -62,6 +62,9 @@ uses
{ SFM/LFM }
constructor op_reg_const_ref(op : tasmop;_op1 : tregister;_op2 : aint;_op3 : treference);
{ *M*LL }
constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
{ this is for Jmp instructions }
constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
@ -209,6 +212,17 @@ implementation
end;
constructor taicpu.op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
begin
inherited create(op);
ops:=4;
loadreg(0,_op1);
loadreg(1,_op2);
loadreg(2,_op3);
loadreg(3,_op3);
end;
constructor taicpu.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint);
begin
inherited create(op);
@ -493,7 +507,10 @@ implementation
end.
{
$Log$
Revision 1.36 2004-11-01 17:41:28 florian
Revision 1.37 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.36 2004/11/01 17:41:28 florian
* fixed arm compilation with cgutils
* ...

View File

@ -39,7 +39,7 @@ unit cgcpu;
type
tcgarm = class(tcg)
{ true, if the next arithmetic operation should modify the flags }
setflags : boolean;
cgsetflags : boolean;
procedure init_register_allocators;override;
procedure done_register_allocators;override;
@ -57,6 +57,8 @@ unit cgcpu;
size: tcgsize; a: aint; src, dst: tregister); override;
procedure a_op_reg_reg_reg(list: taasmoutput; op: TOpCg;
size: tcgsize; src1, src2, dst: tregister); override;
procedure a_op_const_reg_reg_checkoverflow(list: taasmoutput; op: TOpCg; size: tcgsize; a: aint; src, dst: tregister;setflags : boolean;var ovloc : tlocation);override;
procedure a_op_reg_reg_reg_checkoverflow(list: taasmoutput; op: TOpCg; size: tcgsize; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation);override;
{ move instructions }
procedure a_load_const_reg(list : taasmoutput; size: tcgsize; a : aint;reg : tregister);override;
@ -88,6 +90,7 @@ unit cgcpu;
procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint);override;
procedure g_overflowcheck(list: taasmoutput; const l: tlocation; def: tdef); override;
procedure g_overflowCheck_loc(List:TAasmOutput;const Loc:TLocation;def:TDef;ovloc : tlocation);override;
procedure g_save_standard_registers(list : taasmoutput);override;
procedure g_restore_standard_registers(list : taasmoutput);override;
@ -100,10 +103,12 @@ unit cgcpu;
end;
tcg64farm = class(tcg64f32)
procedure a_op64_reg_reg(list : taasmoutput;op:TOpCG;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg(list : taasmoutput;op:TOpCG;value : int64;reg : tregister64);override;
procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);override;
procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);override;
procedure a_op64_reg_reg(list : taasmoutput;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);override;
procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);override;
procedure a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
procedure a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
end;
const
@ -301,160 +306,230 @@ unit cgcpu;
end;
const
op_reg_reg_opcg2asmop: array[TOpCG] of tasmop =
(A_NONE,A_ADD,A_AND,A_NONE,A_NONE,A_MUL,A_MUL,A_NONE,A_NONE,A_ORR,
A_NONE,A_NONE,A_NONE,A_SUB,A_EOR);
const
op_reg_reg_opcg2asmop: array[TOpCG] of tasmop =
(A_NONE,A_ADD,A_AND,A_NONE,A_NONE,A_MUL,A_MUL,A_NONE,A_NONE,A_ORR,
A_NONE,A_NONE,A_NONE,A_SUB,A_EOR);
procedure tcgarm.a_op_const_reg_reg(list: taasmoutput; op: TOpCg;
size: tcgsize; a: aint; src, dst: tregister);
var
shift : byte;
tmpreg : tregister;
so : tshifterop;
l1 : longint;
begin
if is_shifter_const(-a,shift) then
case op of
OP_ADD:
procedure tcgarm.a_op_const_reg_reg(list: taasmoutput; op: TOpCg;
size: tcgsize; a: aint; src, dst: tregister);
var
ovloc : tlocation;
begin
a_op_const_reg_reg_checkoverflow(list,op,size,a,src,dst,false,ovloc);
end;
procedure tcgarm.a_op_reg_reg_reg(list: taasmoutput; op: TOpCg;
size: tcgsize; src1, src2, dst: tregister);
var
ovloc : tlocation;
begin
a_op_reg_reg_reg_checkoverflow(list,op,size,src1,src2,dst,false,ovloc);
end;
procedure tcgarm.a_op_const_reg_reg_checkoverflow(list: taasmoutput; op: TOpCg; size: tcgsize; a: aint; src, dst: tregister;setflags : boolean;var ovloc : tlocation);
var
shift : byte;
tmpreg : tregister;
so : tshifterop;
l1 : longint;
begin
ovloc.loc:=LOC_VOID;
if is_shifter_const(-a,shift) then
case op of
OP_ADD:
begin
op:=OP_SUB;
a:=dword(-a);
end;
OP_SUB:
begin
op:=OP_ADD;
a:=dword(-a);
end
end;
if is_shifter_const(a,shift) and not(op in [OP_IMUL,OP_MUL]) then
case op of
OP_NEG,OP_NOT,
OP_DIV,OP_IDIV:
internalerror(200308281);
OP_SHL:
begin
if a>32 then
internalerror(200308291);
if a<>0 then
begin
shifterop_reset(so);
so.shiftmode:=SM_LSL;
so.shiftimm:=a;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so));
end
else
list.concat(taicpu.op_reg_reg(A_MOV,dst,src));
end;
OP_SHR:
begin
if a>32 then
internalerror(200308292);
shifterop_reset(so);
if a<>0 then
begin
so.shiftmode:=SM_LSR;
so.shiftimm:=a;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so));
end
else
list.concat(taicpu.op_reg_reg(A_MOV,dst,src));
end;
OP_SAR:
begin
if a>32 then
internalerror(200308291);
if a<>0 then
begin
shifterop_reset(so);
so.shiftmode:=SM_ASR;
so.shiftimm:=a;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so));
end
else
list.concat(taicpu.op_reg_reg(A_MOV,dst,src));
end;
else
list.concat(setoppostfix(
taicpu.op_reg_reg_const(op_reg_reg_opcg2asmop[op],dst,src,a),toppostfix(ord(cgsetflags or setflags)*ord(PF_S))
));
if (cgsetflags or setflags) and (size in [OS_8,OS_16,OS_32]) then
begin
op:=OP_SUB;
a:=dword(-a);
ovloc.loc:=LOC_FLAGS;
case op of
OP_ADD:
ovloc.resflags:=F_CS;
OP_SUB:
ovloc.resflags:=F_CC;
end;
end;
OP_SUB:
begin
op:=OP_ADD;
a:=dword(-a);
end
end
else
begin
{ there could be added some more sophisticated optimizations }
if (op in [OP_MUL,OP_IMUL]) and (a=1) then
a_load_reg_reg(list,size,size,src,dst)
else if (op in [OP_MUL,OP_IMUL]) and (a=0) then
a_load_const_reg(list,size,0,dst)
else if (op in [OP_IMUL]) and (a=-1) then
a_op_reg_reg(list,OP_NEG,size,src,dst)
{ we do this here instead in the peephole optimizer because
it saves us a register }
else if (op in [OP_MUL,OP_IMUL]) and ispowerof2(a,l1) and not(cgsetflags or setflags) then
a_op_const_reg_reg(list,OP_SHL,size,l1,src,dst)
else
begin
tmpreg:=getintregister(list,size);
a_load_const_reg(list,size,a,tmpreg);
a_op_reg_reg_reg_checkoverflow(list,op,size,tmpreg,src,dst,setflags,ovloc);
end;
end;
end;
procedure tcgarm.a_op_reg_reg_reg_checkoverflow(list: taasmoutput; op: TOpCg; size: tcgsize; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation);
var
so : tshifterop;
tmpreg,overflowreg : tregister;
asmop : tasmop;
begin
ovloc.loc:=LOC_VOID;
case op of
OP_NEG,OP_NOT,
OP_DIV,OP_IDIV:
internalerror(200308281);
OP_SHL:
begin
shifterop_reset(so);
so.rs:=src1;
so.shiftmode:=SM_LSL;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
end;
if is_shifter_const(a,shift) and not(op in [OP_IMUL,OP_MUL]) then
case op of
OP_NEG,OP_NOT,
OP_DIV,OP_IDIV:
internalerror(200308281);
OP_SHL:
OP_SHR:
begin
shifterop_reset(so);
so.rs:=src1;
so.shiftmode:=SM_LSR;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
end;
OP_SAR:
begin
shifterop_reset(so);
so.rs:=src1;
so.shiftmode:=SM_ASR;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
end;
OP_IMUL,
OP_MUL:
begin
if cgsetflags or setflags then
begin
if a>32 then
internalerror(200308291);
if a<>0 then
overflowreg:=getintregister(list,size);
if op=OP_IMUL then
asmop:=A_SMULL
else
asmop:=A_UMULL;
{ the arm doesn't allow that rd and rm are the same }
if dst=src2 then
begin
shifterop_reset(so);
so.shiftmode:=SM_LSL;
so.shiftimm:=a;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so));
if dst<>src1 then
list.concat(taicpu.op_reg_reg_reg_reg(asmop,dst,overflowreg,src1,src2))
else
begin
tmpreg:=getintregister(list,size);
a_load_reg_reg(list,size,size,src2,dst);
list.concat(taicpu.op_reg_reg_reg_reg(asmop,dst,overflowreg,tmpreg,src1));
end;
end
else
list.concat(taicpu.op_reg_reg(A_MOV,dst,src));
end;
OP_SHR:
begin
if a>32 then
internalerror(200308292);
shifterop_reset(so);
if a<>0 then
begin
so.shiftmode:=SM_LSR;
so.shiftimm:=a;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so));
end
else
list.concat(taicpu.op_reg_reg(A_MOV,dst,src));
end;
OP_SAR:
begin
if a>32 then
internalerror(200308291);
if a<>0 then
list.concat(taicpu.op_reg_reg_reg_reg(asmop,dst,overflowreg,src2,src1));
if op=OP_IMUL then
begin
shifterop_reset(so);
so.shiftmode:=SM_ASR;
so.shiftimm:=a;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so));
so.shiftimm:=31;
list.concat(taicpu.op_reg_reg_shifterop(A_CMP,overflowreg,overflowreg,so));
end
else
list.concat(taicpu.op_reg_reg(A_MOV,dst,src));
end;
else
list.concat(taicpu.op_reg_reg_const(op_reg_reg_opcg2asmop[op],dst,src,a));
end
else
begin
{ there could be added some more sophisticated optimizations }
if (op in [OP_MUL,OP_IMUL]) and (a=1) then
a_load_reg_reg(list,size,size,src,dst)
else if (op in [OP_MUL,OP_IMUL]) and (a=0) then
a_load_const_reg(list,size,0,dst)
else if (op in [OP_IMUL]) and (a=-1) then
a_op_reg_reg(list,OP_NEG,size,src,dst)
{ we do this here instead in the peephole optimizer because
it saves us a register }
else if (op in [OP_MUL,OP_IMUL]) and ispowerof2(a,l1) then
a_op_const_reg_reg(list,OP_SHL,size,l1,src,dst)
list.concat(taicpu.op_reg_const(A_CMP,overflowreg,0));
ovloc.loc:=LOC_FLAGS;
ovloc.resflags:=F_NE;
end
else
begin
tmpreg:=getintregister(list,size);
a_load_const_reg(list,size,a,tmpreg);
a_op_reg_reg_reg(list,op,size,tmpreg,src,dst);
{ the arm doesn't allow that rd and rm are the same }
if dst=src2 then
begin
if dst<>src1 then
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src1,src2))
else
begin
tmpreg:=getintregister(list,size);
a_load_reg_reg(list,size,size,src2,dst);
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,tmpreg,src1));
end;
end
else
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src2,src1));
end;
end;
end;
procedure tcgarm.a_op_reg_reg_reg(list: taasmoutput; op: TOpCg;
size: tcgsize; src1, src2, dst: tregister);
var
so : tshifterop;
tmpreg : tregister;
begin
case op of
OP_NEG,OP_NOT,
OP_DIV,OP_IDIV:
internalerror(200308281);
OP_SHL:
begin
shifterop_reset(so);
so.rs:=src1;
so.shiftmode:=SM_LSL;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
end;
OP_SHR:
begin
shifterop_reset(so);
so.rs:=src1;
so.shiftmode:=SM_LSR;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
end;
OP_SAR:
begin
shifterop_reset(so);
so.rs:=src1;
so.shiftmode:=SM_ASR;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
end;
OP_IMUL,
OP_MUL:
begin
{ the arm doesn't allow that rd and rm are the same }
if dst=src2 then
begin
if dst<>src1 then
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src1,src2))
else
begin
tmpreg:=getintregister(list,size);
a_load_reg_reg(list,size,size,src2,dst);
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,tmpreg,src1));
end;
end
else
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src2,src1));
end;
else
list.concat(setoppostfix(taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop[op],dst,src2,src1),toppostfix(ord(setflags)*ord(PF_S))));
end;
end;
else
list.concat(setoppostfix(
taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop[op],dst,src2,src1),toppostfix(ord(cgsetflags or setflags)*ord(PF_S))
));
end;
end;
function rotl(d : dword;b : byte) : dword;
@ -1177,8 +1252,51 @@ unit cgcpu;
end;
procedure tcgarm.g_overflowcheck(list: taasmoutput; const l: tlocation; def: tdef);
procedure tcgarm.g_overflowCheck(list : taasmoutput;const l : tlocation;def : tdef);
var
ovloc : tlocation;
begin
ovloc.loc:=LOC_VOID;
g_overflowCheck_loc(list,l,def,ovloc);
end;
procedure tcgarm.g_overflowCheck_loc(List:TAasmOutput;const Loc:TLocation;def:TDef;ovloc : tlocation);
var
hl : tasmlabel;
ai:TAiCpu;
hflags : tresflags;
begin
if not(cs_check_overflow in aktlocalswitches) then
exit;
objectlibrary.getlabel(hl);
case ovloc.loc of
LOC_VOID:
begin
ai:=taicpu.op_sym(A_B,hl);
ai.is_jmp:=true;
if not((def.deftype=pointerdef) or
((def.deftype=orddef) and
(torddef(def).typ in [u64bit,u16bit,u32bit,u8bit,uchar,bool8bit,bool16bit,bool32bit]))) then
ai.SetCondition(C_VC)
else
ai.SetCondition(C_CC);
list.concat(ai);
end;
LOC_FLAGS:
begin
hflags:=ovloc.resflags;
inverse_flags(hflags);
cg.a_jmp_flags(list,hflags,hl);
end;
else
internalerror(200409281);
end;
a_call_name(list,'FPC_OVERFLOW');
a_label(list,hl);
end;
@ -1270,7 +1388,7 @@ unit cgcpu;
end;
procedure tcg64farm.a_op64_reg_reg(list : taasmoutput;op:TOpCG;regsrc,regdst : tregister64);
procedure tcg64farm.a_op64_reg_reg(list : taasmoutput;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
var
tmpreg : tregister;
begin
@ -1286,95 +1404,217 @@ unit cgcpu;
cg.a_op_reg_reg(list,OP_NOT,OS_INT,regsrc.reghi,regdst.reghi);
end;
else
a_op64_reg_reg_reg(list,op,regsrc,regdst,regdst);
a_op64_reg_reg_reg(list,op,size,regsrc,regdst,regdst);
end;
end;
procedure tcg64farm.a_op64_const_reg(list : taasmoutput;op:TOpCG;value : int64;reg : tregister64);
procedure tcg64farm.a_op64_const_reg(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);
begin
a_op64_const_reg_reg(list,op,value,reg,reg);
a_op64_const_reg_reg(list,op,size,value,reg,reg);
end;
procedure tcg64farm.a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);
procedure tcg64farm.a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);
var
ovloc : tlocation;
begin
a_op64_const_reg_reg_checkoverflow(list,op,size,value,regsrc,regdst,false,ovloc);
end;
procedure tcg64farm.a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);
var
ovloc : tlocation;
begin
a_op64_reg_reg_reg_checkoverflow(list,op,size,regsrc1,regsrc2,regdst,false,ovloc);
end;
procedure tcg64farm.a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
var
tmpreg : tregister;
b : byte;
begin
ovloc.loc:=LOC_VOID;
case op of
OP_AND,OP_OR,OP_XOR:
begin
cg.a_op_const_reg_reg(list,op,OS_32,lo(value),regsrc.reglo,regdst.reglo);
cg.a_op_const_reg_reg(list,op,OS_32,hi(value),regsrc.reghi,regdst.reghi);
end;
OP_ADD:
begin
if is_shifter_const(lo(value),b) then
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_ADD,regdst.reglo,regsrc.reglo,lo(value)),PF_S))
else
OP_NEG,
OP_NOT :
internalerror(200306017);
end;
if (setflags or tcgarm(cg).cgsetflags) and (op in [OP_ADD,OP_SUB]) then
begin
case op of
OP_ADD:
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,lo(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADD,regdst.reglo,regsrc.reglo,tmpreg),PF_S));
end;
if is_shifter_const(lo(value),b) then
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_ADD,regdst.reglo,regsrc.reglo,lo(value)),PF_S))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,lo(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADD,regdst.reglo,regsrc.reglo,tmpreg),PF_S));
end;
if is_shifter_const(hi(value),b) then
list.concat(taicpu.op_reg_reg_const(A_ADC,regdst.reghi,regsrc.reghi,hi(value)))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
list.concat(taicpu.op_reg_reg_reg(A_ADC,regdst.reghi,regsrc.reghi,tmpreg));
if is_shifter_const(hi(value),b) then
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_ADC,regdst.reghi,regsrc.reghi,hi(value)),PF_S))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADC,regdst.reghi,regsrc.reghi,tmpreg),PF_S));
end;
end;
end;
OP_SUB:
begin
if is_shifter_const(lo(value),b) then
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_SUB,regdst.reglo,regsrc.reglo,lo(value)),PF_S))
else
OP_SUB:
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,lo(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SUB,regdst.reglo,regsrc.reglo,tmpreg),PF_S));
end;
if is_shifter_const(lo(value),b) then
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_SUB,regdst.reglo,regsrc.reglo,lo(value)),PF_S))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,lo(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SUB,regdst.reglo,regsrc.reglo,tmpreg),PF_S));
end;
if is_shifter_const(hi(value),b) then
list.concat(taicpu.op_reg_reg_const(A_SBC,regdst.reghi,regsrc.reghi,hi(value)))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
list.concat(taicpu.op_reg_reg_reg(A_SBC,regdst.reghi,regsrc.reghi,tmpreg));
if is_shifter_const(hi(value),b) then
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_SBC,regdst.reghi,regsrc.reghi,hi(value)),PF_S))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SBC,regdst.reghi,regsrc.reghi,tmpreg),PF_S));
end;
end;
else
internalerror(200502131);
end;
else
internalerror(2003083101);
if size=OS_64 then
begin
{ the arm has an weired opinion how flags for SUB/ADD are handled }
ovloc.loc:=LOC_FLAGS;
case op of
OP_ADD:
ovloc.resflags:=F_CS;
OP_SUB:
ovloc.resflags:=F_CC;
end;
end;
end
else
begin
case op of
OP_AND,OP_OR,OP_XOR:
begin
cg.a_op_const_reg_reg(list,op,OS_32,lo(value),regsrc.reglo,regdst.reglo);
cg.a_op_const_reg_reg(list,op,OS_32,hi(value),regsrc.reghi,regdst.reghi);
end;
OP_ADD:
begin
if is_shifter_const(lo(value),b) then
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_ADD,regdst.reglo,regsrc.reglo,lo(value)),PF_S))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,lo(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADD,regdst.reglo,regsrc.reglo,tmpreg),PF_S));
end;
if is_shifter_const(hi(value),b) then
list.concat(taicpu.op_reg_reg_const(A_ADC,regdst.reghi,regsrc.reghi,hi(value)))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
list.concat(taicpu.op_reg_reg_reg(A_ADC,regdst.reghi,regsrc.reghi,tmpreg));
end;
end;
OP_SUB:
begin
if is_shifter_const(lo(value),b) then
list.concat(setoppostfix(taicpu.op_reg_reg_const(A_SUB,regdst.reglo,regsrc.reglo,lo(value)),PF_S))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,lo(value),tmpreg);
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SUB,regdst.reglo,regsrc.reglo,tmpreg),PF_S));
end;
if is_shifter_const(hi(value),b) then
list.concat(taicpu.op_reg_reg_const(A_SBC,regdst.reghi,regsrc.reghi,hi(value)))
else
begin
tmpreg:=cg.getintregister(list,OS_32);
cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
list.concat(taicpu.op_reg_reg_reg(A_SBC,regdst.reghi,regsrc.reghi,tmpreg));
end;
end;
else
internalerror(2003083101);
end;
end;
end;
procedure tcg64farm.a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);
procedure tcg64farm.a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
var
op1,op2:TAsmOp;
begin
ovloc.loc:=LOC_VOID;
case op of
OP_AND,OP_OR,OP_XOR:
begin
cg.a_op_reg_reg_reg(list,op,OS_32,regsrc1.reglo,regsrc2.reglo,regdst.reglo);
cg.a_op_reg_reg_reg(list,op,OS_32,regsrc1.reghi,regsrc2.reghi,regdst.reghi);
end;
OP_ADD:
begin
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADD,regdst.reglo,regsrc1.reglo,regsrc2.reglo),PF_S));
list.concat(taicpu.op_reg_reg_reg(A_ADC,regdst.reghi,regsrc1.reghi,regsrc2.reghi));
end;
OP_SUB:
begin
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SUB,regdst.reglo,regsrc2.reglo,regsrc1.reglo),PF_S));
list.concat(taicpu.op_reg_reg_reg(A_SBC,regdst.reghi,regsrc2.reghi,regsrc1.reghi));
end;
else
internalerror(2003083101);
OP_NEG,
OP_NOT :
internalerror(200306017);
end;
if (setflags or tcgarm(cg).cgsetflags) and (op in [OP_ADD,OP_SUB]) then
begin
case op of
OP_ADD:
begin
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADD,regdst.reglo,regsrc1.reglo,regsrc2.reglo),PF_S));
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADC,regdst.reghi,regsrc1.reghi,regsrc2.reghi),PF_S));
end;
OP_SUB:
begin
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SUB,regdst.reglo,regsrc2.reglo,regsrc1.reglo),PF_S));
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SBC,regdst.reghi,regsrc2.reghi,regsrc1.reghi),PF_S));
end;
else
internalerror(2003083101);
end;
if size=OS_64 then
begin
{ the arm has an weired opinion how flags for SUB/ADD are handled }
ovloc.loc:=LOC_FLAGS;
case op of
OP_ADD:
ovloc.resflags:=F_CC;
OP_SUB:
ovloc.resflags:=F_CS;
end;
end;
end
else
begin
case op of
OP_AND,OP_OR,OP_XOR:
begin
cg.a_op_reg_reg_reg(list,op,OS_32,regsrc1.reglo,regsrc2.reglo,regdst.reglo);
cg.a_op_reg_reg_reg(list,op,OS_32,regsrc1.reghi,regsrc2.reghi,regdst.reghi);
end;
OP_ADD:
begin
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ADD,regdst.reglo,regsrc1.reglo,regsrc2.reglo),PF_S));
list.concat(taicpu.op_reg_reg_reg(A_ADC,regdst.reghi,regsrc1.reghi,regsrc2.reghi));
end;
OP_SUB:
begin
list.concat(setoppostfix(taicpu.op_reg_reg_reg(A_SUB,regdst.reglo,regsrc2.reglo,regsrc1.reglo),PF_S));
list.concat(taicpu.op_reg_reg_reg(A_SBC,regdst.reghi,regsrc2.reghi,regsrc1.reghi));
end;
else
internalerror(2003083101);
end;
end;
end;
@ -1384,7 +1624,10 @@ begin
end.
{
$Log$
Revision 1.67 2005-01-30 14:43:40 florian
Revision 1.68 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.67 2005/01/30 14:43:40 florian
* fixed compilation of arm compiler
Revision 1.66 2005/01/04 21:00:48 florian

View File

@ -162,16 +162,16 @@ implementation
cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,left.location.reference,hregister);
href:=left.location.reference;
inc(href.offset,4);
tcgarm(cg).setflags:=true;
tcgarm(cg).cgsetflags:=true;
cg.a_op_ref_reg(exprasmlist,OP_OR,OS_32,href,hregister);
tcgarm(cg).setflags:=false;
tcgarm(cg).cgsetflags:=false;
end
else
begin
location_force_reg(exprasmlist,left.location,left.location.size,true);
tcgarm(cg).setflags:=true;
tcgarm(cg).cgsetflags:=true;
cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
tcgarm(cg).setflags:=false;
tcgarm(cg).cgsetflags:=false;
end;
end;
LOC_FLAGS :
@ -184,15 +184,15 @@ implementation
begin
hregister:=cg.getintregister(exprasmlist,OS_32);
cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,left.location.register64.reglo,hregister);
tcgarm(cg).setflags:=true;
tcgarm(cg).cgsetflags:=true;
cg.a_op_reg_reg(exprasmlist,OP_OR,OS_32,left.location.register64.reghi,hregister);
tcgarm(cg).setflags:=false;
tcgarm(cg).cgsetflags:=false;
end
else
begin
tcgarm(cg).setflags:=true;
tcgarm(cg).cgsetflags:=true;
cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
tcgarm(cg).setflags:=false;
tcgarm(cg).cgsetflags:=false;
end;
end;
LOC_JUMP :
@ -205,9 +205,9 @@ implementation
cg.a_label(exprasmlist,falselabel);
cg.a_load_const_reg(exprasmlist,OS_INT,0,hregister);
cg.a_label(exprasmlist,hlabel);
tcgarm(cg).setflags:=true;
tcgarm(cg).cgsetflags:=true;
cg.a_op_reg_reg(exprasmlist,OP_OR,OS_INT,hregister,hregister);
tcgarm(cg).setflags:=false;
tcgarm(cg).cgsetflags:=false;
end;
else
internalerror(200311301);
@ -226,7 +226,10 @@ begin
end.
{
$Log$
Revision 1.13 2004-11-01 12:10:26 florian
Revision 1.14 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.13 2004/11/01 12:10:26 florian
* fixed currency division
Revision 1.12 2004/10/31 21:45:03 peter

View File

@ -149,8 +149,19 @@ unit rgcpu;
begin
if p.typ=ait_instruction then
begin
if (taicpu(p).opcode=A_MUL) then
add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
case taicpu(p).opcode of
A_MUL:
add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
A_UMULL,
A_UMLAL,
A_SMULL,
A_SMLAL:
begin
add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
add_edge(getsupreg(taicpu(p).oper[1]^.reg),getsupreg(taicpu(p).oper[2]^.reg));
add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[2]^.reg));
end;
end;
end;
end;
@ -159,7 +170,10 @@ end.
{
$Log$
Revision 1.15 2004-11-01 17:41:28 florian
Revision 1.16 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.15 2004/11/01 17:41:28 florian
* fixed arm compilation with cgutils
* ...

View File

@ -60,12 +60,12 @@ unit cg64f32;
procedure a_load64high_loc_reg(list : taasmoutput;const l : tlocation;reg : tregister);override;
procedure a_load64low_loc_reg(list : taasmoutput;const l : tlocation;reg : tregister);override;
procedure a_op64_ref_reg(list : taasmoutput;op:TOpCG;const ref : treference;reg : tregister64);override;
procedure a_op64_reg_ref(list : taasmoutput;op:TOpCG;reg : tregister64; const ref: treference);override;
procedure a_op64_const_loc(list : taasmoutput;op:TOpCG;value : int64;const l: tlocation);override;
procedure a_op64_reg_loc(list : taasmoutput;op:TOpCG;reg : tregister64;const l : tlocation);override;
procedure a_op64_loc_reg(list : taasmoutput;op:TOpCG;const l : tlocation;reg : tregister64);override;
procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;value : int64;const ref : treference);override;
procedure a_op64_ref_reg(list : taasmoutput;op:TOpCG;size : tcgsize;const ref : treference;reg : tregister64);override;
procedure a_op64_reg_ref(list : taasmoutput;op:TOpCG;size : tcgsize;reg : tregister64; const ref: treference);override;
procedure a_op64_const_loc(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;const l: tlocation);override;
procedure a_op64_reg_loc(list : taasmoutput;op:TOpCG;size : tcgsize;reg : tregister64;const l : tlocation);override;
procedure a_op64_loc_reg(list : taasmoutput;op:TOpCG;size : tcgsize;const l : tlocation;reg : tregister64);override;
procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;const ref : treference);override;
procedure a_param64_reg(list : taasmoutput;reg : tregister64;const paraloc : tcgpara);override;
procedure a_param64_const(list : taasmoutput;value : int64;const paraloc : tcgpara);override;
@ -404,26 +404,26 @@ unit cg64f32;
end;
procedure tcg64f32.a_op64_const_loc(list : taasmoutput;op:TOpCG;value : int64;const l: tlocation);
procedure tcg64f32.a_op64_const_loc(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;const l: tlocation);
begin
case l.loc of
LOC_REFERENCE, LOC_CREFERENCE:
a_op64_const_ref(list,op,value,l.reference);
a_op64_const_ref(list,op,size,value,l.reference);
LOC_REGISTER,LOC_CREGISTER:
a_op64_const_reg(list,op,value,l.register64);
a_op64_const_reg(list,op,size,value,l.register64);
else
internalerror(200203292);
end;
end;
procedure tcg64f32.a_op64_reg_loc(list : taasmoutput;op:TOpCG;reg : tregister64;const l : tlocation);
procedure tcg64f32.a_op64_reg_loc(list : taasmoutput;op:TOpCG;size : tcgsize;reg : tregister64;const l : tlocation);
begin
case l.loc of
LOC_REFERENCE, LOC_CREFERENCE:
a_op64_reg_ref(list,op,reg,l.reference);
a_op64_reg_ref(list,op,size,reg,l.reference);
LOC_REGISTER,LOC_CREGISTER:
a_op64_reg_reg(list,op,reg,l.register64);
a_op64_reg_reg(list,op,size,reg,l.register64);
else
internalerror(2002032422);
end;
@ -431,52 +431,52 @@ unit cg64f32;
procedure tcg64f32.a_op64_loc_reg(list : taasmoutput;op:TOpCG;const l : tlocation;reg : tregister64);
procedure tcg64f32.a_op64_loc_reg(list : taasmoutput;op:TOpCG;size : tcgsize;const l : tlocation;reg : tregister64);
begin
case l.loc of
LOC_REFERENCE, LOC_CREFERENCE:
a_op64_ref_reg(list,op,l.reference,reg);
a_op64_ref_reg(list,op,size,l.reference,reg);
LOC_REGISTER,LOC_CREGISTER:
a_op64_reg_reg(list,op,l.register64,reg);
a_op64_reg_reg(list,op,size,l.register64,reg);
LOC_CONSTANT :
a_op64_const_reg(list,op,l.value64,reg);
a_op64_const_reg(list,op,size,l.value64,reg);
else
internalerror(200203242);
end;
end;
procedure tcg64f32.a_op64_ref_reg(list : taasmoutput;op:TOpCG;const ref : treference;reg : tregister64);
procedure tcg64f32.a_op64_ref_reg(list : taasmoutput;op:TOpCG;size : tcgsize;const ref : treference;reg : tregister64);
var
tempreg: tregister64;
begin
tempreg.reghi:=cg.getintregister(list,OS_32);
tempreg.reglo:=cg.getintregister(list,OS_32);
a_load64_ref_reg(list,ref,tempreg);
a_op64_reg_reg(list,op,tempreg,reg);
a_op64_reg_reg(list,op,size,tempreg,reg);
end;
procedure tcg64f32.a_op64_reg_ref(list : taasmoutput;op:TOpCG;reg : tregister64; const ref: treference);
procedure tcg64f32.a_op64_reg_ref(list : taasmoutput;op:TOpCG;size : tcgsize;reg : tregister64; const ref: treference);
var
tempreg: tregister64;
begin
tempreg.reghi:=cg.getintregister(list,OS_32);
tempreg.reglo:=cg.getintregister(list,OS_32);
a_load64_ref_reg(list,ref,tempreg);
a_op64_reg_reg(list,op,reg,tempreg);
a_op64_reg_reg(list,op,size,reg,tempreg);
a_load64_reg_ref(list,tempreg,ref);
end;
procedure tcg64f32.a_op64_const_ref(list : taasmoutput;op:TOpCG;value : int64;const ref : treference);
procedure tcg64f32.a_op64_const_ref(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;const ref : treference);
var
tempreg: tregister64;
begin
tempreg.reghi:=cg.getintregister(list,OS_32);
tempreg.reglo:=cg.getintregister(list,OS_32);
a_load64_ref_reg(list,ref,tempreg);
a_op64_const_reg(list,op,value,tempreg);
a_op64_const_reg(list,op,size,value,tempreg);
a_load64_reg_ref(list,tempreg,ref);
end;
@ -781,7 +781,10 @@ unit cg64f32;
end.
{
$Log$
Revision 1.67 2005-01-18 22:19:20 peter
Revision 1.68 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.67 2005/01/18 22:19:20 peter
* multiple location support for i386 a_param_ref
* remove a_param_copy_ref for i386

View File

@ -441,18 +441,18 @@ unit cgobj;
procedure a_load64high_loc_reg(list : taasmoutput;const l : tlocation;reg : tregister);virtual;abstract;
procedure a_load64low_loc_reg(list : taasmoutput;const l : tlocation;reg : tregister);virtual;abstract;
procedure a_op64_ref_reg(list : taasmoutput;op:TOpCG;const ref : treference;reg : tregister64);virtual;abstract;
procedure a_op64_reg_reg(list : taasmoutput;op:TOpCG;regsrc,regdst : tregister64);virtual;abstract;
procedure a_op64_reg_ref(list : taasmoutput;op:TOpCG;regsrc : tregister64;const ref : treference);virtual;abstract;
procedure a_op64_const_reg(list : taasmoutput;op:TOpCG;value : int64;regdst : tregister64);virtual;abstract;
procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;value : int64;const ref : treference);virtual;abstract;
procedure a_op64_const_loc(list : taasmoutput;op:TOpCG;value : int64;const l: tlocation);virtual;abstract;
procedure a_op64_reg_loc(list : taasmoutput;op:TOpCG;reg : tregister64;const l : tlocation);virtual;abstract;
procedure a_op64_loc_reg(list : taasmoutput;op:TOpCG;const l : tlocation;reg64 : tregister64);virtual;abstract;
procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);virtual;
procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);virtual;
procedure a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual;
procedure a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual;
procedure a_op64_ref_reg(list : taasmoutput;op:TOpCG;size : tcgsize;const ref : treference;reg : tregister64);virtual;abstract;
procedure a_op64_reg_reg(list : taasmoutput;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);virtual;abstract;
procedure a_op64_reg_ref(list : taasmoutput;op:TOpCG;size : tcgsize;regsrc : tregister64;const ref : treference);virtual;abstract;
procedure a_op64_const_reg(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;regdst : tregister64);virtual;abstract;
procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;const ref : treference);virtual;abstract;
procedure a_op64_const_loc(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;const l: tlocation);virtual;abstract;
procedure a_op64_reg_loc(list : taasmoutput;op:TOpCG;size : tcgsize;reg : tregister64;const l : tlocation);virtual;abstract;
procedure a_op64_loc_reg(list : taasmoutput;op:TOpCG;size : tcgsize;const l : tlocation;reg64 : tregister64);virtual;abstract;
procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);virtual;
procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);virtual;
procedure a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual;
procedure a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);virtual;
procedure a_param64_reg(list : taasmoutput;reg64 : tregister64;const loc : TCGPara);virtual;abstract;
procedure a_param64_const(list : taasmoutput;value : int64;const loc : TCGPara);virtual;abstract;
@ -2021,14 +2021,14 @@ implementation
*****************************************************************************}
{$ifndef cpu64bit}
procedure tcg64.a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64; regsrc,regdst : tregister64);
procedure tcg64.a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64; regsrc,regdst : tregister64);
begin
a_load64_reg_reg(list,regsrc,regdst);
a_op64_const_reg(list,op,value,regdst);
a_op64_const_reg(list,op,size,value,regdst);
end;
procedure tcg64.a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);
procedure tcg64.a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);
var
tmpreg64 : tregister64;
begin
@ -2042,27 +2042,27 @@ implementation
tmpreg64.reglo:=cg.getintregister(list,OS_32);
tmpreg64.reghi:=cg.getintregister(list,OS_32);
a_load64_reg_reg(list,regsrc2,tmpreg64);
a_op64_reg_reg(list,op,regsrc1,tmpreg64);
a_op64_reg_reg(list,op,size,regsrc1,tmpreg64);
a_load64_reg_reg(list,tmpreg64,regdst);
end
else
begin
a_load64_reg_reg(list,regsrc2,regdst);
a_op64_reg_reg(list,op,regsrc1,regdst);
a_op64_reg_reg(list,op,size,regsrc1,regdst);
end;
end;
procedure tcg64.a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
procedure tcg64.a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
begin
a_op64_const_reg_reg(list,op,value,regsrc,regdst);
a_op64_const_reg_reg(list,op,size,value,regsrc,regdst);
ovloc.loc:=LOC_VOID;
end;
procedure tcg64.a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
procedure tcg64.a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
begin
a_op64_reg_reg_reg(list,op,regsrc1,regsrc2,regdst);
a_op64_reg_reg_reg(list,op,size,regsrc1,regsrc2,regdst);
ovloc.loc:=LOC_VOID;
end;
@ -2081,7 +2081,10 @@ finalization
end.
{
$Log$
Revision 1.193 2005-01-29 00:32:53 peter
Revision 1.194 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.193 2005/01/29 00:32:53 peter
* finalize for refcounted strings shall also reset temps to 0, the
previous exception that decrrefcnt already set it to 0 is not valid
anymore

View File

@ -99,6 +99,14 @@ unit compiler;
{$endif ARM}
{$ifdef MIPS}
{$ifndef CPUOK}
{$DEFINE CPUOK}
{$else}
{$fatal cannot define two CPU switches}
{$endif MIPS}
{$endif MIPS}
{$ifndef CPUOK}
{$fatal One of the switches I386, iA64, Alpha, PowerPC or M68K must be defined}
{$endif}
@ -427,7 +435,10 @@ end;
end.
{
$Log$
Revision 1.53 2005-01-31 21:30:56 olle
Revision 1.54 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.53 2005/01/31 21:30:56 olle
+ Added fake Exception classes, only for MACOS.
Revision 1.52 2005/01/26 16:23:28 peter

View File

@ -53,10 +53,10 @@ unit cgcpu;
end;
tcg64f386 = class(tcg64f32)
procedure a_op64_ref_reg(list : taasmoutput;op:TOpCG;const ref : treference;reg : tregister64);override;
procedure a_op64_reg_reg(list : taasmoutput;op:TOpCG;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg(list : taasmoutput;op:TOpCG;value : int64;reg : tregister64);override;
procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;value : int64;const ref : treference);override;
procedure a_op64_ref_reg(list : taasmoutput;op:TOpCG;size : tcgsize;const ref : treference;reg : tregister64);override;
procedure a_op64_reg_reg(list : taasmoutput;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
procedure a_op64_const_ref(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;const ref : treference);override;
private
procedure get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
end;
@ -645,7 +645,7 @@ unit cgcpu;
end;
procedure tcg64f386.a_op64_ref_reg(list : taasmoutput;op:TOpCG;const ref : treference;reg : tregister64);
procedure tcg64f386.a_op64_ref_reg(list : taasmoutput;op:TOpCG;size : tcgsize;const ref : treference;reg : tregister64);
var
op1,op2 : TAsmOp;
tempref : treference;
@ -658,7 +658,7 @@ unit cgcpu;
end;
procedure tcg64f386.a_op64_reg_reg(list : taasmoutput;op:TOpCG;regsrc,regdst : tregister64);
procedure tcg64f386.a_op64_reg_reg(list : taasmoutput;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
var
op1,op2 : TAsmOp;
begin
@ -687,7 +687,7 @@ unit cgcpu;
end;
procedure tcg64f386.a_op64_const_reg(list : taasmoutput;op:TOpCG;value : int64;reg : tregister64);
procedure tcg64f386.a_op64_const_reg(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);
var
op1,op2 : TAsmOp;
begin
@ -710,7 +710,7 @@ unit cgcpu;
end;
procedure tcg64f386.a_op64_const_ref(list : taasmoutput;op:TOpCG;value : int64;const ref : treference);
procedure tcg64f386.a_op64_const_ref(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;const ref : treference);
var
op1,op2 : TAsmOp;
tempref : treference;
@ -743,7 +743,10 @@ begin
end.
{
$Log$
Revision 1.65 2005-02-03 17:10:21 peter
Revision 1.66 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.65 2005/02/03 17:10:21 peter
* fix win32 small array parameters
Revision 1.64 2005/01/24 22:08:32 peter

View File

@ -210,7 +210,7 @@ interface
{ when swapped another result register }
if (nodetype=subn) and (nf_swaped in flags) then
begin
cg64.a_op64_reg_reg(exprasmlist,op,
cg64.a_op64_reg_reg(exprasmlist,op,location.size,
left.location.register64,
right.location.register64);
location_swap(left.location,right.location);
@ -218,7 +218,7 @@ interface
end
else
begin
cg64.a_op64_reg_reg(exprasmlist,op,
cg64.a_op64_reg_reg(exprasmlist,op,location.size,
right.location.register64,
left.location.register64);
end;
@ -239,7 +239,7 @@ interface
end
else
begin
cg64.a_op64_loc_reg(exprasmlist,op,right.location,
cg64.a_op64_loc_reg(exprasmlist,op,location.size,right.location,
left.location.register64);
end;
location_freetemp(exprasmlist,right.location);
@ -653,7 +653,10 @@ begin
end.
{
$Log$
Revision 1.101 2004-11-01 12:43:29 peter
Revision 1.102 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.101 2004/11/01 12:43:29 peter
* shortstr compare with empty string fixed
* removed special i386 code

View File

@ -529,10 +529,10 @@ interface
xorn,orn,andn,addn:
begin
if (right.location.loc = LOC_CONSTANT) then
cg64.a_op64_const_reg_reg_checkoverflow(exprasmlist,op,right.location.value64,
cg64.a_op64_const_reg_reg_checkoverflow(exprasmlist,op,location.size,right.location.value64,
left.location.register64,location.register64,checkoverflow,ovloc)
else
cg64.a_op64_reg_reg_reg_checkoverflow(exprasmlist,op,right.location.register64,
cg64.a_op64_reg_reg_reg_checkoverflow(exprasmlist,op,location.size,right.location.register64,
left.location.register64,location.register64,checkoverflow,ovloc);
end;
subn:
@ -544,12 +544,12 @@ interface
begin
if right.location.loc <> LOC_CONSTANT then
// reg64 - reg64
cg64.a_op64_reg_reg_reg_checkoverflow(exprasmlist,OP_SUB,
cg64.a_op64_reg_reg_reg_checkoverflow(exprasmlist,OP_SUB,location.size,
right.location.register64,left.location.register64,
location.register64,checkoverflow,ovloc)
else
// reg64 - const64
cg64.a_op64_const_reg_reg_checkoverflow(exprasmlist,OP_SUB,
cg64.a_op64_const_reg_reg_checkoverflow(exprasmlist,OP_SUB,location.size,
right.location.value64,left.location.register64,
location.register64,checkoverflow,ovloc)
end
@ -557,7 +557,7 @@ interface
begin
// const64 - reg64
location_force_reg(exprasmlist,left.location,left.location.size,true);
cg64.a_op64_reg_reg_reg_checkoverflow(exprasmlist,OP_SUB,
cg64.a_op64_reg_reg_reg_checkoverflow(exprasmlist,OP_SUB,location.size,
right.location.register64,left.location.register64,
location.register64,checkoverflow,ovloc);
end;
@ -569,7 +569,7 @@ interface
{ emit overflow check if enabled }
if checkoverflow then
cg.g_overflowcheck(exprasmlist,Location,ResultType.Def);
cg.g_overflowcheck_loc(exprasmlist,Location,ResultType.Def,ovloc);
end;
@ -777,7 +777,10 @@ begin
end.
{
$Log$
Revision 1.40 2005-01-29 00:40:18 peter
Revision 1.41 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.40 2005/01/29 00:40:18 peter
* fixed x86_64 compile
Revision 1.39 2005/01/27 20:32:51 florian

View File

@ -371,7 +371,7 @@ implementation
{$ifndef cpu64bit}
if cgsize in [OS_64,OS_S64] then
cg64.a_op64_const_reg(exprasmlist,cgop,1,location.register64)
cg64.a_op64_const_reg(exprasmlist,cgop,cgsize,1,location.register64)
else
{$endif cpu64bit}
cg.a_op_const_reg(exprasmlist,cgop,location.size,1,location.register);
@ -440,7 +440,7 @@ implementation
begin
{$ifndef cpu64bit}
if cgsize in [OS_64,OS_S64] then
cg64.a_op64_const_loc(exprasmlist,addsubop[inlinenumber],addvalue,tcallparanode(left).left.location)
cg64.a_op64_const_loc(exprasmlist,addsubop[inlinenumber],cgsize,addvalue,tcallparanode(left).left.location)
else
{$endif cpu64bit}
cg.a_op_const_loc(exprasmlist,addsubop[inlinenumber],
@ -450,7 +450,7 @@ implementation
begin
{$ifndef cpu64bit}
if cgsize in [OS_64,OS_S64] then
cg64.a_op64_reg_loc(exprasmlist,addsubop[inlinenumber],
cg64.a_op64_reg_loc(exprasmlist,addsubop[inlinenumber],cgsize,
joinreg64(hregister,hregisterhi),tcallparanode(left).left.location)
else
{$endif cpu64bit}
@ -679,7 +679,10 @@ end.
{
$Log$
Revision 1.67 2004-11-21 15:35:23 peter
Revision 1.68 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.67 2004/11/21 15:35:23 peter
* float routines all use internproc and compilerproc helpers
Revision 1.66 2004/11/08 21:59:34 florian

View File

@ -179,7 +179,7 @@ implementation
{ load left operator in a register }
location_copy(location,left.location);
location_force_reg(exprasmlist,location,OS_64,false);
cg64.a_op64_loc_reg(exprasmlist,OP_NEG,
cg64.a_op64_loc_reg(exprasmlist,OP_NEG,OS_64,
location,joinreg64(location.register64.reglo,location.register64.reghi));
end;
{$endif cpu64bit}
@ -434,7 +434,7 @@ implementation
location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
location_copy(location,left.location);
{ perform the NOT operation }
cg64.a_op64_reg_reg(exprasmlist,OP_NOT,left.location.register64,location.register64);
cg64.a_op64_reg_reg(exprasmlist,OP_NOT,location.size,left.location.register64,location.register64);
end;
{$endif cpu64bit}
@ -473,7 +473,10 @@ begin
end.
{
$Log$
Revision 1.30 2004-10-31 21:45:03 peter
Revision 1.31 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.30 2004/10/31 21:45:03 peter
* generic tlocation
* move tlocation to cgutils

View File

@ -134,10 +134,10 @@ unit cgcpu;
end;
tcg64fppc = class(tcg64f32)
procedure a_op64_reg_reg(list : taasmoutput;op:TOpCG;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg(list : taasmoutput;op:TOpCG;value : int64;reg : tregister64);override;
procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);override;
procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);override;
procedure a_op64_reg_reg(list : taasmoutput;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);override;
procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);override;
end;
@ -2310,19 +2310,19 @@ const
end;
procedure tcg64fppc.a_op64_reg_reg(list : taasmoutput;op:TOpCG;regsrc,regdst : tregister64);
procedure tcg64fppc.a_op64_reg_reg(list : taasmoutput;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
begin
a_op64_reg_reg_reg(list,op,regsrc,regdst,regdst);
a_op64_reg_reg_reg(list,op,size,regsrc,regdst,regdst);
end;
procedure tcg64fppc.a_op64_const_reg(list : taasmoutput;op:TOpCG;value : int64;reg : tregister64);
procedure tcg64fppc.a_op64_const_reg(list : taasmoutput;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);
begin
a_op64_const_reg_reg(list,op,value,reg,reg);
a_op64_const_reg_reg(list,op,size,value,reg,reg);
end;
procedure tcg64fppc.a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);
procedure tcg64fppc.a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);
begin
case op of
OP_AND,OP_OR,OP_XOR:
@ -2346,7 +2346,7 @@ const
end;
procedure tcg64fppc.a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);
procedure tcg64fppc.a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);
const
ops: array[boolean,1..3] of tasmop = ((A_ADDIC,A_ADDC,A_ADDZE),
@ -2398,7 +2398,7 @@ const
tmpreg64.reglo := tcgppc(cg).rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
tmpreg64.reghi := tcgppc(cg).rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
a_load64_const_reg(list,value,tmpreg64);
a_op64_reg_reg_reg(list,op,tmpreg64,regsrc,regdst);
a_op64_reg_reg_reg(list,op,size,tmpreg64,regsrc,regdst);
end
end
else
@ -2420,7 +2420,10 @@ begin
end.
{
$Log$
Revision 1.193 2005-01-24 22:08:32 peter
Revision 1.194 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.193 2005/01/24 22:08:32 peter
* interface wrapper generation moved to cgobj
* generate interface wrappers after the module is parsed

View File

@ -875,7 +875,7 @@ interface
begin
tempreg64.reglo := cg.getintregister(exprasmlist,OS_INT);
tempreg64.reghi := cg.getintregister(exprasmlist,OS_INT);
cg64.a_op64_reg_reg_reg(exprasmlist,OP_XOR,
cg64.a_op64_reg_reg_reg(exprasmlist,OP_XOR,location.size,
left.location.register64,right.location.register64,
tempreg64);
end;
@ -899,10 +899,10 @@ interface
if (left.location.loc = LOC_CONSTANT) then
swapleftright;
if (right.location.loc = LOC_CONSTANT) then
cg64.a_op64_const_reg_reg(exprasmlist,op,right.location.value64,
cg64.a_op64_const_reg_reg(exprasmlist,op,location.size,right.location.value64,
left.location.register64,location.register64)
else
cg64.a_op64_reg_reg_reg(exprasmlist,op,right.location.register64,
cg64.a_op64_reg_reg_reg(exprasmlist,op,location.size,right.location.register64,
left.location.register64,location.register64);
end;
subn:
@ -919,12 +919,12 @@ interface
end;
if right.location.loc <> LOC_CONSTANT then
// reg64 - reg64
cg64.a_op64_reg_reg_reg(exprasmlist,OP_SUB,
cg64.a_op64_reg_reg_reg(exprasmlist,OP_SUB,location.size,
right.location.register64,left.location.register64,
location.register64)
else
// reg64 - const64
cg64.a_op64_const_reg_reg(exprasmlist,OP_SUB,
cg64.a_op64_const_reg_reg(exprasmlist,OP_SUB,location.size,
right.location.value64,left.location.register64,
location.register64)
end
@ -983,7 +983,7 @@ interface
location.register64.reglo := cg.getintregister(exprasmlist,OS_INT);
location.register64.reghi := cg.getintregister(exprasmlist,OS_INT);
end;
cg64.a_op64_reg_reg_reg(exprasmlist,OP_SUB,
cg64.a_op64_reg_reg_reg(exprasmlist,OP_SUB,location.size,
right.location.register64,left.location.register64,
location.register64);
end;
@ -1462,7 +1462,10 @@ begin
end.
{
$Log$
Revision 1.55 2004-12-24 11:58:33 jonas
Revision 1.56 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.55 2004/12/24 11:58:33 jonas
- removed unused variables
Revision 1.54 2004/11/26 12:30:47 jonas

View File

@ -119,6 +119,12 @@ program pp;
{$endif CPUDEFINED}
{$define CPUDEFINED}
{$endif ARM}
{$ifdef MIPS}
{$ifdef CPUDEFINED}
{$fatal ONLY one of the switches for the CPU type must be defined}
{$endif CPUDEFINED}
{$define CPUDEFINED}
{$endif MIPS}
{$ifndef CPUDEFINED}
{$fatal A CPU type switch must be defined}
{$endif CPUDEFINED}
@ -204,7 +210,10 @@ begin
end.
{
$Log$
Revision 1.33 2004-06-20 08:55:30 florian
Revision 1.34 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.33 2004/06/20 08:55:30 florian
* logs truncated
Revision 1.32 2004/06/16 20:07:09 florian

View File

@ -99,12 +99,12 @@ interface
procedure a_load64_reg_ref(list : taasmoutput;reg : tregister64;const ref : treference);override;
procedure a_load64_ref_reg(list : taasmoutput;const ref : treference;reg : tregister64);override;
procedure a_param64_ref(list : taasmoutput;const r : treference;const paraloc : tcgpara);override;
procedure a_op64_reg_reg(list:TAasmOutput;op:TOpCG;regsrc,regdst:TRegister64);override;
procedure a_op64_const_reg(list:TAasmOutput;op:TOpCG;value:int64;regdst:TRegister64);override;
procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64);override;
procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);override;
procedure a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
procedure a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
procedure a_op64_reg_reg(list:TAasmOutput;op:TOpCG;size : tcgsize;regsrc,regdst:TRegister64);override;
procedure a_op64_const_reg(list:TAasmOutput;op:TOpCG;size : tcgsize;value:int64;regdst:TRegister64);override;
procedure a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);override;
procedure a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);override;
procedure a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
procedure a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
end;
const
@ -1388,7 +1388,7 @@ implementation
end;
procedure TCg64Sparc.a_op64_reg_reg(list:TAasmOutput;op:TOpCG;regsrc,regdst:TRegister64);
procedure TCg64Sparc.a_op64_reg_reg(list:TAasmOutput;op:TOpCG;size : tcgsize;regsrc,regdst:TRegister64);
var
op1,op2 : TAsmOp;
begin
@ -1413,7 +1413,7 @@ implementation
end;
procedure TCg64Sparc.a_op64_const_reg(list:TAasmOutput;op:TOpCG;value:int64;regdst:TRegister64);
procedure TCg64Sparc.a_op64_const_reg(list:TAasmOutput;op:TOpCG;size : tcgsize;value:int64;regdst:TRegister64);
var
op1,op2:TAsmOp;
begin
@ -1428,23 +1428,23 @@ implementation
end;
procedure tcg64sparc.a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;value : int64; regsrc,regdst : tregister64);
procedure tcg64sparc.a_op64_const_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64; regsrc,regdst : tregister64);
var
l : tlocation;
begin
a_op64_const_reg_reg_checkoverflow(list,op,value,regsrc,regdst,false,l);
a_op64_const_reg_reg_checkoverflow(list,op,size,value,regsrc,regdst,false,l);
end;
procedure tcg64sparc.a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64);
procedure tcg64sparc.a_op64_reg_reg_reg(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);
var
l : tlocation;
begin
a_op64_reg_reg_reg_checkoverflow(list,op,regsrc1,regsrc2,regdst,false,l);
a_op64_reg_reg_reg_checkoverflow(list,op,size,regsrc1,regsrc2,regdst,false,l);
end;
procedure tcg64sparc.a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
procedure tcg64sparc.a_op64_const_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
var
op1,op2:TAsmOp;
begin
@ -1459,7 +1459,7 @@ implementation
end;
procedure tcg64sparc.a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
procedure tcg64sparc.a_op64_reg_reg_reg_checkoverflow(list: taasmoutput;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
var
op1,op2:TAsmOp;
begin
@ -1480,7 +1480,10 @@ begin
end.
{
$Log$
Revision 1.105 2005-01-27 20:32:51 florian
Revision 1.106 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.105 2005/01/27 20:32:51 florian
+ implemented overflow checking for 64 bit types on sparc
Revision 1.104 2005/01/25 20:58:30 florian

View File

@ -823,6 +823,9 @@ interface
{$ifdef ARM}
pbestrealtype : ^ttype = @s64floattype;
{$endif ARM}
{$ifdef MIPS}
pbestrealtype : ^ttype = @s64floattype;
{$endif MIPS}
function make_mangledname(const typeprefix:string;st:tsymtable;const suffix:string):string;
@ -6391,7 +6394,10 @@ implementation
end.
{
$Log$
Revision 1.295 2005-02-10 22:08:37 peter
Revision 1.296 2005-02-13 18:55:19 florian
+ overflow checking for the arm
Revision 1.295 2005/02/10 22:08:37 peter
* implprocs requires no duplicate entries of the same procdef
Revision 1.294 2005/02/02 19:02:47 florian