Coverage Report

Created: 2026-07-25 06:13

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.13M
  bool is64Bit() const {
86
1.13M
    return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
87
1.13M
  }
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.1k
      : MCTargetAsmParser(Options, sti), Parser(parser) {
97
    // Initialize the set of available features.
98
14.1k
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
99
14.1k
  }
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
184k
  SparcOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
208
209
11.0k
  bool isToken() const override { return Kind == k_Token; }
210
4.48k
  bool isReg() const override { return Kind == k_Register; }
211
5.40k
  bool isImm() const override { return Kind == k_Immediate; }
212
0
  bool isMem() const override { return isMEMrr() || isMEMri(); }
213
1.93k
  bool isMEMrr() const { return Kind == k_MemoryReg; }
214
1.96k
  bool isMEMri() const { return Kind == k_MemoryImm; }
215
216
4.85k
  bool isIntReg() const {
217
4.85k
    return (Kind == k_Register && Reg.Kind == rk_IntReg);
218
4.85k
  }
219
220
11
  bool isFloatReg() const {
221
11
    return (Kind == k_Register && Reg.Kind == rk_FloatReg);
222
11
  }
223
224
4.86k
  bool isFloatOrDoubleReg() const {
225
4.86k
    return (Kind == k_Register && (Reg.Kind == rk_FloatReg
226
908
                                   || Reg.Kind == rk_DoubleReg));
227
4.86k
  }
228
229
230
9.45k
  StringRef getToken() const {
231
9.45k
    assert(Kind == k_Token && "Invalid access!");
232
9.45k
    return StringRef(Tok.Data, Tok.Length);
233
9.45k
  }
234
235
1.41k
  unsigned getReg() const override {
236
1.41k
    assert((Kind == k_Register) && "Invalid access!");
237
1.41k
    return Reg.RegNum;
238
1.41k
  }
239
240
4.85k
  const MCExpr *getImm() const {
241
4.85k
    assert((Kind == k_Immediate) && "Invalid access!");
242
4.85k
    return Imm.Val;
243
4.85k
  }
244
245
1.21k
  unsigned getMemBase() const {
246
1.21k
    assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
247
1.21k
    return Mem.Base;
248
1.21k
  }
249
250
2.37k
  unsigned getMemOffsetReg() const {
251
2.37k
    assert((Kind == k_MemoryReg) && "Invalid access!");
252
2.37k
    return Mem.OffsetReg;
253
2.37k
  }
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
23
  void addRegOperands(MCInst &Inst, unsigned N) const {
284
23
    assert(N == 1 && "Invalid number of operands!");
285
23
    Inst.addOperand(MCOperand::createReg(getReg()));
286
23
  }
287
288
4.81k
  void addImmOperands(MCInst &Inst, unsigned N) const {
289
4.81k
    assert(N == 1 && "Invalid number of operands!");
290
4.81k
    const MCExpr *Expr = getImm();
291
4.81k
    addExpr(Inst, Expr);
292
4.81k
  }
293
294
4.84k
  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
295
    // Add as immediate when possible.  Null MCExpr = 0.
296
4.84k
    if (!Expr)
297
0
      Inst.addOperand(MCOperand::createImm(0));
298
4.84k
    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
299
334
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
300
4.50k
    else
301
4.50k
      Inst.addOperand(MCOperand::createExpr(Expr));
302
4.84k
  }
303
304
1.18k
  void addMEMrrOperands(MCInst &Inst, unsigned N) const {
305
1.18k
    assert(N == 2 && "Invalid number of operands!");
306
307
1.18k
    Inst.addOperand(MCOperand::createReg(getMemBase()));
308
309
1.18k
    assert(getMemOffsetReg() != 0 && "Invalid offset");
310
1.18k
    Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
311
1.18k
  }
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
156k
  static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
323
156k
    auto Op = make_unique<SparcOperand>(k_Token);
324
156k
    Op->Tok.Data = Str.data();
325
156k
    Op->Tok.Length = Str.size();
326
156k
    Op->StartLoc = S;
327
156k
    Op->EndLoc = S;
328
156k
    return Op;
329
156k
  }
330
331
  static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind,
332
340
                                                 SMLoc S, SMLoc E) {
333
340
    auto Op = make_unique<SparcOperand>(k_Register);
334
340
    Op->Reg.RegNum = RegNum;
335
340
    Op->Reg.Kind   = (SparcOperand::RegisterKind)Kind;
336
340
    Op->StartLoc = S;
337
340
    Op->EndLoc = E;
338
340
    return Op;
339
340
  }
