diff --git a/compiler/xtensa/aasmcpu.pas b/compiler/xtensa/aasmcpu.pas index 6ab3d41d4f..b20ab0225a 100644 --- a/compiler/xtensa/aasmcpu.pas +++ b/compiler/xtensa/aasmcpu.pas @@ -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; diff --git a/compiler/xtensa/agcpugas.pas b/compiler/xtensa/agcpugas.pas index 28375ef9c0..9cd1a1c94c 100644 --- a/compiler/xtensa/agcpugas.pas +++ b/compiler/xtensa/agcpugas.pas @@ -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; diff --git a/compiler/xtensa/cpubase.pas b/compiler/xtensa/cpubase.pas index 1637b3f80c..c313689b0d 100644 --- a/compiler/xtensa/cpubase.pas +++ b/compiler/xtensa/cpubase.pas @@ -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; diff --git a/compiler/xtensa/ncpuadd.pas b/compiler/xtensa/ncpuadd.pas index 018f93782c..4fffcd3712 100644 --- a/compiler/xtensa/ncpuadd.pas +++ b/compiler/xtensa/ncpuadd.pas @@ -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; diff --git a/compiler/xtensa/ncpumat.pas b/compiler/xtensa/ncpumat.pas index ad088862fb..79d97e778f 100644 --- a/compiler/xtensa/ncpumat.pas +++ b/compiler/xtensa/ncpumat.pas @@ -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); // diff --git a/compiler/xtensa/xtensaatt.inc b/compiler/xtensa/xtensaatt.inc index 6b4e274799..5a6d2de970 100644 --- a/compiler/xtensa/xtensaatt.inc +++ b/compiler/xtensa/xtensaatt.inc @@ -2,7 +2,7 @@ 'none', 'add', 'and', -'bcc', +'b', 'bt', 'call0', 'call4',