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