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) 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, support::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, support::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. 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. 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. 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. 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 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 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 276 static inline bool hasMultiMIOperands(unsigned Op, unsigned LogicalOpIdx) { 277 return M68k::getLogicalOperandSize(Op, LogicalOpIdx) > 1; 278 } 279 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