Add MC assembly/disassembly support for VCVT{A, N, P, M} to V8FP.
authorJoey Gouly <joey.gouly@arm.com>
Tue, 9 Jul 2013 09:59:04 +0000 (09:59 +0000)
committerJoey Gouly <joey.gouly@arm.com>
Tue, 9 Jul 2013 09:59:04 +0000 (09:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185922 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 16b7bc5e404370ceec55634a2e05e98aab998f50..ed73d36338090f594ec03a7b50dcbf4c04872ff0 100644 (file)
@@ -1551,8 +1551,8 @@ 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, bit opcod3, dag oops, dag iops,
            InstrItinClass itin, string asm, list<dag> pattern>
-  : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
-          VFPBinaryFrm, itin, asm, "", pattern>
+  : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone, VFPBinaryFrm, itin,
+          asm, "", pattern>
 {
   // Instruction operands.
   bits<5> Dd;
@@ -1577,7 +1577,7 @@ class ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
   let Inst{4}     = 0;
 }
 
-// Single precision, unary
+// Single precision, unary, predicated
 class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
            bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
            string asm, list<dag> pattern>
@@ -1601,6 +1601,33 @@ class ASuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
   let Inst{4}     = opcod5;
 }
 
+// Single precision, unary, non-predicated
+class ASuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
+             bit opcod5, dag oops, dag iops, InstrItinClass itin,
+             string asm, list<dag> pattern>
+  : VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
+          VFPUnaryFrm, itin, asm, "", pattern> {
+  // Instruction operands.
+  bits<5> Sd;
+  bits<5> Sm;
+
+  let Inst{31-28} = 0b1111;
+
+  // Encode instruction operands.
+  let Inst{3-0}   = Sm{4-1};
+  let Inst{5}     = Sm{0};
+  let Inst{15-12} = Sd{4-1};
+  let Inst{22}    = Sd{0};
+
+  let Inst{27-23} = opcod1;
+  let Inst{21-20} = opcod2;
+  let Inst{19-16} = opcod3;
+  let Inst{11-9}  = 0b101;
+  let Inst{8}     = 0;          // Single precision
+  let Inst{7-6}   = opcod4;
+  let Inst{4}     = opcod5;
+}
+
 // Single precision unary, if no NEON. Same as ASuI except not available if
 // NEON is enabled.
 class ASuIn<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
index 27e2df4bfd4e9bbde99373cd4f9840a12c5e3194..27f1578b5eacdf8f9c4bbb6c7afbddc4545913d0 100644 (file)
@@ -583,6 +583,57 @@ def VCVTTDH : ADuI<0b11101, 0b11, 0b0011, 0b11, 0,
   let Inst{5}     = Dm{4};
 }
 
+multiclass vcvt_inst<string opc, bits<2> rm> {
+  let PostEncoderMethod = "" in {
+    def SS : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0,
+                    (outs SPR:$Sd), (ins SPR:$Sm),
+                    NoItinerary, !strconcat("vcvt", opc, ".s32.f32\t$Sd, $Sm"),
+                    []>, Requires<[HasV8FP]> {
+      let Inst{17-16} = rm;
+    }
+
+    def US : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0,
+                    (outs SPR:$Sd), (ins SPR:$Sm),
+                    NoItinerary, !strconcat("vcvt", opc, ".u32.f32\t$Sd, $Sm"),
+                    []>, Requires<[HasV8FP]> {
+      let Inst{17-16} = rm;
+    }
+
+    def SD : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0,
+                    (outs SPR:$Sd), (ins DPR:$Dm),
+                    NoItinerary, !strconcat("vcvt", opc, ".s32.f64\t$Sd, $Dm"),
+                    []>, Requires<[HasV8FP]> {
+      bits<5> Dm;
+
+      let Inst{17-16} = rm;
+
+      // Encode instruction operands
+      let Inst{3-0} = Dm{3-0};
+      let Inst{5}   = Dm{4};
+      let Inst{8} = 1;
+    }
+
+    def UD : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0,
+                    (outs SPR:$Sd), (ins DPR:$Dm),
+                    NoItinerary, !strconcat("vcvt", opc, ".u32.f64\t$Sd, $Dm"),
+                    []>, Requires<[HasV8FP]> {
+      bits<5> Dm;
+
+      let Inst{17-16} = rm;
+
+      // Encode instruction operands
+      let Inst{3-0}  = Dm{3-0};
+      let Inst{5}    = Dm{4};
+      let Inst{8} = 1;
+    }
+  }
+}
+
+defm VCVTA : vcvt_inst<"a", 0b00>;
+defm VCVTN : vcvt_inst<"n", 0b01>;
+defm VCVTP : vcvt_inst<"p", 0b10>;
+defm VCVTM : vcvt_inst<"m", 0b11>;
+
 def VNEGD  : ADuI<0b11101, 0b11, 0b0001, 0b01, 0,
                   (outs DPR:$Dd), (ins DPR:$Dm),
                   IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm",
