OSDN Git Service

5ac3273022f208e18774051a18aa5656d7bad5df
[android-x86/external-llvm.git] / lib / Target / RISCV / MCTargetDesc / RISCVAsmBackend.cpp
1 //===-- RISCVAsmBackend.cpp - RISCV Assembler Backend ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MCTargetDesc/RISCVFixupKinds.h"
11 #include "MCTargetDesc/RISCVMCTargetDesc.h"
12 #include "llvm/ADT/APInt.h"
13 #include "llvm/MC/MCAsmBackend.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCDirectives.h"
17 #include "llvm/MC/MCELFObjectWriter.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCFixupKindInfo.h"
20 #include "llvm/MC/MCObjectWriter.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/MC/MCSymbol.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
25
26 using namespace llvm;
27
28 namespace {
29 class RISCVAsmBackend : public MCAsmBackend {
30   const MCSubtargetInfo &STI;
31   uint8_t OSABI;
32   bool Is64Bit;
33
34 public:
35   RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit)
36       : MCAsmBackend(support::little), STI(STI), OSABI(OSABI),
37         Is64Bit(Is64Bit) {}
38   ~RISCVAsmBackend() override {}
39
40   // Generate diff expression relocations if the relax feature is enabled,
41   // otherwise it is safe for the assembler to calculate these internally.
42   bool requiresDiffExpressionRelocations() const override {
43     return STI.getFeatureBits()[RISCV::FeatureRelax];
44   }
45   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
46                   const MCValue &Target, MutableArrayRef<char> Data,
47                   uint64_t Value, bool IsResolved) const override;
48
49   std::unique_ptr<MCObjectTargetWriter>
50   createObjectTargetWriter() const override;
51
52   // If linker relaxation is enabled, always emit relocations even if the fixup
53   // can be resolved. This is necessary for correctness as offsets may change
54   // during relaxation.
55   bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
56                              const MCValue &Target) override {
57     return STI.getFeatureBits()[RISCV::FeatureRelax];
58   }
59
60   bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
61                             const MCRelaxableFragment *DF,
62                             const MCAsmLayout &Layout) const override {
63     llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
64   }
65
66   bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
67                                     uint64_t Value,
68                                     const MCRelaxableFragment *DF,
69                                     const MCAsmLayout &Layout,
70                                     const bool WasForced) const override;
71
72   unsigned getNumFixupKinds() const override {
73     return RISCV::NumTargetFixupKinds;
74   }
75
76   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
77     const static MCFixupKindInfo Infos[RISCV::NumTargetFixupKinds] = {
78       // This table *must* be in the order that the fixup_* kinds are defined in
79       // RISCVFixupKinds.h.
80       //
81       // name                      offset bits  flags
82       { "fixup_riscv_hi20",         12,     20,  0 },
83       { "fixup_riscv_lo12_i",       20,     12,  0 },
84       { "fixup_riscv_lo12_s",        0,     32,  0 },
85       { "fixup_riscv_pcrel_hi20",   12,     20,  MCFixupKindInfo::FKF_IsPCRel },
86       { "fixup_riscv_pcrel_lo12_i", 20,     12,  MCFixupKindInfo::FKF_IsPCRel },
87       { "fixup_riscv_pcrel_lo12_s",  0,     32,  MCFixupKindInfo::FKF_IsPCRel },
88       { "fixup_riscv_jal",          12,     20,  MCFixupKindInfo::FKF_IsPCRel },
89       { "fixup_riscv_branch",        0,     32,  MCFixupKindInfo::FKF_IsPCRel },
90       { "fixup_riscv_rvc_jump",      2,     11,  MCFixupKindInfo::FKF_IsPCRel },
91       { "fixup_riscv_rvc_branch",    0,     16,  MCFixupKindInfo::FKF_IsPCRel }
92     };
93
94     if (Kind < FirstTargetFixupKind)
95       return MCAsmBackend::getFixupKindInfo(Kind);
96
97     assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
98            "Invalid kind!");
99     return Infos[Kind - FirstTargetFixupKind];
100   }
101
102   bool mayNeedRelaxation(const MCInst &Inst) const override;
103   unsigned getRelaxedOpcode(unsigned Op) const;
104
105   void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
106                         MCInst &Res) const override;
107
108
109   bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
110 };
111
112
113 bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
114                                                    bool Resolved,
115                                                    uint64_t Value,
116                                                    const MCRelaxableFragment *DF,
117                                                    const MCAsmLayout &Layout,
118                                                    const bool WasForced) const {
119   // Return true if the symbol is actually unresolved.
120   // Resolved could be always false when shouldForceRelocation return true.
121   // We use !WasForced to indicate that the symbol is unresolved and not forced
122   // by shouldForceRelocation.
123   if (!Resolved && !WasForced)
124     return true;
125
126   int64_t Offset = int64_t(Value);
127   switch ((unsigned)Fixup.getKind()) {
128   default:
129     return false;
130   case RISCV::fixup_riscv_rvc_branch:
131     // For compressed branch instructions the immediate must be
132     // in the range [-256, 254].
133     return Offset > 254 || Offset < -256;
134   case RISCV::fixup_riscv_rvc_jump:
135     // For compressed jump instructions the immediate must be
136     // in the range [-2048, 2046].
137     return Offset > 2046 || Offset < -2048;
138   }
139 }
140
141 void RISCVAsmBackend::relaxInstruction(const MCInst &Inst,
142                                        const MCSubtargetInfo &STI,
143                                        MCInst &Res) const {
144   // TODO: replace this with call to auto generated uncompressinstr() function.
145   switch (Inst.getOpcode()) {
146   default:
147     llvm_unreachable("Opcode not expected!");
148   case RISCV::C_BEQZ:
149     // c.beqz $rs1, $imm -> beq $rs1, X0, $imm.
150     Res.setOpcode(RISCV::BEQ);
151     Res.addOperand(Inst.getOperand(0));
152     Res.addOperand(MCOperand::createReg(RISCV::X0));
153     Res.addOperand(Inst.getOperand(1));
154     break;
155   case RISCV::C_BNEZ:
156     // c.bnez $rs1, $imm -> bne $rs1, X0, $imm.
157     Res.setOpcode(RISCV::BNE);
158     Res.addOperand(Inst.getOperand(0));
159     Res.addOperand(MCOperand::createReg(RISCV::X0));
160     Res.addOperand(Inst.getOperand(1));
161     break;
162   case RISCV::C_J:
163     // c.j $imm -> jal X0, $imm.
164     Res.setOpcode(RISCV::JAL);
165     Res.addOperand(MCOperand::createReg(RISCV::X0));
166     Res.addOperand(Inst.getOperand(0));
167     break;
168   case RISCV::C_JAL:
169     // c.jal $imm -> jal X1, $imm.
170     Res.setOpcode(RISCV::JAL);
171     Res.addOperand(MCOperand::createReg(RISCV::X1));
172     Res.addOperand(Inst.getOperand(0));
173     break;
174   }
175 }
176
177 // Given a compressed control flow instruction this function returns
178 // the expanded instruction.
179 unsigned RISCVAsmBackend::getRelaxedOpcode(unsigned Op) const {
180   switch (Op) {
181   default:
182     return Op;
183   case RISCV::C_BEQZ:
184     return RISCV::BEQ;
185   case RISCV::C_BNEZ:
186     return RISCV::BNE;
187   case RISCV::C_J:
188   case RISCV::C_JAL: // fall through.
189     return RISCV::JAL;
190   }
191 }
192
193 bool RISCVAsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
194   return getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode();
195 }
196
197 bool RISCVAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
198   bool HasStdExtC = STI.getFeatureBits()[RISCV::FeatureStdExtC];
199   unsigned MinNopLen = HasStdExtC ? 2 : 4;
200
201   if ((Count % MinNopLen) != 0)
202     return false;
203
204   // The canonical nop on RISC-V is addi x0, x0, 0.
205   uint64_t Nop32Count = Count / 4;
206   for (uint64_t i = Nop32Count; i != 0; --i)
207     OS.write("\x13\0\0\0", 4);
208
209   // The canonical nop on RVC is c.nop.
210   if (HasStdExtC) {
211     uint64_t Nop16Count = (Count - Nop32Count * 4) / 2;
212     for (uint64_t i = Nop16Count; i != 0; --i)
213       OS.write("\x01\0", 2);
214   }
215
216   return true;
217 }
218
219 static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
220                                  MCContext &Ctx) {
221   unsigned Kind = Fixup.getKind();
222   switch (Kind) {
223   default:
224     llvm_unreachable("Unknown fixup kind!");
225   case FK_Data_1:
226   case FK_Data_2:
227   case FK_Data_4:
228   case FK_Data_8:
229     return Value;
230   case RISCV::fixup_riscv_lo12_i:
231   case RISCV::fixup_riscv_pcrel_lo12_i:
232     return Value & 0xfff;
233   case RISCV::fixup_riscv_lo12_s:
234   case RISCV::fixup_riscv_pcrel_lo12_s:
235     return (((Value >> 5) & 0x7f) << 25) | ((Value & 0x1f) << 7);
236   case RISCV::fixup_riscv_hi20:
237   case RISCV::fixup_riscv_pcrel_hi20:
238     // Add 1 if bit 11 is 1, to compensate for low 12 bits being negative.
239     return ((Value + 0x800) >> 12) & 0xfffff;
240   case RISCV::fixup_riscv_jal: {
241     if (!isInt<21>(Value))
242       Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
243     if (Value & 0x1)
244       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");
245     // Need to produce imm[19|10:1|11|19:12] from the 21-bit Value.
246     unsigned Sbit = (Value >> 20) & 0x1;
247     unsigned Hi8 = (Value >> 12) & 0xff;
248     unsigned Mid1 = (Value >> 11) & 0x1;
249     unsigned Lo10 = (Value >> 1) & 0x3ff;
250     // Inst{31} = Sbit;
251     // Inst{30-21} = Lo10;
252     // Inst{20} = Mid1;
253     // Inst{19-12} = Hi8;
254     Value = (Sbit << 19) | (Lo10 << 9) | (Mid1 << 8) | Hi8;
255     return Value;
256   }
257   case RISCV::fixup_riscv_branch: {
258     if (!isInt<13>(Value))
259       Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
260     if (Value & 0x1)
261       Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned");
262     // Need to extract imm[12], imm[10:5], imm[4:1], imm[11] from the 13-bit
263     // Value.
264     unsigned Sbit = (Value >> 12) & 0x1;
265     unsigned Hi1 = (Value >> 11) & 0x1;
266     unsigned Mid6 = (Value >> 5) & 0x3f;
267     unsigned Lo4 = (Value >> 1) & 0xf;
268     // Inst{31} = Sbit;
269     // Inst{30-25} = Mid6;
270     // Inst{11-8} = Lo4;
271     // Inst{7} = Hi1;
272     Value = (Sbit << 31) | (Mid6 << 25) | (Lo4 << 8) | (Hi1 << 7);
273     return Value;
274   }
275   case RISCV::fixup_riscv_rvc_jump: {
276     // Need to produce offset[11|4|9:8|10|6|7|3:1|5] from the 11-bit Value.
277     unsigned Bit11  = (Value >> 11) & 0x1;
278     unsigned Bit4   = (Value >> 4) & 0x1;
279     unsigned Bit9_8 = (Value >> 8) & 0x3;
280     unsigned Bit10  = (Value >> 10) & 0x1;
281     unsigned Bit6   = (Value >> 6) & 0x1;
282     unsigned Bit7   = (Value >> 7) & 0x1;
283     unsigned Bit3_1 = (Value >> 1) & 0x7;
284     unsigned Bit5   = (Value >> 5) & 0x1;
285     Value = (Bit11 << 10) | (Bit4 << 9) | (Bit9_8 << 7) | (Bit10 << 6) |
286             (Bit6 << 5) | (Bit7 << 4) | (Bit3_1 << 1) | Bit5;
287     return Value;
288   }
289   case RISCV::fixup_riscv_rvc_branch: {
290     // Need to produce offset[8|4:3], [reg 3 bit], offset[7:6|2:1|5]
291     unsigned Bit8   = (Value >> 8) & 0x1;
292     unsigned Bit7_6 = (Value >> 6) & 0x3;
293     unsigned Bit5   = (Value >> 5) & 0x1;
294     unsigned Bit4_3 = (Value >> 3) & 0x3;
295     unsigned Bit2_1 = (Value >> 1) & 0x3;
296     Value = (Bit8 << 12) | (Bit4_3 << 10) | (Bit7_6 << 5) | (Bit2_1 << 3) |
297             (Bit5 << 2);
298     return Value;
299   }
300
301   }
302 }
303
304 void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
305                                  const MCValue &Target,
306                                  MutableArrayRef<char> Data, uint64_t Value,
307                                  bool IsResolved) const {
308   MCContext &Ctx = Asm.getContext();
309   MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
310   if (!Value)
311     return; // Doesn't change encoding.
312   // Apply any target-specific value adjustments.
313   Value = adjustFixupValue(Fixup, Value, Ctx);
314
315   // Shift the value into position.
316   Value <<= Info.TargetOffset;
317
318   unsigned Offset = Fixup.getOffset();
319   unsigned NumBytes = alignTo(Info.TargetSize + Info.TargetOffset, 8) / 8;
320
321   assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
322
323   // For each byte of the fragment that the fixup touches, mask in the
324   // bits from the fixup value.
325   for (unsigned i = 0; i != NumBytes; ++i) {
326     Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
327   }
328 }
329
330 std::unique_ptr<MCObjectTargetWriter>
331 RISCVAsmBackend::createObjectTargetWriter() const {
332   return createRISCVELFObjectWriter(OSABI, Is64Bit);
333 }
334
335 } // end anonymous namespace
336
337 MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
338                                           const MCSubtargetInfo &STI,
339                                           const MCRegisterInfo &MRI,
340                                           const MCTargetOptions &Options) {
341   const Triple &TT = STI.getTargetTriple();
342   uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
343   return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit());
344 }