xtensa: Add preliminary support for comparisons

git-svn-id: trunk@44330 -
This commit is contained in:
Jeppe Johansen 2020-03-21 20:59:31 +00:00
parent 77f5abac66
commit bcbdc4ad92
6 changed files with 117 additions and 317 deletions

View File

@ -78,6 +78,7 @@ uses
constructor op_sym(op : tasmop;_op1 : tasmsymbol);
constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:aint);
constructor op_reg_sym(op : tasmop;_op1 : tregister;_op2:tasmsymbol);
constructor op_reg_reg_sym(op : tasmop;_op1, _op2 : tregister;_op3:tasmsymbol);
constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : aint);
constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:aint;const _op2 : treference);
@ -367,6 +368,15 @@ uses cutils, cclasses;
loadsymbol(1,_op2,0);
end;
constructor taicpu.op_reg_reg_sym(op: tasmop; _op1, _op2: tregister; _op3: tasmsymbol);
begin
inherited create(op);
ops:=3;
loadreg(0,_op1);
loadreg(1,_op2);
loadsymbol(2,_op3,0);
end;
constructor taicpu.op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : aint);
begin
@ -429,9 +439,9 @@ uses cutils, cclasses;
begin
case getregtype(r) of
R_INTREGISTER:
result:=taicpu.op_reg_ref(A_L32I,r,ref);
result:=taicpu.op_reg_reg_const(A_L32I,r,ref.base,ref.offset);
R_FPUREGISTER:
result:=taicpu.op_reg_ref(A_LSI,r,ref);
result:=taicpu.op_reg_reg_const(A_LSI,r,ref.base,ref.offset);
else
internalerror(2020030701);
end;
@ -442,9 +452,9 @@ uses cutils, cclasses;
begin
case getregtype(r) of
R_INTREGISTER:
result:=taicpu.op_reg_ref(A_S32I,r,ref);
result:=taicpu.op_reg_reg_const(A_S32I,r,ref.base,ref.offset);
R_FPUREGISTER:
result:=taicpu.op_reg_ref(A_SSI,r,ref);
result:=taicpu.op_reg_reg_const(A_SSI,r,ref.base,ref.offset);
else
internalerror(2020030701);
end;

View File

@ -150,6 +150,8 @@ unit agcpugas;
op:=taicpu(hp).opcode;
postfix:='';
s:=#9+gas_op2str[op];
if taicpu(hp).condition<>C_None then
s:=s+cond2str[taicpu(hp).condition];
if taicpu(hp).ops<>0 then
begin
sep:=#9;

View File

