mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
[ms-inline asm] Add support for ImmDisp [ Symbol ] memory operands.
rdar://13521249 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179030 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5ee67e8e76
commit
6b369ceb58
@ -22,7 +22,7 @@ class MCInst;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
|
||||
enum AsmRewriteKind {
|
||||
AOK_Align, // Rewrite align as .align.
|
||||
AOK_Align = 0, // Rewrite align as .align.
|
||||
AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
|
||||
// E.g., [eax].foo.bar -> [eax].8
|
||||
AOK_Emit, // Rewrite _emit as .byte.
|
||||
@ -34,6 +34,18 @@ enum AsmRewriteKind {
|
||||
AOK_Skip // Skip emission (e.g., offset/type operators).
|
||||
};
|
||||
|
||||
const char AsmRewritePrecedence [] = {
|
||||
0, // AOK_Align
|
||||
0, // AOK_DotOperator
|
||||
0, // AOK_Emit
|
||||
2, // AOK_Imm
|
||||
2, // AOK_ImmPrefix
|
||||
1, // AOK_Input
|
||||
1, // AOK_Output
|
||||
3, // AOK_SizeDirective
|
||||
0 // AOK_Skip
|
||||
};
|
||||
|
||||
struct AsmRewrite {
|
||||
AsmRewriteKind Kind;
|
||||
SMLoc Loc;
|
||||
|
@ -4046,19 +4046,17 @@ static int RewritesSort(const void *A, const void *B) {
|
||||
if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
|
||||
return 1;
|
||||
|
||||
// It's possible to have a SizeDirective rewrite and an Input/Output rewrite
|
||||
// to the same location. Make sure the SizeDirective rewrite is performed
|
||||
// first. This also ensure the sort algorithm is stable.
|
||||
if (AsmRewriteA->Kind == AOK_SizeDirective) {
|
||||
assert ((AsmRewriteB->Kind == AOK_Input || AsmRewriteB->Kind == AOK_Output) &&
|
||||
"Expected an Input/Output rewrite!");
|
||||
// It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
|
||||
// rewrite to the same location. Make sure the SizeDirective rewrite is
|
||||
// performed first, then the Imm/ImmPrefix and finally the Input/Output. This
|
||||
// ensures the sort algorithm is stable.
|
||||
if (AsmRewritePrecedence [AsmRewriteA->Kind] >
|
||||
AsmRewritePrecedence [AsmRewriteB->Kind])
|
||||
return -1;
|
||||
}
|
||||
if (AsmRewriteB->Kind == AOK_SizeDirective) {
|
||||
assert ((AsmRewriteA->Kind == AOK_Input || AsmRewriteA->Kind == AOK_Output) &&
|
||||
"Expected an Input/Output rewrite!");
|
||||
|
||||
if (AsmRewritePrecedence [AsmRewriteA->Kind] <
|
||||
AsmRewritePrecedence [AsmRewriteB->Kind])
|
||||
return 1;
|
||||
}
|
||||
llvm_unreachable ("Unstable rewrite sort.");
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,8 @@ private:
|
||||
X86Operand *ParseIntelOperator(SMLoc StartLoc, unsigned OpKind);
|
||||
X86Operand *ParseIntelMemOperand(unsigned SegReg, uint64_t ImmDisp,
|
||||
SMLoc StartLoc);
|
||||
X86Operand *ParseIntelBracExpression(unsigned SegReg, uint64_t ImmDisp,
|
||||
unsigned Size);
|
||||
X86Operand *ParseIntelBracExpression(unsigned SegReg, SMLoc SizeDirLoc,
|
||||
uint64_t ImmDisp, unsigned Size);
|
||||
X86Operand *ParseIntelVarWithQualifier(const MCExpr *&Disp,
|
||||
SMLoc &IdentStart);
|
||||
X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
|
||||
@ -1100,6 +1100,7 @@ X86Operand *X86AsmParser::CreateMemForInlineAsm(const MCExpr *Disp, SMLoc Start,
|
||||
}
|
||||
|
||||
X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
|
||||
SMLoc SizeDirLoc,
|
||||
uint64_t ImmDisp,
|
||||
unsigned Size) {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
@ -1126,18 +1127,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();
|
||||
if (!isParsingInlineAsm())
|
||||
return X86Operand::CreateMem(Disp, Start, End, Size);
|
||||
|
||||
// We want the size directive before the '['.
|
||||
SMLoc SizeDirLoc = SMLoc::getFromPointer(Start.getPointer()-1);
|
||||
return CreateMemForInlineAsm(Disp, Start, End, SizeDirLoc, Size);
|
||||
}
|
||||
}
|
||||
@ -1302,11 +1296,11 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
|
||||
Parser.Lex(); // Eat the integer.
|
||||
if (getLexer().isNot(AsmToken::LBrac))
|
||||
return ErrorOperand(Start, "Expected '[' token!");
|
||||
return ParseIntelBracExpression(SegReg, ImmDisp, Size);
|
||||
return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
|
||||
}
|
||||
|
||||
if (getLexer().is(AsmToken::LBrac))
|
||||
return ParseIntelBracExpression(SegReg, ImmDisp, Size);
|
||||
return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
|
||||
|
||||
if (!ParseRegister(SegReg, Start, End)) {
|
||||
// Handel SegReg : [ ... ]
|
||||
@ -1315,7 +1309,7 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
|
||||
Parser.Lex(); // Eat :
|
||||
if (getLexer().isNot(AsmToken::LBrac))
|
||||
return ErrorOperand(Start, "Expected '[' token!");
|
||||
return ParseIntelBracExpression(SegReg, ImmDisp, Size);
|
||||
return ParseIntelBracExpression(SegReg, Start, ImmDisp, Size);
|
||||
}
|
||||
|
||||
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
|
||||
|
Loading…
Reference in New Issue
Block a user