mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[ms-inline asm] Add support of imm displacement before bracketed memory
expression. Specifically, this syntax: ImmDisp [ BaseReg + Scale*IndexReg + Disp ] We don't currently support: ImmDisp [ Symbol ] rdar://13518671 llvm-svn: 178186
This commit is contained in:
parent
fdfa67c4d9
commit
09bc7a9c8d
@ -58,8 +58,10 @@ private:
|
||||
X86Operand *ParseIntelOperand();
|
||||
X86Operand *ParseIntelOffsetOfOperator(SMLoc StartLoc);
|
||||
X86Operand *ParseIntelOperator(SMLoc StartLoc, unsigned OpKind);
|
||||
X86Operand *ParseIntelMemOperand(unsigned SegReg, SMLoc StartLoc);
|
||||
X86Operand *ParseIntelBracExpression(unsigned SegReg, unsigned Size);
|
||||
X86Operand *ParseIntelMemOperand(unsigned SegReg, uint64_t ImmDisp,
|
||||
SMLoc StartLoc);
|
||||
X86Operand *ParseIntelBracExpression(unsigned SegReg, uint64_t ImmDisp,
|
||||
unsigned Size);
|
||||
X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
|
||||
|
||||
X86Operand *CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start, SMLoc End,
|
||||
@ -698,8 +700,8 @@ class IntelBracExprStateMachine {
|
||||
bool isPlus;
|
||||
|
||||
public:
|
||||
IntelBracExprStateMachine(MCAsmParser &parser) :
|
||||
State(IBES_START), BaseReg(0), IndexReg(0), Scale(1), Disp(0),
|
||||
IntelBracExprStateMachine(MCAsmParser &parser, int64_t disp) :
|
||||
State(IBES_START), BaseReg(0), IndexReg(0), Scale(1), Disp(disp),
|
||||
TmpReg(0), TmpInteger(0), isPlus(true) {}
|
||||
|
||||
unsigned getBaseReg() { return BaseReg; }
|
||||
@ -916,7 +918,8 @@ X86Operand *X86AsmParser::CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start,
|
||||
/*Scale*/1, Start, End, Size);
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
uint64_t ImmDisp,
|
||||
unsigned Size) {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc Start = Tok.getLoc(), End = Tok.getEndLoc();
|
||||
@ -928,7 +931,7 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
|
||||
unsigned TmpReg = 0;
|
||||
|
||||
// Try to handle '[' 'symbol' ']'
|
||||
// Try to handle '[' 'Symbol' ']'
|
||||
if (getLexer().is(AsmToken::Identifier)) {
|
||||
if (ParseRegister(TmpReg, Start, End)) {
|
||||
const MCExpr *Disp;
|
||||
@ -937,6 +940,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
|
||||
if (getLexer().isNot(AsmToken::RBrac))
|
||||
return ErrorOperand(Parser.getTok().getLoc(), "Expected ']' token!");
|
||||
|
||||
// FIXME: We don't handle 'ImmDisp' '[' 'Symbol' ']'.
|
||||
if (ImmDisp)
|
||||
return ErrorOperand(Start, "Unsupported immediate displacement!");
|
||||
|
||||
// Adjust the EndLoc due to the ']'.
|
||||
End = SMLoc::getFromPointer(Parser.getTok().getEndLoc().getPointer()-1);
|
||||
Parser.Lex();
|
||||
@ -949,9 +957,10 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
}
|
||||
}
|
||||
|
||||
// Parse [ BaseReg + Scale*IndexReg + Disp ].
|
||||
// Parse [ BaseReg + Scale*IndexReg + Disp ]. We may have already parsed an
|
||||
// immediate displacement before the bracketed expression.
|
||||
bool Done = false;
|
||||
IntelBracExprStateMachine SM(Parser);
|
||||
IntelBracExprStateMachine SM(Parser, ImmDisp);
|
||||
|
||||
// If we parsed a register, then the end loc has already been set and
|
||||
// the identifier has already been lexed. We also need to update the
|
||||
@ -1038,7 +1047,9 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
}
|
||||
|
||||
/// ParseIntelMemOperand - Parse intel style memory operand.
|
||||
X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg, SMLoc Start) {
|
||||
X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
|
||||
uint64_t ImmDisp,
|
||||
SMLoc Start) {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc End;
|
||||
|
||||
@ -1050,8 +1061,21 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg, SMLoc Start) {
|
||||
Parser.Lex();
|
||||
}
|
||||
|
||||
// Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
|
||||
if (getLexer().is(AsmToken::Integer)) {
|
||||
const AsmToken &IntTok = Parser.getTok();
|
||||
if (isParsingInlineAsm())
|
||||
InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix,
|
||||
IntTok.getLoc()));
|
||||
uint64_t ImmDisp = IntTok.getIntVal();
|
||||
Parser.Lex(); // Eat the integer.
|
||||
if (getLexer().isNot(AsmToken::LBrac))
|
||||
return ErrorOperand(Start, "Expected '[' token!");
|
||||
return ParseIntelBracExpression(SegReg, ImmDisp, Size);
|
||||
}
|
||||
|
||||
if (getLexer().is(AsmToken::LBrac))
|
||||
return ParseIntelBracExpression(SegReg, Size);
|
||||
return ParseIntelBracExpression(SegReg, ImmDisp, Size);
|
||||
|
||||
if (!ParseRegister(SegReg, Start, End)) {
|
||||
// Handel SegReg : [ ... ]
|
||||
@ -1060,7 +1084,7 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg, SMLoc Start) {
|
||||
Parser.Lex(); // Eat :
|
||||
if (getLexer().isNot(AsmToken::LBrac))
|
||||
return ErrorOperand(Start, "Expected '[' token!");
|
||||
return ParseIntelBracExpression(SegReg, Size);
|
||||
return ParseIntelBracExpression(SegReg, ImmDisp, Size);
|
||||
}
|
||||
|
||||
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
|
||||
@ -1220,10 +1244,24 @@ X86Operand *X86AsmParser::ParseIntelOperand() {
|
||||
if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Real) ||
|
||||
getLexer().is(AsmToken::Minus)) {
|
||||
const MCExpr *Val;
|
||||
bool isInteger = getLexer().is(AsmToken::Integer);
|
||||
if (!getParser().parseExpression(Val, End)) {
|
||||
if (isParsingInlineAsm())
|
||||
InstInfo->AsmRewrites->push_back(AsmRewrite(AOK_ImmPrefix, Start));
|
||||
return X86Operand::CreateImm(Val, Start, End);
|
||||
// Immediate.
|
||||
if (getLexer().isNot(AsmToken::LBrac))
|
||||
return X86Operand::CreateImm(Val, Start, End);
|
||||
|
||||
// Only positive immediates are valid.
|
||||
if (!isInteger) {
|
||||
Error(Parser.getTok().getLoc(), "expected a positive immediate "
|
||||
"displacement before bracketed expr.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse ImmDisp [ BaseReg + Scale*IndexReg + Disp ].
|
||||
if (uint64_t ImmDisp = dyn_cast<MCConstantExpr>(Val)->getValue())
|
||||
return ParseIntelMemOperand(/*SegReg=*/0, ImmDisp, Start);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1236,11 +1274,11 @@ X86Operand *X86AsmParser::ParseIntelOperand() {
|
||||
return X86Operand::CreateReg(RegNo, Start, End);
|
||||
|
||||
getParser().Lex(); // Eat the colon.
|
||||
return ParseIntelMemOperand(RegNo, Start);
|
||||
return ParseIntelMemOperand(/*SegReg=*/RegNo, /*Disp=*/0, Start);
|
||||
}
|
||||
|
||||
// Memory operand.
|
||||
return ParseIntelMemOperand(0, Start);
|
||||
return ParseIntelMemOperand(/*SegReg=*/0, /*Disp=*/0, Start);
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::ParseATTOperand() {
|
||||
@ -1264,7 +1302,6 @@ X86Operand *X86AsmParser::ParseATTOperand() {
|
||||
if (getLexer().isNot(AsmToken::Colon))
|
||||
return X86Operand::CreateReg(RegNo, Start, End);
|
||||
|
||||
|
||||
getParser().Lex(); // Eat the colon.
|
||||
return ParseMemOperand(RegNo, Start);
|
||||
}
|
||||
|
@ -57,6 +57,26 @@ _t21: ## @t21
|
||||
// CHECK: movl 4(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x04]
|
||||
|
||||
mov eax, 4[esi + 2*eax + 4]
|
||||
// CHECK: movl 8(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x08]
|
||||
mov eax, 4[esi][2*eax + 4]
|
||||
// CHECK: movl 8(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x08]
|
||||
mov eax, 4[esi + 2*eax][4]
|
||||
// CHECK: movl 8(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x08]
|
||||
mov eax, 4[esi][2*eax][4]
|
||||
// CHECK: movl 8(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x08]
|
||||
mov eax, 4[esi][2*eax][4][8]
|
||||
// CHECK: movl 16(%esi,%eax,2), %eax
|
||||
// CHECK: # encoding: [0x8b,0x44,0x46,0x10]
|
||||
|
||||
prefetchnta 64[eax]
|
||||
// CHECK: prefetchnta 64(%eax)
|
||||
// CHECK: # encoding: [0x0f,0x18,0x40,0x40]
|
||||
|
||||
pusha
|
||||
// CHECK: pushal
|
||||
// CHECK: # encoding: [0x60]
|
||||
|
Loading…
Reference in New Issue
Block a user