@ -105,21 +105,24 @@ 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_EQ,C_NE,
C_GE,C_LT,C_GEU,C_LTU,
C_ANY,C_BNONE,C_ALL,C_NALL,C_BC,C_BS
);
TAsmConds = set of TAsmCond;
const
cond2str : array[TAsmCond] of string[2]=('',
'eq','ne','cs','cc','mi','pl','vs','vc','hi','ls',
'ge','lt','gt','le','al','nv'
cond2str : array[TAsmCond] of string[4]=('',
'eq','ne',
'ge','lt','geu','ltu',
'any','none','all','nall','bc','bs'
);
uppercond2str : array[TAsmCond] of string[2]=('',
'EQ','NE','CS','CC','MI','PL','VS','VC','HI','LS',
'GE','LT','GT','LE','AL','NV'
uppercond2str : array[TAsmCond] of string[4]=('',
'EQ','NE',
'GE','LT','GEU','LTU',
'ANY','NONE','ALL','NALL','BC','BS'
);
{*****************************************************************************
@ -248,7 +251,6 @@ unit cpubase;
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
procedure inverse_flags(var f: TResFlags);
function flags_to_cond(const f: TResFlags) : TAsmCond;
function findreg_by_number(r:Tregister):tregisterindex;
function std_regnum_search(const s:string):Tregister;
function std_regname(r:Tregister):string;
@ -349,18 +351,6 @@ unit cpubase;
end;
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);
begin
if f>high(flag_2_cond) then
internalerror(200112301);
result:=flag_2_cond[f];
end;
function findreg_by_number(r:Tregister):tregisterindex;
begin
result:=rgBase.findreg_by_number_table(r,regnumber_index);
@ -388,8 +378,9 @@ 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_NE,C_EQ,
C_LT,C_GE,C_LTU,C_GEU,
C_BNONE,C_ANY,C_NALL,C_BNONE,C_BS,C_BC
);
begin
result := inverse[c];
@ -408,17 +399,7 @@ unit cpubase;
Result := (c = C_None) or conditions_equal(Subset, c);
{ Please update as necessary. [Kit] }
if not Result then
case Subset of
C_EQ:
Result := (c in [C_GE, C_LE]);
C_LT:
Result := (c in [C_LE]);
C_GT:
Result := (c in [C_GE]);
else
Result := False;
end;
Result := False;
end;

View File

@ -57,165 +57,62 @@ interface
*****************************************************************************}
procedure TCPUAddNode.second_cmpsmallset;
procedure gencmp(tmpreg1,tmpreg2 : tregister);
var
i : byte;
begin
//current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,tmpreg1,tmpreg2));
//for i:=2 to tcgsize2size[left.location.size] do
// begin
// tmpreg1:=cg.GetNextReg(tmpreg1);
// tmpreg2:=cg.GetNextReg(tmpreg2);
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
// end;
end;
var
tmpreg : tregister;
cond: TOpCmp;
instr: taicpu;
truelab, falselab: TAsmLabel;
begin
pass_left_right;
location_reset(location,LOC_FLAGS,OS_NO);
current_asmdata.getjumplabel(truelab);
current_asmdata.getjumplabel(falselab);
location_reset_jump(location,truelab,falselab);
force_reg_left_right(false,false);
//
//case nodetype of
// equaln:
// begin
// gencmp(left.location.register,right.location.register);
// location.resflags:=F_EQ;
// end;
// unequaln:
// begin
// gencmp(left.location.register,right.location.register);
// location.resflags:=F_NE;
// end;
// lten,
// gten:
// begin
// if (not(nf_swapped in flags) and
// (nodetype = lten)) or
// ((nf_swapped in flags) and
// (nodetype = gten)) then
// swapleftright;
// tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
// cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,location.size,
// left.location.register,right.location.register,tmpreg);
// gencmp(tmpreg,right.location.register);
// location.resflags:=F_EQ;
// end;
// else
// internalerror(2004012401);
//end;
location_copy(location,left.location);
case nodetype of
equaln: cond:=OC_EQ;
unequaln: cond:=OC_NE;
ltn: cond:=OC_LT;
lten: cond:=OC_LT;
gtn: cond:=OC_GT;
gten: cond:=OC_GTE;
else
internalerror(2020030801);
end;
cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cond,left.location.register,right.location.register,location.truelabel);
current_asmdata.CurrAsmList.concat(taicpu.op_sym(A_J,location.falselabel));
end;
procedure TCPUAddNode.second_cmp;
var
unsigned : boolean;
tmpreg1,tmpreg2 : tregister;
i : longint;
cond: TOpCmp;
instr: taicpu;
truelab, falselab: TAsmLabel;
begin
pass_left_right;
force_reg_left_right(true,true);
//
//unsigned:=not(is_signed(left.resultdef)) or
// not(is_signed(right.resultdef));
//
//if getresflags(unsigned)=F_NotPossible then
// begin
// swapleftright;
// { if we have to swap back and left is a constant, force it to a register because we cannot generate
// the needed code using a constant }
// if (left.location.loc=LOC_CONSTANT) and (left.location.value<>0) then
// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
// end;
//
//if (not unsigned) and
// (right.location.loc=LOC_CONSTANT) and
// (right.location.value=0) and
// (getresflags(unsigned) in [F_LT,F_GE]) then
// begin
// { This is a simple sign test, where we can just test the msb }
// tmpreg1:=left.location.register;
// for i:=2 to tcgsize2size[left.location.size] do
// begin
// if i=5 then
// tmpreg1:=left.location.registerhi
// else
// tmpreg1:=cg.GetNextReg(tmpreg1);
// end;
//
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,tmpreg1,GetDefaultZeroReg));
//
// location_reset(location,LOC_FLAGS,OS_NO);
// location.resflags:=getresflags(unsigned);
//
// exit;
// end;
//
//if right.location.loc=LOC_CONSTANT then
// begin
// { decrease register pressure on registers >= r16 }
// if (right.location.value and $ff)=0 then
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,GetDefaultZeroReg))
// else
// begin
// cg.getcpuregister(current_asmdata.CurrAsmList,NR_R26);
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LDI,NR_R26,right.location.value and $ff));
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,NR_R26));
// cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_R26);
// end;
// end
//{ on the left side, we allow only a constant if it is 0 }
//else if (left.location.loc=LOC_CONSTANT) and (left.location.value=0) then
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,GetDefaultZeroReg,right.location.register))
//else
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,right.location.register));
//
//tmpreg1:=left.location.register;
//tmpreg2:=right.location.register;
//
//for i:=2 to tcgsize2size[left.location.size] do
// begin
// if i=5 then
// begin
// if left.location.loc<>LOC_CONSTANT then
// tmpreg1:=left.location.registerhi;
// if right.location.loc<>LOC_CONSTANT then
// tmpreg2:=right.location.registerhi;
// end
// else
// begin
// if left.location.loc<>LOC_CONSTANT then
// tmpreg1:=cg.GetNextReg(tmpreg1);
// if right.location.loc<>LOC_CONSTANT then
// tmpreg2:=cg.GetNextReg(tmpreg2);
// end;
// if right.location.loc=LOC_CONSTANT then
// begin
// { just use R1? }
// if ((right.location.value64 shr ((i-1)*8)) and $ff)=0 then
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,GetDefaultZeroReg))
// else
// begin
// tmpreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_8);
// cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_8,(right.location.value64 shr ((i-1)*8)) and $ff,tmpreg2);
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
// end;
// end
// { above it is checked, if left=0, then a constant is allowed }
// else if (left.location.loc=LOC_CONSTANT) and (left.location.value=0) then
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,GetDefaultZeroReg,tmpreg2))
// else
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
// end;
//
//location_reset(location,LOC_FLAGS,OS_NO);
//location.resflags:=getresflags(unsigned);
//location.loc:=LOC_REGISTER;
location_copy(location,left.location);
current_asmdata.CurrAsmList.Concat(taicpu.op_none(A_NOP));
current_asmdata.getjumplabel(truelab);
current_asmdata.getjumplabel(falselab);
location_reset_jump(location,truelab,falselab);
force_reg_left_right(false,false);
case nodetype of
equaln: cond:=OC_EQ;
unequaln: cond:=OC_NE;
ltn: cond:=OC_LT;
lten: cond:=OC_LT;
gtn: cond:=OC_GT;
gten: cond:=OC_GTE;
else
internalerror(2020030801);
end;
cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cond,left.location.register,right.location.register,location.truelabel);
current_asmdata.CurrAsmList.concat(taicpu.op_sym(A_J,location.falselabel));
end;