340
341
  static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S,
342
25.6k
                                                 SMLoc E) {
343
25.6k
    auto Op = make_unique<SparcOperand>(k_Immediate);
344
25.6k
    Op->Imm.Val = Val;
345
25.6k
    Op->StartLoc = S;
346
25.6k
    Op->EndLoc = E;
347
25.6k
    return Op;
348
25.6k
  }
349
350
27
  static bool MorphToIntPairReg(SparcOperand &Op) {
351
27
    unsigned Reg = Op.getReg();
352
27
    assert(Op.Reg.Kind == rk_IntReg);
353
27
    unsigned regIdx = 32;
354
27
    if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
355
6
      regIdx = Reg - Sparc::G0;
356
21
    else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
357
9
      regIdx = Reg - Sparc::O0 + 8;
358
12
    else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
359
4
      regIdx = Reg - Sparc::L0 + 16;
360
8
    else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
361
8
      regIdx = Reg - Sparc::I0 + 24;
362
27
    if (regIdx % 2 || regIdx > 31)
363
15
      return false;
364
12
    Op.Reg.RegNum = IntPairRegs[regIdx / 2];
365
12
    Op.Reg.Kind = rk_IntPairReg;
366
12
    return true;
367
27
  }
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
4
      return false;
375
7
    Op.Reg.RegNum = DoubleRegs[regIdx / 2];
376
7
    Op.Reg.Kind = rk_DoubleReg;
377
7
    return true;
378
11
  }
379
380
19
  static bool MorphToQuadReg(SparcOperand &Op) {
381
19
    unsigned Reg = Op.getReg();
382
19
    unsigned regIdx = 0;
383
19
    switch (Op.Reg.Kind) {
384
0
    default: llvm_unreachable("Unexpected register kind!");
385
10
    case rk_FloatReg:
386
10
      regIdx = Reg - Sparc::F0;
387
10
      if (regIdx % 4 || regIdx > 31)
388
4
        return false;
389
6
      Reg = QuadFPRegs[regIdx / 4];
390
6
      break;
391
9
    case rk_DoubleReg:
392
9
      regIdx =  Reg - Sparc::D0;
393
9
      if (regIdx % 2 || regIdx > 31)
394
6
        return false;
395
3
      Reg = QuadFPRegs[regIdx / 2];
396
3
      break;
397
19
    }
398
9
    Op.Reg.RegNum = Reg;
399
9
    Op.Reg.Kind = rk_QuadReg;
400
9
    return true;
401
19
  }
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.72k
  CreateMEMr(unsigned Base, SMLoc S, SMLoc E) {
415
1.72k
    auto Op = make_unique<SparcOperand>(k_MemoryReg);
416
1.72k
    Op->Mem.Base = Base;
417
1.72k
    Op->Mem.OffsetReg = Sparc::G0;  // always 0
418
1.72k
    Op->Mem.Off = nullptr;
419
1.72k
    Op->StartLoc = S;
420
1.72k
    Op->EndLoc = E;
421
1.72k
    return Op;
422
1.72k
  }
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
9.02k
{
516
9.02k
  MCInst Inst(Address);
517
9.02k
  SmallVector<MCInst, 8> Instructions;
518
9.02k
  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
519
9.02k
                                              MatchingInlineAsm);
520
9.02k
  switch (MatchResult) {
521
6.32k
  case Match_Success: {
522
6.32k
    switch (Inst.getOpcode()) {
523
6.32k
    default:
524
6.32k
      Inst.setLoc(IDLoc);
525
6.32k
      Instructions.push_back(Inst);
526
6.32k
      break;
527
0
    case SP::SET:
528
0
      expandSET(Inst, IDLoc, Instructions);
529
0
      break;
530
6.32k
    }
531
532
6.32k
    for (MCInst &I : Instructions) {
533
6.32k
      Out.EmitInstruction(I, getSTI(), ErrorCode);
534
6.32k
    }
535
6.32k
    if (ErrorCode == 0) {
536
6.32k
        Address = Inst.getAddress(); // Keystone update address
537
6.32k
        return false;
538
6.32k
    } else
539
0
        return true;
540
6.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.05k
  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.05k
    ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
563
1.05k
    return true;
564
6.32k
  }
565
1.65k
  case Match_MnemonicFail:
566
    // return Error(IDLoc, "invalid instruction mnemonic");
567
1.65k
    ErrorCode = KS_ERR_ASM_SPARC_MNEMONICFAIL;
568
1.65k
    return true;
569
9.02k
  }
