1
0
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:
Chad Rosier 2013-03-27 21:49:56 +00:00
parent fdfa67c4d9
commit 09bc7a9c8d
2 changed files with 72 additions and 15 deletions

View File

@ -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);
}

View File

@ -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]