1 //===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===// 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 provides Mips specific target streamer methods. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "InstPrinter/MipsInstPrinter.h" 15 #include "MipsMCTargetDesc.h" 16 #include "MipsTargetObjectFile.h" 17 #include "MipsTargetStreamer.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCELF.h" 20 #include "llvm/MC/MCSectionELF.h" 21 #include "llvm/MC/MCSubtargetInfo.h" 22 #include "llvm/MC/MCSymbol.h" 23 #include "llvm/Support/CommandLine.h" 24 #include "llvm/Support/ELF.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/FormattedStream.h" 27 28 using namespace llvm; 29 30 // Pin vtable to this file. 31 void MipsTargetStreamer::anchor() {} 32 33 MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} 34 35 MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S, 36 formatted_raw_ostream &OS) 37 : MipsTargetStreamer(S), OS(OS) {} 38 39 void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() { 40 OS << "\t.set\tmicromips\n"; 41 } 42 43 void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() { 44 OS << "\t.set\tnomicromips\n"; 45 } 46 47 void MipsTargetAsmStreamer::emitDirectiveSetMips16() { 48 OS << "\t.set\tmips16\n"; 49 } 50 51 void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() { 52 OS << "\t.set\tnomips16\n"; 53 } 54 55 void MipsTargetAsmStreamer::emitDirectiveSetReorder() { 56 OS << "\t.set\treorder\n"; 57 } 58 59 void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() { 60 OS << "\t.set\tnoreorder\n"; 61 } 62 63 void MipsTargetAsmStreamer::emitDirectiveSetMacro() { 64 OS << "\t.set\tmacro\n"; 65 } 66 67 void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() { 68 OS << "\t.set\tnomacro\n"; 69 } 70 71 void MipsTargetAsmStreamer::emitDirectiveSetAt() { 72 OS << "\t.set\tat\n"; 73 } 74 75 void MipsTargetAsmStreamer::emitDirectiveSetNoAt() { 76 OS << "\t.set\tnoat\n"; 77 } 78 79 void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) { 80 OS << "\t.end\t" << Name << '\n'; 81 } 82 83 void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 84 OS << "\t.ent\t" << Symbol.getName() << '\n'; 85 } 86 87 void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; } 88 void MipsTargetAsmStreamer::emitDirectiveOptionPic0() { 89 OS << "\t.option\tpic0\n"; 90 } 91 92 void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 93 unsigned ReturnReg) { 94 OS << "\t.frame\t$" 95 << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << "," 96 << StackSize << ",$" 97 << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n'; 98 } 99 100 void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() { 101 OS << "\t.set\tmips32r2\n"; 102 } 103 104 void MipsTargetAsmStreamer::emitDirectiveSetDsp() { 105 OS << "\t.set\tdsp\n"; 106 } 107 // Print a 32 bit hex number with all numbers. 108 static void printHex32(unsigned Value, raw_ostream &OS) { 109 OS << "0x"; 110 for (int i = 7; i >= 0; i--) 111 OS.write_hex((Value & (0xF << (i*4))) >> (i*4)); 112 } 113 114 void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask, 115 int CPUTopSavedRegOff) { 116 OS << "\t.mask \t"; 117 printHex32(CPUBitmask, OS); 118 OS << ',' << CPUTopSavedRegOff << '\n'; 119 } 120 121 void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask, 122 int FPUTopSavedRegOff) { 123 OS << "\t.fmask\t"; 124 printHex32(FPUBitmask, OS); 125 OS << "," << FPUTopSavedRegOff << '\n'; 126 } 127 128 // This part is for ELF object output. 129 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, 130 const MCSubtargetInfo &STI) 131 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { 132 MCAssembler &MCA = getStreamer().getAssembler(); 133 uint64_t Features = STI.getFeatureBits(); 134 Triple T(STI.getTargetTriple()); 135 136 // Update e_header flags 137 unsigned EFlags = 0; 138 139 // Architecture 140 if (Features & Mips::FeatureMips64r2) 141 EFlags |= ELF::EF_MIPS_ARCH_64R2; 142 else if (Features & Mips::FeatureMips64) 143 EFlags |= ELF::EF_MIPS_ARCH_64; 144 else if (Features & Mips::FeatureMips32r2) 145 EFlags |= ELF::EF_MIPS_ARCH_32R2; 146 else if (Features & Mips::FeatureMips32) 147 EFlags |= ELF::EF_MIPS_ARCH_32; 148 149 if (T.isArch64Bit()) { 150 if (Features & Mips::FeatureN32) 151 EFlags |= ELF::EF_MIPS_ABI2; 152 else if (Features & Mips::FeatureO32) { 153 EFlags |= ELF::EF_MIPS_ABI_O32; 154 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */ 155 } 156 // No need to set any bit for N64 which is the default ABI at the moment 157 // for 64-bit Mips architectures. 158 } else { 159 if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64) 160 EFlags |= ELF::EF_MIPS_32BITMODE; 161 162 // ABI 163 EFlags |= ELF::EF_MIPS_ABI_O32; 164 } 165 166 MCA.setELFHeaderEFlags(EFlags); 167 } 168 169 void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 170 if (!isMicroMipsEnabled()) 171 return; 172 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol); 173 uint8_t Type = MCELF::GetType(Data); 174 if (Type != ELF::STT_FUNC) 175 return; 176 177 // The "other" values are stored in the last 6 bits of the second byte 178 // The traditional defines for STO values assume the full byte and thus 179 // the shift to pack it. 180 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2); 181 } 182 183 void MipsTargetELFStreamer::finish() { 184 MCAssembler &MCA = getStreamer().getAssembler(); 185 MCContext &Context = MCA.getContext(); 186 MCStreamer &OS = getStreamer(); 187 Triple T(STI.getTargetTriple()); 188 uint64_t Features = STI.getFeatureBits(); 189 190 if (T.isArch64Bit() && (Features & Mips::FeatureN64)) { 191 const MCSectionELF *Sec = Context.getELFSection( 192 ".MIPS.options", ELF::SHT_MIPS_OPTIONS, 193 ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, SectionKind::getMetadata()); 194 OS.SwitchSection(Sec); 195 196 OS.EmitIntValue(1, 1); // kind 197 OS.EmitIntValue(40, 1); // size 198 OS.EmitIntValue(0, 2); // section 199 OS.EmitIntValue(0, 4); // info 200 OS.EmitIntValue(0, 4); // ri_gprmask 201 OS.EmitIntValue(0, 4); // pad 202 OS.EmitIntValue(0, 4); // ri_cpr[0]mask 203 OS.EmitIntValue(0, 4); // ri_cpr[1]mask 204 OS.EmitIntValue(0, 4); // ri_cpr[2]mask 205 OS.EmitIntValue(0, 4); // ri_cpr[3]mask 206 OS.EmitIntValue(0, 8); // ri_gp_value 207 } else { 208 const MCSectionELF *Sec = 209 Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC, 210 SectionKind::getMetadata()); 211 OS.SwitchSection(Sec); 212 213 OS.EmitIntValue(0, 4); // ri_gprmask 214 OS.EmitIntValue(0, 4); // ri_cpr[0]mask 215 OS.EmitIntValue(0, 4); // ri_cpr[1]mask 216 OS.EmitIntValue(0, 4); // ri_cpr[2]mask 217 OS.EmitIntValue(0, 4); // ri_cpr[3]mask 218 OS.EmitIntValue(0, 4); // ri_gp_value 219 } 220 } 221 222 MCELFStreamer &MipsTargetELFStreamer::getStreamer() { 223 return static_cast<MCELFStreamer &>(Streamer); 224 } 225 226 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() { 227 MicroMipsEnabled = true; 228 229 MCAssembler &MCA = getStreamer().getAssembler(); 230 unsigned Flags = MCA.getELFHeaderEFlags(); 231 Flags |= ELF::EF_MIPS_MICROMIPS; 232 MCA.setELFHeaderEFlags(Flags); 233 } 234 235 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() { 236 MicroMipsEnabled = false; 237 } 238 239 void MipsTargetELFStreamer::emitDirectiveSetMips16() { 240 MCAssembler &MCA = getStreamer().getAssembler(); 241 unsigned Flags = MCA.getELFHeaderEFlags(); 242 Flags |= ELF::EF_MIPS_ARCH_ASE_M16; 243 MCA.setELFHeaderEFlags(Flags); 244 } 245 246 void MipsTargetELFStreamer::emitDirectiveSetNoMips16() { 247 // FIXME: implement. 248 } 249 250 void MipsTargetELFStreamer::emitDirectiveSetReorder() { 251 // FIXME: implement. 252 } 253 254 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() { 255 MCAssembler &MCA = getStreamer().getAssembler(); 256 unsigned Flags = MCA.getELFHeaderEFlags(); 257 Flags |= ELF::EF_MIPS_NOREORDER; 258 MCA.setELFHeaderEFlags(Flags); 259 } 260 261 void MipsTargetELFStreamer::emitDirectiveSetMacro() { 262 // FIXME: implement. 263 } 264 265 void MipsTargetELFStreamer::emitDirectiveSetNoMacro() { 266 // FIXME: implement. 267 } 268 269 void MipsTargetELFStreamer::emitDirectiveSetAt() { 270 // FIXME: implement. 271 } 272 273 void MipsTargetELFStreamer::emitDirectiveSetNoAt() { 274 // FIXME: implement. 275 } 276 277 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { 278 // FIXME: implement. 279 } 280 281 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 282 // FIXME: implement. 283 } 284 285 void MipsTargetELFStreamer::emitDirectiveAbiCalls() { 286 MCAssembler &MCA = getStreamer().getAssembler(); 287 unsigned Flags = MCA.getELFHeaderEFlags(); 288 Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC; 289 MCA.setELFHeaderEFlags(Flags); 290 } 291 void MipsTargetELFStreamer::emitDirectiveOptionPic0() { 292 MCAssembler &MCA = getStreamer().getAssembler(); 293 unsigned Flags = MCA.getELFHeaderEFlags(); 294 Flags &= ~ELF::EF_MIPS_PIC; 295 MCA.setELFHeaderEFlags(Flags); 296 } 297 298 void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 299 unsigned ReturnReg) { 300 // FIXME: implement. 301 } 302 303 void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask, 304 int CPUTopSavedRegOff) { 305 // FIXME: implement. 306 } 307 308 void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask, 309 int FPUTopSavedRegOff) { 310 // FIXME: implement. 311 } 312 313 void MipsTargetELFStreamer::emitDirectiveSetMips32R2() { 314 // No action required for ELF output. 315 } 316 317 void MipsTargetELFStreamer::emitDirectiveSetDsp() { 318 // No action required for ELF output. 319 } 320