1 //===--- M68k.cpp - Implement M68k targets feature support-------------===// 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 // This file implements M68k TargetInfo objects. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "M68k.h" 14 #include "clang/Basic/Builtins.h" 15 #include "clang/Basic/Diagnostic.h" 16 #include "clang/Basic/TargetBuiltins.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/Support/TargetParser.h" 21 #include <cstring> 22 23 namespace clang { 24 namespace targets { 25 26 M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple, 27 const TargetOptions &) 28 : TargetInfo(Triple) { 29 30 std::string Layout = ""; 31 32 // M68k is Big Endian 33 Layout += "E"; 34 35 // FIXME how to wire it with the used object format? 36 Layout += "-m:e"; 37 38 // M68k pointers are always 32 bit wide even for 16 bit cpus 39 Layout += "-p:32:32"; 40 41 // M68k integer data types 42 Layout += "-i8:8:8-i16:16:16-i32:16:32"; 43 44 // FIXME no floats at the moment 45 46 // The registers can hold 8, 16, 32 bits 47 Layout += "-n8:16:32"; 48 49 // 16 bit alignment for both stack and aggregate 50 // in order to conform to ABI used by GCC 51 Layout += "-a:0:16-S16"; 52 53 resetDataLayout(Layout); 54 55 SizeType = UnsignedInt; 56 PtrDiffType = SignedInt; 57 IntPtrType = SignedInt; 58 } 59 60 bool M68kTargetInfo::setCPU(const std::string &Name) { 61 StringRef N = Name; 62 CPU = llvm::StringSwitch<CPUKind>(N) 63 .Case("generic", CK_68000) 64 .Case("M68000", CK_68000) 65 .Case("M68010", CK_68010) 66 .Case("M68020", CK_68020) 67 .Case("M68030", CK_68030) 68 .Case("M68040", CK_68040) 69 .Case("M68060", CK_68060) 70 .Default(CK_Unknown); 71 return CPU != CK_Unknown; 72 } 73 74 void M68kTargetInfo::getTargetDefines(const LangOptions &Opts, 75 MacroBuilder &Builder) const { 76 using llvm::Twine; 77 78 Builder.defineMacro("__m68k__"); 79 80 Builder.defineMacro("mc68000"); 81 Builder.defineMacro("__mc68000"); 82 Builder.defineMacro("__mc68000__"); 83 84 // For sub-architecture 85 switch (CPU) { 86 case CK_68010: 87 Builder.defineMacro("mc68010"); 88 Builder.defineMacro("__mc68010"); 89 Builder.defineMacro("__mc68010__"); 90 break; 91 case CK_68020: 92 Builder.defineMacro("mc68020"); 93 Builder.defineMacro("__mc68020"); 94 Builder.defineMacro("__mc68020__"); 95 break; 96 case CK_68030: 97 Builder.defineMacro("mc68030"); 98 Builder.defineMacro("__mc68030"); 99 Builder.defineMacro("__mc68030__"); 100 break; 101 case CK_68040: 102 Builder.defineMacro("mc68040"); 103 Builder.defineMacro("__mc68040"); 104 Builder.defineMacro("__mc68040__"); 105 break; 106 case CK_68060: 107 Builder.defineMacro("mc68060"); 108 Builder.defineMacro("__mc68060"); 109 Builder.defineMacro("__mc68060__"); 110 break; 111 default: 112 break; 113 } 114 } 115 116 ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const { 117 // FIXME: Implement. 118 return None; 119 } 120 121 bool M68kTargetInfo::hasFeature(StringRef Feature) const { 122 // FIXME elaborate moar 123 return Feature == "M68000"; 124 } 125 126 const char *const M68kTargetInfo::GCCRegNames[] = { 127 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", 128 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", 129 "pc"}; 130 131 ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const { 132 return llvm::makeArrayRef(GCCRegNames); 133 } 134 135 ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const { 136 // No aliases. 137 return None; 138 } 139 140 bool M68kTargetInfo::validateAsmConstraint( 141 const char *&Name, TargetInfo::ConstraintInfo &info) const { 142 switch (*Name) { 143 case 'a': // address register 144 case 'd': // data register 145 case 'f': // floating point register 146 info.setAllowsRegister(); 147 return true; 148 case 'K': // the constant 1 149 case 'L': // constant -1^20 .. 1^19 150 case 'M': // constant 1-4: 151 return true; 152 } 153 // FIXME: Support all constraints like 'N', 'O', 'P', 'R' 154 return false; 155 } 156 157 const char *M68kTargetInfo::getClobbers() const { 158 // FIXME: Is this really right? 159 return ""; 160 } 161 162 TargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const { 163 return TargetInfo::VoidPtrBuiltinVaList; 164 } 165 166 } // namespace targets 167 } // namespace clang 168