1*9880d681SAndroid Build Coastguard Worker //===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file provides Mips specific target streamer methods.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "MipsTargetStreamer.h"
15*9880d681SAndroid Build Coastguard Worker #include "InstPrinter/MipsInstPrinter.h"
16*9880d681SAndroid Build Coastguard Worker #include "MipsELFStreamer.h"
17*9880d681SAndroid Build Coastguard Worker #include "MipsMCExpr.h"
18*9880d681SAndroid Build Coastguard Worker #include "MipsMCTargetDesc.h"
19*9880d681SAndroid Build Coastguard Worker #include "MipsTargetObjectFile.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionELF.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbolELF.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FormattedStream.h"
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker using namespace llvm;
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker namespace {
32*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> RoundSectionSizes(
33*9880d681SAndroid Build Coastguard Worker "mips-round-section-sizes", cl::init(false),
34*9880d681SAndroid Build Coastguard Worker cl::desc("Round section sizes up to the section alignment"), cl::Hidden);
35*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
36*9880d681SAndroid Build Coastguard Worker
MipsTargetStreamer(MCStreamer & S)37*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S)
38*9880d681SAndroid Build Coastguard Worker : MCTargetStreamer(S), ModuleDirectiveAllowed(true) {
39*9880d681SAndroid Build Coastguard Worker GPRInfoSet = FPRInfoSet = FrameInfoSet = false;
40*9880d681SAndroid Build Coastguard Worker }
emitDirectiveSetMicroMips()41*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMicroMips() {}
emitDirectiveSetNoMicroMips()42*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {}
setUsesMicroMips()43*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::setUsesMicroMips() {}
emitDirectiveSetMips16()44*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips16() {}
emitDirectiveSetNoMips16()45*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetNoMips16() { forbidModuleDirective(); }
emitDirectiveSetReorder()46*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetReorder() { forbidModuleDirective(); }
emitDirectiveSetNoReorder()47*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetNoReorder() {}
emitDirectiveSetMacro()48*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMacro() { forbidModuleDirective(); }
emitDirectiveSetNoMacro()49*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetNoMacro() { forbidModuleDirective(); }
emitDirectiveSetMsa()50*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMsa() { forbidModuleDirective(); }
emitDirectiveSetNoMsa()51*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetNoMsa() { forbidModuleDirective(); }
emitDirectiveSetAt()52*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); }
emitDirectiveSetAtWithArg(unsigned RegNo)53*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) {
54*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
55*9880d681SAndroid Build Coastguard Worker }
emitDirectiveSetNoAt()56*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetNoAt() { forbidModuleDirective(); }
emitDirectiveEnd(StringRef Name)57*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveEnd(StringRef Name) {}
emitDirectiveEnt(const MCSymbol & Symbol)58*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {}
emitDirectiveAbiCalls()59*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveAbiCalls() {}
emitDirectiveNaN2008()60*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveNaN2008() {}
emitDirectiveNaNLegacy()61*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveNaNLegacy() {}
emitDirectiveOptionPic0()62*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveOptionPic0() {}
emitDirectiveOptionPic2()63*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveOptionPic2() {}
emitDirectiveInsn()64*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveInsn() { forbidModuleDirective(); }
emitFrame(unsigned StackReg,unsigned StackSize,unsigned ReturnReg)65*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
66*9880d681SAndroid Build Coastguard Worker unsigned ReturnReg) {}
emitMask(unsigned CPUBitmask,int CPUTopSavedRegOff)67*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitMask(unsigned CPUBitmask, int CPUTopSavedRegOff) {}
emitFMask(unsigned FPUBitmask,int FPUTopSavedRegOff)68*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) {
69*9880d681SAndroid Build Coastguard Worker }
emitDirectiveSetArch(StringRef Arch)70*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) {
71*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
72*9880d681SAndroid Build Coastguard Worker }
emitDirectiveSetMips0()73*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips0() { forbidModuleDirective(); }
emitDirectiveSetMips1()74*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips1() { forbidModuleDirective(); }
emitDirectiveSetMips2()75*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips2() { forbidModuleDirective(); }
emitDirectiveSetMips3()76*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips3() { forbidModuleDirective(); }
emitDirectiveSetMips4()77*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips4() { forbidModuleDirective(); }
emitDirectiveSetMips5()78*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips5() { forbidModuleDirective(); }
emitDirectiveSetMips32()79*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips32() { forbidModuleDirective(); }
emitDirectiveSetMips32R2()80*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips32R2() { forbidModuleDirective(); }
emitDirectiveSetMips32R3()81*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips32R3() { forbidModuleDirective(); }
emitDirectiveSetMips32R5()82*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips32R5() { forbidModuleDirective(); }
emitDirectiveSetMips32R6()83*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips32R6() { forbidModuleDirective(); }
emitDirectiveSetMips64()84*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips64() { forbidModuleDirective(); }
emitDirectiveSetMips64R2()85*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips64R2() { forbidModuleDirective(); }
emitDirectiveSetMips64R3()86*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips64R3() { forbidModuleDirective(); }
emitDirectiveSetMips64R5()87*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips64R5() { forbidModuleDirective(); }
emitDirectiveSetMips64R6()88*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetMips64R6() { forbidModuleDirective(); }
emitDirectiveSetPop()89*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetPop() { forbidModuleDirective(); }
emitDirectiveSetPush()90*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetPush() { forbidModuleDirective(); }
emitDirectiveSetSoftFloat()91*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetSoftFloat() {
92*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
93*9880d681SAndroid Build Coastguard Worker }
emitDirectiveSetHardFloat()94*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetHardFloat() {
95*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
96*9880d681SAndroid Build Coastguard Worker }
emitDirectiveSetDsp()97*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); }
emitDirectiveSetNoDsp()98*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); }
emitDirectiveCpLoad(unsigned RegNo)99*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {}
emitDirectiveCpRestore(int Offset,function_ref<unsigned ()> GetATReg,SMLoc IDLoc,const MCSubtargetInfo * STI)100*9880d681SAndroid Build Coastguard Worker bool MipsTargetStreamer::emitDirectiveCpRestore(
101*9880d681SAndroid Build Coastguard Worker int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
102*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
103*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
104*9880d681SAndroid Build Coastguard Worker return true;
105*9880d681SAndroid Build Coastguard Worker }
emitDirectiveCpsetup(unsigned RegNo,int RegOrOffset,const MCSymbol & Sym,bool IsReg)106*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
107*9880d681SAndroid Build Coastguard Worker const MCSymbol &Sym, bool IsReg) {
108*9880d681SAndroid Build Coastguard Worker }
emitDirectiveCpreturn(unsigned SaveLocation,bool SaveLocationIsRegister)109*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
110*9880d681SAndroid Build Coastguard Worker bool SaveLocationIsRegister) {}
111*9880d681SAndroid Build Coastguard Worker
emitDirectiveModuleFP()112*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveModuleFP() {}
113*9880d681SAndroid Build Coastguard Worker
emitDirectiveModuleOddSPReg()114*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveModuleOddSPReg() {
115*9880d681SAndroid Build Coastguard Worker if (!ABIFlagsSection.OddSPReg && !ABIFlagsSection.Is32BitABI)
116*9880d681SAndroid Build Coastguard Worker report_fatal_error("+nooddspreg is only valid for O32");
117*9880d681SAndroid Build Coastguard Worker }
emitDirectiveModuleSoftFloat()118*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveModuleSoftFloat() {}
emitDirectiveModuleHardFloat()119*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveModuleHardFloat() {}
emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value)120*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetFp(
121*9880d681SAndroid Build Coastguard Worker MipsABIFlagsSection::FpABIKind Value) {
122*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
123*9880d681SAndroid Build Coastguard Worker }
emitDirectiveSetOddSPReg()124*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetOddSPReg() { forbidModuleDirective(); }
emitDirectiveSetNoOddSPReg()125*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDirectiveSetNoOddSPReg() {
126*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
127*9880d681SAndroid Build Coastguard Worker }
128*9880d681SAndroid Build Coastguard Worker
emitR(unsigned Opcode,unsigned Reg0,SMLoc IDLoc,const MCSubtargetInfo * STI)129*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
130*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
131*9880d681SAndroid Build Coastguard Worker MCInst TmpInst;
132*9880d681SAndroid Build Coastguard Worker TmpInst.setOpcode(Opcode);
133*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(Reg0));
134*9880d681SAndroid Build Coastguard Worker TmpInst.setLoc(IDLoc);
135*9880d681SAndroid Build Coastguard Worker getStreamer().EmitInstruction(TmpInst, *STI);
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker
emitRX(unsigned Opcode,unsigned Reg0,MCOperand Op1,SMLoc IDLoc,const MCSubtargetInfo * STI)138*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1,
139*9880d681SAndroid Build Coastguard Worker SMLoc IDLoc, const MCSubtargetInfo *STI) {
140*9880d681SAndroid Build Coastguard Worker MCInst TmpInst;
141*9880d681SAndroid Build Coastguard Worker TmpInst.setOpcode(Opcode);
142*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(Reg0));
143*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(Op1);
144*9880d681SAndroid Build Coastguard Worker TmpInst.setLoc(IDLoc);
145*9880d681SAndroid Build Coastguard Worker getStreamer().EmitInstruction(TmpInst, *STI);
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker
emitRI(unsigned Opcode,unsigned Reg0,int32_t Imm,SMLoc IDLoc,const MCSubtargetInfo * STI)148*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm,
149*9880d681SAndroid Build Coastguard Worker SMLoc IDLoc, const MCSubtargetInfo *STI) {
150*9880d681SAndroid Build Coastguard Worker emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, STI);
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker
emitRR(unsigned Opcode,unsigned Reg0,unsigned Reg1,SMLoc IDLoc,const MCSubtargetInfo * STI)153*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
154*9880d681SAndroid Build Coastguard Worker SMLoc IDLoc, const MCSubtargetInfo *STI) {
155*9880d681SAndroid Build Coastguard Worker emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, STI);
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker
emitII(unsigned Opcode,int16_t Imm1,int16_t Imm2,SMLoc IDLoc,const MCSubtargetInfo * STI)158*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2,
159*9880d681SAndroid Build Coastguard Worker SMLoc IDLoc, const MCSubtargetInfo *STI) {
160*9880d681SAndroid Build Coastguard Worker MCInst TmpInst;
161*9880d681SAndroid Build Coastguard Worker TmpInst.setOpcode(Opcode);
162*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createImm(Imm1));
163*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createImm(Imm2));
164*9880d681SAndroid Build Coastguard Worker TmpInst.setLoc(IDLoc);
165*9880d681SAndroid Build Coastguard Worker getStreamer().EmitInstruction(TmpInst, *STI);
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker
emitRRX(unsigned Opcode,unsigned Reg0,unsigned Reg1,MCOperand Op2,SMLoc IDLoc,const MCSubtargetInfo * STI)168*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1,
169*9880d681SAndroid Build Coastguard Worker MCOperand Op2, SMLoc IDLoc,
170*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
171*9880d681SAndroid Build Coastguard Worker MCInst TmpInst;
172*9880d681SAndroid Build Coastguard Worker TmpInst.setOpcode(Opcode);
173*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(Reg0));
174*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(Reg1));
175*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(Op2);
176*9880d681SAndroid Build Coastguard Worker TmpInst.setLoc(IDLoc);
177*9880d681SAndroid Build Coastguard Worker getStreamer().EmitInstruction(TmpInst, *STI);
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
emitRRR(unsigned Opcode,unsigned Reg0,unsigned Reg1,unsigned Reg2,SMLoc IDLoc,const MCSubtargetInfo * STI)180*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1,
181*9880d681SAndroid Build Coastguard Worker unsigned Reg2, SMLoc IDLoc,
182*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
183*9880d681SAndroid Build Coastguard Worker emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc, STI);
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker
emitRRI(unsigned Opcode,unsigned Reg0,unsigned Reg1,int16_t Imm,SMLoc IDLoc,const MCSubtargetInfo * STI)186*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1,
187*9880d681SAndroid Build Coastguard Worker int16_t Imm, SMLoc IDLoc,
188*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
189*9880d681SAndroid Build Coastguard Worker emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc, STI);
190*9880d681SAndroid Build Coastguard Worker }
191*9880d681SAndroid Build Coastguard Worker
emitAddu(unsigned DstReg,unsigned SrcReg,unsigned TrgReg,bool Is64Bit,const MCSubtargetInfo * STI)192*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitAddu(unsigned DstReg, unsigned SrcReg,
193*9880d681SAndroid Build Coastguard Worker unsigned TrgReg, bool Is64Bit,
194*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
195*9880d681SAndroid Build Coastguard Worker emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
196*9880d681SAndroid Build Coastguard Worker STI);
197*9880d681SAndroid Build Coastguard Worker }
198*9880d681SAndroid Build Coastguard Worker
emitDSLL(unsigned DstReg,unsigned SrcReg,int16_t ShiftAmount,SMLoc IDLoc,const MCSubtargetInfo * STI)199*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitDSLL(unsigned DstReg, unsigned SrcReg,
200*9880d681SAndroid Build Coastguard Worker int16_t ShiftAmount, SMLoc IDLoc,
201*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
202*9880d681SAndroid Build Coastguard Worker if (ShiftAmount >= 32) {
203*9880d681SAndroid Build Coastguard Worker emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc, STI);
204*9880d681SAndroid Build Coastguard Worker return;
205*9880d681SAndroid Build Coastguard Worker }
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, STI);
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker
emitEmptyDelaySlot(bool hasShortDelaySlot,SMLoc IDLoc,const MCSubtargetInfo * STI)210*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc,
211*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
212*9880d681SAndroid Build Coastguard Worker if (hasShortDelaySlot)
213*9880d681SAndroid Build Coastguard Worker emitRR(Mips::MOVE16_MM, Mips::ZERO, Mips::ZERO, IDLoc, STI);
214*9880d681SAndroid Build Coastguard Worker else
215*9880d681SAndroid Build Coastguard Worker emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
216*9880d681SAndroid Build Coastguard Worker }
217*9880d681SAndroid Build Coastguard Worker
emitNop(SMLoc IDLoc,const MCSubtargetInfo * STI)218*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI) {
219*9880d681SAndroid Build Coastguard Worker emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker /// Emit the $gp restore operation for .cprestore.
emitGPRestore(int Offset,SMLoc IDLoc,const MCSubtargetInfo * STI)223*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitGPRestore(int Offset, SMLoc IDLoc,
224*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
225*9880d681SAndroid Build Coastguard Worker emitLoadWithImmOffset(Mips::LW, Mips::GP, Mips::SP, Offset, Mips::GP, IDLoc,
226*9880d681SAndroid Build Coastguard Worker STI);
227*9880d681SAndroid Build Coastguard Worker }
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Worker /// Emit a store instruction with an immediate offset.
emitStoreWithImmOffset(unsigned Opcode,unsigned SrcReg,unsigned BaseReg,int64_t Offset,function_ref<unsigned ()> GetATReg,SMLoc IDLoc,const MCSubtargetInfo * STI)230*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitStoreWithImmOffset(
231*9880d681SAndroid Build Coastguard Worker unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset,
232*9880d681SAndroid Build Coastguard Worker function_ref<unsigned()> GetATReg, SMLoc IDLoc,
233*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
234*9880d681SAndroid Build Coastguard Worker if (isInt<16>(Offset)) {
235*9880d681SAndroid Build Coastguard Worker emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI);
236*9880d681SAndroid Build Coastguard Worker return;
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Worker // sw $8, offset($8) => lui $at, %hi(offset)
240*9880d681SAndroid Build Coastguard Worker // add $at, $at, $8
241*9880d681SAndroid Build Coastguard Worker // sw $8, %lo(offset)($at)
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker unsigned ATReg = GetATReg();
244*9880d681SAndroid Build Coastguard Worker if (!ATReg)
245*9880d681SAndroid Build Coastguard Worker return;
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker unsigned LoOffset = Offset & 0x0000ffff;
248*9880d681SAndroid Build Coastguard Worker unsigned HiOffset = (Offset & 0xffff0000) >> 16;
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker // If msb of LoOffset is 1(negative number) we must increment HiOffset
251*9880d681SAndroid Build Coastguard Worker // to account for the sign-extension of the low part.
252*9880d681SAndroid Build Coastguard Worker if (LoOffset & 0x8000)
253*9880d681SAndroid Build Coastguard Worker HiOffset++;
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker // Generate the base address in ATReg.
256*9880d681SAndroid Build Coastguard Worker emitRI(Mips::LUi, ATReg, HiOffset, IDLoc, STI);
257*9880d681SAndroid Build Coastguard Worker if (BaseReg != Mips::ZERO)
258*9880d681SAndroid Build Coastguard Worker emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI);
259*9880d681SAndroid Build Coastguard Worker // Emit the store with the adjusted base and offset.
260*9880d681SAndroid Build Coastguard Worker emitRRI(Opcode, SrcReg, ATReg, LoOffset, IDLoc, STI);
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker /// Emit a store instruction with an symbol offset. Symbols are assumed to be
264*9880d681SAndroid Build Coastguard Worker /// out of range for a simm16 will be expanded to appropriate instructions.
emitStoreWithSymOffset(unsigned Opcode,unsigned SrcReg,unsigned BaseReg,MCOperand & HiOperand,MCOperand & LoOperand,unsigned ATReg,SMLoc IDLoc,const MCSubtargetInfo * STI)265*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitStoreWithSymOffset(
266*9880d681SAndroid Build Coastguard Worker unsigned Opcode, unsigned SrcReg, unsigned BaseReg, MCOperand &HiOperand,
267*9880d681SAndroid Build Coastguard Worker MCOperand &LoOperand, unsigned ATReg, SMLoc IDLoc,
268*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
269*9880d681SAndroid Build Coastguard Worker // sw $8, sym => lui $at, %hi(sym)
270*9880d681SAndroid Build Coastguard Worker // sw $8, %lo(sym)($at)
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker // Generate the base address in ATReg.
273*9880d681SAndroid Build Coastguard Worker emitRX(Mips::LUi, ATReg, HiOperand, IDLoc, STI);
274*9880d681SAndroid Build Coastguard Worker if (BaseReg != Mips::ZERO)
275*9880d681SAndroid Build Coastguard Worker emitRRR(Mips::ADDu, ATReg, ATReg, BaseReg, IDLoc, STI);
276*9880d681SAndroid Build Coastguard Worker // Emit the store with the adjusted base and offset.
277*9880d681SAndroid Build Coastguard Worker emitRRX(Opcode, SrcReg, ATReg, LoOperand, IDLoc, STI);
278*9880d681SAndroid Build Coastguard Worker }
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker /// Emit a load instruction with an immediate offset. DstReg and TmpReg are
281*9880d681SAndroid Build Coastguard Worker /// permitted to be the same register iff DstReg is distinct from BaseReg and
282*9880d681SAndroid Build Coastguard Worker /// DstReg is a GPR. It is the callers responsibility to identify such cases
283*9880d681SAndroid Build Coastguard Worker /// and pass the appropriate register in TmpReg.
emitLoadWithImmOffset(unsigned Opcode,unsigned DstReg,unsigned BaseReg,int64_t Offset,unsigned TmpReg,SMLoc IDLoc,const MCSubtargetInfo * STI)284*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg,
285*9880d681SAndroid Build Coastguard Worker unsigned BaseReg, int64_t Offset,
286*9880d681SAndroid Build Coastguard Worker unsigned TmpReg, SMLoc IDLoc,
287*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
288*9880d681SAndroid Build Coastguard Worker if (isInt<16>(Offset)) {
289*9880d681SAndroid Build Coastguard Worker emitRRI(Opcode, DstReg, BaseReg, Offset, IDLoc, STI);
290*9880d681SAndroid Build Coastguard Worker return;
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker // 1) lw $8, offset($9) => lui $8, %hi(offset)
294*9880d681SAndroid Build Coastguard Worker // add $8, $8, $9
295*9880d681SAndroid Build Coastguard Worker // lw $8, %lo(offset)($9)
296*9880d681SAndroid Build Coastguard Worker // 2) lw $8, offset($8) => lui $at, %hi(offset)
297*9880d681SAndroid Build Coastguard Worker // add $at, $at, $8
298*9880d681SAndroid Build Coastguard Worker // lw $8, %lo(offset)($at)
299*9880d681SAndroid Build Coastguard Worker
300*9880d681SAndroid Build Coastguard Worker unsigned LoOffset = Offset & 0x0000ffff;
301*9880d681SAndroid Build Coastguard Worker unsigned HiOffset = (Offset & 0xffff0000) >> 16;
302*9880d681SAndroid Build Coastguard Worker
303*9880d681SAndroid Build Coastguard Worker // If msb of LoOffset is 1(negative number) we must increment HiOffset
304*9880d681SAndroid Build Coastguard Worker // to account for the sign-extension of the low part.
305*9880d681SAndroid Build Coastguard Worker if (LoOffset & 0x8000)
306*9880d681SAndroid Build Coastguard Worker HiOffset++;
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Worker // Generate the base address in TmpReg.
309*9880d681SAndroid Build Coastguard Worker emitRI(Mips::LUi, TmpReg, HiOffset, IDLoc, STI);
310*9880d681SAndroid Build Coastguard Worker if (BaseReg != Mips::ZERO)
311*9880d681SAndroid Build Coastguard Worker emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
312*9880d681SAndroid Build Coastguard Worker // Emit the load with the adjusted base and offset.
313*9880d681SAndroid Build Coastguard Worker emitRRI(Opcode, DstReg, TmpReg, LoOffset, IDLoc, STI);
314*9880d681SAndroid Build Coastguard Worker }
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker /// Emit a load instruction with an symbol offset. Symbols are assumed to be
317*9880d681SAndroid Build Coastguard Worker /// out of range for a simm16 will be expanded to appropriate instructions.
318*9880d681SAndroid Build Coastguard Worker /// DstReg and TmpReg are permitted to be the same register iff DstReg is a
319*9880d681SAndroid Build Coastguard Worker /// GPR. It is the callers responsibility to identify such cases and pass the
320*9880d681SAndroid Build Coastguard Worker /// appropriate register in TmpReg.
emitLoadWithSymOffset(unsigned Opcode,unsigned DstReg,unsigned BaseReg,MCOperand & HiOperand,MCOperand & LoOperand,unsigned TmpReg,SMLoc IDLoc,const MCSubtargetInfo * STI)321*9880d681SAndroid Build Coastguard Worker void MipsTargetStreamer::emitLoadWithSymOffset(unsigned Opcode, unsigned DstReg,
322*9880d681SAndroid Build Coastguard Worker unsigned BaseReg,
323*9880d681SAndroid Build Coastguard Worker MCOperand &HiOperand,
324*9880d681SAndroid Build Coastguard Worker MCOperand &LoOperand,
325*9880d681SAndroid Build Coastguard Worker unsigned TmpReg, SMLoc IDLoc,
326*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
327*9880d681SAndroid Build Coastguard Worker // 1) lw $8, sym => lui $8, %hi(sym)
328*9880d681SAndroid Build Coastguard Worker // lw $8, %lo(sym)($8)
329*9880d681SAndroid Build Coastguard Worker // 2) ldc1 $f0, sym => lui $at, %hi(sym)
330*9880d681SAndroid Build Coastguard Worker // ldc1 $f0, %lo(sym)($at)
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Worker // Generate the base address in TmpReg.
333*9880d681SAndroid Build Coastguard Worker emitRX(Mips::LUi, TmpReg, HiOperand, IDLoc, STI);
334*9880d681SAndroid Build Coastguard Worker if (BaseReg != Mips::ZERO)
335*9880d681SAndroid Build Coastguard Worker emitRRR(Mips::ADDu, TmpReg, TmpReg, BaseReg, IDLoc, STI);
336*9880d681SAndroid Build Coastguard Worker // Emit the load with the adjusted base and offset.
337*9880d681SAndroid Build Coastguard Worker emitRRX(Opcode, DstReg, TmpReg, LoOperand, IDLoc, STI);
338*9880d681SAndroid Build Coastguard Worker }
339*9880d681SAndroid Build Coastguard Worker
MipsTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS)340*9880d681SAndroid Build Coastguard Worker MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S,
341*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream &OS)
342*9880d681SAndroid Build Coastguard Worker : MipsTargetStreamer(S), OS(OS) {}
343*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMicroMips()344*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
345*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmicromips\n";
346*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
347*9880d681SAndroid Build Coastguard Worker }
348*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoMicroMips()349*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() {
350*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tnomicromips\n";
351*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
352*9880d681SAndroid Build Coastguard Worker }
353*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips16()354*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips16() {
355*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips16\n";
356*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
357*9880d681SAndroid Build Coastguard Worker }
358*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoMips16()359*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() {
360*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tnomips16\n";
361*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetNoMips16();
362*9880d681SAndroid Build Coastguard Worker }
363*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetReorder()364*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetReorder() {
365*9880d681SAndroid Build Coastguard Worker OS << "\t.set\treorder\n";
366*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetReorder();
367*9880d681SAndroid Build Coastguard Worker }
368*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoReorder()369*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() {
370*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tnoreorder\n";
371*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
372*9880d681SAndroid Build Coastguard Worker }
373*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMacro()374*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMacro() {
375*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmacro\n";
376*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMacro();
377*9880d681SAndroid Build Coastguard Worker }
378*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoMacro()379*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() {
380*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tnomacro\n";
381*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetNoMacro();
382*9880d681SAndroid Build Coastguard Worker }
383*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMsa()384*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMsa() {
385*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmsa\n";
386*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMsa();
387*9880d681SAndroid Build Coastguard Worker }
388*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoMsa()389*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetNoMsa() {
390*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tnomsa\n";
391*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetNoMsa();
392*9880d681SAndroid Build Coastguard Worker }
393*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetAt()394*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetAt() {
395*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tat\n";
396*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetAt();
397*9880d681SAndroid Build Coastguard Worker }
398*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetAtWithArg(unsigned RegNo)399*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) {
400*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tat=$" << Twine(RegNo) << "\n";
401*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetAtWithArg(RegNo);
402*9880d681SAndroid Build Coastguard Worker }
403*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoAt()404*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetNoAt() {
405*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tnoat\n";
406*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetNoAt();
407*9880d681SAndroid Build Coastguard Worker }
408*9880d681SAndroid Build Coastguard Worker
emitDirectiveEnd(StringRef Name)409*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) {
410*9880d681SAndroid Build Coastguard Worker OS << "\t.end\t" << Name << '\n';
411*9880d681SAndroid Build Coastguard Worker }
412*9880d681SAndroid Build Coastguard Worker
emitDirectiveEnt(const MCSymbol & Symbol)413*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
414*9880d681SAndroid Build Coastguard Worker OS << "\t.ent\t" << Symbol.getName() << '\n';
415*9880d681SAndroid Build Coastguard Worker }
416*9880d681SAndroid Build Coastguard Worker
emitDirectiveAbiCalls()417*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveAbiCalls() { OS << "\t.abicalls\n"; }
418*9880d681SAndroid Build Coastguard Worker
emitDirectiveNaN2008()419*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveNaN2008() { OS << "\t.nan\t2008\n"; }
420*9880d681SAndroid Build Coastguard Worker
emitDirectiveNaNLegacy()421*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveNaNLegacy() {
422*9880d681SAndroid Build Coastguard Worker OS << "\t.nan\tlegacy\n";
423*9880d681SAndroid Build Coastguard Worker }
424*9880d681SAndroid Build Coastguard Worker
emitDirectiveOptionPic0()425*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveOptionPic0() {
426*9880d681SAndroid Build Coastguard Worker OS << "\t.option\tpic0\n";
427*9880d681SAndroid Build Coastguard Worker }
428*9880d681SAndroid Build Coastguard Worker
emitDirectiveOptionPic2()429*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveOptionPic2() {
430*9880d681SAndroid Build Coastguard Worker OS << "\t.option\tpic2\n";
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker
emitDirectiveInsn()433*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveInsn() {
434*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveInsn();
435*9880d681SAndroid Build Coastguard Worker OS << "\t.insn\n";
436*9880d681SAndroid Build Coastguard Worker }
437*9880d681SAndroid Build Coastguard Worker
emitFrame(unsigned StackReg,unsigned StackSize,unsigned ReturnReg)438*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
439*9880d681SAndroid Build Coastguard Worker unsigned ReturnReg) {
440*9880d681SAndroid Build Coastguard Worker OS << "\t.frame\t$"
441*9880d681SAndroid Build Coastguard Worker << StringRef(MipsInstPrinter::getRegisterName(StackReg)).lower() << ","
442*9880d681SAndroid Build Coastguard Worker << StackSize << ",$"
443*9880d681SAndroid Build Coastguard Worker << StringRef(MipsInstPrinter::getRegisterName(ReturnReg)).lower() << '\n';
444*9880d681SAndroid Build Coastguard Worker }
445*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetArch(StringRef Arch)446*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) {
447*9880d681SAndroid Build Coastguard Worker OS << "\t.set arch=" << Arch << "\n";
448*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetArch(Arch);
449*9880d681SAndroid Build Coastguard Worker }
450*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips0()451*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips0() {
452*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips0\n";
453*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips0();
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips1()456*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips1() {
457*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips1\n";
458*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips1();
459*9880d681SAndroid Build Coastguard Worker }
460*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips2()461*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips2() {
462*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips2\n";
463*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips2();
464*9880d681SAndroid Build Coastguard Worker }
465*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips3()466*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips3() {
467*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips3\n";
468*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips3();
469*9880d681SAndroid Build Coastguard Worker }
470*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips4()471*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips4() {
472*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips4\n";
473*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips4();
474*9880d681SAndroid Build Coastguard Worker }
475*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips5()476*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips5() {
477*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips5\n";
478*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips5();
479*9880d681SAndroid Build Coastguard Worker }
480*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips32()481*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips32() {
482*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips32\n";
483*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips32();
484*9880d681SAndroid Build Coastguard Worker }
485*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips32R2()486*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() {
487*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips32r2\n";
488*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips32R2();
489*9880d681SAndroid Build Coastguard Worker }
490*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips32R3()491*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips32R3() {
492*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips32r3\n";
493*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips32R3();
494*9880d681SAndroid Build Coastguard Worker }
495*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips32R5()496*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips32R5() {
497*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips32r5\n";
498*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips32R5();
499*9880d681SAndroid Build Coastguard Worker }
500*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips32R6()501*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips32R6() {
502*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips32r6\n";
503*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips32R6();
504*9880d681SAndroid Build Coastguard Worker }
505*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips64()506*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips64() {
507*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips64\n";
508*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips64();
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips64R2()511*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() {
512*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips64r2\n";
513*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips64R2();
514*9880d681SAndroid Build Coastguard Worker }
515*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips64R3()516*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips64R3() {
517*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips64r3\n";
518*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips64R3();
519*9880d681SAndroid Build Coastguard Worker }
520*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips64R5()521*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips64R5() {
522*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips64r5\n";
523*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips64R5();
524*9880d681SAndroid Build Coastguard Worker }
525*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips64R6()526*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetMips64R6() {
527*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tmips64r6\n";
528*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetMips64R6();
529*9880d681SAndroid Build Coastguard Worker }
530*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetDsp()531*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetDsp() {
532*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tdsp\n";
533*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetDsp();
534*9880d681SAndroid Build Coastguard Worker }
535*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoDsp()536*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetNoDsp() {
537*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tnodsp\n";
538*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetNoDsp();
539*9880d681SAndroid Build Coastguard Worker }
540*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetPop()541*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetPop() {
542*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tpop\n";
543*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetPop();
544*9880d681SAndroid Build Coastguard Worker }
545*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetPush()546*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetPush() {
547*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tpush\n";
548*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetPush();
549*9880d681SAndroid Build Coastguard Worker }
550*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetSoftFloat()551*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetSoftFloat() {
552*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tsoftfloat\n";
553*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetSoftFloat();
554*9880d681SAndroid Build Coastguard Worker }
555*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetHardFloat()556*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetHardFloat() {
557*9880d681SAndroid Build Coastguard Worker OS << "\t.set\thardfloat\n";
558*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetHardFloat();
559*9880d681SAndroid Build Coastguard Worker }
560*9880d681SAndroid Build Coastguard Worker
561*9880d681SAndroid Build Coastguard Worker // Print a 32 bit hex number with all numbers.
printHex32(unsigned Value,raw_ostream & OS)562*9880d681SAndroid Build Coastguard Worker static void printHex32(unsigned Value, raw_ostream &OS) {
563*9880d681SAndroid Build Coastguard Worker OS << "0x";
564*9880d681SAndroid Build Coastguard Worker for (int i = 7; i >= 0; i--)
565*9880d681SAndroid Build Coastguard Worker OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4));
566*9880d681SAndroid Build Coastguard Worker }
567*9880d681SAndroid Build Coastguard Worker
emitMask(unsigned CPUBitmask,int CPUTopSavedRegOff)568*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
569*9880d681SAndroid Build Coastguard Worker int CPUTopSavedRegOff) {
570*9880d681SAndroid Build Coastguard Worker OS << "\t.mask \t";
571*9880d681SAndroid Build Coastguard Worker printHex32(CPUBitmask, OS);
572*9880d681SAndroid Build Coastguard Worker OS << ',' << CPUTopSavedRegOff << '\n';
573*9880d681SAndroid Build Coastguard Worker }
574*9880d681SAndroid Build Coastguard Worker
emitFMask(unsigned FPUBitmask,int FPUTopSavedRegOff)575*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitFMask(unsigned FPUBitmask,
576*9880d681SAndroid Build Coastguard Worker int FPUTopSavedRegOff) {
577*9880d681SAndroid Build Coastguard Worker OS << "\t.fmask\t";
578*9880d681SAndroid Build Coastguard Worker printHex32(FPUBitmask, OS);
579*9880d681SAndroid Build Coastguard Worker OS << "," << FPUTopSavedRegOff << '\n';
580*9880d681SAndroid Build Coastguard Worker }
581*9880d681SAndroid Build Coastguard Worker
emitDirectiveCpLoad(unsigned RegNo)582*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) {
583*9880d681SAndroid Build Coastguard Worker OS << "\t.cpload\t$"
584*9880d681SAndroid Build Coastguard Worker << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
585*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
586*9880d681SAndroid Build Coastguard Worker }
587*9880d681SAndroid Build Coastguard Worker
emitDirectiveCpRestore(int Offset,function_ref<unsigned ()> GetATReg,SMLoc IDLoc,const MCSubtargetInfo * STI)588*9880d681SAndroid Build Coastguard Worker bool MipsTargetAsmStreamer::emitDirectiveCpRestore(
589*9880d681SAndroid Build Coastguard Worker int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
590*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
591*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveCpRestore(Offset, GetATReg, IDLoc, STI);
592*9880d681SAndroid Build Coastguard Worker OS << "\t.cprestore\t" << Offset << "\n";
593*9880d681SAndroid Build Coastguard Worker return true;
594*9880d681SAndroid Build Coastguard Worker }
595*9880d681SAndroid Build Coastguard Worker
emitDirectiveCpsetup(unsigned RegNo,int RegOrOffset,const MCSymbol & Sym,bool IsReg)596*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
597*9880d681SAndroid Build Coastguard Worker int RegOrOffset,
598*9880d681SAndroid Build Coastguard Worker const MCSymbol &Sym,
599*9880d681SAndroid Build Coastguard Worker bool IsReg) {
600*9880d681SAndroid Build Coastguard Worker OS << "\t.cpsetup\t$"
601*9880d681SAndroid Build Coastguard Worker << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << ", ";
602*9880d681SAndroid Build Coastguard Worker
603*9880d681SAndroid Build Coastguard Worker if (IsReg)
604*9880d681SAndroid Build Coastguard Worker OS << "$"
605*9880d681SAndroid Build Coastguard Worker << StringRef(MipsInstPrinter::getRegisterName(RegOrOffset)).lower();
606*9880d681SAndroid Build Coastguard Worker else
607*9880d681SAndroid Build Coastguard Worker OS << RegOrOffset;
608*9880d681SAndroid Build Coastguard Worker
609*9880d681SAndroid Build Coastguard Worker OS << ", ";
610*9880d681SAndroid Build Coastguard Worker
611*9880d681SAndroid Build Coastguard Worker OS << Sym.getName();
612*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
613*9880d681SAndroid Build Coastguard Worker }
614*9880d681SAndroid Build Coastguard Worker
emitDirectiveCpreturn(unsigned SaveLocation,bool SaveLocationIsRegister)615*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
616*9880d681SAndroid Build Coastguard Worker bool SaveLocationIsRegister) {
617*9880d681SAndroid Build Coastguard Worker OS << "\t.cpreturn";
618*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
619*9880d681SAndroid Build Coastguard Worker }
620*9880d681SAndroid Build Coastguard Worker
emitDirectiveModuleFP()621*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveModuleFP() {
622*9880d681SAndroid Build Coastguard Worker OS << "\t.module\tfp=";
623*9880d681SAndroid Build Coastguard Worker OS << ABIFlagsSection.getFpABIString(ABIFlagsSection.getFpABI()) << "\n";
624*9880d681SAndroid Build Coastguard Worker }
625*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value)626*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetFp(
627*9880d681SAndroid Build Coastguard Worker MipsABIFlagsSection::FpABIKind Value) {
628*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetFp(Value);
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tfp=";
631*9880d681SAndroid Build Coastguard Worker OS << ABIFlagsSection.getFpABIString(Value) << "\n";
632*9880d681SAndroid Build Coastguard Worker }
633*9880d681SAndroid Build Coastguard Worker
emitDirectiveModuleOddSPReg()634*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg() {
635*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveModuleOddSPReg();
636*9880d681SAndroid Build Coastguard Worker
637*9880d681SAndroid Build Coastguard Worker OS << "\t.module\t" << (ABIFlagsSection.OddSPReg ? "" : "no") << "oddspreg\n";
638*9880d681SAndroid Build Coastguard Worker }
639*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetOddSPReg()640*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetOddSPReg() {
641*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetOddSPReg();
642*9880d681SAndroid Build Coastguard Worker OS << "\t.set\toddspreg\n";
643*9880d681SAndroid Build Coastguard Worker }
644*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoOddSPReg()645*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveSetNoOddSPReg() {
646*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveSetNoOddSPReg();
647*9880d681SAndroid Build Coastguard Worker OS << "\t.set\tnooddspreg\n";
648*9880d681SAndroid Build Coastguard Worker }
649*9880d681SAndroid Build Coastguard Worker
emitDirectiveModuleSoftFloat()650*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveModuleSoftFloat() {
651*9880d681SAndroid Build Coastguard Worker OS << "\t.module\tsoftfloat\n";
652*9880d681SAndroid Build Coastguard Worker }
653*9880d681SAndroid Build Coastguard Worker
emitDirectiveModuleHardFloat()654*9880d681SAndroid Build Coastguard Worker void MipsTargetAsmStreamer::emitDirectiveModuleHardFloat() {
655*9880d681SAndroid Build Coastguard Worker OS << "\t.module\thardfloat\n";
656*9880d681SAndroid Build Coastguard Worker }
657*9880d681SAndroid Build Coastguard Worker
658*9880d681SAndroid Build Coastguard Worker // This part is for ELF object output.
MipsTargetELFStreamer(MCStreamer & S,const MCSubtargetInfo & STI)659*9880d681SAndroid Build Coastguard Worker MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
660*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI)
661*9880d681SAndroid Build Coastguard Worker : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) {
662*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
663*9880d681SAndroid Build Coastguard Worker
664*9880d681SAndroid Build Coastguard Worker // It's possible that MCObjectFileInfo isn't fully initialized at this point
665*9880d681SAndroid Build Coastguard Worker // due to an initialization order problem where LLVMTargetMachine creates the
666*9880d681SAndroid Build Coastguard Worker // target streamer before TargetLoweringObjectFile calls
667*9880d681SAndroid Build Coastguard Worker // InitializeMCObjectFileInfo. There doesn't seem to be a single place that
668*9880d681SAndroid Build Coastguard Worker // covers all cases so this statement covers most cases and direct object
669*9880d681SAndroid Build Coastguard Worker // emission must call setPic() once MCObjectFileInfo has been initialized. The
670*9880d681SAndroid Build Coastguard Worker // cases we don't handle here are covered by MipsAsmPrinter.
671*9880d681SAndroid Build Coastguard Worker Pic = MCA.getContext().getObjectFileInfo()->isPositionIndependent();
672*9880d681SAndroid Build Coastguard Worker
673*9880d681SAndroid Build Coastguard Worker const FeatureBitset &Features = STI.getFeatureBits();
674*9880d681SAndroid Build Coastguard Worker
675*9880d681SAndroid Build Coastguard Worker // Set the header flags that we can in the constructor.
676*9880d681SAndroid Build Coastguard Worker // FIXME: This is a fairly terrible hack. We set the rest
677*9880d681SAndroid Build Coastguard Worker // of these in the destructor. The problem here is two-fold:
678*9880d681SAndroid Build Coastguard Worker //
679*9880d681SAndroid Build Coastguard Worker // a: Some of the eflags can be set/reset by directives.
680*9880d681SAndroid Build Coastguard Worker // b: There aren't any usage paths that initialize the ABI
681*9880d681SAndroid Build Coastguard Worker // pointer until after we initialize either an assembler
682*9880d681SAndroid Build Coastguard Worker // or the target machine.
683*9880d681SAndroid Build Coastguard Worker // We can fix this by making the target streamer construct
684*9880d681SAndroid Build Coastguard Worker // the ABI, but this is fraught with wide ranging dependency
685*9880d681SAndroid Build Coastguard Worker // issues as well.
686*9880d681SAndroid Build Coastguard Worker unsigned EFlags = MCA.getELFHeaderEFlags();
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker // Architecture
689*9880d681SAndroid Build Coastguard Worker if (Features[Mips::FeatureMips64r6])
690*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_64R6;
691*9880d681SAndroid Build Coastguard Worker else if (Features[Mips::FeatureMips64r2] ||
692*9880d681SAndroid Build Coastguard Worker Features[Mips::FeatureMips64r3] ||
693*9880d681SAndroid Build Coastguard Worker Features[Mips::FeatureMips64r5])
694*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_64R2;
695*9880d681SAndroid Build Coastguard Worker else if (Features[Mips::FeatureMips64])
696*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_64;
697*9880d681SAndroid Build Coastguard Worker else if (Features[Mips::FeatureMips5])
698*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_5;
699*9880d681SAndroid Build Coastguard Worker else if (Features[Mips::FeatureMips4])
700*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_4;
701*9880d681SAndroid Build Coastguard Worker else if (Features[Mips::FeatureMips3])
702*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_3;
703*9880d681SAndroid Build Coastguard Worker else if (Features[Mips::FeatureMips32r6])
704*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_32R6;
705*9880d681SAndroid Build Coastguard Worker else if (Features[Mips::FeatureMips32r2] ||
706*9880d681SAndroid Build Coastguard Worker Features[Mips::FeatureMips32r3] ||
707*9880d681SAndroid Build Coastguard Worker Features[Mips::FeatureMips32r5])
708*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_32R2;
709*9880d681SAndroid Build Coastguard Worker else if (Features[Mips::FeatureMips32])
710*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_32;
711*9880d681SAndroid Build Coastguard Worker else if (Features[Mips::FeatureMips2])
712*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_2;
713*9880d681SAndroid Build Coastguard Worker else
714*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ARCH_1;
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker // Machine
717*9880d681SAndroid Build Coastguard Worker if (Features[Mips::FeatureCnMips])
718*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_MACH_OCTEON;
719*9880d681SAndroid Build Coastguard Worker
720*9880d681SAndroid Build Coastguard Worker // Other options.
721*9880d681SAndroid Build Coastguard Worker if (Features[Mips::FeatureNaN2008])
722*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_NAN2008;
723*9880d681SAndroid Build Coastguard Worker
724*9880d681SAndroid Build Coastguard Worker // -mabicalls and -mplt are not implemented but we should act as if they were
725*9880d681SAndroid Build Coastguard Worker // given.
726*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_CPIC;
727*9880d681SAndroid Build Coastguard Worker
728*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(EFlags);
729*9880d681SAndroid Build Coastguard Worker }
730*9880d681SAndroid Build Coastguard Worker
emitLabel(MCSymbol * S)731*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitLabel(MCSymbol *S) {
732*9880d681SAndroid Build Coastguard Worker auto *Symbol = cast<MCSymbolELF>(S);
733*9880d681SAndroid Build Coastguard Worker if (!isMicroMipsEnabled())
734*9880d681SAndroid Build Coastguard Worker return;
735*9880d681SAndroid Build Coastguard Worker getStreamer().getAssembler().registerSymbol(*Symbol);
736*9880d681SAndroid Build Coastguard Worker uint8_t Type = Symbol->getType();
737*9880d681SAndroid Build Coastguard Worker if (Type != ELF::STT_FUNC)
738*9880d681SAndroid Build Coastguard Worker return;
739*9880d681SAndroid Build Coastguard Worker
740*9880d681SAndroid Build Coastguard Worker Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
741*9880d681SAndroid Build Coastguard Worker }
742*9880d681SAndroid Build Coastguard Worker
finish()743*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::finish() {
744*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
745*9880d681SAndroid Build Coastguard Worker const MCObjectFileInfo &OFI = *MCA.getContext().getObjectFileInfo();
746*9880d681SAndroid Build Coastguard Worker
747*9880d681SAndroid Build Coastguard Worker // .bss, .text and .data are always at least 16-byte aligned.
748*9880d681SAndroid Build Coastguard Worker MCSection &TextSection = *OFI.getTextSection();
749*9880d681SAndroid Build Coastguard Worker MCA.registerSection(TextSection);
750*9880d681SAndroid Build Coastguard Worker MCSection &DataSection = *OFI.getDataSection();
751*9880d681SAndroid Build Coastguard Worker MCA.registerSection(DataSection);
752*9880d681SAndroid Build Coastguard Worker MCSection &BSSSection = *OFI.getBSSSection();
753*9880d681SAndroid Build Coastguard Worker MCA.registerSection(BSSSection);
754*9880d681SAndroid Build Coastguard Worker
755*9880d681SAndroid Build Coastguard Worker TextSection.setAlignment(std::max(16u, TextSection.getAlignment()));
756*9880d681SAndroid Build Coastguard Worker DataSection.setAlignment(std::max(16u, DataSection.getAlignment()));
757*9880d681SAndroid Build Coastguard Worker BSSSection.setAlignment(std::max(16u, BSSSection.getAlignment()));
758*9880d681SAndroid Build Coastguard Worker
759*9880d681SAndroid Build Coastguard Worker if (RoundSectionSizes) {
760*9880d681SAndroid Build Coastguard Worker // Make sections sizes a multiple of the alignment. This is useful for
761*9880d681SAndroid Build Coastguard Worker // verifying the output of IAS against the output of other assemblers but
762*9880d681SAndroid Build Coastguard Worker // it's not necessary to produce a correct object and increases section
763*9880d681SAndroid Build Coastguard Worker // size.
764*9880d681SAndroid Build Coastguard Worker MCStreamer &OS = getStreamer();
765*9880d681SAndroid Build Coastguard Worker for (MCSection &S : MCA) {
766*9880d681SAndroid Build Coastguard Worker MCSectionELF &Section = static_cast<MCSectionELF &>(S);
767*9880d681SAndroid Build Coastguard Worker
768*9880d681SAndroid Build Coastguard Worker unsigned Alignment = Section.getAlignment();
769*9880d681SAndroid Build Coastguard Worker if (Alignment) {
770*9880d681SAndroid Build Coastguard Worker OS.SwitchSection(&Section);
771*9880d681SAndroid Build Coastguard Worker if (Section.UseCodeAlign())
772*9880d681SAndroid Build Coastguard Worker OS.EmitCodeAlignment(Alignment, Alignment);
773*9880d681SAndroid Build Coastguard Worker else
774*9880d681SAndroid Build Coastguard Worker OS.EmitValueToAlignment(Alignment, 0, 1, Alignment);
775*9880d681SAndroid Build Coastguard Worker }
776*9880d681SAndroid Build Coastguard Worker }
777*9880d681SAndroid Build Coastguard Worker }
778*9880d681SAndroid Build Coastguard Worker
779*9880d681SAndroid Build Coastguard Worker const FeatureBitset &Features = STI.getFeatureBits();
780*9880d681SAndroid Build Coastguard Worker
781*9880d681SAndroid Build Coastguard Worker // Update e_header flags. See the FIXME and comment above in
782*9880d681SAndroid Build Coastguard Worker // the constructor for a full rundown on this.
783*9880d681SAndroid Build Coastguard Worker unsigned EFlags = MCA.getELFHeaderEFlags();
784*9880d681SAndroid Build Coastguard Worker
785*9880d681SAndroid Build Coastguard Worker // ABI
786*9880d681SAndroid Build Coastguard Worker // N64 does not require any ABI bits.
787*9880d681SAndroid Build Coastguard Worker if (getABI().IsO32())
788*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ABI_O32;
789*9880d681SAndroid Build Coastguard Worker else if (getABI().IsN32())
790*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_ABI2;
791*9880d681SAndroid Build Coastguard Worker
792*9880d681SAndroid Build Coastguard Worker if (Features[Mips::FeatureGP64Bit]) {
793*9880d681SAndroid Build Coastguard Worker if (getABI().IsO32())
794*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_32BITMODE; /* Compatibility Mode */
795*9880d681SAndroid Build Coastguard Worker } else if (Features[Mips::FeatureMips64r2] || Features[Mips::FeatureMips64])
796*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_32BITMODE;
797*9880d681SAndroid Build Coastguard Worker
798*9880d681SAndroid Build Coastguard Worker // If we've set the cpic eflag and we're n64, go ahead and set the pic
799*9880d681SAndroid Build Coastguard Worker // one as well.
800*9880d681SAndroid Build Coastguard Worker if (EFlags & ELF::EF_MIPS_CPIC && getABI().IsN64())
801*9880d681SAndroid Build Coastguard Worker EFlags |= ELF::EF_MIPS_PIC;
802*9880d681SAndroid Build Coastguard Worker
803*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(EFlags);
804*9880d681SAndroid Build Coastguard Worker
805*9880d681SAndroid Build Coastguard Worker // Emit all the option records.
806*9880d681SAndroid Build Coastguard Worker // At the moment we are only emitting .Mips.options (ODK_REGINFO) and
807*9880d681SAndroid Build Coastguard Worker // .reginfo.
808*9880d681SAndroid Build Coastguard Worker MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
809*9880d681SAndroid Build Coastguard Worker MEF.EmitMipsOptionRecords();
810*9880d681SAndroid Build Coastguard Worker
811*9880d681SAndroid Build Coastguard Worker emitMipsAbiFlags();
812*9880d681SAndroid Build Coastguard Worker }
813*9880d681SAndroid Build Coastguard Worker
emitAssignment(MCSymbol * S,const MCExpr * Value)814*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitAssignment(MCSymbol *S, const MCExpr *Value) {
815*9880d681SAndroid Build Coastguard Worker auto *Symbol = cast<MCSymbolELF>(S);
816*9880d681SAndroid Build Coastguard Worker // If on rhs is micromips symbol then mark Symbol as microMips.
817*9880d681SAndroid Build Coastguard Worker if (Value->getKind() != MCExpr::SymbolRef)
818*9880d681SAndroid Build Coastguard Worker return;
819*9880d681SAndroid Build Coastguard Worker const auto &RhsSym = cast<MCSymbolELF>(
820*9880d681SAndroid Build Coastguard Worker static_cast<const MCSymbolRefExpr *>(Value)->getSymbol());
821*9880d681SAndroid Build Coastguard Worker
822*9880d681SAndroid Build Coastguard Worker if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS))
823*9880d681SAndroid Build Coastguard Worker return;
824*9880d681SAndroid Build Coastguard Worker
825*9880d681SAndroid Build Coastguard Worker Symbol->setOther(ELF::STO_MIPS_MICROMIPS);
826*9880d681SAndroid Build Coastguard Worker }
827*9880d681SAndroid Build Coastguard Worker
getStreamer()828*9880d681SAndroid Build Coastguard Worker MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
829*9880d681SAndroid Build Coastguard Worker return static_cast<MCELFStreamer &>(Streamer);
830*9880d681SAndroid Build Coastguard Worker }
831*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMicroMips()832*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveSetMicroMips() {
833*9880d681SAndroid Build Coastguard Worker MicroMipsEnabled = true;
834*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
835*9880d681SAndroid Build Coastguard Worker }
836*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoMicroMips()837*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
838*9880d681SAndroid Build Coastguard Worker MicroMipsEnabled = false;
839*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
840*9880d681SAndroid Build Coastguard Worker }
841*9880d681SAndroid Build Coastguard Worker
setUsesMicroMips()842*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::setUsesMicroMips() {
843*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
844*9880d681SAndroid Build Coastguard Worker unsigned Flags = MCA.getELFHeaderEFlags();
845*9880d681SAndroid Build Coastguard Worker Flags |= ELF::EF_MIPS_MICROMIPS;
846*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(Flags);
847*9880d681SAndroid Build Coastguard Worker }
848*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetMips16()849*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveSetMips16() {
850*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
851*9880d681SAndroid Build Coastguard Worker unsigned Flags = MCA.getELFHeaderEFlags();
852*9880d681SAndroid Build Coastguard Worker Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
853*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(Flags);
854*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
855*9880d681SAndroid Build Coastguard Worker }
856*9880d681SAndroid Build Coastguard Worker
emitDirectiveSetNoReorder()857*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
858*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
859*9880d681SAndroid Build Coastguard Worker unsigned Flags = MCA.getELFHeaderEFlags();
860*9880d681SAndroid Build Coastguard Worker Flags |= ELF::EF_MIPS_NOREORDER;
861*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(Flags);
862*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
863*9880d681SAndroid Build Coastguard Worker }
864*9880d681SAndroid Build Coastguard Worker
emitDirectiveEnd(StringRef Name)865*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
866*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
867*9880d681SAndroid Build Coastguard Worker MCContext &Context = MCA.getContext();
868*9880d681SAndroid Build Coastguard Worker MCStreamer &OS = getStreamer();
869*9880d681SAndroid Build Coastguard Worker
870*9880d681SAndroid Build Coastguard Worker MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, 0);
871*9880d681SAndroid Build Coastguard Worker
872*9880d681SAndroid Build Coastguard Worker MCSymbol *Sym = Context.getOrCreateSymbol(Name);
873*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *ExprRef =
874*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Context);
875*9880d681SAndroid Build Coastguard Worker
876*9880d681SAndroid Build Coastguard Worker MCA.registerSection(*Sec);
877*9880d681SAndroid Build Coastguard Worker Sec->setAlignment(4);
878*9880d681SAndroid Build Coastguard Worker
879*9880d681SAndroid Build Coastguard Worker OS.PushSection();
880*9880d681SAndroid Build Coastguard Worker
881*9880d681SAndroid Build Coastguard Worker OS.SwitchSection(Sec);
882*9880d681SAndroid Build Coastguard Worker
883*9880d681SAndroid Build Coastguard Worker OS.EmitValueImpl(ExprRef, 4);
884*9880d681SAndroid Build Coastguard Worker
885*9880d681SAndroid Build Coastguard Worker OS.EmitIntValue(GPRInfoSet ? GPRBitMask : 0, 4); // reg_mask
886*9880d681SAndroid Build Coastguard Worker OS.EmitIntValue(GPRInfoSet ? GPROffset : 0, 4); // reg_offset
887*9880d681SAndroid Build Coastguard Worker
888*9880d681SAndroid Build Coastguard Worker OS.EmitIntValue(FPRInfoSet ? FPRBitMask : 0, 4); // fpreg_mask
889*9880d681SAndroid Build Coastguard Worker OS.EmitIntValue(FPRInfoSet ? FPROffset : 0, 4); // fpreg_offset
890*9880d681SAndroid Build Coastguard Worker
891*9880d681SAndroid Build Coastguard Worker OS.EmitIntValue(FrameInfoSet ? FrameOffset : 0, 4); // frame_offset
892*9880d681SAndroid Build Coastguard Worker OS.EmitIntValue(FrameInfoSet ? FrameReg : 0, 4); // frame_reg
893*9880d681SAndroid Build Coastguard Worker OS.EmitIntValue(FrameInfoSet ? ReturnReg : 0, 4); // return_reg
894*9880d681SAndroid Build Coastguard Worker
895*9880d681SAndroid Build Coastguard Worker // The .end directive marks the end of a procedure. Invalidate
896*9880d681SAndroid Build Coastguard Worker // the information gathered up until this point.
897*9880d681SAndroid Build Coastguard Worker GPRInfoSet = FPRInfoSet = FrameInfoSet = false;
898*9880d681SAndroid Build Coastguard Worker
899*9880d681SAndroid Build Coastguard Worker OS.PopSection();
900*9880d681SAndroid Build Coastguard Worker
901*9880d681SAndroid Build Coastguard Worker // .end also implicitly sets the size.
902*9880d681SAndroid Build Coastguard Worker MCSymbol *CurPCSym = Context.createTempSymbol();
903*9880d681SAndroid Build Coastguard Worker OS.EmitLabel(CurPCSym);
904*9880d681SAndroid Build Coastguard Worker const MCExpr *Size = MCBinaryExpr::createSub(
905*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(CurPCSym, MCSymbolRefExpr::VK_None, Context),
906*9880d681SAndroid Build Coastguard Worker ExprRef, Context);
907*9880d681SAndroid Build Coastguard Worker int64_t AbsSize;
908*9880d681SAndroid Build Coastguard Worker if (!Size->evaluateAsAbsolute(AbsSize, MCA))
909*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Function size must be evaluatable as absolute");
910*9880d681SAndroid Build Coastguard Worker Size = MCConstantExpr::create(AbsSize, Context);
911*9880d681SAndroid Build Coastguard Worker static_cast<MCSymbolELF *>(Sym)->setSize(Size);
912*9880d681SAndroid Build Coastguard Worker }
913*9880d681SAndroid Build Coastguard Worker
emitDirectiveEnt(const MCSymbol & Symbol)914*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
915*9880d681SAndroid Build Coastguard Worker GPRInfoSet = FPRInfoSet = FrameInfoSet = false;
916*9880d681SAndroid Build Coastguard Worker
917*9880d681SAndroid Build Coastguard Worker // .ent also acts like an implicit '.type symbol, STT_FUNC'
918*9880d681SAndroid Build Coastguard Worker static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
919*9880d681SAndroid Build Coastguard Worker }
920*9880d681SAndroid Build Coastguard Worker
emitDirectiveAbiCalls()921*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
922*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
923*9880d681SAndroid Build Coastguard Worker unsigned Flags = MCA.getELFHeaderEFlags();
924*9880d681SAndroid Build Coastguard Worker Flags |= ELF::EF_MIPS_CPIC | ELF::EF_MIPS_PIC;
925*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(Flags);
926*9880d681SAndroid Build Coastguard Worker }
927*9880d681SAndroid Build Coastguard Worker
emitDirectiveNaN2008()928*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveNaN2008() {
929*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
930*9880d681SAndroid Build Coastguard Worker unsigned Flags = MCA.getELFHeaderEFlags();
931*9880d681SAndroid Build Coastguard Worker Flags |= ELF::EF_MIPS_NAN2008;
932*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(Flags);
933*9880d681SAndroid Build Coastguard Worker }
934*9880d681SAndroid Build Coastguard Worker
emitDirectiveNaNLegacy()935*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveNaNLegacy() {
936*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
937*9880d681SAndroid Build Coastguard Worker unsigned Flags = MCA.getELFHeaderEFlags();
938*9880d681SAndroid Build Coastguard Worker Flags &= ~ELF::EF_MIPS_NAN2008;
939*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(Flags);
940*9880d681SAndroid Build Coastguard Worker }
941*9880d681SAndroid Build Coastguard Worker
emitDirectiveOptionPic0()942*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveOptionPic0() {
943*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
944*9880d681SAndroid Build Coastguard Worker unsigned Flags = MCA.getELFHeaderEFlags();
945*9880d681SAndroid Build Coastguard Worker // This option overrides other PIC options like -KPIC.
946*9880d681SAndroid Build Coastguard Worker Pic = false;
947*9880d681SAndroid Build Coastguard Worker Flags &= ~ELF::EF_MIPS_PIC;
948*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(Flags);
949*9880d681SAndroid Build Coastguard Worker }
950*9880d681SAndroid Build Coastguard Worker
emitDirectiveOptionPic2()951*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveOptionPic2() {
952*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
953*9880d681SAndroid Build Coastguard Worker unsigned Flags = MCA.getELFHeaderEFlags();
954*9880d681SAndroid Build Coastguard Worker Pic = true;
955*9880d681SAndroid Build Coastguard Worker // NOTE: We are following the GAS behaviour here which means the directive
956*9880d681SAndroid Build Coastguard Worker // 'pic2' also sets the CPIC bit in the ELF header. This is different from
957*9880d681SAndroid Build Coastguard Worker // what is stated in the SYSV ABI which consider the bits EF_MIPS_PIC and
958*9880d681SAndroid Build Coastguard Worker // EF_MIPS_CPIC to be mutually exclusive.
959*9880d681SAndroid Build Coastguard Worker Flags |= ELF::EF_MIPS_PIC | ELF::EF_MIPS_CPIC;
960*9880d681SAndroid Build Coastguard Worker MCA.setELFHeaderEFlags(Flags);
961*9880d681SAndroid Build Coastguard Worker }
962*9880d681SAndroid Build Coastguard Worker
emitDirectiveInsn()963*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveInsn() {
964*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveInsn();
965*9880d681SAndroid Build Coastguard Worker MipsELFStreamer &MEF = static_cast<MipsELFStreamer &>(Streamer);
966*9880d681SAndroid Build Coastguard Worker MEF.createPendingLabelRelocs();
967*9880d681SAndroid Build Coastguard Worker }
968*9880d681SAndroid Build Coastguard Worker
emitFrame(unsigned StackReg,unsigned StackSize,unsigned ReturnReg_)969*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitFrame(unsigned StackReg, unsigned StackSize,
970*9880d681SAndroid Build Coastguard Worker unsigned ReturnReg_) {
971*9880d681SAndroid Build Coastguard Worker MCContext &Context = getStreamer().getAssembler().getContext();
972*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo *RegInfo = Context.getRegisterInfo();
973*9880d681SAndroid Build Coastguard Worker
974*9880d681SAndroid Build Coastguard Worker FrameInfoSet = true;
975*9880d681SAndroid Build Coastguard Worker FrameReg = RegInfo->getEncodingValue(StackReg);
976*9880d681SAndroid Build Coastguard Worker FrameOffset = StackSize;
977*9880d681SAndroid Build Coastguard Worker ReturnReg = RegInfo->getEncodingValue(ReturnReg_);
978*9880d681SAndroid Build Coastguard Worker }
979*9880d681SAndroid Build Coastguard Worker
emitMask(unsigned CPUBitmask,int CPUTopSavedRegOff)980*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitMask(unsigned CPUBitmask,
981*9880d681SAndroid Build Coastguard Worker int CPUTopSavedRegOff) {
982*9880d681SAndroid Build Coastguard Worker GPRInfoSet = true;
983*9880d681SAndroid Build Coastguard Worker GPRBitMask = CPUBitmask;
984*9880d681SAndroid Build Coastguard Worker GPROffset = CPUTopSavedRegOff;
985*9880d681SAndroid Build Coastguard Worker }
986*9880d681SAndroid Build Coastguard Worker
emitFMask(unsigned FPUBitmask,int FPUTopSavedRegOff)987*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitFMask(unsigned FPUBitmask,
988*9880d681SAndroid Build Coastguard Worker int FPUTopSavedRegOff) {
989*9880d681SAndroid Build Coastguard Worker FPRInfoSet = true;
990*9880d681SAndroid Build Coastguard Worker FPRBitMask = FPUBitmask;
991*9880d681SAndroid Build Coastguard Worker FPROffset = FPUTopSavedRegOff;
992*9880d681SAndroid Build Coastguard Worker }
993*9880d681SAndroid Build Coastguard Worker
emitDirectiveCpLoad(unsigned RegNo)994*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) {
995*9880d681SAndroid Build Coastguard Worker // .cpload $reg
996*9880d681SAndroid Build Coastguard Worker // This directive expands to:
997*9880d681SAndroid Build Coastguard Worker // lui $gp, %hi(_gp_disp)
998*9880d681SAndroid Build Coastguard Worker // addui $gp, $gp, %lo(_gp_disp)
999*9880d681SAndroid Build Coastguard Worker // addu $gp, $gp, $reg
1000*9880d681SAndroid Build Coastguard Worker // when support for position independent code is enabled.
1001*9880d681SAndroid Build Coastguard Worker if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1002*9880d681SAndroid Build Coastguard Worker return;
1003*9880d681SAndroid Build Coastguard Worker
1004*9880d681SAndroid Build Coastguard Worker // There's a GNU extension controlled by -mno-shared that allows
1005*9880d681SAndroid Build Coastguard Worker // locally-binding symbols to be accessed using absolute addresses.
1006*9880d681SAndroid Build Coastguard Worker // This is currently not supported. When supported -mno-shared makes
1007*9880d681SAndroid Build Coastguard Worker // .cpload expand to:
1008*9880d681SAndroid Build Coastguard Worker // lui $gp, %hi(__gnu_local_gp)
1009*9880d681SAndroid Build Coastguard Worker // addiu $gp, $gp, %lo(__gnu_local_gp)
1010*9880d681SAndroid Build Coastguard Worker
1011*9880d681SAndroid Build Coastguard Worker StringRef SymName("_gp_disp");
1012*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
1013*9880d681SAndroid Build Coastguard Worker MCSymbol *GP_Disp = MCA.getContext().getOrCreateSymbol(SymName);
1014*9880d681SAndroid Build Coastguard Worker MCA.registerSymbol(*GP_Disp);
1015*9880d681SAndroid Build Coastguard Worker
1016*9880d681SAndroid Build Coastguard Worker MCInst TmpInst;
1017*9880d681SAndroid Build Coastguard Worker TmpInst.setOpcode(Mips::LUi);
1018*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1019*9880d681SAndroid Build Coastguard Worker const MCExpr *HiSym = MipsMCExpr::create(
1020*9880d681SAndroid Build Coastguard Worker MipsMCExpr::MEK_HI,
1021*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create("_gp_disp", MCSymbolRefExpr::VK_None,
1022*9880d681SAndroid Build Coastguard Worker MCA.getContext()),
1023*9880d681SAndroid Build Coastguard Worker MCA.getContext());
1024*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createExpr(HiSym));
1025*9880d681SAndroid Build Coastguard Worker getStreamer().EmitInstruction(TmpInst, STI);
1026*9880d681SAndroid Build Coastguard Worker
1027*9880d681SAndroid Build Coastguard Worker TmpInst.clear();
1028*9880d681SAndroid Build Coastguard Worker
1029*9880d681SAndroid Build Coastguard Worker TmpInst.setOpcode(Mips::ADDiu);
1030*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1031*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1032*9880d681SAndroid Build Coastguard Worker const MCExpr *LoSym = MipsMCExpr::create(
1033*9880d681SAndroid Build Coastguard Worker MipsMCExpr::MEK_LO,
1034*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create("_gp_disp", MCSymbolRefExpr::VK_None,
1035*9880d681SAndroid Build Coastguard Worker MCA.getContext()),
1036*9880d681SAndroid Build Coastguard Worker MCA.getContext());
1037*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createExpr(LoSym));
1038*9880d681SAndroid Build Coastguard Worker getStreamer().EmitInstruction(TmpInst, STI);
1039*9880d681SAndroid Build Coastguard Worker
1040*9880d681SAndroid Build Coastguard Worker TmpInst.clear();
1041*9880d681SAndroid Build Coastguard Worker
1042*9880d681SAndroid Build Coastguard Worker TmpInst.setOpcode(Mips::ADDu);
1043*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1044*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1045*9880d681SAndroid Build Coastguard Worker TmpInst.addOperand(MCOperand::createReg(RegNo));
1046*9880d681SAndroid Build Coastguard Worker getStreamer().EmitInstruction(TmpInst, STI);
1047*9880d681SAndroid Build Coastguard Worker
1048*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
1049*9880d681SAndroid Build Coastguard Worker }
1050*9880d681SAndroid Build Coastguard Worker
emitDirectiveCpRestore(int Offset,function_ref<unsigned ()> GetATReg,SMLoc IDLoc,const MCSubtargetInfo * STI)1051*9880d681SAndroid Build Coastguard Worker bool MipsTargetELFStreamer::emitDirectiveCpRestore(
1052*9880d681SAndroid Build Coastguard Worker int Offset, function_ref<unsigned()> GetATReg, SMLoc IDLoc,
1053*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo *STI) {
1054*9880d681SAndroid Build Coastguard Worker MipsTargetStreamer::emitDirectiveCpRestore(Offset, GetATReg, IDLoc, STI);
1055*9880d681SAndroid Build Coastguard Worker // .cprestore offset
1056*9880d681SAndroid Build Coastguard Worker // When PIC mode is enabled and the O32 ABI is used, this directive expands
1057*9880d681SAndroid Build Coastguard Worker // to:
1058*9880d681SAndroid Build Coastguard Worker // sw $gp, offset($sp)
1059*9880d681SAndroid Build Coastguard Worker // and adds a corresponding LW after every JAL.
1060*9880d681SAndroid Build Coastguard Worker
1061*9880d681SAndroid Build Coastguard Worker // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
1062*9880d681SAndroid Build Coastguard Worker // is used in non-PIC mode.
1063*9880d681SAndroid Build Coastguard Worker if (!Pic || (getABI().IsN32() || getABI().IsN64()))
1064*9880d681SAndroid Build Coastguard Worker return true;
1065*9880d681SAndroid Build Coastguard Worker
1066*9880d681SAndroid Build Coastguard Worker // Store the $gp on the stack.
1067*9880d681SAndroid Build Coastguard Worker emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, Offset, GetATReg, IDLoc,
1068*9880d681SAndroid Build Coastguard Worker STI);
1069*9880d681SAndroid Build Coastguard Worker return true;
1070*9880d681SAndroid Build Coastguard Worker }
1071*9880d681SAndroid Build Coastguard Worker
emitDirectiveCpsetup(unsigned RegNo,int RegOrOffset,const MCSymbol & Sym,bool IsReg)1072*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
1073*9880d681SAndroid Build Coastguard Worker int RegOrOffset,
1074*9880d681SAndroid Build Coastguard Worker const MCSymbol &Sym,
1075*9880d681SAndroid Build Coastguard Worker bool IsReg) {
1076*9880d681SAndroid Build Coastguard Worker // Only N32 and N64 emit anything for .cpsetup iff PIC is set.
1077*9880d681SAndroid Build Coastguard Worker if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1078*9880d681SAndroid Build Coastguard Worker return;
1079*9880d681SAndroid Build Coastguard Worker
1080*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
1081*9880d681SAndroid Build Coastguard Worker
1082*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
1083*9880d681SAndroid Build Coastguard Worker MCInst Inst;
1084*9880d681SAndroid Build Coastguard Worker
1085*9880d681SAndroid Build Coastguard Worker // Either store the old $gp in a register or on the stack
1086*9880d681SAndroid Build Coastguard Worker if (IsReg) {
1087*9880d681SAndroid Build Coastguard Worker // move $save, $gpreg
1088*9880d681SAndroid Build Coastguard Worker emitRRR(Mips::OR64, RegOrOffset, Mips::GP, Mips::ZERO, SMLoc(), &STI);
1089*9880d681SAndroid Build Coastguard Worker } else {
1090*9880d681SAndroid Build Coastguard Worker // sd $gpreg, offset($sp)
1091*9880d681SAndroid Build Coastguard Worker emitRRI(Mips::SD, Mips::GP, Mips::SP, RegOrOffset, SMLoc(), &STI);
1092*9880d681SAndroid Build Coastguard Worker }
1093*9880d681SAndroid Build Coastguard Worker
1094*9880d681SAndroid Build Coastguard Worker if (getABI().IsN32()) {
1095*9880d681SAndroid Build Coastguard Worker MCSymbol *GPSym = MCA.getContext().getOrCreateSymbol("__gnu_local_gp");
1096*9880d681SAndroid Build Coastguard Worker const MipsMCExpr *HiExpr = MipsMCExpr::create(
1097*9880d681SAndroid Build Coastguard Worker MipsMCExpr::MEK_HI, MCSymbolRefExpr::create(GPSym, MCA.getContext()),
1098*9880d681SAndroid Build Coastguard Worker MCA.getContext());
1099*9880d681SAndroid Build Coastguard Worker const MipsMCExpr *LoExpr = MipsMCExpr::create(
1100*9880d681SAndroid Build Coastguard Worker MipsMCExpr::MEK_LO, MCSymbolRefExpr::create(GPSym, MCA.getContext()),
1101*9880d681SAndroid Build Coastguard Worker MCA.getContext());
1102*9880d681SAndroid Build Coastguard Worker
1103*9880d681SAndroid Build Coastguard Worker // lui $gp, %hi(__gnu_local_gp)
1104*9880d681SAndroid Build Coastguard Worker emitRX(Mips::LUi, Mips::GP, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1105*9880d681SAndroid Build Coastguard Worker
1106*9880d681SAndroid Build Coastguard Worker // addiu $gp, $gp, %lo(__gnu_local_gp)
1107*9880d681SAndroid Build Coastguard Worker emitRRX(Mips::ADDiu, Mips::GP, Mips::GP, MCOperand::createExpr(LoExpr),
1108*9880d681SAndroid Build Coastguard Worker SMLoc(), &STI);
1109*9880d681SAndroid Build Coastguard Worker
1110*9880d681SAndroid Build Coastguard Worker return;
1111*9880d681SAndroid Build Coastguard Worker }
1112*9880d681SAndroid Build Coastguard Worker
1113*9880d681SAndroid Build Coastguard Worker const MipsMCExpr *HiExpr = MipsMCExpr::createGpOff(
1114*9880d681SAndroid Build Coastguard Worker MipsMCExpr::MEK_HI, MCSymbolRefExpr::create(&Sym, MCA.getContext()),
1115*9880d681SAndroid Build Coastguard Worker MCA.getContext());
1116*9880d681SAndroid Build Coastguard Worker const MipsMCExpr *LoExpr = MipsMCExpr::createGpOff(
1117*9880d681SAndroid Build Coastguard Worker MipsMCExpr::MEK_LO, MCSymbolRefExpr::create(&Sym, MCA.getContext()),
1118*9880d681SAndroid Build Coastguard Worker MCA.getContext());
1119*9880d681SAndroid Build Coastguard Worker
1120*9880d681SAndroid Build Coastguard Worker // lui $gp, %hi(%neg(%gp_rel(funcSym)))
1121*9880d681SAndroid Build Coastguard Worker emitRX(Mips::LUi, Mips::GP, MCOperand::createExpr(HiExpr), SMLoc(), &STI);
1122*9880d681SAndroid Build Coastguard Worker
1123*9880d681SAndroid Build Coastguard Worker // addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
1124*9880d681SAndroid Build Coastguard Worker emitRRX(Mips::ADDiu, Mips::GP, Mips::GP, MCOperand::createExpr(LoExpr),
1125*9880d681SAndroid Build Coastguard Worker SMLoc(), &STI);
1126*9880d681SAndroid Build Coastguard Worker
1127*9880d681SAndroid Build Coastguard Worker // daddu $gp, $gp, $funcreg
1128*9880d681SAndroid Build Coastguard Worker emitRRR(Mips::DADDu, Mips::GP, Mips::GP, RegNo, SMLoc(), &STI);
1129*9880d681SAndroid Build Coastguard Worker }
1130*9880d681SAndroid Build Coastguard Worker
emitDirectiveCpreturn(unsigned SaveLocation,bool SaveLocationIsRegister)1131*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
1132*9880d681SAndroid Build Coastguard Worker bool SaveLocationIsRegister) {
1133*9880d681SAndroid Build Coastguard Worker // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
1134*9880d681SAndroid Build Coastguard Worker if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
1135*9880d681SAndroid Build Coastguard Worker return;
1136*9880d681SAndroid Build Coastguard Worker
1137*9880d681SAndroid Build Coastguard Worker MCInst Inst;
1138*9880d681SAndroid Build Coastguard Worker // Either restore the old $gp from a register or on the stack
1139*9880d681SAndroid Build Coastguard Worker if (SaveLocationIsRegister) {
1140*9880d681SAndroid Build Coastguard Worker Inst.setOpcode(Mips::OR);
1141*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Mips::GP));
1142*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(SaveLocation));
1143*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Mips::ZERO));
1144*9880d681SAndroid Build Coastguard Worker } else {
1145*9880d681SAndroid Build Coastguard Worker Inst.setOpcode(Mips::LD);
1146*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Mips::GP));
1147*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Mips::SP));
1148*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(SaveLocation));
1149*9880d681SAndroid Build Coastguard Worker }
1150*9880d681SAndroid Build Coastguard Worker getStreamer().EmitInstruction(Inst, STI);
1151*9880d681SAndroid Build Coastguard Worker
1152*9880d681SAndroid Build Coastguard Worker forbidModuleDirective();
1153*9880d681SAndroid Build Coastguard Worker }
1154*9880d681SAndroid Build Coastguard Worker
emitMipsAbiFlags()1155*9880d681SAndroid Build Coastguard Worker void MipsTargetELFStreamer::emitMipsAbiFlags() {
1156*9880d681SAndroid Build Coastguard Worker MCAssembler &MCA = getStreamer().getAssembler();
1157*9880d681SAndroid Build Coastguard Worker MCContext &Context = MCA.getContext();
1158*9880d681SAndroid Build Coastguard Worker MCStreamer &OS = getStreamer();
1159*9880d681SAndroid Build Coastguard Worker MCSectionELF *Sec = Context.getELFSection(
1160*9880d681SAndroid Build Coastguard Worker ".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS, ELF::SHF_ALLOC, 24, "");
1161*9880d681SAndroid Build Coastguard Worker MCA.registerSection(*Sec);
1162*9880d681SAndroid Build Coastguard Worker Sec->setAlignment(8);
1163*9880d681SAndroid Build Coastguard Worker OS.SwitchSection(Sec);
1164*9880d681SAndroid Build Coastguard Worker
1165*9880d681SAndroid Build Coastguard Worker OS << ABIFlagsSection;
1166*9880d681SAndroid Build Coastguard Worker }
1167