Coverage Report

Created: 2026-09-14 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/keystone/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
Line
Count
Source
1
//===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#include "MCTargetDesc/SparcMCExpr.h"
11
#include "MCTargetDesc/SparcMCTargetDesc.h"
12
#include "llvm/ADT/STLExtras.h"
13
#include "llvm/MC/MCContext.h"
14
#include "llvm/MC/MCInst.h"
15
#include "llvm/MC/MCObjectFileInfo.h"
16
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
17
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
18
#include "llvm/MC/MCRegisterInfo.h"
19
#include "llvm/MC/MCStreamer.h"
20
#include "llvm/MC/MCSubtargetInfo.h"
21
#include "llvm/MC/MCSymbol.h"
22
#include "llvm/Support/TargetRegistry.h"
23
24
#include "keystone/sparc.h"
25
26
using namespace llvm_ks;
27
28
// The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target
29
// namespace. But SPARC backend uses "SP" as its namespace.
30
namespace llvm_ks {
31
  namespace Sparc {
32
    using namespace SP;
33
  }
34
}
35
36
namespace {
37
class SparcOperand;
38
class SparcAsmParser : public MCTargetAsmParser {
39
40
  MCAsmParser &Parser;
41
42
  /// @name Auto-generated Match Functions
43
  /// {
44
45
#define GET_ASSEMBLER_HEADER
46
#include "SparcGenAsmMatcher.inc"
47
48
  /// }
49
50
  // public interface of the MCTargetAsmParser.
51
  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
52
                               OperandVector &Operands, MCStreamer &Out,
53
                               uint64_t &ErrorInfo,
54
                               bool MatchingInlineAsm, unsigned int &ErrorCode, uint64_t &Address) override;
55
  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc, unsigned int &ErrorCode) override;
56
  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
57
                        SMLoc NameLoc, OperandVector &Operands, unsigned int &ErrorCode) override;
58
  bool ParseDirective(AsmToken DirectiveID) override;
59
60
  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
61
                                      unsigned Kind) override;
62
63
  // Custom parse functions for Sparc specific operands.
64
  OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
65
66
  OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
67
68
  OperandMatchResultTy
69
  parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand,
70
                       bool isCall = false);
71
72
  OperandMatchResultTy parseBranchModifiers(OperandVector &Operands);
73
74
  // Helper function for dealing with %lo / %hi in PIC mode.
75
  const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK,
76
                                         const MCExpr *subExpr);
77
78
  // returns true if Tok is matched to a register and returns register in RegNo.
79
  bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo,
80
                         unsigned &RegKind);
81
82
  bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
83
  bool parseDirectiveWord(unsigned Size, SMLoc L);
84
85
1.18M
  bool is64Bit() const {
86
1.18M
    return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
87
1.18M
  }
88
89
  void expandSET(MCInst &Inst, SMLoc IDLoc,
90
                 SmallVectorImpl<MCInst> &Instructions);
91
92
public:
93
  SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
94
                const MCInstrInfo &MII,
95
                const MCTargetOptions &Options)
96
14.4k
      : MCTargetAsmParser(Options, sti), Parser(parser) {
97
    // Initialize the set of available features.
98
14.4k
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
99
14.4k
  }
