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

View File

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

View File

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

View File

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