[mips][microMIPS] Implement disassembler support for 16-bit instructions LBU16, LHU16...
authorJozef Kolek <jozef.kolek@imgtec.com>
Wed, 26 Nov 2014 18:56:38 +0000 (18:56 +0000)
committerJozef Kolek <jozef.kolek@imgtec.com>
Wed, 26 Nov 2014 18:56:38 +0000 (18:56 +0000)
Differential Revision: http://reviews.llvm.org/D6405

llvm-svn: 222847

llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
llvm/lib/Target/Mips/MicroMipsInstrInfo.td
llvm/lib/Target/Mips/MipsRegisterInfo.td
llvm/test/MC/Disassembler/Mips/micromips.txt
llvm/test/MC/Disassembler/Mips/micromips_le.txt
llvm/test/MC/Mips/micromips-16-bit-instructions.s

index 8f25163..62ad7cf 100644 (file)
@@ -255,6 +255,11 @@ static DecodeStatus DecodeCacheOp(MCInst &Inst,
 static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
                                     uint64_t Address, const void *Decoder);
 
+static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
+                                    unsigned Insn,
+                                    uint64_t Address,
+                                    const void *Decoder);
+
 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
                                      unsigned Insn,
                                      uint64_t Address,
@@ -909,7 +914,11 @@ static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
                                                    unsigned RegNo,
                                                    uint64_t Address,
                                                    const void *Decoder) {
-  return MCDisassembler::Fail;
+  if (RegNo > 7)
+    return MCDisassembler::Fail;
+  unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo);
+  Inst.addOperand(MCOperand::CreateReg(Reg));
+  return MCDisassembler::Success;
 }
 
 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
@@ -1082,6 +1091,58 @@ static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeMemMMImm4(MCInst &Inst,
+                                    unsigned Insn,
+                                    uint64_t Address,
+                                    const void *Decoder) {
+  unsigned Offset = Insn & 0xf;
+  unsigned Reg = fieldFromInstruction(Insn, 7, 3);
+  unsigned Base = fieldFromInstruction(Insn, 4, 3);
+
+  switch (Inst.getOpcode()) {
+    case Mips::LBU16_MM:
+    case Mips::LHU16_MM:
+    case Mips::LW16_MM:
+      if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder)
+            == MCDisassembler::Fail)
+        return MCDisassembler::Fail;
+      break;
+    case Mips::SB16_MM:
+    case Mips::SH16_MM:
+    case Mips::SW16_MM:
+      if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)
+            == MCDisassembler::Fail)
+        return MCDisassembler::Fail;
+      break;
+  }
+
+  if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder)
+        == MCDisassembler::Fail)
+    return MCDisassembler::Fail;
+
+  switch (Inst.getOpcode()) {
+    case Mips::LBU16_MM:
+      if (Offset == 0xf)
+        Inst.addOperand(MCOperand::CreateImm(-1));
+      else
+        Inst.addOperand(MCOperand::CreateImm(Offset));
+      break;
+    case Mips::SB16_MM:
+      Inst.addOperand(MCOperand::CreateImm(Offset));
+      break;
+    case Mips::LHU16_MM:
+    case Mips::SH16_MM:
+      Inst.addOperand(MCOperand::CreateImm(Offset << 1));
+      break;
+    case Mips::LW16_MM:
+    case Mips::SW16_MM:
+      Inst.addOperand(MCOperand::CreateImm(Offset << 2));
+      break;
+  }
+
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
                                      unsigned Insn,
                                      uint64_t Address,
index 774b657..9c33040 100644 (file)
@@ -186,6 +186,7 @@ class LoadMM16<string opstr, DAGOperand RO, SDPatternOperator OpNode,
                InstrItinClass Itin, Operand MemOpnd> :
   MicroMipsInst16<(outs RO:$rt), (ins MemOpnd:$addr),
                   !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> {
+  let DecoderMethod = "DecodeMemMMImm4";
   let canFoldAsLoad = 1;
   let mayLoad = 1;
 }
@@ -195,6 +196,7 @@ class StoreMM16<string opstr, DAGOperand RTOpnd, DAGOperand RO,
                 Operand MemOpnd> :
   MicroMipsInst16<(outs), (ins RTOpnd:$rt, MemOpnd:$addr),
                   !strconcat(opstr, "\t$rt, $addr"), [], Itin, FrmI> {
+  let DecoderMethod = "DecodeMemMMImm4";
   let mayStore = 1;
 }
 
