From: Jozef Kolek Date: Wed, 28 Jan 2015 17:27:26 +0000 (+0000) Subject: [mips][microMIPS] Implement LWGP instruction X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=a8c8e06c02faadcab35d4b1c6abadf512fe60291 [mips][microMIPS] Implement LWGP instruction Differential Revision: http://reviews.llvm.org/D6650 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227325 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 2e698dfbc98..aadaf053512 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1361,8 +1361,38 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, } // for } // if load/store - // TODO: Handle this with the AsmOperandClass.PredicateMethod. if (inMicroMipsMode()) { + if (MCID.mayLoad()) { + // Try to create 16-bit GP relative load instruction. + for (unsigned i = 0; i < MCID.getNumOperands(); i++) { + const MCOperandInfo &OpInfo = MCID.OpInfo[i]; + if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || + (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { + MCOperand &Op = Inst.getOperand(i); + if (Op.isImm()) { + int MemOffset = Op.getImm(); + MCOperand &DstReg = Inst.getOperand(0); + MCOperand &BaseReg = Inst.getOperand(1); + if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) && + getContext().getRegisterInfo()->getRegClass( + Mips::GPRMM16RegClassID).contains(DstReg.getReg()) && + BaseReg.getReg() == Mips::GP) { + MCInst TmpInst; + TmpInst.setLoc(IDLoc); + TmpInst.setOpcode(Mips::LWGP_MM); + TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg())); + TmpInst.addOperand(MCOperand::CreateReg(Mips::GP)); + TmpInst.addOperand(MCOperand::CreateImm(MemOffset)); + Instructions.push_back(TmpInst); + return false; + } + } + } + } // for + } // if load + + // TODO: Handle this with the AsmOperandClass.PredicateMethod. + MCOperand Opnd; int Imm; diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 1744b5161b0..29998e92f2a 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -289,6 +289,11 @@ static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder); + static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, @@ -1261,6 +1266,22 @@ static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, return MCDisassembler::Success; } +static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, + unsigned Insn, + uint64_t Address, + const void *Decoder) { + unsigned Offset = Insn & 0x7F; + unsigned Reg = fieldFromInstruction(Insn, 7, 3); + + Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + + Inst.addOperand(MCOperand::CreateReg(Reg)); + Inst.addOperand(MCOperand::CreateReg(Mips::GP)); + Inst.addOperand(MCOperand::CreateImm(Offset << 2)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeMemMMImm12(MCInst &Inst, unsigned Insn, uint64_t Address, diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index f561ea8f221..d7383761ad5 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -735,6 +735,21 @@ getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, return OffBits & 0x1F; } +unsigned MipsMCCodeEmitter:: +getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + // Register is encoded in bits 9-7, offset is encoded in bits 6-0. + assert(MI.getOperand(OpNo).isReg() && + MI.getOperand(OpNo).getReg() == Mips::GP && + "Unexpected base register!"); + + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), + Fixups, STI) >> 2; + + return OffBits & 0x7F; +} + unsigned MipsMCCodeEmitter:: getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 6aac9dcb055..0007c8df89a 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -168,6 +168,9 @@ public: unsigned getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index 0ad16dda85b..2402bf86083 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -131,6 +131,17 @@ class LOAD_STORE_SP_FM_MM16 op> { let Inst{4-0} = offset; } +class LOAD_GP_FM_MM16 op> { + bits<3> rt; + bits<7> offset; + + bits<16> Inst; + + let Inst{15-10} = op; + let Inst{9-7} = rt; + let Inst{6-0} = offset; +} + class ADDIUS5_FM_MM16 { bits<5> rd; bits<4> imm; diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index d91bd91912d..c6b984df7de 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -3,6 +3,7 @@ def addrimm12 : ComplexPattern; def simm4 : Operand { let DecoderMethod = "DecodeSimm4"; } +def simm7 : Operand; def li_simm7 : Operand { let DecoderMethod = "DecodeLiSimm7"; } @@ -96,6 +97,13 @@ def mem_mm_sp_imm5_lsl2 : Operand { let EncoderMethod = "getMemEncodingMMSPImm5Lsl2"; } +def mem_mm_gp_imm7_lsl2 : Operand { + let PrintMethod = "printMemOperand"; + let MIOperandInfo = (ops GPRMM16:$base, simm7:$offset); + let OperandType = "OPERAND_MEMORY"; + let EncoderMethod = "getMemEncodingMMGPImm7Lsl2"; +} + def mem_mm_12 : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops GPR32, simm12); @@ -307,6 +315,15 @@ class StoreSPMM16 : + MicroMipsInst16<(outs RO:$rt), (ins MemOpnd:$offset), + !strconcat(opstr, "\t$rt, $offset"), [], Itin, FrmI> { + let DecoderMethod = "DecodeMemMMGPImm7Lsl2"; + let canFoldAsLoad = 1; + let mayLoad = 1; +} + class AddImmUR2 : MicroMipsInst16<(outs RO:$rd), (ins RO:$rs, simm3_lsa2:$imm), !strconcat(opstr, "\t$rd, $rs, $imm"), @@ -539,6 +556,8 @@ def SH16_MM : StoreMM16<"sh16", GPRMM16OpndZero, GPRMM16Opnd, truncstorei16, LOAD_STORE_FM_MM16<0x2a>; def SW16_MM : StoreMM16<"sw16", GPRMM16OpndZero, GPRMM16Opnd, store, II_SW, mem_mm_4_lsl2>, LOAD_STORE_FM_MM16<0x3a>; +def LWGP_MM : LoadGPMM16<"lw", GPRMM16Opnd, II_LW, mem_mm_gp_imm7_lsl2>, + LOAD_GP_FM_MM16<0x19>; def LWSP_MM : LoadSPMM16<"lw", GPR32Opnd, II_LW, mem_mm_sp_imm5_lsl2>, LOAD_STORE_SP_FM_MM16<0x12>; def SWSP_MM : StoreSPMM16<"sw", GPR32Opnd, II_SW, mem_mm_sp_imm5_lsl2>, diff --git a/test/MC/Disassembler/Mips/micromips.txt b/test/MC/Disassembler/Mips/micromips.txt index 35c197f5ccb..00a6b19aa11 100644 --- a/test/MC/Disassembler/Mips/micromips.txt +++ b/test/MC/Disassembler/Mips/micromips.txt @@ -486,3 +486,6 @@ # CHECK: b16 132 0xcc 0x42 + +# CHECK: lw $3, 32($gp) +0x65 0x88 diff --git a/test/MC/Disassembler/Mips/micromips_le.txt b/test/MC/Disassembler/Mips/micromips_le.txt index 59b83169c35..5a78c0ff5a2 100644 --- a/test/MC/Disassembler/Mips/micromips_le.txt +++ b/test/MC/Disassembler/Mips/micromips_le.txt @@ -486,3 +486,6 @@ # CHECK: b16 132 0x42 0xcc + +# CHECK: lw $3, 32($gp) +0x88 0x65 diff --git a/test/MC/Mips/micromips-16-bit-instructions.s b/test/MC/Mips/micromips-16-bit-instructions.s index bde03502df4..2ad29578fd4 100644 --- a/test/MC/Mips/micromips-16-bit-instructions.s +++ b/test/MC/Mips/micromips-16-bit-instructions.s @@ -26,6 +26,7 @@ # CHECK-EL: sh16 $4, 8($17) # encoding: [0x14,0xaa] # CHECK-EL: sw16 $4, 4($17) # encoding: [0x11,0xea] # CHECK-EL: sw16 $zero, 4($17) # encoding: [0x11,0xe8] +# CHECK-EL: lw $3, 32($gp) # encoding: [0x88,0x65] # CHECK-EL: lw $3, 32($sp) # encoding: [0x68,0x48] # CHECK-EL: sw $4, 124($sp) # encoding: [0x9f,0xc8] # CHECK-EL: li16 $3, -1 # encoding: [0xff,0xed] @@ -79,6 +80,7 @@ # CHECK-EB: sh16 $4, 8($17) # encoding: [0xaa,0x14] # CHECK-EB: sw16 $4, 4($17) # encoding: [0xea,0x11] # CHECK-EB: sw16 $zero, 4($17) # encoding: [0xe8,0x11] +# CHECK-EB: lw $3, 32($gp) # encoding: [0x65,0x88] # CHECK-EB: lw $3, 32($sp) # encoding: [0x48,0x68] # CHECK-EB: sw $4, 124($sp) # encoding: [0xc8,0x9f] # CHECK-EB: li16 $3, -1 # encoding: [0xed,0xff] @@ -130,6 +132,7 @@ sh16 $4, 8($17) sw16 $4, 4($17) sw16 $0, 4($17) + lw $3, 32($gp) lw $3, 32($sp) sw $4, 124($sp) li16 $3, -1 diff --git a/test/MC/Mips/micromips-loadstore-instructions.s b/test/MC/Mips/micromips-loadstore-instructions.s index 995af035dde..de89056ce3c 100644 --- a/test/MC/Mips/micromips-loadstore-instructions.s +++ b/test/MC/Mips/micromips-loadstore-instructions.s @@ -19,6 +19,7 @@ # CHECK-EL: sh $2, 8($4) # encoding: [0x44,0x38,0x08,0x00] # CHECK-EL: sw $5, 4($6) # encoding: [0xa6,0xf8,0x04,0x00] # CHECK-EL: sw $5, 123($sp) # encoding: [0xbd,0xf8,0x7b,0x00] +# CHECK-EL: sw $3, 32($gp) # encoding: [0x7c,0xf8,0x20,0x00] # CHECK-EL: ll $2, 8($4) # encoding: [0x44,0x60,0x08,0x30] # CHECK-EL: sc $2, 8($4) # encoding: [0x44,0x60,0x08,0xb0] # CHECK-EL: lwu $2, 8($4) # encoding: [0x44,0x60,0x08,0xe0] @@ -48,6 +49,7 @@ # CHECK-EB: sh $2, 8($4) # encoding: [0x38,0x44,0x00,0x08] # CHECK-EB: sw $5, 4($6) # encoding: [0xf8,0xa6,0x00,0x04] # CHECK-EB: sw $5, 123($sp) # encoding: [0xf8,0xbd,0x00,0x7b] +# CHECK-EB: sw $3, 32($gp) # encoding: [0xf8,0x7c,0x00,0x20] # CHECK-EB: ll $2, 8($4) # encoding: [0x60,0x44,0x30,0x08] # CHECK-EB: sc $2, 8($4) # encoding: [0x60,0x44,0xb0,0x08] # CHECK-EB: lwu $2, 8($4) # encoding: [0x60,0x44,0xe0,0x08] @@ -74,6 +76,7 @@ sh $2, 8($4) sw $5, 4($6) sw $5, 123($sp) + sw $3, 32($gp) ll $2, 8($4) sc $2, 8($4) lwu $2, 8($4)