1 //===-- HexagonAsmPrinter.cpp - Print machine instrs to Hexagon assembly --===// 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 // This file contains a printer that converts from our internal representation 11 // of machine-dependent LLVM code to Hexagon assembly language. This printer is 12 // the output mechanism used by `llc'. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "Hexagon.h" 17 #include "HexagonAsmPrinter.h" 18 #include "HexagonMachineFunctionInfo.h" 19 #include "HexagonSubtarget.h" 20 #include "HexagonTargetMachine.h" 21 #include "MCTargetDesc/HexagonInstPrinter.h" 22 #include "MCTargetDesc/HexagonMCInstrInfo.h" 23 #include "MCTargetDesc/HexagonMCShuffler.h" 24 #include "llvm/ADT/SmallString.h" 25 #include "llvm/ADT/SmallVector.h" 26 #include "llvm/ADT/StringExtras.h" 27 #include "llvm/Analysis/ConstantFolding.h" 28 #include "llvm/CodeGen/AsmPrinter.h" 29 #include "llvm/CodeGen/MachineFunctionPass.h" 30 #include "llvm/CodeGen/MachineInstr.h" 31 #include "llvm/CodeGen/MachineInstrBuilder.h" 32 #include "llvm/CodeGen/MachineModuleInfo.h" 33 #include "llvm/IR/Constants.h" 34 #include "llvm/IR/DataLayout.h" 35 #include "llvm/IR/DerivedTypes.h" 36 #include "llvm/IR/Mangler.h" 37 #include "llvm/IR/Module.h" 38 #include "llvm/MC/MCAsmInfo.h" 39 #include "llvm/MC/MCContext.h" 40 #include "llvm/MC/MCExpr.h" 41 #include "llvm/MC/MCInst.h" 42 #include "llvm/MC/MCSection.h" 43 #include "llvm/MC/MCSectionELF.h" 44 #include "llvm/MC/MCStreamer.h" 45 #include "llvm/MC/MCSymbol.h" 46 #include "llvm/Support/CommandLine.h" 47 #include "llvm/Support/Compiler.h" 48 #include "llvm/Support/Debug.h" 49 #include "llvm/Support/ELF.h" 50 #include "llvm/Support/Format.h" 51 #include "llvm/Support/MathExtras.h" 52 #include "llvm/Support/TargetRegistry.h" 53 #include "llvm/Support/raw_ostream.h" 54 #include "llvm/Target/TargetInstrInfo.h" 55 #include "llvm/Target/TargetLoweringObjectFile.h" 56 #include "llvm/Target/TargetOptions.h" 57 #include "llvm/Target/TargetRegisterInfo.h" 58 59 using namespace llvm; 60 61 namespace llvm { 62 void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI, 63 MCInst &MCB, HexagonAsmPrinter &AP); 64 } 65 66 #define DEBUG_TYPE "asm-printer" 67 68 static cl::opt<bool> AlignCalls( 69 "hexagon-align-calls", cl::Hidden, cl::init(true), 70 cl::desc("Insert falign after call instruction for Hexagon target")); 71 72 // Given a scalar register return its pair. 73 inline static unsigned getHexagonRegisterPair(unsigned Reg, 74 const MCRegisterInfo *RI) { 75 assert(Hexagon::IntRegsRegClass.contains(Reg)); 76 MCSuperRegIterator SR(Reg, RI, false); 77 unsigned Pair = *SR; 78 assert(Hexagon::DoubleRegsRegClass.contains(Pair)); 79 return Pair; 80 } 81 82 HexagonAsmPrinter::HexagonAsmPrinter(TargetMachine &TM, 83 std::unique_ptr<MCStreamer> Streamer) 84 : AsmPrinter(TM, std::move(Streamer)), Subtarget(nullptr) {} 85 86 void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 87 raw_ostream &O) { 88 const MachineOperand &MO = MI->getOperand(OpNo); 89 90 switch (MO.getType()) { 91 default: llvm_unreachable ("<unknown operand type>"); 92 case MachineOperand::MO_Register: 93 O << HexagonInstPrinter::getRegisterName(MO.getReg()); 94 return; 95 case MachineOperand::MO_Immediate: 96 O << MO.getImm(); 97 return; 98 case MachineOperand::MO_MachineBasicBlock: 99 MO.getMBB()->getSymbol()->print(O, MAI); 100 return; 101 case MachineOperand::MO_ConstantPoolIndex: 102 GetCPISymbol(MO.getIndex())->print(O, MAI); 103 return; 104 case MachineOperand::MO_GlobalAddress: 105 // Computing the address of a global symbol, not calling it. 106 getSymbol(MO.getGlobal())->print(O, MAI); 107 printOffset(MO.getOffset(), O); 108 return; 109 } 110 } 111 112 // 113 // isBlockOnlyReachableByFallthrough - We need to override this since the 114 // default AsmPrinter does not print labels for any basic block that 115 // is only reachable by a fall through. That works for all cases except 116 // for the case in which the basic block is reachable by a fall through but 117 // through an indirect from a jump table. In this case, the jump table 118 // will contain a label not defined by AsmPrinter. 119 // 120 bool HexagonAsmPrinter:: 121 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { 122 if (MBB->hasAddressTaken()) 123 return false; 124 return AsmPrinter::isBlockOnlyReachableByFallthrough(MBB); 125 } 126 127 128 /// PrintAsmOperand - Print out an operand for an inline asm expression. 129 /// 130 bool HexagonAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 131 unsigned AsmVariant, 132 const char *ExtraCode, 133 raw_ostream &OS) { 134 // Does this asm operand have a single letter operand modifier? 135 if (ExtraCode && ExtraCode[0]) { 136 if (ExtraCode[1] != 0) 137 return true; // Unknown modifier. 138 139 switch (ExtraCode[0]) { 140 default: 141 // See if this is a generic print operand 142 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, OS); 143 case 'c': // Don't print "$" before a global var name or constant. 144 // Hexagon never has a prefix. 145 printOperand(MI, OpNo, OS); 146 return false; 147 case 'L': // Write second word of DImode reference. 148 // Verify that this operand has two consecutive registers. 149 if (!MI->getOperand(OpNo).isReg() || 150 OpNo+1 == MI->getNumOperands() || 151 !MI->getOperand(OpNo+1).isReg()) 152 return true; 153 ++OpNo; // Return the high-part. 154 break; 155 case 'I': 156 // Write 'i' if an integer constant, otherwise nothing. Used to print 157 // addi vs add, etc. 158 if (MI->getOperand(OpNo).isImm()) 159 OS << "i"; 160 return false; 161 } 162 } 163 164 printOperand(MI, OpNo, OS); 165 return false; 166 } 167 168 bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 169 unsigned OpNo, unsigned AsmVariant, 170 const char *ExtraCode, 171 raw_ostream &O) { 172 if (ExtraCode && ExtraCode[0]) 173 return true; // Unknown modifier. 174 175 const MachineOperand &Base = MI->getOperand(OpNo); 176 const MachineOperand &Offset = MI->getOperand(OpNo+1); 177 178 if (Base.isReg()) 179 printOperand(MI, OpNo, O); 180 else 181 llvm_unreachable("Unimplemented"); 182 183 if (Offset.isImm()) { 184 if (Offset.getImm()) 185 O << " + #" << Offset.getImm(); 186 } 187 else 188 llvm_unreachable("Unimplemented"); 189 190 return false; 191 } 192 193 static MCSymbol *smallData(AsmPrinter &AP, const MachineInstr &MI, 194 MCStreamer &OutStreamer, const MCOperand &Imm, 195 int AlignSize) { 196 MCSymbol *Sym; 197 int64_t Value; 198 if (Imm.getExpr()->evaluateAsAbsolute(Value)) { 199 StringRef sectionPrefix; 200 std::string ImmString; 201 StringRef Name; 202 if (AlignSize == 8) { 203 Name = ".CONST_0000000000000000"; 204 sectionPrefix = ".gnu.linkonce.l8"; 205 ImmString = utohexstr(Value); 206 } else { 207 Name = ".CONST_00000000"; 208 sectionPrefix = ".gnu.linkonce.l4"; 209 ImmString = utohexstr(static_cast<uint32_t>(Value)); 210 } 211 212 std::string symbolName = // Yes, leading zeros are kept. 213 Name.drop_back(ImmString.size()).str() + ImmString; 214 std::string sectionName = sectionPrefix.str() + symbolName; 215 216 MCSectionELF *Section = OutStreamer.getContext().getELFSection( 217 sectionName, ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 218 OutStreamer.SwitchSection(Section); 219 220 Sym = AP.OutContext.getOrCreateSymbol(Twine(symbolName)); 221 if (Sym->isUndefined()) { 222 OutStreamer.EmitLabel(Sym); 223 OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global); 224 OutStreamer.EmitIntValue(Value, AlignSize); 225 OutStreamer.EmitCodeAlignment(AlignSize); 226 } 227 } else { 228 assert(Imm.isExpr() && "Expected expression and found none"); 229 const MachineOperand &MO = MI.getOperand(1); 230 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI()); 231 MCSymbol *MOSymbol = nullptr; 232 if (MO.isGlobal()) 233 MOSymbol = AP.getSymbol(MO.getGlobal()); 234 else if (MO.isCPI()) 235 MOSymbol = AP.GetCPISymbol(MO.getIndex()); 236 else if (MO.isJTI()) 237 MOSymbol = AP.GetJTISymbol(MO.getIndex()); 238 else 239 llvm_unreachable("Unknown operand type!"); 240 241 StringRef SymbolName = MOSymbol->getName(); 242 std::string LitaName = ".CONST_" + SymbolName.str(); 243 244 MCSectionELF *Section = OutStreamer.getContext().getELFSection( 245 ".lita", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 246 247 OutStreamer.SwitchSection(Section); 248 Sym = AP.OutContext.getOrCreateSymbol(Twine(LitaName)); 249 if (Sym->isUndefined()) { 250 OutStreamer.EmitLabel(Sym); 251 OutStreamer.EmitSymbolAttribute(Sym, MCSA_Local); 252 OutStreamer.EmitValue(Imm.getExpr(), AlignSize); 253 OutStreamer.EmitCodeAlignment(AlignSize); 254 } 255 } 256 return Sym; 257 } 258 259 void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst, 260 const MachineInstr &MI) { 261 MCInst &MappedInst = static_cast <MCInst &>(Inst); 262 const MCRegisterInfo *RI = OutStreamer->getContext().getRegisterInfo(); 263 264 switch (Inst.getOpcode()) { 265 default: return; 266 267 // "$dst = CONST64(#$src1)", 268 case Hexagon::CONST64_Float_Real: 269 case Hexagon::CONST64_Int_Real: 270 if (!OutStreamer->hasRawTextSupport()) { 271 const MCOperand &Imm = MappedInst.getOperand(1); 272 MCSectionSubPair Current = OutStreamer->getCurrentSection(); 273 274 MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 8); 275 276 OutStreamer->SwitchSection(Current.first, Current.second); 277 MCInst TmpInst; 278 MCOperand &Reg = MappedInst.getOperand(0); 279 TmpInst.setOpcode(Hexagon::L2_loadrdgp); 280 TmpInst.addOperand(Reg); 281 TmpInst.addOperand(MCOperand::createExpr( 282 MCSymbolRefExpr::create(Sym, OutContext))); 283 MappedInst = TmpInst; 284 285 } 286 break; 287 case Hexagon::CONST32: 288 case Hexagon::CONST32_Float_Real: 289 case Hexagon::CONST32_Int_Real: 290 case Hexagon::FCONST32_nsdata: 291 if (!OutStreamer->hasRawTextSupport()) { 292 MCOperand &Imm = MappedInst.getOperand(1); 293 MCSectionSubPair Current = OutStreamer->getCurrentSection(); 294 MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 4); 295 OutStreamer->SwitchSection(Current.first, Current.second); 296 MCInst TmpInst; 297 MCOperand &Reg = MappedInst.getOperand(0); 298 TmpInst.setOpcode(Hexagon::L2_loadrigp); 299 TmpInst.addOperand(Reg); 300 TmpInst.addOperand(MCOperand::createExpr( 301 MCSymbolRefExpr::create(Sym, OutContext))); 302 MappedInst = TmpInst; 303 } 304 break; 305 306 // C2_pxfer_map maps to C2_or instruction. Though, it's possible to use 307 // C2_or during instruction selection itself but it results 308 // into suboptimal code. 309 case Hexagon::C2_pxfer_map: { 310 MCOperand &Ps = Inst.getOperand(1); 311 MappedInst.setOpcode(Hexagon::C2_or); 312 MappedInst.addOperand(Ps); 313 return; 314 } 315 316 // Vector reduce complex multiply by scalar, Rt & 1 map to :hi else :lo 317 // The insn is mapped from the 4 operand to the 3 operand raw form taking 318 // 3 register pairs. 319 case Hexagon::M2_vrcmpys_acc_s1: { 320 MCOperand &Rt = Inst.getOperand(3); 321 assert (Rt.isReg() && "Expected register and none was found"); 322 unsigned Reg = RI->getEncodingValue(Rt.getReg()); 323 if (Reg & 1) 324 MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h); 325 else 326 MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l); 327 Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI)); 328 return; 329 } 330 case Hexagon::M2_vrcmpys_s1: { 331 MCOperand &Rt = Inst.getOperand(2); 332 assert (Rt.isReg() && "Expected register and none was found"); 333 unsigned Reg = RI->getEncodingValue(Rt.getReg()); 334 if (Reg & 1) 335 MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_h); 336 else 337 MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_l); 338 Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI)); 339 return; 340 } 341 342 case Hexagon::M2_vrcmpys_s1rp: { 343 MCOperand &Rt = Inst.getOperand(2); 344 assert (Rt.isReg() && "Expected register and none was found"); 345 unsigned Reg = RI->getEncodingValue(Rt.getReg()); 346 if (Reg & 1) 347 MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h); 348 else 349 MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l); 350 Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI)); 351 return; 352 } 353 354 case Hexagon::A4_boundscheck: { 355 MCOperand &Rs = Inst.getOperand(1); 356 assert (Rs.isReg() && "Expected register and none was found"); 357 unsigned Reg = RI->getEncodingValue(Rs.getReg()); 358 if (Reg & 1) // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2 359 MappedInst.setOpcode(Hexagon::A4_boundscheck_hi); 360 else // raw:lo 361 MappedInst.setOpcode(Hexagon::A4_boundscheck_lo); 362 Rs.setReg(getHexagonRegisterPair(Rs.getReg(), RI)); 363 return; 364 } 365 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: { 366 MCOperand &MO = MappedInst.getOperand(2); 367 int64_t Imm; 368 MCExpr const *Expr = MO.getExpr(); 369 bool Success = Expr->evaluateAsAbsolute(Imm); 370 assert (Success && "Expected immediate and none was found");(void)Success; 371 MCInst TmpInst; 372 if (Imm == 0) { 373 TmpInst.setOpcode(Hexagon::S2_vsathub); 374 TmpInst.addOperand(MappedInst.getOperand(0)); 375 TmpInst.addOperand(MappedInst.getOperand(1)); 376 MappedInst = TmpInst; 377 return; 378 } 379 TmpInst.setOpcode(Hexagon::S5_asrhub_rnd_sat); 380 TmpInst.addOperand(MappedInst.getOperand(0)); 381 TmpInst.addOperand(MappedInst.getOperand(1)); 382 const MCExpr *One = MCConstantExpr::create(1, OutContext); 383 const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext); 384 TmpInst.addOperand(MCOperand::createExpr(Sub)); 385 MappedInst = TmpInst; 386 return; 387 } 388 case Hexagon::S5_vasrhrnd_goodsyntax: 389 case Hexagon::S2_asr_i_p_rnd_goodsyntax: { 390 MCOperand &MO2 = MappedInst.getOperand(2); 391 MCExpr const *Expr = MO2.getExpr(); 392 int64_t Imm; 393 bool Success = Expr->evaluateAsAbsolute(Imm); 394 assert (Success && "Expected immediate and none was found");(void)Success; 395 MCInst TmpInst; 396 if (Imm == 0) { 397 TmpInst.setOpcode(Hexagon::A2_combinew); 398 TmpInst.addOperand(MappedInst.getOperand(0)); 399 MCOperand &MO1 = MappedInst.getOperand(1); 400 unsigned High = RI->getSubReg(MO1.getReg(), Hexagon::subreg_hireg); 401 unsigned Low = RI->getSubReg(MO1.getReg(), Hexagon::subreg_loreg); 402 // Add a new operand for the second register in the pair. 403 TmpInst.addOperand(MCOperand::createReg(High)); 404 TmpInst.addOperand(MCOperand::createReg(Low)); 405 MappedInst = TmpInst; 406 return; 407 } 408 409 if (Inst.getOpcode() == Hexagon::S2_asr_i_p_rnd_goodsyntax) 410 TmpInst.setOpcode(Hexagon::S2_asr_i_p_rnd); 411 else 412 TmpInst.setOpcode(Hexagon::S5_vasrhrnd); 413 TmpInst.addOperand(MappedInst.getOperand(0)); 414 TmpInst.addOperand(MappedInst.getOperand(1)); 415 const MCExpr *One = MCConstantExpr::create(1, OutContext); 416 const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext); 417 TmpInst.addOperand(MCOperand::createExpr(Sub)); 418 MappedInst = TmpInst; 419 return; 420 } 421 // if ("#u5==0") Assembler mapped to: "Rd=Rs"; else Rd=asr(Rs,#u5-1):rnd 422 case Hexagon::S2_asr_i_r_rnd_goodsyntax: { 423 MCOperand &MO = Inst.getOperand(2); 424 MCExpr const *Expr = MO.getExpr(); 425 int64_t Imm; 426 bool Success = Expr->evaluateAsAbsolute(Imm); 427 assert (Success && "Expected immediate and none was found");(void)Success; 428 MCInst TmpInst; 429 if (Imm == 0) { 430 TmpInst.setOpcode(Hexagon::A2_tfr); 431 TmpInst.addOperand(MappedInst.getOperand(0)); 432 TmpInst.addOperand(MappedInst.getOperand(1)); 433 MappedInst = TmpInst; 434 return; 435 } 436 TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd); 437 TmpInst.addOperand(MappedInst.getOperand(0)); 438 TmpInst.addOperand(MappedInst.getOperand(1)); 439 const MCExpr *One = MCConstantExpr::create(1, OutContext); 440 const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext); 441 TmpInst.addOperand(MCOperand::createExpr(Sub)); 442 MappedInst = TmpInst; 443 return; 444 } 445 case Hexagon::TFRI_f: 446 MappedInst.setOpcode(Hexagon::A2_tfrsi); 447 return; 448 case Hexagon::TFRI_cPt_f: 449 MappedInst.setOpcode(Hexagon::C2_cmoveit); 450 return; 451 case Hexagon::TFRI_cNotPt_f: 452 MappedInst.setOpcode(Hexagon::C2_cmoveif); 453 return; 454 case Hexagon::MUX_ri_f: 455 MappedInst.setOpcode(Hexagon::C2_muxri); 456 return; 457 case Hexagon::MUX_ir_f: 458 MappedInst.setOpcode(Hexagon::C2_muxir); 459 return; 460 461 // Translate a "$Rdd = #imm" to "$Rdd = combine(#[-1,0], #imm)" 462 case Hexagon::A2_tfrpi: { 463 MCInst TmpInst; 464 MCOperand &Rdd = MappedInst.getOperand(0); 465 MCOperand &MO = MappedInst.getOperand(1); 466 467 TmpInst.setOpcode(Hexagon::A2_combineii); 468 TmpInst.addOperand(Rdd); 469 int64_t Imm; 470 bool Success = MO.getExpr()->evaluateAsAbsolute(Imm); 471 if (Success && Imm < 0) { 472 const MCExpr *MOne = MCConstantExpr::create(-1, OutContext); 473 TmpInst.addOperand(MCOperand::createExpr(MOne)); 474 } else { 475 const MCExpr *Zero = MCConstantExpr::create(0, OutContext); 476 TmpInst.addOperand(MCOperand::createExpr(Zero)); 477 } 478 TmpInst.addOperand(MO); 479 MappedInst = TmpInst; 480 return; 481 } 482 // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)" 483 case Hexagon::A2_tfrp: { 484 MCOperand &MO = MappedInst.getOperand(1); 485 unsigned High = RI->getSubReg(MO.getReg(), Hexagon::subreg_hireg); 486 unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::subreg_loreg); 487 MO.setReg(High); 488 // Add a new operand for the second register in the pair. 489 MappedInst.addOperand(MCOperand::createReg(Low)); 490 MappedInst.setOpcode(Hexagon::A2_combinew); 491 return; 492 } 493 494 case Hexagon::A2_tfrpt: 495 case Hexagon::A2_tfrpf: { 496 MCOperand &MO = MappedInst.getOperand(2); 497 unsigned High = RI->getSubReg(MO.getReg(), Hexagon::subreg_hireg); 498 unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::subreg_loreg); 499 MO.setReg(High); 500 // Add a new operand for the second register in the pair. 501 MappedInst.addOperand(MCOperand::createReg(Low)); 502 MappedInst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt) 503 ? Hexagon::C2_ccombinewt 504 : Hexagon::C2_ccombinewf); 505 return; 506 } 507 case Hexagon::A2_tfrptnew: 508 case Hexagon::A2_tfrpfnew: { 509 MCOperand &MO = MappedInst.getOperand(2); 510 unsigned High = RI->getSubReg(MO.getReg(), Hexagon::subreg_hireg); 511 unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::subreg_loreg); 512 MO.setReg(High); 513 // Add a new operand for the second register in the pair. 514 MappedInst.addOperand(MCOperand::createReg(Low)); 515 MappedInst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew) 516 ? Hexagon::C2_ccombinewnewt 517 : Hexagon::C2_ccombinewnewf); 518 return; 519 } 520 521 case Hexagon::M2_mpysmi: { 522 MCOperand &Imm = MappedInst.getOperand(2); 523 MCExpr const *Expr = Imm.getExpr(); 524 int64_t Value; 525 bool Success = Expr->evaluateAsAbsolute(Value); 526 assert(Success);(void)Success; 527 if (Value < 0 && Value > -256) { 528 MappedInst.setOpcode(Hexagon::M2_mpysin); 529 Imm.setExpr(MCUnaryExpr::createMinus(Expr, OutContext)); 530 } 531 else 532 MappedInst.setOpcode(Hexagon::M2_mpysip); 533 return; 534 } 535 536 case Hexagon::A2_addsp: { 537 MCOperand &Rt = Inst.getOperand(1); 538 assert (Rt.isReg() && "Expected register and none was found"); 539 unsigned Reg = RI->getEncodingValue(Rt.getReg()); 540 if (Reg & 1) 541 MappedInst.setOpcode(Hexagon::A2_addsph); 542 else 543 MappedInst.setOpcode(Hexagon::A2_addspl); 544 Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI)); 545 return; 546 } 547 case Hexagon::HEXAGON_V6_vd0_pseudo: 548 case Hexagon::HEXAGON_V6_vd0_pseudo_128B: { 549 MCInst TmpInst; 550 assert (Inst.getOperand(0).isReg() && 551 "Expected register and none was found"); 552 553 TmpInst.setOpcode(Hexagon::V6_vxor); 554 TmpInst.addOperand(Inst.getOperand(0)); 555 TmpInst.addOperand(Inst.getOperand(0)); 556 TmpInst.addOperand(Inst.getOperand(0)); 557 MappedInst = TmpInst; 558 return; 559 } 560 561 } 562 } 563 564 565 /// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to 566 /// the current output stream. 567 /// 568 void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { 569 MCInst MCB = HexagonMCInstrInfo::createBundle(); 570 const MCInstrInfo &MCII = *Subtarget->getInstrInfo(); 571 572 if (MI->isBundle()) { 573 const MachineBasicBlock* MBB = MI->getParent(); 574 MachineBasicBlock::const_instr_iterator MII = MI->getIterator(); 575 unsigned IgnoreCount = 0; 576 577 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII) 578 if (MII->getOpcode() == TargetOpcode::DBG_VALUE || 579 MII->getOpcode() == TargetOpcode::IMPLICIT_DEF) 580 ++IgnoreCount; 581 else 582 HexagonLowerToMC(MCII, &*MII, MCB, *this); 583 } 584 else 585 HexagonLowerToMC(MCII, MI, MCB, *this); 586 587 bool Ok = HexagonMCInstrInfo::canonicalizePacket( 588 MCII, *Subtarget, OutStreamer->getContext(), MCB, nullptr); 589 assert(Ok); 590 (void)Ok; 591 if(HexagonMCInstrInfo::bundleSize(MCB) == 0) 592 return; 593 OutStreamer->EmitInstruction(MCB, getSubtargetInfo()); 594 } 595 596 extern "C" void LLVMInitializeHexagonAsmPrinter() { 597 RegisterAsmPrinter<HexagonAsmPrinter> X(TheHexagonTarget); 598 } 599