myhsu updated this revision to Diff 326505.
myhsu marked 4 inline comments as done.
myhsu added a comment.
- [NFC] Addressed feedbacks
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D88393/new/
https://reviews.llvm.org/D88393
Files:
clang/include/clang/Basic/Attr.td
clang/lib/Basic/CMakeLists.txt
clang/lib/Basic/Targets.cpp
clang/lib/Basic/Targets/M68k.cpp
clang/lib/Basic/Targets/M68k.h
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/Sema/SemaDeclAttr.cpp
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -6306,6 +6306,39 @@
D->addAttr(::new (S.Context) MipsInterruptAttr(S.Context, AL, Kind));
}
+static void handleM68kInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (!checkAttributeNumArgs(S, AL, 1))
+ return;
+
+ if (!AL.isArgExpr(0)) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
+ << AL << AANT_ArgumentIntegerConstant;
+ return;
+ }
+
+ // FIXME: Check for decl - it should be void ()(void).
+
+ Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0));
+ auto MaybeNumParams = NumParamsExpr->getIntegerConstantExpr(S.Context);
+ if (!MaybeNumParams) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
+ << AL << AANT_ArgumentIntegerConstant
+ << NumParamsExpr->getSourceRange();
+ return;
+ }
+
+ unsigned Num = MaybeNumParams->getLimitedValue(255);
+ if ((Num & 1) || Num > 30) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
+ << AL << (int)MaybeNumParams->getSExtValue()
+ << NumParamsExpr->getSourceRange();
+ return;
+ }
+
+ D->addAttr(::new (S.Context) M68kInterruptAttr(S.Context, AL, Num));
+ D->addAttr(UsedAttr::CreateImplicit(S.Context));
+}
+
static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// Semantic checks for a function with the 'interrupt' attribute.
// a) Must be a function.
@@ -6578,6 +6611,9 @@
case llvm::Triple::mips:
handleMipsInterruptAttr(S, D, AL);
break;
+ case llvm::Triple::m68k:
+ handleM68kInterruptAttr(S, D, AL);
+ break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
handleAnyX86InterruptAttr(S, D, AL);
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -8066,6 +8066,43 @@
return false;
}
+//===----------------------------------------------------------------------===//
+// M68k ABI Implementation
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class M68kTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+ M68kTargetCodeGenInfo(CodeGenTypes &CGT)
+ : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}
+ void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+ CodeGen::CodeGenModule &M) const override;
+};
+
+} // namespace
+
+void M68kTargetCodeGenInfo::setTargetAttributes(
+ const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
+ if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+ if (const auto *attr = FD->getAttr<M68kInterruptAttr>()) {
+ // Handle 'interrupt' attribute:
+ llvm::Function *F = cast<llvm::Function>(GV);
+
+ // Step 1: Set ISR calling convention.
+ F->setCallingConv(llvm::CallingConv::M68k_INTR);
+
+ // Step 2: Add attributes goodness.
+ F->addFnAttr(llvm::Attribute::NoInline);
+
+ // Step 3: Emit ISR vector alias.
+ unsigned Num = attr->getNumber() / 2;
+ llvm::GlobalAlias::create(llvm::Function::ExternalLinkage,
+ "__isr_" + Twine(Num), F);
+ }
+ }
+}
+
//===----------------------------------------------------------------------===//
// AVR ABI Implementation.
//===----------------------------------------------------------------------===//
@@ -10877,6 +10914,8 @@
case llvm::Triple::le32:
return SetCGInfo(new PNaClTargetCodeGenInfo(Types));
+ case llvm::Triple::m68k:
+ return SetCGInfo(new M68kTargetCodeGenInfo(Types));
case llvm::Triple::mips:
case llvm::Triple::mipsel:
if (Triple.getOS() == llvm::Triple::NaCl)
Index: clang/lib/Basic/Targets/M68k.h
===================================================================
--- /dev/null
+++ clang/lib/Basic/Targets/M68k.h
@@ -0,0 +1,57 @@
+//===--- M68k.h - Declare M68k target feature support -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares M68k TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_M68K_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_M68K_H
+
+#include "OSTargets.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+namespace targets {
+
+class LLVM_LIBRARY_VISIBILITY M68kTargetInfo : public TargetInfo {
+ static const char *const GCCRegNames[];
+
+ enum CPUKind {
+ CK_Unknown,
+ CK_68000,
+ CK_68010,
+ CK_68020,
+ CK_68030,
+ CK_68040,
+ CK_68060
+ } CPU = CK_Unknown;
+
+public:
+ M68kTargetInfo(const llvm::Triple &Triple, const TargetOptions &);
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override;
+ bool hasFeature(StringRef Feature) const override;
+ ArrayRef<const char *> getGCCRegNames() const override;
+ ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
+ bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &info) const override;
+ const char *getClobbers() const override;
+ BuiltinVaListKind getBuiltinVaListKind() const override;
+ bool setCPU(const std::string &Name) override;
+};
+
+} // namespace targets
+} // namespace clang
+
+#endif
Index: clang/lib/Basic/Targets/M68k.cpp
===================================================================
--- /dev/null
+++ clang/lib/Basic/Targets/M68k.cpp
@@ -0,0 +1,168 @@
+//===--- M68k.cpp - Implement M68k targets feature support-------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements M68k TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "M68k.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/TargetBuiltins.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/TargetParser.h"
+#include <cstring>
+
+namespace clang {
+namespace targets {
+
+M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,
+ const TargetOptions &)
+ : TargetInfo(Triple) {
+
+ std::string Layout = "";
+
+ // M68k is Big Endian
+ Layout += "E";
+
+ // FIXME how to wire it with the used object format?
+ Layout += "-m:e";
+
+ // M68k pointers are always 32 bit wide even for 16 bit cpus
+ Layout += "-p:32:32";
+
+ // M68k integer data types
+ Layout += "-i8:8:8-i16:16:16-i32:16:32";
+
+ // FIXME no floats at the moment
+
+ // The registers can hold 8, 16, 32 bits
+ Layout += "-n8:16:32";
+
+ // 16 bit alignment for both stack and aggregate
+ // in order to conform to ABI used by GCC
+ Layout += "-a:0:16-S16";
+
+ resetDataLayout(Layout);
+
+ SizeType = UnsignedInt;
+ PtrDiffType = SignedInt;
+ IntPtrType = SignedInt;
+}
+
+bool M68kTargetInfo::setCPU(const std::string &Name) {
+ StringRef N = Name;
+ CPU = llvm::StringSwitch<CPUKind>(N)
+ .Case("generic", CK_68000)
+ .Case("M68000", CK_68000)
+ .Case("M68010", CK_68010)
+ .Case("M68020", CK_68020)
+ .Case("M68030", CK_68030)
+ .Case("M68040", CK_68040)
+ .Case("M68060", CK_68060)
+ .Default(CK_Unknown);
+ return CPU != CK_Unknown;
+}
+
+void M68kTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ using llvm::Twine;
+
+ Builder.defineMacro("__m68k__");
+
+ Builder.defineMacro("mc68000");
+ Builder.defineMacro("__mc68000");
+ Builder.defineMacro("__mc68000__");
+
+ // For sub-architecture
+ switch (CPU) {
+ case CK_68010:
+ Builder.defineMacro("mc68010");
+ Builder.defineMacro("__mc68010");
+ Builder.defineMacro("__mc68010__");
+ break;
+ case CK_68020:
+ Builder.defineMacro("mc68020");
+ Builder.defineMacro("__mc68020");
+ Builder.defineMacro("__mc68020__");
+ break;
+ case CK_68030:
+ Builder.defineMacro("mc68030");
+ Builder.defineMacro("__mc68030");
+ Builder.defineMacro("__mc68030__");
+ break;
+ case CK_68040:
+ Builder.defineMacro("mc68040");
+ Builder.defineMacro("__mc68040");
+ Builder.defineMacro("__mc68040__");
+ break;
+ case CK_68060:
+ Builder.defineMacro("mc68060");
+ Builder.defineMacro("__mc68060");
+ Builder.defineMacro("__mc68060__");
+ break;
+ default:
+ break;
+ }
+}
+
+ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const {
+ // FIXME: Implement.
+ return None;
+}
+
+bool M68kTargetInfo::hasFeature(StringRef Feature) const {
+ // FIXME elaborate moar
+ return Feature == "M68000";
+}
+
+const char *const M68kTargetInfo::GCCRegNames[] = {
+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
+ "pc"};
+
+ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const {
+ return llvm::makeArrayRef(GCCRegNames);
+}
+
+ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const {
+ // No aliases.
+ return None;
+}
+
+bool M68kTargetInfo::validateAsmConstraint(
+ const char *&Name, TargetInfo::ConstraintInfo &info) const {
+ switch (*Name) {
+ case 'a': // address register
+ case 'd': // data register
+ case 'f': // floating point register
+ info.setAllowsRegister();
+ return true;
+ case 'K': // the constant 1
+ case 'L': // constant -1^20 .. 1^19
+ case 'M': // constant 1-4:
+ return true;
+ }
+ // FIXME: Support all constraints like 'N', 'O', 'P', 'R'
+ return false;
+}
+
+const char *M68kTargetInfo::getClobbers() const {
+ // FIXME: Is this really right?
+ return "";
+}
+
+M68kTargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const {
+ // FIXME: implement
+ llvm_unreachable("Not implemented yet");
+}
+
+} // namespace targets
+} // namespace clang
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -22,6 +22,7 @@
#include "Targets/Hexagon.h"
#include "Targets/Lanai.h"
#include "Targets/Le64.h"
+#include "Targets/M68k.h"
#include "Targets/MSP430.h"
#include "Targets/Mips.h"
#include "Targets/NVPTX.h"
@@ -303,6 +304,16 @@
return new MipsTargetInfo(Triple, Opts);
}
+ case llvm::Triple::m68k:
+ switch (os) {
+ case llvm::Triple::Linux:
+ return new LinuxTargetInfo<M68kTargetInfo>(Triple, Opts);
+ case llvm::Triple::NetBSD:
+ return new NetBSDTargetInfo<M68kTargetInfo>(Triple, Opts);
+ default:
+ return new M68kTargetInfo(Triple, Opts);
+ }
+
case llvm::Triple::le32:
switch (os) {
case llvm::Triple::NaCl:
Index: clang/lib/Basic/CMakeLists.txt
===================================================================
--- clang/lib/Basic/CMakeLists.txt
+++ clang/lib/Basic/CMakeLists.txt
@@ -76,6 +76,7 @@
Targets/Hexagon.cpp
Targets/Lanai.cpp
Targets/Le64.cpp
+ Targets/M68k.cpp
Targets/MSP430.cpp
Targets/Mips.cpp
Targets/NVPTX.cpp
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -364,6 +364,7 @@
def TargetMips32 : TargetArch<["mips", "mipsel"]>;
def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
+def TargetM68k : TargetArch<["m68k"]>;
def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
def TargetX86 : TargetArch<["x86"]>;
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
@@ -755,8 +756,9 @@
}
def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
- // NOTE: If you add any additional spellings, MSP430Interrupt's,
- // MipsInterrupt's and AnyX86Interrupt's spellings must match.
+ // NOTE: If you add any additional spellings, M68kInterrupt's,
+ // MSP430Interrupt's, MipsInterrupt's and AnyX86Interrupt's spellings
+ // must match.
let Spellings = [GCC<"interrupt">];
let Args = [EnumArgument<"Interrupt", "InterruptType",
["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
@@ -1486,8 +1488,8 @@
}
def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> {
- // NOTE: If you add any additional spellings, ARMInterrupt's, MipsInterrupt's
- // and AnyX86Interrupt's spellings must match.
+ // NOTE: If you add any additional spellings, ARMInterrupt's, M68kInterrupt's,
+ // MipsInterrupt's and AnyX86Interrupt's spellings must match.
let Spellings = [GCC<"interrupt">];
let Args = [UnsignedArgument<"Number">];
let ParseKind = "Interrupt";
@@ -1503,7 +1505,8 @@
def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips32> {
// NOTE: If you add any additional spellings, ARMInterrupt's,
- // MSP430Interrupt's and AnyX86Interrupt's spellings must match.
+ // M68kInterrupt's, MSP430Interrupt's and AnyX86Interrupt's spellings
+ // must match.
let Spellings = [GCC<"interrupt">];
let Subjects = SubjectList<[Function]>;
let Args = [EnumArgument<"Interrupt", "InterruptType",
@@ -1535,6 +1538,16 @@
let Documentation = [MipsShortCallStyleDocs];
}
+def M68kInterrupt : InheritableAttr, TargetSpecificAttr<TargetM68k> {
+ // NOTE: If you add any additional spellings, ARMInterrupt's, MipsInterrupt's
+ // MSP430Interrupt's and AnyX86Interrupt's spellings must match.
+ let Spellings = [GNU<"interrupt">];
+ let Args = [UnsignedArgument<"Number">];
+ let ParseKind = "Interrupt";
+ let HasCustomParsing = 1;
+ let Documentation = [Undocumented];
+}
+
def Mode : Attr {
let Spellings = [GCC<"mode">];
let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag>;
@@ -2677,7 +2690,7 @@
def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
// NOTE: If you add any additional spellings, ARMInterrupt's,
- // MSP430Interrupt's and MipsInterrupt's spellings must match.
+ // M68kInterrupt's, MSP430Interrupt's and MipsInterrupt's spellings must match.
let Spellings = [GCC<"interrupt">];
let Subjects = SubjectList<[HasFunctionProto]>;
let ParseKind = "Interrupt";
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits