diff --git a/compiler/mips/aasmcpu.pas b/compiler/mips/aasmcpu.pas index 67c1e4335f..065e23d67f 100644 --- a/compiler/mips/aasmcpu.pas +++ b/compiler/mips/aasmcpu.pas @@ -195,12 +195,7 @@ end; constructor taicpu.op_sym(op: tasmop; _op1: tasmsymbol); begin inherited Create(op); - is_jmp := op in [A_J, A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI, - A_BLTUI, A_BLEUI, A_BGTUI, A_BGEUI, - A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE, - A_BLTU, A_BLEU, A_BGTU, A_BGEU - ]; - + is_jmp := op in [A_BC, A_BA]; ops := 1; loadsymbol(0, _op1, 0); end; @@ -208,10 +203,7 @@ end; constructor taicpu.op_reg_reg_sym(op: tasmop; _op1, _op2: tregister; _op3: tasmsymbol); begin inherited create(op); - is_jmp := op in [A_J, - A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI, A_BLTUI, A_BLEUI, - A_BGTUI, A_BGEUI, - A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE, A_BLTU, A_BLEU, A_BGTU, A_BGEU]; + is_jmp := op in [A_BC, A_BA]; ops := 3; loadreg(0, _op1); loadreg(1, _op2); @@ -221,10 +213,7 @@ end; constructor taicpu.op_reg_sym(op: tasmop; _op1: tregister; _op2: tasmsymbol); begin inherited create(op); - is_jmp := op in [A_J, - A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI, A_BLTUI, A_BLEUI, - A_BGTUI, A_BGEUI, - A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE, A_BLTU, A_BLEU, A_BGTU, A_BGEU, A_BGTZ]; + is_jmp := op in [A_BC, A_BA]; ops := 2; loadreg(0, _op1); loadsymbol(1, _op2, 0); diff --git a/compiler/mips/aoptcpub.pas b/compiler/mips/aoptcpub.pas index c758c914b0..ed51361166 100644 --- a/compiler/mips/aoptcpub.pas +++ b/compiler/mips/aoptcpub.pas @@ -93,8 +93,8 @@ Const StoreDst = 1; - aopt_uncondjmp = A_J; - aopt_condjmp = A_BEQ; + aopt_uncondjmp = A_BA; + aopt_condjmp = A_BC; Implementation diff --git a/compiler/mips/cgcpu.pas b/compiler/mips/cgcpu.pas index 2523761f04..d4780d777f 100644 --- a/compiler/mips/cgcpu.pas +++ b/compiler/mips/cgcpu.pas @@ -27,7 +27,7 @@ interface uses globtype, parabase, - cgbase, cgutils, cgobj, cg64f32, + cgbase, cgutils, cgobj, cg64f32, cpupara, aasmbase, aasmtai, aasmcpu, aasmdata, cpubase, cpuinfo, node, symconst, SymType, symdef, @@ -36,6 +36,7 @@ uses type TCGMIPS = class(tcg) public + procedure init_register_allocators; override; procedure done_register_allocators; override; function getfpuregister(list: tasmlist; size: Tcgsize): Tregister; override; @@ -106,6 +107,11 @@ type procedure create_codegen; + const + TOpCmp2AsmCond : array[topcmp] of TAsmCond=(C_NONE, + C_EQ,C_GT,C_LT,C_GE,C_LE,C_NE,C_LEU,C_LTU,C_GEU,C_GTU + ); + implementation uses @@ -311,7 +317,7 @@ begin if (cs_create_pic in current_settings.moduleswitches) and assigned(ref.symbol) then begin - tmpreg := GetIntRegister(list, OS_INT); + tmpreg := cg.GetIntRegister(list, OS_INT); reference_reset(tmpref,sizeof(aint)); tmpref.symbol := ref.symbol; tmpref.refaddr := addr_pic; @@ -518,12 +524,18 @@ begin RS_R20,RS_R21,RS_R22,RS_R23,RS_R24,RS_R25], first_int_imreg, []); +{ rg[R_FPUREGISTER] := trgcpu.Create(R_FPUREGISTER, R_SUBFS, [RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7, RS_F8,RS_F9,RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15, RS_F16,RS_F17,RS_F18,RS_F19,RS_F20,RS_F21,RS_F22,RS_F23, RS_F24,RS_F25,RS_F26,RS_F27,RS_F28,RS_F29,RS_F30,RS_F31], first_fpu_imreg, []); +} + rg[R_FPUREGISTER] := trgcpu.Create(R_FPUREGISTER, R_SUBFS, + [RS_F0,RS_F2,RS_F4,RS_F6, RS_F8,RS_F10,RS_F12,RS_F14, + RS_F16,RS_F18,RS_F20,RS_F22, RS_F24,RS_F26,RS_F28,RS_F30], + first_fpu_imreg, []); { needs at least one element for rgobj not to crash } rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE, @@ -1235,6 +1247,7 @@ end; procedure TCGMIPS.a_cmp_const_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); var tmpreg: tregister; + ai : Taicpu; begin if a = 0 then tmpreg := NR_R0 @@ -1243,75 +1256,37 @@ begin tmpreg := GetIntRegister(list, OS_INT); list.concat(taicpu.op_reg_const(A_LI, tmpreg, a)); end; - case cmp_op of - OC_EQ: { equality comparison } - list.concat(taicpu.op_reg_reg_sym(A_BEQ, reg, tmpreg, l)); - OC_GT: { greater than (signed) } - list.concat(taicpu.op_reg_reg_sym(A_BGT, reg, tmpreg, l)); - OC_LT: { less than (signed) } - list.concat(taicpu.op_reg_reg_sym(A_BLT, reg, tmpreg, l)); - OC_GTE: { greater or equal than (signed) } - list.concat(taicpu.op_reg_reg_sym(A_BGE, reg, tmpreg, l)); - OC_LTE: { less or equal than (signed) } - list.concat(taicpu.op_reg_reg_sym(A_BLE, reg, tmpreg, l)); - OC_NE: { not equal } - list.concat(taicpu.op_reg_reg_sym(A_BNE, reg, tmpreg, l)); - OC_BE: { less or equal than (unsigned) } - list.concat(taicpu.op_reg_reg_sym(A_BLEU, reg, tmpreg, l)); - OC_B: { less than (unsigned) } - list.concat(taicpu.op_reg_reg_sym(A_BLTU, reg, tmpreg, l)); - OC_AE: { greater or equal than (unsigned) } - list.concat(taicpu.op_reg_reg_sym(A_BGEU, reg, tmpreg, l)); - OC_A: { greater than (unsigned) } - list.concat(taicpu.op_reg_reg_sym(A_BGTU, reg, tmpreg, l)); - else - internalerror(200701071); - end; + ai := taicpu.op_reg_reg_sym(A_BC, reg, tmpreg, l); + ai.SetCondition(TOpCmp2AsmCond[cmp_op]); + list.concat(ai); list.Concat(TAiCpu.Op_none(A_NOP)); end; procedure TCGMIPS.a_cmp_reg_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel); +var + ai : Taicpu; begin - case cmp_op of - OC_EQ: { equality comparison } - list.concat(taicpu.op_reg_reg_sym(A_BEQ, reg2, reg1, l)); - OC_GT: { greater than (signed) } - list.concat(taicpu.op_reg_reg_sym(A_BGT, reg2, reg1, l)); - OC_LT: { less than (signed) } - list.concat(taicpu.op_reg_reg_sym(A_BLT, reg2, reg1, l)); - OC_GTE: { greater or equal than (signed) } - list.concat(taicpu.op_reg_reg_sym(A_BGE, reg2, reg1, l)); - OC_LTE: { less or equal than (signed) } - list.concat(taicpu.op_reg_reg_sym(A_BLE, reg2, reg1, l)); - OC_NE: { not equal } - list.concat(taicpu.op_reg_reg_sym(A_BNE, reg2, reg1, l)); - OC_BE: { less or equal than (unsigned) } - list.concat(taicpu.op_reg_reg_sym(A_BLEU, reg2, reg1, l)); - OC_B: { less than (unsigned) } - list.concat(taicpu.op_reg_reg_sym(A_BLTU, reg2, reg1, l)); - OC_AE: { greater or equal than (unsigned) } - list.concat(taicpu.op_reg_reg_sym(A_BGEU, reg2, reg1, l)); - OC_A: { greater than (unsigned) } - list.concat(taicpu.op_reg_reg_sym(A_BGTU, reg2, reg1, l)); - else - internalerror(200701072); - end;{ case } + ai := taicpu.op_reg_reg_sym(A_BC, reg2, reg1, l); + ai.SetCondition(TOpCmp2AsmCond[cmp_op]); + list.concat(ai); list.Concat(TAiCpu.Op_none(A_NOP)); end; procedure TCGMIPS.a_jmp_always(List: tasmlist; l: TAsmLabel); +var + ai : Taicpu; begin - List.Concat(TAiCpu.op_sym(A_J,l)); - { Delay slot } + ai := taicpu.op_sym(A_BA, l); + list.concat(ai); list.Concat(TAiCpu.Op_none(A_NOP)); end; procedure TCGMIPS.a_jmp_name(list: tasmlist; const s: string); begin - List.Concat(TAiCpu.op_sym(A_J, current_asmdata.RefAsmSymbol(s))); + List.Concat(TAiCpu.op_sym(A_BA, current_asmdata.RefAsmSymbol(s))); { Delay slot } list.Concat(TAiCpu.Op_none(A_NOP)); end; @@ -1341,6 +1316,8 @@ procedure TCGMIPS.g_proc_entry(list: tasmlist; localsize: longint; nostackframe: var lastintoffset,lastfpuoffset, nextoffset : aint; + i : longint; + ra_save,framesave : taicpu; fmask,mask : dword; saveregs : tcpuregisterset; href: treference; @@ -1348,14 +1325,8 @@ var reg : Tsuperregister; helplist : TAsmList; begin - { - if STK2_dummy <> 0 then - begin - list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, -STK2_dummy)); - end; - } a_reg_alloc(list,NR_STACK_POINTER_REG); - if current_procinfo.framepointer<>NR_STACK_POINTER_REG then + // if current_procinfo.framepointer<>NR_STACK_POINTER_REG then a_reg_alloc(list,NR_FRAME_POINTER_REG); if nostackframe then @@ -1368,9 +1339,7 @@ begin { if current_procinfo.framepointer<>NR_STACK_POINTER_REG then list.concat(Taicpu.Op_reg_reg_const(A_P_SW, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG, -LocalSize)); } - { if current_procinfo.framepointer<>NR_STACK_POINTER_REG then - list.concat(Taicpu.op_reg_reg(A_MOVE, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG)); - } + reference_reset(href,0); href.base:=NR_STACK_POINTER_REG; @@ -1397,7 +1366,11 @@ begin nextoffset:=TMIPSProcInfo(current_procinfo).intregstart; saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall); include(saveregs,RS_R31); + //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then + include(saveregs,RS_FRAME_POINTER_REG); lastintoffset:=LocalSize; + framesave:=nil; + for reg:=RS_R1 to RS_R31 do begin if reg in saveregs then @@ -1406,24 +1379,67 @@ begin mask:=mask or (1 shl ord(reg)); href.offset:=nextoffset; lastintoffset:=nextoffset; - helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)); + if (reg=RS_FRAME_POINTER_REG) then + framesave:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href) + else if (reg=RS_R31) then + ra_save:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href) + else + helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)); inc(nextoffset,4); end; end; + //list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_FRAME_POINTER_REG,NR_STACK_POINTER_REG,current_procinfo.para_stack_size)); list.concat(Taicpu.op_none(A_P_SET_NOMIPS16)); - list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,current_procinfo.framepointer,LocalSize,NR_R31)); + list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,NR_STACK_POINTER_REG,LocalSize,NR_R31)); list.concat(Taicpu.op_const_const(A_P_MASK,mask,-(LocalSize-lastintoffset))); list.concat(Taicpu.op_const_const(A_P_FMASK,Fmask,-(LocalSize-lastfpuoffset))); list.concat(Taicpu.op_none(A_P_SET_NOREORDER)); list.concat(Taicpu.op_none(A_P_SET_NOMACRO)); if (-LocalSize >= simm16lo) and (-LocalSize <= simm16hi) then - list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-LocalSize)) + begin + list.concat(Taicpu.Op_reg_reg_const(A_ADDI,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-LocalSize)); + list.concat(ra_save); + //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then + begin + list.concat(framesave); + list.concat(Taicpu.op_reg_reg_const(A_ADDIU,NR_FRAME_POINTER_REG, + NR_STACK_POINTER_REG,LocalSize)); + end; + end else begin list.concat(Taicpu.Op_reg_const(A_LI,NR_R3,-LocalSize)); list.concat(Taicpu.Op_reg_reg_reg(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R3)); + list.concat(ra_save); + //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then + begin + list.concat(framesave); + list.concat(Taicpu.op_reg_reg_reg(A_SUB,NR_FRAME_POINTER_REG, + NR_STACK_POINTER_REG,NR_R3)); + end; + end; + + with TMIPSProcInfo(current_procinfo) do + begin + href.offset:=0; + //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then + href.base:=NR_FRAME_POINTER_REG; + + for i:=0 to MIPS_MAX_REGISTERS_USED_IN_CALL-1 do + if (register_used[i]) then + begin + reg:=parainsupregs[i]; + if register_offset[i]=-1 then + comment(V_warning,'Register parameter has offset -1 in TCGMIPS.g_proc_entry'); + + //if current_procinfo.framepointer=NR_STACK_POINTER_REG then + // href.offset:=register_offset[i]+Localsize + //else + href.offset:=register_offset[i]; + list.concat(taicpu.op_reg_ref(A_SW, newreg(R_INTREGISTER,reg,R_SUBWHOLE), href)); + end; end; if (cs_create_pic in current_settings.moduleswitches) and @@ -1447,9 +1463,6 @@ begin stacksize:=current_procinfo.calc_stackframe_size; if nostackframe then begin - { if STK2_dummy <> 0 then - list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, STK2_dummy)); - } list.concat(taicpu.op_reg(A_J, NR_R31)); list.concat(Taicpu.op_none(A_NOP)); list.concat(Taicpu.op_none(A_P_SET_MACRO)); @@ -1474,12 +1487,14 @@ begin nextoffset:=TMIPSProcInfo(current_procinfo).intregstart; saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall); include(saveregs,RS_R31); + //if current_procinfo.framepointer<>NR_STACK_POINTER_REG then + include(saveregs,RS_FRAME_POINTER_REG); for reg:=RS_R1 to RS_R31 do begin if reg in saveregs then begin href.offset:=nextoffset; - list.concat(taicpu.op_reg_ref(A_LD,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)); + list.concat(taicpu.op_reg_ref(A_LW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)); inc(nextoffset,sizeof(aint)); end; end; @@ -1539,6 +1554,7 @@ var src, dst: TReference; lab: tasmlabel; Count, count2: aint; + ai : TaiCpu; begin if len > high(longint) then internalerror(2002072704); @@ -1575,7 +1591,10 @@ begin list.concat(taicpu.op_reg_reg_const(A_ADDIU, src.base, src.base, 4)); list.concat(taicpu.op_reg_reg_const(A_ADDIU, dst.base, dst.base, 4)); list.concat(taicpu.op_reg_reg_const(A_ADDIU, countreg, countreg, -1)); - list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab)); + //list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab)); + ai := taicpu.op_reg_reg_sym(A_BC,countreg, NR_R0, lab); + ai.setcondition(C_GT); + list.concat(ai); list.concat(taicpu.op_none(A_NOP)); len := len mod 4; end; @@ -1626,6 +1645,7 @@ var tmpreg1, countreg: TRegister; i: aint; lab: tasmlabel; + ai : TaiCpu; begin if len > 31 then g_concatcopy_move(list, Source, dest, len) @@ -1646,8 +1666,8 @@ begin { have to be set to 8. I put an Inc there so debugging may be } { easier (should offset be different from zero here, it will be } { easy to notice in the generated assembler } - countreg := GetIntRegister(list, OS_INT); - tmpreg1 := GetIntRegister(list, OS_INT); + countreg := cg.GetIntRegister(list, OS_INT); + tmpreg1 := cg.GetIntRegister(list, OS_INT); a_load_const_reg(list, OS_INT, len, countreg); { explicitely allocate R_O0 since it can be used safely here } { (for holding date that's being copied) } @@ -1658,13 +1678,16 @@ begin list.concat(taicpu.op_reg_reg_const(A_ADDIU, src.base, src.base, 1)); list.concat(taicpu.op_reg_reg_const(A_ADDIU, dst.base, dst.base, 1)); list.concat(taicpu.op_reg_reg_const(A_ADDIU, countreg, countreg, -1)); - list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab)); + //list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab)); + ai := taicpu.op_reg_reg_sym(A_BC,countreg, NR_R0, lab); + ai.setcondition(C_GT); + list.concat(ai); list.concat(taicpu.op_none(A_NOP)); end else begin { unrolled loop } - tmpreg1 := GetIntRegister(list, OS_INT); + tmpreg1 := cg.GetIntRegister(list, OS_INT); for i := 1 to len do begin list.concat(taicpu.op_reg_ref(A_LBU, tmpreg1, src)); @@ -1679,25 +1702,25 @@ end; procedure TCGMIPS.g_intf_wrapper(list: tasmlist; procdef: tprocdef; const labelname: string; ioffset: longint); - procedure loadvmttor24; + procedure loadvmttor25; var href: treference; begin reference_reset_base(href, NR_R2, 0, sizeof(aint)); { return value } - cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R24); + cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R25); end; - procedure op_onr24methodaddr; + procedure op_onr25methodaddr; var href : treference; begin if (procdef.extnumber=$ffff) then Internalerror(200006139); { call/jmp vmtoffs(%eax) ; method offs } - reference_reset_base(href, NR_R24, tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber), sizeof(aint)); - cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R24); - list.concat(taicpu.op_reg(A_JR, NR_R24)); + reference_reset_base(href, NR_R25, tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber), sizeof(aint)); + cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R25); + list.concat(taicpu.op_reg(A_JR, NR_R25)); end; var make_global: boolean; @@ -1728,8 +1751,8 @@ begin if (po_virtualmethod in procdef.procoptions) and not is_objectpascal_helper(procdef.struct) then begin - loadvmttor24; - op_onr24methodaddr; + loadvmttor25; + op_onr25methodaddr; end else list.concat(taicpu.op_sym(A_J,current_asmdata.RefAsmSymbol(procdef.mangledname))); @@ -1790,26 +1813,21 @@ begin a_load64_reg_cgpara(list, hreg64, paraloc); end; - - - procedure TCg64MPSel.a_op64_reg_reg(list: tasmlist; op: TOpCG; size: tcgsize; regsrc, regdst: TRegister64); var op1, op2, op_call64: TAsmOp; tmpreg1, tmpreg2: TRegister; begin - tmpreg1 := NR_TCR12; //GetIntRegister(list, OS_INT); - tmpreg2 := NR_TCR13; //GetIntRegister(list, OS_INT); + tmpreg1 := cg.GetIntRegister(list, OS_INT); + tmpreg2 := cg.GetIntRegister(list, OS_INT); case op of OP_ADD: begin - list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg1, regsrc.reglo, regdst.reglo)); - list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, tmpreg1, regsrc.reglo)); + list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reglo, regsrc.reglo, regdst.reglo)); + list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regdst.reglo, regsrc.reglo)); list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg2, regsrc.reghi, regdst.reghi)); - list.concat(taicpu.op_reg_reg_reg(A_ADDU, NR_TCR10, NR_TCR10, tmpreg2)); - list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1)); - list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, NR_TCR10)); + list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, tmpreg1, tmpreg2)); exit; end; OP_AND: @@ -1822,10 +1840,10 @@ begin OP_NEG: begin list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reglo, NR_R0, regsrc.reglo)); - list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, NR_R0, regdst.reglo)); + list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, NR_R0, regdst.reglo)); list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, NR_R0, regsrc.reghi)); - list.concat(taicpu.op_reg_reg_reg(A_SUBU, NR_TCR10, regdst.reghi, NR_TCR10)); - list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, NR_TCR10)); + list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regdst.reghi, tmpreg1)); + list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg1)); exit; end; OP_NOT: @@ -1843,11 +1861,10 @@ begin OP_SUB: begin list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regdst.reglo, regsrc.reglo)); - list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, regdst.reglo, tmpreg1)); - list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg2, regdst.reghi, regsrc.reghi)); - list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg2, tmpreg2, NR_TCR10)); + list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, regdst.reglo, tmpreg1)); + list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regdst.reghi, regsrc.reghi)); + list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regdst.reghi, tmpreg2)); list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1)); - list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg2)); exit; end; OP_XOR: @@ -1860,26 +1877,14 @@ begin internalerror(200306017); end; {case} - - - end; procedure TCg64MPSel.a_op64_const_reg(list: tasmlist; op: TOpCG; size: tcgsize; Value: int64; regdst: TRegister64); -var - op1, op2: TAsmOp; begin - case op of - OP_NEG, - OP_NOT: - internalerror(200306017); - end; a_op64_const_reg_reg(list, op, size, value, regdst, regdst); - end; - procedure TCg64MPSel.a_op64_const_reg_reg(list: tasmlist; op: TOpCG; size: tcgsize; Value: int64; regsrc, regdst: tregister64); var l: tlocation; @@ -1898,59 +1903,15 @@ end; procedure TCg64MPSel.a_op64_const_reg_reg_checkoverflow(list: tasmlist; op: TOpCG; size: tcgsize; Value: int64; regsrc, regdst: tregister64; setflags: boolean; var ovloc: tlocation); var - op1, op2: TAsmOp; - tmpreg1: TRegister; + tmpreg64: TRegister64; begin - tmpreg1 := NR_TCR12; - case op of - OP_NEG, - OP_NOT: - internalerror(200306017); - end; + tmpreg64.reglo := cg.GetIntRegister(list, OS_S32); + tmpreg64.reghi := cg.GetIntRegister(list, OS_S32); - list.concat(taicpu.op_reg_const(A_LI, NR_TCR10, aint(hi(Value)))); - list.concat(taicpu.op_reg_const(A_LI, NR_TCR11, aint(lo(Value)))); - case op of - OP_ADD: - begin - list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reglo, regsrc.reglo, NR_TCR10)); - list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regdst.reglo, regsrc.reglo)); - list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, regsrc.reghi, NR_TCR11)); - list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg1, tmpreg1, regdst.reghi)); - list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg1)); - exit; - end; - OP_AND: - begin - list.concat(taicpu.op_reg_reg_reg(A_AND, regdst.reglo, regsrc.reglo, NR_TCR10)); - list.concat(taicpu.op_reg_reg_reg(A_AND, regdst.reghi, regsrc.reghi, NR_TCR11)); - exit; - end; + list.concat(taicpu.op_reg_const(A_LI, tmpreg64.reglo, aint(lo(Value)))); + list.concat(taicpu.op_reg_const(A_LI, tmpreg64.reghi, aint(hi(Value)))); - OP_OR: - begin - list.concat(taicpu.op_reg_reg_reg(A_OR, regdst.reglo, regsrc.reglo, NR_TCR10)); - list.concat(taicpu.op_reg_reg_reg(A_OR, regdst.reghi, regsrc.reghi, NR_TCR11)); - exit; - end; - OP_SUB: - begin - list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reglo, regsrc.reglo, NR_TCR10)); - list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regsrc.reglo, regdst.reglo)); - list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regsrc.reghi, NR_TCR11)); - list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regdst.reghi, tmpreg1)); - list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg1)); - exit; - end; - OP_XOR: - begin - list.concat(taicpu.op_reg_reg_reg(A_XOR, regdst.reglo, regsrc.reglo, NR_TCR10)); - list.concat(taicpu.op_reg_reg_reg(A_XOR, regdst.reghi, regsrc.reghi, NR_TCR11)); - exit; - end; - else - internalerror(200306017); - end; + a_op64_reg_reg_reg_checkoverflow(list, op, size, tmpreg64, regsrc, regdst, False, ovloc); end; @@ -1961,22 +1922,15 @@ var tmpreg1, tmpreg2: TRegister; begin - tmpreg1 := NR_TCR12; - tmpreg2 := NR_TCR13; - case op of - OP_NEG, - OP_NOT: - internalerror(200306017); - end; case op of OP_ADD: begin - list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg1, regsrc2.reglo, regsrc1.reglo)); - list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, tmpreg1, regsrc2.reglo)); - list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg2, regsrc2.reghi, regsrc1.reghi)); - list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, NR_TCR10, tmpreg2)); - list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1)); + tmpreg1 := cg.GetIntRegister(list,OS_S32); + list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reglo, regsrc2.reglo, regsrc1.reglo)); + list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regdst.reglo, regsrc2.reglo)); + list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, regsrc2.reghi, regsrc1.reghi)); + list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, regdst.reghi, tmpreg1)); exit; end; OP_AND: @@ -1993,11 +1947,11 @@ begin end; OP_SUB: begin - list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regsrc2.reglo, regsrc1.reglo)); - list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, regsrc2.reglo, tmpreg1)); - list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg2, regsrc2.reghi, regsrc1.reghi)); - list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, tmpreg2, NR_TCR10)); - list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1)); + tmpreg1 := cg.GetIntRegister(list,OS_S32); + list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reglo, regsrc2.reglo, regsrc1.reglo)); + list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regsrc2.reglo, regdst.reglo)); + list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regsrc2.reghi, regsrc1.reghi)); + list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regdst.reghi, tmpreg1)); exit; end; OP_XOR: diff --git a/compiler/mips/cpubase.pas b/compiler/mips/cpubase.pas index 29c73d8f35..76ef839b19 100644 --- a/compiler/mips/cpubase.pas +++ b/compiler/mips/cpubase.pas @@ -181,7 +181,6 @@ unit cpubase; Generic Register names *****************************************************************************} - STK2_PTR = NR_R23; NR_GP = NR_R28; NR_SP = NR_R29; NR_S8 = NR_R30; @@ -228,14 +227,6 @@ unit cpubase; NR_FPU_RESULT_REG = NR_F0; NR_MM_RESULT_REG = NR_NO; - NR_TCR0 = NR_R15; - NR_TCR1 = NR_R3; - - NR_TCR10 = NR_R20; - NR_TCR11 = NR_R21; - NR_TCR12 = NR_R18; - NR_TCR13 = NR_R19; - {***************************************************************************** GCC /ABI linking information @@ -287,10 +278,6 @@ unit cpubase; function std_regnum_search(const s:string):Tregister; function std_regname(r:Tregister):string; - var - STK2_dummy: aint; - STK2_Localsize: aint; - implementation uses @@ -342,27 +329,25 @@ unit cpubase; begin { This isn't 100% perfect because the arm allows jumps also by writing to PC=R15. To overcome this problem we simply forbid that FPC generates jumps by loading R15 } - is_calljmp:= o in [A_J,A_JAL,A_JALR,{ A_JALX, }A_JR, - A_BEQ,A_BNE,A_BGEZ,A_BGEZAL,A_BGTZ,A_BLEZ,A_BLTZ,A_BLTZAL, - A_BEQL,A_BGEZALL,A_BGEZL,A_BGTZL,A_BLEZL,A_BLTZALL,A_BLTZL,A_BNEL]; + is_calljmp:= o in [A_J,A_JAL,A_JALR,{ A_JALX, }A_JR, A_BA, A_BC, A_BC1T, A_BC1F]; end; function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE} const inverse: array[TAsmCond] of TAsmCond=(C_None, - C_EQ, C_NE, C_LT, C_LE, C_GT, C_GE, C_LTU, C_LEU, C_GTU, C_GEU, - C_FEQ, {Equal} - C_FNE, {Not Equal} - C_FGT, {Greater} - C_FLT, {Less} - C_FGE, {Greater or Equal} - C_FLE {Less or Equal} - + C_NE, C_EQ, C_GE, C_GT, C_LE, C_LT, C_GEU, C_GTU, C_LEU, C_LTU, + C_FNE, + C_FEQ, + C_FLE, + C_FGE, + C_FLT, + C_FGT ); begin result := inverse[c]; - end; function findreg_by_number(r:Tregister):tregisterindex; + end; + function findreg_by_number(r:Tregister):tregisterindex; begin result:=rgBase.findreg_by_number_table(r,regnumber_index); end; @@ -393,6 +378,4 @@ unit cpubase; begin - STK2_dummy := 10; - STK2_Localsize := 0; end. diff --git a/compiler/mips/cpugas.pas b/compiler/mips/cpugas.pas index a4844ae121..8bea6f4ac4 100644 --- a/compiler/mips/cpugas.pas +++ b/compiler/mips/cpugas.pas @@ -150,6 +150,27 @@ unit cpugas; end; end; +{ + function getnextfpreg(tmpfpu : shortstring) : shortstring; + begin + case length(tmpfpu) of + 3: + if (tmpfpu[3] = '9') then + tmpfpu:='$f10' + else + tmpfpu[3] := succ(tmpfpu[3]); + 4: + if (tmpfpu[4] = '9') then + tmpfpu:='$f20' + else + tmpfpu[4] := succ(tmpfpu[4]); + else + internalerror(20120531); + end; + getnextfpreg := tmpfpu; + end; +} + procedure TMIPSInstrWriter.WriteInstruction(hp: Tai); var @@ -158,23 +179,13 @@ unit cpugas; i: integer; tmpfpu: string; tmpfpu_len: longint; + r: TRegister; begin if hp.typ <> ait_instruction then exit; op := taicpu(hp).opcode; case op of - A_P_STK2: - begin - s1 := getopstr(taicpu(hp).oper[2]^); - STK2_LocalSize := align(STK2_LocalSize, 8); - if s1[1] = '-' then - str(-STK2_LocalSize, s1) - else - str(STK2_LocalSize, s1); - s := #9 + gas_op2str[A_ADDIU] + #9 + getopstr(taicpu(hp).oper[0]^)+ ',' + getopstr(taicpu(hp).oper[1]^) + ',' + s1; - owner.AsmWriteLn(s); - end; A_P_SET_NOMIPS16: begin s := #9 + '.set' + #9 + 'nomips16'; @@ -222,8 +233,14 @@ unit cpugas; s := #9 + gas_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')'; owner.AsmWriteLn(s); +{ bug if $f9/$f19 tmpfpu_len := length(tmpfpu); tmpfpu[tmpfpu_len] := succ(tmpfpu[tmpfpu_len]); + +} + r := taicpu(hp).oper[0]^.reg; + setsupreg(r, getsupreg(r) + 1); + tmpfpu := gas_regname(r); s := #9 + gas_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')'; owner.AsmWriteLn(s); end; @@ -233,8 +250,13 @@ unit cpugas; s := #9 + gas_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')'; owner.AsmWriteLn(s); +{ tmpfpu_len := length(tmpfpu); tmpfpu[tmpfpu_len] := succ(tmpfpu[tmpfpu_len]); +} + r := taicpu(hp).oper[0]^.reg; + setsupreg(r, getsupreg(r) + 1); + tmpfpu := gas_regname(r); s := #9 + gas_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')'; owner.AsmWriteLn(s); end; diff --git a/compiler/mips/ncpuadd.pas b/compiler/mips/ncpuadd.pas index 8d88ce49ca..06dcd85ada 100644 --- a/compiler/mips/ncpuadd.pas +++ b/compiler/mips/ncpuadd.pas @@ -137,145 +137,216 @@ end; 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, NR_TCR10, 0)); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 0)); - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4)); - 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.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_const(A_LI, NR_TCR10, 1)); + //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 := NR_TCR10; + 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, NR_TCR10, 1)); + 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)); - 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)); + //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_const(A_LI, NR_TCR10, 0)); + //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 := NR_TCR10; + 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 - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0)); + 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, NR_TCR11, left_reg.reghi, right_reg.reghi)); - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, 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)); + //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, NR_TCR11, left_reg.reglo, right_reg.reglo)); - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5)); + 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_B, lfcmp64_L4)); + 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, NR_TCR10, 1)); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1)); cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_lt := NR_TCR10; + 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 - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0)); + 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, NR_TCR11, right_reg.reghi, left_reg.reghi)); - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4)); + 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)); + //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, NR_TCR11, right_reg.reglo, left_reg.reglo)); - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4)); + 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, NR_TCR10, 1)); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1)); cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_le := NR_TCR10; + 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 - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0)); + 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, NR_TCR11, left_reg.reghi, right_reg.reghi)); - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, 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)); + //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, NR_TCR11, left_reg.reglo, right_reg.reglo)); - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5)); + 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_B, lfcmp64_L4)); + 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, NR_TCR10, 1)); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1)); cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_ltu := NR_TCR10; + 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 - current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0)); + 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, NR_TCR11, right_reg.reghi, left_reg.reghi)); - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4)); + 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)); + //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, NR_TCR11, right_reg.reglo, left_reg.reglo)); - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4)); + 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, NR_TCR10, 1)); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1)); cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4); - cmp64_leu := NR_TCR10; + cmp64_leu := tmpreg1; end; function tmipsaddnode.GetRes64_register(unsigned: boolean; //this_reg: TRegister; @@ -432,7 +503,7 @@ begin location_force_fpureg(current_asmdata.CurrAsmList, right.location, True); location_reset(location, LOC_REGISTER, OS_INT); - location.Register := NR_TCR0; + location.Register := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); case NodeType of equaln: @@ -442,11 +513,11 @@ begin else op := A_C_EQ_S; current_asmdata.getjumplabel(lfcmpfalse); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0)); + 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_TCR0}, NR_R0, 1)); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1)); cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse); end; @@ -457,11 +528,11 @@ begin else op := A_C_EQ_S; current_asmdata.getjumplabel(lfcmpfalse); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1)); + 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_TCR0}, NR_R0, NR_R0)); + 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: @@ -471,11 +542,11 @@ begin else op := A_C_LT_S; current_asmdata.getjumplabel(lfcmptrue); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1)); + 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_TCR0}, NR_R0, NR_R0)); + 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; lten: @@ -485,11 +556,11 @@ begin else op := A_C_LE_S; current_asmdata.getjumplabel(lfcmptrue); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1)); + 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_TCR0}, NR_R0, NR_R0)); + 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: @@ -499,11 +570,11 @@ begin else op := A_C_LT_S; current_asmdata.getjumplabel(lfcmptrue); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1)); + 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_TCR0}, NR_R0, NR_R0)); + 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: @@ -513,11 +584,11 @@ begin else op := A_C_LE_S; current_asmdata.getjumplabel(lfcmptrue); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1)); + 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_TCR0}, NR_R0, NR_R0)); + 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} @@ -526,11 +597,12 @@ end; procedure tmipsaddnode.second_cmpboolean; var - tmp_right_reg: TRegister; + 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); @@ -540,18 +612,19 @@ begin tmp_right_reg := right.location.Register; location_reset(location, LOC_REGISTER, OS_INT); - location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg); + location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg); end; procedure tmipsaddnode.second_cmpsmallset; var - tmp_right_reg: TRegister; + 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 @@ -565,7 +638,7 @@ begin location_reset(location, LOC_REGISTER, OS_INT); - location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg); + location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg); end; @@ -582,20 +655,21 @@ begin not(is_signed(right.resultdef)); location_reset(location, LOC_REGISTER, OS_INT); - location.Register := GetRes64_register(unsigned, {NR_TCR0, }left.location.register64, right.location.register64); // NR_TCR0; + location.Register := GetRes64_register(unsigned, left.location.register64, right.location.register64); end; procedure tmipsaddnode.second_cmpordinal; var unsigned: boolean; - tmp_right_reg: TRegister; + 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); @@ -604,7 +678,7 @@ begin else tmp_right_reg := right.location.Register; location_reset(location, LOC_REGISTER, OS_INT); - location.Register := getres_register(unsigned, NR_TCR0, left.location.Register, tmp_right_reg); + location.Register := getres_register(unsigned, tmpreg, left.location.Register, tmp_right_reg); end; begin diff --git a/compiler/mips/ncpucnv.pas b/compiler/mips/ncpucnv.pas index c6361ddb8b..afc69a5872 100644 --- a/compiler/mips/ncpucnv.pas +++ b/compiler/mips/ncpucnv.pas @@ -134,6 +134,7 @@ var href: treference; hregister: tregister; l1, l2: tasmlabel; + ai : TaiCpu; begin location_reset(location, LOC_FPUREGISTER, def_cgsize(resultdef)); @@ -149,7 +150,9 @@ begin loadsigned; - current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BGE, hregister, NR_R0, l2)); + ai := Taicpu.op_reg_reg_sym(A_BC, hregister, NR_R0, l2); + ai.setCondition(C_GE); + current_asmdata.CurrAsmList.concat(ai); case tfloatdef(resultdef).floattype of { converting dword to s64real first and cut off at the end avoids precision loss } @@ -214,6 +217,8 @@ var hreg1, hreg2: tregister; opsize: tcgsize; hlabel, oldtruelabel, oldfalselabel: tasmlabel; + newsize : tcgsize; + href: treference; begin oldtruelabel := current_procinfo.CurrTrueLabel; oldfalselabel := current_procinfo.CurrFalseLabel; @@ -223,17 +228,24 @@ begin if codegenerror then exit; - { byte(boolean) or word(wordbool) or longint(longbool) must } - { be accepted for var parameters } - if (nf_explicit in flags) and - (left.resultdef.size = resultdef.size) and - (left.location.loc in [LOC_REFERENCE, LOC_CREFERENCE, LOC_CREGISTER]) then - begin - location_copy(location, left.location); - current_procinfo.CurrTrueLabel := oldtruelabel; - current_procinfo.CurrFalseLabel := oldfalselabel; - exit; - end; + { Explicit typecasts from any ordinal type to a boolean type } + { must not change the ordinal value } + if (nf_explicit in flags) and + not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then + begin + location_copy(location,left.location); + newsize:=def_cgsize(resultdef); + { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend } + if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or + ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,true) + else + location.size:=newsize; + current_procinfo.CurrTrueLabel:=oldTrueLabel; + current_procinfo.CurrFalseLabel:=oldFalseLabel; + exit; + end; + location_reset(location, LOC_REGISTER, def_cgsize(resultdef)); opsize := def_cgsize(left.resultdef); case left.location.loc of @@ -242,21 +254,35 @@ begin if left.location.loc in [LOC_CREFERENCE, LOC_REFERENCE] then begin hreg2 := cg.getintregister(current_asmdata.CurrAsmList, opsize); - cg.a_load_ref_reg(current_asmdata.CurrAsmList, opsize, opsize, left.location.reference, hreg2); +{$ifndef cpu64bitalu} + if left.location.size in [OS_64,OS_S64] then + begin + cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,left.location.reference,hreg2); + hreg1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); + href:=left.location.reference; + inc(href.offset,4); + cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,href,hreg1); + cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,hreg1,hreg2,hreg2); + end + else +{$endif not cpu64bitalu} + cg.a_load_ref_reg(current_asmdata.CurrAsmList, opsize, opsize, left.location.reference, hreg2); end else - hreg2 := left.location.Register; -{$ifndef cpu64bit} - if left.location.size in [OS_64, OS_S64] then - begin - hreg1 := cg.getintregister(current_asmdata.CurrAsmList, OS_32); - cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_OR, OS_32, hreg2, tregister(succ(longint(hreg2))), hreg1); - hreg2 := hreg1; - opsize := OS_32; - end; -{$endif cpu64bit} - hreg1 := cg.getintregister(current_asmdata.CurrAsmList, opsize); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SNE, hreg1, hreg2, NR_R0)); + begin + hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); +{$ifndef cpu64bitalu} + if left.location.size in [OS_64,OS_S64] then + begin + hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); + cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,left.location.register64.reglo,hreg2); + end + else +{$endif not cpu64bitalu} + cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,opsize,left.location.register,hreg2); + end; + hreg1 := cg.getintregister(current_asmdata.CurrAsmList, opsize); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SNE, hreg1, hreg2, NR_R0)); end; LOC_JUMP: begin @@ -272,10 +298,26 @@ begin else internalerror(10062); end; - location.Register := hreg1; +{$ifndef cpu64bitalu} + if (location.size in [OS_64,OS_S64]) then + begin + location.register64.reglo:=hreg1; + location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32); + if (is_cbool(resultdef)) then + { reglo is either 0 or -1 -> reghi has to become the same } + cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,location.register64.reglo,location.register64.reghi) + else + { unsigned } + cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,location.register64.reghi); + end + else +{$endif not cpu64bitalu} + location.Register := hreg1; +{zfx if location.size in [OS_64, OS_S64] then internalerror(200408241); +} current_procinfo.CurrTrueLabel := oldtruelabel; current_procinfo.CurrFalseLabel := oldfalselabel; diff --git a/compiler/mips/ncpumat.pas b/compiler/mips/ncpumat.pas index bf894d8a64..2c93a71e56 100644 --- a/compiler/mips/ncpumat.pas +++ b/compiler/mips/ncpumat.pas @@ -257,6 +257,7 @@ end; procedure tMIPSELnotnode.second_boolean; var hl: tasmlabel; + tmpreg : TRegister; begin { if the location is LOC_JUMP, we do the secondpass after the labels are allocated @@ -283,10 +284,11 @@ begin end; LOC_REGISTER, LOC_CREGISTER, LOC_REFERENCE, LOC_CREFERENCE: begin + tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT); hlcg.location_force_reg(current_asmdata.CurrAsmList, left.location, left.resultdef, left.resultdef, True); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SEQ, NR_TCR0, left.location.Register, NR_R0)); + current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SEQ, tmpreg, left.location.Register, NR_R0)); location_reset(location, LOC_REGISTER, OS_INT); - location.Register := NR_TCR0; + location.Register := tmpreg; end; else internalerror(2003042401); diff --git a/compiler/mips/opcode.inc b/compiler/mips/opcode.inc index 9e9e292fa7..1f15252bbb 100644 --- a/compiler/mips/opcode.inc +++ b/compiler/mips/opcode.inc @@ -1,5 +1,4 @@ A_NONE, -A_P_STK2, A_P_LW, A_P_SET_NOMIPS16, A_P_SET_NOREORDER, @@ -15,7 +14,8 @@ A_NOP, A_NOT, A_NEG, A_NEGU, -A_B, +A_BA, +A_BC, A_LI, A_DLI, A_LA, @@ -108,22 +108,6 @@ A_J, A_JAL, A_JR, A_JALR, -A_BEQ, -A_BNE, -A_BLEZ, -A_BGTZ, -A_BLTZ, -A_BGEZ, -A_BLTZAL, -A_BGEZAL, -A_BEQL, -A_BNEL, -A_BLEZL, -A_BGTZL, -A_BLTZL, -A_BGEZL, -A_BLTZALL, -A_BGEZALL, A_SLL, A_SRL, A_SRA, @@ -193,32 +177,12 @@ A_FLOOR_L_S, A_FLOOR_L_D, A_BC1T, A_BC1F, -A_BC1TL, -A_BC1FL, A_C_EQ_D, A_C_EQ_S, A_C_LE_D, A_C_LE_S, A_C_LT_D, A_C_LT_S, -A_BEQI, -A_BNEI, -A_BLTI, -A_BLEI, -A_BGTI, -A_BGEI, -A_BLTUI, -A_BLEUI, -A_BGTUI, -A_BGEUI, -A_BLT, -A_BLE, -A_BGT, -A_BGE, -A_BLTU, -A_BLEU, -A_BGTU, -A_BGEU, A_SEQ, A_SGE, A_SGEU, diff --git a/compiler/mips/racpugas.pas b/compiler/mips/racpugas.pas index d1b06b3406..b94eb2b0fe 100644 --- a/compiler/mips/racpugas.pas +++ b/compiler/mips/racpugas.pas @@ -639,7 +639,7 @@ Interface begin { we can search here without an extra table which is sorted by string length because we take the whole remaining string without the leading B } - actopcode := A_B; + actopcode := A_BC; for cond:=low(TAsmCond) to high(TAsmCond) do if (Upper(copy(s,2,length(s)-1))=Upper(Cond2Str[cond])) then begin diff --git a/compiler/mips/strinst.inc b/compiler/mips/strinst.inc index eee1e43386..ccab5b5e0c 100644 --- a/compiler/mips/strinst.inc +++ b/compiler/mips/strinst.inc @@ -1,5 +1,4 @@ 'none', -'p_stk2', 'p_lw', 'p_set_nomips16', 'p_set_noreorder', @@ -15,6 +14,7 @@ 'not', 'neg', 'negu', +'b ', 'b', 'li', 'dli', @@ -108,22 +108,6 @@ 'jal', 'jr', 'jalr', -'beq', -'bne', -'blez', -'bgtz', -'bltz', -'bgez', -'bltzal', -'bgezal', -'beql', -'bnel', -'blezl', -'bgtzl', -'bltzl', -'bgezl', -'bltzall', -'bgezall', 'sll', 'srl', 'sra', @@ -193,32 +177,12 @@ 'floor.l.d', 'bc1t', 'bc1f', -'bc1tl', -'bc1fl', 'c.eq.d', 'c.eq.s', 'c.le.d', 'c.le.s', 'c.lt.d', 'c.lt.s', -'beqi', -'bnei', -'blti', -'blei', -'bgti', -'bgei', -'bltui', -'bleui', -'bgtui', -'bgeui', -'blt', -'ble', -'bgt', -'bge', -'bltu', -'bleu', -'bgtu', -'bgeu', 'seq', 'sge', 'sgeu',