View File

@ -78,39 +78,11 @@ implementation
var
tmpreg : TRegister;
begin
location.loc:=LOC_REGISTER;
//{ if the location is LOC_JUMP, we do the secondpass after the
// labels are allocated
//}
//if not handle_locjump then
// begin
// secondpass(left);
// case left.location.loc of
// LOC_FLAGS :
// begin
// location_copy(location,left.location);
// inverse_flags(location.resflags);
// end;
// LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE,
// LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF :
// begin
// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
// cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
// if is_64bit(resultdef) then
// begin
// tmpreg:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT);
// { OR low and high parts together }
// current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,tmpreg,left.location.register64.reglo,left.location.register64.reghi),PF_S));
// end
// else
// current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP,left.location.register,0));
// location_reset(location,LOC_FLAGS,OS_NO);
// location.resflags:=F_EQ;
// end;
// else
// internalerror(2003042401);
// end;
// end;
secondpass(left);
location:=left.location;
hlcg.location_force_reg(current_asmdata.CurrAsmList,location,resultdef,resultdef,false);
cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NOT,def_cgsize(resultdef), location.register, location.register);
end;
{*****************************************************************************
@ -123,106 +95,43 @@ implementation
fdef : tdef;
begin
Result:=nil;
//if (current_settings.fputype=fpu_soft) and
// (left.resultdef.typ=floatdef) then
// begin
// result:=nil;
// firstpass(left);
// expectloc:=LOC_REGISTER;
// exit;
// end;
//
//if not(FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[current_settings.fputype]) or
// (tfloatdef(resultdef).floattype=s32real) then
// exit(inherited pass_1);
//
//result:=nil;
//firstpass(left);
//if codegenerror then
// exit;
//
//if (left.resultdef.typ=floatdef) then
// begin
// case tfloatdef(resultdef).floattype of
// s64real:
// begin
// procname:='float64_sub';
// fdef:=search_system_type('FLOAT64').typedef;
// end;
// else
// internalerror(2005082801);
// end;
// result:=ctypeconvnode.create_internal(ccallnode.createintern(procname,ccallparanode.create(
// ctypeconvnode.create_internal(left,fDef),
// ccallparanode.create(ctypeconvnode.create_internal(crealconstnode.create(0,resultdef),fdef),nil))),resultdef);
//
// left:=nil;
// end
//else
// begin
// if (left.resultdef.typ=floatdef) then
// expectloc:=LOC_FPUREGISTER
// else if (left.resultdef.typ=orddef) then
// expectloc:=LOC_REGISTER;
// end;
if (current_settings.fputype=fpu_soft) and
(left.resultdef.typ=floatdef) then
begin
result:=nil;
firstpass(left);
expectloc:=LOC_REGISTER;
exit;
end;
result:=nil;
firstpass(left);
if codegenerror then
exit;
expectloc:=LOC_REGISTER;
end;
procedure tcpuunaryminusnode.second_float;
begin
//secondpass(left);
//case current_settings.fputype of
// fpu_fpa,
// fpu_fpa10,
// fpu_fpa11:
// begin
// hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,false);
// location:=left.location;
// current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_const(A_RSF,
// location.register,left.location.register,0),
// cgsize2fpuoppostfix[def_cgsize(resultdef)]));
// end;
// fpu_soft:
// begin
// hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
// location:=left.location;
// case location.size of
// OS_32:
// cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register);
// OS_64:
// cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi);
// else
// internalerror(2014033101);
// end;
// end
// else if FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[init_settings.fputype] then
// begin
// hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
// location:=left.location;
// if (left.location.loc=LOC_CMMREGISTER) then
// location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
//
// if (tfloatdef(left.resultdef).floattype=s32real) then
// pf:=PF_F32
// else
// pf:=PF_F64;
//
// current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
// location.register,left.location.register), pf));
// cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
// end
// else if FPUARM_HAS_VFP_SINGLE_ONLY in fpu_capabilities[init_settings.fputype] then
// begin
// hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
// location:=left.location;
// if (left.location.loc=LOC_CMMREGISTER) then
// location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
// current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
// location.register,left.location.register), PF_F32));
// cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
// end
// else
// internalerror(2009112602);
//end;
secondpass(left);
case current_settings.fputype of
fpu_soft:
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
location:=left.location;
case location.size of
OS_32:
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register);
OS_64:
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi);
else
internalerror(2014033101);
end;
end
else
internalerror(2009112602);
end;
end;
procedure tcpushlshrnode.second_64bit;
@ -287,14 +196,15 @@ implementation
//cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
end;
begin
begin
inherited;
//if GenerateThumbCode or GenerateThumb2Code then
//begin
// inherited;
// exit;
//end;
//
location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
//location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
//location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
//location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
//

View File

@ -2,7 +2,7 @@
'none',
'add',
'and',
'bcc',
'b',
'bt',
'call0',
'call4',