mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-05 14:34:55 +00:00
[ms-inline asm] Support offsets after segment registers
Summary: MASM let's you do stuff like 'MOV FS:20, EAX' and 'MOV EAX, FS:20' Reviewers: craig.topper, rnk Reviewed By: rnk CC: llvm-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1470 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189407 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
66b7139b1b
commit
7cde9d0286
@ -497,8 +497,9 @@ private:
|
||||
X86Operand *ParseIntelOffsetOfOperator();
|
||||
X86Operand *ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
|
||||
X86Operand *ParseIntelOperator(unsigned OpKind);
|
||||
X86Operand *ParseIntelMemOperand(unsigned SegReg, int64_t ImmDisp,
|
||||
SMLoc StartLoc);
|
||||
X86Operand *ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
|
||||
X86Operand *ParseIntelMemOperand(int64_t ImmDisp, SMLoc StartLoc,
|
||||
unsigned Size);
|
||||
X86Operand *ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End);
|
||||
X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
||||
int64_t ImmDisp, unsigned Size);
|
||||
@ -1405,46 +1406,67 @@ X86Operand *X86AsmParser::ParseIntelIdentifier(const MCExpr *&Val,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// ParseIntelMemOperand - Parse intel style memory operand.
|
||||
X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
|
||||
int64_t ImmDisp,
|
||||
SMLoc Start) {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc End;
|
||||
/// \brief Parse intel style segment override.
|
||||
X86Operand *X86AsmParser::ParseIntelSegmentOverride(unsigned SegReg,
|
||||
SMLoc Start,
|
||||
unsigned Size) {
|
||||
assert(SegReg != 0 && "Tried to parse a segment override without a segment!");
|
||||
const AsmToken &Tok = Parser.getTok(); // Eat colon.
|
||||
if (Tok.isNot(AsmToken::Colon))
|
||||
return ErrorOperand(Tok.getLoc(), "Expected ':' token!");
|
||||
Parser.Lex(); // Eat ':'
|
||||
|
||||
unsigned Size = getIntelMemOperandSize(Tok.getString());
|
||||
if (Size) {
|
||||
Parser.Lex(); // Eat operand size (e.g., byte, word).
|
||||
if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
|
||||
return ErrorOperand(Start, "Expected 'PTR' or 'ptr' token!");
|
||||
Parser.Lex(); // Eat ptr.
|
||||
}
|
||||
|
||||
// Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
|
||||
int64_t ImmDisp = 0;
|
||||
if (getLexer().is(AsmToken::Integer)) {
|
||||
ImmDisp = Tok.getIntVal();
|
||||
AsmToken ImmDispToken = Parser.Lex(); // Eat the integer.
|
||||
|
||||
if (isParsingInlineAsm())
|
||||
InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
|
||||
Tok.getLoc()));
|
||||
int64_t ImmDisp = Tok.getIntVal();
|
||||
Parser.Lex(); // Eat the integer.
|
||||
if (getLexer().isNot(AsmToken::LBrac))
|
||||
return ErrorOperand(Start, "Expected '[' token!");
|
||||
return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
|
||||
InstInfo->AsmRewrites->push_back(
|
||||
AsmRewrite(AOK_ImmPrefix, ImmDispToken.getLoc()));
|
||||
|
||||
if (getLexer().isNot(AsmToken::LBrac)) {
|
||||
// An immediate following a 'segment register', 'colon' token sequence can
|
||||
// be followed by a bracketed expression. If it isn't we know we have our
|
||||
// final segment override.
|
||||
const MCExpr *Disp = MCConstantExpr::Create(ImmDisp, getContext());
|
||||
return X86Operand::CreateMem(SegReg, Disp, /*BaseReg=*/0, /*IndexReg=*/0,
|
||||
/*Scale=*/1, Start, ImmDispToken.getEndLoc(),
|
||||
Size);
|
||||
}
|
||||
}
|
||||
|
||||
if (getLexer().is(AsmToken::LBrac))
|
||||
return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
|
||||
|
||||
if (!ParseRegister(SegReg, Start, End)) {
|
||||
// Handel SegReg : [ ... ]
|
||||
if (getLexer().isNot(AsmToken::Colon))
|
||||
return ErrorOperand(Start, "Expected ':' token!");
|
||||
Parser.Lex(); // Eat :
|
||||
if (getLexer().isNot(AsmToken::LBrac))
|
||||
return ErrorOperand(Start, "Expected '[' token!");
|
||||
return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
|
||||
const MCExpr *Val;
|
||||
SMLoc End;
|
||||
if (!isParsingInlineAsm()) {
|
||||
if (getParser().parsePrimaryExpr(Val, End))
|
||||
return ErrorOperand(Tok.getLoc(), "Unexpected token!");
|
||||
|
||||
return X86Operand::CreateMem(Val, Start, End, Size);
|
||||
}
|
||||
|
||||
InlineAsmIdentifierInfo Info;
|
||||
StringRef Identifier = Tok.getString();
|
||||
if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info,
|
||||
/*Unevaluated*/ false, End))
|
||||
return Err;
|
||||
return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
|
||||
/*Scale=*/1, Start, End, Size, Identifier, Info);
|
||||
}
|
||||
|
||||
/// ParseIntelMemOperand - Parse intel style memory operand.
|
||||
X86Operand *X86AsmParser::ParseIntelMemOperand(int64_t ImmDisp, SMLoc Start,
|
||||
unsigned Size) {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc End;
|
||||
|
||||
// Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
|
||||
if (getLexer().is(AsmToken::LBrac))
|
||||
return ParseIntelBracExpression(/*SegReg=*/0, Start, ImmDisp, Size);
|
||||
|
||||
const MCExpr *Val;
|
||||
if (!isParsingInlineAsm()) {
|
||||
if (getParser().parsePrimaryExpr(Val, End))
|
||||
@ -1458,7 +1480,7 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
|
||||
if (X86Operand *Err = ParseIntelIdentifier(Val, Identifier, Info,
|
||||
/*Unevaluated*/ false, End))
|
||||
return Err;
|
||||
return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0,/*IndexReg=*/0,
|
||||
return CreateMemForInlineAsm(/*SegReg=*/0, Val, /*BaseReg=*/0, /*IndexReg=*/0,
|
||||
/*Scale=*/1, Start, End, Size, Identifier, Info);
|
||||
}
|
||||
|
||||
@ -1574,7 +1596,7 @@ X86Operand *X86AsmParser::ParseIntelOperator(unsigned OpKind) {
|
||||
|
||||
X86Operand *X86AsmParser::ParseIntelOperand() {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc Start = Tok.getLoc(), End;
|
||||
SMLoc Start, End;
|
||||
|
||||
// Offset, length, type and size operators.
|
||||
if (isParsingInlineAsm()) {
|
||||
@ -1589,6 +1611,15 @@ X86Operand *X86AsmParser::ParseIntelOperand() {
|
||||
return ParseIntelOperator(IOK_TYPE);
|
||||
}
|
||||
|
||||
unsigned Size = getIntelMemOperandSize(Tok.getString());
|
||||
if (Size) {
|
||||
Parser.Lex(); // Eat operand size (e.g., byte, word).
|
||||
if (Tok.getString() != "PTR" && Tok.getString() != "ptr")
|
||||
return ErrorOperand(Start, "Expected 'PTR' or 'ptr' token!");
|
||||
Parser.Lex(); // Eat ptr.
|
||||
}
|
||||
Start = Tok.getLoc();
|
||||
|
||||
// Immediate.
|
||||
if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) ||
|
||||
getLexer().is(AsmToken::LParen)) {
|
||||
@ -1620,23 +1651,22 @@ X86Operand *X86AsmParser::ParseIntelOperand() {
|
||||
"before bracketed expr.");
|
||||
|
||||
// Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
|
||||
return ParseIntelMemOperand(/*SegReg=*/0, Imm, Start);
|
||||
return ParseIntelMemOperand(Imm, Start, Size);
|
||||
}
|
||||
|
||||
// Register.
|
||||
unsigned RegNo = 0;
|
||||
if (!ParseRegister(RegNo, Start, End)) {
|
||||
// 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.
|
||||
// of a segment override, otherwise this is a normal register reference.
|
||||
if (getLexer().isNot(AsmToken::Colon))
|
||||
return X86Operand::CreateReg(RegNo, Start, End);
|
||||
|
||||
getParser().Lex(); // Eat the colon.
|
||||
return ParseIntelMemOperand(/*SegReg=*/RegNo, /*Disp=*/0, Start);
|
||||
return ParseIntelSegmentOverride(/*SegReg=*/RegNo, Start, Size);
|
||||
}
|
||||
|
||||
// Memory operand.
|
||||
return ParseIntelMemOperand(/*SegReg=*/0, /*Disp=*/0, Start);
|
||||
return ParseIntelMemOperand(/*Disp=*/0, Start, Size);
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::ParseATTOperand() {
|
||||
|
@ -63,6 +63,12 @@ _main:
|
||||
mov ECX, DWORD PTR [4*ECX + _fnan]
|
||||
// CHECK: movq %fs:320, %rax
|
||||
mov RAX, QWORD PTR FS:[320]
|
||||
// CHECK: movq %fs:320, %rax
|
||||
mov RAX, QWORD PTR FS:320
|
||||
// CHECK: movq %rax, %fs:320
|
||||
mov QWORD PTR FS:320, RAX
|
||||
// CHECK: movq %rax, %fs:20(%rbx)
|
||||
mov QWORD PTR FS:20[rbx], RAX
|
||||
// CHECK: vpgatherdd %xmm8, (%r15,%xmm9,2), %xmm1
|
||||
vpgatherdd XMM10, DWORD PTR [R15 + 2*XMM9], XMM8
|
||||
// CHECK: movsd -8, %xmm5
|
||||
|
Loading…
x
Reference in New Issue
Block a user