570
9.02k
  llvm_unreachable("Implement any new match types added!");
571
9.02k
}
572
573
bool SparcAsmParser::
574
ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc, unsigned int &ErrorCode)
575
28.8k
{
576
28.8k
  const AsmToken &Tok = Parser.getTok();
577
28.8k
  StartLoc = Tok.getLoc();
578
28.8k
  EndLoc = Tok.getEndLoc();
579
28.8k
  RegNo = 0;
580
28.8k
  if (getLexer().getKind() != AsmToken::Percent)
581
24.8k
    return false;
582
4.04k
  Parser.Lex();
583
4.04k
  unsigned regKind = SparcOperand::rk_None;
584
4.04k
  if (matchRegisterName(Tok, RegNo, regKind)) {
585
797
    Parser.Lex();
586
797
    return false;
587
797
  }
588
589
3.24k
  return Error(StartLoc, "invalid register name");
590
4.04k
}
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
136k
{
599
  // First operand in MCInst is instruction mnemonic.
600
136k
  Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
601
602
  // apply mnemonic aliases, if any, so that we can parse operands correctly.
603
136k
  applyMnemonicAliases(Name, getAvailableFeatures(), 0);
604
605
136k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
606
    // Read the first operand.
607
135k
    if (getLexer().is(AsmToken::Comma)) {
608
334
      if (parseBranchModifiers(Operands) != MatchOperand_Success) {
609
        // SMLoc Loc = getLexer().getLoc();
610
68
        Parser.eatToEndOfStatement();
611
        // return Error(Loc, "unexpected token");
612
68
        ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
613
68
        return true;
614
68
      }
615
334
    }
616
135k
    if (parseOperand(Operands, Name) != MatchOperand_Success) {
617
      // SMLoc Loc = getLexer().getLoc();
618
124k
      Parser.eatToEndOfStatement();
619
      // return Error(Loc, "unexpected token");
620
124k
      ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
621
124k
      return true;
622
124k
    }
623
624
27.7k
    while (getLexer().is(AsmToken::Comma)) {
625
17.6k
      Parser.Lex(); // Eat the comma.
626
      // Parse and remember the operand.
627
17.6k
      if (parseOperand(Operands, Name) != MatchOperand_Success) {
628
        // SMLoc Loc = getLexer().getLoc();
629
1.39k
        Parser.eatToEndOfStatement();
630
        // return Error(Loc, "unexpected token");
631
1.39k
        ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
632
1.39k
        return true;
633
1.39k
      }
634
17.6k
    }
635
11.4k
  }
636
11.0k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
637
    // SMLoc Loc = getLexer().getLoc();
638
2.01k
    Parser.eatToEndOfStatement();
639
    // return Error(Loc, "unexpected token");
640
2.01k
    ErrorCode = KS_ERR_ASM_SPARC_INVALIDOPERAND;
641
2.01k
    return true;
642
2.01k
  }
643
9.02k
  Parser.Lex(); // Consume the EndOfStatement.
644
9.02k
  return false;
645
11.0k
}
646
647
bool SparcAsmParser::
648
ParseDirective(AsmToken DirectiveID)
649
1.14M
{
650
1.14M
  StringRef IDVal = DirectiveID.getString();
651
652
1.14M
  if (IDVal == ".byte")
653
735
    return parseDirectiveWord(1, DirectiveID.getLoc());
654
655
1.14M
  if (IDVal == ".half")
656
38
    return parseDirectiveWord(2, DirectiveID.getLoc());
657
658
1.14M
  if (IDVal == ".word")
659
14.2k
    return parseDirectiveWord(4, DirectiveID.getLoc());
660
661
1.13M
  if (IDVal == ".nword")
662
27
    return parseDirectiveWord(is64Bit() ? 8 : 4, DirectiveID.getLoc());
663
664
1.13M
  if (is64Bit() && IDVal == ".xword")
665
0
    return parseDirectiveWord(8, DirectiveID.getLoc());
666
667
1.13M
  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.13M
  return true;
675
1.13M
}
676
677
15.0k
bool SparcAsmParser:: parseDirectiveWord(unsigned Size, SMLoc L) {
678
15.0k
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
679
39.3k
    for (;;) {
680
39.3k
      const MCExpr *Value;
681
39.3k
      if (getParser().parseExpression(Value))
682
512
        return true;
683
684
38.8k
      getParser().getStreamer().EmitValue(Value, Size);
685
686
38.8k
      if (getLexer().is(AsmToken::EndOfStatement))
687
12.2k
        break;
688
689
      // FIXME: Improve diagnostic.
690
26.6k
      if (getLexer().isNot(AsmToken::Comma))
691
632
        return Error(L, "unexpected token in directive");
692
25.9k
      Parser.Lex();
693
25.9k
    }
694
13.3k
  }
