From f58c95aac05338f67132fec9636cd5aab437a0a5 Mon Sep 17 00:00:00 2001 From: Zoran Jovanovic Date: Thu, 23 Oct 2014 10:59:24 +0000 Subject: [PATCH] ps][microMIPS] Implement LI16 instruction Differential Revision: http://reviews.llvm.org/D5149 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220475 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 8 ++++++++ lib/Target/Mips/MicroMipsInstrFormats.td | 11 +++++++++++ lib/Target/Mips/MicroMipsInstrInfo.td | 12 ++++++++++++ test/MC/Mips/micromips-16-bit-instructions.s | 6 ++++++ test/MC/Mips/micromips-invalid.s | 2 ++ 5 files changed, 39 insertions(+) diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 6e8639c0914..501b1d276a7 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1170,6 +1170,14 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, if (Imm < 1 || Imm > 8) return Error(IDLoc, "immediate operand value out of range"); break; + case Mips::LI16_MM: + Opnd = Inst.getOperand(1); + if (!Opnd.isImm()) + return Error(IDLoc, "expected immediate operand kind"); + Imm = Opnd.getImm(); + if (Imm < -1 || Imm > 126) + return Error(IDLoc, "immediate operand value out of range"); + break; } } diff --git a/lib/Target/Mips/MicroMipsInstrFormats.td b/lib/Target/Mips/MicroMipsInstrFormats.td index 90ee077347e..ae80b4f7e6d 100644 --- a/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/lib/Target/Mips/MicroMipsInstrFormats.td @@ -114,6 +114,17 @@ class MOVE_FM_MM16 funct> { let Inst{4-0} = rs; } +class LI_FM_MM16 { + bits<3> rd; + bits<7> imm; + + bits<16> Inst; + + let Inst{15-10} = 0x3b; + let Inst{9-7} = rd; + let Inst{6-0} = imm; +} + class JALR_FM_MM16 op> { bits<5> rs; diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 656d369fe4d..3efa17cdc8c 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -1,6 +1,7 @@ def addrimm12 : ComplexPattern; def simm4 : Operand; +def simm7 : Operand; def simm12 : Operand { let DecoderMethod = "DecodeSimm12"; @@ -20,6 +21,8 @@ def uimm3_shift : Operand { def immZExt2Shift : ImmLeaf= 1 && Imm <= 8;}]>; +def immLi16 : ImmLeaf= -1 && Imm <= 126;}]>; + def mem_mm_12 : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops GPR32, simm12); @@ -154,6 +157,13 @@ class MoveMM16 : + MicroMipsInst16<(outs RO:$rd), (ins Od:$imm), + !strconcat(opstr, "\t$rd, $imm"), [], NoItinerary, FrmI> { + let isReMaterializable = 1; +} + // 16-bit Jump and Link (Call) class JumpLinkRegMM16 : MicroMipsInst16<(outs), (ins RO:$rs), !strconcat(opstr, "\t$rs"), @@ -240,6 +250,8 @@ def ADDIUSP_MM : AddImmUSP<"addiusp">, ADDIUSP_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>; +def LI16_MM : LoadImmMM16<"li16", simm7, GPRMM16Opnd, immLi16>, + LI_FM_MM16, IsAsCheapAsAMove; def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>; def JALRS16_MM : JumpLinkRegSMM16<"jalrs16", GPR32Opnd>, JALR_FM_MM16<0x0f>; def JRC16_MM : JumpRegCMM16<"jrc", GPR32Opnd>, JALR_FM_MM16<0x0d>; diff --git a/test/MC/Mips/micromips-16-bit-instructions.s b/test/MC/Mips/micromips-16-bit-instructions.s index 64296e8a17f..869c7b53493 100644 --- a/test/MC/Mips/micromips-16-bit-instructions.s +++ b/test/MC/Mips/micromips-16-bit-instructions.s @@ -17,6 +17,8 @@ # CHECK-EL: xor16 $17, $5 # encoding: [0x4d,0x44] # CHECK-EL: sll16 $3, $16, 5 # encoding: [0x8a,0x25] # 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: addius5 $7, -2 # encoding: [0xfc,0x4c] # CHECK-EL: addiusp -16 # encoding: [0xf9,0x4f] # CHECK-EL: mfhi $9 # encoding: [0x09,0x46] @@ -41,6 +43,8 @@ # CHECK-EB: xor16 $17, $5 # encoding: [0x44,0x4d] # CHECK-EB: sll16 $3, $16, 5 # encoding: [0x25,0x8a] # 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: addius5 $7, -2 # encoding: [0x4c,0xfc] # CHECK-EB: addiusp -16 # encoding: [0x4f,0xf9] # CHECK-EB: mfhi $9 # encoding: [0x46,0x09] @@ -63,6 +67,8 @@ xor16 $17, $5 sll16 $3, $16, 5 srl16 $4, $17, 6 + li16 $3, -1 + li16 $3, 126 addius5 $7, -2 addiusp -16 mfhi $9 diff --git a/test/MC/Mips/micromips-invalid.s b/test/MC/Mips/micromips-invalid.s index d9a5beb93ce..60e85f78c11 100644 --- a/test/MC/Mips/micromips-invalid.s +++ b/test/MC/Mips/micromips-invalid.s @@ -13,3 +13,5 @@ srl16 $4, $9, 6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction sll16 $3, $16, 9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range srl16 $4, $5, 15 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range + li16 $8, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction + li16 $4, -2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range -- 2.34.1