100
101
};
102
103
  static const MCPhysReg IntRegs[32] = {
104
    Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
105
    Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
106
    Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
107
    Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
108
    Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
109
    Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
110
    Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
111
    Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
112
113
  static const MCPhysReg FloatRegs[32] = {
114
    Sparc::F0,  Sparc::F1,  Sparc::F2,  Sparc::F3,
115
    Sparc::F4,  Sparc::F5,  Sparc::F6,  Sparc::F7,
116
    Sparc::F8,  Sparc::F9,  Sparc::F10, Sparc::F11,
117
    Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15,
118
    Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19,
119
    Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23,
120
    Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27,
121
    Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 };
122
123
  static const MCPhysReg DoubleRegs[32] = {
124
    Sparc::D0,  Sparc::D1,  Sparc::D2,  Sparc::D3,
125
    Sparc::D4,  Sparc::D5,  Sparc::D6,  Sparc::D7,
126
    Sparc::D8,  Sparc::D7,  Sparc::D8,  Sparc::D9,
127
    Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
128
    Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
129
    Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
130
    Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
131
    Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
132
133
  static const MCPhysReg QuadFPRegs[32] = {
134
    Sparc::Q0,  Sparc::Q1,  Sparc::Q2,  Sparc::Q3,
135
    Sparc::Q4,  Sparc::Q5,  Sparc::Q6,  Sparc::Q7,
136
    Sparc::Q8,  Sparc::Q9,  Sparc::Q10, Sparc::Q11,
137
    Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
138
139
  static const MCPhysReg ASRRegs[32] = {
140
    SP::Y,     SP::ASR1,  SP::ASR2,  SP::ASR3,
141
    SP::ASR4,  SP::ASR5,  SP::ASR6, SP::ASR7,
142
    SP::ASR8,  SP::ASR9,  SP::ASR10, SP::ASR11,
143
    SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
144
    SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
145
    SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
146
    SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
147
    SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
148
149
  static const MCPhysReg IntPairRegs[] = {
150
    Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
151
    Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
152
    Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
153
    Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
154
155
/// SparcOperand - Instances of this class represent a parsed Sparc machine
156
/// instruction.
157
class SparcOperand : public MCParsedAsmOperand {
158
public:
159
  enum RegisterKind {
160
    rk_None,
161
    rk_IntReg,
162
    rk_IntPairReg,
163
    rk_FloatReg,
164
    rk_DoubleReg,
165
    rk_QuadReg,
166
    rk_Special,
167
  };
168
169
private:
170
  enum KindTy {
171
    k_Token,
172
    k_Register,
173
    k_Immediate,
174
    k_MemoryReg,
175
    k_MemoryImm
176
  } Kind;
177
178
  SMLoc StartLoc, EndLoc;
179
180
  struct Token {
181
    const char *Data;
182
    unsigned Length;
183
  };
184
185
  struct RegOp {
186
    unsigned RegNum;
187
    RegisterKind Kind;
188
  };
189
190
  struct ImmOp {
191
    const MCExpr *Val;
192
  };
193
194
  struct MemOp {
195
    unsigned Base;
196
    unsigned OffsetReg;
197
    const MCExpr *Off;
198
  };
199
200
  union {
201
    struct Token Tok;
202
    struct RegOp Reg;
203
    struct ImmOp Imm;
204
    struct MemOp Mem;
205
  };
206
public:
207
220k
  SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
208
209
13.6k
  bool isToken() const override { return Kind == k_Token; }
210
4.99k
  bool isReg() const override { return Kind == k_Register; }
211
7.18k
  bool isImm() const override { return Kind == k_Immediate; }
212
0
  bool isMem() const override { return isMEMrr() || isMEMri(); }
213
2.29k
  bool isMEMrr() const { return Kind == k_MemoryReg; }
214
2.32k
  bool isMEMri() const { return Kind == k_MemoryImm; }
215
216
5.40k
  bool isIntReg() const {
217
5.40k
    return (Kind == k_Register && Reg.Kind == rk_IntReg);
218
5.40k
  }
219
220
11
  bool isFloatReg() const {
221
11
    return (Kind == k_Register && Reg.Kind == rk_FloatReg);
222
11
  }
223
224
5.41k
  bool isFloatOrDoubleReg() const {
225
5.41k
    return (Kind == k_Register && (Reg.Kind == rk_FloatReg
226
866
                                   || Reg.Kind == rk_DoubleReg));
227
5.41k
  }
228
229
230
11.7k
  StringRef getToken() const {
231
11.7k
    assert(Kind == k_Token && "Invalid access!");
232
11.7k
    return StringRef(Tok.Data, Tok.Length);
233
11.7k
  }
234
235
1.37k
  unsigned getReg() const override {
236
1.37k
    assert((Kind == k_Register) && "Invalid access!");
237
1.37k
    return Reg.RegNum;
238
1.37k
  }
239
240
6.67k
  const MCExpr *getImm() const {
241
6.67k
    assert((Kind == k_Immediate) && "Invalid access!");
242
6.67k
    return Imm.Val;
243
6.67k
  }
244
245
1.40k
  unsigned getMemBase() const {
246
1.40k
    assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
247
1.40k
    return Mem.Base;
248
1.40k
  }
249
250
2.74k
  unsigned getMemOffsetReg() const {
251
2.74k
    assert((Kind == k_MemoryReg) && "Invalid access!");
252
2.74k
    return Mem.OffsetReg;
253
2.74k
  }
254
255
27
  const MCExpr *getMemOff() const {
256
27
    assert((Kind == k_MemoryImm) && "Invalid access!");
257
27
    return Mem.Off;
258
27
  }
259
260
  /// getStartLoc - Get the location of the first token of this operand.
261
0
  SMLoc getStartLoc() const override {
262
0
    return StartLoc;
263
0
  }
264
  /// getEndLoc - Get the location of the last token of this operand.
265
0
  SMLoc getEndLoc() const override {
266
0
    return EndLoc;
267
0
  }
268
269
0
  void print(raw_ostream &OS) const override {
270
0
    switch (Kind) {
271
0
    case k_Token:     OS << "Token: " << getToken() << "\n"; break;
272
0
    case k_Register:  OS << "Reg: #" << getReg() << "\n"; break;
273
0
    case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
274
0
    case k_MemoryReg: OS << "Mem: " << getMemBase() << "+"
275
0
                         << getMemOffsetReg() << "\n"; break;
276
0
    case k_MemoryImm: assert(getMemOff() != nullptr);
277
0
      OS << "Mem: " << getMemBase()
278
0
         << "+" << *getMemOff()
279
0
         << "\n"; break;
280
0
    }
281
0
  }
282
283
21
  void addRegOperands(MCInst &Inst, unsigned N) const {
284
21
    assert(N == 1 && "Invalid number of operands!");
285
21
    Inst.addOperand(MCOperand::createReg(getReg()));
286
21
  }
287
288
6.63k
  void addImmOperands(MCInst &Inst, unsigned N) const {
289
6.63k
    assert(N == 1 && "Invalid number of operands!");
290
6.63k
    const MCExpr *Expr = getImm();
291
6.63k
    addExpr(Inst, Expr);
292
6.63k
  }
293
294
6.65k
  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
295
    // Add as immediate when possible.  Null MCExpr = 0.
296
6.65k
    if (!Expr)
297
0
      Inst.addOperand(MCOperand::createImm(0));
298
6.65k
    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
299
340
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
300
6.31k
    else
301
6.31k
      Inst.addOperand(MCOperand::createExpr(Expr));
302
6.65k
  }
303
304
1.37k
  void addMEMrrOperands(MCInst &Inst, unsigned N) const {
305
1.37k
    assert(N == 2 && "Invalid number of operands!");
306
307
1.37k
    Inst.addOperand(MCOperand::createReg(getMemBase()));
308
309
1.37k
    assert(getMemOffsetReg() != 0 && "Invalid offset");
310
1.37k
    Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
311
1.37k
  }
312
313
27
  void addMEMriOperands(MCInst &Inst, unsigned N) const {
314
27
    assert(N == 2 && "Invalid number of operands!");
315
316
27
    Inst.addOperand(MCOperand::createReg(getMemBase()));
317
318
27
    const MCExpr *Expr = getMemOff();
319
27
    addExpr(Inst, Expr);
320
27
  }
321
322
188k
  static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
323
188k
    auto Op = make_unique<SparcOperand>(k_Token);
324
188k
    Op->Tok.Data = Str.data();
325
188k
    Op->Tok.Length = Str.size();
326
188k
    Op->StartLoc = S;
327
188k
    Op->EndLoc = S;
328
188k
    return Op;
329
188k
  }
330
331
  static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
332
402
                                                 SMLoc S, SMLoc E) {
333
402
    auto Op = make_unique<SparcOperand>(k_Register);
334
402
    Op->Reg.RegNum = RegNum;
335
402
    Op->Reg.Kind   = (SparcOperand::RegisterKind)Kind;
336
402
    Op->StartLoc = S;
337
402
    Op->EndLoc = E;
338
402
    return Op;
339
402
  }
340
341
  static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
342
29.6k
                                                 SMLoc E) {
343
29.6k
    auto Op = make_unique<SparcOperand>(k_Immediate);
344
29.6k
    Op->Imm.Val = Val;
345
29.6k
    Op->StartLoc = S;
346
29.6k
    Op->EndLoc = E;
347
29.6k
    return Op;
348
29.6k
  }
349
350
21
  static bool MorphToIntPairReg(SparcOperand &Op) {
351
21
    unsigned Reg = Op.getReg();
352
21
    assert(Op.Reg.Kind == rk_IntReg);
353
21
    unsigned regIdx = 32;
354
21
    if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
355
5
      regIdx = Reg - Sparc::G0;
356
16
    else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
357
8
      regIdx = Reg - Sparc::O0 + 8;
358
8
    else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
359
4
      regIdx = Reg - Sparc::L0 + 16;
360
4
    else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
361
4
      regIdx = Reg - Sparc::I0 + 24;
362
21
    if (regIdx % 2 || regIdx > 31)
363
13
      return false;
364
8
    Op.Reg.RegNum = IntPairRegs[regIdx / 2];
365
8
    Op.Reg.Kind = rk_IntPairReg;
366
8
    return true;
367
21
  }
368
369
11
  static bool MorphToDoubleReg(SparcOperand &Op) {
370
11
    unsigned Reg = Op.getReg();
371
11
    assert(Op.Reg.Kind == rk_FloatReg);
372
11
    unsigned regIdx = Reg - Sparc::F0;
373
11
    if (regIdx % 2 || regIdx > 31)
374
3
      return false;
375
8
    Op.Reg.RegNum = DoubleRegs[regIdx / 2];
376
8
    Op.Reg.Kind = rk_DoubleReg;
377
8
    return true;
378
11
  }
379
380
15
  static bool MorphToQuadReg(SparcOperand &Op) {
381
15
    unsigned Reg = Op.getReg();
382
15
    unsigned regIdx = 0;
383
15
    switch (Op.Reg.Kind) {
384
0
    default: llvm_unreachable("Unexpected register kind!");
385
9
    case rk_FloatReg:
386
9
      regIdx = Reg - Sparc::F0;
387
9
      if (regIdx % 4 || regIdx > 31)
388
3
        return false;
389
6
      Reg = QuadFPRegs[regIdx / 4];
390
6
      break;
391
6
    case rk_DoubleReg:
392
6
      regIdx =  Reg - Sparc::D0;
393
6
      if (regIdx % 2 || regIdx > 31)
394
5
        return false;
395
1
      Reg = QuadFPRegs[regIdx / 2];
396
1
      break;
397
15
    }
398
7
    Op.Reg.RegNum = Reg;
399
7
    Op.Reg.Kind = rk_QuadReg;
400
7
    return true;
401
15
  }
402
403
  static std::unique_ptr<SparcOperand>
404
1
  MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) {
405
1
    unsigned offsetReg = Op->getReg();
406
1
    Op->Kind = k_MemoryReg;
407
1
    Op->Mem.Base = Base;
408
1
    Op->Mem.OffsetReg = offsetReg;
409
1
    Op->Mem.Off = nullptr;
410
1
    return Op;
411
1
  }
412
413
  static std::unique_ptr<SparcOperand>
414
1.93k
  CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
415
1.93k
    auto Op = make_unique<SparcOperand>(k_MemoryReg);
416
1.93k
    Op->Mem.Base = Base;
417
1.93k
    Op->Mem.OffsetReg = Sparc::G0;  // always 0
418
1.93k
    Op->Mem.Off = nullptr;
419
1.93k
    Op->StartLoc = S;
420
1.93k
    Op->EndLoc = E;
421
1.93k
    return Op;
422
1.93k
  }
