1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00

[mips][microMIPS] Implement LWGP instruction

Differential Revision: http://reviews.llvm.org/D6650

llvm-svn: 227325
This commit is contained in:
Jozef Kolek 2015-01-28 17:27:26 +00:00
parent d39a45731a
commit e6b6be169a
10 changed files with 112 additions and 1 deletions

View File

@ -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;

View File

@ -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,

View File

@ -735,6 +735,21 @@ getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
return OffBits & 0x1F;
}
unsigned MipsMCCodeEmitter::
getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &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<MCFixup> &Fixups,

View File

@ -168,6 +168,9 @@ public:
unsigned getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

View File

@ -131,6 +131,17 @@ class LOAD_STORE_SP_FM_MM16<bits<6> op> {
let Inst{4-0} = offset;
}
class LOAD_GP_FM_MM16<bits<6> 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;

View File

@ -3,6 +3,7 @@ def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddrMM", [frameindex]>;
def simm4 : Operand<i32> {
let DecoderMethod = "DecodeSimm4";
}
def simm7 : Operand<i32>;
def li_simm7 : Operand<i32> {
let DecoderMethod = "DecodeLiSimm7";
}
@ -96,6 +97,13 @@ def mem_mm_sp_imm5_lsl2 : Operand<i32> {
let EncoderMethod = "getMemEncodingMMSPImm5Lsl2";
}
def mem_mm_gp_imm7_lsl2 : Operand<i32> {
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops GPRMM16:$base, simm7:$offset);
let OperandType = "OPERAND_MEMORY";
let EncoderMethod = "getMemEncodingMMGPImm7Lsl2";
}
def mem_mm_12 : Operand<i32> {
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops GPR32, simm12);
@ -307,6 +315,15 @@ class StoreSPMM16<string opstr, DAGOperand RO, InstrItinClass Itin,
let mayStore = 1;
}
class LoadGPMM16<string opstr, DAGOperand RO, InstrItinClass Itin,
Operand MemOpnd> :
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<string opstr, RegisterOperand RO> :
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>,

View File

@ -486,3 +486,6 @@
# CHECK: b16 132
0xcc 0x42
# CHECK: lw $3, 32($gp)
0x65 0x88

View File

@ -486,3 +486,6 @@
# CHECK: b16 132
0x42 0xcc
# CHECK: lw $3, 32($gp)
0x88 0x65

View File

@ -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

View File

@ -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)