diff options
| author | Douglas Katzman <dougk@google.com> | 2016-10-05 15:23:35 +0000 |
|---|---|---|
| committer | Douglas Katzman <dougk@google.com> | 2016-10-05 15:23:35 +0000 |
| commit | 0411e8669b82233a645fd6dcdc813e989eef25c6 (patch) | |
| tree | 14e5c1c66046d46dcedde9b956bd49e751d95096 | |
| parent | 592024759e2f62057b4acb967a4063a0f95f006e (diff) | |
| download | bcm5719-llvm-0411e8669b82233a645fd6dcdc813e989eef25c6.tar.gz bcm5719-llvm-0411e8669b82233a645fd6dcdc813e989eef25c6.zip | |
[X86] Don't randomly encode %rip where illegal
Differential Revision: https://reviews.llvm.org/D25112
llvm-svn: 283326
| -rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 29 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.td | 2 | ||||
| -rw-r--r-- | llvm/test/MC/X86/intel-syntax-error.s | 5 | ||||
| -rw-r--r-- | llvm/test/MC/X86/x86_errors.s | 8 |
4 files changed, 40 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 87364b2a8ca..170f55cb1cd 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -840,6 +840,11 @@ static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg, // If we have both a base register and an index register make sure they are // both 64-bit or 32-bit registers. // To support VSIB, IndexReg can be 128-bit or 256-bit registers. + + if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP)) { + ErrMsg = "invalid base+index expression"; + return true; + } if (BaseReg != 0 && IndexReg != 0) { if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) && (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || @@ -1781,10 +1786,12 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() { !ParseRegister(RegNo, Start, End)) { // If this is a segment register followed by a ':', then this is the start // of a segment override, otherwise this is a normal register reference. - // In case it is a normal register and there is ptr in the operand this + // In case it is a normal register and there is ptr in the operand this // is an error - if (getLexer().isNot(AsmToken::Colon)){ - if (PtrInOperand){ + if (RegNo == X86::RIP) + return ErrorOperand(Start, "rip can only be used as a base register"); + if (getLexer().isNot(AsmToken::Colon)) { + if (PtrInOperand) { return ErrorOperand(Start, "expected memory operand after " "'ptr', found register operand instead"); } @@ -1865,6 +1872,11 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() { SMRange(Start, End)); return nullptr; } + if (RegNo == X86::RIP) { + Error(Start, "%rip can only be used as a base register", + SMRange(Start, End)); + return nullptr; + } // If this is a segment register followed by a ':', then this is the start // of a memory reference, otherwise this is a normal register reference. @@ -2044,7 +2056,16 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg, // like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this. if (getLexer().is(AsmToken::Percent)) { SMLoc L; - if (ParseRegister(IndexReg, L, L)) return nullptr; + if (ParseRegister(IndexReg, L, L)) + return nullptr; + if (BaseReg == X86::RIP) { + Error(IndexLoc, "%rip as base register can not have an index register"); + return nullptr; + } + if (IndexReg == X86::RIP) { + Error(IndexLoc, "%rip is not allowed as an index register"); + return nullptr; + } if (getLexer().isNot(AsmToken::RParen)) { // Parse the scale amount: diff --git a/llvm/lib/Target/X86/X86RegisterInfo.td b/llvm/lib/Target/X86/X86RegisterInfo.td index 373f9b4c65f..372a15aff15 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.td +++ b/llvm/lib/Target/X86/X86RegisterInfo.td @@ -345,6 +345,8 @@ def GR32 : RegisterClass<"X86", [i32], 32, // GR64 - 64-bit GPRs. This oddly includes RIP, which isn't accurate, since // RIP isn't really a register and it can't be used anywhere except in an // address, but it doesn't cause trouble. +// FIXME: it *does* cause trouble - CheckBaseRegAndIndexReg() has extra +// tests because of the inclusion of RIP in this register class. def GR64 : RegisterClass<"X86", [i64], 64, (add RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, RBX, R14, R15, R12, R13, RBP, RSP, RIP)>; diff --git a/llvm/test/MC/X86/intel-syntax-error.s b/llvm/test/MC/X86/intel-syntax-error.s index 637ba7e1c8f..eeb68a3b9f7 100644 --- a/llvm/test/MC/X86/intel-syntax-error.s +++ b/llvm/test/MC/X86/intel-syntax-error.s @@ -24,3 +24,8 @@ mov eax, DWORD PTR arr[ebp + 1 + (2 * 5) - 3 + 1<<1] mov eax, DWORD PTR arr[esi*4] //CHECK: error: cannot use more than one symbol in memory operand mov eax, DWORD PTR arr[i] +//CHECK: error: rip can only be used as a base register +.code64 +mov rax, rip +//CHECK: error: invalid base+index expression +mov rbx, [rax+rip] diff --git a/llvm/test/MC/X86/x86_errors.s b/llvm/test/MC/X86/x86_errors.s index f928fbc3801..ad8a8a7a23d 100644 --- a/llvm/test/MC/X86/x86_errors.s +++ b/llvm/test/MC/X86/x86_errors.s @@ -74,3 +74,11 @@ movl %edx, %cr8 // 32: error: register %dr8 is only available in 64-bit mode movl %edx, %dr8 + +// 32: error: register %rip is only available in 64-bit mode +// 64: error: %rip can only be used as a base register +mov %rip, %rax + +// 32: error: register %rax is only available in 64-bit mode +// 64: error: %rip is not allowed as an index register +mov (%rax,%rip), %rbx |