695
13.8k
  Parser.Lex();
696
13.8k
  return false;
697
15.0k
}
698
699
SparcAsmParser::OperandMatchResultTy
700
28.8k
SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
701
702
28.8k
  SMLoc S, E;
703
28.8k
  unsigned BaseReg = 0;
704
28.8k
  unsigned int ErrorCode;
705
706
28.8k
  if (ParseRegister(BaseReg, S, E, ErrorCode)) {
707
3.24k
    return MatchOperand_NoMatch;
708
3.24k
  }
709
710
25.6k
  switch (getLexer().getKind()) {
711
636
  default: return MatchOperand_NoMatch;
712
713
186
  case AsmToken::Comma:
714
487
  case AsmToken::RBrac:
715
1.72k
  case AsmToken::EndOfStatement:
716
1.72k
    Operands.push_back(SparcOperand::CreateMEMr(BaseReg, S, E));
717
1.72k
    return MatchOperand_Success;
718
719
25
  case AsmToken:: Plus:
720
25
    Parser.Lex(); // Eat the '+'
721
25
    break;
722
23.2k
  case AsmToken::Minus:
723
23.2k
    break;
724
25.6k
  }
725
726
23.2k
  std::unique_ptr<SparcOperand> Offset;
727
23.2k
  OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset);
728
23.2k
  if (ResTy != MatchOperand_Success || !Offset)
729
23.2k
    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
23.2k
}
737
738
SparcAsmParser::OperandMatchResultTy
739
153k
SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
740
741
153k
  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
153k
  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
747
1.42k
    return ResTy;
748
749
151k
  if (getLexer().is(AsmToken::LBrac)) {
750
    // Memory operand
751
19.6k
    Operands.push_back(SparcOperand::CreateToken("[",
752
19.6k
                                                 Parser.getTok().getLoc()));
753
19.6k
    Parser.Lex(); // Eat the [
754
755
19.6k
    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
19.6k
    } else {
770
19.6k
      ResTy = parseMEMOperand(Operands);
771
19.6k
    }
772
773
19.6k
    if (ResTy != MatchOperand_Success)
774
19.3k
      return ResTy;
775
776
335
    if (!getLexer().is(AsmToken::RBrac))
777
34
      return MatchOperand_ParseFail;
778
779
301
    Operands.push_back(SparcOperand::CreateToken("]",
780
301
                                                 Parser.getTok().getLoc()));
781
301
    Parser.Lex(); // Eat the ]
782
783
    // Parse an optional address-space identifier after the address.
784
301
    if (getLexer().is(AsmToken::Integer)) {
785
23
      std::unique_ptr<SparcOperand> Op;
786
23
      ResTy = parseSparcAsmOperand(Op, false);
787
23
      if (ResTy != MatchOperand_Success || !Op)
788
1
        return MatchOperand_ParseFail;
789
22
      Operands.push_back(std::move(Op));
790
22
    }
791
300
    return MatchOperand_Success;
792
301
  }
793
794
131k
  std::unique_ptr<SparcOperand> Op;
795
796
131k
  ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
797
131k
  if (ResTy != MatchOperand_Success || !Op)
798
106k
    return MatchOperand_ParseFail;
799
800
  // Push the parsed operand into the list of operands
801
25.9k
  Operands.push_back(std::move(Op));
802
803
25.9k
  return MatchOperand_Success;