423
424
  static std::unique_ptr<SparcOperand>
425
38
  MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) {
426
38
    const MCExpr *Imm  = Op->getImm();
427
38
    Op->Kind = k_MemoryImm;
428
38
    Op->Mem.Base = Base;
429
38
    Op->Mem.OffsetReg = 0;
430
38
    Op->Mem.Off = Imm;
431
38
    return Op;
432
38
  }
433
};
434
435
} // end namespace
436
437
void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
438
0
                               SmallVectorImpl<MCInst> &Instructions) {
439
0
  MCOperand MCRegOp = Inst.getOperand(0);
440
0
  MCOperand MCValOp = Inst.getOperand(1);
441
0
  assert(MCRegOp.isReg());
442
0
  assert(MCValOp.isImm() || MCValOp.isExpr());
443
444
  // the imm operand can be either an expression or an immediate.
445
0
  bool IsImm = Inst.getOperand(1).isImm();
446
0
  int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
447
448
  // Allow either a signed or unsigned 32-bit immediate.
449
0
  if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
450
0
    Error(IDLoc, "set: argument must be between -2147483648 and 4294967295");
451
0
    return;
452
0
  }
453
454
  // If the value was expressed as a large unsigned number, that's ok.
455
  // We want to see if it "looks like" a small signed number.
456
0
  int32_t ImmValue = RawImmValue;
457
  // For 'set' you can't use 'or' with a negative operand on V9 because
458
  // that would splat the sign bit across the upper half of the destination
459
  // register, whereas 'set' is defined to zero the high 32 bits.
460
0
  bool IsEffectivelyImm13 =
461
0
      IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
462
0
  const MCExpr *ValExpr;
463
0
  if (IsImm)
464
0
    ValExpr = MCConstantExpr::create(ImmValue, getContext());
465
0
  else
466
0
    ValExpr = MCValOp.getExpr();
467
468
0
  MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
469
470
  // If not just a signed imm13 value, then either we use a 'sethi' with a
471
  // following 'or', or a 'sethi' by itself if there are no more 1 bits.
472
  // In either case, start with the 'sethi'.
