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 // On a LE host: 52 // MSB LSB MSB LSB 53 // | 0x12 0x34 | 0xAB 0xCD | -> | 0xAB 0xCD | 0x12 0x34 | 54 // (On a BE host nothing changes) 55 template <typename value_t> value_t swapWord(value_t Val) { 56 const unsigned NumWords = sizeof(Val) / 2; 57 if (NumWords <= 1) 58 return Val; 59 Val = support::endian::byte_swap(Val, support::big); 60 value_t NewVal = 0; 61 for (unsigned i = 0U; i != NumWords; ++i) { 62 uint16_t Part = (Val >> (i * 16)) & 0xFFFF; 63 Part = support::endian::byte_swap(Part, support::big); 64 NewVal |= (Part << (i * 16)); 65 } 66 return NewVal; 67 } 68 } // namespace M68k 69 70 namespace M68kBeads { 71 enum { 72 Ctrl = 0x0, 73 Bits1 = 0x1, 74 Bits2 = 0x2, 75 Bits3 = 0x3, 76 Bits4 = 0x4, 77 DAReg = 0x5, 78 DA = 0x6, 79 Reg = 0x7, 80 DReg = 0x8, 81 Disp8 = 0x9, 82 Imm8 = 0xA, 83 Imm16 = 0xB, 84 Imm32 = 0xC, 85 Imm3 = 0xD, 86 }; 87 88 // Ctrl payload 89 enum { 90 Term = 0x0, 91 Ignore = 0x1, 92 }; 93 } // namespace M68kBeads 94 95 /// This namespace holds all of the target specific flags that instruction info 96 /// tracks. 97 namespace M68kII { 98 /// Target Operand Flag enum. 99 enum TOF { 100 101 MO_NO_FLAG, 102 103 /// On a symbol operand this indicates that the immediate is the absolute 104 /// address of the symbol. 105 MO_ABSOLUTE_ADDRESS, 106 107 /// On a symbol operand this indicates that the immediate is the pc-relative 108 /// address of the symbol. 109 MO_PC_RELATIVE_ADDRESS, 110 111 /// On a symbol operand this indicates that the immediate is the offset to 112 /// the GOT entry for the symbol name from the base of the GOT. 113 /// 114 /// name@GOT 115 MO_GOT, 116 117 /// On a symbol operand this indicates that the immediate is the offset to 118 /// the location of the symbol name from the base of the GOT. 119 /// 120 /// name@GOTOFF 121 MO_GOTOFF, 122 123 /// On a symbol operand this indicates that the immediate is offset to the 124 /// GOT entry for the symbol name from the current code location. 125 /// 126 /// name@GOTPCREL 127 MO_GOTPCREL, 128 129 /// On a symbol operand this indicates that the immediate is offset to the 130 /// PLT entry of symbol name from the current code location. 131 /// 132 /// name@PLT 133 MO_PLT, 134 }; // enum TOF 135 136 /// Return true if the specified TargetFlag operand is a reference to a stub 137 /// for a global, not the global itself. 138 inline static bool isGlobalStubReference(unsigned char TargetFlag) { 139 switch (TargetFlag) { 140 default: 141 return false; 142 case M68kII::MO_GOTPCREL: // pc-relative GOT reference. 143 case M68kII::MO_GOT: // normal GOT reference. 144 return true; 145 } 146 } 147 148 /// Return True if the specified GlobalValue is a direct reference for a 149 /// symbol. 150 inline static bool isDirectGlobalReference(unsigned char Flag) { 151 switch (Flag) { 152 default: 153 return false; 154 case M68kII::MO_NO_FLAG: 155 case M68kII::MO_ABSOLUTE_ADDRESS: 156 case M68kII::MO_PC_RELATIVE_ADDRESS: 157 return true; 158 } 159 } 160 161 /// Return true if the specified global value reference is relative to a 32-bit 162 /// PIC base (M68kISD::GLOBAL_BASE_REG). If this is true, the addressing mode 163 /// has the PIC base register added in. 164 inline static bool isGlobalRelativeToPICBase(unsigned char TargetFlag) { 165 switch (TargetFlag) { 166 default: 167 return false; 168 case M68kII::MO_GOTOFF: // isPICStyleGOT: local global. 169 case M68kII::MO_GOT: // isPICStyleGOT: other global. 170 return true; 171 } 172 } 173 174 /// Return True if the specified GlobalValue requires PC addressing mode. 175 inline static bool isPCRelGlobalReference(unsigned char Flag) { 176 switch (Flag) { 177 default: 178 return false; 179 case M68kII::MO_GOTPCREL: 180 case M68kII::MO_PC_RELATIVE_ADDRESS: 181 return true; 182 } 183 } 184 185 /// Return True if the Block is referenced using PC 186 inline static bool isPCRelBlockReference(unsigned char Flag) { 187 switch (Flag) { 188 default: 189 return false; 190 case M68kII::MO_PC_RELATIVE_ADDRESS: 191 return true; 192 } 193 } 194 195 static inline bool isAddressRegister(unsigned RegNo) { 196 switch (RegNo) { 197 case M68k::WA0: 198 case M68k::WA1: 199 case M68k::WA2: 200 case M68k::WA3: 201 case M68k::WA4: 202 case M68k::WA5: 203 case M68k::WA6: 204 case M68k::WSP: 205 case M68k::A0: 206 case M68k::A1: 207 case M68k::A2: 208 case M68k::A3: 209 case M68k::A4: 210 case M68k::A5: 211 case M68k::A6: 212 case M68k::SP: 213 return true; 214 default: 215 return false; 216 } 217 } 218 219 static inline bool hasMultiMIOperands(unsigned Op, unsigned LogicalOpIdx) { 220 return M68k::getLogicalOperandSize(Op, LogicalOpIdx) > 1; 221 } 222 223 static inline unsigned getMaskedSpillRegister(unsigned order) { 224 switch (order) { 225 default: 226 return 0; 227 case 0: 228 return M68k::D0; 229 case 1: 230 return M68k::D1; 231 case 2: 232 return M68k::D2; 233 case 3: 234 return M68k::D3; 235 case 4: 236 return M68k::D4; 237 case 5: 238 return M68k::D5; 239 case 6: 240 return M68k::D6; 241 case 7: 242 return M68k::D7; 243 case 8: 244 return M68k::A0; 245 case 9: 246 return M68k::A1; 247 case 10: 248 return M68k::A2; 249 case 11: 250 return M68k::A3; 251 case 12: 252 return M68k::A4; 253 case 13: 254 return M68k::A5; 255 case 14: 256 return M68k::A6; 257 case 15: 258 return M68k::SP; 259 } 260 } 261 262 } // namespace M68kII 263 264 } // namespace llvm 265 266 #endif // LLVM_LIB_TARGET_M68K_MCTARGETDESC_M68KBASEINFO_H 267