804
131k
}
805
806
SparcAsmParser::OperandMatchResultTy
807
SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op,
808
155k
                                     bool isCall) {
809
810
155k
  SMLoc S = Parser.getTok().getLoc();
811
155k
  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
812
155k
  const MCExpr *EVal;
813
814
155k
  Op = nullptr;
815
155k
  switch (getLexer().getKind()) {
816
1.08k
  default:  break;
817
818
1.38k
  case AsmToken::Percent:
819
1.38k
    Parser.Lex(); // Eat the '%'.
820
1.38k
    unsigned RegNo;
821
1.38k
    unsigned RegKind;
822
1.38k
    if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) {
823
408
      StringRef name = Parser.getTok().getString();
824
408
      Parser.Lex(); // Eat the identifier token.
825
408
      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
826
408
      switch (RegNo) {
827
339
      default:
828
339
        Op = SparcOperand::CreateReg(RegNo, RegKind, S, E);
829
339
        break;
830
15
      case Sparc::PSR:
831
15
        Op = SparcOperand::CreateToken("%psr", S);
832
15
        break;
833
24
      case Sparc::FSR:
834
24
        Op = SparcOperand::CreateToken("%fsr", S);
835
24
        break;
836
15
      case Sparc::WIM:
837
15
        Op = SparcOperand::CreateToken("%wim", S);
838
15
        break;
839
3
      case Sparc::TBR:
840
3
        Op = SparcOperand::CreateToken("%tbr", S);
841
3
        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
408
      }
849
408
      break;
850
408
    }
851
976
    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
976
    break;
856
857
74.5k
  case AsmToken::Minus:
858
79.0k
  case AsmToken::Integer:
859
129k
  case AsmToken::LParen:
860
134k
  case AsmToken::Dot:
861
134k
    if (!getParser().parseExpression(EVal, E))
862
6.83k
      Op = SparcOperand::CreateImm(EVal, S, E);
863
134k
    break;
864
865
18.7k
  case AsmToken::Identifier: {
866
18.7k
    StringRef Identifier;
867
18.7k
    if (!getParser().parseIdentifier(Identifier)) {
868
18.7k
      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
869
18.7k
      MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
870
871
18.7k
      const MCExpr *Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
872
18.7k
                                                  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
18.7k
      Op = SparcOperand::CreateImm(Res, S, E);
880
18.7k
    }
881
18.7k
    break;
882
129k
  }
883
155k
  }
884
155k
  return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
885
155k
}
886
887
SparcAsmParser::OperandMatchResultTy
888
334
SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
889
890
  // parse (,a|,pn|,pt)+
891
892
740
  while (getLexer().is(AsmToken::Comma)) {
893
894
474
    Parser.Lex(); // Eat the comma
895
896
474
    if (!getLexer().is(AsmToken::Identifier))
897
68
      return MatchOperand_ParseFail;
898
406
    StringRef modName = Parser.getTok().getString();
899
406
    if (modName == "a" || modName == "pn" || modName == "pt") {
900
198
      Operands.push_back(SparcOperand::CreateToken(modName,
901
198
                                                   Parser.getTok().getLoc()));
902
198
      Parser.Lex(); // eat the identifier.
903
198
    }
904
406
  }
905
266
  return MatchOperand_Success;
906
334
}
907
908
bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
909
                                       unsigned &RegNo,
910
                                       unsigned &RegKind)