473
0
  if (!IsEffectivelyImm13) {
474
0
    MCInst TmpInst;
475
0
    const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
476
0
    TmpInst.setLoc(IDLoc);
477
0
    TmpInst.setOpcode(SP::SETHIi);
478
0
    TmpInst.addOperand(MCRegOp);
479
0
    TmpInst.addOperand(MCOperand::createExpr(Expr));
480
0
    Instructions.push_back(TmpInst);
481
0
    PrevReg = MCRegOp;
482
0
  }
483
484
  // The low bits require touching in 3 cases:
485
  // * A non-immediate value will always require both instructions.
486
  // * An effectively imm13 value needs only an 'or' instruction.
487
  // * Otherwise, an immediate that is not effectively imm13 requires the
488
  //   'or' only if bits remain after clearing the 22 bits that 'sethi' set.
489
  // If the low bits are known zeros, there's nothing to do.
490
  // In the second case, and only in that case, must we NOT clear
491
  // bits of the immediate value via the %lo() assembler function.
492
  // Note also, the 'or' instruction doesn't mind a large value in the case
493
  // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
494
0
  if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
495
0
    MCInst TmpInst;
496
0
    const MCExpr *Expr;
497
0
    if (IsEffectivelyImm13)
498
0
      Expr = ValExpr;
499
0
    else
500
0
      Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
501
0
    TmpInst.setLoc(IDLoc);
502
0
    TmpInst.setOpcode(SP::ORri);
503
0
    TmpInst.addOperand(MCRegOp);
504
0
    TmpInst.addOperand(PrevReg);
505
0
    TmpInst.addOperand(MCOperand::createExpr(Expr));
506
0
    Instructions.push_back(TmpInst);
507
0
  }
508
0
}
509
510
bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
511
                                             OperandVector &Operands,
512
                                             MCStreamer &Out,
513
                                             uint64_t &ErrorInfo,
514
                                             bool MatchingInlineAsm, unsigned int &ErrorCode, uint64_t &Address)
515
11.2k
{
516
11.2k
  MCInst Inst(Address);
517
11.2k
  SmallVector<MCInst, 8> Instructions;
518
11.2k
  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
519
11.2k
                                              MatchingInlineAsm);
520
11.2k
  switch (MatchResult) {
521
8.32k
  case Match_Success: {
522
8.32k
    switch (Inst.getOpcode()) {
523
8.32k
    default:
524
8.32k
      Inst.setLoc(IDLoc);
525
8.32k
      Instructions.push_back(Inst);
526
8.32k
      break;
527
0
    case SP::SET:
528
0
      expandSET(Inst, IDLoc, Instructions);
529
0
      break;
530
8.32k
    }
531
532
8.32k
    for (MCInst &I : Instructions) {
533
8.32k
      Out.EmitInstruction(I, getSTI(), ErrorCode);
534
8.32k
    }
535
8.32k
    if (ErrorCode == 0) {
536
8.32k
        Address = Inst.getAddress(); // Keystone update address
537
8.32k
        return false;
538
8.32k
    } else
539
0
        return true;
540
8.32k
  }
541
542
1
  case Match_MissingFeature:
543
    // return Error(IDLoc,
544
    //              "instruction requires a CPU feature not currently enabled");
545
1
    ErrorCode = KS_ERR_ASM_SPARC_MISSINGFEATURE;
546
1
    return true;
547
548
1.24k
  case Match_InvalidOperand: {
549
#if 0
550
    SMLoc ErrorLoc = IDLoc;
551
    if (ErrorInfo != ~0ULL) {
552
      if (ErrorInfo >= Operands.size())
553
        return Error(IDLoc, "too few operands for instruction");
554
555
      ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
556
      if (ErrorLoc == SMLoc())
557
        ErrorLoc = IDLoc;
558
    }
559
560
    return Error(ErrorLoc, "invalid operand for instruction");
561
#endif
562
1.24k
    ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
563
1.24k
    return true;
564
8.32k
  }
565
1.68k
  case Match_MnemonicFail:
566
    // return Error(IDLoc, "invalid instruction mnemonic");
567
1.68k
    ErrorCode = KS_ERR_ASM_SPARC_MNEMONICFAIL;
568
1.68k
    return true;
569
11.2k
  }
570
11.2k
  llvm_unreachable("Implement any new match types added!");
571
11.2k
}
572
573
bool SparcAsmParser::
574
ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc, unsigned int &ErrorCode)
575
40.2k
{
576
40.2k
  const AsmToken &Tok = Parser.getTok();
577
40.2k
  StartLoc = Tok.getLoc();
578
40.2k
  EndLoc = Tok.getEndLoc();
579
40.2k
  RegNo = 0;
580
40.2k
  if (getLexer().getKind() != AsmToken::Percent)
581
35.3k
    return false;
582
4.92k
  Parser.Lex();
583
4.92k
  unsigned regKind = SparcOperand::rk_None;
584
4.92k
  if (matchRegisterName(Tok, RegNo, regKind)) {
585
983
    Parser.Lex();
586
983
    return false;
587
983
  }
588
589
3.94k
  return Error(StartLoc, "invalid register name");
590
4.92k
}
591
592
static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
593
                                 unsigned VariantID);
594
595
bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info,
596
                                      StringRef Name, SMLoc NameLoc,
597
                                      OperandVector &Operands, unsigned int &ErrorCode)
