1 //===-- VEAsmBackend.cpp - VE Assembler Backend ---------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/VEFixupKinds.h"
10 #include "MCTargetDesc/VEMCTargetDesc.h"
11 #include "llvm/MC/MCAsmBackend.h"
12 #include "llvm/MC/MCELFObjectWriter.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCFixupKindInfo.h"
15 #include "llvm/MC/MCObjectWriter.h"
16 #include "llvm/MC/MCSubtargetInfo.h"
17 #include "llvm/MC/MCValue.h"
18 #include "llvm/MC/TargetRegistry.h"
19 #include "llvm/Support/EndianStream.h"
23 static uint64_t adjustFixupValue(unsigned Kind
, uint64_t Value
) {
26 llvm_unreachable("Unknown fixup kind!");
36 case VE::fixup_ve_hi32
:
37 case VE::fixup_ve_pc_hi32
:
38 case VE::fixup_ve_got_hi32
:
39 case VE::fixup_ve_gotoff_hi32
:
40 case VE::fixup_ve_plt_hi32
:
41 case VE::fixup_ve_tls_gd_hi32
:
42 case VE::fixup_ve_tpoff_hi32
:
43 return (Value
>> 32) & 0xffffffff;
44 case VE::fixup_ve_reflong
:
45 case VE::fixup_ve_srel32
:
46 case VE::fixup_ve_lo32
:
47 case VE::fixup_ve_pc_lo32
:
48 case VE::fixup_ve_got_lo32
:
49 case VE::fixup_ve_gotoff_lo32
:
50 case VE::fixup_ve_plt_lo32
:
51 case VE::fixup_ve_tls_gd_lo32
:
52 case VE::fixup_ve_tpoff_lo32
:
53 return Value
& 0xffffffff;
57 /// getFixupKindNumBytes - The number of bytes the fixup may change.
58 static unsigned getFixupKindNumBytes(unsigned Kind
) {
61 llvm_unreachable("Unknown fixup kind!");
71 case VE::fixup_ve_reflong
:
72 case VE::fixup_ve_srel32
:
73 case VE::fixup_ve_hi32
:
74 case VE::fixup_ve_lo32
:
75 case VE::fixup_ve_pc_hi32
:
76 case VE::fixup_ve_pc_lo32
:
77 case VE::fixup_ve_got_hi32
:
78 case VE::fixup_ve_got_lo32
:
79 case VE::fixup_ve_gotoff_hi32
:
80 case VE::fixup_ve_gotoff_lo32
:
81 case VE::fixup_ve_plt_hi32
:
82 case VE::fixup_ve_plt_lo32
:
83 case VE::fixup_ve_tls_gd_hi32
:
84 case VE::fixup_ve_tls_gd_lo32
:
85 case VE::fixup_ve_tpoff_hi32
:
86 case VE::fixup_ve_tpoff_lo32
:
95 class VEAsmBackend
: public MCAsmBackend
{
97 const Target
&TheTarget
;
100 VEAsmBackend(const Target
&T
)
101 : MCAsmBackend(llvm::endianness::little
), TheTarget(T
) {}
103 unsigned getNumFixupKinds() const override
{ return VE::NumTargetFixupKinds
; }
105 const MCFixupKindInfo
&getFixupKindInfo(MCFixupKind Kind
) const override
{
106 const static MCFixupKindInfo Infos
[VE::NumTargetFixupKinds
] = {
107 // name, offset, bits, flags
108 {"fixup_ve_reflong", 0, 32, 0},
109 {"fixup_ve_srel32", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
110 {"fixup_ve_hi32", 0, 32, 0},
111 {"fixup_ve_lo32", 0, 32, 0},
112 {"fixup_ve_pc_hi32", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
113 {"fixup_ve_pc_lo32", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
114 {"fixup_ve_got_hi32", 0, 32, 0},
115 {"fixup_ve_got_lo32", 0, 32, 0},
116 {"fixup_ve_gotoff_hi32", 0, 32, 0},
117 {"fixup_ve_gotoff_lo32", 0, 32, 0},
118 {"fixup_ve_plt_hi32", 0, 32, 0},
119 {"fixup_ve_plt_lo32", 0, 32, 0},
120 {"fixup_ve_tls_gd_hi32", 0, 32, 0},
121 {"fixup_ve_tls_gd_lo32", 0, 32, 0},
122 {"fixup_ve_tpoff_hi32", 0, 32, 0},
123 {"fixup_ve_tpoff_lo32", 0, 32, 0},
126 if (Kind
< FirstTargetFixupKind
)
127 return MCAsmBackend::getFixupKindInfo(Kind
);
129 assert(unsigned(Kind
- FirstTargetFixupKind
) < getNumFixupKinds() &&
131 return Infos
[Kind
- FirstTargetFixupKind
];
134 bool shouldForceRelocation(const MCAssembler
&Asm
, const MCFixup
&Fixup
,
135 const MCValue
&Target
,
136 const MCSubtargetInfo
*STI
) override
{
137 switch ((VE::Fixups
)Fixup
.getKind()) {
140 case VE::fixup_ve_tls_gd_hi32
:
141 case VE::fixup_ve_tls_gd_lo32
:
142 case VE::fixup_ve_tpoff_hi32
:
143 case VE::fixup_ve_tpoff_lo32
:
148 bool mayNeedRelaxation(const MCInst
&Inst
,
149 const MCSubtargetInfo
&STI
) const override
{
150 // Not implemented yet. For example, if we have a branch with
151 // lager than SIMM32 immediate value, we want to relaxation such
152 // branch instructions.
156 void relaxInstruction(MCInst
&Inst
,
157 const MCSubtargetInfo
&STI
) const override
{
158 // Aurora VE doesn't support relaxInstruction yet.
159 llvm_unreachable("relaxInstruction() should not be called");
162 bool writeNopData(raw_ostream
&OS
, uint64_t Count
,
163 const MCSubtargetInfo
*STI
) const override
{
164 if ((Count
% 8) != 0)
167 for (uint64_t i
= 0; i
< Count
; i
+= 8)
168 support::endian::write
<uint64_t>(OS
, 0x7900000000000000ULL
,
169 llvm::endianness::little
);
175 class ELFVEAsmBackend
: public VEAsmBackend
{
176 Triple::OSType OSType
;
179 ELFVEAsmBackend(const Target
&T
, Triple::OSType OSType
)
180 : VEAsmBackend(T
), OSType(OSType
) {}
182 void applyFixup(const MCAssembler
&Asm
, const MCFixup
&Fixup
,
183 const MCValue
&Target
, MutableArrayRef
<char> Data
,
184 uint64_t Value
, bool IsResolved
,
185 const MCSubtargetInfo
*STI
) const override
{
186 Value
= adjustFixupValue(Fixup
.getKind(), Value
);
188 return; // Doesn't change encoding.
190 MCFixupKindInfo Info
= getFixupKindInfo(Fixup
.getKind());
192 // Shift the value into position.
193 Value
<<= Info
.TargetOffset
;
195 unsigned NumBytes
= getFixupKindNumBytes(Fixup
.getKind());
196 unsigned Offset
= Fixup
.getOffset();
197 assert(Offset
+ NumBytes
<= Data
.size() && "Invalid fixup offset!");
198 // For each byte of the fragment that the fixup touches, mask in the bits
199 // from the fixup value. The Value has been "split up" into the
200 // appropriate bitfields above.
201 for (unsigned i
= 0; i
!= NumBytes
; ++i
) {
203 Endian
== llvm::endianness::little
? i
: (NumBytes
- 1) - i
;
204 Data
[Offset
+ Idx
] |= static_cast<uint8_t>((Value
>> (i
* 8)) & 0xff);
208 std::unique_ptr
<MCObjectTargetWriter
>
209 createObjectTargetWriter() const override
{
210 uint8_t OSABI
= MCELFObjectTargetWriter::getOSABI(OSType
);
211 return createVEELFObjectWriter(OSABI
);
214 } // end anonymous namespace
216 MCAsmBackend
*llvm::createVEAsmBackend(const Target
&T
,
217 const MCSubtargetInfo
&STI
,
218 const MCRegisterInfo
&MRI
,
219 const MCTargetOptions
&Options
) {
220 return new ELFVEAsmBackend(T
, STI
.getTargetTriple().getOS());