diff --git a/compiler/mips/ncpuadd.pas b/compiler/mips/ncpuadd.pas index 06dcd85ada..1fd831a269 100644 --- a/compiler/mips/ncpuadd.pas +++ b/compiler/mips/ncpuadd.pas @@ -34,23 +34,18 @@ type tmipsaddnode = class(tcgaddnode) private - function cmp64_lt(left_reg, right_reg: TRegister64): TRegister; - function cmp64_le(left_reg, right_reg: TRegister64): TRegister; - function cmp64_eq(left_reg, right_reg: TRegister64): TRegister; - function cmp64_ne(left_reg, right_reg: TRegister64): TRegister; - function cmp64_ltu(left_reg, right_reg: TRegister64): TRegister; - function cmp64_leu(left_reg, right_reg: TRegister64): TRegister; - - function GetRes_register(unsigned: boolean; this_reg, left_reg, right_reg: TRegister): TRegister; - function GetRes64_register(unsigned: boolean; {this_reg,} left_reg, right_reg: TRegister64): TRegister; + procedure cmp64_lt(left_reg, right_reg: TRegister64;unsigned:boolean); + procedure cmp64_le(left_reg, right_reg: TRegister64;unsigned:boolean); + procedure second_generic_cmp32(unsigned: boolean); protected - function pass_1: tnode; override; procedure second_addfloat; override; procedure second_cmpfloat; override; procedure second_cmpboolean; override; procedure second_cmpsmallset; override; procedure second_cmp64bit; override; procedure second_cmpordinal; override; + public + function pass_1: tnode; override; end; implementation @@ -63,370 +58,219 @@ uses defutil, {cgbase,} cgcpu, cgutils, cpupara, + procinfo, + symconst,symdef, ncon, nset, nadd, ncgutil, cgobj; {***************************************************************************** tmipsaddnode *****************************************************************************} -function tmipsaddnode.GetRes_register(unsigned: boolean; this_reg, left_reg, right_reg: TRegister): TRegister; +const + swapped_nodetype: array[ltn..gten] of tnodetype = + //lt lte gt gte + (gtn, gten,ltn,lten); + + ops: array[boolean] of tasmop = (A_SLT,A_SLTU); + ops_immed: array[boolean] of tasmop = (A_SLTI,A_SLTIU); + +procedure tmipsaddnode.second_generic_cmp32(unsigned: boolean); var - tmp_asm_op: tasmop; + ntype: tnodetype; + tmp_left,tmp_right: TRegister; begin - case NodeType of - equaln: - tmp_asm_op := A_SEQ; - unequaln: - tmp_asm_op := A_SNE; - else - if not (unsigned) then - begin - if nf_swapped in flags then - case NodeType of - ltn: - tmp_asm_op := A_SGT; - lten: - tmp_asm_op := A_SGE; - gtn: - tmp_asm_op := A_SLT; - gten: - tmp_asm_op := A_SLE; - end - else - case NodeType of - ltn: - tmp_asm_op := A_SLT; - lten: - tmp_asm_op := A_SLE; - gtn: - tmp_asm_op := A_SGT; - gten: - tmp_asm_op := A_SGE; - end; - end - else - begin - if nf_swapped in Flags then - case NodeType of - ltn: - tmp_asm_op := A_SGTU; - lten: - tmp_asm_op := A_SGEU; - gtn: - tmp_asm_op := A_SLTU; - gten: - tmp_asm_op := A_SLEU; - end - else - case NodeType of - ltn: - tmp_asm_op := A_SLTU; - lten: - tmp_asm_op := A_SLEU; - gtn: - tmp_asm_op := A_SGTU; - gten: - tmp_asm_op := A_SGEU; - end; - end; - end; - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(tmp_asm_op, this_reg, left_reg, right_reg)); - GetRes_register := this_reg; -end; + pass_left_right; + force_reg_left_right(True, True); + location_reset(location,LOC_REGISTER,OS_INT); + location.register:=cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); -function tmipsaddnode.cmp64_eq(left_reg, right_reg: TRegister64): TRegister; -var - lfcmp64_L4: tasmlabel; - tmpreg : TRegister; - ai : TaiCpu; -begin - - tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - current_asmdata.getjumplabel(lfcmp64_L4); - - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 0)); - - ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - - //current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4)); - ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reglo, right_reg.reglo, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 1)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_eq := tmpreg; -end; - -function tmipsaddnode.cmp64_ne(left_reg, right_reg: TRegister64): TRegister; -var - lfcmp64_L4: tasmlabel; - tmpreg : TRegister; - ai : TaiCpu; -begin - - tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - current_asmdata.getjumplabel(lfcmp64_L4); - - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 1)); - - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4)); - ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - - //current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4)); - ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reglo, right_reg.reglo, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 0)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_ne := tmpreg; -end; - -function tmipsaddnode.cmp64_lt(left_reg, right_reg: TRegister64): TRegister; -var - lfcmp64_L4, lfcmp64_L5: tasmlabel; - tmpreg1,tmpreg2 : TRegister; - ai : TaiCpu; -begin - tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0)); - - current_asmdata.getjumplabel(lfcmp64_L4); - current_asmdata.getjumplabel(lfcmp64_L5); - - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, tmpreg2, left_reg.reghi, right_reg.reghi)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5)); - ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4)); - ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, left_reg.reglo, right_reg.reglo)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5)); - ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BA, lfcmp64_L4)); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_lt := tmpreg1; -end; - -function tmipsaddnode.cmp64_le(left_reg, right_reg: TRegister64): TRegister; -var - lfcmp64_L4, lfcmp64_L5: tasmlabel; - tmpreg1,tmpreg2 : TRegister; - ai : TaiCpu; -begin - tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0)); - - current_asmdata.getjumplabel(lfcmp64_L4); - current_asmdata.getjumplabel(lfcmp64_L5); - - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, tmpreg2, right_reg.reghi, left_reg.reghi)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4)); - ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5)); - ai := Taicpu.op_reg_reg_sym(A_BC, right_reg.reghi, left_reg.reghi, lfcmp64_L5); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, right_reg.reglo, left_reg.reglo)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4)); - ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_le := tmpreg1; -end; - -function tmipsaddnode.cmp64_ltu(left_reg, right_reg: TRegister64): TRegister; -var - lfcmp64_L4, lfcmp64_L5: tasmlabel; - tmpreg1,tmpreg2 : TRegister; - ai : TaiCpu; -begin - tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0)); - - current_asmdata.getjumplabel(lfcmp64_L4); - current_asmdata.getjumplabel(lfcmp64_L5); - - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, left_reg.reghi, right_reg.reghi)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5)); - ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4)); - ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, left_reg.reglo, right_reg.reglo)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5)); - ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BA, lfcmp64_L4)); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_ltu := tmpreg1; -end; - -function tmipsaddnode.cmp64_leu(left_reg, right_reg: TRegister64): TRegister; -var - lfcmp64_L4, lfcmp64_L5: tasmlabel; - tmpreg1,tmpreg2 : TRegister; - ai : TaiCpu; -begin - tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0)); - - current_asmdata.getjumplabel(lfcmp64_L4); - current_asmdata.getjumplabel(lfcmp64_L5); - - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, right_reg.reghi, left_reg.reghi)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4)); - ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5)); - ai := Taicpu.op_reg_reg_sym(A_BC, right_reg.reghi, left_reg.reghi, lfcmp64_L5); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, right_reg.reglo, left_reg.reglo)); - //current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4)); - ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4); - ai.setCondition(C_NE); - current_asmdata.CurrAsmList.concat(ai); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1)); - - cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_leu := tmpreg1; -end; - -function tmipsaddnode.GetRes64_register(unsigned: boolean; //this_reg: TRegister; - left_reg, right_reg: TRegister64): TRegister; -var - tmpreg: TRegister; - lfcmp64_L4, lfcmp_L5: tasmlabel; -begin - case NodeType of - equaln: + if nodetype in [equaln,unequaln] then begin - GetRes64_register := cmp64_eq(left_reg, right_reg); - end; - unequaln: - GetRes64_register := cmp64_ne(left_reg, right_reg); - else - if not (unsigned) then - begin - if nf_swapped in flags then - case NodeType of - ltn: - GetRes64_register := cmp64_lt(right_reg, left_reg); - lten: - GetRes64_register := cmp64_le(right_reg, left_reg); - gtn: - GetRes64_register := cmp64_lt(left_reg, right_reg); - gten: - GetRes64_register := cmp64_le(left_reg, right_reg); - end - else - case NodeType of - ltn: - GetRes64_register := cmp64_lt(left_reg, right_reg); - lten: - GetRes64_register := cmp64_le(left_reg, right_reg); - gtn: - GetRes64_register := cmp64_lt(right_reg, left_reg); - gten: - GetRes64_register := cmp64_le(right_reg, left_reg); - end; - end + tmp_left:=location.register; + { XORI needs unsigned immediate in range 0-65535 } + if (right.location.loc=LOC_CONSTANT) and (right.location.value>=0) and + (right.location.value<=65535) then + begin + if right.location.value<>0 then + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_XORI,location.register,left.location.register,right.location.value)) + else + tmp_left:=left.location.register; + end else - begin - if nf_swapped in Flags then - case NodeType of - ltn: - GetRes64_register := cmp64_ltu(right_reg, left_reg); - lten: - GetRes64_register := cmp64_leu(right_reg, left_reg); - gtn: - GetRes64_register := cmp64_ltu(left_reg, right_reg); - gten: - GetRes64_register := cmp64_leu(left_reg, right_reg); - end - else - case NodeType of - ltn: - GetRes64_register := cmp64_ltu(left_reg, right_reg); - lten: - GetRes64_register := cmp64_leu(left_reg, right_reg); - gtn: - GetRes64_register := cmp64_ltu(right_reg, left_reg); - gten: - GetRes64_register := cmp64_leu(right_reg, left_reg); + begin + if (right.location.loc<>LOC_CONSTANT) then + tmp_right:=right.location.register + else + begin + tmp_right:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT); + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,right.location.value,tmp_right); + end; + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_XOR,location.register,left.location.register,tmp_right)); + end; + + if nodetype=equaln then + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_SLTIU,location.register,tmp_left,1)) + else + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU,location.register,NR_R0,tmp_left)); + exit; + end; + + ntype:=nodetype; + if nf_swapped in flags then + ntype:=swapped_nodetype[nodetype]; + + { + sle x,a,b --> slt x,b,a; xori x,x,1 immediate not possible (or must be at left) + sgt x,a,b --> slt x,b,a likewise + sge x,a,b --> slt x,a,b; xori x,x,1 + slt x,a,b --> unchanged + } + + if (ntype in [gten,ltn]) and + (right.location.loc=LOC_CONSTANT) and + (right.location.value>=simm16lo) and + (right.location.value<=simm16hi) then + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(ops_immed[unsigned],location.register,left.location.register,right.location.value)) + else + begin + if (right.location.loc=LOC_CONSTANT) then + begin + if (right.location.value=0) then + tmp_right:=NR_R0 + else + begin + tmp_right:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT); + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,right.location.value,tmp_right); end; + end + else + tmp_right:=right.location.register; + + if (ntype in [lten,gtn]) then + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(ops[unsigned],location.register,tmp_right,left.location.register)) + else + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(ops[unsigned],location.register,left.location.register,tmp_right)); + end; + if (ntype in [lten,gten]) then + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_XORI,location.register,location.register,1)); +end; + + +procedure tmipsaddnode.cmp64_lt(left_reg, right_reg: TRegister64;unsigned: boolean); +var + hreg: tregister; +begin + hreg:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(ops[unsigned], hreg, left_reg.reghi, right_reg.reghi)); + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,NR_R0,hreg,current_procinfo.CurrTrueLabel); + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,current_procinfo.CurrFalseLabel); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, hreg, left_reg.reglo, right_reg.reglo)); + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,NR_R0,hreg,current_procinfo.CurrTrueLabel); + cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel); +end; + + +procedure tmipsaddnode.cmp64_le(left_reg, right_reg: TRegister64;unsigned: boolean); +var + hreg: TRegister; +begin + hreg:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_INT); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(ops[unsigned], hreg, right_reg.reghi, left_reg.reghi)); + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,NR_R0,hreg,current_procinfo.CurrFalseLabel); + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,current_procinfo.CurrTrueLabel); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, hreg, right_reg.reglo, left_reg.reglo)); + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,NR_R0,hreg,current_procinfo.CurrFalseLabel); + cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel); +end; + + +procedure tmipsaddnode.second_cmp64bit; +var + unsigned: boolean; + left_reg,right_reg: TRegister64; +begin + location_reset(location, LOC_JUMP, OS_NO); + pass_left_right; + force_reg_left_right(true,true); + + unsigned:=not(is_signed(left.resultdef)) or + not(is_signed(right.resultdef)); + + left_reg:=left.location.register64; + if (right.location.loc=LOC_CONSTANT) then + begin + if lo(right.location.value64)=0 then + right_reg.reglo:=NR_R0 + else + begin + right_reg.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,lo(right.location.value64),right_reg.reglo); + end; + if hi(right.location.value64)=0 then + right_reg.reghi:=NR_R0 + else + begin + right_reg.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,hi(right.location.value64),right_reg.reghi); + end; + end + else + right_reg:=right.location.register64; + + case NodeType of + equaln: + begin + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,current_procinfo.CurrFalseLabel); + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,current_procinfo.CurrFalseLabel); + cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel); + end; + unequaln: + begin + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,current_procinfo.CurrTrueLabel); + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,current_procinfo.CurrTrueLabel); + cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel); + end; + else + if nf_swapped in flags then + case NodeType of + ltn: + cmp64_lt(right_reg, left_reg,unsigned); + lten: + cmp64_le(right_reg, left_reg,unsigned); + gtn: + cmp64_lt(left_reg, right_reg,unsigned); + gten: + cmp64_le(left_reg, right_reg,unsigned); + end + else + case NodeType of + ltn: + cmp64_lt(left_reg, right_reg,unsigned); + lten: + cmp64_le(left_reg, right_reg,unsigned); + gtn: + cmp64_lt(right_reg, left_reg,unsigned); + gten: + cmp64_le(right_reg, left_reg,unsigned); end; end; end; function tmipsaddnode.pass_1 : tnode; - var - unsigned : boolean; begin result:=inherited pass_1; if not(assigned(result)) then begin if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) then - expectloc:=LOC_REGISTER; + begin + if (left.resultdef.typ=floatdef) or (right.resultdef.typ=floatdef) then + expectloc:=LOC_JUMP + else if ((left.resultdef.typ<>orddef) or + (not (torddef(left.resultdef).ordtype in [s64bit,u64bit,scurrency]))) then + expectloc:=LOC_REGISTER; + end; end; end; @@ -488,197 +332,69 @@ begin end; +const + ops_cmpfloat: array[boolean,ltn..unequaln] of TAsmOp = ( + // ltn lten gtn gten equaln unequaln + (A_C_LT_S, A_C_LE_S, A_C_LT_S, A_C_LE_S, A_C_EQ_S, A_C_EQ_S), + (A_C_LT_D, A_C_LE_D, A_C_LT_D, A_C_LE_D, A_C_EQ_D, A_C_EQ_D) + ); + procedure tmipsaddnode.second_cmpfloat; var - op: tasmop; - lfcmptrue, lfcmpfalse: tasmlabel; + op,op2: tasmop; + lreg,rreg: tregister; begin pass_left_right; if nf_swapped in flags then swapleftright; - { force fpureg as location, left right doesn't matter - as both will be in a fpureg } location_force_fpureg(current_asmdata.CurrAsmList, left.location, True); location_force_fpureg(current_asmdata.CurrAsmList, right.location, True); + location_reset(location, LOC_JUMP, OS_NO); - location_reset(location, LOC_REGISTER, OS_INT); - location.Register := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); + op:=ops_cmpfloat[left.location.size=OS_F64,nodetype]; - case NodeType of - equaln: - begin - if left.location.size = OS_F64 then - op := A_C_EQ_D - else - op := A_C_EQ_S; - current_asmdata.getjumplabel(lfcmpfalse); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register , NR_R0, NR_R0)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register)); - current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1F, lfcmpfalse)); //lfcmpfalse - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1)); - cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse); + if (nodetype=unequaln) then + op2:=A_BC1F + else + op2:=A_BC1T; - end; - unequaln: + if (nodetype in [gtn,gten]) then begin - if left.location.size = OS_F64 then - op := A_C_EQ_D - else - op := A_C_EQ_S; - current_asmdata.getjumplabel(lfcmpfalse); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register)); - current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1F, lfcmpfalse)); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register , NR_R0, NR_R0)); - cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse); - end; - ltn: + lreg:=right.location.register; + rreg:=left.location.register; + end + else begin - if left.location.size = OS_F64 then - op := A_C_LT_D - else - op := A_C_LT_S; - current_asmdata.getjumplabel(lfcmptrue); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register)); - current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue)); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0)); - cg.a_label(current_asmdata.CurrAsmList, lfcmptrue); + lreg:=left.location.register; + rreg:=right.location.register; end; - lten: - begin - if left.location.size = OS_F64 then - op := A_C_LE_D - else - op := A_C_LE_S; - current_asmdata.getjumplabel(lfcmptrue); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register)); - current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue)); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0)); - cg.a_label(current_asmdata.CurrAsmList, lfcmptrue); - end; - gtn: - begin - if left.location.size = OS_F64 then - op := A_C_LT_D - else - op := A_C_LT_S; - current_asmdata.getjumplabel(lfcmptrue); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, right.location.Register, left.location.Register)); - current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue)); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0)); - cg.a_label(current_asmdata.CurrAsmList, lfcmptrue); - end; - gten: - begin - if left.location.size = OS_F64 then - op := A_C_LE_D - else - op := A_C_LE_S; - current_asmdata.getjumplabel(lfcmptrue); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, right.location.Register, left.location.Register)); - current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue)); - current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0)); - cg.a_label(current_asmdata.CurrAsmList, lfcmptrue); - end; - end; {case} + + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,lreg,rreg)); + current_asmdata.CurrAsmList.concat(Taicpu.op_sym(op2,current_procinfo.CurrTrueLabel)); + current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP)); + cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel); end; procedure tmipsaddnode.second_cmpboolean; -var - tmp_right_reg, tmpreg: TRegister; begin - pass_left_right; - force_reg_left_right(True, True); - tmp_right_reg := NR_NO; - tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - if right.location.loc = LOC_CONSTANT then - begin - tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value)); - end - else - tmp_right_reg := right.location.Register; - - location_reset(location, LOC_REGISTER, OS_INT); - location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg); + second_generic_cmp32(true); end; procedure tmipsaddnode.second_cmpsmallset; -var - tmp_right_reg, tmpreg: TRegister; begin - pass_left_right; - force_reg_left_right(True, True); - - tmp_right_reg := NR_NO; - tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - - if right.location.loc = LOC_CONSTANT then - begin - tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value)); - end - else - begin - tmp_right_reg := right.location.Register; - end; - - - location_reset(location, LOC_REGISTER, OS_INT); - location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg); -end; - - -procedure tmipsaddnode.second_cmp64bit; -var - unsigned : boolean; - tmp_left_reg: TRegister; - -begin - pass_left_right; - force_reg_left_right(false,false); - - unsigned:=not(is_signed(left.resultdef)) or - not(is_signed(right.resultdef)); - - location_reset(location, LOC_REGISTER, OS_INT); - location.Register := GetRes64_register(unsigned, left.location.register64, right.location.register64); + second_generic_cmp32(true); end; procedure tmipsaddnode.second_cmpordinal; var unsigned: boolean; - tmp_right_reg,tmpreg: TRegister; begin - pass_left_right; - force_reg_left_right(True, True); unsigned := not (is_signed(left.resultdef)) or not (is_signed(right.resultdef)); - - tmp_right_reg := NR_NO; - tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - if right.location.loc = LOC_CONSTANT then - begin - tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value)); - end - else - tmp_right_reg := right.location.Register; - location_reset(location, LOC_REGISTER, OS_INT); - location.Register := getres_register(unsigned, tmpreg, left.location.Register, tmp_right_reg); + second_generic_cmp32(unsigned); end; begin