[mips][microMIPS] Implement ADDU16 and SUBU16 instructions
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Tue, 21 Oct 2014 08:44:58 +0000 (08:44 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Tue, 21 Oct 2014 08:44:58 +0000 (08:44 +0000)
Differential Revision: http://reviews.llvm.org/D5118

llvm-svn: 220276

llvm/lib/Target/Mips/MicroMipsInstrFormats.td
llvm/lib/Target/Mips/MicroMipsInstrInfo.td
llvm/test/MC/Mips/micromips-16-bit-instructions.s
llvm/test/MC/Mips/micromips-invalid.s

index 2cf1968..4f2444c 100644 (file)
@@ -41,6 +41,20 @@ class MicroMipsInst16<dag outs, dag ins, string asmstr, list<dag> pattern,
 // MicroMIPS 16-bit Instruction Formats
 //===----------------------------------------------------------------------===//
 
+class ARITH_FM_MM16<bit funct> {
+  bits<3> rd;
+  bits<3> rt;
+  bits<3> rs;
+
+  bits<16> Inst;
+
+  let Inst{15-10} = 0x01;
+  let Inst{9-7}   = rd;
+  let Inst{6-4}   = rt;
+  let Inst{3-1}   = rs;
+  let Inst{0}     = funct;
+}
+
 class LOGIC_FM_MM16<bits<4> funct> {
   bits<3> rt;
   bits<3> rs;
index 6e19315..ab649be 100644 (file)
@@ -90,6 +90,15 @@ class LoadMM<string opstr, DAGOperand RO, SDPatternOperator OpNode = null_frag,
   let mayLoad = 1;
 }
 
+class ArithRMM16<string opstr, RegisterOperand RO, bit isComm = 0,
+                 InstrItinClass Itin = NoItinerary,
+                 SDPatternOperator OpNode = null_frag> :
+  MicroMipsInst16<(outs RO:$rd), (ins RO:$rs, RO:$rt),
+                  !strconcat(opstr, "\t$rd, $rs, $rt"),
+                  [(set RO:$rd, (OpNode RO:$rs, RO:$rt))], Itin, FrmR> {
+  let isCommutable = isComm;
+}
+
 class LogicRMM16<string opstr, RegisterOperand RO,
                  InstrItinClass Itin = NoItinerary,
                  SDPatternOperator OpNode = null_frag> :
@@ -197,6 +206,10 @@ let isCall = 1, hasDelaySlot = 1, Defs = [RA] in {
            !strconcat(opstr, "\t$rs, $offset"), [], IIBranch, FrmI, opstr>;
 }
 
+def ADDU16_MM : ArithRMM16<"addu16", GPRMM16Opnd, 1, II_ADDU, add>,
+                ARITH_FM_MM16<0>;
+def SUBU16_MM : ArithRMM16<"subu16", GPRMM16Opnd, 0, II_SUBU, sub>,
+                ARITH_FM_MM16<1>;
 def AND16_MM : LogicRMM16<"and16", GPRMM16Opnd, II_AND, and>,
                LOGIC_FM_MM16<0x2>;
 def OR16_MM  : LogicRMM16<"or16", GPRMM16Opnd, II_OR, or>,
index 2aea84f..4a4b9eb 100644 (file)
@@ -9,6 +9,8 @@
 #------------------------------------------------------------------------------
 # Little endian
 #------------------------------------------------------------------------------
+# CHECK-EL: addu16  $6, $17, $4     # encoding: [0x42,0x07]
+# CHECK-EL: subu16  $5, $16, $3     # encoding: [0xb1,0x06]
 # CHECK-EL: and16   $16, $2         # encoding: [0x82,0x44]
 # CHECK-EL: not16   $17, $3         # encoding: [0x0b,0x44]
 # CHECK-EL: or16    $16, $4         # encoding: [0xc4,0x44]
@@ -29,6 +31,8 @@
 #------------------------------------------------------------------------------
 # Big endian
 #------------------------------------------------------------------------------
+# CHECK-EB: addu16  $6, $17, $4     # encoding: [0x07,0x42]
+# CHECK-EB: subu16  $5, $16, $3     # encoding: [0x06,0xb1]
 # CHECK-EB: and16   $16, $2         # encoding: [0x44,0x82]
 # CHECK-EB: not16   $17, $3         # encoding: [0x44,0x0b]
 # CHECK-EB: or16    $16, $4         # encoding: [0x44,0xc4]
@@ -47,6 +51,8 @@
 # CHECK-EB: jr16    $9              # encoding: [0x45,0x89]
 # CHECK-EB: nop                     # encoding: [0x00,0x00,0x00,0x00]
 
+    addu16  $6, $17, $4
+    subu16  $5, $16, $3
     and16   $16, $2
     not16   $17, $3
     or16    $16, $4
index b9697c2..9cea8ef 100644 (file)
@@ -3,6 +3,8 @@
 
   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
+  subu16  $5, $16, $9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   and16   $16, $8   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   not16   $18, $9   # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
   or16    $16, $10  # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction