[mips][microMIPS] Implement PREFX, LHUE, LBE, LBUE, LHE, LWE, SBE, SHE and SWE instru...
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Wed, 16 Sep 2015 09:14:35 +0000 (09:14 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Wed, 16 Sep 2015 09:14:35 +0000 (09:14 +0000)
Differential Revision: http://reviews.llvm.org/D9189

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247780 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/MicroMipsInstrFormats.td
lib/Target/Mips/MicroMipsInstrInfo.td
lib/Target/Mips/MipsInstrInfo.td
test/MC/Disassembler/Mips/micromips.txt
test/MC/Disassembler/Mips/micromips_le.txt
test/MC/Mips/micromips-control-instructions.s
test/MC/Mips/micromips-invalid.s
test/MC/Mips/micromips-loadstore-instructions.s
test/MC/Mips/mips32r6/invalid-mips4-wrong-error.s
test/MC/Mips/mips32r6/invalid-mips4.s
test/MC/Mips/mips64r6/invalid-mips4-wrong-error.s
test/MC/Mips/mips64r6/invalid-mips4.s

index 0bddc4ca690007e5c3d9a5c460ba5429a7aac07e..ee92f357a12272ed6cbe38f7b00b117142668cfe 100644 (file)
@@ -947,6 +947,10 @@ public:
     return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
       && getMemBase()->isGPRAsmReg();
   }
+  template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
+    return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff()) &&
+           getMemBase()->isGPRAsmReg();
+  }
   bool isMemWithGRPMM16Base() const {
     return isMem() && getMemBase()->isMM16AsmReg();
   }
@@ -1758,6 +1762,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
         if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
           return Error(IDLoc, "immediate operand value out of range");
         break;
+      case Mips::PREFX_MM:
       case Mips::CACHE:
       case Mips::PREF:
         Opnd = Inst.getOperand(2);
index 161de310ab51a534f31347e90df58a12a57e3511..7807809470e749fca140de140d7f201a9cfdd8df 100644 (file)
@@ -389,6 +389,22 @@ class LW_FM_MM<bits<6> op> : MMArch {
   let Inst{15-0}  = addr{15-0};
 }
 
