1*9880d681SAndroid Build Coastguard Worker //===-- SparcAsmBackend.cpp - Sparc Assembler Backend ---------------------===//
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 #include "llvm/MC/MCAsmBackend.h"
11*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/SparcFixupKinds.h"
12*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/SparcMCTargetDesc.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCELFObjectWriter.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixupKindInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectWriter.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCValue.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker using namespace llvm;
21*9880d681SAndroid Build Coastguard Worker
adjustFixupValue(unsigned Kind,uint64_t Value)22*9880d681SAndroid Build Coastguard Worker static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
23*9880d681SAndroid Build Coastguard Worker switch (Kind) {
24*9880d681SAndroid Build Coastguard Worker default:
25*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown fixup kind!");
26*9880d681SAndroid Build Coastguard Worker case FK_Data_1:
27*9880d681SAndroid Build Coastguard Worker case FK_Data_2:
28*9880d681SAndroid Build Coastguard Worker case FK_Data_4:
29*9880d681SAndroid Build Coastguard Worker case FK_Data_8:
30*9880d681SAndroid Build Coastguard Worker return Value;
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_wplt30:
33*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_call30:
34*9880d681SAndroid Build Coastguard Worker return (Value >> 2) & 0x3fffffff;
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_br22:
37*9880d681SAndroid Build Coastguard Worker return (Value >> 2) & 0x3fffff;
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_br19:
40*9880d681SAndroid Build Coastguard Worker return (Value >> 2) & 0x7ffff;
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_br16_2:
43*9880d681SAndroid Build Coastguard Worker return (Value >> 2) & 0xc000;
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_br16_14:
46*9880d681SAndroid Build Coastguard Worker return (Value >> 2) & 0x3fff;
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_pc22:
49*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_got22:
50*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_gd_hi22:
51*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldm_hi22:
52*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_hi22:
53*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_hi22:
54*9880d681SAndroid Build Coastguard Worker return (Value >> 10) & 0x3fffff;
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_pc10:
57*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_got10:
58*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_gd_lo10:
59*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldm_lo10:
60*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_lo10:
61*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_lo10:
62*9880d681SAndroid Build Coastguard Worker return Value & 0x3ff;
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldo_hix22:
65*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_le_hix22:
66*9880d681SAndroid Build Coastguard Worker return (~Value >> 10) & 0x3fffff;
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldo_lox10:
69*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_le_lox10:
70*9880d681SAndroid Build Coastguard Worker return (~(~Value & 0x3ff)) & 0x1fff;
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_h44:
73*9880d681SAndroid Build Coastguard Worker return (Value >> 22) & 0x3fffff;
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_m44:
76*9880d681SAndroid Build Coastguard Worker return (Value >> 12) & 0x3ff;
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_l44:
79*9880d681SAndroid Build Coastguard Worker return Value & 0xfff;
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_hh:
82*9880d681SAndroid Build Coastguard Worker return (Value >> 42) & 0x3fffff;
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_hm:
85*9880d681SAndroid Build Coastguard Worker return (Value >> 32) & 0x3ff;
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_gd_add:
88*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_gd_call:
89*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldm_add:
90*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldm_call:
91*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldo_add:
92*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_ld:
93*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_ldx:
94*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_add:
95*9880d681SAndroid Build Coastguard Worker return 0;
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker }
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker namespace {
100*9880d681SAndroid Build Coastguard Worker class SparcAsmBackend : public MCAsmBackend {
101*9880d681SAndroid Build Coastguard Worker protected:
102*9880d681SAndroid Build Coastguard Worker const Target &TheTarget;
103*9880d681SAndroid Build Coastguard Worker bool IsLittleEndian;
104*9880d681SAndroid Build Coastguard Worker bool Is64Bit;
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker public:
SparcAsmBackend(const Target & T)107*9880d681SAndroid Build Coastguard Worker SparcAsmBackend(const Target &T)
108*9880d681SAndroid Build Coastguard Worker : MCAsmBackend(), TheTarget(T),
109*9880d681SAndroid Build Coastguard Worker IsLittleEndian(StringRef(TheTarget.getName()) == "sparcel"),
110*9880d681SAndroid Build Coastguard Worker Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {}
111*9880d681SAndroid Build Coastguard Worker
getNumFixupKinds() const112*9880d681SAndroid Build Coastguard Worker unsigned getNumFixupKinds() const override {
113*9880d681SAndroid Build Coastguard Worker return Sparc::NumTargetFixupKinds;
114*9880d681SAndroid Build Coastguard Worker }
115*9880d681SAndroid Build Coastguard Worker
getFixupKindInfo(MCFixupKind Kind) const116*9880d681SAndroid Build Coastguard Worker const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
117*9880d681SAndroid Build Coastguard Worker const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
118*9880d681SAndroid Build Coastguard Worker // name offset bits flags
119*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
120*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
121*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
122*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_br16_2", 10, 2, MCFixupKindInfo::FKF_IsPCRel },
123*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_br16_14", 18, 14, MCFixupKindInfo::FKF_IsPCRel },
124*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_hi22", 10, 22, 0 },
125*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_lo10", 22, 10, 0 },
126*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_h44", 10, 22, 0 },
127*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_m44", 22, 10, 0 },
128*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_l44", 20, 12, 0 },
129*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_hh", 10, 22, 0 },
130*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_hm", 22, 10, 0 },
131*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
132*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel },
133*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_got22", 10, 22, 0 },
134*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_got10", 22, 10, 0 },
135*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
136*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_gd_hi22", 10, 22, 0 },
137*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_gd_lo10", 22, 10, 0 },
138*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_gd_add", 0, 0, 0 },
139*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_gd_call", 0, 0, 0 },
140*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldm_hi22", 10, 22, 0 },
141*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldm_lo10", 22, 10, 0 },
142*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldm_add", 0, 0, 0 },
143*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldm_call", 0, 0, 0 },
144*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldo_hix22", 10, 22, 0 },
145*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldo_lox10", 22, 10, 0 },
146*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldo_add", 0, 0, 0 },
147*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_hi22", 10, 22, 0 },
148*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_lo10", 22, 10, 0 },
149*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_ld", 0, 0, 0 },
150*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_ldx", 0, 0, 0 },
151*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_add", 0, 0, 0 },
152*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_le_hix22", 0, 0, 0 },
153*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_le_lox10", 0, 0, 0 }
154*9880d681SAndroid Build Coastguard Worker };
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
157*9880d681SAndroid Build Coastguard Worker // name offset bits flags
158*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
159*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
160*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
161*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_br16_2", 20, 2, MCFixupKindInfo::FKF_IsPCRel },
162*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_br16_14", 0, 14, MCFixupKindInfo::FKF_IsPCRel },
163*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_hi22", 0, 22, 0 },
164*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_lo10", 0, 10, 0 },
165*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_h44", 0, 22, 0 },
166*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_m44", 0, 10, 0 },
167*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_l44", 0, 12, 0 },
168*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_hh", 0, 22, 0 },
169*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_hm", 0, 10, 0 },
170*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_pc22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
171*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_pc10", 0, 10, MCFixupKindInfo::FKF_IsPCRel },
172*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_got22", 0, 22, 0 },
173*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_got10", 0, 10, 0 },
174*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
175*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_gd_hi22", 0, 22, 0 },
176*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_gd_lo10", 0, 10, 0 },
177*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_gd_add", 0, 0, 0 },
178*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_gd_call", 0, 0, 0 },
179*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldm_hi22", 0, 22, 0 },
180*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldm_lo10", 0, 10, 0 },
181*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldm_add", 0, 0, 0 },
182*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldm_call", 0, 0, 0 },
183*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldo_hix22", 0, 22, 0 },
184*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldo_lox10", 0, 10, 0 },
185*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ldo_add", 0, 0, 0 },
186*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_hi22", 0, 22, 0 },
187*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_lo10", 0, 10, 0 },
188*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_ld", 0, 0, 0 },
189*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_ldx", 0, 0, 0 },
190*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_ie_add", 0, 0, 0 },
191*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_le_hix22", 0, 0, 0 },
192*9880d681SAndroid Build Coastguard Worker { "fixup_sparc_tls_le_lox10", 0, 0, 0 }
193*9880d681SAndroid Build Coastguard Worker };
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker if (Kind < FirstTargetFixupKind)
196*9880d681SAndroid Build Coastguard Worker return MCAsmBackend::getFixupKindInfo(Kind);
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
199*9880d681SAndroid Build Coastguard Worker "Invalid kind!");
200*9880d681SAndroid Build Coastguard Worker if (IsLittleEndian)
201*9880d681SAndroid Build Coastguard Worker return InfosLE[Kind - FirstTargetFixupKind];
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker return InfosBE[Kind - FirstTargetFixupKind];
204*9880d681SAndroid Build Coastguard Worker }
205*9880d681SAndroid Build Coastguard Worker
processFixupValue(const MCAssembler & Asm,const MCAsmLayout & Layout,const MCFixup & Fixup,const MCFragment * DF,const MCValue & Target,uint64_t & Value,bool & IsResolved)206*9880d681SAndroid Build Coastguard Worker void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout,
207*9880d681SAndroid Build Coastguard Worker const MCFixup &Fixup, const MCFragment *DF,
208*9880d681SAndroid Build Coastguard Worker const MCValue &Target, uint64_t &Value,
209*9880d681SAndroid Build Coastguard Worker bool &IsResolved) override {
210*9880d681SAndroid Build Coastguard Worker switch ((Sparc::Fixups)Fixup.getKind()) {
211*9880d681SAndroid Build Coastguard Worker default: break;
212*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_wplt30:
213*9880d681SAndroid Build Coastguard Worker if (Target.getSymA()->getSymbol().isTemporary())
214*9880d681SAndroid Build Coastguard Worker return;
215*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_gd_hi22:
216*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_gd_lo10:
217*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_gd_add:
218*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_gd_call:
219*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldm_hi22:
220*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldm_lo10:
221*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldm_add:
222*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldm_call:
223*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldo_hix22:
224*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldo_lox10:
225*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ldo_add:
226*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_hi22:
227*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_lo10:
228*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_ld:
229*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_ldx:
230*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_ie_add:
231*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_le_hix22:
232*9880d681SAndroid Build Coastguard Worker case Sparc::fixup_sparc_tls_le_lox10: IsResolved = false; break;
233*9880d681SAndroid Build Coastguard Worker }
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker
mayNeedRelaxation(const MCInst & Inst) const236*9880d681SAndroid Build Coastguard Worker bool mayNeedRelaxation(const MCInst &Inst) const override {
237*9880d681SAndroid Build Coastguard Worker // FIXME.
238*9880d681SAndroid Build Coastguard Worker return false;
239*9880d681SAndroid Build Coastguard Worker }
240*9880d681SAndroid Build Coastguard Worker
241*9880d681SAndroid Build Coastguard Worker /// fixupNeedsRelaxation - Target specific predicate for whether a given
242*9880d681SAndroid Build Coastguard Worker /// fixup requires the associated instruction to be relaxed.
fixupNeedsRelaxation(const MCFixup & Fixup,uint64_t Value,const MCRelaxableFragment * DF,const MCAsmLayout & Layout) const243*9880d681SAndroid Build Coastguard Worker bool fixupNeedsRelaxation(const MCFixup &Fixup,
244*9880d681SAndroid Build Coastguard Worker uint64_t Value,
245*9880d681SAndroid Build Coastguard Worker const MCRelaxableFragment *DF,
246*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout) const override {
247*9880d681SAndroid Build Coastguard Worker // FIXME.
248*9880d681SAndroid Build Coastguard Worker llvm_unreachable("fixupNeedsRelaxation() unimplemented");
249*9880d681SAndroid Build Coastguard Worker return false;
250*9880d681SAndroid Build Coastguard Worker }
relaxInstruction(const MCInst & Inst,const MCSubtargetInfo & STI,MCInst & Res) const251*9880d681SAndroid Build Coastguard Worker void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
252*9880d681SAndroid Build Coastguard Worker MCInst &Res) const override {
253*9880d681SAndroid Build Coastguard Worker // FIXME.
254*9880d681SAndroid Build Coastguard Worker llvm_unreachable("relaxInstruction() unimplemented");
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker
writeNopData(uint64_t Count,MCObjectWriter * OW) const257*9880d681SAndroid Build Coastguard Worker bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override {
258*9880d681SAndroid Build Coastguard Worker // Cannot emit NOP with size not multiple of 32 bits.
259*9880d681SAndroid Build Coastguard Worker if (Count % 4 != 0)
260*9880d681SAndroid Build Coastguard Worker return false;
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker uint64_t NumNops = Count / 4;
263*9880d681SAndroid Build Coastguard Worker for (uint64_t i = 0; i != NumNops; ++i)
264*9880d681SAndroid Build Coastguard Worker OW->write32(0x01000000);
265*9880d681SAndroid Build Coastguard Worker
266*9880d681SAndroid Build Coastguard Worker return true;
267*9880d681SAndroid Build Coastguard Worker }
268*9880d681SAndroid Build Coastguard Worker };
269*9880d681SAndroid Build Coastguard Worker
270*9880d681SAndroid Build Coastguard Worker class ELFSparcAsmBackend : public SparcAsmBackend {
271*9880d681SAndroid Build Coastguard Worker Triple::OSType OSType;
272*9880d681SAndroid Build Coastguard Worker public:
ELFSparcAsmBackend(const Target & T,Triple::OSType OSType)273*9880d681SAndroid Build Coastguard Worker ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
274*9880d681SAndroid Build Coastguard Worker SparcAsmBackend(T), OSType(OSType) { }
275*9880d681SAndroid Build Coastguard Worker
applyFixup(const MCFixup & Fixup,char * Data,unsigned DataSize,uint64_t Value,bool IsPCRel) const276*9880d681SAndroid Build Coastguard Worker void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
277*9880d681SAndroid Build Coastguard Worker uint64_t Value, bool IsPCRel) const override {
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Worker Value = adjustFixupValue(Fixup.getKind(), Value);
280*9880d681SAndroid Build Coastguard Worker if (!Value) return; // Doesn't change encoding.
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker unsigned Offset = Fixup.getOffset();
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker // For each byte of the fragment that the fixup touches, mask in the bits
285*9880d681SAndroid Build Coastguard Worker // from the fixup value. The Value has been "split up" into the
286*9880d681SAndroid Build Coastguard Worker // appropriate bitfields above.
287*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != 4; ++i) {
288*9880d681SAndroid Build Coastguard Worker unsigned Idx = IsLittleEndian ? i : 3 - i;
289*9880d681SAndroid Build Coastguard Worker Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker
createObjectWriter(raw_pwrite_stream & OS) const293*9880d681SAndroid Build Coastguard Worker MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override {
294*9880d681SAndroid Build Coastguard Worker uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
295*9880d681SAndroid Build Coastguard Worker return createSparcELFObjectWriter(OS, Is64Bit, IsLittleEndian, OSABI);
296*9880d681SAndroid Build Coastguard Worker }
297*9880d681SAndroid Build Coastguard Worker };
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
300*9880d681SAndroid Build Coastguard Worker
createSparcAsmBackend(const Target & T,const MCRegisterInfo & MRI,const Triple & TT,StringRef CPU)301*9880d681SAndroid Build Coastguard Worker MCAsmBackend *llvm::createSparcAsmBackend(const Target &T,
302*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo &MRI,
303*9880d681SAndroid Build Coastguard Worker const Triple &TT, StringRef CPU) {
304*9880d681SAndroid Build Coastguard Worker return new ELFSparcAsmBackend(T, TT.getOS());
305*9880d681SAndroid Build Coastguard Worker }
306