[llvm] r221341 - [ARM] Honor FeatureD16 in the assembler and disassembler

Oliver Stannard oliver.stannard at arm.com
Wed Nov 5 04:06:40 PST 2014


Author: olista01
Date: Wed Nov  5 06:06:39 2014
New Revision: 221341

URL: http://llvm.org/viewvc/llvm-project?rev=221341&view=rev
Log:
[ARM] Honor FeatureD16 in the assembler and disassembler

Some ARM FPUs only have 16 double-precision registers, rather than the
normal 32. LLVM represents this with the D16 target feature. This is
currently used by CodeGen to avoid using high registers when they are
not available, but the assembler and disassembler do not.

I fix this in the assmebler and disassembler rather than the
InstrInfo.td files, as the latter would require a large number of
changes everywhere one of the floating-point instructions is referenced
in the backend. This solution is similar to the one used for
co-processor numbers and MSR masks.


Added:
    llvm/trunk/test/MC/ARM/d16.s
    llvm/trunk/test/MC/Disassembler/ARM/d16.txt
Modified:
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
    llvm/trunk/test/MC/ARM/directive-fpu-instrs.s
    llvm/trunk/test/MC/ARM/vfp4.s

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=221341&r1=221340&r2=221341&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Wed Nov  5 06:06:39 2014
@@ -270,6 +270,9 @@ class ARMAsmParser : public MCTargetAsmP
   bool hasThumb2DSP() const {
     return STI.getFeatureBits() & ARM::FeatureDSPThumb2;
   }
+  bool hasD16() const {
+    return STI.getFeatureBits() & ARM::FeatureD16;
+  }
 
   void SwitchMode() {
     uint64_t FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
@@ -2988,6 +2991,10 @@ int ARMAsmParser::tryParseRegister() {
     return Entry->getValue();
   }
 
+  // Some FPUs only have 16 D registers, so D16-D31 are invalid
+  if (hasD16() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
+    return -1;
+
   Parser.Lex(); // Eat identifier token.
 
   return RegNum;

Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=221341&r1=221340&r2=221341&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Wed Nov  5 06:06:39 2014
@@ -1017,7 +1017,11 @@ static const uint16_t DPRDecoderTable[]
 
 static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
                                    uint64_t Address, const void *Decoder) {
-  if (RegNo > 31)
+  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
+                                                          .getFeatureBits();
+  bool hasD16 = featureBits & ARM::FeatureD16;
+
+  if (RegNo > 31 || (hasD16 && RegNo > 15))
     return MCDisassembler::Fail;
 
   unsigned Register = DPRDecoderTable[RegNo];

Added: llvm/trunk/test/MC/ARM/d16.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/d16.s?rev=221341&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/d16.s (added)
+++ llvm/trunk/test/MC/ARM/d16.s Wed Nov  5 06:06:39 2014
@@ -0,0 +1,24 @@
+@ RUN:     llvm-mc < %s -triple thumbv7-unknown-unknown -show-encoding -mattr=+vfp4,-d16 |& FileCheck %s --check-prefix=D32
+@ RUN: not llvm-mc < %s -triple thumbv7-unknown-unknown -show-encoding -mattr=+vfp4,+d16 |& FileCheck %s --check-prefix=D16
+
+@ D32-NOT: error:
+
+@ D16: invalid operand for instruction
+@ D16-NEXT: vadd.f64 d1, d2, d16
+vadd.f64 d1, d2, d16
+
+@ D16: invalid operand for instruction
+@ D16-NEXT: vadd.f64 d1, d17, d6
+vadd.f64 d1, d17, d6
+
+@ D16: invalid operand for instruction
+@ D16-NEXT: vadd.f64 d19, d7, d6
+vadd.f64 d19, d7, d6
+
+@ D16: invalid operand for instruction
+@ D16-NEXT: vcvt.f64.f32 d22, s4
+vcvt.f64.f32 d22, s4
+
+@ D16: invalid operand for instruction
+@ D16-NEXT: vcvt.f32.f64 s26, d30
+vcvt.f32.f64 s26, d30

Modified: llvm/trunk/test/MC/ARM/directive-fpu-instrs.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/directive-fpu-instrs.s?rev=221341&r1=221340&r2=221341&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/directive-fpu-instrs.s (original)
+++ llvm/trunk/test/MC/ARM/directive-fpu-instrs.s Wed Nov  5 06:06:39 2014
@@ -1,4 +1,4 @@
-// RUN: llvm-mc -triple armv7-unknown-linux-gnueabi -mattr=+vfp3,+d16,-neon %s
+// RUN: llvm-mc -triple armv7-unknown-linux-gnueabi -mattr=+vfp3,-neon %s
 
 .fpu neon
 VAND d3, d5, d5

Modified: llvm/trunk/test/MC/ARM/vfp4.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/vfp4.s?rev=221341&r1=221340&r2=221341&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/vfp4.s (original)
+++ llvm/trunk/test/MC/ARM/vfp4.s Wed Nov  5 06:06:39 2014
@@ -6,7 +6,7 @@
 
 @ ARM: vfma.f64 d16, d18, d17 @ encoding: [0xa1,0x0b,0xe2,0xee]
 @ THUMB: vfma.f64 d16, d18, d17 @ encoding: [0xe2,0xee,0xa1,0x0b]
-@ THUMB_V7EM-ERRORS: error: instruction requires: double precision VFP
+@ THUMB_V7EM-ERRORS: error: invalid operand for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfma.f64 d16, d18, d17
 vfma.f64 d16, d18, d17
 
@@ -17,7 +17,7 @@ vfma.f32 s2, s4, s0
 
 @ ARM: vfma.f32 d16, d18, d17 @ encoding: [0xb1,0x0c,0x42,0xf2]
 @ THUMB: vfma.f32 d16, d18, d17 @ encoding: [0x42,0xef,0xb1,0x0c]
-@ THUMB_V7EM-ERRORS: error: instruction requires: NEON
+@ THUMB_V7EM-ERRORS: error: invalid operand for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfma.f32 d16, d18, d17
 vfma.f32 d16, d18, d17
 
@@ -29,7 +29,7 @@ vfma.f32 q2, q4, q0
 
 @ ARM: vfnma.f64 d16, d18, d17 @ encoding: [0xe1,0x0b,0xd2,0xee]
 @ THUMB: vfnma.f64 d16, d18, d17 @ encoding: [0xd2,0xee,0xe1,0x0b]
-@ THUMB_V7EM-ERRORS: error: instruction requires: double precision VFP
+@ THUMB_V7EM-ERRORS: error: invalid operand for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfnma.f64 d16, d18, d17
 vfnma.f64 d16, d18, d17
 
@@ -40,7 +40,7 @@ vfnma.f32 s2, s4, s0
 
 @ ARM: vfms.f64 d16, d18, d17 @ encoding: [0xe1,0x0b,0xe2,0xee]
 @ THUMB: vfms.f64 d16, d18, d17 @ encoding: [0xe2,0xee,0xe1,0x0b]
-@ THUMB_V7EM-ERRORS: error: instruction requires: double precision VFP
+@ THUMB_V7EM-ERRORS: error: invalid operand for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfms.f64 d16, d18, d17
 vfms.f64 d16, d18, d17
 
@@ -51,7 +51,7 @@ vfms.f32 s2, s4, s0
 
 @ ARM: vfms.f32 d16, d18, d17 @ encoding: [0xb1,0x0c,0x62,0xf2]
 @ THUMB: vfms.f32 d16, d18, d17 @ encoding: [0x62,0xef,0xb1,0x0c]
-@ THUMB_V7EM-ERRORS: error: instruction requires: NEON
+@ THUMB_V7EM-ERRORS: error: invalid operand for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfms.f32 d16, d18, d17
 vfms.f32 d16, d18, d17
 
@@ -63,7 +63,7 @@ vfms.f32 q2, q4, q0
 
 @ ARM: vfnms.f64 d16, d18, d17 @ encoding: [0xa1,0x0b,0xd2,0xee]
 @ THUMB: vfnms.f64 d16, d18, d17 @ encoding: [0xd2,0xee,0xa1,0x0b]
-@ THUMB_V7EM-ERRORS: error: instruction requires: double precision VFP
+@ THUMB_V7EM-ERRORS: error: invalid operand for instruction
 @ THUMB_V7EM-ERRORS-NEXT: vfnms.f64 d16, d18, d17
 vfnms.f64 d16, d18, d17
 

Added: llvm/trunk/test/MC/Disassembler/ARM/d16.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/d16.txt?rev=221341&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARM/d16.txt (added)
+++ llvm/trunk/test/MC/Disassembler/ARM/d16.txt Wed Nov  5 06:06:39 2014
@@ -0,0 +1,23 @@
+# RUN: llvm-mc < %s -triple thumbv7-unknown-unknown -disassemble -mattr=+vfp4,-d16 |& FileCheck %s --check-prefix=D32
+# RUN: llvm-mc < %s -triple thumbv7-unknown-unknown -disassemble -mattr=+vfp4,-d16 |& FileCheck %s --check-prefix=D32
+
+
+# D32: vadd.f64 d1, d2, d16
+# D16: warning: invalid instruction encoding
+[0x32,0xee,0x20,0x1b]
+
+# D32: vadd.f64 d1, d17, d6
+# D16: warning: invalid instruction encoding
+[0x31,0xee,0x86,0x1b]
+
+# D32: vadd.f64 d19, d7, d6
+# D16: warning: invalid instruction encoding
+[0x77,0xee,0x06,0x3b]
+
+# D32: vcvt.f64.f32 d22, s4
+# D16: warning: invalid instruction encoding
+[0xf7,0xee,0xc2,0x6a]
+
+# D32: vcvt.f32.f64 s26, d30
+# D16: warning: invalid instruction encoding
+[0xb7,0xee,0xee,0xdb]





More information about the llvm-commits mailing list