Add MC support for the v8fp instructions: vmaxnm and vminnm.
authorJoey Gouly <joey.gouly@arm.com>
Sat, 6 Jul 2013 20:50:18 +0000 (20:50 +0000)
committerJoey Gouly <joey.gouly@arm.com>
Sat, 6 Jul 2013 20:50:18 +0000 (20:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185767 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrFormats.td
lib/Target/ARM/ARMInstrVFP.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/v8fp.s
test/MC/Disassembler/ARM/v8fp.txt

index 91564da8e628f5178349409c7e9042e02ed44dfe..16b7bc5e404370ceec55634a2e05e98aab998f50 100644 (file)
@@ -1549,7 +1549,7 @@ class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
 }
 
 // FP, binary, not predicated
-class ADbInp<bits<5> opcod1, bits<2> opcod2, dag oops, dag iops,
+class ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
            InstrItinClass itin, string asm, list<dag> pattern>
   : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
           VFPBinaryFrm, itin, asm, "", pattern>
@@ -1573,7 +1573,7 @@ class ADbInp<bits<5> opcod1, bits<2> opcod2, dag oops, dag iops,
   let Inst{21-20} = opcod2;
   let Inst{11-9}  = 0b101;
   let Inst{8}     = 1; // double precision
-  let Inst{6}     = 0;
+  let Inst{6}     = opcod3;
   let Inst{4}     = 0;
 }
 
@@ -1637,7 +1637,7 @@ class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
 }
 
 // Single precision, binary, not predicated
-class ASbInp<bits<5> opcod1, bits<2> opcod2, dag oops, dag iops,
+class ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
            InstrItinClass itin, string asm, list<dag> pattern>
   : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
           VFPBinaryFrm, itin, asm, "", pattern>
@@ -1661,7 +1661,7 @@ class ASbInp<bits<5> opcod1, bits<2> opcod2, dag oops, dag iops,
   let Inst{21-20} = opcod2;
   let Inst{11-9}  = 0b101;
   let Inst{8}     = 0; // Single precision
-  let Inst{6}     = 0;
+  let Inst{6}     = opcod3;
   let Inst{4}     = 0;
 }
 
index dcac75443734c818563d8cdbe0131da3f969114f..27e2df4bfd4e9bbde99373cd4f9840a12c5e3194 100644 (file)
@@ -335,12 +335,12 @@ def VNMULS : ASbI<0b11100, 0b10, 1, 0,
 
 multiclass vsel_inst<string op, bits<2> opc> {
   let DecoderNamespace = "VFPV8", PostEncoderMethod = "" in {
-    def S : ASbInp<0b11100, opc,
+    def S : ASbInp<0b11100, opc, 0,
                    (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
                    NoItinerary, !strconcat("vsel", op, ".f32\t$Sd, $Sn, $Sm"),
                    []>, Requires<[HasV8FP]>;
 
-    def D : ADbInp<0b11100, opc,
+    def D : ADbInp<0b11100, opc, 0,
                    (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
                    NoItinerary, !strconcat("vsel", op, ".f64\t$Dd, $Dn, $Dm"),
                    []>, Requires<[HasV8FP]>;
@@ -352,6 +352,23 @@ defm VSELGE : vsel_inst<"ge", 0b10>;
 defm VSELEQ : vsel_inst<"eq", 0b00>;
 defm VSELVS : vsel_inst<"vs", 0b01>;
 
+multiclass vmaxmin_inst<string op, bit opc> {
+  let DecoderNamespace = "VFPV8", PostEncoderMethod = "" in {
+    def S : ASbInp<0b11101, 0b00, opc,
+                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
+                   NoItinerary, !strconcat(op, ".f32\t$Sd, $Sn, $Sm"),
+                   []>, Requires<[HasV8FP]>;
+
+    def D : ADbInp<0b11101, 0b00, opc,
+                   (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
+                   NoItinerary, !strconcat(op, ".f64\t$Dd, $Dn, $Dm"),
+                   []>, Requires<[HasV8FP]>;
+  }
+}
+
+defm VMAXNM : vmaxmin_inst<"vmaxnm", 0>;
+defm VMINNM : vmaxmin_inst<"vminnm", 1>;
+
 // Match reassociated forms only if not sign dependent rounding.
 def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)),
           (VNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
index 687ea3f9410167f1355854465cdd3b1874e778cc..f7f19014895ffb02b6b3cdff21e6e68a995b94e2 100644 (file)
@@ -4905,7 +4905,8 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
       Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
       Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
       Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
-      Mnemonic == "fmuls" || Mnemonic.startswith("vsel"))
+      Mnemonic == "fmuls" || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" ||
+      Mnemonic.startswith("vsel"))
     return Mnemonic;
 
   // First, split out any predication code. Ignore mnemonics we know aren't
@@ -5005,7 +5006,8 @@ getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
   if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
       Mnemonic == "cps" ||  Mnemonic == "it" ||  Mnemonic == "cbz" ||
       Mnemonic == "trap" || Mnemonic == "setend" ||
-      Mnemonic.startswith("cps") || Mnemonic.startswith("vsel")) {
+      Mnemonic.startswith("cps") || Mnemonic == "vmaxnm" ||
+                       Mnemonic == "vminnm" || Mnemonic.startswith("vsel")) {
     // These mnemonics are never predicable
     CanAcceptPredicationCode = false;
   } else if (!isThumb()) {
index 440a94ca1ad1aad039b576d218f0deb9eb112838..05a7f1badde5d9b73076e27756b843e0cc063db3 100644 (file)
 @ CHECK: vselvs.f32 s21, s16, s14 @ encoding: [0x07,0xaa,0x58,0xfe]
   vselvs.f64 d0, d1, d31
 @ CHECK: vselvs.f64 d0, d1, d31   @ encoding: [0x2f,0x0b,0x11,0xfe]
+
+
+@ VMAXNM / VMINNM
+  vmaxnm.f32 s5, s12, s0
+@ CHECK: vmaxnm.f32 s5, s12, s0    @ encoding: [0x00,0x2a,0xc6,0xfe]
+  vmaxnm.f64 d5, d22, d30
+@ CHECK: vmaxnm.f64 d5, d22, d30   @ encoding: [0xae,0x5b,0x86,0xfe]
+  vminnm.f32 s0, s0, s12
+@ CHECK: vminnm.f32 s0, s0, s12    @ encoding: [0x46,0x0a,0x80,0xfe]
+  vminnm.f64 d4, d6, d9
+@ CHECK: vminnm.f64 d4, d6, d9     @ encoding: [0x49,0x4b,0x86,0xfe]
index a4a91c14959bd79139b3e1eff9373295ac9b9770..a805f817681e1ffdcd1785587e15672f74efdd77 100644 (file)
 
 0x2f 0x0b 0x11 0xfe
 # CHECK: vselvs.f64 d0, d1, d31
+
+
+0x00 0x2a 0xc6 0xfe
+# CHECK: vmaxnm.f32 s5, s12, s0
+
+0xae 0x5b 0x86 0xfe
+# CHECK: vmaxnm.f64 d5, d22, d30
+
+0x46 0x0a 0x80 0xfe
+# CHECK: vminnm.f32 s0, s0, s12
+
+0x49 0x4b 0x86 0xfe
+# CHECK: vminnm.f64 d4, d6, d9