mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-04 11:50:17 +02:00
+ avr flag and condition handling
git-svn-id: trunk@17016 -
This commit is contained in:
parent
ca76476cfa
commit
ef699b1864
@ -138,7 +138,7 @@ implementation
|
|||||||
inherited create(op);
|
inherited create(op);
|
||||||
ops:=2;
|
ops:=2;
|
||||||
loadreg(0,_op1);
|
loadreg(0,_op1);
|
||||||
loadconst(1,_op2);
|
loadconst(1,aint(_op2));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor taicpu.op_const_reg(op:tasmop; _op1: LongInt; _op2: tregister);
|
constructor taicpu.op_const_reg(op:tasmop; _op1: LongInt; _op2: tregister);
|
||||||
|
@ -86,7 +86,6 @@ unit cgcpu;
|
|||||||
procedure g_concatcopy_internal(list : TAsmList;const source,dest : treference;len : aint;aligned : boolean);
|
procedure g_concatcopy_internal(list : TAsmList;const source,dest : treference;len : aint;aligned : boolean);
|
||||||
|
|
||||||
procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef); override;
|
procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef); override;
|
||||||
procedure g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);override;
|
|
||||||
|
|
||||||
// procedure g_save_registers(list : TAsmList);override;
|
// procedure g_save_registers(list : TAsmList);override;
|
||||||
// procedure g_restore_registers(list : TAsmList);override;
|
// procedure g_restore_registers(list : TAsmList);override;
|
||||||
@ -113,9 +112,6 @@ unit cgcpu;
|
|||||||
procedure create_codegen;
|
procedure create_codegen;
|
||||||
|
|
||||||
const
|
const
|
||||||
OpCmp2AsmCond : Array[topcmp] of TAsmCond = (C_NONE,C_EQ,C_GT,
|
|
||||||
C_LT,C_GE,C_LE,C_NE,C_LS,C_CC,C_CS,C_HI);
|
|
||||||
|
|
||||||
TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE,A_MOV,A_ADD,A_AND,A_NONE,
|
TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE,A_MOV,A_ADD,A_AND,A_NONE,
|
||||||
A_NONE,A_MUL,A_MULS,A_NEG,A_COM,A_OR,
|
A_NONE,A_MUL,A_MULS,A_NEG,A_COM,A_OR,
|
||||||
A_ASR,A_LSL,A_LSR,A_SUB,A_EOR,A_ROL,A_ROR);
|
A_ASR,A_LSL,A_LSR,A_SUB,A_EOR,A_ROL,A_ROR);
|
||||||
@ -401,6 +397,7 @@ unit cgcpu;
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
end;
|
end;
|
||||||
|
|
||||||
OP_SUB:
|
OP_SUB:
|
||||||
begin
|
begin
|
||||||
if src<>dst then
|
if src<>dst then
|
||||||
@ -417,6 +414,7 @@ unit cgcpu;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
OP_NEG:
|
OP_NEG:
|
||||||
begin
|
begin
|
||||||
if src<>dst then
|
if src<>dst then
|
||||||
@ -441,6 +439,7 @@ unit cgcpu;
|
|||||||
else
|
else
|
||||||
list.concat(taicpu.op_reg(A_NEG,dst));
|
list.concat(taicpu.op_reg(A_NEG,dst));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
OP_NOT:
|
OP_NOT:
|
||||||
begin
|
begin
|
||||||
for i:=1 to tcgsize2size[size] do
|
for i:=1 to tcgsize2size[size] do
|
||||||
@ -452,6 +451,7 @@ unit cgcpu;
|
|||||||
dst:=GetNextReg(dst);
|
dst:=GetNextReg(dst);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
OP_MUL,OP_IMUL:
|
OP_MUL,OP_IMUL:
|
||||||
begin
|
begin
|
||||||
if size in [OS_8,OS_S8] then
|
if size in [OS_8,OS_S8] then
|
||||||
@ -459,20 +459,17 @@ unit cgcpu;
|
|||||||
else
|
else
|
||||||
internalerror(2011022002);
|
internalerror(2011022002);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
OP_DIV,OP_IDIV:
|
OP_DIV,OP_IDIV:
|
||||||
{ special stuff, needs separate handling inside code }
|
{ special stuff, needs separate handling inside code }
|
||||||
{ generator }
|
{ generator }
|
||||||
internalerror(2011022001);
|
internalerror(2011022001);
|
||||||
{!!!!
|
|
||||||
OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
|
OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
|
||||||
begin
|
begin
|
||||||
{ Use ecx to load the value, that allows better coalescing }
|
{!!!!!!!}
|
||||||
getcpuregister(list,NR_ECX);
|
|
||||||
a_load_reg_reg(list,size,OS_32,src,NR_ECX);
|
|
||||||
list.concat(taicpu.op_reg_reg(Topcg2asmop[op],tcgsize2opsize[size],NR_CL,dst));
|
|
||||||
ungetcpuregister(list,NR_ECX);
|
|
||||||
end;
|
end;
|
||||||
}
|
|
||||||
OP_AND,OP_OR,OP_XOR:
|
OP_AND,OP_OR,OP_XOR:
|
||||||
begin
|
begin
|
||||||
if src<>dst then
|
if src<>dst then
|
||||||
@ -501,7 +498,7 @@ unit cgcpu;
|
|||||||
shift:=0;
|
shift:=0;
|
||||||
for i:=1 to tcgsize2size[size] do
|
for i:=1 to tcgsize2size[size] do
|
||||||
begin
|
begin
|
||||||
list.concat(taicpu.op_reg_const(A_LDI,reg,(a and mask) shr shift));
|
list.concat(taicpu.op_reg_const(A_LDI,reg,(qword(a) and mask) shr shift));
|
||||||
mask:=mask shl 8;
|
mask:=mask shl 8;
|
||||||
inc(shift,8);
|
inc(shift,8);
|
||||||
reg:=GetNextReg(reg);
|
reg:=GetNextReg(reg);
|
||||||
@ -1129,6 +1126,7 @@ unit cgcpu;
|
|||||||
current_asmdata.getjumplabel(l);
|
current_asmdata.getjumplabel(l);
|
||||||
if len>16 then
|
if len>16 then
|
||||||
begin
|
begin
|
||||||
|
{!!!!!!! load refs!}
|
||||||
copysize:=OS_8;
|
copysize:=OS_8;
|
||||||
if len<256 then
|
if len<256 then
|
||||||
countregsize:=OS_8
|
countregsize:=OS_8
|
||||||
@ -1177,16 +1175,26 @@ unit cgcpu;
|
|||||||
|
|
||||||
procedure tcgavr.g_overflowCheck(list : TAsmList;const l : tlocation;def : tdef);
|
procedure tcgavr.g_overflowCheck(list : TAsmList;const l : tlocation;def : tdef);
|
||||||
var
|
var
|
||||||
ovloc : tlocation;
|
hl : tasmlabel;
|
||||||
|
ai : taicpu;
|
||||||
|
cond : TAsmCond;
|
||||||
begin
|
begin
|
||||||
ovloc.loc:=LOC_VOID;
|
if not(cs_check_overflow in current_settings.localswitches) then
|
||||||
g_overflowCheck_loc(list,l,def,ovloc);
|
exit;
|
||||||
end;
|
current_asmdata.getjumplabel(hl);
|
||||||
|
if not ((def.typ=pointerdef) or
|
||||||
|
((def.typ=orddef) and
|
||||||
|
(torddef(def).ordtype in [u64bit,u16bit,u32bit,u8bit,uchar,pasbool]))) then
|
||||||
|
cond:=C_VC
|
||||||
|
else
|
||||||
|
cond:=C_CC;
|
||||||
|
ai:=Taicpu.Op_Sym(A_BRxx,hl);
|
||||||
|
ai.SetCondition(cond);
|
||||||
|
ai.is_jmp:=true;
|
||||||
|
list.concat(ai);
|
||||||
|
|
||||||
|
a_call_name(list,'FPC_OVERFLOW',false);
|
||||||
procedure tcgavr.g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);
|
a_label(list,hl);
|
||||||
begin
|
|
||||||
internalerror(2011021322);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1194,10 +1202,24 @@ unit cgcpu;
|
|||||||
var
|
var
|
||||||
ai : taicpu;
|
ai : taicpu;
|
||||||
begin
|
begin
|
||||||
|
{!!!!!
|
||||||
ai:=Taicpu.Op_sym(A_BRxx,l);
|
ai:=Taicpu.Op_sym(A_BRxx,l);
|
||||||
ai.SetCondition(OpCmp2AsmCond[cond]);
|
case cond of
|
||||||
|
OC_EQ:
|
||||||
|
ai.SetCondition(C_EQ);
|
||||||
|
OC_GT
|
||||||
|
OC_LT
|
||||||
|
OC_GTE
|
||||||
|
OC_LTE
|
||||||
|
OC_NE
|
||||||
|
OC_BE
|
||||||
|
OC_B
|
||||||
|
OC_AE
|
||||||
|
OC_A:
|
||||||
|
|
||||||
ai.is_jmp:=true;
|
ai.is_jmp:=true;
|
||||||
list.concat(ai);
|
list.concat(ai);
|
||||||
|
}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1211,7 +1233,7 @@ unit cgcpu;
|
|||||||
var
|
var
|
||||||
instr: taicpu;
|
instr: taicpu;
|
||||||
begin
|
begin
|
||||||
instr:=taicpu.op_reg_reg(A_MOV, reg2, reg1);
|
instr:=taicpu.op_reg_reg(A_MOV,reg2,reg1);
|
||||||
list.Concat(instr);
|
list.Concat(instr);
|
||||||
{ Notify the register allocator that we have written a move instruction so
|
{ Notify the register allocator that we have written a move instruction so
|
||||||
it can try to eliminate it. }
|
it can try to eliminate it. }
|
||||||
|
@ -133,19 +133,19 @@ unit cpubase;
|
|||||||
|
|
||||||
type
|
type
|
||||||
TAsmCond=(C_None,
|
TAsmCond=(C_None,
|
||||||
C_EQ,C_NE,C_CS,C_CC,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS,
|
C_CC,C_CS,C_EQ,C_GE,C_HC,C_HS,C_ID,C_IE,C_LO,C_LT,
|
||||||
C_GE,C_LT,C_GT,C_LE,C_AL,C_NV
|
C_MI,C_NE,C_PL,C_SH,C_TC,C_TS,C_VC,C_VS
|
||||||
);
|
);
|
||||||
|
|
||||||
const
|
const
|
||||||
cond2str : array[TAsmCond] of string[2]=('',
|
cond2str : array[TAsmCond] of string[2]=('',
|
||||||
'eq','ne','cs','cc','mi','pl','vs','vc','hi','ls',
|
'cc','cs','eq','ge','hc','hs','id','ie','lo','lt',
|
||||||
'ge','lt','gt','le','al','nv'
|
'mi','ne','pl','sh','tc','ts','vc','vs'
|
||||||
);
|
);
|
||||||
|
|
||||||
uppercond2str : array[TAsmCond] of string[2]=('',
|
uppercond2str : array[TAsmCond] of string[2]=('',
|
||||||
'EQ','NE','CS','CC','MI','PL','VS','VC','HI','LS',
|
'CC','CS','EQ','GE','HC','HS','ID','IE','LO','LT',
|
||||||
'GE','LT','GT','LE','AL','NV'
|
'MI','NE','PL','SH','TC','TS','VC','VS'
|
||||||
);
|
);
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
@ -153,8 +153,8 @@ unit cpubase;
|
|||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
type
|
type
|
||||||
TResFlags = (F_EQ,F_NE,F_CS,F_CC,F_MI,F_PL,F_VS,F_VC,F_HI,F_LS,
|
TResFlags = (F_NotPossible,F_CC,F_CS,F_EQ,F_GE,F_LO,F_LT,
|
||||||
F_GE,F_LT,F_GT,F_LE);
|
F_NE,F_SH,F_VC,F_VS);
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
Operands
|
Operands
|
||||||
@ -383,8 +383,8 @@ unit cpubase;
|
|||||||
procedure inverse_flags(var f: TResFlags);
|
procedure inverse_flags(var f: TResFlags);
|
||||||
const
|
const
|
||||||
inv_flags: array[TResFlags] of TResFlags =
|
inv_flags: array[TResFlags] of TResFlags =
|
||||||
(F_NE,F_EQ,F_CC,F_CS,F_PL,F_MI,F_VC,F_VS,F_LS,F_HI,
|
(F_NotPossible,F_CS,F_CC,F_NE,F_LT,F_SH,F_GE,
|
||||||
F_LT,F_GE,F_LE,F_GT);
|
F_NE,F_LO,F_VS,F_VC);
|
||||||
begin
|
begin
|
||||||
f:=inv_flags[f];
|
f:=inv_flags[f];
|
||||||
end;
|
end;
|
||||||
@ -392,10 +392,12 @@ unit cpubase;
|
|||||||
|
|
||||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||||
const
|
const
|
||||||
flag_2_cond: array[F_EQ..F_LE] of TAsmCond =
|
flag_2_cond: array[F_CC..F_VS] of TAsmCond =
|
||||||
(C_EQ,C_NE,C_CS,C_CC,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS,
|
(C_CC,C_CS,C_EQ,C_GE,C_LO,C_LT,
|
||||||
C_GE,C_LT,C_GT,C_LE);
|
C_NE,C_SH,C_VC,C_VS);
|
||||||
begin
|
begin
|
||||||
|
if f=F_NotPossible then
|
||||||
|
internalerror(2011022101);
|
||||||
if f>high(flag_2_cond) then
|
if f>high(flag_2_cond) then
|
||||||
internalerror(200112301);
|
internalerror(200112301);
|
||||||
result:=flag_2_cond[f];
|
result:=flag_2_cond[f];
|
||||||
@ -429,9 +431,8 @@ unit cpubase;
|
|||||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||||
const
|
const
|
||||||
inverse: array[TAsmCond] of TAsmCond=(C_None,
|
inverse: array[TAsmCond] of TAsmCond=(C_None,
|
||||||
C_NE,C_EQ,C_CC,C_CS,C_PL,C_MI,C_VC,C_VS,C_LS,C_HI,
|
C_CS,C_CC,C_NE,C_LT,C_HS,C_HC,C_IE,C_ID,C_SH,C_GE,
|
||||||
C_LT,C_GE,C_LE,C_GT,C_None,C_None
|
C_PL,C_EQ,C_MI,C_LO,C_TS,C_TC,C_VS,C_VC);
|
||||||
);
|
|
||||||
begin
|
begin
|
||||||
result := inverse[c];
|
result := inverse[c];
|
||||||
end;
|
end;
|
||||||
|
@ -70,22 +70,22 @@ interface
|
|||||||
if nf_swapped in flags then
|
if nf_swapped in flags then
|
||||||
case NodeType of
|
case NodeType of
|
||||||
ltn:
|
ltn:
|
||||||
GetResFlags:=F_GT;
|
GetResFlags:=F_NotPossible;
|
||||||
lten:
|
lten:
|
||||||
GetResFlags:=F_GE;
|
GetResFlags:=F_GE;
|
||||||
gtn:
|
gtn:
|
||||||
GetResFlags:=F_LT;
|
GetResFlags:=F_LT;
|
||||||
gten:
|
gten:
|
||||||
GetResFlags:=F_LE;
|
GetResFlags:=F_NotPossible;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
case NodeType of
|
case NodeType of
|
||||||
ltn:
|
ltn:
|
||||||
GetResFlags:=F_LT;
|
GetResFlags:=F_LT;
|
||||||
lten:
|
lten:
|
||||||
GetResFlags:=F_LE;
|
GetResFlags:=F_NotPossible;
|
||||||
gtn:
|
gtn:
|
||||||
GetResFlags:=F_GT;
|
GetResFlags:=F_NotPossible;
|
||||||
gten:
|
gten:
|
||||||
GetResFlags:=F_GE;
|
GetResFlags:=F_GE;
|
||||||
end;
|
end;
|
||||||
@ -95,22 +95,22 @@ interface
|
|||||||
if nf_swapped in Flags then
|
if nf_swapped in Flags then
|
||||||
case NodeType of
|
case NodeType of
|
||||||
ltn:
|
ltn:
|
||||||
GetResFlags:=F_HI;
|
GetResFlags:=F_NotPossible;
|
||||||
lten:
|
lten:
|
||||||
GetResFlags:=F_CS;
|
GetResFlags:=F_CS;
|
||||||
gtn:
|
gtn:
|
||||||
GetResFlags:=F_CC;
|
GetResFlags:=F_CC;
|
||||||
gten:
|
gten:
|
||||||
GetResFlags:=F_LS;
|
GetResFlags:=F_NotPossible;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
case NodeType of
|
case NodeType of
|
||||||
ltn:
|
ltn:
|
||||||
GetResFlags:=F_CC;
|
GetResFlags:=F_CC;
|
||||||
lten:
|
lten:
|
||||||
GetResFlags:=F_LS;
|
GetResFlags:=F_NotPossible;
|
||||||
gtn:
|
gtn:
|
||||||
GetResFlags:=F_HI;
|
GetResFlags:=F_NotPossible;
|
||||||
gten:
|
gten:
|
||||||
GetResFlags:=F_CS;
|
GetResFlags:=F_CS;
|
||||||
end;
|
end;
|
||||||
@ -173,6 +173,9 @@ interface
|
|||||||
unsigned:=not(is_signed(left.resultdef)) or
|
unsigned:=not(is_signed(left.resultdef)) or
|
||||||
not(is_signed(right.resultdef));
|
not(is_signed(right.resultdef));
|
||||||
|
|
||||||
|
if getresflags(unsigned)=F_NotPossible then
|
||||||
|
swapleftright;
|
||||||
|
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,right.location.register));
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,right.location.register));
|
||||||
tmpreg1:=left.location.register;
|
tmpreg1:=left.location.register;
|
||||||
tmpreg2:=right.location.register;
|
tmpreg2:=right.location.register;
|
||||||
|
Loading…
Reference in New Issue
Block a user