[mips][microMIPS] Implement LB, LBE, LBU and LBUE instructions

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

llvm-svn: 250511
This commit is contained in:
Hrvoje Varga 2015-10-16 12:24:58 +00:00
parent 1487a3de40
commit 3c88fbd367
8 changed files with 148 additions and 1 deletions

View File

@ -246,6 +246,16 @@ static DecodeStatus DecodeMemEVA(MCInst &Inst,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLoadByte9(MCInst &Inst,
unsigned Insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLoadByte15(MCInst &Inst,
unsigned Insn,
uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeCacheOp(MCInst &Inst,
unsigned Insn,
uint64_t Address,
@ -1153,6 +1163,42 @@ static DecodeStatus DecodeMemEVA(MCInst &Inst,
return MCDisassembler::Success;
}
static DecodeStatus DecodeLoadByte9(MCInst &Inst,
unsigned Insn,
uint64_t Address,
const void *Decoder) {
int Offset = SignExtend32<9>(Insn & 0x1ff);
unsigned Base = fieldFromInstruction(Insn, 16, 5);
unsigned Reg = fieldFromInstruction(Insn, 21, 5);
Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
Inst.addOperand(MCOperand::createReg(Reg));
Inst.addOperand(MCOperand::createReg(Base));
Inst.addOperand(MCOperand::createImm(Offset));
return MCDisassembler::Success;
}
static DecodeStatus DecodeLoadByte15(MCInst &Inst,
unsigned Insn,
uint64_t Address,
const void *Decoder) {
int Offset = SignExtend32<16>(Insn & 0xffff);
unsigned Base = fieldFromInstruction(Insn, 16, 5);
unsigned Reg = fieldFromInstruction(Insn, 21, 5);
Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
Inst.addOperand(MCOperand::createReg(Reg));
Inst.addOperand(MCOperand::createReg(Base));
Inst.addOperand(MCOperand::createImm(Offset));
return MCDisassembler::Success;
}
static DecodeStatus DecodeCacheOp(MCInst &Inst,
unsigned Insn,
uint64_t Address,

View File

@ -773,7 +773,7 @@ getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
return OffBits & 0x7F;
}
unsigned MipsMCCodeEmitter::
unsigned MipsMCCodeEmitter::
getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
@ -809,6 +809,19 @@ getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
return (OffBits & 0x0FFF) | RegBits;
}
unsigned MipsMCCodeEmitter::
getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
// Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
assert(MI.getOperand(OpNo).isReg());
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
STI) << 16;
unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
return (OffBits & 0xFFFF) | RegBits;
}
unsigned MipsMCCodeEmitter::
getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,

View File

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

View File

@ -133,6 +133,48 @@ class POOL32C_ST_EVA_FM_MMR6<bits<6> op, bits<3> funct> : MipsR6Inst {
let Inst{8-0} = offset;
}
class LB32_FM_MMR6 : MipsR6Inst {
bits<21> addr;
bits<5> rt;
bits<5> base = addr{20-16};
bits<16> offset = addr{15-0};
bits<32> Inst;
let Inst{31-26} = 0b000111;
let Inst{25-21} = rt;
let Inst{20-16} = base;
let Inst{15-0} = offset;
}
class LBU32_FM_MMR6 : MipsR6Inst {
bits<21> addr;
bits<5> rt;
bits<5> base = addr{20-16};
bits<16> offset = addr{15-0};
bits<32> Inst;
let Inst{31-26} = 0b000101;
let Inst{25-21} = rt;
let Inst{20-16} = base;
let Inst{15-0} = offset;
}
class POOL32C_LB_LBU_FM_MMR6<bits<3> funct> : MipsR6Inst {
bits<21> addr;
bits<5> rt;
bits<32> Inst;
let Inst{31-26} = 0b011000;
let Inst{25-21} = rt;
let Inst{20-16} = addr{20-16};
let Inst{15-12} = 0b0110;
let Inst{11-9} = funct;
let Inst{8-0} = addr{8-0};
}
class SIGN_EXTEND_FM_MMR6<string instr_asm, bits<10> funct>
: MMR6Arch<instr_asm> {
bits<5> rd;

View File

@ -78,6 +78,10 @@ class PREFE_MMR6_ENC : POOL32C_ST_EVA_FM_MMR6<0b011000, 0b010>;
class CACHEE_MMR6_ENC : POOL32C_ST_EVA_FM_MMR6<0b011000, 0b011>;
class WRPGPR_MMR6_ENC : POOL32A_WRPGPR_WSBH_FM_MMR6<0x3c5>;
class WSBH_MMR6_ENC : POOL32A_WRPGPR_WSBH_FM_MMR6<0x1ec>;
class LB_MMR6_ENC : LB32_FM_MMR6;
class LBU_MMR6_ENC : LBU32_FM_MMR6;
class LBE_MMR6_ENC : POOL32C_LB_LBU_FM_MMR6<0b100>;
class LBUE_MMR6_ENC : POOL32C_LB_LBU_FM_MMR6<0b000>;
class XOR_MMR6_ENC : ARITH_FM_MMR6<"xor", 0x310>;
class XORI_MMR6_ENC : ADDI_FM_MMR6<"xori", 0x1c>;
class ABS_S_MMR6_ENC : POOL32F_ABS_FM_MMR6<"abs.s", 0, 0b0001101>;
@ -285,6 +289,25 @@ class PREFE_CACHEE_MMR6_DESC_BASE<string instr_asm, Operand MemOpnd,
class PREFE_MMR6_DESC : PREFE_CACHEE_MMR6_DESC_BASE<"prefe", mem_mm_9, GPR32Opnd>;
class CACHEE_MMR6_DESC : PREFE_CACHEE_MMR6_DESC_BASE<"cachee", mem_mm_9, GPR32Opnd>;
class LB_LBU_MMR6_DESC_BASE<string instr_asm, Operand MemOpnd,
RegisterOperand GPROpnd> : MMR6Arch<instr_asm> {
dag OutOperandList = (outs GPROpnd:$rt);
dag InOperandList = (ins MemOpnd:$addr);
string AsmString = !strconcat(instr_asm, "\t$rt, $addr");
string DecoderMethod = "DecodeLoadByte15";
bit mayLoad = 1;
}
class LB_MMR6_DESC : LB_LBU_MMR6_DESC_BASE<"lb", mem_mm_16, GPR32Opnd>;
class LBU_MMR6_DESC : LB_LBU_MMR6_DESC_BASE<"lbu", mem_mm_16, GPR32Opnd>;
class LBE_LBUE_MMR6_DESC_BASE<string instr_asm, Operand MemOpnd,
RegisterOperand GPROpnd>
: LB_LBU_MMR6_DESC_BASE<instr_asm, MemOpnd, GPROpnd> {
let DecoderMethod = "DecodeLoadByte9";
}
class LBE_MMR6_DESC : LBE_LBUE_MMR6_DESC_BASE<"lbe", mem_mm_9, GPR32Opnd>;
class LBUE_MMR6_DESC : LBE_LBUE_MMR6_DESC_BASE<"lbue", mem_mm_9, GPR32Opnd>;
class CLO_CLZ_MMR6_DESC_BASE<string instr_asm, RegisterOperand GPROpnd>
: MMR6Arch<instr_asm> {
dag OutOperandList = (outs GPROpnd:$rt);
@ -830,6 +853,10 @@ def CACHEE_MMR6 : StdMMR6Rel, CACHEE_MMR6_ENC, CACHEE_MMR6_DESC,
def WRPGPR_MMR6 : StdMMR6Rel, WRPGPR_MMR6_ENC, WRPGPR_MMR6_DESC,
ISA_MICROMIPS32R6;
def WSBH_MMR6 : StdMMR6Rel, WSBH_MMR6_ENC, WSBH_MMR6_DESC, ISA_MICROMIPS32R6;
def LB_MMR6 : R6MMR6Rel, LB_MMR6_ENC, LB_MMR6_DESC, ISA_MICROMIPS32R6;
def LBU_MMR6 : R6MMR6Rel, LBU_MMR6_ENC, LBU_MMR6_DESC, ISA_MICROMIPS32R6;
def LBE_MMR6 : R6MMR6Rel, LBE_MMR6_ENC, LBE_MMR6_DESC, ISA_MICROMIPS32R6;
def LBUE_MMR6 : R6MMR6Rel, LBUE_MMR6_ENC, LBUE_MMR6_DESC, ISA_MICROMIPS32R6;
def XOR_MMR6 : StdMMR6Rel, XOR_MMR6_DESC, XOR_MMR6_ENC, ISA_MICROMIPS32R6;
def XORI_MMR6 : StdMMR6Rel, XORI_MMR6_DESC, XORI_MMR6_ENC, ISA_MICROMIPS32R6;
let DecoderMethod = "DecodeMemMMImm16" in {

View File

@ -130,6 +130,14 @@ def mem_mm_12 : Operand<i32> {
let OperandType = "OPERAND_MEMORY";
}
def mem_mm_16 : Operand<i32> {
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops GPR32, simm16);
let EncoderMethod = "getMemEncodingMMImm16";
let ParserMatchClass = MipsMemAsmOperand;
let OperandType = "OPERAND_MEMORY";
}
def MipsMemUimm4AsmOperand : AsmOperandClass {
let Name = "MemOffsetUimm4";
let SuperClasses = [MipsMemAsmOperand];

View File

@ -214,3 +214,7 @@
0x46 0x3b # CHECK: sdbbp16 8
0x04 0x3b # CHECK: subu16 $5, $16, $3
0x44 0xd8 # CHECK: xor16 $17, $5
0x1c 0x85 0x00 0x08 # CHECK: lb $4, 8($5)
0x14 0x85 0x00 0x08 # CHECK: lbu $4, 8($5)
0x60 0x85 0x68 0x08 # CHECK: lbe $4, 8($5)
0x60 0x85 0x60 0x08 # CHECK: lbue $4, 8($5)

View File

@ -204,3 +204,7 @@
sdbbp16 8 # CHECK: sdbbp16 8 # encoding: [0x46,0x3b]
subu16 $5, $16, $3 # CHECK: subu16 $5, $16, $3 # encoding: [0x04,0x3b]
xor16 $17, $5 # CHECK: xor16 $17, $5 # encoding: [0x44,0xd8]
lb $4, 8($5) # CHECK: lb $4, 8($5) # encoding: [0x1c,0x85,0x00,0x08]
lbu $4, 8($5) # CHECK: lbu $4, 8($5) # encoding: [0x14,0x85,0x00,0x08]
lbe $4, 8($5) # CHECK: lbe $4, 8($5) # encoding: [0x60,0x85,0x68,0x08]
lbue $4, 8($5) # CHECK: lbue $4, 8($5) # encoding: [0x60,0x85,0x60,0x08]