OSDN Git Service

[Hexagon] Improving error reporting for writing to read only registers
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Mon, 1 May 2017 20:10:41 +0000 (20:10 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Mon, 1 May 2017 20:10:41 +0000 (20:10 +0000)
Patch by Colin LeMahieu.

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

lib/Target/Hexagon/HexagonRegisterInfo.td
lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
test/MC/Hexagon/PacketRules/registers_readonly.s [new file with mode: 0644]
test/MC/Hexagon/registers_readonly.s [new file with mode: 0644]
test/MC/Hexagon/ro-c9.s [new file with mode: 0644]
test/MC/Hexagon/ro-cc9.s [new file with mode: 0644]

index 93ab2f7..2519b7c 100644 (file)
@@ -157,7 +157,7 @@ let Namespace = "Hexagon" in {
   // and isub_lo can be composed, which leads to all kinds of issues
   // with lane masks.
   def C8:         Rc<8,  "c8",         [], [USR]>, DwarfRegNum<[75]>;
-  def PC:         Rc<9,  "pc">,                    DwarfRegNum<[76]>;
+  def PC:         Rc<9,  "pc",         ["c9"]>,    DwarfRegNum<[76]>;
   def UGP:        Rc<10, "ugp",        ["c10"]>,   DwarfRegNum<[77]>;
   def GP:         Rc<11, "gp",         ["c11"]>,   DwarfRegNum<[78]>;
   def CS0:        Rc<12, "cs0",        ["c12"]>,   DwarfRegNum<[79]>;
index 36e0aee..88172b8 100644 (file)
@@ -36,6 +36,7 @@ const HexagonMCChecker::PredSense
 void HexagonMCChecker::init() {
   // Initialize read-only registers set.
   ReadOnly.insert(Hexagon::PC);
+  ReadOnly.insert(Hexagon::C9_8);
 
   // Figure out the loop-registers definitions.
   if (HexagonMCInstrInfo::isInnerLoop(MCB)) {
@@ -250,6 +251,7 @@ bool HexagonMCChecker::check(bool FullCheck) {
   bool chkP = checkPredicates();
   bool chkNV = checkNewValues();
   bool chkR = checkRegisters();
+  bool chkRRO = checkRegistersReadOnly();
   bool chkS = checkSolo();
   bool chkSh = true;
   if (FullCheck)
@@ -257,7 +259,7 @@ bool HexagonMCChecker::check(bool FullCheck) {
   bool chkSl = true;
   if (FullCheck)
     chkSl = checkSlots();
-  bool chk = chkB && chkP && chkNV && chkR && chkS && chkSh && chkSl;
+  bool chk = chkB && chkP && chkNV && chkR && chkRRO && chkS && chkSh && chkSl;
 
   return chk;
 }
@@ -376,18 +378,30 @@ bool HexagonMCChecker::checkNewValues() {
   return true;
 }
 
+bool HexagonMCChecker::checkRegistersReadOnly() {
+  for (auto I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
+    MCInst const &Inst = *I.getInst();
+    unsigned Defs = HexagonMCInstrInfo::getDesc(MCII, Inst).getNumDefs();
+    for (unsigned j = 0; j < Defs; ++j) {
+      MCOperand const &Operand = Inst.getOperand(j);
+      assert(Operand.isReg() && "Def is not a register");
+      unsigned Register = Operand.getReg();
+      if (ReadOnly.find(Register) != ReadOnly.end()) {
+        reportError(Inst.getLoc(), "Cannot write to read-only register `" +
+                                       llvm::Twine(RI.getName(Register)) + "'");
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
 // Check for legal register uses and definitions.
 bool HexagonMCChecker::checkRegisters() {
   // Check for proper register definitions.
   for (const auto &I : Defs) {
     unsigned R = I.first;
 
-    if (ReadOnly.count(R)) {
-      // Error out for definitions of read-only registers.
-      reportError("cannot write to read-only register `" +
-                  llvm::Twine(RI.getName(R)) + "'");
-      return false;
-    }
     if (isLoopRegister(R) && Defs.count(R) > 1 &&
         (HexagonMCInstrInfo::isInnerLoop(MCB) ||
          HexagonMCInstrInfo::isOuterLoop(MCB))) {
index 69c0ef2..d023869 100644 (file)
@@ -115,6 +115,7 @@ class HexagonMCChecker {
   bool checkPredicates();
   bool checkNewValues();
   bool checkRegisters();
+  bool checkRegistersReadOnly();
   bool checkSolo();
   bool checkShuffle();
   bool checkSlots();
diff --git a/test/MC/Hexagon/PacketRules/registers_readonly.s b/test/MC/Hexagon/PacketRules/registers_readonly.s
new file mode 100644 (file)
index 0000000..ec11858
--- /dev/null
@@ -0,0 +1,5 @@
+# RUN: not llvm-mc -arch=hexagon -filetype=obj %s 2>&1 | FileCheck %s
+
+# CHECK: 4:3: error: Cannot write to read-only register `PC'
+{ pc = r0
+  r0 = r0 }
diff --git a/test/MC/Hexagon/registers_readonly.s b/test/MC/Hexagon/registers_readonly.s
new file mode 100644 (file)
index 0000000..cf109fe
--- /dev/null
@@ -0,0 +1,7 @@
+# RUN: not llvm-mc -arch=hexagon -filetype=obj -mv5 %s 2>&1 | FileCheck %s
+
+# CHECK: 4:1: error: Cannot write to read-only register `PC'
+pc = r0
+
+# CHECK: 7:1: error: Cannot write to read-only register `PC'
+c9 = r0
diff --git a/test/MC/Hexagon/ro-c9.s b/test/MC/Hexagon/ro-c9.s
new file mode 100644 (file)
index 0000000..6771430
--- /dev/null
@@ -0,0 +1,6 @@
+# RUN: llvm-mc -arch=hexagon -filetype=asm %s 2> %t; FileCheck %s < %t
+
+# Check that changes to a read-only register is caught.
+
+       { pc = r0 }
+# CHECK: error: Cannot write to read-only register
diff --git a/test/MC/Hexagon/ro-cc9.s b/test/MC/Hexagon/ro-cc9.s
new file mode 100644 (file)
index 0000000..0596ca1
--- /dev/null
@@ -0,0 +1,7 @@
+# RUN: not llvm-mc -arch=hexagon -filetype=asm %s 2> %t; FileCheck %s < %t
+#
+
+# Check that changes to a read-only register is caught.
+
+{ c9:8 = r1:0 }
+# CHECK: error: Cannot write to read-only register