index f7f19014895ffb02b6b3cdff21e6e68a995b94e2..56557e3736c199a94db2592bbc29d1257c2f7e9d 100644 (file)
@@ -4906,7 +4906,8 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
       Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
       Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
       Mnemonic == "fmuls" || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" ||
-      Mnemonic.startswith("vsel"))
+      Mnemonic == "vcvta" || Mnemonic == "vcvtn" || Mnemonic == "vcvtp" ||
+      Mnemonic == "vcvtm" || Mnemonic.startswith("vsel"))
     return Mnemonic;
 
   // First, split out any predication code. Ignore mnemonics we know aren't
@@ -5006,8 +5007,9 @@ 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 == "vmaxnm" ||
-                       Mnemonic == "vminnm" || Mnemonic.startswith("vsel")) {
+      Mnemonic.startswith("cps") || Mnemonic.startswith("vsel") ||
+      Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" ||
+      Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm") {
     // These mnemonics are never predicable
     CanAcceptPredicationCode = false;
   } else if (!isThumb()) {
index 05a7f1badde5d9b73076e27756b843e0cc063db3..36cec8b98743daad1e8d365ce6ae1e2cdbb30867 100644 (file)
   vcvtblt.f16.f64 s4, d1
 @ CHECK: vcvtblt.f16.f64 s4, d1     @ encoding: [0x41,0x2b,0xb3,0xbe]
 
+
+@ VCVT{A,N,P,M}
+
+  vcvta.s32.f32 s2, s3
+@ CHECK: vcvta.s32.f32 s2, s3     @ encoding: [0xe1,0x1a,0xbc,0xfe]
+  vcvta.s32.f64 s2, d3
+@ CHECK: vcvta.s32.f64 s2, d3     @ encoding: [0xc3,0x1b,0xbc,0xfe]
+  vcvtn.s32.f32 s6, s23
+@ CHECK: vcvtn.s32.f32 s6, s23     @ encoding: [0xeb,0x3a,0xbd,0xfe]
+  vcvtn.s32.f64 s6, d23
+@ CHECK: vcvtn.s32.f64 s6, d23     @ encoding: [0xe7,0x3b,0xbd,0xfe]
+  vcvtp.s32.f32 s0, s4
+@ CHECK: vcvtp.s32.f32 s0, s4     @ encoding: [0xc2,0x0a,0xbe,0xfe]
+  vcvtp.s32.f64 s0, d4
+@ CHECK: vcvtp.s32.f64 s0, d4     @ encoding: [0xc4,0x0b,0xbe,0xfe]
+  vcvtm.s32.f32 s17, s8
+@ CHECK: vcvtm.s32.f32 s17, s8     @ encoding: [0xc4,0x8a,0xff,0xfe]
+  vcvtm.s32.f64 s17, d8
+@ CHECK: vcvtm.s32.f64 s17, d8     @ encoding: [0xc8,0x8b,0xff,0xfe]
+
+  vcvta.u32.f32 s2, s3
+@ CHECK: vcvta.u32.f32 s2, s3     @ encoding: [0x61,0x1a,0xbc,0xfe]
+  vcvta.u32.f64 s2, d3
+@ CHECK: vcvta.u32.f64 s2, d3     @ encoding: [0x43,0x1b,0xbc,0xfe]
+  vcvtn.u32.f32 s6, s23
+@ CHECK: vcvtn.u32.f32 s6, s23     @ encoding: [0x6b,0x3a,0xbd,0xfe]
+  vcvtn.u32.f64 s6, d23
+@ CHECK: vcvtn.u32.f64 s6, d23     @ encoding: [0x67,0x3b,0xbd,0xfe]
+  vcvtp.u32.f32 s0, s4
+@ CHECK: vcvtp.u32.f32 s0, s4     @ encoding: [0x42,0x0a,0xbe,0xfe]
+  vcvtp.u32.f64 s0, d4
+@ CHECK: vcvtp.u32.f64 s0, d4     @ encoding: [0x44,0x0b,0xbe,0xfe]
+  vcvtm.u32.f32 s17, s8
+@ CHECK: vcvtm.u32.f32 s17, s8     @ encoding: [0x44,0x8a,0xff,0xfe]
+  vcvtm.u32.f64 s17, d8
+@ CHECK: vcvtm.u32.f64 s17, d8     @ encoding: [0x48,0x8b,0xff,0xfe]
+
+
 @ VSEL
   vselge.f32 s4, s1, s23
 @ CHECK: vselge.f32 s4, s1, s23    @ encoding: [0xab,0x2a,0x20,0xfe]
index a805f817681e1ffdcd1785587e15672f74efdd77..9c9d47058a7787c094832e1520222b845b16d8c6 100644 (file)
 # CHECK: vcvtblt.f16.f64 s4, d1
 
 
+0xe1 0x1a 0xbc 0xfe
+# CHECK: vcvta.s32.f32 s2, s3
+
+0xc3 0x1b 0xbc 0xfe
+# CHECK: vcvta.s32.f64 s2, d3
+
+0xeb 0x3a 0xbd 0xfe
+# CHECK: vcvtn.s32.f32 s6, s23
+
+0xe7 0x3b 0xbd 0xfe
+# CHECK: vcvtn.s32.f64 s6, d23
+
+0xc2 0x0a 0xbe 0xfe
+# CHECK: vcvtp.s32.f32 s0, s4
+
+0xc4 0x0b 0xbe 0xfe
+# CHECK: vcvtp.s32.f64 s0, d4
+
+0xc4 0x8a 0xff 0xfe
+# CHECK: vcvtm.s32.f32 s17, s8
+
+0xc8 0x8b 0xff 0xfe
+# CHECK: vcvtm.s32.f64 s17, d8
+
+0x61 0x1a 0xbc 0xfe
+# CHECK: vcvta.u32.f32 s2, s3
+
+0x43 0x1b 0xbc 0xfe
+# CHECK: vcvta.u32.f64 s2, d3
+
+0x6b 0x3a 0xbd 0xfe
+# CHECK: vcvtn.u32.f32 s6, s23
+
+0x67 0x3b 0xbd 0xfe
+# CHECK: vcvtn.u32.f64 s6, d23
+
+0x42 0x0a 0xbe 0xfe
+# CHECK: vcvtp.u32.f32 s0, s4
+
+0x44 0x0b 0xbe 0xfe
+# CHECK: vcvtp.u32.f64 s0, d4
+
+0x44 0x8a 0xff 0xfe
+# CHECK: vcvtm.u32.f32 s17, s8
+
+0x48 0x8b 0xff 0xfe
+# CHECK: vcvtm.u32.f64 s17, d8
+
+
 0xab 0x2a 0x20 0xfe
 # CHECK: vselge.f32 s4, s1, s23