+class POOL32C_LHUE_FM_MM<bits<6> op, bits<4> fmt, bits<3> funct> : MMArch {
+  bits<5> rt;
+  bits<21> addr;
+  bits<5> base = addr{20-16};
+  bits<9> offset = addr{8-0};
+
+  bits<32> Inst;
+
+  let Inst{31-26} = op;
+  let Inst{25-21} = rt;
+  let Inst{20-16} = base;
+  let Inst{15-12} = fmt;
+  let Inst{11-9} = funct;
+  let Inst{8-0}  = offset;
+}
+
 class LWL_FM_MM<bits<4> funct> {
   bits<5> rt;
   bits<21> addr;
@@ -938,6 +954,21 @@ class CACHE_PREFE_FM_MM<bits<6> op, bits<3> funct> : MMArch {
   let Inst{8-0}  = offset;
 }
 
+class POOL32F_PREFX_FM_MM<bits<6> op, bits<9> funct> : MMArch {
+  bits<5> index;
+  bits<5> base;
+  bits<5> hint;
+
+  bits<32> Inst;
+
+  let Inst{31-26} = op;
+  let Inst{25-21} = index;
+  let Inst{20-16} = base;
+  let Inst{15-11} = hint;
+  let Inst{10-9}  = 0x0;
+  let Inst{8-0}   = funct;
+}
+
 class BARRIER_FM_MM<bits<5> op> : MMArch {
   bits<32> Inst;
 
index a114309e68847428b38c7692ad26e24690640614..78474b8379e9f0b47b94c882b4eaf623d0d66c7f 100644 (file)
@@ -484,6 +484,10 @@ class LoadWordIndexedScaledMM<string opstr, RegisterOperand RO,
   InstSE<(outs RO:$rd), (ins PtrRC:$base, PtrRC:$index),
          !strconcat(opstr, "\t$rd, ${index}(${base})"), [], Itin, FrmFI>;
 
+class PrefetchIndexed<string opstr> :
+  InstSE<(outs), (ins PtrRC:$base, PtrRC:$index, uimm5:$hint),
+         !strconcat(opstr, "\t$hint, ${index}(${base})"), [], NoItinerary, FrmOther>;
+
 class AddImmUPC<string opstr, RegisterOperand RO> :
   InstSE<(outs RO:$rs), (ins simm23_lsl2:$imm),
          !strconcat(opstr, "\t$rs, $imm"), [], NoItinerary, FrmR>;
@@ -713,6 +717,18 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
     def SW_MM  : Store<"sw", GPR32Opnd>, MMRel, LW_FM_MM<0x3e>;
   }
 
+  let DecoderMethod = "DecodeMemMMImm9" in {
+    def LBE_MM  : Load<"lbe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x4>;
+    def LBuE_MM : Load<"lbue", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x0>;
+    def LHE_MM  : Load<"lhe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x5>;
+    def LHuE_MM : Load<"lhue", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x1>;
+    def LWE_MM  : Load<"lwe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0x6, 0x7>;
+    def SBE_MM  : Store<"sbe", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x4>;
+    def SHE_MM  : Store<"she", GPR32Opnd>, POOL32C_LHUE_FM_MM<0x18, 0xa, 0x5>;
+    def SWE_MM  : StoreMemory<"swe", GPR32Opnd, mem_simm9gpr>,
+                  POOL32C_LHUE_FM_MM<0x18, 0xa, 0x7>;
+  }
+
   def LWXS_MM : LoadWordIndexedScaledMM<"lwxs", GPR32Opnd>, LWXS_FM_MM<0x118>;
 
   def LWU_MM : LoadMM<"lwu", GPR32Opnd, zextloadi32, II_LWU>, LL_FM_MM<0xe>;
@@ -890,6 +906,8 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
 
   def SDBBP_MM : MMRel, SYS_FT<"sdbbp">, SDBBP_FM_MM;
   def RDHWR_MM : MMRel, ReadHardware<GPR32Opnd, HWRegsOpnd>, RDHWR_FM_MM;
+
+  def PREFX_MM : PrefetchIndexed<"prefx">, POOL32F_PREFX_FM_MM<0x15, 0x1A0>;
 }
 
 let Predicates = [InMicroMips] in {
index dfee87f82759cfd9cd81b6329143ec95c1955cf8..f9bf19f00dca71af8197961f28239b1888f8c595 100644 (file)
@@ -466,6 +466,14 @@ def MipsMemSimm9AsmOperand : AsmOperandClass {
   let PredicateMethod = "isMemWithSimmOffset<9>";
 }
 
+def MipsMemSimm9GPRAsmOperand : AsmOperandClass {
+  let Name = "MemOffsetSimm9GPR";
+  let SuperClasses = [MipsMemAsmOperand];
+  let RenderMethod = "addMemOperands";
+  let ParserMethod = "parseMemOperand";
+  let PredicateMethod = "isMemWithSimmOffsetGPR<9>";
+}
+
 def MipsMemSimm11AsmOperand : AsmOperandClass {
   let Name = "MemOffsetSimm11";
   let SuperClasses = [MipsMemAsmOperand];
@@ -519,6 +527,12 @@ def mem_simm9 : mem_generic {
   let ParserMatchClass = MipsMemSimm9AsmOperand;
 }
 
+def mem_simm9gpr : mem_generic {
+  let MIOperandInfo = (ops ptr_rc, simm9);
+  let EncoderMethod = "getMemEncoding";
+  let ParserMatchClass = MipsMemSimm9GPRAsmOperand;
+}
+
 def mem_simm11 : mem_generic {
   let MIOperandInfo = (ops ptr_rc, simm11);
   let EncoderMethod = "getMemEncoding";
@@ -707,14 +721,19 @@ class Load<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
   let mayLoad = 1;
 }
 
-class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
+class StoreMemory<string opstr, DAGOperand RO, DAGOperand MO,
+            SDPatternOperator OpNode = null_frag,
             InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
-  InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
+  InstSE<(outs), (ins RO:$rt, MO:$addr), !strconcat(opstr, "\t$rt, $addr"),
          [(OpNode RO:$rt, Addr:$addr)], Itin, FrmI, opstr> {
   let DecoderMethod = "DecodeMem";
   let mayStore = 1;
 }
 
+class Store<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
+            InstrItinClass Itin = NoItinerary, ComplexPattern Addr = addr> :
+  StoreMemory<opstr, RO, mem, OpNode, Itin, Addr>;
+
 // Load/Store Left/Right
 let canFoldAsLoad = 1 in
 class LoadLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
index 238d786a2b6834f67b5ff0ad1448c5d1db8a797d..8b0aa9c71e7645cc09bea3a512897effd31be353 100644 (file)
 0x60 0x25 0xa6 0x08 # CHECK: cachee 1, 8($5)
 
 0x60 0x25 0xa4 0x08 # CHECK: prefe 1, 8($5)
+
+0x54 0x65 0x09 0xa0 # CHECK: prefx 1, $3($5)
+
+0x60 0x82 0x62 0x08 # CHECK: lhue $4, 8($2)
+
+0x60 0x82 0x68 0x08 # CHECK: lbe $4, 8($2)
+
+0x60 0x82 0x60 0x08 # CHECK: lbue $4, 8($2)
+
+0x60 0x82 0x6a 0x08 # CHECK: lhe $4, 8($2)
+
+0x60 0x82 0x6e 0x08 # CHECK: lwe $4, 8($2)
+
+0x60 0xa4 0xa8 0x08 # CHECK: sbe $5, 8($4)
+
+0x60 0xa4 0xaa 0x08 # CHECK: she $5, 8($4)
+
+0x60 0xa4 0xae 0x08 # CHECK: swe $5, 8($4)
index c3b23741bd0d7e1746cde2c90220aafad5bdcac3..8b12b8648c909ab73ae2ee7010349566d175da82 100644 (file)
 0x25 0x60 0x08 0xa6 # CHECK: cachee 1, 8($5)
 
 0x25 0x60 0x08 0xa4 # CHECK: prefe 1, 8($5)
+
+0x65 0x54 0xa0 0x09 # CHECK: prefx 1, $3($5)
+
+0x82 0x60 0x08 0x62 # CHECK: lhue $4, 8($2)
+
+0x82 0x60 0x08 0x68 # CHECK: lbe $4, 8($2)
+
+0x82 0x60 0x08 0x60 # CHECK: lbue $4, 8($2)
+
+0x82 0x60 0x08 0x6a # CHECK: lhe $4, 8($2)
+
+0x82 0x60 0x08 0x6e # CHECK: lwe $4, 8($2)
+
+0xa4 0x60 0x08 0xa8 # CHECK: sbe $5, 8($4)
+
+0xa4 0x60 0x08 0xaa # CHECK: she $5, 8($4)
+
+0xa4 0x60 0x08 0xae # CHECK: swe $5, 8($4)
index 5e42a6072a9839457a58eb17e117e15a59bdbf62..41f2b62ca3ddc47b5a665b788bfe9d54be847a94 100644 (file)
@@ -41,6 +41,7 @@
 # CHECK-EL:    tlbwr                      # encoding: [0x00,0x00,0x7c,0x33]
 # CHECK-EL:    prefe 1, 8($5)             # encoding: [0x25,0x60,0x08,0xa4]
 # CHECK-EL:    cachee 1, 8($5)            # encoding: [0x25,0x60,0x08,0xa6]
+# CHECK-EL:    prefx 1, $3($5)            # encoding: [0x65,0x54,0xa0,0x09]
 #------------------------------------------------------------------------------
 # Big endian
 #------------------------------------------------------------------------------
@@ -76,6 +77,7 @@
 # CHECK-EB:   tlbwr                       # encoding: [0x00,0x00,0x33,0x7c]
 # CHECK-EB:   prefe 1, 8($5)              # encoding: [0x60,0x25,0xa4,0x08]
 # CHECK-EB:   cachee 1, 8($5)             # encoding: [0x60,0x25,0xa6,0x08]
+# CHECK-EB:   prefx 1, $3($5)             # encoding: [0x54,0x65,0x09,0xa0]
 
     sdbbp
     sdbbp 34
     tlbwr
     prefe 1, 8($5)
     cachee 1, 8($5)
+    prefx 1, $3($5)
index 74a62ceeba0a69591b8e4d0fe2b4d21804dd47b5..1cf792eec55f64c2258bce94ffdf30c61742fad8 100644 (file)
@@ -78,3 +78,4 @@
   break 7, 1024     # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   break 1024, 1024  # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   wait 1024         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  prefx 33, $8($5) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
index f22719dff94e39d2e1f5d20896a370b2d58a3d04..4865713a3c72cc0104d32768b0cc9e008f1a88bf 100644 (file)
 # CHECK-EL: swm32  $16, $17, 8($sp)           # encoding: [0x5d,0x20,0x08,0xd0]
 # CHECK-EL: swp    $16, 8($4)                 # encoding: [0x04,0x22,0x08,0x90]
 # CHECK-EL: lwp    $16, 8($4)                 # encoding: [0x04,0x22,0x08,0x10]
+# CHECK-EL: lhue   $4, 8($2)                  # encoding: [0x82,0x60,0x08,0x62]
+# CHECK-EL: lbe    $4, 8($2)                  # encoding: [0x82,0x60,0x08,0x68]
+# CHECK-EL: lbue   $4, 8($2)                  # encoding: [0x82,0x60,0x08,0x60]
+# CHECK-EL: lhe    $4, 8($2)                  # encoding: [0x82,0x60,0x08,0x6a]
+# CHECK-EL: lwe    $4, 8($2)                  # encoding: [0x82,0x60,0x08,0x6e]
+# CHECK-EL: sbe    $5, 8($4)                  # encoding: [0xa4,0x60,0x08,0xa8]
+# CHECK-EL: she    $5, 8($4)                  # encoding: [0xa4,0x60,0x08,0xaa]
+# CHECK-EL: swe    $5, 8($4)                  # encoding: [0xa4,0x60,0x08,0xae]
 #------------------------------------------------------------------------------
 # Big endian
 #------------------------------------------------------------------------------
 # CHECK-EB: swm32  $16, $17, 8($sp)          # encoding: [0x20,0x5d,0xd0,0x08]
 # CHECK-EB: swp    $16, 8($4)                # encoding: [0x22,0x04,0x90,0x08]
 # CHECK-EB: lwp    $16, 8($4)                # encoding: [0x22,0x04,0x10,0x08]
+# CHECK-EB: lhue   $4, 8($2)                 # encoding: [0x60,0x82,0x62,0x08]
+# CHECK-EB: lbe    $4, 8($2)                 # encoding: [0x60,0x82,0x68,0x08]
+# CHECK-EB: lbue   $4, 8($2)                 # encoding: [0x60,0x82,0x60,0x08]
+# CHECK-EB: lhe    $4, 8($2)                 # encoding: [0x60,0x82,0x6a,0x08]
+# CHECK-EB: lwe    $4, 8($2)                 # encoding: [0x60,0x82,0x6e,0x08]
+# CHECK-EB: sbe    $5, 8($4)                 # encoding: [0x60,0xa4,0xa8,0x08]
+# CHECK-EB: she    $5, 8($4)                 # encoding: [0x60,0xa4,0xaa,0x08]
+# CHECK-EB: swe    $5, 8($4)                 # encoding: [0x60,0xa4,0xae,0x08]
      lb     $5, 8($4)
      lbu    $6, 8($4)
      lh     $2, 8($4)
      swm    $16, $17, 8($sp)
      swp    $16, 8($4)
      lwp    $16, 8($4)
+     lhue   $4, 8($2)
+     lbe    $4, 8($2)
+     lbue   $4, 8($2)
+     lhe    $4, 8($2)
+     lwe    $4, 8($2)
+     sbe    $5, 8($4)
+     she    $5, 8($4)
+     swe    $5, 8($4)
index 06bf58c1e8fa98395a9901e7c3bc0572ae706602..1cec777c27a653f43af55adfb69e7264dede28a4 100644 (file)
@@ -8,4 +8,3 @@
         .set noat
         bc2tl 4                 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction
         bc2fl 4                 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction
-        prefx 0,$2($31)         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction
index 9d8f02fb6d67c3c68a0ca501125ca6586ae9e951..6a037087011244e1fa4b57f17f374ed4467f29ca 100644 (file)
@@ -11,3 +11,4 @@
         lwxc1     $f12,$s1($s8)       # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
         sdxc1     $f11,$10($14)       # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
         swxc1     $f19,$12($k0)       # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
+        prefx     0,$2($31)           # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
index 06bf58c1e8fa98395a9901e7c3bc0572ae706602..1cec777c27a653f43af55adfb69e7264dede28a4 100644 (file)
@@ -8,4 +8,3 @@
         .set noat
         bc2tl 4                 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction
         bc2fl 4                 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction
-        prefx 0,$2($31)         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction
index 82a1196daf84950863c70cd3f377bdcd75bd2524..a25eeaa09871c8024dc90e132a1bbc7f9f00ed32 100644 (file)
@@ -14,3 +14,4 @@
         lwxc1     $f12,$s1($s8)       # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
         sdxc1     $f11,$10($14)       # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
         swxc1     $f19,$12($k0)       # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
+        prefx     0,$2($31)           # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled