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