Subzero: Work around another llvm-mc parser bug for relocatable symbols.
There's already a hack that emits asm like:
lea eax, myglobal
instead of:
mov eax, [myglobal]
because of an llvm-mc parser bug. However, the lea hack still doesn't work if the symbol is a reserved word, e.g.:
lea eax, flags
The extra hack is to drop into AT&T syntax temporarily:
.att_syntax
leal flags, %eax
.intel_syntax
BUG= none
R=jvoung@chromium.org
Review URL: https://codereview.chromium.org/543803002
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index a1a4d68..1454778 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -968,16 +968,22 @@
// The llvm-mc assembler using Intel syntax has a bug in which "mov
// reg, RelocatableConstant" does not generate the right instruction
// with a relocation. To work around, we emit "lea reg,
- // [RelocatableConstant]". Also, the lowering and legalization is
+ // RelocatableConstant". Also, the lowering and legalization is
// changed to allow relocatable constants only in Assign and Call
// instructions or in Mem operands. TODO(stichnot): remove LEAHACK
// once a proper emitter is used.
+ //
+ // In addition, llvm-mc doesn't like "lea eax, bp" or "lea eax, Sp"
+ // or "lea eax, flags" etc., when the relocatable constant name is a
+ // reserved word. The hack-on-top-of-hack is to temporarily drop
+ // into AT&T syntax for this lea instruction.
bool UseLeaHack = llvm::isa<ConstantRelocatable>(Src);
- Str << "\t";
- if (UseLeaHack)
- Str << "lea";
- else
- Str << "mov" << TypeX8632Attributes[getDest()->getType()].SdSsString;
+ if (UseLeaHack) {
+ Str << ".att_syntax\n";
+ Str << "\tleal";
+ } else {
+ Str << "\tmov" << TypeX8632Attributes[getDest()->getType()].SdSsString;
+ }
Str << "\t";
// For an integer truncation operation, src is wider than dest.
// Ideally, we use a mov instruction whose data width matches the
@@ -991,10 +997,18 @@
// Clean this up.
assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) ==
Func->getTarget()->typeWidthInBytesOnStack(Src->getType()));
- getDest()->asType(Src->getType()).emit(Func);
- Str << ", ";
- Src->emit(Func);
- Str << "\n";
+ if (UseLeaHack) {
+ Src->emit(Func);
+ Str << ", %";
+ getDest()->emit(Func);
+ Str << "\n";
+ Str << ".intel_syntax\n";
+ } else {
+ getDest()->asType(Src->getType()).emit(Func);
+ Str << ", ";
+ Src->emit(Func);
+ Str << "\n";
+ }
}
template <> void InstX8632Movp::emit(const Cfg *Func) const {
diff --git a/tests_lit/llvm2ice_tests/globalinit.pnacl.ll b/tests_lit/llvm2ice_tests/globalinit.pnacl.ll
index f5657f5..a0772ee 100644
--- a/tests_lit/llvm2ice_tests/globalinit.pnacl.ll
+++ b/tests_lit/llvm2ice_tests/globalinit.pnacl.ll
@@ -92,7 +92,28 @@
call void @use(i32 %expanded13)
ret i32 0
}
-; CHECK: entry:
+; CHECK-LABEL: main
+; CHECK: .att_syntax
+; CHECK: leal PrimitiveInit,
+; CHECK: .intel_syntax
+; CHECK: .att_syntax
+; CHECK: leal PrimitiveInitConst,
+; CHECK: .intel_syntax
+; CHECK: .att_syntax
+; CHECK: leal PrimitiveInitStatic,
+; CHECK: .intel_syntax
+; CHECK: .att_syntax
+; CHECK: leal PrimitiveUninit,
+; CHECK: .intel_syntax
+; CHECK: .att_syntax
+; CHECK: leal ArrayInit,
+; CHECK: .intel_syntax
+; CHECK: .att_syntax
+; CHECK: leal ArrayInitPartial,
+; CHECK: .intel_syntax
+; CHECK: .att_syntax
+; CHECK: leal ArrayUninit,
+; CHECK: .intel_syntax
declare void @use(i32)