From 2c6d73207ec948ed62433818e6ce197ca571c795 Mon Sep 17 00:00:00 2001 From: Jozef Kolek Date: Wed, 21 Jan 2015 12:10:11 +0000 Subject: [PATCH] [mips][microMIPS] Implement ADDIUPC instruction Differential Revision: http://reviews.llvm.org/D6582 llvm-svn: 226656 --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 8 ++++++++ llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 9 +++++++++ llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 12 ++++++++++++ llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h | 4 ++++ llvm/lib/Target/Mips/MicroMipsInstrFormats.td | 11 +++++++++++ llvm/lib/Target/Mips/MicroMipsInstrInfo.td | 12 ++++++++++++ llvm/test/MC/Disassembler/Mips/micromips.txt | 9 +++++++++ llvm/test/MC/Disassembler/Mips/micromips_le.txt | 9 +++++++++ llvm/test/MC/Mips/micromips-alu-instructions.s | 9 +++++++++ llvm/test/MC/Mips/micromips-invalid.s | 3 +++ 10 files changed, 86 insertions(+) diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 7db5b34..efb987e 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1396,6 +1396,14 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, if (!isUInt<5>(Imm)) return Error(IDLoc, "immediate operand value out of range"); break; + case Mips::ADDIUPC_MM: + MCOperand Opnd = Inst.getOperand(1); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + int Imm = Opnd.getImm(); + if ((Imm % 4 != 0) || !isIntN(25, Imm)) + return Error(IDLoc, "immediate operand value out of range"); + break; } } diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 98fc1eb..501e066 100644 --- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -370,6 +370,9 @@ static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't /// handle. template @@ -1756,3 +1759,9 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, return MCDisassembler::Success; } + +static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + Inst.addOperand(MCOperand::CreateImm(SignExtend32<23>(Insn) << 2)); + return MCDisassembler::Success; +} diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index a54a2eb..1fe85ec 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -905,4 +905,16 @@ MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); } +unsigned +MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); + // The immediate is encoded as 'immediate >> 2'. + unsigned Res = static_cast(MO.getImm()); + assert((Res & 3) == 0); + return Res >> 2; +} + #include "MipsGenMCCodeEmitter.inc" diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 0f0f49d..33cc8b6 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -198,6 +198,10 @@ public: SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFormats.td b/llvm/lib/Target/Mips/MicroMipsInstrFormats.td index 51b5c0c..fdc3659 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrFormats.td @@ -898,3 +898,14 @@ class BARRIER_FM_MM op> : MMArch { let Inst{10-6} = 0x0; let Inst{5-0} = 0x0; } + +class ADDIUPC_FM_MM { + bits<3> rs; + bits<23> imm; + + bits<32> Inst; + + let Inst{31-26} = 0x1e; + let Inst{25-23} = rs; + let Inst{22-0} = imm; +} diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index 241f452..ed4e894 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -141,6 +141,11 @@ def brtarget_mm : Operand { let DecoderMethod = "DecodeBranchTargetMM"; } +def simm23_lsl2 : Operand { + let EncoderMethod = "getSimm23Lsl2Encoding"; + let DecoderMethod = "DecodeSimm23Lsl2"; +} + class CompactBranchMM : InstSE<(outs), (ins RO:$rs, opnd:$offset), @@ -422,6 +427,10 @@ class LoadWordIndexedScaledMM; +class AddImmUPC : + InstSE<(outs RO:$rs), (ins simm23_lsl2:$imm), + !strconcat(opstr, "\t$rs, $imm"), [], NoItinerary, FrmR>; + /// A list of registers used by load/store multiple instructions. def RegListAsmOperand : AsmOperandClass { let Name = "RegList"; @@ -591,6 +600,9 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def UDIV_MM : MMRel, Div<"divu", II_DIVU, GPR32Opnd, [HI0, LO0]>, MULT_FM_MM<0x2ec>; + /// Arithmetic Instructions with PC and Immediate + def ADDIUPC_MM : AddImmUPC<"addiupc", GPRMM16Opnd>, ADDIUPC_FM_MM; + /// Shift Instructions def SLL_MM : MMRel, shift_rotate_imm<"sll", uimm5, GPR32Opnd, II_SLL>, SRA_FM_MM<0, 0>; diff --git a/llvm/test/MC/Disassembler/Mips/micromips.txt b/llvm/test/MC/Disassembler/Mips/micromips.txt index 07c1df9..cca5cb7 100644 --- a/llvm/test/MC/Disassembler/Mips/micromips.txt +++ b/llvm/test/MC/Disassembler/Mips/micromips.txt @@ -373,6 +373,15 @@ # CHECK: nop 0x00 0x00 0x00 0x00 +# CHECK: addiupc $2, 20 +0x79 0x00 0x00 0x05 + +# CHECK: addiupc $7, 16777212 +0x7b 0xbf 0xff 0xff + +# CHECK: addiupc $7, -16777216 +0x7b 0xc0 0x00 0x00 + # CHECK: addu16 $6, $17, $4 0x07 0x42 diff --git a/llvm/test/MC/Disassembler/Mips/micromips_le.txt b/llvm/test/MC/Disassembler/Mips/micromips_le.txt index 9a8c4a9..44b6b5d 100644 --- a/llvm/test/MC/Disassembler/Mips/micromips_le.txt +++ b/llvm/test/MC/Disassembler/Mips/micromips_le.txt @@ -373,6 +373,15 @@ # CHECK: nop 0x00 0x00 0x00 0x00 +# CHECK: addiupc $2, 20 +0x00 0x79 0x05 0x00 + +# CHECK: addiupc $7, 16777212 +0xbf 0x7b 0xff 0xff + +# CHECK: addiupc $7, -16777216 +0xc0 0x7b 0x00 0x00 + # CHECK: addu16 $6, $17, $4 0x42 0x07 diff --git a/llvm/test/MC/Mips/micromips-alu-instructions.s b/llvm/test/MC/Mips/micromips-alu-instructions.s index 1131d1f..aeab09e 100644 --- a/llvm/test/MC/Mips/micromips-alu-instructions.s +++ b/llvm/test/MC/Mips/micromips-alu-instructions.s @@ -38,6 +38,9 @@ # CHECK-EL: multu $9, $7 # encoding: [0xe9,0x00,0x3c,0x9b] # CHECK-EL: div $zero, $9, $7 # encoding: [0xe9,0x00,0x3c,0xab] # CHECK-EL: divu $zero, $9, $7 # encoding: [0xe9,0x00,0x3c,0xbb] +# CHECK-EL: addiupc $2, 20 # encoding: [0x00,0x79,0x05,0x00] +# CHECK-EL: addiupc $7, 16777212 # encoding: [0xbf,0x7b,0xff,0xff] +# CHECK-EL: addiupc $7, -16777216 # encoding: [0xc0,0x7b,0x00,0x00] #------------------------------------------------------------------------------ # Big endian #------------------------------------------------------------------------------ @@ -72,6 +75,9 @@ # CHECK-EB: multu $9, $7 # encoding: [0x00,0xe9,0x9b,0x3c] # CHECK-EB: div $zero, $9, $7 # encoding: [0x00,0xe9,0xab,0x3c] # CHECK-EB: divu $zero, $9, $7 # encoding: [0x00,0xe9,0xbb,0x3c] +# CHECK-EB: addiupc $2, 20 # encoding: [0x79,0x00,0x00,0x05] +# CHECK-EB: addiupc $7, 16777212 # encoding: [0x7b,0xbf,0xff,0xff] +# CHECK-EB: addiupc $7, -16777216 # encoding: [0x7b,0xc0,0x00,0x00] add $9, $6, $7 add $9, $6, 17767 addu $9, $6, -15001 @@ -104,3 +110,6 @@ multu $9, $7 div $0, $9, $7 divu $0, $9, $7 + addiupc $2, 20 + addiupc $7, 16777212 + addiupc $7, -16777216 diff --git a/llvm/test/MC/Mips/micromips-invalid.s b/llvm/test/MC/Mips/micromips-invalid.s index 1dbfb11..5ab111f 100644 --- a/llvm/test/MC/Mips/micromips-invalid.s +++ b/llvm/test/MC/Mips/micromips-invalid.s @@ -38,6 +38,9 @@ swm32 $16, $19, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: consecutive register numbers expected swm32 $16-$25, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand lwm32 $16, $17, $18, $19, $20, $21, $22, $23, $24, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid register operand + addiupc $7, 16777216 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + addiupc $6, -16777220 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + addiupc $3, 3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range lbu16 $9, 8($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction lhu16 $9, 4($16) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction lw16 $9, 8($17) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction -- 2.7.4