1 //===-- M68kBaseInfo.h - Top level definitions for M68k MC ------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file contains small standalone helper functions and enum definitions
11 /// for the M68k target useful for the compiler back-end and the MC
12 /// libraries. As such, it deliberately does not include references to LLVM
13 /// core code gen types, passes, etc..
14 ///
15 //===----------------------------------------------------------------------===//
16
17 #ifndef LLVM_LIB_TARGET_M68K_MCTARGETDESC_M68KBASEINFO_H
18 #define LLVM_LIB_TARGET_M68K_MCTARGETDESC_M68KBASEINFO_H
19
20 #include "M68kMCTargetDesc.h"
21
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/Support/DataTypes.h"
24 #include "llvm/Support/Endian.h"
25 #include "llvm/Support/ErrorHandling.h"
26
27 #define GET_INSTRINFO_MI_OPS_INFO
28 #define GET_INSTRINFO_OPERAND_TYPES_ENUM
29 #define GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP
30 #include "M68kGenInstrInfo.inc"
31
32 namespace llvm {
33
34 namespace M68k {
35
36 /// Enums for memory operand decoding. Supports these forms:
37 /// (d,An)
38 /// (d,An,Xn)
39 /// ([bd,An],Xn,od)
40 /// ([bd,An,Xn],od)
41 /// TODO Implement scaling other than 1
42 enum { MemDisp = 0, MemBase = 1, MemIndex = 2, MemOuter = 3 };
43
44 /// Enums for pc-relative memory operand decoding. Supports these forms:
45 /// (d,PC)
46 /// (d,PC,Xn)
47 /// ([bd,PC],Xn,od)
48 /// ([bd,PC,Xn],od)
49 enum { PCRelDisp = 0, PCRelIndex = 1, PCRelOuter = 2 };
50
51 enum class MemAddrModeKind : unsigned {
52 j = 1, // (An)
53 o, // (An)+
54 e, // -(An)
55 p, // (d,An)
56 f, // (d,An,Xn.L)
57 F, // (d,An,Xn.W)
58 g, // (d,An,Xn.L,SCALE)
59 G, // (d,An,Xn.W,SCALE)
60 u, // ([bd,An],Xn.L,SCALE,od)
61 U, // ([bd,An],Xn.W,SCALE,od)
62 v, // ([bd,An,Xn.L,SCALE],od)
63 V, // ([bd,An,Xn.W,SCALE],od)
64 b, // abs.L
65 B, // abs.W
66 q, // (d,PC)
67 k, // (d,PC,Xn.L)
68 K, // (d,PC,Xn.W)
69 l, // (d,PC,Xn.L,SCALE)
70 L, // (d,PC,Xn.W,SCALE)
71 x, // ([bd,PC],Xn.L,SCALE,od)
72 X, // ([bd,PC],Xn.W,SCALE,od)
73 y, // ([bd,PC,Xn.L,SCALE],od)
74 Y // ([bd,PC,Xn.W,SCALE],od)
75 };
76
77 // On a LE host:
78 // MSB LSB MSB LSB
79 // | 0x12 0x34 | 0xAB 0xCD | -> | 0xAB 0xCD | 0x12 0x34 |
80 // (On a BE host nothing changes)
swapWord(value_t Val)81 template <typename value_t> value_t swapWord(value_t Val) {
82 const unsigned NumWords = sizeof(Val) / 2;
83 if (NumWords <= 1)
84 return Val;
85 Val = support::endian::byte_swap(Val, llvm::endianness::big);
86 value_t NewVal = 0;
87 for (unsigned i = 0U; i != NumWords; ++i) {
88 uint16_t Part = (Val >> (i * 16)) & 0xFFFF;
89 Part = support::endian::byte_swap(Part, llvm::endianness::big);
90 NewVal |= (Part << (i * 16));
91 }
92 return NewVal;
93 }
94 } // namespace M68k
95
96 namespace M68kBeads {
97 enum {
98 Ctrl = 0x0,
99 Bits1 = 0x1,
100 Bits2 = 0x2,
101 Bits3 = 0x3,
102 Bits4 = 0x4,
103 DAReg = 0x5,
104 DA = 0x6,
105 Reg = 0x7,
106 DReg = 0x8,
107 Disp8 = 0x9,
108 Imm8 = 0xA,
109 Imm16 = 0xB,
110 Imm32 = 0xC,
111 Imm3 = 0xD,
112 };
113
114 // Ctrl payload
115 enum {
116 Term = 0x0,
117 Ignore = 0x1,
118 };
119 } // namespace M68kBeads
120
121 /// This namespace holds all of the target specific flags that instruction info
122 /// tracks.
123 namespace M68kII {
124 /// Target Operand Flag enum.
125 enum TOF {
126
127 MO_NO_FLAG,
128
129 /// On a symbol operand this indicates that the immediate is the absolute
130 /// address of the symbol.
131 MO_ABSOLUTE_ADDRESS,
132
133 /// On a symbol operand this indicates that the immediate is the pc-relative
134 /// address of the symbol.
135 MO_PC_RELATIVE_ADDRESS,
136
137 /// On a symbol operand this indicates that the immediate is the offset to
138 /// the GOT entry for the symbol name from the base of the GOT.
139 ///
140 /// name@GOT
141 MO_GOT,
142
143 /// On a symbol operand this indicates that the immediate is the offset to
144 /// the location of the symbol name from the base of the GOT.
145 ///
146 /// name@GOTOFF
147 MO_GOTOFF,
148
149 /// On a symbol operand this indicates that the immediate is offset to the
150 /// GOT entry for the symbol name from the current code location.
151 ///
152 /// name@GOTPCREL
153 MO_GOTPCREL,
154
155 /// On a symbol operand this indicates that the immediate is offset to the
156 /// PLT entry of symbol name from the current code location.
157 ///
158 /// name@PLT
159 MO_PLT,
160
161 /// On a symbol operand, this indicates that the immediate is the offset to
162 /// the slot in GOT which stores the information for accessing the TLS
163 /// variable. This is used when operating in Global Dynamic mode.
164 /// name@TLSGD
165 MO_TLSGD,
166
167 /// On a symbol operand, this indicates that the immediate is the offset to
168 /// variable within the thread local storage when operating in Local Dynamic
169 /// mode.
170 /// name@TLSLD
171 MO_TLSLD,
172
173 /// On a symbol operand, this indicates that the immediate is the offset to
174 /// the slot in GOT which stores the information for accessing the TLS
175 /// variable. This is used when operating in Local Dynamic mode.
176 /// name@TLSLDM
177 MO_TLSLDM,
178
179 /// On a symbol operand, this indicates that the immediate is the offset to
180 /// the variable within the thread local storage when operating in Initial
181 /// Exec mode.
182 /// name@TLSIE
183 MO_TLSIE,
184
185 /// On a symbol operand, this indicates that the immediate is the offset to
186 /// the variable within in the thread local storage when operating in Local
187 /// Exec mode.
188 /// name@TLSLE
189 MO_TLSLE,
190
191 }; // enum TOF
192
193 /// Return true if the specified TargetFlag operand is a reference to a stub
194 /// for a global, not the global itself.
isGlobalStubReference(unsigned char TargetFlag)195 inline static bool isGlobalStubReference(unsigned char TargetFlag) {
196 switch (TargetFlag) {
197 default:
198 return false;
199 case M68kII::MO_GOTPCREL: // pc-relative GOT reference.
200 case M68kII::MO_GOT: // normal GOT reference.
201 return true;
202 }
203 }
204
205 /// Return True if the specified GlobalValue is a direct reference for a
206 /// symbol.
isDirectGlobalReference(unsigned char Flag)207 inline static bool isDirectGlobalReference(unsigned char Flag) {
208 switch (Flag) {
209 default:
210 return false;
211 case M68kII::MO_NO_FLAG:
212 case M68kII::MO_ABSOLUTE_ADDRESS:
213 case M68kII::MO_PC_RELATIVE_ADDRESS:
214 return true;
215 }
216 }
217
218 /// Return true if the specified global value reference is relative to a 32-bit
219 /// PIC base (M68kISD::GLOBAL_BASE_REG). If this is true, the addressing mode
220 /// has the PIC base register added in.
isGlobalRelativeToPICBase(unsigned char TargetFlag)221 inline static bool isGlobalRelativeToPICBase(unsigned char TargetFlag) {
222 switch (TargetFlag) {
223 default:
224 return false;
225 case M68kII::MO_GOTOFF: // isPICStyleGOT: local global.
226 case M68kII::MO_GOT: // isPICStyleGOT: other global.
227 return true;
228 }
229 }
230
231 /// Return True if the specified GlobalValue requires PC addressing mode.
isPCRelGlobalReference(unsigned char Flag)232 inline static bool isPCRelGlobalReference(unsigned char Flag) {
233 switch (Flag) {
234 default:
235 return false;
236 case M68kII::MO_GOTPCREL:
237 case M68kII::MO_PC_RELATIVE_ADDRESS:
238 return true;
239 }
240 }
241
242 /// Return True if the Block is referenced using PC
isPCRelBlockReference(unsigned char Flag)243 inline static bool isPCRelBlockReference(unsigned char Flag) {
244 switch (Flag) {
245 default:
246 return false;
247 case M68kII::MO_PC_RELATIVE_ADDRESS:
248 return true;
249 }
250 }
251
isAddressRegister(unsigned RegNo)252 static inline bool isAddressRegister(unsigned RegNo) {
253 switch (RegNo) {
254 case M68k::WA0:
255 case M68k::WA1:
256 case M68k::WA2:
257 case M68k::WA3:
258 case M68k::WA4:
259 case M68k::WA5:
260 case M68k::WA6:
261 case M68k::WSP:
262 case M68k::A0:
263 case M68k::A1:
264 case M68k::A2:
265 case M68k::A3:
266 case M68k::A4:
267 case M68k::A5:
268 case M68k::A6:
269 case M68k::SP:
270 return true;
271 default:
272 return false;
273 }
274 }
275
hasMultiMIOperands(unsigned Op,unsigned LogicalOpIdx)276 static inline bool hasMultiMIOperands(unsigned Op, unsigned LogicalOpIdx) {
277 return M68k::getLogicalOperandSize(Op, LogicalOpIdx) > 1;
278 }
279
getMaskedSpillRegister(unsigned order)280 static inline unsigned getMaskedSpillRegister(unsigned order) {
281 switch (order) {
282 default:
283 return 0;
284 case 0:
285 return M68k::D0;
286 case 1:
287 return M68k::D1;
288 case 2:
289 return M68k::D2;
290 case 3:
291 return M68k::D3;
292 case 4:
293 return M68k::D4;
294 case 5:
295 return M68k::D5;
296 case 6:
297 return M68k::D6;
298 case 7:
299 return M68k::D7;
300 case 8:
301 return M68k::A0;
302 case 9:
303 return M68k::A1;
304 case 10:
305 return M68k::A2;
306 case 11:
307 return M68k::A3;
308 case 12:
309 return M68k::A4;
310 case 13:
311 return M68k::A5;
312 case 14:
313 return M68k::A6;
314 case 15:
315 return M68k::SP;
316 }
317 }
318
319 } // namespace M68kII
320
321 } // namespace llvm
322
323 #endif // LLVM_LIB_TARGET_M68K_MCTARGETDESC_M68KBASEINFO_H
324