1480093f4SDimitry Andric //===-- VEAsmPrinter.cpp - VE LLVM assembly writer ------------------------===// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric // 9480093f4SDimitry Andric // This file contains a printer that converts from our internal representation 10480093f4SDimitry Andric // of machine-dependent LLVM code to GAS-format VE assembly language. 11480093f4SDimitry Andric // 12480093f4SDimitry Andric //===----------------------------------------------------------------------===// 13480093f4SDimitry Andric 14*5ffd83dbSDimitry Andric #include "MCTargetDesc/VEInstPrinter.h" 15*5ffd83dbSDimitry Andric #include "MCTargetDesc/VEMCExpr.h" 16480093f4SDimitry Andric #include "MCTargetDesc/VETargetStreamer.h" 17*5ffd83dbSDimitry Andric #include "TargetInfo/VETargetInfo.h" 18480093f4SDimitry Andric #include "VE.h" 19480093f4SDimitry Andric #include "VEInstrInfo.h" 20480093f4SDimitry Andric #include "VETargetMachine.h" 21480093f4SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 22480093f4SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 23480093f4SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 24480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 25480093f4SDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 26480093f4SDimitry Andric #include "llvm/IR/Mangler.h" 27480093f4SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 28480093f4SDimitry Andric #include "llvm/MC/MCContext.h" 29480093f4SDimitry Andric #include "llvm/MC/MCInst.h" 30480093f4SDimitry Andric #include "llvm/MC/MCInstBuilder.h" 31480093f4SDimitry Andric #include "llvm/MC/MCStreamer.h" 32480093f4SDimitry Andric #include "llvm/MC/MCSymbol.h" 33480093f4SDimitry Andric #include "llvm/Support/TargetRegistry.h" 34480093f4SDimitry Andric #include "llvm/Support/raw_ostream.h" 35480093f4SDimitry Andric using namespace llvm; 36480093f4SDimitry Andric 37480093f4SDimitry Andric #define DEBUG_TYPE "ve-asmprinter" 38480093f4SDimitry Andric 39480093f4SDimitry Andric namespace { 40480093f4SDimitry Andric class VEAsmPrinter : public AsmPrinter { 41480093f4SDimitry Andric VETargetStreamer &getTargetStreamer() { 42480093f4SDimitry Andric return static_cast<VETargetStreamer &>(*OutStreamer->getTargetStreamer()); 43480093f4SDimitry Andric } 44480093f4SDimitry Andric 45480093f4SDimitry Andric public: 46480093f4SDimitry Andric explicit VEAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) 47480093f4SDimitry Andric : AsmPrinter(TM, std::move(Streamer)) {} 48480093f4SDimitry Andric 49480093f4SDimitry Andric StringRef getPassName() const override { return "VE Assembly Printer"; } 50480093f4SDimitry Andric 51*5ffd83dbSDimitry Andric void lowerGETGOTAndEmitMCInsts(const MachineInstr *MI, 52*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI); 53*5ffd83dbSDimitry Andric void lowerGETFunPLTAndEmitMCInsts(const MachineInstr *MI, 54*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI); 55*5ffd83dbSDimitry Andric void lowerGETTLSAddrAndEmitMCInsts(const MachineInstr *MI, 56*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI); 57*5ffd83dbSDimitry Andric 58*5ffd83dbSDimitry Andric void emitInstruction(const MachineInstr *MI) override; 59480093f4SDimitry Andric 60480093f4SDimitry Andric static const char *getRegisterName(unsigned RegNo) { 61480093f4SDimitry Andric return VEInstPrinter::getRegisterName(RegNo); 62480093f4SDimitry Andric } 63480093f4SDimitry Andric }; 64480093f4SDimitry Andric } // end of anonymous namespace 65480093f4SDimitry Andric 66*5ffd83dbSDimitry Andric static MCOperand createVEMCOperand(VEMCExpr::VariantKind Kind, MCSymbol *Sym, 67*5ffd83dbSDimitry Andric MCContext &OutContext) { 68*5ffd83dbSDimitry Andric const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Sym, OutContext); 69*5ffd83dbSDimitry Andric const VEMCExpr *expr = VEMCExpr::create(Kind, MCSym, OutContext); 70*5ffd83dbSDimitry Andric return MCOperand::createExpr(expr); 71*5ffd83dbSDimitry Andric } 72*5ffd83dbSDimitry Andric 73*5ffd83dbSDimitry Andric static MCOperand createGOTRelExprOp(VEMCExpr::VariantKind Kind, 74*5ffd83dbSDimitry Andric MCSymbol *GOTLabel, MCContext &OutContext) { 75*5ffd83dbSDimitry Andric const MCSymbolRefExpr *GOT = MCSymbolRefExpr::create(GOTLabel, OutContext); 76*5ffd83dbSDimitry Andric const VEMCExpr *expr = VEMCExpr::create(Kind, GOT, OutContext); 77*5ffd83dbSDimitry Andric return MCOperand::createExpr(expr); 78*5ffd83dbSDimitry Andric } 79*5ffd83dbSDimitry Andric 80*5ffd83dbSDimitry Andric static void emitSIC(MCStreamer &OutStreamer, MCOperand &RD, 81*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 82*5ffd83dbSDimitry Andric MCInst SICInst; 83*5ffd83dbSDimitry Andric SICInst.setOpcode(VE::SIC); 84*5ffd83dbSDimitry Andric SICInst.addOperand(RD); 85*5ffd83dbSDimitry Andric OutStreamer.emitInstruction(SICInst, STI); 86*5ffd83dbSDimitry Andric } 87*5ffd83dbSDimitry Andric 88*5ffd83dbSDimitry Andric static void emitBSIC(MCStreamer &OutStreamer, MCOperand &R1, MCOperand &R2, 89*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 90*5ffd83dbSDimitry Andric MCInst BSICInst; 91*5ffd83dbSDimitry Andric BSICInst.setOpcode(VE::BSICrii); 92*5ffd83dbSDimitry Andric BSICInst.addOperand(R1); 93*5ffd83dbSDimitry Andric BSICInst.addOperand(R2); 94*5ffd83dbSDimitry Andric MCOperand czero = MCOperand::createImm(0); 95*5ffd83dbSDimitry Andric BSICInst.addOperand(czero); 96*5ffd83dbSDimitry Andric BSICInst.addOperand(czero); 97*5ffd83dbSDimitry Andric OutStreamer.emitInstruction(BSICInst, STI); 98*5ffd83dbSDimitry Andric } 99*5ffd83dbSDimitry Andric 100*5ffd83dbSDimitry Andric static void emitLEAzzi(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, 101*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 102*5ffd83dbSDimitry Andric MCInst LEAInst; 103*5ffd83dbSDimitry Andric LEAInst.setOpcode(VE::LEAzii); 104*5ffd83dbSDimitry Andric LEAInst.addOperand(RD); 105*5ffd83dbSDimitry Andric MCOperand CZero = MCOperand::createImm(0); 106*5ffd83dbSDimitry Andric LEAInst.addOperand(CZero); 107*5ffd83dbSDimitry Andric LEAInst.addOperand(CZero); 108*5ffd83dbSDimitry Andric LEAInst.addOperand(Imm); 109*5ffd83dbSDimitry Andric OutStreamer.emitInstruction(LEAInst, STI); 110*5ffd83dbSDimitry Andric } 111*5ffd83dbSDimitry Andric 112*5ffd83dbSDimitry Andric static void emitLEASLzzi(MCStreamer &OutStreamer, MCOperand &Imm, MCOperand &RD, 113*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 114*5ffd83dbSDimitry Andric MCInst LEASLInst; 115*5ffd83dbSDimitry Andric LEASLInst.setOpcode(VE::LEASLzii); 116*5ffd83dbSDimitry Andric LEASLInst.addOperand(RD); 117*5ffd83dbSDimitry Andric MCOperand CZero = MCOperand::createImm(0); 118*5ffd83dbSDimitry Andric LEASLInst.addOperand(CZero); 119*5ffd83dbSDimitry Andric LEASLInst.addOperand(CZero); 120*5ffd83dbSDimitry Andric LEASLInst.addOperand(Imm); 121*5ffd83dbSDimitry Andric OutStreamer.emitInstruction(LEASLInst, STI); 122*5ffd83dbSDimitry Andric } 123*5ffd83dbSDimitry Andric 124*5ffd83dbSDimitry Andric static void emitLEAzii(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, 125*5ffd83dbSDimitry Andric MCOperand &RD, const MCSubtargetInfo &STI) { 126*5ffd83dbSDimitry Andric MCInst LEAInst; 127*5ffd83dbSDimitry Andric LEAInst.setOpcode(VE::LEAzii); 128*5ffd83dbSDimitry Andric LEAInst.addOperand(RD); 129*5ffd83dbSDimitry Andric MCOperand CZero = MCOperand::createImm(0); 130*5ffd83dbSDimitry Andric LEAInst.addOperand(CZero); 131*5ffd83dbSDimitry Andric LEAInst.addOperand(RS1); 132*5ffd83dbSDimitry Andric LEAInst.addOperand(Imm); 133*5ffd83dbSDimitry Andric OutStreamer.emitInstruction(LEAInst, STI); 134*5ffd83dbSDimitry Andric } 135*5ffd83dbSDimitry Andric 136*5ffd83dbSDimitry Andric static void emitLEASLrri(MCStreamer &OutStreamer, MCOperand &RS1, 137*5ffd83dbSDimitry Andric MCOperand &RS2, MCOperand &Imm, MCOperand &RD, 138*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 139*5ffd83dbSDimitry Andric MCInst LEASLInst; 140*5ffd83dbSDimitry Andric LEASLInst.setOpcode(VE::LEASLrri); 141*5ffd83dbSDimitry Andric LEASLInst.addOperand(RD); 142*5ffd83dbSDimitry Andric LEASLInst.addOperand(RS1); 143*5ffd83dbSDimitry Andric LEASLInst.addOperand(RS2); 144*5ffd83dbSDimitry Andric LEASLInst.addOperand(Imm); 145*5ffd83dbSDimitry Andric OutStreamer.emitInstruction(LEASLInst, STI); 146*5ffd83dbSDimitry Andric } 147*5ffd83dbSDimitry Andric 148*5ffd83dbSDimitry Andric static void emitBinary(MCStreamer &OutStreamer, unsigned Opcode, MCOperand &RS1, 149*5ffd83dbSDimitry Andric MCOperand &Src2, MCOperand &RD, 150*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 151*5ffd83dbSDimitry Andric MCInst Inst; 152*5ffd83dbSDimitry Andric Inst.setOpcode(Opcode); 153*5ffd83dbSDimitry Andric Inst.addOperand(RD); 154*5ffd83dbSDimitry Andric Inst.addOperand(RS1); 155*5ffd83dbSDimitry Andric Inst.addOperand(Src2); 156*5ffd83dbSDimitry Andric OutStreamer.emitInstruction(Inst, STI); 157*5ffd83dbSDimitry Andric } 158*5ffd83dbSDimitry Andric 159*5ffd83dbSDimitry Andric static void emitANDrm(MCStreamer &OutStreamer, MCOperand &RS1, MCOperand &Imm, 160*5ffd83dbSDimitry Andric MCOperand &RD, const MCSubtargetInfo &STI) { 161*5ffd83dbSDimitry Andric emitBinary(OutStreamer, VE::ANDrm, RS1, Imm, RD, STI); 162*5ffd83dbSDimitry Andric } 163*5ffd83dbSDimitry Andric 164*5ffd83dbSDimitry Andric static void emitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym, 165*5ffd83dbSDimitry Andric VEMCExpr::VariantKind HiKind, VEMCExpr::VariantKind LoKind, 166*5ffd83dbSDimitry Andric MCOperand &RD, MCContext &OutContext, 167*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 168*5ffd83dbSDimitry Andric 169*5ffd83dbSDimitry Andric MCOperand hi = createVEMCOperand(HiKind, GOTSym, OutContext); 170*5ffd83dbSDimitry Andric MCOperand lo = createVEMCOperand(LoKind, GOTSym, OutContext); 171*5ffd83dbSDimitry Andric emitLEAzzi(OutStreamer, lo, RD, STI); 172*5ffd83dbSDimitry Andric MCOperand M032 = MCOperand::createImm(M0(32)); 173*5ffd83dbSDimitry Andric emitANDrm(OutStreamer, RD, M032, RD, STI); 174*5ffd83dbSDimitry Andric emitLEASLzzi(OutStreamer, hi, RD, STI); 175*5ffd83dbSDimitry Andric } 176*5ffd83dbSDimitry Andric 177*5ffd83dbSDimitry Andric void VEAsmPrinter::lowerGETGOTAndEmitMCInsts(const MachineInstr *MI, 178*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 179*5ffd83dbSDimitry Andric MCSymbol *GOTLabel = 180*5ffd83dbSDimitry Andric OutContext.getOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_")); 181*5ffd83dbSDimitry Andric 182*5ffd83dbSDimitry Andric const MachineOperand &MO = MI->getOperand(0); 183*5ffd83dbSDimitry Andric MCOperand MCRegOP = MCOperand::createReg(MO.getReg()); 184*5ffd83dbSDimitry Andric 185*5ffd83dbSDimitry Andric if (!isPositionIndependent()) { 186*5ffd83dbSDimitry Andric // Just load the address of GOT to MCRegOP. 187*5ffd83dbSDimitry Andric switch (TM.getCodeModel()) { 188*5ffd83dbSDimitry Andric default: 189*5ffd83dbSDimitry Andric llvm_unreachable("Unsupported absolute code model"); 190*5ffd83dbSDimitry Andric case CodeModel::Small: 191*5ffd83dbSDimitry Andric case CodeModel::Medium: 192*5ffd83dbSDimitry Andric case CodeModel::Large: 193*5ffd83dbSDimitry Andric emitHiLo(*OutStreamer, GOTLabel, VEMCExpr::VK_VE_HI32, 194*5ffd83dbSDimitry Andric VEMCExpr::VK_VE_LO32, MCRegOP, OutContext, STI); 195*5ffd83dbSDimitry Andric break; 196*5ffd83dbSDimitry Andric } 197*5ffd83dbSDimitry Andric return; 198*5ffd83dbSDimitry Andric } 199*5ffd83dbSDimitry Andric 200*5ffd83dbSDimitry Andric MCOperand RegGOT = MCOperand::createReg(VE::SX15); // GOT 201*5ffd83dbSDimitry Andric MCOperand RegPLT = MCOperand::createReg(VE::SX16); // PLT 202*5ffd83dbSDimitry Andric 203*5ffd83dbSDimitry Andric // lea %got, _GLOBAL_OFFSET_TABLE_@PC_LO(-24) 204*5ffd83dbSDimitry Andric // and %got, %got, (32)0 205*5ffd83dbSDimitry Andric // sic %plt 206*5ffd83dbSDimitry Andric // lea.sl %got, _GLOBAL_OFFSET_TABLE_@PC_HI(%got, %plt) 207*5ffd83dbSDimitry Andric MCOperand cim24 = MCOperand::createImm(-24); 208*5ffd83dbSDimitry Andric MCOperand loImm = 209*5ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PC_LO32, GOTLabel, OutContext); 210*5ffd83dbSDimitry Andric emitLEAzii(*OutStreamer, cim24, loImm, MCRegOP, STI); 211*5ffd83dbSDimitry Andric MCOperand M032 = MCOperand::createImm(M0(32)); 212*5ffd83dbSDimitry Andric emitANDrm(*OutStreamer, MCRegOP, M032, MCRegOP, STI); 213*5ffd83dbSDimitry Andric emitSIC(*OutStreamer, RegPLT, STI); 214*5ffd83dbSDimitry Andric MCOperand hiImm = 215*5ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PC_HI32, GOTLabel, OutContext); 216*5ffd83dbSDimitry Andric emitLEASLrri(*OutStreamer, RegGOT, RegPLT, hiImm, MCRegOP, STI); 217*5ffd83dbSDimitry Andric } 218*5ffd83dbSDimitry Andric 219*5ffd83dbSDimitry Andric void VEAsmPrinter::lowerGETFunPLTAndEmitMCInsts(const MachineInstr *MI, 220*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 221*5ffd83dbSDimitry Andric const MachineOperand &MO = MI->getOperand(0); 222*5ffd83dbSDimitry Andric MCOperand MCRegOP = MCOperand::createReg(MO.getReg()); 223*5ffd83dbSDimitry Andric const MachineOperand &Addr = MI->getOperand(1); 224*5ffd83dbSDimitry Andric MCSymbol *AddrSym = nullptr; 225*5ffd83dbSDimitry Andric 226*5ffd83dbSDimitry Andric switch (Addr.getType()) { 227*5ffd83dbSDimitry Andric default: 228*5ffd83dbSDimitry Andric llvm_unreachable("<unknown operand type>"); 229*5ffd83dbSDimitry Andric return; 230*5ffd83dbSDimitry Andric case MachineOperand::MO_MachineBasicBlock: 231*5ffd83dbSDimitry Andric report_fatal_error("MBB is not supported yet"); 232*5ffd83dbSDimitry Andric return; 233*5ffd83dbSDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 234*5ffd83dbSDimitry Andric report_fatal_error("ConstantPool is not supported yet"); 235*5ffd83dbSDimitry Andric return; 236*5ffd83dbSDimitry Andric case MachineOperand::MO_ExternalSymbol: 237*5ffd83dbSDimitry Andric AddrSym = GetExternalSymbolSymbol(Addr.getSymbolName()); 238*5ffd83dbSDimitry Andric break; 239*5ffd83dbSDimitry Andric case MachineOperand::MO_GlobalAddress: 240*5ffd83dbSDimitry Andric AddrSym = getSymbol(Addr.getGlobal()); 241*5ffd83dbSDimitry Andric break; 242*5ffd83dbSDimitry Andric } 243*5ffd83dbSDimitry Andric 244*5ffd83dbSDimitry Andric if (!isPositionIndependent()) { 245*5ffd83dbSDimitry Andric llvm_unreachable("Unsupported uses of %plt in not PIC code"); 246*5ffd83dbSDimitry Andric return; 247*5ffd83dbSDimitry Andric } 248*5ffd83dbSDimitry Andric 249*5ffd83dbSDimitry Andric MCOperand RegPLT = MCOperand::createReg(VE::SX16); // PLT 250*5ffd83dbSDimitry Andric 251*5ffd83dbSDimitry Andric // lea %dst, %plt_lo(func)(-24) 252*5ffd83dbSDimitry Andric // and %dst, %dst, (32)0 253*5ffd83dbSDimitry Andric // sic %plt ; FIXME: is it safe to use %plt here? 254*5ffd83dbSDimitry Andric // lea.sl %dst, %plt_hi(func)(%dst, %plt) 255*5ffd83dbSDimitry Andric MCOperand cim24 = MCOperand::createImm(-24); 256*5ffd83dbSDimitry Andric MCOperand loImm = 257*5ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PLT_LO32, AddrSym, OutContext); 258*5ffd83dbSDimitry Andric emitLEAzii(*OutStreamer, cim24, loImm, MCRegOP, STI); 259*5ffd83dbSDimitry Andric MCOperand M032 = MCOperand::createImm(M0(32)); 260*5ffd83dbSDimitry Andric emitANDrm(*OutStreamer, MCRegOP, M032, MCRegOP, STI); 261*5ffd83dbSDimitry Andric emitSIC(*OutStreamer, RegPLT, STI); 262*5ffd83dbSDimitry Andric MCOperand hiImm = 263*5ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PLT_HI32, AddrSym, OutContext); 264*5ffd83dbSDimitry Andric emitLEASLrri(*OutStreamer, MCRegOP, RegPLT, hiImm, MCRegOP, STI); 265*5ffd83dbSDimitry Andric } 266*5ffd83dbSDimitry Andric 267*5ffd83dbSDimitry Andric void VEAsmPrinter::lowerGETTLSAddrAndEmitMCInsts(const MachineInstr *MI, 268*5ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 269*5ffd83dbSDimitry Andric const MachineOperand &Addr = MI->getOperand(0); 270*5ffd83dbSDimitry Andric MCSymbol *AddrSym = nullptr; 271*5ffd83dbSDimitry Andric 272*5ffd83dbSDimitry Andric switch (Addr.getType()) { 273*5ffd83dbSDimitry Andric default: 274*5ffd83dbSDimitry Andric llvm_unreachable("<unknown operand type>"); 275*5ffd83dbSDimitry Andric return; 276*5ffd83dbSDimitry Andric case MachineOperand::MO_MachineBasicBlock: 277*5ffd83dbSDimitry Andric report_fatal_error("MBB is not supported yet"); 278*5ffd83dbSDimitry Andric return; 279*5ffd83dbSDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 280*5ffd83dbSDimitry Andric report_fatal_error("ConstantPool is not supported yet"); 281*5ffd83dbSDimitry Andric return; 282*5ffd83dbSDimitry Andric case MachineOperand::MO_ExternalSymbol: 283*5ffd83dbSDimitry Andric AddrSym = GetExternalSymbolSymbol(Addr.getSymbolName()); 284*5ffd83dbSDimitry Andric break; 285*5ffd83dbSDimitry Andric case MachineOperand::MO_GlobalAddress: 286*5ffd83dbSDimitry Andric AddrSym = getSymbol(Addr.getGlobal()); 287*5ffd83dbSDimitry Andric break; 288*5ffd83dbSDimitry Andric } 289*5ffd83dbSDimitry Andric 290*5ffd83dbSDimitry Andric MCOperand RegLR = MCOperand::createReg(VE::SX10); // LR 291*5ffd83dbSDimitry Andric MCOperand RegS0 = MCOperand::createReg(VE::SX0); // S0 292*5ffd83dbSDimitry Andric MCOperand RegS12 = MCOperand::createReg(VE::SX12); // S12 293*5ffd83dbSDimitry Andric MCSymbol *GetTLSLabel = OutContext.getOrCreateSymbol(Twine("__tls_get_addr")); 294*5ffd83dbSDimitry Andric 295*5ffd83dbSDimitry Andric // lea %s0, sym@tls_gd_lo(-24) 296*5ffd83dbSDimitry Andric // and %s0, %s0, (32)0 297*5ffd83dbSDimitry Andric // sic %lr 298*5ffd83dbSDimitry Andric // lea.sl %s0, sym@tls_gd_hi(%s0, %lr) 299*5ffd83dbSDimitry Andric // lea %s12, __tls_get_addr@plt_lo(8) 300*5ffd83dbSDimitry Andric // and %s12, %s12, (32)0 301*5ffd83dbSDimitry Andric // lea.sl %s12, __tls_get_addr@plt_hi(%s12, %lr) 302*5ffd83dbSDimitry Andric // bsic %lr, (, %s12) 303*5ffd83dbSDimitry Andric MCOperand cim24 = MCOperand::createImm(-24); 304*5ffd83dbSDimitry Andric MCOperand loImm = 305*5ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_TLS_GD_LO32, AddrSym, OutContext); 306*5ffd83dbSDimitry Andric emitLEAzii(*OutStreamer, cim24, loImm, RegS0, STI); 307*5ffd83dbSDimitry Andric MCOperand M032 = MCOperand::createImm(M0(32)); 308*5ffd83dbSDimitry Andric emitANDrm(*OutStreamer, RegS0, M032, RegS0, STI); 309*5ffd83dbSDimitry Andric emitSIC(*OutStreamer, RegLR, STI); 310*5ffd83dbSDimitry Andric MCOperand hiImm = 311*5ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_TLS_GD_HI32, AddrSym, OutContext); 312*5ffd83dbSDimitry Andric emitLEASLrri(*OutStreamer, RegS0, RegLR, hiImm, RegS0, STI); 313*5ffd83dbSDimitry Andric MCOperand ci8 = MCOperand::createImm(8); 314*5ffd83dbSDimitry Andric MCOperand loImm2 = 315*5ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PLT_LO32, GetTLSLabel, OutContext); 316*5ffd83dbSDimitry Andric emitLEAzii(*OutStreamer, ci8, loImm2, RegS12, STI); 317*5ffd83dbSDimitry Andric emitANDrm(*OutStreamer, RegS12, M032, RegS12, STI); 318*5ffd83dbSDimitry Andric MCOperand hiImm2 = 319*5ffd83dbSDimitry Andric createGOTRelExprOp(VEMCExpr::VK_VE_PLT_HI32, GetTLSLabel, OutContext); 320*5ffd83dbSDimitry Andric emitLEASLrri(*OutStreamer, RegS12, RegLR, hiImm2, RegS12, STI); 321*5ffd83dbSDimitry Andric emitBSIC(*OutStreamer, RegLR, RegS12, STI); 322*5ffd83dbSDimitry Andric } 323*5ffd83dbSDimitry Andric 324*5ffd83dbSDimitry Andric void VEAsmPrinter::emitInstruction(const MachineInstr *MI) { 325480093f4SDimitry Andric 326480093f4SDimitry Andric switch (MI->getOpcode()) { 327480093f4SDimitry Andric default: 328480093f4SDimitry Andric break; 329480093f4SDimitry Andric case TargetOpcode::DBG_VALUE: 330480093f4SDimitry Andric // FIXME: Debug Value. 331480093f4SDimitry Andric return; 332*5ffd83dbSDimitry Andric case VE::GETGOT: 333*5ffd83dbSDimitry Andric lowerGETGOTAndEmitMCInsts(MI, getSubtargetInfo()); 334*5ffd83dbSDimitry Andric return; 335*5ffd83dbSDimitry Andric case VE::GETFUNPLT: 336*5ffd83dbSDimitry Andric lowerGETFunPLTAndEmitMCInsts(MI, getSubtargetInfo()); 337*5ffd83dbSDimitry Andric return; 338*5ffd83dbSDimitry Andric case VE::GETTLSADDR: 339*5ffd83dbSDimitry Andric lowerGETTLSAddrAndEmitMCInsts(MI, getSubtargetInfo()); 340*5ffd83dbSDimitry Andric return; 341480093f4SDimitry Andric } 342*5ffd83dbSDimitry Andric 343480093f4SDimitry Andric MachineBasicBlock::const_instr_iterator I = MI->getIterator(); 344480093f4SDimitry Andric MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); 345480093f4SDimitry Andric do { 346480093f4SDimitry Andric MCInst TmpInst; 347480093f4SDimitry Andric LowerVEMachineInstrToMCInst(&*I, TmpInst, *this); 348480093f4SDimitry Andric EmitToStreamer(*OutStreamer, TmpInst); 349480093f4SDimitry Andric } while ((++I != E) && I->isInsideBundle()); // Delay slot check. 350480093f4SDimitry Andric } 351480093f4SDimitry Andric 352480093f4SDimitry Andric // Force static initialization. 353480093f4SDimitry Andric extern "C" void LLVMInitializeVEAsmPrinter() { 354480093f4SDimitry Andric RegisterAsmPrinter<VEAsmPrinter> X(getTheVETarget()); 355480093f4SDimitry Andric } 356