@@ -67,7 +67,9 @@ class X86AsmParser : public MCTargetAsmParser {
67
67
StringRef &Identifier);
68
68
X86Operand *ParseMemOperand (unsigned SegReg, SMLoc StartLoc);
69
69
70
- X86Operand *CreateMemForInlineAsm (const MCExpr *Disp, SMLoc Start, SMLoc End,
70
+ X86Operand *CreateMemForInlineAsm (unsigned SegReg, const MCExpr *Disp,
71
+ unsigned BaseReg, unsigned IndexReg,
72
+ unsigned Scale, SMLoc Start, SMLoc End,
71
73
SMLoc SizeDirLoc, unsigned Size,
72
74
StringRef SymName);
73
75
@@ -851,15 +853,20 @@ class IntelBracExprStateMachine {
851
853
IntelBracExprState State;
852
854
unsigned BaseReg, IndexReg, TmpReg, Scale;
853
855
int64_t Disp;
856
+ const MCExpr *Sym;
857
+ StringRef SymName;
854
858
InfixCalculator IC;
855
859
public:
856
860
IntelBracExprStateMachine (MCAsmParser &parser, int64_t disp) :
857
- State (IBES_PLUS), BaseReg(0 ), IndexReg(0 ), TmpReg(0 ), Scale(1 ), Disp(disp){}
861
+ State (IBES_PLUS), BaseReg(0 ), IndexReg(0 ), TmpReg(0 ), Scale(1 ), Disp(disp),
862
+ Sym (0 ) {}
858
863
859
864
unsigned getBaseReg () { return BaseReg; }
860
865
unsigned getIndexReg () { return IndexReg; }
861
866
unsigned getScale () { return Scale; }
862
- int64_t getDisp () { return Disp + IC.execute (); }
867
+ const MCExpr *getSym () { return Sym; }
868
+ StringRef getSymName () { return SymName; }
869
+ int64_t getImmDisp () { return Disp + IC.execute (); }
863
870
bool isValidEndState () { return State == IBES_RBRAC; }
864
871
865
872
void onPlus () {
@@ -936,14 +943,16 @@ class IntelBracExprStateMachine {
936
943
break ;
937
944
}
938
945
}
939
- void onDispExpr () {
946
+ void onDispExpr (const MCExpr *SymRef, StringRef SymRefName ) {
940
947
switch (State) {
941
948
default :
942
949
State = IBES_ERROR;
943
950
break ;
944
951
case IBES_PLUS:
945
952
case IBES_MINUS:
946
953
State = IBES_INTEGER;
954
+ Sym = SymRef;
955
+ SymName = SymRefName;
947
956
IC.pushOperand (IC_IMM);
948
957
break ;
949
958
}
@@ -1070,45 +1079,47 @@ class IntelBracExprStateMachine {
1070
1079
}
1071
1080
};
1072
1081
1073
- X86Operand *X86AsmParser::CreateMemForInlineAsm (const MCExpr *Disp, SMLoc Start,
1074
- SMLoc End, SMLoc SizeDirLoc,
1075
- unsigned Size, StringRef SymName) {
1082
+ X86Operand *
1083
+ X86AsmParser::CreateMemForInlineAsm (unsigned SegReg, const MCExpr *Disp,
1084
+ unsigned BaseReg, unsigned IndexReg,
1085
+ unsigned Scale, SMLoc Start, SMLoc End,
1086
+ SMLoc SizeDirLoc, unsigned Size,
1087
+ StringRef SymName) {
1076
1088
bool NeedSizeDir = false ;
1077
- bool IsVarDecl = false ;
1078
-
1079
1089
if (const MCSymbolRefExpr *SymRef = dyn_cast<MCSymbolRefExpr>(Disp)) {
1080
1090
const MCSymbol &Sym = SymRef->getSymbol ();
1081
1091
// FIXME: The SemaLookup will fail if the name is anything other then an
1082
1092
// identifier.
1083
1093
// FIXME: Pass a valid SMLoc.
1094
+ bool IsVarDecl = false ;
1084
1095
unsigned tLength, tSize, tType;
1085
1096
SemaCallback->LookupInlineAsmIdentifier (Sym.getName (), NULL , tLength, tSize,
1086
1097
tType, IsVarDecl);
1087
1098
if (!Size) {
1088
1099
Size = tType * 8 ; // Size is in terms of bits in this context.
1089
1100
NeedSizeDir = Size > 0 ;
1090
1101
}
1091
- }
1092
-
1093
- // If this is not a VarDecl then assume it is a FuncDecl or some other label
1094
- // reference. We need an 'r' constraint here, so we need to create register
1095
- // operand to ensure proper matching. Just pick a GPR based on the size of
1096
- // a pointer.
1097
- if (!IsVarDecl) {
1098
- unsigned RegNo = is64BitMode () ? X86::RBX : X86::EBX;
1099
- return X86Operand::CreateReg (RegNo, Start, End, /* AddressOf=*/ true , SMLoc (),
1100
- SymName);
1102
+ // If this is not a VarDecl then assume it is a FuncDecl or some other label
1103
+ // reference. We need an 'r' constraint here, so we need to create register
1104
+ // operand to ensure proper matching. Just pick a GPR based on the size of
1105
+ // a pointer.
1106
+ if (!IsVarDecl) {
1107
+ unsigned RegNo = is64BitMode () ? X86::RBX : X86::EBX;
1108
+ return X86Operand::CreateReg (RegNo, Start, End, /* AddressOf=*/ true ,
1109
+ SMLoc (), SymName);
1110
+ }
1101
1111
}
1102
1112
1103
1113
if (NeedSizeDir)
1104
1114
InstInfo->AsmRewrites ->push_back (AsmRewrite (AOK_SizeDirective, SizeDirLoc,
1105
1115
/* Len*/ 0 , Size));
1106
1116
1107
1117
// When parsing inline assembly we set the base register to a non-zero value
1108
- // as we don't know the actual value at this time. This is necessary to
1118
+ // if we don't know the actual value at this time. This is necessary to
1109
1119
// get the matching correct in some cases.
1110
- return X86Operand::CreateMem (/* SegReg*/ 0 , Disp, /* BaseReg*/ 1 , /* IndexReg*/ 0 ,
1111
- /* Scale*/ 1 , Start, End, Size, SymName);
1120
+ BaseReg = BaseReg ? BaseReg : 1 ;
1121
+ return X86Operand::CreateMem (SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1122
+ End, Size, SymName);
1112
1123
}
1113
1124
1114
1125
X86Operand *X86AsmParser::ParseIntelBracExpression (unsigned SegReg,
@@ -1118,12 +1129,12 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
1118
1129
const AsmToken &Tok = Parser.getTok ();
1119
1130
SMLoc Start = Tok.getLoc (), End = Tok.getEndLoc ();
1120
1131
1121
- // Eat '['
1122
1132
if (getLexer ().isNot (AsmToken::LBrac))
1123
1133
return ErrorOperand (Start, " Expected '[' token!" );
1124
- Parser.Lex ();
1134
+ Parser.Lex (); // Eat '['
1125
1135
1126
1136
unsigned TmpReg = 0 ;
1137
+ SMLoc StartInBrac = Tok.getLoc ();
1127
1138
1128
1139
// Try to handle '[' 'Symbol' ']'
1129
1140
if (getLexer ().is (AsmToken::Identifier)) {
@@ -1148,8 +1159,9 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
1148
1159
Parser.Lex (); // Eat ']'
1149
1160
if (!isParsingInlineAsm ())
1150
1161
return X86Operand::CreateMem (Disp, Start, End, Size);
1151
- return CreateMemForInlineAsm (Disp, Start, End, SizeDirLoc, Size,
1152
- Identifier);
1162
+ return CreateMemForInlineAsm (/* SegReg=*/ 0 , Disp, /* BaseReg=*/ 0 ,
1163
+ /* IndexReg=*/ 0 , /* Scale*/ 1 , Start, End,
1164
+ SizeDirLoc, Size, Identifier);
1153
1165
}
1154
1166
}
1155
1167
@@ -1164,7 +1176,6 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
1164
1176
if (TmpReg)
1165
1177
SM.onRegister (TmpReg);
1166
1178
1167
- const MCExpr *Disp = 0 ;
1168
1179
while (!Done) {
1169
1180
bool UpdateLocLex = true ;
1170
1181
@@ -1182,14 +1193,17 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
1182
1193
return ErrorOperand (Tok.getLoc (), " Unexpected token!" );
1183
1194
}
1184
1195
case AsmToken::Identifier: {
1185
- // This could be a register or a displacement expression.
1186
- SMLoc Loc = Tok.getLoc ();
1187
- if (!ParseRegister (TmpReg, Loc, End)) {
1196
+ // This could be a register or a symbolic displacement.
1197
+ unsigned TmpReg;
1198
+ const MCExpr *Disp = 0 ;
1199
+ AsmToken IdentTok = Parser.getTok ();
1200
+ SMLoc IdentLoc = IdentTok.getLoc ();
1201
+ if (!ParseRegister (TmpReg, IdentLoc, End)) {
1188
1202
SM.onRegister (TmpReg);
1189
1203
UpdateLocLex = false ;
1190
1204
break ;
1191
1205
} else if (!getParser ().parsePrimaryExpr (Disp, End)) {
1192
- SM.onDispExpr ();
1206
+ SM.onDispExpr (Disp, IdentTok. getString () );
1193
1207
UpdateLocLex = false ;
1194
1208
break ;
1195
1209
}
@@ -1215,14 +1229,58 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
1215
1229
Parser.Lex (); // Consume the token.
1216
1230
}
1217
1231
}
1218
- if (isParsingInlineAsm () && Disp && isa<MCSymbolRefExpr>(Disp)) {
1219
- // Remove the '[' and ']' from the IR string.
1220
- InstInfo->AsmRewrites ->push_back (AsmRewrite (AOK_Skip, Start, 1 ));
1221
- InstInfo->AsmRewrites ->push_back (AsmRewrite (AOK_Skip, End, 1 ));
1222
- }
1223
1232
1224
- if (!Disp)
1225
- Disp = MCConstantExpr::Create (SM.getDisp (), getContext ());
1233
+ const MCExpr *Disp;
1234
+ if (const MCExpr *Sym = SM.getSym ()) {
1235
+ Disp = Sym;
1236
+
1237
+ if (isParsingInlineAsm ()) {
1238
+ // Remove the '[' and ']' from the IR string.
1239
+ InstInfo->AsmRewrites ->push_back (AsmRewrite (AOK_Skip, Start, 1 ));
1240
+ InstInfo->AsmRewrites ->push_back (AsmRewrite (AOK_Skip, End, 1 ));
1241
+
1242
+ // If ImmDisp is non-zero, then we parsed a displacement before the
1243
+ // bracketed expression (i.e., ImmDisp [ BaseReg + Scale*IndexReg + Disp ])
1244
+ uint64_t FinalImmDisp = SM.getImmDisp ();
1245
+ if (ImmDisp && ImmDisp != FinalImmDisp) {
1246
+ // If ImmDisp doesn't match the displacement computed by the state machine
1247
+ // then we have an additional displacement in the bracketed expression.
1248
+
1249
+ } else if (FinalImmDisp) {
1250
+ // We have a symbolic and an immediate displacement, but no displacement
1251
+ // before the bracketed expression.
1252
+
1253
+ // Put the immediate displacement before the bracketed expression.
1254
+ InstInfo->AsmRewrites ->push_back (AsmRewrite (AOK_Imm, Start, 0 ,
1255
+ FinalImmDisp));
1256
+ }
1257
+ // Remove all the ImmPrefix rewrites within the brackets.
1258
+ for (SmallVectorImpl<AsmRewrite>::iterator
1259
+ I = InstInfo->AsmRewrites ->begin (),
1260
+ E = InstInfo->AsmRewrites ->end (); I != E; ++I) {
1261
+ if ((*I).Loc .getPointer () < StartInBrac.getPointer ())
1262
+ continue ;
1263
+ if ((*I).Kind == AOK_ImmPrefix)
1264
+ (*I).Kind = AOK_Delete;
1265
+ }
1266
+ StringRef SymName = SM.getSymName ();
1267
+ const char *SymLocPtr = SymName.data ();
1268
+ // Skip everything before the symbol.
1269
+ if (unsigned Len = SymLocPtr - StartInBrac.getPointer ()) {
1270
+ assert (Len > 0 && " Expected a non-negative length." );
1271
+ InstInfo->AsmRewrites ->push_back (AsmRewrite (AOK_Skip, StartInBrac, Len));
1272
+ }
1273
+ // Skip everything after the symbol.
1274
+ if (unsigned Len = End.getPointer () - (SymLocPtr + SymName.size ())) {
1275
+ SMLoc Loc = SMLoc::getFromPointer (SymLocPtr + SymName.size ());
1276
+ assert (Len > 0 && " Expected a non-negative length." );
1277
+ InstInfo->AsmRewrites ->push_back (AsmRewrite (AOK_Skip, Loc, Len));
1278
+ }
1279
+ }
1280
+ } else {
1281
+ // An immediate displacement only.
1282
+ Disp = MCConstantExpr::Create (SM.getImmDisp (), getContext ());
1283
+ }
1226
1284
1227
1285
// Parse the dot operator (e.g., [ebx].foo.bar).
1228
1286
if (Tok.getString ().startswith (" ." )) {
@@ -1238,6 +1296,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
1238
1296
1239
1297
int BaseReg = SM.getBaseReg ();
1240
1298
int IndexReg = SM.getIndexReg ();
1299
+ int Scale = SM.getScale ();
1300
+
1301
+ if (isParsingInlineAsm ())
1302
+ return CreateMemForInlineAsm (SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1303
+ End, SizeDirLoc, Size, SM.getSymName ());
1241
1304
1242
1305
// handle [-42]
1243
1306
if (!BaseReg && !IndexReg) {
@@ -1246,8 +1309,6 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg,
1246
1309
else
1247
1310
return X86Operand::CreateMem (SegReg, Disp, 0 , 0 , 1 , Start, End, Size);
1248
1311
}
1249
-
1250
- int Scale = SM.getScale ();
1251
1312
return X86Operand::CreateMem (SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1252
1313
End, Size);
1253
1314
}
@@ -1345,7 +1406,8 @@ X86Operand *X86AsmParser::ParseIntelMemOperand(unsigned SegReg,
1345
1406
if (X86Operand *Err = ParseIntelVarWithQualifier (Disp, Identifier))
1346
1407
return Err;
1347
1408
1348
- return CreateMemForInlineAsm (Disp, Start, End, Start, Size, Identifier);
1409
+ return CreateMemForInlineAsm (/* SegReg=*/ 0 , Disp, /* BaseReg=*/ 0 ,/* IndexReg=*/ 0 ,
1410
+ /* Scale=*/ 1 , Start, End, Start, Size,Identifier);
1349
1411
}
1350
1412
1351
1413
// / Parse the '.' operator.
0 commit comments