12
12
#include " llvm/ADT/STLExtras.h"
13
13
#include " llvm/ADT/SmallVector.h"
14
14
#include " llvm/ADT/StringRef.h"
15
+ #include " llvm/MC/MCAsmMacro.h"
15
16
#include " llvm/MC/MCContext.h"
16
17
#include " llvm/MC/MCExpr.h"
17
18
#include " llvm/MC/MCInst.h"
@@ -88,6 +89,8 @@ class SparcAsmParser : public MCTargetAsmParser {
88
89
89
90
OperandMatchResultTy parseMembarTag (OperandVector &Operands);
90
91
92
+ OperandMatchResultTy parseASITag (OperandVector &Operands);
93
+
91
94
template <TailRelocKind Kind>
92
95
OperandMatchResultTy parseTailRelocSym (OperandVector &Operands);
93
96
@@ -238,7 +241,8 @@ class SparcOperand : public MCParsedAsmOperand {
238
241
k_Register,
239
242
k_Immediate,
240
243
k_MemoryReg,
241
- k_MemoryImm
244
+ k_MemoryImm,
245
+ k_ASITag
242
246
} Kind;
243
247
244
248
SMLoc StartLoc, EndLoc;
@@ -268,6 +272,7 @@ class SparcOperand : public MCParsedAsmOperand {
268
272
struct RegOp Reg;
269
273
struct ImmOp Imm;
270
274
struct MemOp Mem;
275
+ unsigned ASI;
271
276
};
272
277
273
278
public:
@@ -280,6 +285,7 @@ class SparcOperand : public MCParsedAsmOperand {
280
285
bool isMEMrr () const { return Kind == k_MemoryReg; }
281
286
bool isMEMri () const { return Kind == k_MemoryImm; }
282
287
bool isMembarTag () const { return Kind == k_Immediate; }
288
+ bool isASITag () const { return Kind == k_ASITag; }
283
289
bool isTailRelocSym () const { return Kind == k_Immediate; }
284
290
285
291
bool isCallTarget () const {
@@ -359,6 +365,11 @@ class SparcOperand : public MCParsedAsmOperand {
359
365
return Mem.Off ;
360
366
}
361
367
368
+ unsigned getASITag () const {
369
+ assert ((Kind == k_ASITag) && " Invalid access!" );
370
+ return ASI;
371
+ }
372
+
362
373
// / getStartLoc - Get the location of the first token of this operand.
363
374
SMLoc getStartLoc () const override {
364
375
return StartLoc;
@@ -379,6 +390,9 @@ class SparcOperand : public MCParsedAsmOperand {
379
390
OS << " Mem: " << getMemBase ()
380
391
<< " +" << *getMemOff ()
381
392
<< " \n " ; break ;
393
+ case k_ASITag:
394
+ OS << " ASI tag: " << getASITag () << " \n " ;
395
+ break ;
382
396
}
383
397
}
384
398
@@ -430,6 +444,11 @@ class SparcOperand : public MCParsedAsmOperand {
430
444
addExpr (Inst, Expr);
431
445
}
432
446
447
+ void addASITagOperands (MCInst &Inst, unsigned N) const {
448
+ assert (N == 1 && " Invalid number of operands!" );
449
+ Inst.addOperand (MCOperand::createImm (getASITag ()));
450
+ }
451
+
433
452
void addMembarTagOperands (MCInst &Inst, unsigned N) const {
434
453
assert (N == 1 && " Invalid number of operands!" );
435
454
const MCExpr *Expr = getImm ();
@@ -474,6 +493,15 @@ class SparcOperand : public MCParsedAsmOperand {
474
493
return Op;
475
494
}
476
495
496
+ static std::unique_ptr<SparcOperand> CreateASITag (unsigned Val, SMLoc S,
497
+ SMLoc E) {
498
+ auto Op = std::make_unique<SparcOperand>(k_ASITag);
499
+ Op->ASI = Val;
500
+ Op->StartLoc = S;
501
+ Op->EndLoc = E;
502
+ return Op;
503
+ }
504
+
477
505
static bool MorphToIntPairReg (SparcOperand &Op) {
478
506
unsigned Reg = Op.getReg ();
479
507
assert (Op.Reg .Kind == rk_IntReg);
@@ -1080,6 +1108,29 @@ OperandMatchResultTy SparcAsmParser::parseMembarTag(OperandVector &Operands) {
1080
1108
return MatchOperand_Success;
1081
1109
}
1082
1110
1111
+ OperandMatchResultTy SparcAsmParser::parseASITag (OperandVector &Operands) {
1112
+ SMLoc S = Parser.getTok ().getLoc ();
1113
+ SMLoc E = Parser.getTok ().getEndLoc ();
1114
+ int64_t ASIVal = 0 ;
1115
+
1116
+ if (getParser ().parseAbsoluteExpression (ASIVal)) {
1117
+ Error (
1118
+ S,
1119
+ is64Bit ()
1120
+ ? " malformed ASI tag, must be %asi or a constant integer expression"
1121
+ : " malformed ASI tag, must be a constant integer expression" );
1122
+ return MatchOperand_ParseFail;
1123
+ }
1124
+
1125
+ if (!isUInt<8 >(ASIVal)) {
1126
+ Error (S, " invalid ASI number, must be between 0 and 255" );
1127
+ return MatchOperand_ParseFail;
1128
+ }
1129
+
1130
+ Operands.push_back (SparcOperand::CreateASITag (ASIVal, S, E));
1131
+ return MatchOperand_Success;
1132
+ }
1133
+
1083
1134
OperandMatchResultTy SparcAsmParser::parseCallTarget (OperandVector &Operands) {
1084
1135
SMLoc S = Parser.getTok ().getLoc ();
1085
1136
SMLoc E = SMLoc::getFromPointer (S.getPointer () - 1 );
@@ -1154,13 +1205,49 @@ SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1154
1205
Parser.Lex (); // Eat the ]
1155
1206
1156
1207
// Parse an optional address-space identifier after the address.
1157
- if (getLexer ().is (AsmToken::Integer)) {
1158
- std::unique_ptr<SparcOperand> Op;
1159
- ResTy = parseSparcAsmOperand (Op, false );
1160
- if (ResTy != MatchOperand_Success || !Op)
1161
- return MatchOperand_ParseFail;
1162
- Operands.push_back (std::move (Op));
1208
+ // This will be either an immediate constant expression, or, on 64-bit
1209
+ // processors, the %asi register.
1210
+ if (is64Bit () && getLexer ().is (AsmToken::Percent)) {
1211
+ SMLoc S = Parser.getTok ().getLoc ();
1212
+ Parser.Lex (); // Eat the %.
1213
+ const AsmToken Tok = Parser.getTok ();
1214
+ if (Tok.is (AsmToken::Identifier) && Tok.getString () == " asi" ) {
1215
+ // Here we patch the MEM operand from [base + %g0] into [base + 0]
1216
+ // as memory operations with ASI tag stored in %asi register needs
1217
+ // to use immediate offset. We need to do this because Reg addressing
1218
+ // will be parsed as Reg+G0 initially.
1219
+ // This allows forms such as `ldxa [%o0] %asi, %o0` to parse correctly.
1220
+ SparcOperand &OldMemOp = (SparcOperand &)*Operands[Operands.size () - 2 ];
1221
+ if (OldMemOp.isMEMrr ()) {
1222
+ if (OldMemOp.getMemOffsetReg () != Sparc::G0) {
1223
+ Error (S, " invalid operand for instruction" );
1224
+ return MatchOperand_ParseFail;
1225
+ }
1226
+ Operands[Operands.size () - 2 ] = SparcOperand::MorphToMEMri (
1227
+ OldMemOp.getMemBase (),
1228
+ SparcOperand::CreateImm (MCConstantExpr::create (0 , getContext ()),
1229
+ OldMemOp.getStartLoc (),
1230
+ OldMemOp.getEndLoc ()));
1231
+ }
1232
+ Parser.Lex (); // Eat the identifier.
1233
+ // In this context, we convert the register operand into
1234
+ // a plain "%asi" token since the register access is already
1235
+ // implicit in the instruction definition and encoding.
1236
+ // See LoadASI/StoreASI in SparcInstrInfo.td.
1237
+ Operands.push_back (SparcOperand::CreateToken (" %asi" , S));
1238
+ return MatchOperand_Success;
1239
+ }
1240
+
1241
+ Error (S,
1242
+ " malformed ASI tag, must be %asi or a constant integer expression" );
1243
+ return MatchOperand_ParseFail;
1163
1244
}
1245
+
1246
+ // If we're not at the end of statement and the next token is not a comma,
1247
+ // then it is an immediate ASI value.
1248
+ if (getLexer ().isNot (AsmToken::EndOfStatement) &&
1249
+ getLexer ().isNot (AsmToken::Comma))
1250
+ return parseASITag (Operands);
1164
1251
return MatchOperand_Success;
1165
1252
}
1166
1253
0 commit comments