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 "MipsTargetObjectFile.h" 16 #include "MipsTargetStreamer.h" 17 #include "MipsMCTargetDesc.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCELF.h" 20 #include "llvm/MC/MCSectionELF.h" 21 #include "llvm/MC/MCSymbol.h" 22 #include "llvm/MC/MCSubtargetInfo.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 // Print a 32 bit hex number with all numbers. 101 static void printHex32(unsigned Value, raw_ostream &OS) { 102 OS << "0x"; 103 for (int i = 7; i >= 0; i--) 104 OS.write_hex((Value & (0xF << (i*4))) >> (i*4)); 105 } 106 107 void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask, 108 int CPUTopSavedRegOff) { 109 OS << "\t.mask \t"; 110 printHex32(CPUBitmask, OS); 111 OS << ',' << CPUTopSavedRegOff << '\n'; 112 } 113 114 void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask, 115 int FPUTopSavedRegOff) { 116 OS << "\t.fmask\t"; 117 printHex32(FPUBitmask, OS); 118 OS << "," << FPUTopSavedRegOff << '\n'; 119 } 120 121 // This part is for ELF object output. 122 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, 123 const MCSubtargetInfo &STI) 124 : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { 125 MCAssembler &MCA = getStreamer().getAssembler(); 126 uint64_t Features = STI.getFeatureBits(); 127 Triple T(STI.getTargetTriple()); 128 129 // Update e_header flags 130 unsigned EFlags = 0; 131 132 // Architecture 133 if (Features & Mips::FeatureMips64r2) 134 EFlags |= ELF::EF_MIPS_ARCH_64R2; 135 else if (Features & Mips::FeatureMips64) 136 EFlags |= ELF::EF_MIPS_ARCH_64; 137 else if (Features & Mips::FeatureMips32r2) 138 EFlags |= ELF::EF_MIPS_ARCH_32R2; 139 else if (Features & Mips::FeatureMips32) 140 EFlags |= ELF::EF_MIPS_ARCH_32; 141 142 if (T.isArch64Bit()) { 143 if (Features & Mips::FeatureN32) 144 EFlags |= ELF::EF_MIPS_ABI2; 145 else if (Features & Mips::FeatureO32) { 146 EFlags |= ELF::EF_MIPS_ABI_O32; 147 EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */ 148 } 149 // No need to set any bit for N64 which is the default ABI at the moment 150 // for 64-bit Mips architectures. 151 } else { 152 if (Features & Mips::FeatureMips64r2 || Features & Mips::FeatureMips64) 153 EFlags |= ELF::EF_MIPS_32BITMODE; 154 155 // ABI 156 EFlags |= ELF::EF_MIPS_ABI_O32; 157 } 158 159 MCA.setELFHeaderEFlags(EFlags); 160 } 161 162 void MipsTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 163 if (!isMicroMipsEnabled()) 164 return; 165 MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Symbol); 166 uint8_t Type = MCELF::GetType(Data); 167 if (Type != ELF::STT_FUNC) 168 return; 169 170 // The "other" values are stored in the last 6 bits of the second byte 171 // The traditional defines for STO values assume the full byte and thus 172 // the shift to pack it. 173 MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2); 174 } 175 176 void MipsTargetELFStreamer::finish() { 177 MCAssembler &MCA = getStreamer().getAssembler(); 178 MCContext &Context = MCA.getContext(); 179 MCStreamer &OS = getStreamer(); 180 Triple T(STI.getTargetTriple()); 181 uint64_t Features = STI.getFeatureBits(); 182 183 if (T.isArch64Bit() && (Features & Mips::FeatureN64)) { 184 const MCSectionELF *Sec = Context.getELFSection( 185 ".MIPS.options", ELF::SHT_MIPS_OPTIONS, 186 ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, SectionKind::getMetadata()); 187 OS.SwitchSection(Sec); 188 189 OS.EmitIntValue(1, 1); // kind 190 OS.EmitIntValue(40, 1); // size 191 OS.EmitIntValue(0, 2); // section 192 OS.EmitIntValue(0, 4); // info 193 OS.EmitIntValue(0, 4); // ri_gprmask 194 OS.EmitIntValue(0, 4); // pad 195 OS.EmitIntValue(0, 4); // ri_cpr[0]mask 196 OS.EmitIntValue(0, 4); // ri_cpr[1]mask 197 OS.EmitIntValue(0, 4); // ri_cpr[2]mask 198 OS.EmitIntValue(0, 4); // ri_cpr[3]mask 199 OS.EmitIntValue(0, 8); // ri_gp_value 200 } else { 201 const MCSectionELF *Sec = 202 Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC, 203 SectionKind::getMetadata()); 204 OS.SwitchSection(Sec); 205 206 OS.EmitIntValue(0, 4); // ri_gprmask 207 OS.EmitIntValue(0, 4); // ri_cpr[0]mask 208 OS.EmitIntValue(0, 4); // ri_cpr[1]mask 209 OS.EmitIntValue(0, 4); // ri_cpr[2]mask 210 OS.EmitIntValue(0, 4); // ri_cpr[3]mask 211 OS.EmitIntValue(0, 4); // ri_gp_value 212 } 213 } 214 215 MCELFStreamer &MipsTargetELFStreamer::getStreamer() { 216 return static_cast<MCELFStreamer &>(Streamer); 217 } 218 219 void MipsTargetELFStreamer::emitDirectiveSetMicroMips() { 220 MicroMipsEnabled = true; 221 222 MCAssembler &MCA = getStreamer().getAssembler(); 223 unsigned Flags = MCA.getELFHeaderEFlags(); 224 Flags |= ELF::EF_MIPS_MICROMIPS; 225 MCA.setELFHeaderEFlags(Flags); 226 } 227 228 void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() { 229 MicroMipsEnabled = false; 230 } 231 232 void MipsTargetELFStreamer::emitDirectiveSetMips16() { 233 MCAssembler &MCA = getStreamer().getAssembler(); 234 unsigned Flags = MCA.getELFHeaderEFlags(); 235 Flags |= ELF::EF_MIPS_ARCH_ASE_M16; 236 MCA.setELFHeaderEFlags(Flags); 237 } 238 239 void MipsTargetELFStreamer::emitDirectiveSetNoMips16() { 240 // FIXME: implement. 241 } 242 243 void MipsTargetELFStreamer::emitDirectiveSetReorder() { 244 // FIXME: implement. 245 } 246 247 void MipsTargetELFStreamer::emitDirectiveSetNoReorder() { 248 MCAssembler &MCA = getStreamer().getAssembler(); 249 unsigned Flags = MCA.getELFHeaderEFlags(); 250 Flags |= ELF::EF_MIPS_NOREORDER; 251 MCA.setELFHeaderEFlags(Flags); 252 } 253 254 void MipsTargetELFStreamer::emitDirectiveSetMacro() { 255 // FIXME: implement. 256 } 257 258 void MipsTargetELFStreamer::emitDirectiveSetNoMacro() { 259 // FIXME: implement. 260 } 261 262 void MipsTargetELFStreamer::emitDirectiveSetAt() { 263 // FIXME: implement. 264 } 265 266 void MipsTargetELFStreamer::emitDirectiveSetNoAt() { 267 // FIXME: implement. 268 } 269 270 void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { 271 // FIXME: implement. 272 } 273 274 void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { 275 // FIXME: implement. 276 } 277 278 void MipsTargetELFStreamer::emitDirectiveAbiCalls() { 279 MCAssembler &MCA = getStreamer().getAssembler(); 280 unsigned Flags = MCA.getELFHeaderEFlags(); 281 Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC; 282 MCA.setELFHeaderEFlags(Flags); 283 } 284 void MipsTargetELFStreamer::emitDirectiveOptionPic0() { 285 MCAssembler &MCA = getStreamer().getAssembler(); 286 unsigned Flags = MCA.getELFHeaderEFlags(); 287 Flags &= ~ELF::EF_MIPS_PIC; 288 MCA.setELFHeaderEFlags(Flags); 289 } 290 291 void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize, 292 unsigned ReturnReg) { 293 // FIXME: implement. 294 } 295 296 void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask, 297 int CPUTopSavedRegOff) { 298 // FIXME: implement. 299 } 300 301 void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask, 302 int FPUTopSavedRegOff) { 303 // FIXME: implement. 304 } 305