Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp
35266 views
//===--- M68k.cpp - Implement M68k targets feature support-------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements M68k TargetInfo objects.9//10//===----------------------------------------------------------------------===//1112#include "M68k.h"13#include "clang/Basic/Builtins.h"14#include "clang/Basic/Diagnostic.h"15#include "clang/Basic/TargetBuiltins.h"16#include "llvm/ADT/StringExtras.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/ADT/StringSwitch.h"19#include "llvm/TargetParser/TargetParser.h"20#include <cstdint>21#include <cstring>22#include <limits>23#include <optional>2425namespace clang {26namespace targets {2728M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,29const TargetOptions &Opts)30: TargetInfo(Triple), TargetOpts(Opts) {3132std::string Layout;3334// M68k is Big Endian35Layout += "E";3637// FIXME how to wire it with the used object format?38Layout += "-m:e";3940// M68k pointers are always 32 bit wide even for 16-bit CPUs41Layout += "-p:32:16:32";4243// M68k integer data types44Layout += "-i8:8:8-i16:16:16-i32:16:32";4546// FIXME no floats at the moment4748// The registers can hold 8, 16, 32 bits49Layout += "-n8:16:32";5051// 16 bit alignment for both stack and aggregate52// in order to conform to ABI used by GCC53Layout += "-a:0:16-S16";5455resetDataLayout(Layout);5657SizeType = UnsignedInt;58PtrDiffType = SignedInt;59IntPtrType = SignedInt;60}6162bool M68kTargetInfo::setCPU(const std::string &Name) {63StringRef N = Name;64CPU = llvm::StringSwitch<CPUKind>(N)65.Case("generic", CK_68000)66.Case("M68000", CK_68000)67.Case("M68010", CK_68010)68.Case("M68020", CK_68020)69.Case("M68030", CK_68030)70.Case("M68040", CK_68040)71.Case("M68060", CK_68060)72.Default(CK_Unknown);73return CPU != CK_Unknown;74}7576void M68kTargetInfo::getTargetDefines(const LangOptions &Opts,77MacroBuilder &Builder) const {78using llvm::Twine;7980Builder.defineMacro("__m68k__");8182DefineStd(Builder, "mc68000", Opts);8384// For sub-architecture85switch (CPU) {86case CK_68010:87DefineStd(Builder, "mc68010", Opts);88break;89case CK_68020:90DefineStd(Builder, "mc68020", Opts);91break;92case CK_68030:93DefineStd(Builder, "mc68030", Opts);94break;95case CK_68040:96DefineStd(Builder, "mc68040", Opts);97break;98case CK_68060:99DefineStd(Builder, "mc68060", Opts);100break;101default:102break;103}104105if (CPU >= CK_68020) {106Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");107Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");108Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");109}110111// Floating point112if (TargetOpts.FeatureMap.lookup("isa-68881") ||113TargetOpts.FeatureMap.lookup("isa-68882"))114Builder.defineMacro("__HAVE_68881__");115}116117ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const {118// FIXME: Implement.119return std::nullopt;120}121122bool M68kTargetInfo::hasFeature(StringRef Feature) const {123// FIXME elaborate moar124return Feature == "M68000";125}126127const char *const M68kTargetInfo::GCCRegNames[] = {128"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",129"a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp",130"pc"};131132ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const {133return llvm::ArrayRef(GCCRegNames);134}135136const TargetInfo::GCCRegAlias M68kTargetInfo::GCCRegAliases[] = {137{{"bp"}, "a5"},138{{"fp"}, "a6"},139{{"usp", "ssp", "isp", "a7"}, "sp"},140};141142ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const {143return llvm::ArrayRef(GCCRegAliases);144}145146bool M68kTargetInfo::validateAsmConstraint(147const char *&Name, TargetInfo::ConstraintInfo &info) const {148switch (*Name) {149case 'a': // address register150case 'd': // data register151info.setAllowsRegister();152return true;153case 'I': // constant integer in the range [1,8]154info.setRequiresImmediate(1, 8);155return true;156case 'J': // constant signed 16-bit integer157info.setRequiresImmediate(std::numeric_limits<int16_t>::min(),158std::numeric_limits<int16_t>::max());159return true;160case 'K': // constant that is NOT in the range of [-0x80, 0x80)161info.setRequiresImmediate();162return true;163case 'L': // constant integer in the range [-8,-1]164info.setRequiresImmediate(-8, -1);165return true;166case 'M': // constant that is NOT in the range of [-0x100, 0x100]167info.setRequiresImmediate();168return true;169case 'N': // constant integer in the range [24,31]170info.setRequiresImmediate(24, 31);171return true;172case 'O': // constant integer 16173info.setRequiresImmediate(16);174return true;175case 'P': // constant integer in the range [8,15]176info.setRequiresImmediate(8, 15);177return true;178case 'C':179++Name;180switch (*Name) {181case '0': // constant integer 0182info.setRequiresImmediate(0);183return true;184case 'i': // constant integer185case 'j': // integer constant that doesn't fit in 16 bits186info.setRequiresImmediate();187return true;188default:189break;190}191break;192case 'Q': // address register indirect addressing193case 'U': // address register indirect w/ constant offset addressing194// TODO: Handle 'S' (basically 'm' when pc-rel is enforced) when195// '-mpcrel' flag is properly handled by the driver.196info.setAllowsMemory();197return true;198default:199break;200}201return false;202}203204std::optional<std::string>205M68kTargetInfo::handleAsmEscapedChar(char EscChar) const {206char C;207switch (EscChar) {208case '.':209case '#':210C = EscChar;211break;212case '/':213C = '%';214break;215case '$':216C = 's';217break;218case '&':219C = 'd';220break;221default:222return std::nullopt;223}224225return std::string(1, C);226}227228std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const {229if (*Constraint == 'C')230// Two-character constraint; add "^" hint for later parsing231return std::string("^") + std::string(Constraint++, 2);232233return std::string(1, *Constraint);234}235236std::string_view M68kTargetInfo::getClobbers() const {237// FIXME: Is this really right?238return "";239}240241TargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const {242return TargetInfo::VoidPtrBuiltinVaList;243}244245TargetInfo::CallingConvCheckResult246M68kTargetInfo::checkCallingConvention(CallingConv CC) const {247switch (CC) {248case CC_C:249case CC_M68kRTD:250return CCCR_OK;251default:252return TargetInfo::checkCallingConvention(CC);253}254}255} // namespace targets256} // namespace clang257258259