index 521ed2d..2b3b6c1 100644 (file)
@@ -297,10 +297,10 @@ def GPRMM16 : RegisterClass<"Mips", [i32], 32, (add
 def GPRMM16Zero : RegisterClass<"Mips", [i32], 32, (add
   // Reserved
   ZERO,
-  // Return Values and Arguments
-  V0, V1, A0, A1, A2, A3,
   // Callee save
-  S1)>;
+  S1,
+  // Return Values and Arguments
+  V0, V1, A0, A1, A2, A3)>;
 
 def GPR64 : RegisterClass<"Mips", [i64], 64, (add
 // Reserved
index dc27852..ab0cb99 100644 (file)
 # CHECK: srl16 $4, $17, 6
 0x26 0x1d
 
+# CHECK: lbu16 $3, 4($17)
+0x09 0x94
+
+# CHECK: lbu16 $3, -1($16)
+0x09 0x8f
+
+# CHECK: lhu16 $3, 4($16)
+0x29 0x82
+
+# CHECK: lw16 $4, 8($17)
+0x6a 0x12
+
+# CHECK: sb16 $3, 4($16)
+0x89 0x84
+
+# CHECK: sh16 $4, 8($17)
+0xaa 0x14
+
+# CHECK: sw16 $4, 4($17)
+0xea 0x11
+
+# CHECK: sw16 $zero, 4($17)
+0xe8 0x11
+
 # CHECK: mfhi $9
 0x46 0x09
 
index 47fdb2c..0da08bd 100644 (file)
 # CHECK: srl16 $4, $17, 6
 0x1d 0x26
 
+# CHECK: lbu16 $3, 4($17)
+0x94 0x09
+
+# CHECK: lbu16 $3, -1($16)
+0x8f 0x09
+
+# CHECK: lhu16 $3, 4($16)
+0x82 0x29
+
+# CHECK: lw16 $4, 8($17)
+0x12 0x6a
+
+# CHECK: sb16 $3, 4($16)
+0x84 0x89
+
+# CHECK: sh16 $4, 8($17)
+0x14 0xaa
+
+# CHECK: sw16 $4, 4($17)
+0x11 0xea
+
+# CHECK: sw16 $zero, 4($17)
+0x11 0xe8
+
 # CHECK: mfhi $9
 0x09 0x46
 
index f8095b1..2dfec79 100644 (file)
@@ -19,6 +19,7 @@
 # CHECK-EL: sll16   $3, $16, 5      # encoding: [0x8a,0x25]
 # CHECK-EL: srl16   $4, $17, 6      # encoding: [0x1d,0x26]
 # CHECK-EL: lbu16   $3, 4($17)      # encoding: [0x94,0x09]
+# CHECK-EL: lbu16   $3, -1($16)     # encoding: [0x8f,0x09]
 # CHECK-EL: lhu16   $3, 4($16)      # encoding: [0x82,0x29]
 # CHECK-EL: lw16    $4, 8($17)      # encoding: [0x12,0x6a]
 # CHECK-EL: sb16    $3, 4($16)      # encoding: [0x84,0x89]
@@ -55,6 +56,7 @@
 # CHECK-EB: sll16   $3, $16, 5      # encoding: [0x25,0x8a]
 # CHECK-EB: srl16   $4, $17, 6      # encoding: [0x26,0x1d]
 # CHECK-EB: lbu16   $3, 4($17)      # encoding: [0x09,0x94]
+# CHECK-EB: lbu16   $3, -1($16)     # encoding: [0x09,0x8f]
 # CHECK-EB: lhu16   $3, 4($16)      # encoding: [0x29,0x82]
 # CHECK-EB: lw16    $4, 8($17)      # encoding: [0x6a,0x12]
 # CHECK-EB: sb16    $3, 4($16)      # encoding: [0x89,0x84]
@@ -89,6 +91,7 @@
     sll16   $3, $16, 5
     srl16   $4, $17, 6
     lbu16   $3, 4($17)
+    lbu16   $3, -1($16)
     lhu16   $3, 4($16)
     lw16    $4, 8($17)
     sb16    $3, 4($16)