598
158k
{
599
  // First operand in MCInst is instruction mnemonic.
600
158k
  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
601
602
  // apply mnemonic aliases, if any, so that we can parse operands correctly.
603
158k
  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
604
605
158k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
606
    // Read the first operand.
607
157k
    if (getLexer().is(AsmToken::Comma)) {
608
367
      if (parseBranchModifiers(Operands) != MatchOperand_Success) {
609
        // SMLoc Loc = getLexer().getLoc();
610
67
        Parser.eatToEndOfStatement();
611
        // return Error(Loc, "unexpected token");
612
67
        ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
613
67
        return true;
614
67
      }
615
367
    }
616
157k
    if (parseOperand(Operands, Name) != MatchOperand_Success) {
617
      // SMLoc Loc = getLexer().getLoc();
618
143k
      Parser.eatToEndOfStatement();
619
      // return Error(Loc, "unexpected token");
620
143k
      ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
621
143k
      return true;
622
143k
    }
623
624
31.9k
    while (getLexer().is(AsmToken::Comma)) {
625
19.4k
      Parser.Lex(); // Eat the comma.
626
      // Parse and remember the operand.
627
19.4k
      if (parseOperand(Operands, Name) != MatchOperand_Success) {
628
        // SMLoc Loc = getLexer().getLoc();
629
1.58k
        Parser.eatToEndOfStatement();
630
        // return Error(Loc, "unexpected token");
631
1.58k
        ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
632
1.58k
        return true;
633
1.58k
      }
634
19.4k
    }
635
14.0k
  }
636
13.5k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
637
    // SMLoc Loc = getLexer().getLoc();
638
2.25k
    Parser.eatToEndOfStatement();
639
    // return Error(Loc, "unexpected token");
640
2.25k
    ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
641
2.25k
    return true;
642
2.25k
  }
643
11.2k
  Parser.Lex(); // Consume the EndOfStatement.
644
11.2k
  return false;
645
13.5k
}
646
647
bool SparcAsmParser::
648
ParseDirective(AsmToken DirectiveID)
649
1.20M
{
650
1.20M
  StringRef IDVal = DirectiveID.getString();
651
652
1.20M
  if (IDVal == ".byte")
653
909
    return parseDirectiveWord(1, DirectiveID.getLoc());
654
655
1.19M
  if (IDVal == ".half")
656
38
    return parseDirectiveWord(2, DirectiveID.getLoc());
657
658
1.19M
  if (IDVal == ".word")
659
17.0k
    return parseDirectiveWord(4, DirectiveID.getLoc());
660
661
1.18M
  if (IDVal == ".nword")
662
26
    return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc());
663
664
1.18M
  if (is64Bit() && IDVal == ".xword")
665
0
    return parseDirectiveWord(8, DirectiveID.getLoc());
666
667
1.18M
  if (IDVal == ".register") {
668
    // For now, ignore .register directive.
669
1
    Parser.eatToEndOfStatement();
670
1
    return false;
671
1
  }
672
673
  // Let the MC layer to handle other directives.
674
1.18M
  return true;
675
1.18M
}
676
677
17.9k
bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
678
17.9k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
679
50.2k
    for (;;) {
680
50.2k
      const MCExpr *Value;
681
50.2k
      if (getParser().parseExpression(Value))
682
423
        return true;
683
684
49.8k
      getParser().getStreamer().EmitValue(Value, Size);
685
686
49.8k
      if (getLexer().is(AsmToken::EndOfStatement))
687
14.6k
        break;
688
689
      // FIXME: Improve diagnostic.
690
35.1k
      if (getLexer().isNot(AsmToken::Comma))
691
954
        return Error(L, "unexpected token in directive");
692
34.2k
      Parser.Lex();
693
34.2k
    }
694
15.9k
  }
695
16.6k
  Parser.Lex();
696
16.6k
  return false;
697
17.9k
}
698
699
SparcAsmParser::OperandMatchResultTy
700
40.2k
SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
701
702
40.2k
  SMLoc S, E;
703
40.2k
  unsigned BaseReg = 0;
704
40.2k
  unsigned int ErrorCode;
705
706
40.2k
  if (ParseRegister(BaseReg, S, E, ErrorCode)) {
707
3.94k
    return MatchOperand_NoMatch;
708
3.94k
  }
709
710
36.3k
  switch (getLexer().getKind()) {
711
671
  default: return MatchOperand_NoMatch;
712
713
193
  case AsmToken::Comma:
714
506
  case AsmToken::RBrac:
715
1.93k
  case AsmToken::EndOfStatement:
716
1.93k
    Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
717
1.93k
    return MatchOperand_Success;
718
719
25
  case AsmToken:: Plus:
720
25
    Parser.Lex(); // Eat the '+'
721
25
    break;
722
33.6k
  case AsmToken::Minus:
723
33.6k
    break;
724
36.3k
  }
725
726
33.7k
  std::unique_ptr<SparcOperand> Offset;
727
33.7k
  OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
728
33.7k
  if (ResTy != MatchOperand_Success || !Offset)
729
33.6k
    return MatchOperand_NoMatch;
730
731
39
  Operands.push_back(
732
39
      Offset->isImm() ? SparcOperand::MorphToMEMri(BaseReg, std::move(Offset))
733
39
                      : SparcOperand::MorphToMEMrr(BaseReg, std::move(Offset)));
734
735
39
  return MatchOperand_Success;
736
33.7k
}
737
738
SparcAsmParser::OperandMatchResultTy
739
177k
SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
740
741
177k
  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
742
743
  // If there wasn't a custom match, try the generic matcher below. Otherwise,
744
  // there was a match, but an error occurred, in which case, just return that
745
  // the operand parsing failed.
746
177k
  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
747
1.63k
    return ResTy;
748
749
175k
  if (getLexer().is(AsmToken::LBrac)) {
750
    // Memory operand
751
29.3k
    Operands.push_back(SparcOperand::CreateToken("[",
752
29.3k
                                                 Parser.getTok().getLoc()));
753
29.3k
    Parser.Lex(); // Eat the [
754
755
29.3k
    if (Mnemonic == "cas" || Mnemonic == "casx") {
756
3
      SMLoc S = Parser.getTok().getLoc();
757
3
      if (getLexer().getKind() != AsmToken::Percent)
758
1
        return MatchOperand_NoMatch;
759
2
      Parser.Lex(); // eat %
760
761
2
      unsigned RegNo, RegKind;
762
2
      if (!matchRegisterName(Parser.getTok(), RegNo, RegKind))
763
1
        return MatchOperand_NoMatch;
764
765
1
      Parser.Lex(); // Eat the identifier token.
766
1
      SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
767
1
      Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E));
768
1
      ResTy = MatchOperand_Success;
