xref: /aosp_15_r20/external/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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