1 //===-- SparcAsmParser.cpp - Parse Sparc assembly to MCInst instructions --===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/SparcMCExpr.h" 10 #include "MCTargetDesc/SparcMCTargetDesc.h" 11 #include "TargetInfo/SparcTargetInfo.h" 12 #include "llvm/ADT/STLExtras.h" 13 #include "llvm/ADT/SmallVector.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/ADT/Triple.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCExpr.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCObjectFileInfo.h" 20 #include "llvm/MC/MCParser/MCAsmLexer.h" 21 #include "llvm/MC/MCParser/MCAsmParser.h" 22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 23 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 24 #include "llvm/MC/MCRegisterInfo.h" 25 #include "llvm/MC/MCStreamer.h" 26 #include "llvm/MC/MCSubtargetInfo.h" 27 #include "llvm/MC/MCSymbol.h" 28 #include "llvm/MC/TargetRegistry.h" 29 #include "llvm/Support/Casting.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/SMLoc.h" 32 #include "llvm/Support/raw_ostream.h" 33 #include <algorithm> 34 #include <cassert> 35 #include <cstdint> 36 #include <memory> 37 38 using namespace llvm; 39 40 // The generated AsmMatcher SparcGenAsmMatcher uses "Sparc" as the target 41 // namespace. But SPARC backend uses "SP" as its namespace. 42 namespace llvm { 43 namespace Sparc { 44 45 using namespace SP; 46 47 } // end namespace Sparc 48 } // end namespace llvm 49 50 namespace { 51 52 class SparcOperand; 53 54 class SparcAsmParser : public MCTargetAsmParser { 55 MCAsmParser &Parser; 56 57 /// @name Auto-generated Match Functions 58 /// { 59 60 #define GET_ASSEMBLER_HEADER 61 #include "SparcGenAsmMatcher.inc" 62 63 /// } 64 65 // public interface of the MCTargetAsmParser. 66 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 67 OperandVector &Operands, MCStreamer &Out, 68 uint64_t &ErrorInfo, 69 bool MatchingInlineAsm) override; 70 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 71 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 72 SMLoc &EndLoc) override; 73 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 74 SMLoc NameLoc, OperandVector &Operands) override; 75 bool ParseDirective(AsmToken DirectiveID) override; 76 77 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 78 unsigned Kind) override; 79 80 // Custom parse functions for Sparc specific operands. 81 OperandMatchResultTy parseMEMOperand(OperandVector &Operands); 82 83 OperandMatchResultTy parseMembarTag(OperandVector &Operands); 84 85 template <unsigned N> 86 OperandMatchResultTy parseShiftAmtImm(OperandVector &Operands); 87 88 OperandMatchResultTy parseCallTarget(OperandVector &Operands); 89 90 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name); 91 92 OperandMatchResultTy 93 parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Operand, 94 bool isCall = false); 95 96 OperandMatchResultTy parseBranchModifiers(OperandVector &Operands); 97 98 // Helper function for dealing with %lo / %hi in PIC mode. 99 const SparcMCExpr *adjustPICRelocation(SparcMCExpr::VariantKind VK, 100 const MCExpr *subExpr); 101 102 // returns true if Tok is matched to a register and returns register in RegNo. 103 bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, 104 unsigned &RegKind); 105 106 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc); 107 108 bool is64Bit() const { 109 return getSTI().getTargetTriple().getArch() == Triple::sparcv9; 110 } 111 112 bool expandSET(MCInst &Inst, SMLoc IDLoc, 113 SmallVectorImpl<MCInst> &Instructions); 114 115 public: 116 SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, 117 const MCInstrInfo &MII, 118 const MCTargetOptions &Options) 119 : MCTargetAsmParser(Options, sti, MII), Parser(parser) { 120 Parser.addAliasForDirective(".half", ".2byte"); 121 Parser.addAliasForDirective(".uahalf", ".2byte"); 122 Parser.addAliasForDirective(".word", ".4byte"); 123 Parser.addAliasForDirective(".uaword", ".4byte"); 124 Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte"); 125 if (is64Bit()) 126 Parser.addAliasForDirective(".xword", ".8byte"); 127 128 // Initialize the set of available features. 129 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); 130 } 131 }; 132 133 } // end anonymous namespace 134 135 static const MCPhysReg IntRegs[32] = { 136 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3, 137 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7, 138 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3, 139 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7, 140 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3, 141 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7, 142 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3, 143 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 }; 144 145 static const MCPhysReg FloatRegs[32] = { 146 Sparc::F0, Sparc::F1, Sparc::F2, Sparc::F3, 147 Sparc::F4, Sparc::F5, Sparc::F6, Sparc::F7, 148 Sparc::F8, Sparc::F9, Sparc::F10, Sparc::F11, 149 Sparc::F12, Sparc::F13, Sparc::F14, Sparc::F15, 150 Sparc::F16, Sparc::F17, Sparc::F18, Sparc::F19, 151 Sparc::F20, Sparc::F21, Sparc::F22, Sparc::F23, 152 Sparc::F24, Sparc::F25, Sparc::F26, Sparc::F27, 153 Sparc::F28, Sparc::F29, Sparc::F30, Sparc::F31 }; 154 155 static const MCPhysReg DoubleRegs[32] = { 156 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3, 157 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7, 158 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11, 159 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15, 160 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19, 161 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23, 162 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27, 163 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 }; 164 165 static const MCPhysReg QuadFPRegs[32] = { 166 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3, 167 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7, 168 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11, 169 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 }; 170 171 static const MCPhysReg ASRRegs[32] = { 172 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3, 173 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7, 174 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11, 175 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15, 176 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19, 177 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23, 178 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27, 179 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31}; 180 181 static const MCPhysReg IntPairRegs[] = { 182 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7, 183 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7, 184 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7, 185 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7}; 186 187 static const MCPhysReg CoprocRegs[32] = { 188 Sparc::C0, Sparc::C1, Sparc::C2, Sparc::C3, 189 Sparc::C4, Sparc::C5, Sparc::C6, Sparc::C7, 190 Sparc::C8, Sparc::C9, Sparc::C10, Sparc::C11, 191 Sparc::C12, Sparc::C13, Sparc::C14, Sparc::C15, 192 Sparc::C16, Sparc::C17, Sparc::C18, Sparc::C19, 193 Sparc::C20, Sparc::C21, Sparc::C22, Sparc::C23, 194 Sparc::C24, Sparc::C25, Sparc::C26, Sparc::C27, 195 Sparc::C28, Sparc::C29, Sparc::C30, Sparc::C31 }; 196 197 static const MCPhysReg CoprocPairRegs[] = { 198 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7, 199 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15, 200 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23, 201 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31}; 202 203 namespace { 204 205 /// SparcOperand - Instances of this class represent a parsed Sparc machine 206 /// instruction. 207 class SparcOperand : public MCParsedAsmOperand { 208 public: 209 enum RegisterKind { 210 rk_None, 211 rk_IntReg, 212 rk_IntPairReg, 213 rk_FloatReg, 214 rk_DoubleReg, 215 rk_QuadReg, 216 rk_CoprocReg, 217 rk_CoprocPairReg, 218 rk_Special, 219 }; 220 221 private: 222 enum KindTy { 223 k_Token, 224 k_Register, 225 k_Immediate, 226 k_MemoryReg, 227 k_MemoryImm 228 } Kind; 229 230 SMLoc StartLoc, EndLoc; 231 232 struct Token { 233 const char *Data; 234 unsigned Length; 235 }; 236 237 struct RegOp { 238 unsigned RegNum; 239 RegisterKind Kind; 240 }; 241 242 struct ImmOp { 243 const MCExpr *Val; 244 }; 245 246 struct MemOp { 247 unsigned Base; 248 unsigned OffsetReg; 249 const MCExpr *Off; 250 }; 251 252 union { 253 struct Token Tok; 254 struct RegOp Reg; 255 struct ImmOp Imm; 256 struct MemOp Mem; 257 }; 258 259 public: 260 SparcOperand(KindTy K) : Kind(K) {} 261 262 bool isToken() const override { return Kind == k_Token; } 263 bool isReg() const override { return Kind == k_Register; } 264 bool isImm() const override { return Kind == k_Immediate; } 265 bool isMem() const override { return isMEMrr() || isMEMri(); } 266 bool isMEMrr() const { return Kind == k_MemoryReg; } 267 bool isMEMri() const { return Kind == k_MemoryImm; } 268 bool isMembarTag() const { return Kind == k_Immediate; } 269 270 bool isCallTarget() const { 271 if (!isImm()) 272 return false; 273 274 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) 275 return CE->getValue() % 4 == 0; 276 277 return true; 278 } 279 280 bool isShiftAmtImm5() const { 281 if (!isImm()) 282 return false; 283 284 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) 285 return isUInt<5>(CE->getValue()); 286 287 return false; 288 } 289 290 bool isShiftAmtImm6() const { 291 if (!isImm()) 292 return false; 293 294 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) 295 return isUInt<6>(CE->getValue()); 296 297 return false; 298 } 299 300 bool isIntReg() const { 301 return (Kind == k_Register && Reg.Kind == rk_IntReg); 302 } 303 304 bool isFloatReg() const { 305 return (Kind == k_Register && Reg.Kind == rk_FloatReg); 306 } 307 308 bool isFloatOrDoubleReg() const { 309 return (Kind == k_Register && (Reg.Kind == rk_FloatReg 310 || Reg.Kind == rk_DoubleReg)); 311 } 312 313 bool isCoprocReg() const { 314 return (Kind == k_Register && Reg.Kind == rk_CoprocReg); 315 } 316 317 StringRef getToken() const { 318 assert(Kind == k_Token && "Invalid access!"); 319 return StringRef(Tok.Data, Tok.Length); 320 } 321 322 unsigned getReg() const override { 323 assert((Kind == k_Register) && "Invalid access!"); 324 return Reg.RegNum; 325 } 326 327 const MCExpr *getImm() const { 328 assert((Kind == k_Immediate) && "Invalid access!"); 329 return Imm.Val; 330 } 331 332 unsigned getMemBase() const { 333 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!"); 334 return Mem.Base; 335 } 336 337 unsigned getMemOffsetReg() const { 338 assert((Kind == k_MemoryReg) && "Invalid access!"); 339 return Mem.OffsetReg; 340 } 341 342 const MCExpr *getMemOff() const { 343 assert((Kind == k_MemoryImm) && "Invalid access!"); 344 return Mem.Off; 345 } 346 347 /// getStartLoc - Get the location of the first token of this operand. 348 SMLoc getStartLoc() const override { 349 return StartLoc; 350 } 351 /// getEndLoc - Get the location of the last token of this operand. 352 SMLoc getEndLoc() const override { 353 return EndLoc; 354 } 355 356 void print(raw_ostream &OS) const override { 357 switch (Kind) { 358 case k_Token: OS << "Token: " << getToken() << "\n"; break; 359 case k_Register: OS << "Reg: #" << getReg() << "\n"; break; 360 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break; 361 case k_MemoryReg: OS << "Mem: " << getMemBase() << "+" 362 << getMemOffsetReg() << "\n"; break; 363 case k_MemoryImm: assert(getMemOff() != nullptr); 364 OS << "Mem: " << getMemBase() 365 << "+" << *getMemOff() 366 << "\n"; break; 367 } 368 } 369 370 void addRegOperands(MCInst &Inst, unsigned N) const { 371 assert(N == 1 && "Invalid number of operands!"); 372 Inst.addOperand(MCOperand::createReg(getReg())); 373 } 374 375 void addImmOperands(MCInst &Inst, unsigned N) const { 376 assert(N == 1 && "Invalid number of operands!"); 377 const MCExpr *Expr = getImm(); 378 addExpr(Inst, Expr); 379 } 380 381 void addShiftAmtImm5Operands(MCInst &Inst, unsigned N) const { 382 assert(N == 1 && "Invalid number of operands!"); 383 addExpr(Inst, getImm()); 384 } 385 void addShiftAmtImm6Operands(MCInst &Inst, unsigned N) const { 386 assert(N == 1 && "Invalid number of operands!"); 387 addExpr(Inst, getImm()); 388 } 389 390 void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 391 // Add as immediate when possible. Null MCExpr = 0. 392 if (!Expr) 393 Inst.addOperand(MCOperand::createImm(0)); 394 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 395 Inst.addOperand(MCOperand::createImm(CE->getValue())); 396 else 397 Inst.addOperand(MCOperand::createExpr(Expr)); 398 } 399 400 void addMEMrrOperands(MCInst &Inst, unsigned N) const { 401 assert(N == 2 && "Invalid number of operands!"); 402 403 Inst.addOperand(MCOperand::createReg(getMemBase())); 404 405 assert(getMemOffsetReg() != 0 && "Invalid offset"); 406 Inst.addOperand(MCOperand::createReg(getMemOffsetReg())); 407 } 408 409 void addMEMriOperands(MCInst &Inst, unsigned N) const { 410 assert(N == 2 && "Invalid number of operands!"); 411 412 Inst.addOperand(MCOperand::createReg(getMemBase())); 413 414 const MCExpr *Expr = getMemOff(); 415 addExpr(Inst, Expr); 416 } 417 418 void addMembarTagOperands(MCInst &Inst, unsigned N) const { 419 assert(N == 1 && "Invalid number of operands!"); 420 const MCExpr *Expr = getImm(); 421 addExpr(Inst, Expr); 422 } 423 424 void addCallTargetOperands(MCInst &Inst, unsigned N) const { 425 assert(N == 1 && "Invalid number of operands!"); 426 addExpr(Inst, getImm()); 427 } 428 429 static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) { 430 auto Op = std::make_unique<SparcOperand>(k_Token); 431 Op->Tok.Data = Str.data(); 432 Op->Tok.Length = Str.size(); 433 Op->StartLoc = S; 434 Op->EndLoc = S; 435 return Op; 436 } 437 438 static std::unique_ptr<SparcOperand> CreateReg(unsigned RegNum, unsigned Kind, 439 SMLoc S, SMLoc E) { 440 auto Op = std::make_unique<SparcOperand>(k_Register); 441 Op->Reg.RegNum = RegNum; 442 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind; 443 Op->StartLoc = S; 444 Op->EndLoc = E; 445 return Op; 446 } 447 448 static std::unique_ptr<SparcOperand> CreateImm(const MCExpr *Val, SMLoc S, 449 SMLoc E) { 450 auto Op = std::make_unique<SparcOperand>(k_Immediate); 451 Op->Imm.Val = Val; 452 Op->StartLoc = S; 453 Op->EndLoc = E; 454 return Op; 455 } 456 457 static bool MorphToIntPairReg(SparcOperand &Op) { 458 unsigned Reg = Op.getReg(); 459 assert(Op.Reg.Kind == rk_IntReg); 460 unsigned regIdx = 32; 461 if (Reg >= Sparc::G0 && Reg <= Sparc::G7) 462 regIdx = Reg - Sparc::G0; 463 else if (Reg >= Sparc::O0 && Reg <= Sparc::O7) 464 regIdx = Reg - Sparc::O0 + 8; 465 else if (Reg >= Sparc::L0 && Reg <= Sparc::L7) 466 regIdx = Reg - Sparc::L0 + 16; 467 else if (Reg >= Sparc::I0 && Reg <= Sparc::I7) 468 regIdx = Reg - Sparc::I0 + 24; 469 if (regIdx % 2 || regIdx > 31) 470 return false; 471 Op.Reg.RegNum = IntPairRegs[regIdx / 2]; 472 Op.Reg.Kind = rk_IntPairReg; 473 return true; 474 } 475 476 static bool MorphToDoubleReg(SparcOperand &Op) { 477 unsigned Reg = Op.getReg(); 478 assert(Op.Reg.Kind == rk_FloatReg); 479 unsigned regIdx = Reg - Sparc::F0; 480 if (regIdx % 2 || regIdx > 31) 481 return false; 482 Op.Reg.RegNum = DoubleRegs[regIdx / 2]; 483 Op.Reg.Kind = rk_DoubleReg; 484 return true; 485 } 486 487 static bool MorphToQuadReg(SparcOperand &Op) { 488 unsigned Reg = Op.getReg(); 489 unsigned regIdx = 0; 490 switch (Op.Reg.Kind) { 491 default: llvm_unreachable("Unexpected register kind!"); 492 case rk_FloatReg: 493 regIdx = Reg - Sparc::F0; 494 if (regIdx % 4 || regIdx > 31) 495 return false; 496 Reg = QuadFPRegs[regIdx / 4]; 497 break; 498 case rk_DoubleReg: 499 regIdx = Reg - Sparc::D0; 500 if (regIdx % 2 || regIdx > 31) 501 return false; 502 Reg = QuadFPRegs[regIdx / 2]; 503 break; 504 } 505 Op.Reg.RegNum = Reg; 506 Op.Reg.Kind = rk_QuadReg; 507 return true; 508 } 509 510 static bool MorphToCoprocPairReg(SparcOperand &Op) { 511 unsigned Reg = Op.getReg(); 512 assert(Op.Reg.Kind == rk_CoprocReg); 513 unsigned regIdx = 32; 514 if (Reg >= Sparc::C0 && Reg <= Sparc::C31) 515 regIdx = Reg - Sparc::C0; 516 if (regIdx % 2 || regIdx > 31) 517 return false; 518 Op.Reg.RegNum = CoprocPairRegs[regIdx / 2]; 519 Op.Reg.Kind = rk_CoprocPairReg; 520 return true; 521 } 522 523 static std::unique_ptr<SparcOperand> 524 MorphToMEMrr(unsigned Base, std::unique_ptr<SparcOperand> Op) { 525 unsigned offsetReg = Op->getReg(); 526 Op->Kind = k_MemoryReg; 527 Op->Mem.Base = Base; 528 Op->Mem.OffsetReg = offsetReg; 529 Op->Mem.Off = nullptr; 530 return Op; 531 } 532 533 static std::unique_ptr<SparcOperand> 534 CreateMEMr(unsigned Base, SMLoc S, SMLoc E) { 535 auto Op = std::make_unique<SparcOperand>(k_MemoryReg); 536 Op->Mem.Base = Base; 537 Op->Mem.OffsetReg = Sparc::G0; // always 0 538 Op->Mem.Off = nullptr; 539 Op->StartLoc = S; 540 Op->EndLoc = E; 541 return Op; 542 } 543 544 static std::unique_ptr<SparcOperand> 545 MorphToMEMri(unsigned Base, std::unique_ptr<SparcOperand> Op) { 546 const MCExpr *Imm = Op->getImm(); 547 Op->Kind = k_MemoryImm; 548 Op->Mem.Base = Base; 549 Op->Mem.OffsetReg = 0; 550 Op->Mem.Off = Imm; 551 return Op; 552 } 553 }; 554 555 } // end anonymous namespace 556 557 bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc, 558 SmallVectorImpl<MCInst> &Instructions) { 559 MCOperand MCRegOp = Inst.getOperand(0); 560 MCOperand MCValOp = Inst.getOperand(1); 561 assert(MCRegOp.isReg()); 562 assert(MCValOp.isImm() || MCValOp.isExpr()); 563 564 // the imm operand can be either an expression or an immediate. 565 bool IsImm = Inst.getOperand(1).isImm(); 566 int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0; 567 568 // Allow either a signed or unsigned 32-bit immediate. 569 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) { 570 return Error(IDLoc, 571 "set: argument must be between -2147483648 and 4294967295"); 572 } 573 574 // If the value was expressed as a large unsigned number, that's ok. 575 // We want to see if it "looks like" a small signed number. 576 int32_t ImmValue = RawImmValue; 577 // For 'set' you can't use 'or' with a negative operand on V9 because 578 // that would splat the sign bit across the upper half of the destination 579 // register, whereas 'set' is defined to zero the high 32 bits. 580 bool IsEffectivelyImm13 = 581 IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096); 582 const MCExpr *ValExpr; 583 if (IsImm) 584 ValExpr = MCConstantExpr::create(ImmValue, getContext()); 585 else 586 ValExpr = MCValOp.getExpr(); 587 588 MCOperand PrevReg = MCOperand::createReg(Sparc::G0); 589 590 // If not just a signed imm13 value, then either we use a 'sethi' with a 591 // following 'or', or a 'sethi' by itself if there are no more 1 bits. 592 // In either case, start with the 'sethi'. 593 if (!IsEffectivelyImm13) { 594 MCInst TmpInst; 595 const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr); 596 TmpInst.setLoc(IDLoc); 597 TmpInst.setOpcode(SP::SETHIi); 598 TmpInst.addOperand(MCRegOp); 599 TmpInst.addOperand(MCOperand::createExpr(Expr)); 600 Instructions.push_back(TmpInst); 601 PrevReg = MCRegOp; 602 } 603 604 // The low bits require touching in 3 cases: 605 // * A non-immediate value will always require both instructions. 606 // * An effectively imm13 value needs only an 'or' instruction. 607 // * Otherwise, an immediate that is not effectively imm13 requires the 608 // 'or' only if bits remain after clearing the 22 bits that 'sethi' set. 609 // If the low bits are known zeros, there's nothing to do. 610 // In the second case, and only in that case, must we NOT clear 611 // bits of the immediate value via the %lo() assembler function. 612 // Note also, the 'or' instruction doesn't mind a large value in the case 613 // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean. 614 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) { 615 MCInst TmpInst; 616 const MCExpr *Expr; 617 if (IsEffectivelyImm13) 618 Expr = ValExpr; 619 else 620 Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr); 621 TmpInst.setLoc(IDLoc); 622 TmpInst.setOpcode(SP::ORri); 623 TmpInst.addOperand(MCRegOp); 624 TmpInst.addOperand(PrevReg); 625 TmpInst.addOperand(MCOperand::createExpr(Expr)); 626 Instructions.push_back(TmpInst); 627 } 628 return false; 629 } 630 631 bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 632 OperandVector &Operands, 633 MCStreamer &Out, 634 uint64_t &ErrorInfo, 635 bool MatchingInlineAsm) { 636 MCInst Inst; 637 SmallVector<MCInst, 8> Instructions; 638 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 639 MatchingInlineAsm); 640 switch (MatchResult) { 641 case Match_Success: { 642 switch (Inst.getOpcode()) { 643 default: 644 Inst.setLoc(IDLoc); 645 Instructions.push_back(Inst); 646 break; 647 case SP::SET: 648 if (expandSET(Inst, IDLoc, Instructions)) 649 return true; 650 break; 651 } 652 653 for (const MCInst &I : Instructions) { 654 Out.emitInstruction(I, getSTI()); 655 } 656 return false; 657 } 658 659 case Match_MissingFeature: 660 return Error(IDLoc, 661 "instruction requires a CPU feature not currently enabled"); 662 663 case Match_InvalidOperand: { 664 SMLoc ErrorLoc = IDLoc; 665 if (ErrorInfo != ~0ULL) { 666 if (ErrorInfo >= Operands.size()) 667 return Error(IDLoc, "too few operands for instruction"); 668 669 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc(); 670 if (ErrorLoc == SMLoc()) 671 ErrorLoc = IDLoc; 672 } 673 674 return Error(ErrorLoc, "invalid operand for instruction"); 675 } 676 case Match_MnemonicFail: 677 return Error(IDLoc, "invalid instruction mnemonic"); 678 } 679 llvm_unreachable("Implement any new match types added!"); 680 } 681 682 bool SparcAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 683 SMLoc &EndLoc) { 684 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 685 return Error(StartLoc, "invalid register name"); 686 return false; 687 } 688 689 OperandMatchResultTy SparcAsmParser::tryParseRegister(unsigned &RegNo, 690 SMLoc &StartLoc, 691 SMLoc &EndLoc) { 692 const AsmToken &Tok = Parser.getTok(); 693 StartLoc = Tok.getLoc(); 694 EndLoc = Tok.getEndLoc(); 695 RegNo = 0; 696 if (getLexer().getKind() != AsmToken::Percent) 697 return MatchOperand_NoMatch; 698 Parser.Lex(); 699 unsigned regKind = SparcOperand::rk_None; 700 if (matchRegisterName(Tok, RegNo, regKind)) { 701 Parser.Lex(); 702 return MatchOperand_Success; 703 } 704 705 getLexer().UnLex(Tok); 706 return MatchOperand_NoMatch; 707 } 708 709 static void applyMnemonicAliases(StringRef &Mnemonic, 710 const FeatureBitset &Features, 711 unsigned VariantID); 712 713 bool SparcAsmParser::ParseInstruction(ParseInstructionInfo &Info, 714 StringRef Name, SMLoc NameLoc, 715 OperandVector &Operands) { 716 717 // First operand in MCInst is instruction mnemonic. 718 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc)); 719 720 // apply mnemonic aliases, if any, so that we can parse operands correctly. 721 applyMnemonicAliases(Name, getAvailableFeatures(), 0); 722 723 if (getLexer().isNot(AsmToken::EndOfStatement)) { 724 // Read the first operand. 725 if (getLexer().is(AsmToken::Comma)) { 726 if (parseBranchModifiers(Operands) != MatchOperand_Success) { 727 SMLoc Loc = getLexer().getLoc(); 728 return Error(Loc, "unexpected token"); 729 } 730 } 731 if (parseOperand(Operands, Name) != MatchOperand_Success) { 732 SMLoc Loc = getLexer().getLoc(); 733 return Error(Loc, "unexpected token"); 734 } 735 736 while (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::Plus)) { 737 if (getLexer().is(AsmToken::Plus)) { 738 // Plus tokens are significant in software_traps (p83, sparcv8.pdf). We must capture them. 739 Operands.push_back(SparcOperand::CreateToken("+", Parser.getTok().getLoc())); 740 } 741 Parser.Lex(); // Eat the comma or plus. 742 // Parse and remember the operand. 743 if (parseOperand(Operands, Name) != MatchOperand_Success) { 744 SMLoc Loc = getLexer().getLoc(); 745 return Error(Loc, "unexpected token"); 746 } 747 } 748 } 749 if (getLexer().isNot(AsmToken::EndOfStatement)) { 750 SMLoc Loc = getLexer().getLoc(); 751 return Error(Loc, "unexpected token"); 752 } 753 Parser.Lex(); // Consume the EndOfStatement. 754 return false; 755 } 756 757 bool SparcAsmParser:: 758 ParseDirective(AsmToken DirectiveID) 759 { 760 StringRef IDVal = DirectiveID.getString(); 761 762 if (IDVal == ".register") { 763 // For now, ignore .register directive. 764 Parser.eatToEndOfStatement(); 765 return false; 766 } 767 if (IDVal == ".proc") { 768 // For compatibility, ignore this directive. 769 // (It's supposed to be an "optimization" in the Sun assembler) 770 Parser.eatToEndOfStatement(); 771 return false; 772 } 773 774 // Let the MC layer to handle other directives. 775 return true; 776 } 777 778 OperandMatchResultTy 779 SparcAsmParser::parseMEMOperand(OperandVector &Operands) { 780 SMLoc S, E; 781 782 std::unique_ptr<SparcOperand> LHS; 783 if (parseSparcAsmOperand(LHS) != MatchOperand_Success) 784 return MatchOperand_NoMatch; 785 786 // Single immediate operand 787 if (LHS->isImm()) { 788 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS))); 789 return MatchOperand_Success; 790 } 791 792 if (!LHS->isIntReg()) { 793 Error(LHS->getStartLoc(), "invalid register kind for this operand"); 794 return MatchOperand_ParseFail; 795 } 796 797 AsmToken Tok = getLexer().getTok(); 798 // The plus token may be followed by a register or an immediate value, the 799 // minus one is always interpreted as sign for the immediate value 800 if (Tok.is(AsmToken::Plus) || Tok.is(AsmToken::Minus)) { 801 (void)Parser.parseOptionalToken(AsmToken::Plus); 802 803 std::unique_ptr<SparcOperand> RHS; 804 if (parseSparcAsmOperand(RHS) != MatchOperand_Success) 805 return MatchOperand_NoMatch; 806 807 if (RHS->isReg() && !RHS->isIntReg()) { 808 Error(RHS->getStartLoc(), "invalid register kind for this operand"); 809 return MatchOperand_ParseFail; 810 } 811 812 Operands.push_back( 813 RHS->isImm() 814 ? SparcOperand::MorphToMEMri(LHS->getReg(), std::move(RHS)) 815 : SparcOperand::MorphToMEMrr(LHS->getReg(), std::move(RHS))); 816 817 return MatchOperand_Success; 818 } 819 820 Operands.push_back(SparcOperand::CreateMEMr(LHS->getReg(), S, E)); 821 return MatchOperand_Success; 822 } 823 824 template <unsigned N> 825 OperandMatchResultTy SparcAsmParser::parseShiftAmtImm(OperandVector &Operands) { 826 SMLoc S = Parser.getTok().getLoc(); 827 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 828 829 // This is a register, not an immediate 830 if (getLexer().getKind() == AsmToken::Percent) 831 return MatchOperand_NoMatch; 832 833 const MCExpr *Expr; 834 if (getParser().parseExpression(Expr)) 835 return MatchOperand_ParseFail; 836 837 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr); 838 if (!CE) { 839 Error(S, "constant expression expected"); 840 return MatchOperand_ParseFail; 841 } 842 843 if (!isUInt<N>(CE->getValue())) { 844 Error(S, "immediate shift value out of range"); 845 return MatchOperand_ParseFail; 846 } 847 848 Operands.push_back(SparcOperand::CreateImm(Expr, S, E)); 849 return MatchOperand_Success; 850 } 851 852 OperandMatchResultTy SparcAsmParser::parseMembarTag(OperandVector &Operands) { 853 SMLoc S = Parser.getTok().getLoc(); 854 const MCExpr *EVal; 855 int64_t ImmVal = 0; 856 857 std::unique_ptr<SparcOperand> Mask; 858 if (parseSparcAsmOperand(Mask) == MatchOperand_Success) { 859 if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(ImmVal) || 860 ImmVal < 0 || ImmVal > 127) { 861 Error(S, "invalid membar mask number"); 862 return MatchOperand_ParseFail; 863 } 864 } 865 866 while (getLexer().getKind() == AsmToken::Hash) { 867 SMLoc TagStart = getLexer().getLoc(); 868 Parser.Lex(); // Eat the '#'. 869 unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString()) 870 .Case("LoadLoad", 0x1) 871 .Case("StoreLoad", 0x2) 872 .Case("LoadStore", 0x4) 873 .Case("StoreStore", 0x8) 874 .Case("Lookaside", 0x10) 875 .Case("MemIssue", 0x20) 876 .Case("Sync", 0x40) 877 .Default(0); 878 879 Parser.Lex(); // Eat the identifier token. 880 881 if (!MaskVal) { 882 Error(TagStart, "unknown membar tag"); 883 return MatchOperand_ParseFail; 884 } 885 886 ImmVal |= MaskVal; 887 888 if (getLexer().getKind() == AsmToken::Pipe) 889 Parser.Lex(); // Eat the '|'. 890 } 891 892 EVal = MCConstantExpr::create(ImmVal, getContext()); 893 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 894 Operands.push_back(SparcOperand::CreateImm(EVal, S, E)); 895 return MatchOperand_Success; 896 } 897 898 OperandMatchResultTy SparcAsmParser::parseCallTarget(OperandVector &Operands) { 899 SMLoc S = Parser.getTok().getLoc(); 900 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 901 902 switch (getLexer().getKind()) { 903 default: 904 return MatchOperand_NoMatch; 905 case AsmToken::LParen: 906 case AsmToken::Integer: 907 case AsmToken::Identifier: 908 case AsmToken::Dot: 909 break; 910 } 911 912 const MCExpr *DestValue; 913 if (getParser().parseExpression(DestValue)) 914 return MatchOperand_NoMatch; 915 916 bool IsPic = getContext().getObjectFileInfo()->isPositionIndependent(); 917 SparcMCExpr::VariantKind Kind = 918 IsPic ? SparcMCExpr::VK_Sparc_WPLT30 : SparcMCExpr::VK_Sparc_WDISP30; 919 920 const MCExpr *DestExpr = SparcMCExpr::create(Kind, DestValue, getContext()); 921 Operands.push_back(SparcOperand::CreateImm(DestExpr, S, E)); 922 return MatchOperand_Success; 923 } 924 925 OperandMatchResultTy 926 SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 927 928 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 929 930 // If there wasn't a custom match, try the generic matcher below. Otherwise, 931 // there was a match, but an error occurred, in which case, just return that 932 // the operand parsing failed. 933 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) 934 return ResTy; 935 936 if (getLexer().is(AsmToken::LBrac)) { 937 // Memory operand 938 Operands.push_back(SparcOperand::CreateToken("[", 939 Parser.getTok().getLoc())); 940 Parser.Lex(); // Eat the [ 941 942 if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") { 943 SMLoc S = Parser.getTok().getLoc(); 944 if (getLexer().getKind() != AsmToken::Percent) 945 return MatchOperand_NoMatch; 946 Parser.Lex(); // eat % 947 948 unsigned RegNo, RegKind; 949 if (!matchRegisterName(Parser.getTok(), RegNo, RegKind)) 950 return MatchOperand_NoMatch; 951 952 Parser.Lex(); // Eat the identifier token. 953 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1); 954 Operands.push_back(SparcOperand::CreateReg(RegNo, RegKind, S, E)); 955 ResTy = MatchOperand_Success; 956 } else { 957 ResTy = parseMEMOperand(Operands); 958 } 959 960 if (ResTy != MatchOperand_Success) 961 return ResTy; 962 963 if (!getLexer().is(AsmToken::RBrac)) 964 return MatchOperand_ParseFail; 965 966 Operands.push_back(SparcOperand::CreateToken("]", 967 Parser.getTok().getLoc())); 968 Parser.Lex(); // Eat the ] 969 970 // Parse an optional address-space identifier after the address. 971 if (getLexer().is(AsmToken::Integer)) { 972 std::unique_ptr<SparcOperand> Op; 973 ResTy = parseSparcAsmOperand(Op, false); 974 if (ResTy != MatchOperand_Success || !Op) 975 return MatchOperand_ParseFail; 976 Operands.push_back(std::move(Op)); 977 } 978 return MatchOperand_Success; 979 } 980 981 std::unique_ptr<SparcOperand> Op; 982 983 ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call")); 984 if (ResTy != MatchOperand_Success || !Op) 985 return MatchOperand_ParseFail; 986 987 // Push the parsed operand into the list of operands 988 Operands.push_back(std::move(Op)); 989 990 return MatchOperand_Success; 991 } 992 993 OperandMatchResultTy 994 SparcAsmParser::parseSparcAsmOperand(std::unique_ptr<SparcOperand> &Op, 995 bool isCall) { 996 SMLoc S = Parser.getTok().getLoc(); 997 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 998 const MCExpr *EVal; 999 1000 Op = nullptr; 1001 switch (getLexer().getKind()) { 1002 default: break; 1003 1004 case AsmToken::Percent: 1005 Parser.Lex(); // Eat the '%'. 1006 unsigned RegNo; 1007 unsigned RegKind; 1008 if (matchRegisterName(Parser.getTok(), RegNo, RegKind)) { 1009 StringRef name = Parser.getTok().getString(); 1010 Parser.Lex(); // Eat the identifier token. 1011 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1012 switch (RegNo) { 1013 default: 1014 Op = SparcOperand::CreateReg(RegNo, RegKind, S, E); 1015 break; 1016 case Sparc::PSR: 1017 Op = SparcOperand::CreateToken("%psr", S); 1018 break; 1019 case Sparc::FSR: 1020 Op = SparcOperand::CreateToken("%fsr", S); 1021 break; 1022 case Sparc::FQ: 1023 Op = SparcOperand::CreateToken("%fq", S); 1024 break; 1025 case Sparc::CPSR: 1026 Op = SparcOperand::CreateToken("%csr", S); 1027 break; 1028 case Sparc::CPQ: 1029 Op = SparcOperand::CreateToken("%cq", S); 1030 break; 1031 case Sparc::WIM: 1032 Op = SparcOperand::CreateToken("%wim", S); 1033 break; 1034 case Sparc::TBR: 1035 Op = SparcOperand::CreateToken("%tbr", S); 1036 break; 1037 case Sparc::PC: 1038 Op = SparcOperand::CreateToken("%pc", S); 1039 break; 1040 case Sparc::ICC: 1041 if (name == "xcc") 1042 Op = SparcOperand::CreateToken("%xcc", S); 1043 else 1044 Op = SparcOperand::CreateToken("%icc", S); 1045 break; 1046 } 1047 break; 1048 } 1049 if (matchSparcAsmModifiers(EVal, E)) { 1050 E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1051 Op = SparcOperand::CreateImm(EVal, S, E); 1052 } 1053 break; 1054 1055 case AsmToken::Plus: 1056 case AsmToken::Minus: 1057 case AsmToken::Integer: 1058 case AsmToken::LParen: 1059 case AsmToken::Dot: 1060 case AsmToken::Identifier: 1061 if (getParser().parseExpression(EVal, E)) 1062 break; 1063 1064 int64_t Res; 1065 if (!EVal->evaluateAsAbsolute(Res)) { 1066 SparcMCExpr::VariantKind Kind = SparcMCExpr::VK_Sparc_13; 1067 1068 if (getContext().getObjectFileInfo()->isPositionIndependent()) { 1069 if (isCall) 1070 Kind = SparcMCExpr::VK_Sparc_WPLT30; 1071 else 1072 Kind = SparcMCExpr::VK_Sparc_GOT13; 1073 } 1074 EVal = SparcMCExpr::create(Kind, EVal, getContext()); 1075 } 1076 Op = SparcOperand::CreateImm(EVal, S, E); 1077 break; 1078 } 1079 return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; 1080 } 1081 1082 OperandMatchResultTy 1083 SparcAsmParser::parseBranchModifiers(OperandVector &Operands) { 1084 // parse (,a|,pn|,pt)+ 1085 1086 while (getLexer().is(AsmToken::Comma)) { 1087 Parser.Lex(); // Eat the comma 1088 1089 if (!getLexer().is(AsmToken::Identifier)) 1090 return MatchOperand_ParseFail; 1091 StringRef modName = Parser.getTok().getString(); 1092 if (modName == "a" || modName == "pn" || modName == "pt") { 1093 Operands.push_back(SparcOperand::CreateToken(modName, 1094 Parser.getTok().getLoc())); 1095 Parser.Lex(); // eat the identifier. 1096 } 1097 } 1098 return MatchOperand_Success; 1099 } 1100 1101 bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, unsigned &RegNo, 1102 unsigned &RegKind) { 1103 int64_t intVal = 0; 1104 RegNo = 0; 1105 RegKind = SparcOperand::rk_None; 1106 if (Tok.is(AsmToken::Identifier)) { 1107 StringRef name = Tok.getString(); 1108 1109 // %fp 1110 if (name.equals("fp")) { 1111 RegNo = Sparc::I6; 1112 RegKind = SparcOperand::rk_IntReg; 1113 return true; 1114 } 1115 // %sp 1116 if (name.equals("sp")) { 1117 RegNo = Sparc::O6; 1118 RegKind = SparcOperand::rk_IntReg; 1119 return true; 1120 } 1121 1122 if (name.equals("y")) { 1123 RegNo = Sparc::Y; 1124 RegKind = SparcOperand::rk_Special; 1125 return true; 1126 } 1127 1128 if (name.substr(0, 3).equals_insensitive("asr") && 1129 !name.substr(3).getAsInteger(10, intVal) && intVal > 0 && intVal < 32) { 1130 RegNo = ASRRegs[intVal]; 1131 RegKind = SparcOperand::rk_Special; 1132 return true; 1133 } 1134 1135 // %fprs is an alias of %asr6. 1136 if (name.equals("fprs")) { 1137 RegNo = ASRRegs[6]; 1138 RegKind = SparcOperand::rk_Special; 1139 return true; 1140 } 1141 1142 if (name.equals("icc")) { 1143 RegNo = Sparc::ICC; 1144 RegKind = SparcOperand::rk_Special; 1145 return true; 1146 } 1147 1148 if (name.equals("psr")) { 1149 RegNo = Sparc::PSR; 1150 RegKind = SparcOperand::rk_Special; 1151 return true; 1152 } 1153 1154 if (name.equals("fsr")) { 1155 RegNo = Sparc::FSR; 1156 RegKind = SparcOperand::rk_Special; 1157 return true; 1158 } 1159 1160 if (name.equals("fq")) { 1161 RegNo = Sparc::FQ; 1162 RegKind = SparcOperand::rk_Special; 1163 return true; 1164 } 1165 1166 if (name.equals("csr")) { 1167 RegNo = Sparc::CPSR; 1168 RegKind = SparcOperand::rk_Special; 1169 return true; 1170 } 1171 1172 if (name.equals("cq")) { 1173 RegNo = Sparc::CPQ; 1174 RegKind = SparcOperand::rk_Special; 1175 return true; 1176 } 1177 1178 if (name.equals("wim")) { 1179 RegNo = Sparc::WIM; 1180 RegKind = SparcOperand::rk_Special; 1181 return true; 1182 } 1183 1184 if (name.equals("tbr")) { 1185 RegNo = Sparc::TBR; 1186 RegKind = SparcOperand::rk_Special; 1187 return true; 1188 } 1189 1190 if (name.equals("xcc")) { 1191 // FIXME:: check 64bit. 1192 RegNo = Sparc::ICC; 1193 RegKind = SparcOperand::rk_Special; 1194 return true; 1195 } 1196 1197 // %fcc0 - %fcc3 1198 if (name.substr(0, 3).equals_insensitive("fcc") && 1199 !name.substr(3).getAsInteger(10, intVal) && intVal < 4) { 1200 // FIXME: check 64bit and handle %fcc1 - %fcc3 1201 RegNo = Sparc::FCC0 + intVal; 1202 RegKind = SparcOperand::rk_Special; 1203 return true; 1204 } 1205 1206 // %g0 - %g7 1207 if (name.substr(0, 1).equals_insensitive("g") && 1208 !name.substr(1).getAsInteger(10, intVal) && intVal < 8) { 1209 RegNo = IntRegs[intVal]; 1210 RegKind = SparcOperand::rk_IntReg; 1211 return true; 1212 } 1213 // %o0 - %o7 1214 if (name.substr(0, 1).equals_insensitive("o") && 1215 !name.substr(1).getAsInteger(10, intVal) && intVal < 8) { 1216 RegNo = IntRegs[8 + intVal]; 1217 RegKind = SparcOperand::rk_IntReg; 1218 return true; 1219 } 1220 if (name.substr(0, 1).equals_insensitive("l") && 1221 !name.substr(1).getAsInteger(10, intVal) && intVal < 8) { 1222 RegNo = IntRegs[16 + intVal]; 1223 RegKind = SparcOperand::rk_IntReg; 1224 return true; 1225 } 1226 if (name.substr(0, 1).equals_insensitive("i") && 1227 !name.substr(1).getAsInteger(10, intVal) && intVal < 8) { 1228 RegNo = IntRegs[24 + intVal]; 1229 RegKind = SparcOperand::rk_IntReg; 1230 return true; 1231 } 1232 // %f0 - %f31 1233 if (name.substr(0, 1).equals_insensitive("f") && 1234 !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 32) { 1235 RegNo = FloatRegs[intVal]; 1236 RegKind = SparcOperand::rk_FloatReg; 1237 return true; 1238 } 1239 // %f32 - %f62 1240 if (name.substr(0, 1).equals_insensitive("f") && 1241 !name.substr(1, 2).getAsInteger(10, intVal) && intVal >= 32 && 1242 intVal <= 62 && (intVal % 2 == 0)) { 1243 // FIXME: Check V9 1244 RegNo = DoubleRegs[intVal/2]; 1245 RegKind = SparcOperand::rk_DoubleReg; 1246 return true; 1247 } 1248 1249 // %r0 - %r31 1250 if (name.substr(0, 1).equals_insensitive("r") && 1251 !name.substr(1, 2).getAsInteger(10, intVal) && intVal < 31) { 1252 RegNo = IntRegs[intVal]; 1253 RegKind = SparcOperand::rk_IntReg; 1254 return true; 1255 } 1256 1257 // %c0 - %c31 1258 if (name.substr(0, 1).equals_insensitive("c") && 1259 !name.substr(1).getAsInteger(10, intVal) && intVal < 32) { 1260 RegNo = CoprocRegs[intVal]; 1261 RegKind = SparcOperand::rk_CoprocReg; 1262 return true; 1263 } 1264 1265 if (name.equals("tpc")) { 1266 RegNo = Sparc::TPC; 1267 RegKind = SparcOperand::rk_Special; 1268 return true; 1269 } 1270 if (name.equals("tnpc")) { 1271 RegNo = Sparc::TNPC; 1272 RegKind = SparcOperand::rk_Special; 1273 return true; 1274 } 1275 if (name.equals("tstate")) { 1276 RegNo = Sparc::TSTATE; 1277 RegKind = SparcOperand::rk_Special; 1278 return true; 1279 } 1280 if (name.equals("tt")) { 1281 RegNo = Sparc::TT; 1282 RegKind = SparcOperand::rk_Special; 1283 return true; 1284 } 1285 if (name.equals("tick")) { 1286 RegNo = Sparc::TICK; 1287 RegKind = SparcOperand::rk_Special; 1288 return true; 1289 } 1290 if (name.equals("tba")) { 1291 RegNo = Sparc::TBA; 1292 RegKind = SparcOperand::rk_Special; 1293 return true; 1294 } 1295 if (name.equals("pstate")) { 1296 RegNo = Sparc::PSTATE; 1297 RegKind = SparcOperand::rk_Special; 1298 return true; 1299 } 1300 if (name.equals("tl")) { 1301 RegNo = Sparc::TL; 1302 RegKind = SparcOperand::rk_Special; 1303 return true; 1304 } 1305 if (name.equals("pil")) { 1306 RegNo = Sparc::PIL; 1307 RegKind = SparcOperand::rk_Special; 1308 return true; 1309 } 1310 if (name.equals("cwp")) { 1311 RegNo = Sparc::CWP; 1312 RegKind = SparcOperand::rk_Special; 1313 return true; 1314 } 1315 if (name.equals("cansave")) { 1316 RegNo = Sparc::CANSAVE; 1317 RegKind = SparcOperand::rk_Special; 1318 return true; 1319 } 1320 if (name.equals("canrestore")) { 1321 RegNo = Sparc::CANRESTORE; 1322 RegKind = SparcOperand::rk_Special; 1323 return true; 1324 } 1325 if (name.equals("cleanwin")) { 1326 RegNo = Sparc::CLEANWIN; 1327 RegKind = SparcOperand::rk_Special; 1328 return true; 1329 } 1330 if (name.equals("otherwin")) { 1331 RegNo = Sparc::OTHERWIN; 1332 RegKind = SparcOperand::rk_Special; 1333 return true; 1334 } 1335 if (name.equals("wstate")) { 1336 RegNo = Sparc::WSTATE; 1337 RegKind = SparcOperand::rk_Special; 1338 return true; 1339 } 1340 if (name.equals("pc")) { 1341 RegNo = Sparc::PC; 1342 RegKind = SparcOperand::rk_Special; 1343 return true; 1344 } 1345 } 1346 return false; 1347 } 1348 1349 // Determine if an expression contains a reference to the symbol 1350 // "_GLOBAL_OFFSET_TABLE_". 1351 static bool hasGOTReference(const MCExpr *Expr) { 1352 switch (Expr->getKind()) { 1353 case MCExpr::Target: 1354 if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr)) 1355 return hasGOTReference(SE->getSubExpr()); 1356 break; 1357 1358 case MCExpr::Constant: 1359 break; 1360 1361 case MCExpr::Binary: { 1362 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); 1363 return hasGOTReference(BE->getLHS()) || hasGOTReference(BE->getRHS()); 1364 } 1365 1366 case MCExpr::SymbolRef: { 1367 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); 1368 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_"); 1369 } 1370 1371 case MCExpr::Unary: 1372 return hasGOTReference(cast<MCUnaryExpr>(Expr)->getSubExpr()); 1373 } 1374 return false; 1375 } 1376 1377 const SparcMCExpr * 1378 SparcAsmParser::adjustPICRelocation(SparcMCExpr::VariantKind VK, 1379 const MCExpr *subExpr) { 1380 // When in PIC mode, "%lo(...)" and "%hi(...)" behave differently. 1381 // If the expression refers contains _GLOBAL_OFFSET_TABLE, it is 1382 // actually a %pc10 or %pc22 relocation. Otherwise, they are interpreted 1383 // as %got10 or %got22 relocation. 1384 1385 if (getContext().getObjectFileInfo()->isPositionIndependent()) { 1386 switch(VK) { 1387 default: break; 1388 case SparcMCExpr::VK_Sparc_LO: 1389 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC10 1390 : SparcMCExpr::VK_Sparc_GOT10); 1391 break; 1392 case SparcMCExpr::VK_Sparc_HI: 1393 VK = (hasGOTReference(subExpr) ? SparcMCExpr::VK_Sparc_PC22 1394 : SparcMCExpr::VK_Sparc_GOT22); 1395 break; 1396 } 1397 } 1398 1399 return SparcMCExpr::create(VK, subExpr, getContext()); 1400 } 1401 1402 bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal, 1403 SMLoc &EndLoc) { 1404 AsmToken Tok = Parser.getTok(); 1405 if (!Tok.is(AsmToken::Identifier)) 1406 return false; 1407 1408 StringRef name = Tok.getString(); 1409 1410 SparcMCExpr::VariantKind VK = SparcMCExpr::parseVariantKind(name); 1411 1412 if (VK == SparcMCExpr::VK_Sparc_None) 1413 return false; 1414 1415 Parser.Lex(); // Eat the identifier. 1416 if (Parser.getTok().getKind() != AsmToken::LParen) 1417 return false; 1418 1419 Parser.Lex(); // Eat the LParen token. 1420 const MCExpr *subExpr; 1421 if (Parser.parseParenExpression(subExpr, EndLoc)) 1422 return false; 1423 1424 EVal = adjustPICRelocation(VK, subExpr); 1425 return true; 1426 } 1427 1428 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser() { 1429 RegisterMCAsmParser<SparcAsmParser> A(getTheSparcTarget()); 1430 RegisterMCAsmParser<SparcAsmParser> B(getTheSparcV9Target()); 1431 RegisterMCAsmParser<SparcAsmParser> C(getTheSparcelTarget()); 1432 } 1433 1434 #define GET_REGISTER_MATCHER 1435 #define GET_MATCHER_IMPLEMENTATION 1436 #include "SparcGenAsmMatcher.inc" 1437 1438 unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp, 1439 unsigned Kind) { 1440 SparcOperand &Op = (SparcOperand &)GOp; 1441 if (Op.isFloatOrDoubleReg()) { 1442 switch (Kind) { 1443 default: break; 1444 case MCK_DFPRegs: 1445 if (!Op.isFloatReg() || SparcOperand::MorphToDoubleReg(Op)) 1446 return MCTargetAsmParser::Match_Success; 1447 break; 1448 case MCK_QFPRegs: 1449 if (SparcOperand::MorphToQuadReg(Op)) 1450 return MCTargetAsmParser::Match_Success; 1451 break; 1452 } 1453 } 1454 if (Op.isIntReg() && Kind == MCK_IntPair) { 1455 if (SparcOperand::MorphToIntPairReg(Op)) 1456 return MCTargetAsmParser::Match_Success; 1457 } 1458 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) { 1459 if (SparcOperand::MorphToCoprocPairReg(Op)) 1460 return MCTargetAsmParser::Match_Success; 1461 } 1462 return Match_InvalidOperand; 1463 } 1464