+ avr flag and condition handling

git-svn-id: trunk@17016 -
This commit is contained in:
florian 2011-02-26 20:15:03 +00:00
parent ca76476cfa
commit ef699b1864
4 changed files with 73 additions and 47 deletions

View File

@ -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);

View File

@ -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. }

View File

@ -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;

View File

@ -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;