summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-06-22 20:20:38 +0000
committerCraig Topper <craig.topper@intel.com>2018-06-22 20:20:38 +0000
commit9bc2c059c3796813995e662d4418e1abfa2f5d73 (patch)
treedceaa71aa2efedaae3838996ab90f1cc6bad04cf /llvm
parentc835306ac58b7a5d84a1f9b0aa7e415fc2d7fc76 (diff)
downloadbcm5719-llvm-9bc2c059c3796813995e662d4418e1abfa2f5d73.tar.gz
bcm5719-llvm-9bc2c059c3796813995e662d4418e1abfa2f5d73.zip
[X86] Don't accept (%si,%bp) 16-bit address expressions.
The second register is the index register and should only be %si or %di if used with a base register. And in that case the base register should be %bp or %bx. This makes us compatible with gas. We do still need to support both orders with Intel syntax which uses [bp+si] and [si+bp] llvm-svn: 335384
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp13
-rw-r--r--llvm/test/MC/X86/address-size.s2
-rw-r--r--llvm/test/MC/X86/intel-syntax-32.s6
-rw-r--r--llvm/test/MC/X86/intel-syntax.s1
-rw-r--r--llvm/test/MC/X86/x86_errors.s13
5 files changed, 29 insertions, 6 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index d72af591f05..6c39cac70cf 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -1021,10 +1021,8 @@ static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
ErrMsg = "base register is 16-bit, but index register is not";
return true;
}
- if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
- IndexReg != X86::SI && IndexReg != X86::DI) ||
- ((BaseReg == X86::SI || BaseReg == X86::DI) &&
- IndexReg != X86::BX && IndexReg != X86::BP)) {
+ if ((BaseReg != X86::BX && BaseReg != X86::BP) ||
+ (IndexReg != X86::SI && IndexReg != X86::DI)) {
ErrMsg = "invalid 16-bit base/index register combination";
return true;
}
@@ -1860,6 +1858,13 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
unsigned IndexReg = SM.getIndexReg();
unsigned Scale = SM.getScale();
+ // If this is a 16-bit addressing mode with the base and index in the wrong
+ // order, swap them so CheckBaseRegAndIndexRegAndScale doesn't fail. It is
+ // shared with att syntax where order matters.
+ if ((BaseReg == X86::SI || BaseReg == X86::DI) &&
+ (IndexReg == X86::BX || IndexReg == X86::BP))
+ std::swap(BaseReg, IndexReg);
+
if ((BaseReg || IndexReg) &&
CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
ErrMsg))
diff --git a/llvm/test/MC/X86/address-size.s b/llvm/test/MC/X86/address-size.s
index a7db10d7f48..205096b6a4f 100644
--- a/llvm/test/MC/X86/address-size.s
+++ b/llvm/test/MC/X86/address-size.s
@@ -23,8 +23,6 @@
// CHECK: encoding: [0xc6,0x04,0x00]
movb $0x0, (%esi)
// CHECK: encoding: [0x67,0xc6,0x06,0x00]
- movb $0x5a, (%di,%bp,1)
-// CHECK: encoding: [0xc6,0x03,0x5a]
movb $0x5a, (%bp,%di,1)
// CHECK: encoding: [0xc6,0x03,0x5a]
movb $0x5a, (%bp,%si,1)
diff --git a/llvm/test/MC/X86/intel-syntax-32.s b/llvm/test/MC/X86/intel-syntax-32.s
new file mode 100644
index 00000000000..a503a256ce2
--- /dev/null
+++ b/llvm/test/MC/X86/intel-syntax-32.s
@@ -0,0 +1,6 @@
+// RUN: llvm-mc -triple i686-unknown-unknown -x86-asm-syntax=intel %s | FileCheck %s
+
+// CHECK: leaw (%bp,%si), %ax
+lea ax, [bp+si]
+// CHECK: leaw (%bp,%si), %ax
+lea ax, [si+bp]
diff --git a/llvm/test/MC/X86/intel-syntax.s b/llvm/test/MC/X86/intel-syntax.s
index ee78e71f0fc..5fb28fb2eb3 100644
--- a/llvm/test/MC/X86/intel-syntax.s
+++ b/llvm/test/MC/X86/intel-syntax.s
@@ -888,3 +888,4 @@ sysexitq
sysret
// CHECK: sysretq
sysretq
+
diff --git a/llvm/test/MC/X86/x86_errors.s b/llvm/test/MC/X86/x86_errors.s
index 41cde0e0251..1abcfa5aaeb 100644
--- a/llvm/test/MC/X86/x86_errors.s
+++ b/llvm/test/MC/X86/x86_errors.s
@@ -89,3 +89,16 @@ leaq (%rax,%rsp), %rax
// 32: error: invalid base+index expression
// 64: error: invalid base+index expression
leaq (%eax,%esp), %eax
+
+// 32: error: invalid 16-bit base/index register combination
+// 64: error: invalid 16-bit base register
+lea (%si,%bp), %ax
+// 32: error: invalid 16-bit base/index register combination
+// 64: error: invalid 16-bit base register
+lea (%di,%bp), %ax
+// 32: error: invalid 16-bit base/index register combination
+// 64: error: invalid 16-bit base register
+lea (%si,%bx), %ax
+// 32: error: invalid 16-bit base/index register combination
+// 64: error: invalid 16-bit base register
+lea (%di,%bx), %ax
OpenPOWER on IntegriCloud