769
29.3k
    } else {
770
29.3k
      ResTy = parseMEMOperand(Operands);
771
29.3k
    }
772
773
29.3k
    if (ResTy != MatchOperand_Success)
774
28.9k
      return ResTy;
775
776
337
    if (!getLexer().is(AsmToken::RBrac))
777
32
      return MatchOperand_ParseFail;
778
779
305
    Operands.push_back(SparcOperand::CreateToken("]",
780
305
                                                 Parser.getTok().getLoc()));
781
305
    Parser.Lex(); // Eat the ]
782
783
    // Parse an optional address-space identifier after the address.
784
305
    if (getLexer().is(AsmToken::Integer)) {
785
28
      std::unique_ptr<SparcOperand> Op;
786
28
      ResTy = parseSparcAsmOperand(Op, false);
787
28
      if (ResTy != MatchOperand_Success || !Op)
788
1
        return MatchOperand_ParseFail;
789
27
      Operands.push_back(std::move(Op));
790
27
    }
791
304
    return MatchOperand_Success;
792
305
  }
793
794
146k
  std::unique_ptr<SparcOperand> Op;
795
796
146k
  ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
797
146k
  if (ResTy != MatchOperand_Success || !Op)
798
116k
    return MatchOperand_ParseFail;
799
800
  // Push the parsed operand into the list of operands
801
30.0k
  Operands.push_back(std::move(Op));
802
803
30.0k
  return MatchOperand_Success;
804
146k
}
805
806
SparcAsmParser::OperandMatchResultTy
807
SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
808
179k
                                     bool isCall) {
809
810
179k
  SMLoc S = Parser.getTok().getLoc();
811
179k
  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
812
179k
  const MCExpr *EVal;
813
814
179k
  Op = nullptr;
815
179k
  switch (getLexer().getKind()) {
816
1.15k
  default:  break;
817
818
1.50k
  case AsmToken::Percent:
819
1.50k
    Parser.Lex(); // Eat the '%'.
820
1.50k
    unsigned RegNo;
821
1.50k
    unsigned RegKind;
822
1.50k
    if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
823
476
      StringRef name = Parser.getTok().getString();
824
476
      Parser.Lex(); // Eat the identifier token.
825
476
      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
826
476
      switch (RegNo) {
827
401
      default:
828
401
        Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
829
401
        break;
830
15
      case Sparc::PSR:
831
15
        Op = SparcOperand::CreateToken("%psr", S);
832
15
        break;
833
25
      case Sparc::FSR:
834
25
        Op = SparcOperand::CreateToken("%fsr", S);
835
25
        break;
836
19
      case Sparc::WIM:
837
19
        Op = SparcOperand::CreateToken("%wim", S);
838
19
        break;
839
4
      case Sparc::TBR:
840
4
        Op = SparcOperand::CreateToken("%tbr", S);
841
4
        break;
842
12
      case Sparc::ICC:
843
12
        if (name == "xcc")
844
8
          Op = SparcOperand::CreateToken("%xcc", S);
845
4
        else
846
4
          Op = SparcOperand::CreateToken("%icc", S);
847
12
        break;
848
476
      }
849
476
      break;
850
476
    }
851
1.02k
    if (matchSparcAsmModifiers(EVal, E)) {
852
14
      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
853
14
      Op = SparcOperand::CreateImm(EVal, S, E);
854
14
    }
855
1.02k
    break;
856
857
94.8k
  case AsmToken::Minus:
858
99.5k
  case AsmToken::Integer:
859
150k
  case AsmToken::LParen:
860
156k
  case AsmToken::Dot:
861
156k
    if (!getParser().parseExpression(EVal, E))
862
8.67k
      Op = SparcOperand::CreateImm(EVal, S, E);
863
156k
    break;
864
865
20.9k
  case AsmToken::Identifier: {
866
20.9k
    StringRef Identifier;
867
20.9k
    if (!getParser().parseIdentifier(Identifier)) {
868
20.9k
      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
869
20.9k
      MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
870
871
20.9k
      const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
872
20.9k
                                                  getContext());
873
#if 0
874
      if (isCall &&
875
          getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
876
        Res = SparcMCExpr::create(SparcMCExpr::VK_Sparc_WPLT30, Res,
877
                                  getContext());
878
#endif
879
20.9k
      Op = SparcOperand::CreateImm(Res, S, E);
880
20.9k
    }
881
20.9k
    break;
882
150k
  }
883
179k
  }
884
179k
  return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
885
179k
}
886
887
SparcAsmParser::OperandMatchResultTy
888
367
SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
889
890
  // parse (,a|,pn|,pt)+
891
892
832
  while (getLexer().is(AsmToken::Comma)) {
893
894
532
    Parser.Lex(); // Eat the comma
895
896
532
    if (!getLexer().is(AsmToken::Identifier))
897
67
      return MatchOperand_ParseFail;
898
465
    StringRef modName = Parser.getTok().getString();
899
465
    if (modName == "a" || modName == "pn" || modName == "pt") {
900
234
      Operands.push_back(SparcOperand::CreateToken(modName,
901
234
                                                   Parser.getTok().getLoc()));
902
234
      Parser.Lex(); // eat the identifier.
903
234
    }
904
465
  }
905
300
  return MatchOperand_Success;
906
367
}
907
908
bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
909
                                       unsigned &RegNo,
910
                                       unsigned &RegKind)
