LLVM: lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
20
21using namespace llvm;
22
23namespace llvm {
25}
26namespace {
27class XtensaAsmBackend : public MCAsmBackend {
28 uint8_t OSABI;
29 bool IsLittleEndian;
30
31public:
32 XtensaAsmBackend(uint8_t osABI, bool isLE)
34 IsLittleEndian(isLE) {}
35
36 MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
37 std::optional evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
38 uint64_t &) override;
39 void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
40 uint8_t *Data, uint64_t Value, bool IsResolved) override;
41 bool writeNopData(raw_ostream &OS, uint64_t Count,
42 const MCSubtargetInfo *STI) const override;
43
44 std::unique_ptr createObjectTargetWriter() const override {
46 }
47};
48}
49
52
53 {"fixup_xtensa_branch_6", 0, 16, 0},
54 {"fixup_xtensa_branch_8", 16, 8, 0},
55 {"fixup_xtensa_branch_12", 12, 12, 0},
56 {"fixup_xtensa_jump_18", 6, 18, 0},
57 {"fixup_xtensa_call_18", 6, 18, 0},
58 {"fixup_xtensa_l32r_16", 8, 16, 0},
59 {"fixup_xtensa_loop_8", 16, 8, 0},
60 };
61
65 "Invalid kind!");
67}
68
71 unsigned Kind = Fixup.getKind();
72 switch (Kind) {
73 default:
82 return 0;
85 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
86 unsigned Hi2 = (Value >> 4) & 0x3;
87 unsigned Lo4 = Value & 0xf;
88 return (Hi2 << 4) | (Lo4 << 12);
89 }
93 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
94 return (Value & 0xff);
98 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
99 return (Value & 0xfff);
103 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
104 return (Value & 0x3ffff);
108 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
110 Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
111 return (Value & 0xffffc) >> 2;
115 Ctx.reportError(Fixup.getLoc(), "loop fixup value out of range");
116 return (Value & 0xff);
122 Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
124 Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
125 return (Value & 0x3fffc) >> 2;
126 }
127}
128
129static unsigned getSize(unsigned Kind) {
130 switch (Kind) {
131 default:
132 return 3;
134 return 4;
136 return 2;
137 }
138}
139
140std::optional XtensaAsmBackend::evaluateFixup(const MCFragment &F,
141 MCFixup &Fixup, MCValue &,
142 uint64_t &Value) {
143
144
145
146 switch (Fixup.getKind()) {
149 Value = (Asm->getFragmentOffset(F) + Fixup.getOffset()) % 4;
150 }
151 return {};
152}
153
154void XtensaAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
155 const MCValue &Target, uint8_t *Data,
156 uint64_t Value, bool IsResolved) {
157 maybeAddReloc(F, Fixup, Target, Value, IsResolved);
159 MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
160
162
163
165
167 return;
168
169 unsigned FullSize = getSize(Fixup.getKind());
170
171 for (unsigned i = 0; i != FullSize; ++i) {
172 Data[i] |= uint8_t((Value >> (i * 8)) & 0xff);
173 }
174}
175
176bool XtensaAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
177 const MCSubtargetInfo *STI) const {
178 uint64_t NumNops24b = Count / 3;
179
180 for (uint64_t i = 0; i != NumNops24b; ++i) {
181
182
183 if (IsLittleEndian) {
184 OS.write("\xf0", 1);
185 OS.write("\x20", 1);
186 OS.write("\0x00", 1);
187 } else {
189 }
191 }
192
193
195 default:
196 break;
197 case 1:
198 OS.write("\0", 1);
199 break;
200 case 2:
201
202 OS.write("\x3d", 1);
203 OS.write("\xf0", 1);
204 break;
205 }
206
207 return true;
208}
209
216 return new XtensaAsmBackend(OSABI, true);
217}
unsigned const MachineRegisterInfo * MRI
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Analysis containing CSE Info
PowerPC TLS Dynamic Call Fixup
static unsigned getSize(unsigned Kind)
Definition XtensaAsmBackend.cpp:129
Generic interface to target specific assembler backends.
virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Context object for machine code objects.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Base class for classes that define behaviour that is specific to both the target and the object forma...
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
Target - Wrapper for Target specific information.
OSType getOS() const
Get the parsed operating system type of this triple.
LLVM Value Representation.
raw_ostream & write(unsigned char C)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)
Apply fixup expression for edge to block content.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
std::unique_ptr< MCObjectTargetWriter > createXtensaObjectWriter(uint8_t OSABI, bool IsLittleEndian)
@ FK_Data_8
A eight-byte fixup.
@ FK_Data_1
A one-byte fixup.
@ FK_Data_4
A four-byte fixup.
@ FK_Data_2
A two-byte fixup.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
MCAsmBackend * createXtensaAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Definition XtensaAsmBackend.cpp:210
Target independent information on a fixup kind.