911
5.42k
{
912
5.42k
  int64_t intVal = 0;
913
5.42k
  RegNo = 0;
914
5.42k
  RegKind = SparcOperand::rk_None;
915
5.42k
  if (Tok.is(AsmToken::Identifier)) {
916
4.23k
    StringRef name = Tok.getString();
917
918
    // %fp
919
4.23k
    if (name.equals("fp")) {
920
4
      RegNo = Sparc::I6;
921
4
      RegKind = SparcOperand::rk_IntReg;
922
4
      return true;
923
4
    }
924
    // %sp
925
4.23k
    if (name.equals("sp")) {
926
1
      RegNo = Sparc::O6;
927
1
      RegKind = SparcOperand::rk_IntReg;
928
1
      return true;
929
1
    }
930
931
4.23k
    if (name.equals("y")) {
932
28
      RegNo = Sparc::Y;
933
28
      RegKind = SparcOperand::rk_Special;
934
28
      return true;
935
28
    }
936
937
4.20k
    if (name.substr(0, 3).equals_lower("asr")
938
59
        && !name.substr(3).getAsInteger(10, intVal)
939
51
        && 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
4.20k
    if (name.equals("fprs")) {
947
5
      RegNo = ASRRegs[6];
948
5
      RegKind = SparcOperand::rk_Special;
949
5
      return true;
950
5
    }
951
952
4.19k
    if (name.equals("icc")) {
953
4
      RegNo = Sparc::ICC;
954
4
      RegKind = SparcOperand::rk_Special;
955
4
      return true;
956
4
    }
957
958
4.19k
    if (name.equals("psr")) {
959
16
      RegNo = Sparc::PSR;
960
16
      RegKind = SparcOperand::rk_Special;
961
16
      return true;
962
16
    }
963
964
4.17k
    if (name.equals("fsr")) {
965
445
      RegNo = Sparc::FSR;
966
445
      RegKind = SparcOperand::rk_Special;
967
445
      return true;
968
445
    }
969
970
3.73k
    if (name.equals("wim")) {
971
15
      RegNo = Sparc::WIM;
972
15
      RegKind = SparcOperand::rk_Special;
973
15
      return true;
974
15
    }
975
976
3.71k
    if (name.equals("tbr")) {
977
3
      RegNo = Sparc::TBR;
978
3
      RegKind = SparcOperand::rk_Special;
979
3
      return true;
980
3
    }
981
982
3.71k
    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
3.70k
    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
3.70k
    if (name.substr(0, 1).equals_lower("g")
1001
70
        && !name.substr(1).getAsInteger(10, intVal)
1002
41
        && intVal < 8) {
1003
16
      RegNo = IntRegs[intVal];
1004
16
      RegKind = SparcOperand::rk_IntReg;
1005
16
      return true;
1006
16
    }
1007
    // %o0 - %o7
1008
3.68k
    if (name.substr(0, 1).equals_lower("o")
1009
1.50k
        && !name.substr(1).getAsInteger(10, intVal)
1010
541
        && intVal < 8) {
1011
267
      RegNo = IntRegs[8 + intVal];
1012
267
      RegKind = SparcOperand::rk_IntReg;
1013
267
      return true;
1014
267
    }
1015
3.42k
    if (name.substr(0, 1).equals_lower("l")
1016
91
        && !name.substr(1).getAsInteger(10, intVal)
1017
59
        && intVal < 8) {
1018
13
      RegNo = IntRegs[16 + intVal];
1019
13
      RegKind = SparcOperand::rk_IntReg;
1020
13
      return true;
1021
13
    }
1022
3.40k
    if (name.substr(0, 1).equals_lower("i")
1023
222
        && !name.substr(1).getAsInteger(10, intVal)
1024
75
        && intVal < 8) {
1025
17
      RegNo = IntRegs[24 + intVal];
1026
17
      RegKind = SparcOperand::rk_IntReg;
1027
17
      return true;
1028
17
    }
1029
    // %f0 - %f31
1030
3.39k
    if (name.substr(0, 1).equals_lower("f")
1031
839
        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) {
1032
222
      RegNo = FloatRegs[intVal];
1033
222
      RegKind = SparcOperand::rk_FloatReg;
1034
222
      return true;
1035
222
    }
1036
    // %f32 - %f62
1037
3.16k
    if (name.substr(0, 1).equals_lower("f")
1038
617
        && !name.substr(1, 2).getAsInteger(10, intVal)
1039
83
        && intVal >= 32 && intVal <= 62 && (intVal % 2 == 0)) {
1040
      // FIXME: Check V9
1041
80
      RegNo = DoubleRegs[intVal/2];
1042
80
      RegKind = SparcOperand::rk_DoubleReg;
1043
80
      return true;
1044
80
    }
1045
1046
    // %r0 - %r31
1047
3.08k
    if (name.substr(0, 1).equals_lower("r")
1048
75
        && !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) {
1049
27
      RegNo = IntRegs[intVal];
1050
27
      RegKind = SparcOperand::rk_IntReg;
1051
27
      return true;
1052
27
    }
1053
1054
3.06k
    if (name.equals("tpc")) {
1055
1
      RegNo = Sparc::TPC;
1056
1
      RegKind = SparcOperand::rk_Special;
1057
1
      return true;
1058
1
    }
1059
3.06k
    if (name.equals("tnpc")) {
1060
1
      RegNo = Sparc::TNPC;
1061
1
      RegKind = SparcOperand::rk_Special;
1062
1
      return true;
1063
1
    }
1064
3.05k
    if (name.equals("tstate")) {
1065
1
      RegNo = Sparc::TSTATE;
1066
1
      RegKind = SparcOperand::rk_Special;
1067
1
      return true;
1068
1
    }
1069
3.05k
    if (name.equals("tt")) {
1070
6
      RegNo = Sparc::TT;
1071
6
      RegKind = SparcOperand::rk_Special;
1072
6
      return true;
1073
6
    }
1074
3.05k
    if (name.equals("tick")) {
1075
1
      RegNo = Sparc::TICK;
1076
1
      RegKind = SparcOperand::rk_Special;
1077
1
      return true;
1078
1
    }
1079
3.05k
    if (name.equals("tba")) {
1080
1
      RegNo = Sparc::TBA;
1081
1
      RegKind = SparcOperand::rk_Special;
1082
1
      return true;
1083
1
    }
1084
3.05k
    if (name.equals("pstate")) {
1085
1
      RegNo = Sparc::PSTATE;
1086
1
      RegKind = SparcOperand::rk_Special;
1087
1
      return true;
1088
1
    }
1089
3.04k
    if (name.equals("tl")) {
1090
1
      RegNo = Sparc::TL;
1091
1
      RegKind = SparcOperand::rk_Special;
1092
1
      return true;
1093
1
    }
1094
3.04k
    if (name.equals("pil")) {
1095
1
      RegNo = Sparc::PIL;
1096
1
      RegKind = SparcOperand::rk_Special;
1097
1
      return true;
1098
1
    }
1099
3.04k
    if (name.equals("cwp")) {
1100
1
      RegNo = Sparc::CWP;
1101
1
      RegKind = SparcOperand::rk_Special;
1102
1
      return true;
1103
1
    }
1104
3.04k
    if (name.equals("cansave")) {
1105
11
      RegNo = Sparc::CANSAVE;
1106
11
      RegKind = SparcOperand::rk_Special;
1107
11
      return true;
1108
11
    }
1109
3.03k
    if (name.equals("canrestore")) {
1110
1
      RegNo = Sparc::CANRESTORE;
1111
1
      RegKind = SparcOperand::rk_Special;
1112
1
      return true;
1113
1
    }
1114
3.03k
    if (name.equals("cleanwin")) {
1115
1
      RegNo = Sparc::CLEANWIN;
1116
1
      RegKind = SparcOperand::rk_Special;
1117
1
      return true;
1118
1
    }
1119
3.03k
    if (name.equals("otherwin")) {
1120
1
      RegNo = Sparc::OTHERWIN;
1121
1
      RegKind = SparcOperand::rk_Special;
1122
1
      return true;
1123
1
    }
1124
3.03k
    if (name.equals("wstate")) {
1125
1
      RegNo = Sparc::WSTATE;
1126
1
      RegKind = SparcOperand::rk_Special;
1127
1
      return true;
1128
1
    }
1129
3.03k
  }
1130
4.22k
  return false;
1131
5.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
976
{
1164
976
  AsmToken Tok = Parser.getTok();
1165
976
  if (!Tok.is(AsmToken::Identifier))
1166
104
    return false;
1167
1168
872
  StringRef name = Tok.getString();
1169
1170
872
  SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name);
1171
1172
872
  if (VK == SparcMCExpr::VK_Sparc_None)
1173
840
    return false;
1174
1175
32
  Parser.Lex(); // Eat the identifier.
1176
32
  if (Parser.getTok().getKind() != AsmToken::LParen)
1177
14
    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
4.86k
                                                    unsigned Kind) {
1200
4.86k
  SparcOperand &Op = (SparcOperand &)GOp;
1201
4.86k
  if (Op.isFloatOrDoubleReg()) {
1202
546
    switch (Kind) {
1203
516
    default: break;
1204
516
    case MCK_DFPRegs:
1205
11
      if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1206
7
        return MCTargetAsmParser::Match_Success;
1207
4
      break;
1208
19
    case MCK_QFPRegs:
1209
19
      if (SparcOperand::MorphToQuadReg(Op))
1210
9
        return MCTargetAsmParser::Match_Success;
1211
10
      break;
1212
546
    }
1213
546
  }
1214
4.85k
  if (Op.isIntReg() && Kind == MCK_IntPair) {
1215
27
    if (SparcOperand::MorphToIntPairReg(Op))
1216
12
      return MCTargetAsmParser::Match_Success;
1217
27
  }
1218
4.84k
  return Match_InvalidOperand;
1219
4.85k
}