911
6.42k
{
912
6.42k
  int64_t intVal = 0;
913
6.42k
  RegNo = 0;
914
6.42k
  RegKind = SparcOperand::rk_None;
915
6.42k
  if (Tok.is(AsmToken::Identifier)) {
916
5.08k
    StringRef name = Tok.getString();
917
918
    // %fp
919
5.08k
    if (name.equals("fp")) {
920
4
      RegNo = Sparc::I6;
921
4
      RegKind = SparcOperand::rk_IntReg;
922
4
      return true;
923
4
    }
924
    // %sp
925
5.07k
    if (name.equals("sp")) {
926
1
      RegNo = Sparc::O6;
927
1
      RegKind = SparcOperand::rk_IntReg;
928
1
      return true;
929
1
    }
930
931
5.07k
    if (name.equals("y")) {
932
25
      RegNo = Sparc::Y;
933
25
      RegKind = SparcOperand::rk_Special;
934
25
      return true;
935
25
    }
936
937
5.05k
    if (name.substr(0, 3).equals_lower("asr")
938
59
        && !name.substr(3).getAsInteger(10, intVal)
939
50
        && intVal > 0 && intVal < 32) {
940
4
      RegNo = ASRRegs[intVal];
941
4
      RegKind = SparcOperand::rk_Special;
942
4
      return true;
943
4
    }
944
945
    // %fprs is an alias of %asr6.
946
5.04k
    if (name.equals("fprs")) {
947
5
      RegNo = ASRRegs[6];
948
5
      RegKind = SparcOperand::rk_Special;
949
5
      return true;
950
5
    }
951
952
5.04k
    if (name.equals("icc")) {
953
4
      RegNo = Sparc::ICC;
954
4
      RegKind = SparcOperand::rk_Special;
955
4
      return true;
956
4
    }
957
958
5.03k
    if (name.equals("psr")) {
959
16
      RegNo = Sparc::PSR;
960
16
      RegKind = SparcOperand::rk_Special;
961
16
      return true;
962
16
    }
963
964
5.02k
    if (name.equals("fsr")) {
965
593
      RegNo = Sparc::FSR;
966
593
      RegKind = SparcOperand::rk_Special;
967
593
      return true;
968
593
    }
969
970
4.43k
    if (name.equals("wim")) {
971
19
      RegNo = Sparc::WIM;
972
19
      RegKind = SparcOperand::rk_Special;
973
19
      return true;
974
19
    }
975
976
4.41k
    if (name.equals("tbr")) {
977
4
      RegNo = Sparc::TBR;
978
4
      RegKind = SparcOperand::rk_Special;
979
4
      return true;
980
4
    }
981
982
4.40k
    if (name.equals("xcc")) {
983
      // FIXME:: check 64bit.
984
8
      RegNo = Sparc::ICC;
985
8
      RegKind = SparcOperand::rk_Special;
986
8
      return true;
987
8
    }
988
989
    // %fcc0 - %fcc3
990
4.39k
    if (name.substr(0, 3).equals_lower("fcc")
991
52
        && !name.substr(3).getAsInteger(10, intVal)
992
35
        && intVal < 4) {
993
      // FIXME: check 64bit and  handle %fcc1 - %fcc3
994
1
      RegNo = Sparc::FCC0 + intVal;
995
1
      RegKind = SparcOperand::rk_Special;
996
1
      return true;
997
1
    }
998
999
    // %g0 - %g7
1000
4.39k
    if (name.substr(0, 1).equals_lower("g")
1001
72
        && !name.substr(1).getAsInteger(10, intVal)
1002
45
        && intVal < 8) {
1003
20
      RegNo = IntRegs[intVal];
1004
20
      RegKind = SparcOperand::rk_IntReg;
1005
20
      return true;
1006
20
    }
1007
    // %o0 - %o7
1008
4.37k
    if (name.substr(0, 1).equals_lower("o")
1009
2.08k
        && !name.substr(1).getAsInteger(10, intVal)
1010
651
        && intVal < 8) {
1011
297
      RegNo = IntRegs[8 + intVal];
1012
297
      RegKind = SparcOperand::rk_IntReg;
1013
297
      return true;
1014
297
    }
1015
4.08k
    if (name.substr(0, 1).equals_lower("l")
1016
105
        && !name.substr(1).getAsInteger(10, intVal)
1017
67
        && intVal < 8) {
1018
21
      RegNo = IntRegs[16 + intVal];
1019
21
      RegKind = SparcOperand::rk_IntReg;
1020
21
      return true;
1021
21
    }
1022
4.06k
    if (name.substr(0, 1).equals_lower("i")
1023
281
        && !name.substr(1).getAsInteger(10, intVal)
1024
78
        && intVal < 8) {
1025
12
      RegNo = IntRegs[24 + intVal];
1026
12
      RegKind = SparcOperand::rk_IntReg;
1027
12
      return true;
1028
12
    }
1029
    // %f0 - %f31
1030
4.04k
    if (name.substr(0, 1).equals_lower("f")
1031
803
        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1032
243
      RegNo = FloatRegs[intVal];
1033
243
      RegKind = SparcOperand::rk_FloatReg;
1034
243
      return true;
1035
243
    }
1036
    // %f32 - %f62
1037
3.80k
    if (name.substr(0, 1).equals_lower("f")
1038
560
        && !name.substr(1, 2).getAsInteger(10, intVal)
1039
125
        && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
1040
      // FIXME: Check V9
1041
122
      RegNo = DoubleRegs[intVal/2];
1042
122
      RegKind = SparcOperand::rk_DoubleReg;
1043
122
      return true;
1044
122
    }
1045
1046
    // %r0 - %r31
1047
3.68k
    if (name.substr(0, 1).equals_lower("r")
1048
64
        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1049
26
      RegNo = IntRegs[intVal];
1050
26
      RegKind = SparcOperand::rk_IntReg;
1051
26
      return true;
1052
26
    }
1053
1054
3.65k
    if (name.equals("tpc")) {
1055
1
      RegNo = Sparc::TPC;
1056
1
      RegKind = SparcOperand::rk_Special;
1057
1
      return true;
1058
1
    }
1059
3.65k
    if (name.equals("tnpc")) {
1060
1
      RegNo = Sparc::TNPC;
1061
1
      RegKind = SparcOperand::rk_Special;
1062
1
      return true;
1063
1
    }
1064
3.65k
    if (name.equals("tstate")) {
1065
1
      RegNo = Sparc::TSTATE;
1066
1
      RegKind = SparcOperand::rk_Special;
1067
1
      return true;
1068
1
    }
1069
3.65k
    if (name.equals("tt")) {
1070
10
      RegNo = Sparc::TT;
1071
10
      RegKind = SparcOperand::rk_Special;
1072
10
      return true;
1073
10
    }
1074
3.64k
    if (name.equals("tick")) {
1075
1
      RegNo = Sparc::TICK;
1076
1
      RegKind = SparcOperand::rk_Special;
1077
1
      return true;
1078
1
    }
1079
3.64k
    if (name.equals("tba")) {
1080
1
      RegNo = Sparc::TBA;
1081
1
      RegKind = SparcOperand::rk_Special;
1082
1
      return true;
1083
1
    }
1084
3.64k
    if (name.equals("pstate")) {
1085
1
      RegNo = Sparc::PSTATE;
1086
1
      RegKind = SparcOperand::rk_Special;
1087
1
      return true;
1088
1
    }
1089
3.64k
    if (name.equals("tl")) {
1090
1
      RegNo = Sparc::TL;
1091
1
      RegKind = SparcOperand::rk_Special;
1092
1
      return true;
1093
1
    }
1094
3.64k
    if (name.equals("pil")) {
1095
1
      RegNo = Sparc::PIL;
1096
1
      RegKind = SparcOperand::rk_Special;
1097
1
      return true;
1098
1
    }
1099
3.63k
    if (name.equals("cwp")) {
1100
1
      RegNo = Sparc::CWP;
1101
1
      RegKind = SparcOperand::rk_Special;
1102
1
      return true;
1103
1
    }
1104
3.63k
    if (name.equals("cansave")) {
1105
10
      RegNo = Sparc::CANSAVE;
1106
10
      RegKind = SparcOperand::rk_Special;
1107
10
      return true;
1108
10
    }
1109
3.62k
    if (name.equals("canrestore")) {
1110
1
      RegNo = Sparc::CANRESTORE;
1111
1
      RegKind = SparcOperand::rk_Special;
1112
1
      return true;
1113
1
    }
1114
3.62k
    if (name.equals("cleanwin")) {
1115
1
      RegNo = Sparc::CLEANWIN;
1116
1
      RegKind = SparcOperand::rk_Special;
1117
1
      return true;
1118
1
    }
1119
3.62k
    if (name.equals("otherwin")) {
1120
3
      RegNo = Sparc::OTHERWIN;
1121
3
      RegKind = SparcOperand::rk_Special;
1122
3
      return true;
1123
3
    }
1124
3.62k
    if (name.equals("wstate")) {
1125
1
      RegNo = Sparc::WSTATE;
1126
1
      RegKind = SparcOperand::rk_Special;
1127
1
      return true;
1128
1
    }
1129
3.62k
  }
1130
4.96k
  return false;
1131
6.42k
}
1132
1133
const SparcMCExpr *
1134
SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK,
1135
                                    const MCExpr *subExpr)
