From bf6106bf51a298dc75015dd78829d66bc299b444 Mon Sep 17 00:00:00 2001 From: Hrvoje Varga Date: Fri, 16 Oct 2015 12:24:58 +0000 Subject: [PATCH] [mips][microMIPS] Implement LB, LBE, LBU and LBUE instructions Differential Revision: http://reviews.llvm.org/D11633 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250511 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Mips/Disassembler/MipsDisassembler.cpp | 46 +++++++++++++++++++ .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 15 +++++- .../Mips/MCTargetDesc/MipsMCCodeEmitter.h | 3 ++ lib/Target/Mips/MicroMips32r6InstrFormats.td | 42 +++++++++++++++++ lib/Target/Mips/MicroMips32r6InstrInfo.td | 27 +++++++++++ lib/Target/Mips/MicroMipsInstrInfo.td | 8 ++++ .../Disassembler/Mips/micromips32r6/valid.txt | 4 ++ test/MC/Mips/micromips32r6/valid.s | 4 ++ 8 files changed, 148 insertions(+), 1 deletion(-) diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 79268e5e184..2fa4d322d59 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -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, diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 1d06860bdf9..bd6afcb1fe1 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -773,7 +773,7 @@ getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, return OffBits & 0x7F; } - unsigned MipsMCCodeEmitter:: +unsigned MipsMCCodeEmitter:: getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, SmallVectorImpl &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 &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 &Fixups, diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index b2eedd34544..56f286ab3d9 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -178,6 +178,9 @@ public: unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; unsigned getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/lib/Target/Mips/MicroMips32r6InstrFormats.td b/lib/Target/Mips/MicroMips32r6InstrFormats.td index a08ba7d81d3..bc7656d93a4 100644 --- a/lib/Target/Mips/MicroMips32r6InstrFormats.td +++ b/lib/Target/Mips/MicroMips32r6InstrFormats.td @@ -133,6 +133,48 @@ class POOL32C_ST_EVA_FM_MMR6 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 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 funct> : MMR6Arch { bits<5> rd; diff --git a/lib/Target/Mips/MicroMips32r6InstrInfo.td b/lib/Target/Mips/MicroMips32r6InstrInfo.td index d74421c3371..59f42c900cd 100644 --- a/lib/Target/Mips/MicroMips32r6InstrInfo.td +++ b/lib/Target/Mips/MicroMips32r6InstrInfo.td @@ -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; class CACHEE_MMR6_DESC : PREFE_CACHEE_MMR6_DESC_BASE<"cachee", mem_mm_9, GPR32Opnd>; +class LB_LBU_MMR6_DESC_BASE : MMR6Arch { + 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 + : LB_LBU_MMR6_DESC_BASE { + 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 : MMR6Arch { 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 { diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 5daf9f361fc..7bd2f4be560 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -130,6 +130,14 @@ def mem_mm_12 : Operand { let OperandType = "OPERAND_MEMORY"; } +def mem_mm_16 : Operand { + 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]; diff --git a/test/MC/Disassembler/Mips/micromips32r6/valid.txt b/test/MC/Disassembler/Mips/micromips32r6/valid.txt index 8e948557bd2..70cae38ad34 100644 --- a/test/MC/Disassembler/Mips/micromips32r6/valid.txt +++ b/test/MC/Disassembler/Mips/micromips32r6/valid.txt @@ -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) diff --git a/test/MC/Mips/micromips32r6/valid.s b/test/MC/Mips/micromips32r6/valid.s index f1260630811..1700a22617e 100644 --- a/test/MC/Mips/micromips32r6/valid.s +++ b/test/MC/Mips/micromips32r6/valid.s @@ -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] -- 2.34.1