1*a9ac8606Spatrick //===--- M68k.cpp - Implement M68k targets feature support-------------===// 2*a9ac8606Spatrick // 3*a9ac8606Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*a9ac8606Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*a9ac8606Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*a9ac8606Spatrick // 7*a9ac8606Spatrick //===----------------------------------------------------------------------===// 8*a9ac8606Spatrick // 9*a9ac8606Spatrick // This file implements M68k TargetInfo objects. 10*a9ac8606Spatrick // 11*a9ac8606Spatrick //===----------------------------------------------------------------------===// 12*a9ac8606Spatrick 13*a9ac8606Spatrick #include "M68k.h" 14*a9ac8606Spatrick #include "clang/Basic/Builtins.h" 15*a9ac8606Spatrick #include "clang/Basic/Diagnostic.h" 16*a9ac8606Spatrick #include "clang/Basic/TargetBuiltins.h" 17*a9ac8606Spatrick #include "llvm/ADT/StringExtras.h" 18*a9ac8606Spatrick #include "llvm/ADT/StringRef.h" 19*a9ac8606Spatrick #include "llvm/ADT/StringSwitch.h" 20*a9ac8606Spatrick #include "llvm/Support/TargetParser.h" 21*a9ac8606Spatrick #include <cstdint> 22*a9ac8606Spatrick #include <cstring> 23*a9ac8606Spatrick #include <limits> 24*a9ac8606Spatrick 25*a9ac8606Spatrick namespace clang { 26*a9ac8606Spatrick namespace targets { 27*a9ac8606Spatrick 28*a9ac8606Spatrick M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple, 29*a9ac8606Spatrick const TargetOptions &) 30*a9ac8606Spatrick : TargetInfo(Triple) { 31*a9ac8606Spatrick 32*a9ac8606Spatrick std::string Layout = ""; 33*a9ac8606Spatrick 34*a9ac8606Spatrick // M68k is Big Endian 35*a9ac8606Spatrick Layout += "E"; 36*a9ac8606Spatrick 37*a9ac8606Spatrick // FIXME how to wire it with the used object format? 38*a9ac8606Spatrick Layout += "-m:e"; 39*a9ac8606Spatrick 40*a9ac8606Spatrick // M68k pointers are always 32 bit wide even for 16-bit CPUs 41*a9ac8606Spatrick Layout += "-p:32:16:32"; 42*a9ac8606Spatrick 43*a9ac8606Spatrick // M68k integer data types 44*a9ac8606Spatrick Layout += "-i8:8:8-i16:16:16-i32:16:32"; 45*a9ac8606Spatrick 46*a9ac8606Spatrick // FIXME no floats at the moment 47*a9ac8606Spatrick 48*a9ac8606Spatrick // The registers can hold 8, 16, 32 bits 49*a9ac8606Spatrick Layout += "-n8:16:32"; 50*a9ac8606Spatrick 51*a9ac8606Spatrick // 16 bit alignment for both stack and aggregate 52*a9ac8606Spatrick // in order to conform to ABI used by GCC 53*a9ac8606Spatrick Layout += "-a:0:16-S16"; 54*a9ac8606Spatrick 55*a9ac8606Spatrick resetDataLayout(Layout); 56*a9ac8606Spatrick 57*a9ac8606Spatrick SizeType = UnsignedInt; 58*a9ac8606Spatrick PtrDiffType = SignedInt; 59*a9ac8606Spatrick IntPtrType = SignedInt; 60*a9ac8606Spatrick } 61*a9ac8606Spatrick 62*a9ac8606Spatrick bool M68kTargetInfo::setCPU(const std::string &Name) { 63*a9ac8606Spatrick StringRef N = Name; 64*a9ac8606Spatrick CPU = llvm::StringSwitch<CPUKind>(N) 65*a9ac8606Spatrick .Case("generic", CK_68000) 66*a9ac8606Spatrick .Case("M68000", CK_68000) 67*a9ac8606Spatrick .Case("M68010", CK_68010) 68*a9ac8606Spatrick .Case("M68020", CK_68020) 69*a9ac8606Spatrick .Case("M68030", CK_68030) 70*a9ac8606Spatrick .Case("M68040", CK_68040) 71*a9ac8606Spatrick .Case("M68060", CK_68060) 72*a9ac8606Spatrick .Default(CK_Unknown); 73*a9ac8606Spatrick return CPU != CK_Unknown; 74*a9ac8606Spatrick } 75*a9ac8606Spatrick 76*a9ac8606Spatrick void M68kTargetInfo::getTargetDefines(const LangOptions &Opts, 77*a9ac8606Spatrick MacroBuilder &Builder) const { 78*a9ac8606Spatrick using llvm::Twine; 79*a9ac8606Spatrick 80*a9ac8606Spatrick Builder.defineMacro("__m68k__"); 81*a9ac8606Spatrick 82*a9ac8606Spatrick Builder.defineMacro("mc68000"); 83*a9ac8606Spatrick Builder.defineMacro("__mc68000"); 84*a9ac8606Spatrick Builder.defineMacro("__mc68000__"); 85*a9ac8606Spatrick 86*a9ac8606Spatrick // For sub-architecture 87*a9ac8606Spatrick switch (CPU) { 88*a9ac8606Spatrick case CK_68010: 89*a9ac8606Spatrick Builder.defineMacro("mc68010"); 90*a9ac8606Spatrick Builder.defineMacro("__mc68010"); 91*a9ac8606Spatrick Builder.defineMacro("__mc68010__"); 92*a9ac8606Spatrick break; 93*a9ac8606Spatrick case CK_68020: 94*a9ac8606Spatrick Builder.defineMacro("mc68020"); 95*a9ac8606Spatrick Builder.defineMacro("__mc68020"); 96*a9ac8606Spatrick Builder.defineMacro("__mc68020__"); 97*a9ac8606Spatrick break; 98*a9ac8606Spatrick case CK_68030: 99*a9ac8606Spatrick Builder.defineMacro("mc68030"); 100*a9ac8606Spatrick Builder.defineMacro("__mc68030"); 101*a9ac8606Spatrick Builder.defineMacro("__mc68030__"); 102*a9ac8606Spatrick break; 103*a9ac8606Spatrick case CK_68040: 104*a9ac8606Spatrick Builder.defineMacro("mc68040"); 105*a9ac8606Spatrick Builder.defineMacro("__mc68040"); 106*a9ac8606Spatrick Builder.defineMacro("__mc68040__"); 107*a9ac8606Spatrick break; 108*a9ac8606Spatrick case CK_68060: 109*a9ac8606Spatrick Builder.defineMacro("mc68060"); 110*a9ac8606Spatrick Builder.defineMacro("__mc68060"); 111*a9ac8606Spatrick Builder.defineMacro("__mc68060__"); 112*a9ac8606Spatrick break; 113*a9ac8606Spatrick default: 114*a9ac8606Spatrick break; 115*a9ac8606Spatrick } 116*a9ac8606Spatrick } 117*a9ac8606Spatrick 118*a9ac8606Spatrick ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const { 119*a9ac8606Spatrick // FIXME: Implement. 120*a9ac8606Spatrick return None; 121*a9ac8606Spatrick } 122*a9ac8606Spatrick 123*a9ac8606Spatrick bool M68kTargetInfo::hasFeature(StringRef Feature) const { 124*a9ac8606Spatrick // FIXME elaborate moar 125*a9ac8606Spatrick return Feature == "M68000"; 126*a9ac8606Spatrick } 127*a9ac8606Spatrick 128*a9ac8606Spatrick const char *const M68kTargetInfo::GCCRegNames[] = { 129*a9ac8606Spatrick "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", 130*a9ac8606Spatrick "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", 131*a9ac8606Spatrick "pc"}; 132*a9ac8606Spatrick 133*a9ac8606Spatrick ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const { 134*a9ac8606Spatrick return llvm::makeArrayRef(GCCRegNames); 135*a9ac8606Spatrick } 136*a9ac8606Spatrick 137*a9ac8606Spatrick ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const { 138*a9ac8606Spatrick // No aliases. 139*a9ac8606Spatrick return None; 140*a9ac8606Spatrick } 141*a9ac8606Spatrick 142*a9ac8606Spatrick bool M68kTargetInfo::validateAsmConstraint( 143*a9ac8606Spatrick const char *&Name, TargetInfo::ConstraintInfo &info) const { 144*a9ac8606Spatrick switch (*Name) { 145*a9ac8606Spatrick case 'a': // address register 146*a9ac8606Spatrick case 'd': // data register 147*a9ac8606Spatrick info.setAllowsRegister(); 148*a9ac8606Spatrick return true; 149*a9ac8606Spatrick case 'I': // constant integer in the range [1,8] 150*a9ac8606Spatrick info.setRequiresImmediate(1, 8); 151*a9ac8606Spatrick return true; 152*a9ac8606Spatrick case 'J': // constant signed 16-bit integer 153*a9ac8606Spatrick info.setRequiresImmediate(std::numeric_limits<int16_t>::min(), 154*a9ac8606Spatrick std::numeric_limits<int16_t>::max()); 155*a9ac8606Spatrick return true; 156*a9ac8606Spatrick case 'K': // constant that is NOT in the range of [-0x80, 0x80) 157*a9ac8606Spatrick info.setRequiresImmediate(); 158*a9ac8606Spatrick return true; 159*a9ac8606Spatrick case 'L': // constant integer in the range [-8,-1] 160*a9ac8606Spatrick info.setRequiresImmediate(-8, -1); 161*a9ac8606Spatrick return true; 162*a9ac8606Spatrick case 'M': // constant that is NOT in the range of [-0x100, 0x100] 163*a9ac8606Spatrick info.setRequiresImmediate(); 164*a9ac8606Spatrick return true; 165*a9ac8606Spatrick case 'N': // constant integer in the range [24,31] 166*a9ac8606Spatrick info.setRequiresImmediate(24, 31); 167*a9ac8606Spatrick return true; 168*a9ac8606Spatrick case 'O': // constant integer 16 169*a9ac8606Spatrick info.setRequiresImmediate(16); 170*a9ac8606Spatrick return true; 171*a9ac8606Spatrick case 'P': // constant integer in the range [8,15] 172*a9ac8606Spatrick info.setRequiresImmediate(8, 15); 173*a9ac8606Spatrick return true; 174*a9ac8606Spatrick case 'C': 175*a9ac8606Spatrick ++Name; 176*a9ac8606Spatrick switch (*Name) { 177*a9ac8606Spatrick case '0': // constant integer 0 178*a9ac8606Spatrick info.setRequiresImmediate(0); 179*a9ac8606Spatrick return true; 180*a9ac8606Spatrick case 'i': // constant integer 181*a9ac8606Spatrick case 'j': // integer constant that doesn't fit in 16 bits 182*a9ac8606Spatrick info.setRequiresImmediate(); 183*a9ac8606Spatrick return true; 184*a9ac8606Spatrick default: 185*a9ac8606Spatrick break; 186*a9ac8606Spatrick } 187*a9ac8606Spatrick break; 188*a9ac8606Spatrick default: 189*a9ac8606Spatrick break; 190*a9ac8606Spatrick } 191*a9ac8606Spatrick return false; 192*a9ac8606Spatrick } 193*a9ac8606Spatrick 194*a9ac8606Spatrick llvm::Optional<std::string> 195*a9ac8606Spatrick M68kTargetInfo::handleAsmEscapedChar(char EscChar) const { 196*a9ac8606Spatrick char C; 197*a9ac8606Spatrick switch (EscChar) { 198*a9ac8606Spatrick case '.': 199*a9ac8606Spatrick case '#': 200*a9ac8606Spatrick C = EscChar; 201*a9ac8606Spatrick break; 202*a9ac8606Spatrick case '/': 203*a9ac8606Spatrick C = '%'; 204*a9ac8606Spatrick break; 205*a9ac8606Spatrick case '$': 206*a9ac8606Spatrick C = 's'; 207*a9ac8606Spatrick break; 208*a9ac8606Spatrick case '&': 209*a9ac8606Spatrick C = 'd'; 210*a9ac8606Spatrick break; 211*a9ac8606Spatrick default: 212*a9ac8606Spatrick return llvm::None; 213*a9ac8606Spatrick } 214*a9ac8606Spatrick 215*a9ac8606Spatrick return std::string(1, C); 216*a9ac8606Spatrick } 217*a9ac8606Spatrick 218*a9ac8606Spatrick std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const { 219*a9ac8606Spatrick if (*Constraint == 'C') 220*a9ac8606Spatrick // Two-character constraint; add "^" hint for later parsing 221*a9ac8606Spatrick return std::string("^") + std::string(Constraint++, 2); 222*a9ac8606Spatrick 223*a9ac8606Spatrick return std::string(1, *Constraint); 224*a9ac8606Spatrick } 225*a9ac8606Spatrick 226*a9ac8606Spatrick const char *M68kTargetInfo::getClobbers() const { 227*a9ac8606Spatrick // FIXME: Is this really right? 228*a9ac8606Spatrick return ""; 229*a9ac8606Spatrick } 230*a9ac8606Spatrick 231*a9ac8606Spatrick TargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const { 232*a9ac8606Spatrick return TargetInfo::VoidPtrBuiltinVaList; 233*a9ac8606Spatrick } 234*a9ac8606Spatrick 235*a9ac8606Spatrick } // namespace targets 236*a9ac8606Spatrick } // namespace clang 237