From e2db3024be540cfaa7c27cff5d578449c4b3ef24 Mon Sep 17 00:00:00 2001 From: Zoran Jovanovic Date: Fri, 10 Oct 2014 13:45:34 +0000 Subject: [PATCH] [mips][microMIPS] Implement ADDIUS5 instruction Differential Revision: http://reviews.llvm.org/D5049 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219495 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 19 +++++++++++++++++++ lib/Target/Mips/MicroMipsInstrFormats.td | 12 ++++++++++++ lib/Target/Mips/MicroMipsInstrInfo.td | 10 ++++++++++ test/MC/Mips/micromips-16-bit-instructions.s | 3 +++ test/MC/Mips/micromips-invalid.s | 4 ++++ 5 files changed, 48 insertions(+) create mode 100644 test/MC/Mips/micromips-invalid.s diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 21d2876fdd0..db9c679b767 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1117,6 +1117,25 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, } // for } // if load/store + // TODO: Handle this with the AsmOperandClass.PredicateMethod. + if (inMicroMipsMode()) { + MCOperand Opnd; + int Imm; + + switch (Inst.getOpcode()) { + default: + break; + case Mips::ADDIUS5_MM: + Opnd = Inst.getOperand(2); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < -8 || Imm > 7) + return Error(IDLoc, "immediate operand value out of range"); + break; + } + } + if (needsExpansion(Inst)) return expandInstruction(Inst, IDLoc, Instructions); else diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index 57f3dd540ef..9d403460cd8 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -41,6 +41,18 @@ class MicroMipsInst16 pattern, // MicroMIPS 16-bit Instruction Formats //===----------------------------------------------------------------------===// +class ADDIUS5_FM_MM16 { + bits<5> rd; + bits<4> imm; + + bits<16> Inst; + + let Inst{15-10} = 0x13; + let Inst{9-5} = rd; + let Inst{4-1} = imm; + let Inst{0} = 0; +} + class MOVE_FM_MM16 funct> { bits<5> rs; bits<5> rd; diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 86b4b0f279e..71abfcd82ef 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -1,5 +1,7 @@ def addrimm12 : ComplexPattern; +def simm4 : Operand; + def simm12 : Operand { let DecoderMethod = "DecodeSimm12"; } @@ -84,6 +86,13 @@ class LoadMM : + MicroMipsInst16<(outs RO:$dst), (ins RO:$rd, simm4:$imm), + !strconcat(opstr, "\t$rd, $imm"), [], NoItinerary, FrmR> { + let Constraints = "$rd = $dst"; + let isCommutable = 1; +} + class MoveFromHILOMM : MicroMipsInst16<(outs RO:$rd), (ins), !strconcat(opstr, "\t$rd"), [], II_MFHI_MFLO, FrmR> { @@ -156,6 +165,7 @@ let isCall = 1, hasDelaySlot = 1, Defs = [RA] in { !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>; } +def ADDIUS5_MM : AddImmUS5<"addius5", GPR32Opnd>, ADDIUS5_FM_MM16; def MFHI16_MM : MoveFromHILOMM<"mfhi", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x10>; def MFLO16_MM : MoveFromHILOMM<"mflo", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x12>; def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>; diff --git a/test/MC/Mips/micromips-16-bit-instructions.s b/test/MC/Mips/micromips-16-bit-instructions.s index 63ae5d0575c..c9d22936d32 100644 --- a/test/MC/Mips/micromips-16-bit-instructions.s +++ b/test/MC/Mips/micromips-16-bit-instructions.s @@ -9,6 +9,7 @@ #------------------------------------------------------------------------------ # Little endian #------------------------------------------------------------------------------ +# CHECK-EL: addius5 $7, -2 # encoding: [0xfc,0x4c] # CHECK-EL: mfhi $9 # encoding: [0x09,0x46] # CHECK-EL: mflo $9 # encoding: [0x49,0x46] # CHECK-EL: move $25, $1 # encoding: [0x21,0x0f] @@ -21,6 +22,7 @@ #------------------------------------------------------------------------------ # Big endian #------------------------------------------------------------------------------ +# CHECK-EB: addius5 $7, -2 # encoding: [0x4c,0xfc] # CHECK-EB: mfhi $9 # encoding: [0x46,0x09] # CHECK-EB: mflo $9 # encoding: [0x46,0x49] # CHECK-EB: move $25, $1 # encoding: [0x0f,0x21] @@ -31,6 +33,7 @@ # CHECK-EB: jalrs16 $9 # encoding: [0x45,0xe9] # CHECK-EB: move $zero, $zero # encoding: [0x0c,0x00] + addius5 $7, -2 mfhi $9 mflo $9 move $25, $1 diff --git a/test/MC/Mips/micromips-invalid.s b/test/MC/Mips/micromips-invalid.s new file mode 100644 index 00000000000..116628e8715 --- /dev/null +++ b/test/MC/Mips/micromips-invalid.s @@ -0,0 +1,4 @@ +# RUN: not llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips 2>%t1 +# RUN: FileCheck %s < %t1 + + addius5 $7, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range