1bdd1243dSDimitry Andric //===-- XtensaMCCodeEmitter.cpp - Convert Xtensa Code to Machine Code -----===//
2bdd1243dSDimitry Andric //
3bdd1243dSDimitry Andric // The LLVM Compiler Infrastructure
4bdd1243dSDimitry Andric //
5bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
7bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8bdd1243dSDimitry Andric //
9bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
10bdd1243dSDimitry Andric //
11bdd1243dSDimitry Andric // This file implements the XtensaMCCodeEmitter class.
12bdd1243dSDimitry Andric //
13bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
14bdd1243dSDimitry Andric
15bdd1243dSDimitry Andric #include "MCTargetDesc/XtensaFixupKinds.h"
16bdd1243dSDimitry Andric #include "MCTargetDesc/XtensaMCExpr.h"
17bdd1243dSDimitry Andric #include "MCTargetDesc/XtensaMCTargetDesc.h"
18bdd1243dSDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
19bdd1243dSDimitry Andric #include "llvm/MC/MCContext.h"
20bdd1243dSDimitry Andric #include "llvm/MC/MCExpr.h"
21bdd1243dSDimitry Andric #include "llvm/MC/MCInst.h"
22bdd1243dSDimitry Andric #include "llvm/MC/MCInstrInfo.h"
23bdd1243dSDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
24bdd1243dSDimitry Andric
25bdd1243dSDimitry Andric #define GET_INSTRMAP_INFO
26bdd1243dSDimitry Andric #include "XtensaGenInstrInfo.inc"
27bdd1243dSDimitry Andric #undef GET_INSTRMAP_INFO
28bdd1243dSDimitry Andric
29bdd1243dSDimitry Andric using namespace llvm;
30bdd1243dSDimitry Andric
31bdd1243dSDimitry Andric #define DEBUG_TYPE "mccodeemitter"
32bdd1243dSDimitry Andric
33bdd1243dSDimitry Andric namespace {
34bdd1243dSDimitry Andric class XtensaMCCodeEmitter : public MCCodeEmitter {
35bdd1243dSDimitry Andric const MCInstrInfo &MCII;
36bdd1243dSDimitry Andric MCContext &Ctx;
37bdd1243dSDimitry Andric bool IsLittleEndian;
38bdd1243dSDimitry Andric
39bdd1243dSDimitry Andric public:
XtensaMCCodeEmitter(const MCInstrInfo & mcii,MCContext & ctx,bool isLE)40bdd1243dSDimitry Andric XtensaMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool isLE)
41bdd1243dSDimitry Andric : MCII(mcii), Ctx(ctx), IsLittleEndian(isLE) {}
42bdd1243dSDimitry Andric
~XtensaMCCodeEmitter()43bdd1243dSDimitry Andric ~XtensaMCCodeEmitter() {}
44bdd1243dSDimitry Andric
45bdd1243dSDimitry Andric // OVerride MCCodeEmitter.
46*06c3fb27SDimitry Andric void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
47bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
48bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const override;
49bdd1243dSDimitry Andric
50bdd1243dSDimitry Andric private:
51bdd1243dSDimitry Andric // Automatically generated by TableGen.
52bdd1243dSDimitry Andric uint64_t getBinaryCodeForInstr(const MCInst &MI,
53bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
54bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
55bdd1243dSDimitry Andric
56bdd1243dSDimitry Andric // Called by the TableGen code to get the binary encoding of operand
57bdd1243dSDimitry Andric // MO in MI. Fixups is the list of fixups against MI.
58bdd1243dSDimitry Andric uint32_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
59bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
60bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
61bdd1243dSDimitry Andric
62bdd1243dSDimitry Andric uint32_t getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum,
63bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
64bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
65bdd1243dSDimitry Andric
66bdd1243dSDimitry Andric uint32_t getBranchTargetEncoding(const MCInst &MI, unsigned int OpNum,
67bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
68bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
69bdd1243dSDimitry Andric
70bdd1243dSDimitry Andric uint32_t getCallEncoding(const MCInst &MI, unsigned int OpNum,
71bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
72bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
73bdd1243dSDimitry Andric
74bdd1243dSDimitry Andric uint32_t getL32RTargetEncoding(const MCInst &MI, unsigned OpNum,
75bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
76bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
77bdd1243dSDimitry Andric
78bdd1243dSDimitry Andric uint32_t getMemRegEncoding(const MCInst &MI, unsigned OpNo,
79bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
80bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
81bdd1243dSDimitry Andric
82bdd1243dSDimitry Andric uint32_t getImm8OpValue(const MCInst &MI, unsigned OpNo,
83bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
84bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
85bdd1243dSDimitry Andric
86bdd1243dSDimitry Andric uint32_t getImm8_sh8OpValue(const MCInst &MI, unsigned OpNo,
87bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
88bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
89bdd1243dSDimitry Andric
90bdd1243dSDimitry Andric uint32_t getImm12OpValue(const MCInst &MI, unsigned OpNo,
91bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
92bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
93bdd1243dSDimitry Andric
94bdd1243dSDimitry Andric uint32_t getUimm4OpValue(const MCInst &MI, unsigned OpNo,
95bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
96bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
97bdd1243dSDimitry Andric
98bdd1243dSDimitry Andric uint32_t getUimm5OpValue(const MCInst &MI, unsigned OpNo,
99bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
100bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
101bdd1243dSDimitry Andric
102bdd1243dSDimitry Andric uint32_t getImm1_16OpValue(const MCInst &MI, unsigned OpNo,
103bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
104bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
105bdd1243dSDimitry Andric
106bdd1243dSDimitry Andric uint32_t getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,
107bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
108bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
109bdd1243dSDimitry Andric
110bdd1243dSDimitry Andric uint32_t getB4constOpValue(const MCInst &MI, unsigned OpNo,
111bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
112bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
113bdd1243dSDimitry Andric
114bdd1243dSDimitry Andric uint32_t getB4constuOpValue(const MCInst &MI, unsigned OpNo,
115bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
116bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const;
117bdd1243dSDimitry Andric };
118bdd1243dSDimitry Andric } // namespace
119bdd1243dSDimitry Andric
createXtensaMCCodeEmitter(const MCInstrInfo & MCII,MCContext & Ctx)120bdd1243dSDimitry Andric MCCodeEmitter *llvm::createXtensaMCCodeEmitter(const MCInstrInfo &MCII,
121bdd1243dSDimitry Andric MCContext &Ctx) {
122bdd1243dSDimitry Andric return new XtensaMCCodeEmitter(MCII, Ctx, true);
123bdd1243dSDimitry Andric }
124bdd1243dSDimitry Andric
encodeInstruction(const MCInst & MI,SmallVectorImpl<char> & CB,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const125*06c3fb27SDimitry Andric void XtensaMCCodeEmitter::encodeInstruction(const MCInst &MI,
126*06c3fb27SDimitry Andric SmallVectorImpl<char> &CB,
127bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
128bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
129bdd1243dSDimitry Andric uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
130bdd1243dSDimitry Andric unsigned Size = MCII.get(MI.getOpcode()).getSize();
131bdd1243dSDimitry Andric
132bdd1243dSDimitry Andric if (IsLittleEndian) {
133bdd1243dSDimitry Andric // Little-endian insertion of Size bytes.
134bdd1243dSDimitry Andric unsigned ShiftValue = 0;
135bdd1243dSDimitry Andric for (unsigned I = 0; I != Size; ++I) {
136*06c3fb27SDimitry Andric CB.push_back(char(Bits >> ShiftValue));
137bdd1243dSDimitry Andric ShiftValue += 8;
138bdd1243dSDimitry Andric }
139bdd1243dSDimitry Andric } else {
140bdd1243dSDimitry Andric // TODO Big-endian insertion of Size bytes.
141bdd1243dSDimitry Andric report_fatal_error("Big-endian mode currently is not supported!");
142bdd1243dSDimitry Andric }
143bdd1243dSDimitry Andric }
144bdd1243dSDimitry Andric
145bdd1243dSDimitry Andric uint32_t
getMachineOpValue(const MCInst & MI,const MCOperand & MO,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const146bdd1243dSDimitry Andric XtensaMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
147bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
148bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
149bdd1243dSDimitry Andric if (MO.isReg())
150bdd1243dSDimitry Andric return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
151bdd1243dSDimitry Andric if (MO.isImm()) {
152bdd1243dSDimitry Andric uint32_t Res = static_cast<uint32_t>(MO.getImm());
153bdd1243dSDimitry Andric return Res;
154bdd1243dSDimitry Andric }
155bdd1243dSDimitry Andric
156bdd1243dSDimitry Andric report_fatal_error("Unhandled expression!");
157bdd1243dSDimitry Andric return 0;
158bdd1243dSDimitry Andric }
159bdd1243dSDimitry Andric
160bdd1243dSDimitry Andric uint32_t
getJumpTargetEncoding(const MCInst & MI,unsigned int OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const161bdd1243dSDimitry Andric XtensaMCCodeEmitter::getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum,
162bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
163bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
164bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNum);
165bdd1243dSDimitry Andric
166bdd1243dSDimitry Andric if (MO.isImm())
167bdd1243dSDimitry Andric return MO.getImm();
168bdd1243dSDimitry Andric
169bdd1243dSDimitry Andric const MCExpr *Expr = MO.getExpr();
170bdd1243dSDimitry Andric Fixups.push_back(MCFixup::create(
171bdd1243dSDimitry Andric 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_jump_18), MI.getLoc()));
172bdd1243dSDimitry Andric return 0;
173bdd1243dSDimitry Andric }
174bdd1243dSDimitry Andric
getBranchTargetEncoding(const MCInst & MI,unsigned int OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const175bdd1243dSDimitry Andric uint32_t XtensaMCCodeEmitter::getBranchTargetEncoding(
176bdd1243dSDimitry Andric const MCInst &MI, unsigned int OpNum, SmallVectorImpl<MCFixup> &Fixups,
177bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
178bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNum);
179bdd1243dSDimitry Andric if (MO.isImm())
180bdd1243dSDimitry Andric return static_cast<uint32_t>(MO.getImm());
181bdd1243dSDimitry Andric
182bdd1243dSDimitry Andric const MCExpr *Expr = MO.getExpr();
183bdd1243dSDimitry Andric switch (MI.getOpcode()) {
184bdd1243dSDimitry Andric case Xtensa::BEQZ:
185bdd1243dSDimitry Andric case Xtensa::BGEZ:
186bdd1243dSDimitry Andric case Xtensa::BLTZ:
187bdd1243dSDimitry Andric case Xtensa::BNEZ:
188bdd1243dSDimitry Andric Fixups.push_back(MCFixup::create(
189bdd1243dSDimitry Andric 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_12), MI.getLoc()));
190bdd1243dSDimitry Andric return 0;
191bdd1243dSDimitry Andric default:
192bdd1243dSDimitry Andric Fixups.push_back(MCFixup::create(
193bdd1243dSDimitry Andric 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_8), MI.getLoc()));
194bdd1243dSDimitry Andric return 0;
195bdd1243dSDimitry Andric }
196bdd1243dSDimitry Andric }
197bdd1243dSDimitry Andric
198bdd1243dSDimitry Andric uint32_t
getCallEncoding(const MCInst & MI,unsigned int OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const199bdd1243dSDimitry Andric XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum,
200bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
201bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
202bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNum);
203bdd1243dSDimitry Andric if (MO.isImm()) {
204bdd1243dSDimitry Andric int32_t Res = MO.getImm();
205bdd1243dSDimitry Andric if (Res & 0x3) {
206bdd1243dSDimitry Andric llvm_unreachable("Unexpected operand value!");
207bdd1243dSDimitry Andric }
208bdd1243dSDimitry Andric Res >>= 2;
209bdd1243dSDimitry Andric return Res;
210bdd1243dSDimitry Andric }
211bdd1243dSDimitry Andric
212bdd1243dSDimitry Andric assert((MO.isExpr()) && "Unexpected operand value!");
213bdd1243dSDimitry Andric const MCExpr *Expr = MO.getExpr();
214bdd1243dSDimitry Andric Fixups.push_back(MCFixup::create(
215bdd1243dSDimitry Andric 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_call_18), MI.getLoc()));
216bdd1243dSDimitry Andric return 0;
217bdd1243dSDimitry Andric }
218bdd1243dSDimitry Andric
219bdd1243dSDimitry Andric uint32_t
getL32RTargetEncoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const220bdd1243dSDimitry Andric XtensaMCCodeEmitter::getL32RTargetEncoding(const MCInst &MI, unsigned OpNum,
221bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
222bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
223bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNum);
224bdd1243dSDimitry Andric if (MO.isImm()) {
225bdd1243dSDimitry Andric int32_t Res = MO.getImm();
226bdd1243dSDimitry Andric // We don't check first 2 bits, because in these bits we could store first 2
227bdd1243dSDimitry Andric // bits of instruction address
228bdd1243dSDimitry Andric Res >>= 2;
229bdd1243dSDimitry Andric return Res;
230bdd1243dSDimitry Andric }
231bdd1243dSDimitry Andric
232bdd1243dSDimitry Andric assert((MO.isExpr()) && "Unexpected operand value!");
233bdd1243dSDimitry Andric
234bdd1243dSDimitry Andric Fixups.push_back(MCFixup::create(
235bdd1243dSDimitry Andric 0, MO.getExpr(), MCFixupKind(Xtensa::fixup_xtensa_l32r_16), MI.getLoc()));
236bdd1243dSDimitry Andric return 0;
237bdd1243dSDimitry Andric }
238bdd1243dSDimitry Andric
239bdd1243dSDimitry Andric uint32_t
getMemRegEncoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const240bdd1243dSDimitry Andric XtensaMCCodeEmitter::getMemRegEncoding(const MCInst &MI, unsigned OpNo,
241bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
242bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
243bdd1243dSDimitry Andric assert(MI.getOperand(OpNo + 1).isImm());
244bdd1243dSDimitry Andric
245bdd1243dSDimitry Andric uint32_t Res = static_cast<uint32_t>(MI.getOperand(OpNo + 1).getImm());
246bdd1243dSDimitry Andric
247bdd1243dSDimitry Andric switch (MI.getOpcode()) {
248bdd1243dSDimitry Andric case Xtensa::S16I:
249bdd1243dSDimitry Andric case Xtensa::L16SI:
250bdd1243dSDimitry Andric case Xtensa::L16UI:
251bdd1243dSDimitry Andric if (Res & 0x1) {
252bdd1243dSDimitry Andric report_fatal_error("Unexpected operand value!");
253bdd1243dSDimitry Andric }
254bdd1243dSDimitry Andric Res >>= 1;
255bdd1243dSDimitry Andric break;
256bdd1243dSDimitry Andric case Xtensa::S32I:
257bdd1243dSDimitry Andric case Xtensa::L32I:
258bdd1243dSDimitry Andric if (Res & 0x3) {
259bdd1243dSDimitry Andric report_fatal_error("Unexpected operand value!");
260bdd1243dSDimitry Andric }
261bdd1243dSDimitry Andric Res >>= 2;
262bdd1243dSDimitry Andric break;
263bdd1243dSDimitry Andric }
264bdd1243dSDimitry Andric
265bdd1243dSDimitry Andric assert((isUInt<8>(Res)) && "Unexpected operand value!");
266bdd1243dSDimitry Andric
267bdd1243dSDimitry Andric uint32_t OffBits = Res << 4;
268bdd1243dSDimitry Andric uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
269bdd1243dSDimitry Andric
270bdd1243dSDimitry Andric return ((OffBits & 0xFF0) | RegBits);
271bdd1243dSDimitry Andric }
272bdd1243dSDimitry Andric
getImm8OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const273bdd1243dSDimitry Andric uint32_t XtensaMCCodeEmitter::getImm8OpValue(const MCInst &MI, unsigned OpNo,
274bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
275bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
276bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNo);
277bdd1243dSDimitry Andric int32_t Res = MO.getImm();
278bdd1243dSDimitry Andric
279bdd1243dSDimitry Andric assert(((Res >= -128) && (Res <= 127)) && "Unexpected operand value!");
280bdd1243dSDimitry Andric
281bdd1243dSDimitry Andric return (Res & 0xff);
282bdd1243dSDimitry Andric }
283bdd1243dSDimitry Andric
284bdd1243dSDimitry Andric uint32_t
getImm8_sh8OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const285bdd1243dSDimitry Andric XtensaMCCodeEmitter::getImm8_sh8OpValue(const MCInst &MI, unsigned OpNo,
286bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
287bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
288bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNo);
289bdd1243dSDimitry Andric int32_t Res = MO.getImm();
290bdd1243dSDimitry Andric
291bdd1243dSDimitry Andric assert(((Res >= -32768) && (Res <= 32512) && ((Res & 0xff) == 0)) &&
292bdd1243dSDimitry Andric "Unexpected operand value!");
293bdd1243dSDimitry Andric
294bdd1243dSDimitry Andric return (Res & 0xffff);
295bdd1243dSDimitry Andric }
296bdd1243dSDimitry Andric
297bdd1243dSDimitry Andric uint32_t
getImm12OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const298bdd1243dSDimitry Andric XtensaMCCodeEmitter::getImm12OpValue(const MCInst &MI, unsigned OpNo,
299bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
300bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
301bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNo);
302bdd1243dSDimitry Andric int32_t Res = MO.getImm();
303bdd1243dSDimitry Andric
304bdd1243dSDimitry Andric assert(((Res >= -2048) && (Res <= 2047)) && "Unexpected operand value!");
305bdd1243dSDimitry Andric
306bdd1243dSDimitry Andric return (Res & 0xfff);
307bdd1243dSDimitry Andric }
308bdd1243dSDimitry Andric
309bdd1243dSDimitry Andric uint32_t
getUimm4OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const310bdd1243dSDimitry Andric XtensaMCCodeEmitter::getUimm4OpValue(const MCInst &MI, unsigned OpNo,
311bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
312bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
313bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNo);
314bdd1243dSDimitry Andric uint32_t Res = static_cast<uint32_t>(MO.getImm());
315bdd1243dSDimitry Andric
316bdd1243dSDimitry Andric assert((Res <= 15) && "Unexpected operand value!");
317bdd1243dSDimitry Andric
318bdd1243dSDimitry Andric return Res & 0xf;
319bdd1243dSDimitry Andric }
320bdd1243dSDimitry Andric
321bdd1243dSDimitry Andric uint32_t
getUimm5OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const322bdd1243dSDimitry Andric XtensaMCCodeEmitter::getUimm5OpValue(const MCInst &MI, unsigned OpNo,
323bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
324bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
325bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNo);
326bdd1243dSDimitry Andric uint32_t Res = static_cast<uint32_t>(MO.getImm());
327bdd1243dSDimitry Andric
328bdd1243dSDimitry Andric assert((Res <= 31) && "Unexpected operand value!");
329bdd1243dSDimitry Andric
330bdd1243dSDimitry Andric return (Res & 0x1f);
331bdd1243dSDimitry Andric }
332bdd1243dSDimitry Andric
333bdd1243dSDimitry Andric uint32_t
getShimm1_31OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const334bdd1243dSDimitry Andric XtensaMCCodeEmitter::getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,
335bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
336bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
337bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNo);
338bdd1243dSDimitry Andric uint32_t Res = static_cast<uint32_t>(MO.getImm());
339bdd1243dSDimitry Andric
340bdd1243dSDimitry Andric assert(((Res >= 1) && (Res <= 31)) && "Unexpected operand value!");
341bdd1243dSDimitry Andric
342bdd1243dSDimitry Andric return ((32 - Res) & 0x1f);
343bdd1243dSDimitry Andric }
344bdd1243dSDimitry Andric
345bdd1243dSDimitry Andric uint32_t
getImm1_16OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const346bdd1243dSDimitry Andric XtensaMCCodeEmitter::getImm1_16OpValue(const MCInst &MI, unsigned OpNo,
347bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
348bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
349bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNo);
350bdd1243dSDimitry Andric uint32_t Res = static_cast<uint32_t>(MO.getImm());
351bdd1243dSDimitry Andric
352bdd1243dSDimitry Andric assert(((Res >= 1) && (Res <= 16)) && "Unexpected operand value!");
353bdd1243dSDimitry Andric
354bdd1243dSDimitry Andric return (Res - 1);
355bdd1243dSDimitry Andric }
356bdd1243dSDimitry Andric
357bdd1243dSDimitry Andric uint32_t
getB4constOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const358bdd1243dSDimitry Andric XtensaMCCodeEmitter::getB4constOpValue(const MCInst &MI, unsigned OpNo,
359bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
360bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
361bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNo);
362bdd1243dSDimitry Andric uint32_t Res = static_cast<uint32_t>(MO.getImm());
363bdd1243dSDimitry Andric
364bdd1243dSDimitry Andric switch (Res) {
365bdd1243dSDimitry Andric case 0xffffffff:
366bdd1243dSDimitry Andric Res = 0;
367bdd1243dSDimitry Andric break;
368bdd1243dSDimitry Andric case 1:
369bdd1243dSDimitry Andric case 2:
370bdd1243dSDimitry Andric case 3:
371bdd1243dSDimitry Andric case 4:
372bdd1243dSDimitry Andric case 5:
373bdd1243dSDimitry Andric case 6:
374bdd1243dSDimitry Andric case 7:
375bdd1243dSDimitry Andric case 8:
376bdd1243dSDimitry Andric break;
377bdd1243dSDimitry Andric case 10:
378bdd1243dSDimitry Andric Res = 9;
379bdd1243dSDimitry Andric break;
380bdd1243dSDimitry Andric case 12:
381bdd1243dSDimitry Andric Res = 10;
382bdd1243dSDimitry Andric break;
383bdd1243dSDimitry Andric case 16:
384bdd1243dSDimitry Andric Res = 11;
385bdd1243dSDimitry Andric break;
386bdd1243dSDimitry Andric case 32:
387bdd1243dSDimitry Andric Res = 12;
388bdd1243dSDimitry Andric break;
389bdd1243dSDimitry Andric case 64:
390bdd1243dSDimitry Andric Res = 13;
391bdd1243dSDimitry Andric break;
392bdd1243dSDimitry Andric case 128:
393bdd1243dSDimitry Andric Res = 14;
394bdd1243dSDimitry Andric break;
395bdd1243dSDimitry Andric case 256:
396bdd1243dSDimitry Andric Res = 15;
397bdd1243dSDimitry Andric break;
398bdd1243dSDimitry Andric default:
399bdd1243dSDimitry Andric llvm_unreachable("Unexpected operand value!");
400bdd1243dSDimitry Andric }
401bdd1243dSDimitry Andric
402bdd1243dSDimitry Andric return Res;
403bdd1243dSDimitry Andric }
404bdd1243dSDimitry Andric
405bdd1243dSDimitry Andric uint32_t
getB4constuOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const406bdd1243dSDimitry Andric XtensaMCCodeEmitter::getB4constuOpValue(const MCInst &MI, unsigned OpNo,
407bdd1243dSDimitry Andric SmallVectorImpl<MCFixup> &Fixups,
408bdd1243dSDimitry Andric const MCSubtargetInfo &STI) const {
409bdd1243dSDimitry Andric const MCOperand &MO = MI.getOperand(OpNo);
410bdd1243dSDimitry Andric uint32_t Res = static_cast<uint32_t>(MO.getImm());
411bdd1243dSDimitry Andric
412bdd1243dSDimitry Andric switch (Res) {
413bdd1243dSDimitry Andric case 32768:
414bdd1243dSDimitry Andric Res = 0;
415bdd1243dSDimitry Andric break;
416bdd1243dSDimitry Andric case 65536:
417bdd1243dSDimitry Andric Res = 1;
418bdd1243dSDimitry Andric break;
419bdd1243dSDimitry Andric case 2:
420bdd1243dSDimitry Andric case 3:
421bdd1243dSDimitry Andric case 4:
422bdd1243dSDimitry Andric case 5:
423bdd1243dSDimitry Andric case 6:
424bdd1243dSDimitry Andric case 7:
425bdd1243dSDimitry Andric case 8:
426bdd1243dSDimitry Andric break;
427bdd1243dSDimitry Andric case 10:
428bdd1243dSDimitry Andric Res = 9;
429bdd1243dSDimitry Andric break;
430bdd1243dSDimitry Andric case 12:
431bdd1243dSDimitry Andric Res = 10;
432bdd1243dSDimitry Andric break;
433bdd1243dSDimitry Andric case 16:
434bdd1243dSDimitry Andric Res = 11;
435bdd1243dSDimitry Andric break;
436bdd1243dSDimitry Andric case 32:
437bdd1243dSDimitry Andric Res = 12;
438bdd1243dSDimitry Andric break;
439bdd1243dSDimitry Andric case 64:
440bdd1243dSDimitry Andric Res = 13;
441bdd1243dSDimitry Andric break;
442bdd1243dSDimitry Andric case 128:
443bdd1243dSDimitry Andric Res = 14;
444bdd1243dSDimitry Andric break;
445bdd1243dSDimitry Andric case 256:
446bdd1243dSDimitry Andric Res = 15;
447bdd1243dSDimitry Andric break;
448bdd1243dSDimitry Andric default:
449bdd1243dSDimitry Andric llvm_unreachable("Unexpected operand value!");
450bdd1243dSDimitry Andric }
451bdd1243dSDimitry Andric
452bdd1243dSDimitry Andric return Res;
453bdd1243dSDimitry Andric }
454bdd1243dSDimitry Andric #include "XtensaGenMCCodeEmitter.inc"
455