[llvm] 353a169 - [ms] [llvm-ml] Use default RIP-relative addressing for x64 MASM.
Eric Astor via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 1 09:41:41 PDT 2020
Author: Eric Astor
Date: 2020-07-01T12:41:07-04:00
New Revision: 353a169cb814334e47bc2e98f03931e62023665a
URL: https://github.com/llvm/llvm-project/commit/353a169cb814334e47bc2e98f03931e62023665a
DIFF: https://github.com/llvm/llvm-project/commit/353a169cb814334e47bc2e98f03931e62023665a.diff
LOG: [ms] [llvm-ml] Use default RIP-relative addressing for x64 MASM.
Summary:
When parsing 64-bit MASM, treat memory operands with unspecified base register as RIP-based.
Documented in several places, including https://software.intel.com/en-us/articles/introduction-to-x64-assembly: "Unfortunately, MASM does not allow this form of opcode, but other assemblers like FASM and YASM do. Instead, MASM embeds RIP-relative addressing implicitly."
Reviewed By: thakis
Differential Revision: https://reviews.llvm.org/D73227
Added:
llvm/test/tools/llvm-ml/rip-relative-addressing.test
Modified:
llvm/include/llvm/MC/MCParser/MCAsmParser.h
llvm/lib/MC/MCParser/MasmParser.cpp
llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
llvm/lib/Target/X86/AsmParser/X86Operand.h
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCParser/MCAsmParser.h b/llvm/include/llvm/MC/MCParser/MCAsmParser.h
index 7d57dd605fcb..f02578e451b5 100644
--- a/llvm/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/llvm/include/llvm/MC/MCParser/MCAsmParser.h
@@ -168,6 +168,8 @@ class MCAsmParser {
virtual void setParsingMSInlineAsm(bool V) = 0;
virtual bool isParsingMSInlineAsm() = 0;
+ virtual bool isParsingMasm() const { return false; }
+
/// Parse MS-style inline assembly.
virtual bool parseMSInlineAsm(
void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
diff --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp
index ad44fd51712b..423230962de5 100644
--- a/llvm/lib/MC/MCParser/MasmParser.cpp
+++ b/llvm/lib/MC/MCParser/MasmParser.cpp
@@ -245,6 +245,8 @@ class MasmParser : public MCAsmParser {
}
bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; }
+ bool isParsingMasm() const override { return true; }
+
bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
SmallVectorImpl<std::pair<void *,bool>> &OpDecls,
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index a9577e67def3..7de2b2079b8d 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -1509,8 +1509,9 @@ std::unique_ptr<X86Operand> X86AsmParser::CreateMemForMSInlineAsm(
} else {
BaseReg = BaseReg ? BaseReg : 1;
return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
- IndexReg, Scale, Start, End, Size, Identifier,
- Decl, FrontendSize);
+ IndexReg, Scale, Start, End, Size,
+ /*DefaultBaseReg=*/X86::RIP, Identifier, Decl,
+ FrontendSize);
}
}
@@ -2073,6 +2074,14 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
return CreateMemForMSInlineAsm(RegNo, Disp, BaseReg, IndexReg, Scale, Start,
End, Size, SM.getSymName(),
SM.getIdentifierInfo());
+
+ // When parsing x64 MS-style assembly, all memory operands default to
+ // RIP-relative when interpreted as non-absolute references.
+ if (Parser.isParsingMasm() && is64BitMode())
+ return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp, BaseReg,
+ IndexReg, Scale, Start, End, Size,
+ /*DefaultBaseReg=*/X86::RIP);
+
if (!(BaseReg || IndexReg || RegNo))
return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
return X86Operand::CreateMem(getPointerWidth(), RegNo, Disp,
diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h
index fb5f3355532e..5393d90f16ba 100644
--- a/llvm/lib/Target/X86/AsmParser/X86Operand.h
+++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h
@@ -58,6 +58,7 @@ struct X86Operand final : public MCParsedAsmOperand {
unsigned SegReg;
const MCExpr *Disp;
unsigned BaseReg;
+ unsigned DefaultBaseReg;
unsigned IndexReg;
unsigned Scale;
unsigned Size;
@@ -182,6 +183,10 @@ struct X86Operand final : public MCParsedAsmOperand {
assert(Kind == Memory && "Invalid access!");
return Mem.BaseReg;
}
+ unsigned getMemDefaultBaseReg() const {
+ assert(Kind == Memory && "Invalid access!");
+ return Mem.DefaultBaseReg;
+ }
unsigned getMemIndexReg() const {
assert(Kind == Memory && "Invalid access!");
return Mem.IndexReg;
@@ -546,7 +551,10 @@ struct X86Operand final : public MCParsedAsmOperand {
void addMemOperands(MCInst &Inst, unsigned N) const {
assert((N == 5) && "Invalid number of operands!");
- Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
+ if (getMemBaseReg())
+ Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
+ else
+ Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg()));
Inst.addOperand(MCOperand::createImm(getMemScale()));
Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
addExpr(Inst, getMemDisp());
@@ -639,6 +647,7 @@ struct X86Operand final : public MCParsedAsmOperand {
Res->Mem.SegReg = 0;
Res->Mem.Disp = Disp;
Res->Mem.BaseReg = 0;
+ Res->Mem.DefaultBaseReg = 0;
Res->Mem.IndexReg = 0;
Res->Mem.Scale = 1;
Res->Mem.Size = Size;
@@ -654,11 +663,14 @@ struct X86Operand final : public MCParsedAsmOperand {
static std::unique_ptr<X86Operand>
CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
- SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
- void *OpDecl = nullptr, unsigned FrontendSize = 0) {
+ SMLoc EndLoc, unsigned Size = 0,
+ unsigned DefaultBaseReg = X86::NoRegister,
+ StringRef SymName = StringRef(), void *OpDecl = nullptr,
+ unsigned FrontendSize = 0) {
// We should never just have a displacement, that should be parsed as an
// absolute memory operand.
- assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
+ assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) &&
+ "Invalid memory operand!");
// The scale should always be one of {1,2,4,8}.
assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
@@ -667,6 +679,7 @@ struct X86Operand final : public MCParsedAsmOperand {
Res->Mem.SegReg = SegReg;
Res->Mem.Disp = Disp;
Res->Mem.BaseReg = BaseReg;
+ Res->Mem.DefaultBaseReg = DefaultBaseReg;
Res->Mem.IndexReg = IndexReg;
Res->Mem.Scale = Scale;
Res->Mem.Size = Size;
diff --git a/llvm/test/tools/llvm-ml/rip-relative-addressing.test b/llvm/test/tools/llvm-ml/rip-relative-addressing.test
new file mode 100644
index 000000000000..81e5676d041e
--- /dev/null
+++ b/llvm/test/tools/llvm-ml/rip-relative-addressing.test
@@ -0,0 +1,8 @@
+# RUN: llvm-ml -m32 -filetype=asm %s | FileCheck %s --check-prefix=CHECK-32
+# RUN: llvm-ml -m64 -filetype=asm %s | FileCheck %s --check-prefix=CHECK-64
+
+.code
+mov eax, [4]
+; CHECK-32: mov eax, dword ptr [4]
+; CHECK-64: mov eax, dword ptr [rip + 4]
+END
\ No newline at end of file
More information about the llvm-commits
mailing list