mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 18:29:28 +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);
|
||||
ops:=2;
|
||||
loadreg(0,_op1);
|
||||
loadconst(1,_op2);
|
||||
loadconst(1,aint(_op2));
|
||||
end;
|
||||
|
||||
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_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_restore_registers(list : TAsmList);override;
|
||||
@ -113,9 +112,6 @@ unit cgcpu;
|
||||
procedure create_codegen;
|
||||
|
||||
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,
|
||||
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);
|
||||
@ -401,6 +397,7 @@ unit cgcpu;
|
||||
end
|
||||
else
|
||||
end;
|
||||
|
||||
OP_SUB:
|
||||
begin
|
||||
if src<>dst then
|
||||
@ -417,6 +414,7 @@ unit cgcpu;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
OP_NEG:
|
||||
begin
|
||||
if src<>dst then
|
||||
@ -441,6 +439,7 @@ unit cgcpu;
|
||||
else
|
||||
list.concat(taicpu.op_reg(A_NEG,dst));
|
||||
end;
|
||||
|
||||
OP_NOT:
|
||||
begin
|
||||
for i:=1 to tcgsize2size[size] do
|
||||
@ -452,6 +451,7 @@ unit cgcpu;
|
||||
dst:=GetNextReg(dst);
|
||||
end;
|
||||
end;
|
||||
|
||||
OP_MUL,OP_IMUL:
|
||||
begin
|
||||
if size in [OS_8,OS_S8] then
|
||||
@ -459,20 +459,17 @@ unit cgcpu;
|
||||
else
|
||||
internalerror(2011022002);
|
||||
end;
|
||||
|
||||
OP_DIV,OP_IDIV:
|
||||
{ special stuff, needs separate handling inside code }
|
||||
{ generator }
|
||||
internalerror(2011022001);
|
||||
{!!!!
|
||||
|
||||
OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
|
||||
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;
|
||||
}
|
||||
|
||||
OP_AND,OP_OR,OP_XOR:
|
||||
begin
|
||||
if src<>dst then
|
||||
@ -501,7 +498,7 @@ unit cgcpu;
|
||||
shift:=0;
|
||||
for i:=1 to tcgsize2size[size] do
|
||||
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;
|
||||
inc(shift,8);
|
||||
reg:=GetNextReg(reg);
|
||||
@ -1129,6 +1126,7 @@ unit cgcpu;
|
||||
current_asmdata.getjumplabel(l);
|
||||
if len>16 then
|
||||
begin
|
||||
{!!!!!!! load refs!}
|
||||
copysize:=OS_8;
|
||||
if len<256 then
|
||||
countregsize:=OS_8
|
||||
@ -1177,16 +1175,26 @@ unit cgcpu;
|
||||
|
||||
procedure tcgavr.g_overflowCheck(list : TAsmList;const l : tlocation;def : tdef);
|
||||
var
|
||||
ovloc : tlocation;
|
||||
hl : tasmlabel;
|
||||
ai : taicpu;
|
||||
cond : TAsmCond;
|
||||
begin
|
||||
ovloc.loc:=LOC_VOID;
|
||||
g_overflowCheck_loc(list,l,def,ovloc);
|
||||
end;
|
||||
if not(cs_check_overflow in current_settings.localswitches) then
|
||||
exit;
|
||||
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);
|
||||
|
||||
|
||||
procedure tcgavr.g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);
|
||||
begin
|
||||
internalerror(2011021322);
|
||||
a_call_name(list,'FPC_OVERFLOW',false);
|
||||
a_label(list,hl);
|
||||
end;
|
||||
|
||||
|
||||
@ -1194,10 +1202,24 @@ unit cgcpu;
|
||||
var
|
||||
ai : taicpu;
|
||||
begin
|
||||
{!!!!!
|
||||
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;
|
||||
list.concat(ai);
|
||||
}
|
||||
end;
|
||||
|
||||
|
||||
@ -1211,7 +1233,7 @@ unit cgcpu;
|
||||
var
|
||||
instr: taicpu;
|
||||
begin
|
||||
instr:=taicpu.op_reg_reg(A_MOV, reg2, reg1);
|
||||
instr:=taicpu.op_reg_reg(A_MOV,reg2,reg1);
|
||||
list.Concat(instr);
|
||||
{ Notify the register allocator that we have written a move instruction so
|
||||
it can try to eliminate it. }
|
||||
|
@ -133,19 +133,19 @@ unit cpubase;
|
||||
|
||||
type
|
||||
TAsmCond=(C_None,
|
||||
C_EQ,C_NE,C_CS,C_CC,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS,
|
||||
C_GE,C_LT,C_GT,C_LE,C_AL,C_NV
|
||||
C_CC,C_CS,C_EQ,C_GE,C_HC,C_HS,C_ID,C_IE,C_LO,C_LT,
|
||||
C_MI,C_NE,C_PL,C_SH,C_TC,C_TS,C_VC,C_VS
|
||||
);
|
||||
|
||||
const
|
||||
cond2str : array[TAsmCond] of string[2]=('',
|
||||
'eq','ne','cs','cc','mi','pl','vs','vc','hi','ls',
|
||||
'ge','lt','gt','le','al','nv'
|
||||
'cc','cs','eq','ge','hc','hs','id','ie','lo','lt',
|
||||
'mi','ne','pl','sh','tc','ts','vc','vs'
|
||||
);
|
||||
|
||||
uppercond2str : array[TAsmCond] of string[2]=('',
|
||||
'EQ','NE','CS','CC','MI','PL','VS','VC','HI','LS',
|
||||
'GE','LT','GT','LE','AL','NV'
|
||||
'CC','CS','EQ','GE','HC','HS','ID','IE','LO','LT',
|
||||
'MI','NE','PL','SH','TC','TS','VC','VS'
|
||||
);
|
||||
|
||||
{*****************************************************************************
|
||||
@ -153,8 +153,8 @@ unit cpubase;
|
||||
*****************************************************************************}
|
||||
|
||||
type
|
||||
TResFlags = (F_EQ,F_NE,F_CS,F_CC,F_MI,F_PL,F_VS,F_VC,F_HI,F_LS,
|
||||
F_GE,F_LT,F_GT,F_LE);
|
||||
TResFlags = (F_NotPossible,F_CC,F_CS,F_EQ,F_GE,F_LO,F_LT,
|
||||
F_NE,F_SH,F_VC,F_VS);
|
||||
|
||||
{*****************************************************************************
|
||||
Operands
|
||||
@ -383,8 +383,8 @@ unit cpubase;
|
||||
procedure inverse_flags(var f: TResFlags);
|
||||
const
|
||||
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_LT,F_GE,F_LE,F_GT);
|
||||
(F_NotPossible,F_CS,F_CC,F_NE,F_LT,F_SH,F_GE,
|
||||
F_NE,F_LO,F_VS,F_VC);
|
||||
begin
|
||||
f:=inv_flags[f];
|
||||
end;
|
||||
@ -392,10 +392,12 @@ unit cpubase;
|
||||
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
const
|
||||
flag_2_cond: array[F_EQ..F_LE] of TAsmCond =
|
||||
(C_EQ,C_NE,C_CS,C_CC,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS,
|
||||
C_GE,C_LT,C_GT,C_LE);
|
||||
flag_2_cond: array[F_CC..F_VS] of TAsmCond =
|
||||
(C_CC,C_CS,C_EQ,C_GE,C_LO,C_LT,
|
||||
C_NE,C_SH,C_VC,C_VS);
|
||||
begin
|
||||
if f=F_NotPossible then
|
||||
internalerror(2011022101);
|
||||
if f>high(flag_2_cond) then
|
||||
internalerror(200112301);
|
||||
result:=flag_2_cond[f];
|
||||
@ -429,9 +431,8 @@ unit cpubase;
|
||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
const
|
||||
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_LT,C_GE,C_LE,C_GT,C_None,C_None
|
||||
);
|
||||
C_CS,C_CC,C_NE,C_LT,C_HS,C_HC,C_IE,C_ID,C_SH,C_GE,
|
||||
C_PL,C_EQ,C_MI,C_LO,C_TS,C_TC,C_VS,C_VC);
|
||||
begin
|
||||
result := inverse[c];
|
||||
end;
|
||||
|
@ -70,22 +70,22 @@ interface
|
||||
if nf_swapped in flags then
|
||||
case NodeType of
|
||||
ltn:
|
||||
GetResFlags:=F_GT;
|
||||
GetResFlags:=F_NotPossible;
|
||||
lten:
|
||||
GetResFlags:=F_GE;
|
||||
gtn:
|
||||
GetResFlags:=F_LT;
|
||||
gten:
|
||||
GetResFlags:=F_LE;
|
||||
GetResFlags:=F_NotPossible;
|
||||
end
|
||||
else
|
||||
case NodeType of
|
||||
ltn:
|
||||
GetResFlags:=F_LT;
|
||||
lten:
|
||||
GetResFlags:=F_LE;
|
||||
GetResFlags:=F_NotPossible;
|
||||
gtn:
|
||||
GetResFlags:=F_GT;
|
||||
GetResFlags:=F_NotPossible;
|
||||
gten:
|
||||
GetResFlags:=F_GE;
|
||||
end;
|
||||
@ -95,22 +95,22 @@ interface
|
||||
if nf_swapped in Flags then
|
||||
case NodeType of
|
||||
ltn:
|
||||
GetResFlags:=F_HI;
|
||||
GetResFlags:=F_NotPossible;
|
||||
lten:
|
||||
GetResFlags:=F_CS;
|
||||
gtn:
|
||||
GetResFlags:=F_CC;
|
||||
gten:
|
||||
GetResFlags:=F_LS;
|
||||
GetResFlags:=F_NotPossible;
|
||||
end
|
||||
else
|
||||
case NodeType of
|
||||
ltn:
|
||||
GetResFlags:=F_CC;
|
||||
lten:
|
||||
GetResFlags:=F_LS;
|
||||
GetResFlags:=F_NotPossible;
|
||||
gtn:
|
||||
GetResFlags:=F_HI;
|
||||
GetResFlags:=F_NotPossible;
|
||||
gten:
|
||||
GetResFlags:=F_CS;
|
||||
end;
|
||||
@ -173,6 +173,9 @@ interface
|
||||
unsigned:=not(is_signed(left.resultdef)) or
|
||||
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));
|
||||
tmpreg1:=left.location.register;
|
||||
tmpreg2:=right.location.register;
|
||||
|
Loading…
Reference in New Issue
Block a user