mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
[X86][MS-compatability][llvm] allow MS TYPE/SIZE/LENGTH operators as a part of a compound expression
This patch introduces X86AsmParser with the ability to handle the aforementioned ops within compound "MS" arithmetical expressions. Currently - only supported as a stand alone Operand, e.g.: "TYPE X" now allowed : "4 + TYPE X * 128" Clang side: https://reviews.llvm.org/D31174 Differential Revision: https://reviews.llvm.org/D31173 llvm-svn: 298425
This commit is contained in:
parent
68c26974a8
commit
06adb3d9b0
@ -98,6 +98,14 @@ private:
|
||||
IC_REGISTER
|
||||
};
|
||||
|
||||
enum IntelOperatorKind {
|
||||
IOK_INVALID = 0,
|
||||
IOK_LENGTH,
|
||||
IOK_SIZE,
|
||||
IOK_TYPE,
|
||||
IOK_OFFSET
|
||||
};
|
||||
|
||||
class InfixCalculator {
|
||||
typedef std::pair< InfixCalculatorTok, int64_t > ICToken;
|
||||
SmallVector<InfixCalculatorTok, 4> InfixOperatorStack;
|
||||
@ -704,7 +712,8 @@ private:
|
||||
std::unique_ptr<X86Operand> ParseIntelOperand();
|
||||
std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
|
||||
bool ParseIntelDotOperator(const MCExpr *Disp, const MCExpr *&NewDisp);
|
||||
std::unique_ptr<X86Operand> ParseIntelOperator(unsigned OpKind);
|
||||
unsigned IdentifyIntelOperator(StringRef Name);
|
||||
unsigned ParseIntelOperator(unsigned OpKind);
|
||||
std::unique_ptr<X86Operand>
|
||||
ParseIntelSegmentOverride(unsigned SegReg, SMLoc Start, unsigned Size);
|
||||
std::unique_ptr<X86Operand> ParseRoundingModeOp(SMLoc Start, SMLoc End);
|
||||
@ -814,6 +823,7 @@ private:
|
||||
/// }
|
||||
|
||||
public:
|
||||
|
||||
X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
|
||||
const MCInstrInfo &mii, const MCTargetOptions &Options)
|
||||
: MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr),
|
||||
@ -1266,10 +1276,12 @@ RewriteIntelBracExpression(SmallVectorImpl<AsmRewrite> &AsmRewrites,
|
||||
}
|
||||
}
|
||||
// Remove all the ImmPrefix rewrites within the brackets.
|
||||
// We may have some Imm rewrties as a result of an operator applying,
|
||||
// remove them as well
|
||||
for (AsmRewrite &AR : AsmRewrites) {
|
||||
if (AR.Loc.getPointer() < StartInBrac.getPointer())
|
||||
continue;
|
||||
if (AR.Kind == AOK_ImmPrefix)
|
||||
if (AR.Kind == AOK_ImmPrefix || AR.Kind == AOK_Imm)
|
||||
AR.Kind = AOK_Delete;
|
||||
}
|
||||
const char *SymLocPtr = SymName.data();
|
||||
@ -1324,31 +1336,34 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {
|
||||
const MCExpr *Val;
|
||||
SMLoc IdentLoc = Tok.getLoc();
|
||||
StringRef Identifier = Tok.getString();
|
||||
UpdateLocLex = false;
|
||||
if (TK != AsmToken::String && !ParseRegister(TmpReg, IdentLoc, End)) {
|
||||
SM.onRegister(TmpReg);
|
||||
UpdateLocLex = false;
|
||||
break;
|
||||
} else {
|
||||
if (!isParsingInlineAsm()) {
|
||||
if (getParser().parsePrimaryExpr(Val, End))
|
||||
return Error(Tok.getLoc(), "Unexpected identifier!");
|
||||
} else {
|
||||
// This is a dot operator, not an adjacent identifier.
|
||||
if (Identifier.find('.') != StringRef::npos &&
|
||||
PrevTK == AsmToken::RBrac) {
|
||||
return false;
|
||||
} else {
|
||||
InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
|
||||
if (ParseIntelIdentifier(Val, Identifier, Info,
|
||||
/*Unevaluated=*/false, End))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (!isParsingInlineAsm()) {
|
||||
if (getParser().parsePrimaryExpr(Val, End))
|
||||
return Error(Tok.getLoc(), "Unexpected identifier!");
|
||||
SM.onIdentifierExpr(Val, Identifier);
|
||||
} else if (unsigned OpKind = IdentifyIntelOperator(Identifier)) {
|
||||
if (OpKind == IOK_OFFSET)
|
||||
return Error(IdentLoc, "Dealing OFFSET operator as part of"
|
||||
"a compound immediate expression is yet to be supported");
|
||||
int64_t Val = ParseIntelOperator(OpKind);
|
||||
if (!Val)
|
||||
return true;
|
||||
StringRef ErrMsg;
|
||||
if (SM.onInteger(Val, ErrMsg))
|
||||
return Error(IdentLoc, ErrMsg);
|
||||
} else if (Identifier.find('.') != StringRef::npos &&
|
||||
PrevTK == AsmToken::RBrac) {
|
||||
return false;
|
||||
} else {
|
||||
InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
|
||||
if (ParseIntelIdentifier(Val, Identifier, Info,
|
||||
/*Unevaluated=*/false, End))
|
||||
return true;
|
||||
SM.onIdentifierExpr(Val, Identifier);
|
||||
UpdateLocLex = false;
|
||||
break;
|
||||
}
|
||||
return Error(Tok.getLoc(), "Unexpected identifier!");
|
||||
break;
|
||||
}
|
||||
case AsmToken::Integer: {
|
||||
StringRef ErrMsg;
|
||||
@ -1715,11 +1730,16 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
|
||||
OffsetOfLoc, Identifier, Info.OpDecl);
|
||||
}
|
||||
|
||||
enum IntelOperatorKind {
|
||||
IOK_LENGTH,
|
||||
IOK_SIZE,
|
||||
IOK_TYPE
|
||||
};
|
||||
// Query a candidate string for being an Intel assembly operator
|
||||
// Report back its kind, or IOK_INVALID if does not evaluated as a known one
|
||||
unsigned X86AsmParser::IdentifyIntelOperator(StringRef Name) {
|
||||
return StringSwitch<unsigned>(Name)
|
||||
.Cases("TYPE","type",IOK_TYPE)
|
||||
.Cases("SIZE","size",IOK_SIZE)
|
||||
.Cases("LENGTH","length",IOK_LENGTH)
|
||||
.Cases("OFFSET","offset",IOK_OFFSET)
|
||||
.Default(IOK_INVALID);
|
||||
}
|
||||
|
||||
/// Parse the 'LENGTH', 'TYPE' and 'SIZE' operators. The LENGTH operator
|
||||
/// returns the number of elements in an array. It returns the value 1 for
|
||||
@ -1727,7 +1747,7 @@ enum IntelOperatorKind {
|
||||
/// variable. A variable's size is the product of its LENGTH and TYPE. The
|
||||
/// TYPE operator returns the size of a C or C++ type or variable. If the
|
||||
/// variable is an array, TYPE returns the size of a single element.
|
||||
std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
|
||||
unsigned X86AsmParser::ParseIntelOperator(unsigned OpKind) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc TypeLoc = Tok.getLoc();
|
||||
@ -1739,11 +1759,13 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
|
||||
StringRef Identifier = Tok.getString();
|
||||
if (ParseIntelIdentifier(Val, Identifier, Info,
|
||||
/*Unevaluated=*/true, End))
|
||||
return nullptr;
|
||||
|
||||
if (!Info.OpDecl)
|
||||
return ErrorOperand(Start, "unable to lookup expression");
|
||||
return 0;
|
||||
|
||||
if (!Info.OpDecl) {
|
||||
Error(Start, "unable to lookup expression");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned CVal = 0;
|
||||
switch(OpKind) {
|
||||
default: llvm_unreachable("Unexpected operand kind!");
|
||||
@ -1757,8 +1779,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperator(unsigned OpKind) {
|
||||
unsigned Len = End.getPointer() - TypeLoc.getPointer();
|
||||
InstInfo->AsmRewrites->emplace_back(AOK_Imm, TypeLoc, Len, CVal);
|
||||
|
||||
const MCExpr *Imm = MCConstantExpr::create(CVal, getContext());
|
||||
return X86Operand::CreateImm(Imm, Start, End);
|
||||
return CVal;
|
||||
}
|
||||
|
||||
std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
|
||||
@ -1766,18 +1787,12 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
SMLoc Start, End;
|
||||
|
||||
// Offset, length, type and size operators.
|
||||
if (isParsingInlineAsm()) {
|
||||
StringRef AsmTokStr = Tok.getString();
|
||||
if (AsmTokStr == "offset" || AsmTokStr == "OFFSET")
|
||||
// FIXME: Offset operator
|
||||
// Should be handled as part of immediate expression, as other operators
|
||||
// Currently, only supported as a stand-alone operand
|
||||
if (isParsingInlineAsm())
|
||||
if (IdentifyIntelOperator(Tok.getString()) == IOK_OFFSET)
|
||||
return ParseIntelOffsetOfOperator();
|
||||
if (AsmTokStr == "length" || AsmTokStr == "LENGTH")
|
||||
return ParseIntelOperator(IOK_LENGTH);
|
||||
if (AsmTokStr == "size" || AsmTokStr == "SIZE")
|
||||
return ParseIntelOperator(IOK_SIZE);
|
||||
if (AsmTokStr == "type" || AsmTokStr == "TYPE")
|
||||
return ParseIntelOperator(IOK_TYPE);
|
||||
}
|
||||
|
||||
bool PtrInOperand = false;
|
||||
unsigned Size = getIntelMemOperandSize(Tok.getString());
|
||||
|
Loading…
Reference in New Issue
Block a user