[mips][microMIPS] Implement DDIV, DMOD, DDIVU and DMODU instructions
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Tue, 18 Aug 2015 14:40:43 +0000 (14:40 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Tue, 18 Aug 2015 14:40:43 +0000 (14:40 +0000)
Differential Revision: http://reviews.llvm.org/D10953

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

lib/Target/Mips/MicroMips64r6InstrFormats.td
lib/Target/Mips/MicroMips64r6InstrInfo.td
test/MC/Disassembler/Mips/micromips64r6.txt
test/MC/Mips/micromips64r6/invalid.s [new file with mode: 0644]
test/MC/Mips/micromips64r6/valid.s [new file with mode: 0644]

index a530ec931136d52f6c386201147283ada32cf994..da305a2d508aa157733d25a0858e08f69ea734f9 100644 (file)
@@ -68,3 +68,19 @@ class POOL32S_DALIGN_FM_MMR6 {
   let Inst{7-6}   = 0b00;
   let Inst{5-0}   = 0b011100;
 }
+
+class POOL32A_DIVMOD_FM_MMR6<string instr_asm, bits<9> funct>
+    : MMR6Arch<instr_asm> {
+  bits<5> rd;
+  bits<5> rs;
+  bits<5> rt;
+
+  bits<32> Inst;
+
+  let Inst{31-26} = 0b010110;
+  let Inst{25-21} = rd;
+  let Inst{20-16} = rs;
+  let Inst{15-11} = rt;
+  let Inst{10-9}  = 0b00;
+  let Inst{8-0}  = funct;
+}
index f93843d5ea79af95864e7b6b5398bd42b735feba..dfc54d75b3614b0587a0c730405a7a8f64132c14 100644 (file)
@@ -24,6 +24,10 @@ class DEXT_MMR6_ENC : POOL32S_EXTBITS_FM_MMR6<0b101100>;
 class DEXTM_MMR6_ENC : POOL32S_EXTBITS_FM_MMR6<0b100100>;
 class DEXTU_MMR6_ENC : POOL32S_EXTBITS_FM_MMR6<0b010100>;
 class DALIGN_MMR6_ENC : POOL32S_DALIGN_FM_MMR6;
+class DDIV_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"ddiv", 0b100011000>;
+class DMOD_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmod", 0b101011000>;
+class DDIVU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"ddivu", 0b110011000>;
+class DMODU_MM64R6_ENC : POOL32A_DIVMOD_FM_MMR6<"dmodu", 0b111011000>;
 
 //===----------------------------------------------------------------------===//
 //
@@ -77,6 +81,11 @@ class DALIGN_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
 
 class DALIGN_MMR6_DESC : DALIGN_DESC_BASE<"dalign", GPR64Opnd, uimm3>;
 
+class DDIV_MM64R6_DESC : ArithLogicR<"ddiv", GPR32Opnd>;
+class DMOD_MM64R6_DESC : ArithLogicR<"dmod", GPR32Opnd>;
+class DDIVU_MM64R6_DESC : ArithLogicR<"ddivu", GPR32Opnd>;
+class DMODU_MM64R6_DESC : ArithLogicR<"dmodu", GPR32Opnd>;
+
 //===----------------------------------------------------------------------===//
 //
 // Instruction Definitions
@@ -95,4 +104,12 @@ let DecoderNamespace = "MicroMipsR6" in {
                      ISA_MICROMIPS64R6;
   def DALIGN_MM64R6 : StdMMR6Rel, DALIGN_MMR6_DESC, DALIGN_MMR6_ENC,
                       ISA_MICROMIPS64R6;
+  def DDIV_MM64R6 : R6MMR6Rel, DDIV_MM64R6_DESC, DDIV_MM64R6_ENC,
+                    ISA_MICROMIPS64R6;
+  def DMOD_MM64R6 : R6MMR6Rel, DMOD_MM64R6_DESC, DMOD_MM64R6_ENC,
+                    ISA_MICROMIPS64R6;
+  def DDIVU_MM64R6 : R6MMR6Rel, DDIVU_MM64R6_DESC, DDIVU_MM64R6_ENC,
+                     ISA_MICROMIPS64R6;
+  def DMODU_MM64R6 : R6MMR6Rel, DMODU_MM64R6_DESC, DMODU_MM64R6_ENC,
+                     ISA_MICROMIPS64R6;
 }
index 3abb7d22e18f74f2bbe6406576a1342cf3735bbf..b0ab43d0a30a2d0aece38f96dbd6cb56af641aad 100644 (file)
 0x59 0x26 0x30 0xd4 # CHECK: dextu $9, $6, 3, 7
 
 0x58 0x43 0x25 0x1c # CHECK: dalign $4, $2, $3, 5
+
+0x58 0x64 0x29 0x18 # CHECK: ddiv $3, $4, $5
+
+0x58 0x64 0x29 0x58 # CHECK: dmod $3, $4, $5
+
+0x58 0x64 0x29 0x98 # CHECK: ddivu $3, $4, $5
+
+0x58 0x64 0x29 0xd8 # CHECK: dmodu $3, $4, $5
diff --git a/test/MC/Mips/micromips64r6/invalid.s b/test/MC/Mips/micromips64r6/invalid.s
new file mode 100644 (file)
index 0000000..d88caf4
--- /dev/null
@@ -0,0 +1,15 @@
+# RUN: not llvm-mc %s -triple=mips -show-encoding -mcpu=mips64r6 -mattr=micromips 2>%t1
+# RUN: FileCheck %s < %t1
+
+  ddiv $32, $4, $5         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  ddiv $3, $34, $5         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  ddiv $3, $4, $35         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  dmod $32, $4, $5         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  dmod $3, $34, $5         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  dmod $3, $4, $35         # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  ddivu $32, $4, $5        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  ddivu $3, $34, $5        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  ddivu $3, $4, $35        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  dmodu $32, $4, $5        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  dmodu $3, $34, $5        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
+  dmodu $3, $4, $35        # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
diff --git a/test/MC/Mips/micromips64r6/valid.s b/test/MC/Mips/micromips64r6/valid.s
new file mode 100644 (file)
index 0000000..5937db5
--- /dev/null
@@ -0,0 +1,16 @@
+# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips64r6 -mattr=micromips | FileCheck %s
+a:
+        .set noat
+        daui $3, $4, 5           # CHECK: daui $3, $4, 5      # encoding: [0xf0,0x64,0x00,0x05]
+        dahi $3, 4               # CHECK: dahi $3, 4          # encoding: [0x42,0x23,0x00,0x04]
+        dati $3, 4               # CHECK: dati $3, 4          # encoding: [0x42,0x03,0x00,0x04]
+        dext $9, $6, 3, 7        # CHECK: dext $9, $6, 3, 7   # encoding: [0x59,0x26,0x30,0xec]
+        dextm $9, $6, 3, 7       # CHECK: dextm $9, $6, 3, 7  # encoding: [0x59,0x26,0x30,0xe4]
+        dextu $9, $6, 3, 7       # CHECK: dextu $9, $6, 3, 7  # encoding: [0x59,0x26,0x30,0xd4]
+        dalign $4, $2, $3, 5     # CHECK: dalign $4, $2, $3, 5  # encoding: [0x58,0x43,0x25,0x1c]
+        ddiv $3, $4, $5          # CHECK: ddiv $3, $4, $5     # encoding: [0x58,0x64,0x29,0x18]
+        dmod $3, $4, $5          # CHECK: dmod $3, $4, $5     # encoding: [0x58,0x64,0x29,0x58]
+        ddivu $3, $4, $5         # CHECK: ddivu $3, $4, $5    # encoding: [0x58,0x64,0x29,0x98]
+        dmodu $3, $4, $5         # CHECK: dmodu $3, $4, $5    # encoding: [0x58,0x64,0x29,0xd8]
+
+1: