[llvm] r265936 - [ARM] Avoid switching ARM/Thumb mode on .arch/.cpu directive

Oliver Stannard via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 11 06:06:29 PDT 2016


Author: olista01
Date: Mon Apr 11 08:06:28 2016
New Revision: 265936

URL: http://llvm.org/viewvc/llvm-project?rev=265936&view=rev
Log:
[ARM] Avoid switching ARM/Thumb mode on .arch/.cpu directive

When we see a .arch or .cpu directive, we should try to avoid switching
ARM/Thumb mode if possible.

If we do have to switch modes, we also need to emit the correct mapping
symbol for the new ISA. We did not do this previously, so could emit
ARM code with Thumb mapping symbols (or vice-versa).

The GAS behaviour is to always stay in the same mode, and to emit an
error on any instructions seen when the current mode is not available on
the current target. We can't represent that situation easily (we assume
that Thumb mode is available if ModeThumb is set), so we differ from the
GAS behaviour when switching to a target that can't support the old
mode. I've added a warning for when this implicit mode-switch occurs.

Differential Revision: http://reviews.llvm.org/D18955


Added:
    llvm/trunk/test/MC/ARM/directive-arch-mode-switch.s
Modified:
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

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=265936&r1=265935&r2=265936&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Mon Apr 11 08:06:28 2016
@@ -296,6 +296,7 @@ class ARMAsmParser : public MCTargetAsmP
     uint64_t FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
     setAvailableFeatures(FB);
   }
+  void FixModeAfterArchChange(bool WasThumb, SMLoc Loc);
   bool isMClass() const {
     return getSTI().getFeatureBits()[ARM::FeatureMClass];
   }
@@ -9099,6 +9100,31 @@ bool ARMAsmParser::parseDirectiveUnreq(S
   return false;
 }
 
+// After changing arch/CPU, try to put the ARM/Thumb mode back to what it was
+// before, if supported by the new target, or emit mapping symbols for the mode
+// switch.
+void ARMAsmParser::FixModeAfterArchChange(bool WasThumb, SMLoc Loc) {
+  if (WasThumb != isThumb()) {
+    if (WasThumb && hasThumb()) {
+      // Stay in Thumb mode
+      SwitchMode();
+    } else if (!WasThumb && hasARM()) {
+      // Stay in ARM mode
+      SwitchMode();
+    } else {
+      // Mode switch forced, because the new arch doesn't support the old mode.
+      getParser().getStreamer().EmitAssemblerFlag(isThumb() ? MCAF_Code16
+                                                            : MCAF_Code32);
+      // Warn about the implcit mode switch. GAS does not switch modes here,
+      // but instead stays in the old mode, reporting an error on any following
+      // instructions as the mode does not exist on the target.
+      Warning(Loc, Twine("new target does not support ") +
+                       (WasThumb ? "thumb" : "arm") + " mode, switching to " +
+                       (!WasThumb ? "thumb" : "arm") + " mode");
+    }
+  }
+}
+
 /// parseDirectiveArch
 ///  ::= .arch token
 bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
@@ -9111,10 +9137,12 @@ bool ARMAsmParser::parseDirectiveArch(SM
     return false;
   }
 
+  bool WasThumb = isThumb();
   Triple T;
   MCSubtargetInfo &STI = copySTI();
   STI.setDefaultFeatures("", ("+" + ARM::getArchName(ID)).str());
   setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
+  FixModeAfterArchChange(WasThumb, L);
 
   getTargetStreamer().emitArch(ID);
   return false;
@@ -9245,9 +9273,11 @@ bool ARMAsmParser::parseDirectiveCPU(SML
     return false;
   }
 
+  bool WasThumb = isThumb();
   MCSubtargetInfo &STI = copySTI();
   STI.setDefaultFeatures(CPU, "");
   setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
+  FixModeAfterArchChange(WasThumb, L);
 
   return false;
 }

Added: llvm/trunk/test/MC/ARM/directive-arch-mode-switch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/directive-arch-mode-switch.s?rev=265936&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/directive-arch-mode-switch.s (added)
+++ llvm/trunk/test/MC/ARM/directive-arch-mode-switch.s Mon Apr 11 08:06:28 2016
@@ -0,0 +1,52 @@
+@ RUN: llvm-mc -triple arm-none-eabi -filetype asm %s 2>%t | FileCheck %s
+@ RUN: FileCheck %s <%t --check-prefix=STDERR
+
+@ Start in arm mode
+  .arm
+@ CHECK: .code 32
+
+@ In ARM mode, switch to an arch which has ARM and Thumb, no warning or .code directive (stay in ARM mode)
+  .arch armv7-a
+@ STDERR-NOT: [[@LINE-1]]:{{[0-9]+}}: warning:
+@ CHECK-NOT: .code
+@ CHECK: .arch   armv7-a
+@ CHECK-NOT: .code
+
+@ In ARM mode, switch to an arch which has Thumb only, expect warning and .code 16 directive
+  .arch armv6-m
+@ STDERR: [[@LINE-1]]:{{[0-9]+}}: warning: new target does not support arm mode, switching to thumb mode
+@ CHECK: .code   16
+@ CHECK: .arch   armv6-m
+
+@ In Thumb mode, switch to an arch which has ARM and Thumb, no warning or .code directive (stay in Thumb mode)
+  .arch armv7-a
+@ STDERR-NOT: [[@LINE-1]]:{{[0-9]+}}: warning:
+@ CHECK-NOT: .code
+@ CHECK: .arch   armv7-a
+@ CHECK-NOT: .code
+
+@ In Thumb mode, switch to a CPU which has ARM and Thumb, no warning or .code directive (stay in Thumb mode)
+  .cpu cortex-a8
+@ STDERR-NOT: [[@LINE-1]]:{{[0-9]+}}: warning:
+@ CHECK-NOT: .code
+@ CHECK: .cpu cortex-a8
+@ CHECK-NOT: .code
+
+@ Switch to ARM mode
+  .arm
+@ CHECK: .code 32
+
+@ In ARM mode, switch to a CPU which has ARM and Thumb, no warning or .code directive (stay in ARM mode)
+  .cpu cortex-a8
+@ STDERR-NOT: [[@LINE-1]]:{{[0-9]+}}: warning:
+@ CHECK-NOT: .code
+@ CHECK: .cpu cortex-a8
+@ CHECK-NOT: .code
+
+@ In ARM mode, switch to a CPU which has Thumb only, expect warning and .code 16 directive
+  .cpu cortex-m3
+@ STDERR: [[@LINE-1]]:{{[0-9]+}}: warning: new target does not support arm mode, switching to thumb mode
+@ CHECK: .cpu    cortex-m3
+@ CHECK: .code   16
+
+@ We don't have any ARM-only targets (i.e. v4), so we can't test the forced Thumb->ARM case




More information about the llvm-commits mailing list