From 71832e7ed99a3a82ea917f568bd95885d951fc43 Mon Sep 17 00:00:00 2001 From: Zoran Jovanovic Date: Thu, 23 Oct 2014 11:13:59 +0000 Subject: [PATCH] [mips][microMIPS] Implement ADDIUR1SP instruction Differential Revision: http://reviews.llvm.org/D5153 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220477 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 10 ++++++++++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 14 ++++++++++++++ lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h | 4 ++++ lib/Target/Mips/MicroMipsInstrFormats.td | 12 ++++++++++++ lib/Target/Mips/MicroMipsInstrInfo.td | 9 +++++++++ test/MC/Mips/micromips-16-bit-instructions.s | 3 +++ test/MC/Mips/micromips-invalid.s | 3 +++ 7 files changed, 55 insertions(+) diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index ee67f74ce30..e98346fc9e4 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1187,6 +1187,16 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, ((Imm % 4 == 0) && Imm < 28 && Imm > 0))) return Error(IDLoc, "immediate operand value out of range"); break; + case Mips::ADDIUR1SP_MM: + Opnd = Inst.getOperand(1); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (OffsetToAlignment(Imm, 4LL)) + return Error(IDLoc, "misaligned immediate operand value"); + if (Imm < 0 || Imm > 255) + return Error(IDLoc, "immediate operand value out of range"); + break; } } diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index ddb52f6d4e1..9636deb026c 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -377,6 +377,20 @@ getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, return 0; } +unsigned MipsMCCodeEmitter:: +getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + + const MCOperand &MO = MI.getOperand(OpNo); + if (MO.isImm()) { + unsigned Value = MO.getImm(); + return Value >> 2; + } + + return 0; +} + unsigned MipsMCCodeEmitter:: getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl &Fixups, diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h index 3bb9f2b7a03..6a82a1df424 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h @@ -84,6 +84,10 @@ public: SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + unsigned getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + // getSImm9AddiuspValue - Return binary encoding of the microMIPS addiusp // instruction immediate operand. unsigned getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index 23c8dd6d1b2..dcddfbc8875 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -170,6 +170,18 @@ class JRADDIUSP_FM_MM16 op> { let Inst{4-0} = imm; } +class ADDIUR1SP_FM_MM16 { + bits<3> rd; + bits<6> imm; + + bits<16> Inst; + + let Inst{15-10} = 0x1b; + let Inst{9-7} = rd; + let Inst{6-1} = imm; + let Inst{0} = 1; +} + //===----------------------------------------------------------------------===// // MicroMIPS 32-bit Instruction Formats //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 2cd59224a92..ea8d65b1cb3 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -11,6 +11,10 @@ def uimm5_lsl2 : Operand { let EncoderMethod = "getUImm5Lsl2Encoding"; } +def uimm6_lsl2 : Operand { + let EncoderMethod = "getUImm6Lsl2Encoding"; +} + def simm9_addiusp : Operand { let EncoderMethod = "getSImm9AddiuspValue"; } @@ -149,6 +153,10 @@ class AddImmUS5 : let isCommutable = 1; } +class AddImmUR1SP : + MicroMipsInst16<(outs RO:$rd), (ins uimm6_lsl2:$imm), + !strconcat(opstr, "\t$rd, $imm"), [], NoItinerary, FrmR>; + class AddImmUSP : MicroMipsInst16<(outs), (ins simm9_addiusp:$imm), !strconcat(opstr, "\t$imm"), [], NoItinerary, FrmI>; @@ -256,6 +264,7 @@ def SLL16_MM : ShiftIMM16<"sll16", uimm3_shift, GPRMM16Opnd, shl, immZExt2Shift, II_SLL>, SHIFT_FM_MM16<0>; def SRL16_MM : ShiftIMM16<"srl16", uimm3_shift, GPRMM16Opnd, srl, immZExt2Shift, II_SRL>, SHIFT_FM_MM16<1>; +def ADDIUR1SP_MM : AddImmUR1SP<"addiur1sp", GPRMM16Opnd>, ADDIUR1SP_FM_MM16; def ADDIUR2_MM : AddImmUR2<"addiur2", GPRMM16Opnd>, ADDIUR2_FM_MM16; def ADDIUS5_MM : AddImmUS5<"addius5", GPR32Opnd>, ADDIUS5_FM_MM16; def ADDIUSP_MM : AddImmUSP<"addiusp">, ADDIUSP_FM_MM16; diff --git a/test/MC/Mips/micromips-16-bit-instructions.s b/test/MC/Mips/micromips-16-bit-instructions.s index 396d56aca5f..06938a9e6b9 100644 --- a/test/MC/Mips/micromips-16-bit-instructions.s +++ b/test/MC/Mips/micromips-16-bit-instructions.s @@ -19,6 +19,7 @@ # CHECK-EL: srl16 $4, $17, 6 # encoding: [0x1d,0x26] # CHECK-EL: li16 $3, -1 # encoding: [0xff,0xed] # CHECK-EL: li16 $3, 126 # encoding: [0xfe,0xed] +# CHECK-EL: addiur1sp $7, 4 # encoding: [0x83,0x6f] # CHECK-EL: addiur2 $6, $7, -1 # encoding: [0x7e,0x6f] # CHECK-EL: addiur2 $6, $7, 12 # encoding: [0x76,0x6f] # CHECK-EL: addius5 $7, -2 # encoding: [0xfc,0x4c] @@ -47,6 +48,7 @@ # CHECK-EB: srl16 $4, $17, 6 # encoding: [0x26,0x1d] # CHECK-EB: li16 $3, -1 # encoding: [0xed,0xff] # CHECK-EB: li16 $3, 126 # encoding: [0xed,0xfe] +# CHECK-EB: addiur1sp $7, 4 # encoding: [0x6f,0x83] # CHECK-EB: addiur2 $6, $7, -1 # encoding: [0x6f,0x7e] # CHECK-EB: addiur2 $6, $7, 12 # encoding: [0x6f,0x76] # CHECK-EB: addius5 $7, -2 # encoding: [0x4c,0xfc] @@ -73,6 +75,7 @@ srl16 $4, $17, 6 li16 $3, -1 li16 $3, 126 + addiur1sp $7, 4 addiur2 $6, $7, -1 addiur2 $6, $7, 12 addius5 $7, -2 diff --git a/test/MC/Mips/micromips-invalid.s b/test/MC/Mips/micromips-invalid.s index f7b7e3d0c4e..ad7b8aab10b 100644 --- a/test/MC/Mips/micromips-invalid.s +++ b/test/MC/Mips/micromips-invalid.s @@ -1,6 +1,9 @@ # RUN: not llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips 2>%t1 # RUN: FileCheck %s < %t1 + addiur1sp $7, 260 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + addiur1sp $7, 241 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: misaligned immediate operand value + addiur1sp $8, 240 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction addius5 $7, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range addiusp 1032 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range addu16 $6, $14, $4 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction -- 2.34.1