1249259Sdim//===-- MipsELFStreamer.cpp - MipsELFStreamer ---------------------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===-------------------------------------------------------------------===// 9249259Sdim#include "MCTargetDesc/MipsELFStreamer.h" 10249259Sdim#include "MipsSubtarget.h" 11249259Sdim#include "llvm/MC/MCAssembler.h" 12249259Sdim#include "llvm/MC/MCELF.h" 13249259Sdim#include "llvm/MC/MCELFSymbolFlags.h" 14249259Sdim#include "llvm/MC/MCSymbol.h" 15249259Sdim#include "llvm/Support/ELF.h" 16249259Sdim#include "llvm/Support/ErrorHandling.h" 17249259Sdim 18249259Sdimnamespace llvm { 19249259Sdim 20249259Sdim MCELFStreamer* createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, 21249259Sdim raw_ostream &OS, MCCodeEmitter *Emitter, 22249259Sdim bool RelaxAll, bool NoExecStack) { 23249259Sdim MipsELFStreamer *S = new MipsELFStreamer(Context, TAB, OS, Emitter, 24249259Sdim RelaxAll, NoExecStack); 25249259Sdim return S; 26249259Sdim } 27249259Sdim 28249259Sdim // For llc. Set a group of ELF header flags 29249259Sdim void 30249259Sdim MipsELFStreamer::emitELFHeaderFlagsCG(const MipsSubtarget &Subtarget) { 31249259Sdim 32249259Sdim if (hasRawTextSupport()) 33249259Sdim return; 34249259Sdim 35249259Sdim // Update e_header flags 36249259Sdim MCAssembler& MCA = getAssembler(); 37249259Sdim unsigned EFlags = MCA.getELFHeaderEFlags(); 38249259Sdim 39249259Sdim if (Subtarget.inMips16Mode()) 40249259Sdim EFlags |= ELF::EF_MIPS_ARCH_ASE_M16; 41249259Sdim else 42249259Sdim EFlags |= ELF::EF_MIPS_NOREORDER; 43249259Sdim 44249259Sdim // Architecture 45249259Sdim if (Subtarget.hasMips64r2()) 46249259Sdim EFlags |= ELF::EF_MIPS_ARCH_64R2; 47249259Sdim else if (Subtarget.hasMips64()) 48249259Sdim EFlags |= ELF::EF_MIPS_ARCH_64; 49249259Sdim else if (Subtarget.hasMips32r2()) 50249259Sdim EFlags |= ELF::EF_MIPS_ARCH_32R2; 51249259Sdim else 52249259Sdim EFlags |= ELF::EF_MIPS_ARCH_32; 53249259Sdim 54249259Sdim if (Subtarget.inMicroMipsMode()) 55249259Sdim EFlags |= ELF::EF_MIPS_MICROMIPS; 56249259Sdim 57249259Sdim // ABI 58249259Sdim if (Subtarget.isABI_O32()) 59249259Sdim EFlags |= ELF::EF_MIPS_ABI_O32; 60249259Sdim 61249259Sdim // Relocation Model 62249259Sdim Reloc::Model RM = Subtarget.getRelocationModel(); 63249259Sdim if (RM == Reloc::PIC_ || RM == Reloc::Default) 64249259Sdim EFlags |= ELF::EF_MIPS_PIC; 65249259Sdim else if (RM == Reloc::Static) 66249259Sdim ; // Do nothing for Reloc::Static 67249259Sdim else 68249259Sdim llvm_unreachable("Unsupported relocation model for e_flags"); 69249259Sdim 70249259Sdim MCA.setELFHeaderEFlags(EFlags); 71249259Sdim } 72249259Sdim 73249259Sdim // For llc. Set a symbol's STO flags 74249259Sdim void 75249259Sdim MipsELFStreamer::emitMipsSTOCG(const MipsSubtarget &Subtarget, 76249259Sdim MCSymbol *Sym, 77249259Sdim unsigned Val) { 78249259Sdim 79249259Sdim if (hasRawTextSupport()) 80249259Sdim return; 81249259Sdim 82249259Sdim MCSymbolData &Data = getOrCreateSymbolData(Sym); 83249259Sdim // The "other" values are stored in the last 6 bits of the second byte 84249259Sdim // The traditional defines for STO values assume the full byte and thus 85249259Sdim // the shift to pack it. 86249259Sdim MCELF::setOther(Data, Val >> 2); 87249259Sdim } 88249259Sdim 89249259Sdim} // namespace llvm 90