1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

[Hexagon] Improving error reporting for writing to read only registers

Patch by Colin LeMahieu.

llvm-svn: 301828
This commit is contained in:
Krzysztof Parzyszek 2017-05-01 20:10:41 +00:00
parent 5213039bde
commit f44562707e
7 changed files with 48 additions and 8 deletions

View 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]>;

View 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))) {

View File

@ -115,6 +115,7 @@ class HexagonMCChecker {
bool checkPredicates();
bool checkNewValues();
bool checkRegisters();
bool checkRegistersReadOnly();
bool checkSolo();
bool checkShuffle();
bool checkSlots();

View File

@ -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 }

View File

@ -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

6
test/MC/Hexagon/ro-c9.s Normal file
View File

@ -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

7
test/MC/Hexagon/ro-cc9.s Normal file
View File

@ -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