1136
14
{
1137
#if 0
1138
  // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently.
1139
  // If the expression refers contains _GLOBAL_OFFSETE_TABLE, it is
1140
  // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted
1141
  // as %got10 or %got22 relocation.
1142
1143
  if (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) {
1144
    switch(VK) {
1145
    default: break;
1146
    case SparcMCExpr::VK_Sparc_LO:
1147
      VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC10
1148
                                     : SparcMCExpr::VK_Sparc_GOT10);
1149
      break;
1150
    case SparcMCExpr::VK_Sparc_HI:
1151
      VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC22
1152
                                     : SparcMCExpr::VK_Sparc_GOT22);
1153
      break;
1154
    }
1155
  }
1156
#endif
1157
1158
14
  return SparcMCExpr::create(VK, subExpr, getContext());
1159
14
}
1160
1161
bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1162
                                            SMLoc &EndLoc)
1163
1.02k
{
1164
1.02k
  AsmToken Tok = Parser.getTok();
1165
1.02k
  if (!Tok.is(AsmToken::Identifier))
1166
104
    return false;
1167
1168
921
  StringRef name = Tok.getString();
1169
1170
921
  SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
1171
1172
921
  if (VK == SparcMCExpr::VK_Sparc_None)
1173
888
    return false;
1174
1175
33
  Parser.Lex(); // Eat the identifier.
1176
33
  if (Parser.getTok().getKind() != AsmToken::LParen)
1177
15
    return false;
1178
1179
18
  Parser.Lex(); // Eat the LParen token.
1180
18
  const MCExpr *subExpr;
1181
18
  if (Parser.parseParenExpression(subExpr, EndLoc))
1182
4
    return false;
1183
1184
14
  EVal = adjustPICRelocation(VK, subExpr);
1185
14
  return true;
1186
18
}
1187
1188
26
extern "C" void LLVMInitializeSparcAsmParser() {
1189
26
  RegisterMCAsmParser<SparcAsmParser> A(TheSparcTarget);
1190
26
  RegisterMCAsmParser<SparcAsmParser> B(TheSparcV9Target);
1191
26
  RegisterMCAsmParser<SparcAsmParser> C(TheSparcelTarget);
1192
26
}
1193
1194
#define GET_REGISTER_MATCHER
1195
#define GET_MATCHER_IMPLEMENTATION
1196
#include "SparcGenAsmMatcher.inc"
1197
1198
unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1199
5.41k
                                                    unsigned Kind) {
1200
5.41k
  SparcOperand &Op = (SparcOperand &)GOp;
1201
5.41k
  if (Op.isFloatOrDoubleReg()) {
1202
537
    switch (Kind) {
1203
511
    default: break;
1204
511
    case MCK_DFPRegs:
1205
11
      if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1206
8
        return MCTargetAsmParser::Match_Success;
1207
3
      break;
1208
15
    case MCK_QFPRegs:
1209
15
      if (SparcOperand::MorphToQuadReg(Op))
1210
7
        return MCTargetAsmParser::Match_Success;
1211
8
      break;
1212
537
    }
1213
537
  }
1214
5.40k
  if (Op.isIntReg() && Kind == MCK_IntPair) {
1215
21
    if (SparcOperand::MorphToIntPairReg(Op))
1216
8
      return MCTargetAsmParser::Match_Success;
1217
21
  }
1218
5.39k
  return Match_InvalidOperand;
1219
5.40k
}