diff --git a/llvm/include/llvm/Support/MSP430AttributeParser.h b/llvm/include/llvm/Support/MSP430AttributeParser.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Support/MSP430AttributeParser.h @@ -0,0 +1,44 @@ +//===-- MSP430AttributeParser.h - MSP430 Attribute Parser -------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains support routines for parsing MSP430 ELF build attributes. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_MSP430ATTRIBUTEPARSER_H +#define LLVM_SUPPORT_MSP430ATTRIBUTEPARSER_H + +#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/MSP430Attributes.h" + +namespace llvm { +class MSP430AttributeParser : public ELFAttributeParser { + struct DisplayHandler { + MSP430Attrs::AttrType Attribute; + Error (MSP430AttributeParser::*Routine)(MSP430Attrs::AttrType); + }; + static const std::array DisplayRoutines; + + Error parseISA(MSP430Attrs::AttrType Tag); + Error parseCodeModel(MSP430Attrs::AttrType Tag); + Error parseDataModel(MSP430Attrs::AttrType Tag); + Error parseEnumSize(MSP430Attrs::AttrType Tag); + + Error handler(uint64_t Tag, bool &Handled) override; + +public: + MSP430AttributeParser(ScopedPrinter *SW) + : ELFAttributeParser(SW, MSP430Attrs::getMSP430AttributeTags(), + "mspabi") {} + MSP430AttributeParser() + : ELFAttributeParser(MSP430Attrs::getMSP430AttributeTags(), "mspabi") {} +}; +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/Support/MSP430Attributes.h b/llvm/include/llvm/Support/MSP430Attributes.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Support/MSP430Attributes.h @@ -0,0 +1,44 @@ +//===-- MSP430Attributes.h - MSP430 Attributes ------------------*- 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 +// +//===-----------------------------------------------------------------------===// +/// +/// \file +/// This file contains enumerations for MSP430 ELF build attributes as +/// defined in the MSP430 ELF psABI specification. +/// +/// MSP430 ELF psABI specification +/// +/// https://www.ti.com/lit/pdf/slaa534 +/// +//===----------------------------------------------------------------------===// +#ifndef LLVM_SUPPORT_MSP430ATTRIBUTES_H +#define LLVM_SUPPORT_MSP430ATTRIBUTES_H + +#include "llvm/Support/ELFAttributes.h" + +namespace llvm { +namespace MSP430Attrs { + +const TagNameMap &getMSP430AttributeTags(); + +enum AttrType : unsigned { + // Attribute types in ELF/.MSP430.attributes. + TagISA = 4, + TagCodeModel = 6, + TagDataModel = 8, + TagEnumSize = 10 +}; + +enum ISA { ISAMSP430 = 1, ISAMSP430X = 2 }; +enum CodeModel { CMSmall = 1, CMLarge = 2 }; +enum DataModel { DMSmall = 1, DMLarge = 2, DMRestricted = 3 }; +enum EnumSize { ESSmall = 1, ESInteger = 2, ESDontCare = 3 }; + +} // namespace MSP430Attrs +} // namespace llvm + +#endif diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -171,6 +171,8 @@ MemoryBuffer.cpp MemoryBufferRef.cpp MD5.cpp + MSP430Attributes.cpp + MSP430AttributeParser.cpp NativeFormatting.cpp OptimizedStructLayout.cpp Optional.cpp diff --git a/llvm/lib/Support/MSP430AttributeParser.cpp b/llvm/lib/Support/MSP430AttributeParser.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Support/MSP430AttributeParser.cpp @@ -0,0 +1,53 @@ +//===-- MSP430AttributeParser.cpp - MSP430 Attribute Parser ---------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/MSP430AttributeParser.h" +#include "llvm/ADT/StringExtras.h" + +using namespace llvm; +using namespace llvm::MSP430Attrs; + +constexpr std::array + MSP430AttributeParser::DisplayRoutines{ + {{MSP430Attrs::TagISA, &MSP430AttributeParser::parseISA}, + {MSP430Attrs::TagCodeModel, &MSP430AttributeParser::parseCodeModel}, + {MSP430Attrs::TagDataModel, &MSP430AttributeParser::parseDataModel}, + {MSP430Attrs::TagEnumSize, &MSP430AttributeParser::parseEnumSize}}}; + +Error MSP430AttributeParser::parseISA(AttrType Tag) { + static const char *StringVals[] = {"None", "MSP430", "MSP430X"}; + return parseStringAttribute("ISA", Tag, makeArrayRef(StringVals)); +} + +Error MSP430AttributeParser::parseCodeModel(AttrType Tag) { + static const char *StringVals[] = {"None", "Small", "Large"}; + return parseStringAttribute("Code Model", Tag, makeArrayRef(StringVals)); +} + +Error MSP430AttributeParser::parseDataModel(AttrType Tag) { + static const char *StringVals[] = {"None", "Small", "Large", "Restricted"}; + return parseStringAttribute("Data Model", Tag, makeArrayRef(StringVals)); +} + +Error MSP430AttributeParser::parseEnumSize(AttrType Tag) { + static const char *StringVals[] = {"None", "Small", "Integer", "Don't Care"}; + return parseStringAttribute("Enum Size", Tag, makeArrayRef(StringVals)); +} + +Error MSP430AttributeParser::handler(uint64_t Tag, bool &Handled) { + Handled = false; + for (const DisplayHandler &Disp : DisplayRoutines) { + if (uint64_t(Disp.Attribute) != Tag) + continue; + if (Error E = (this->*Disp.Routine)(static_cast(Tag))) + return E; + Handled = true; + break; + } + return Error::success(); +} diff --git a/llvm/lib/Support/MSP430Attributes.cpp b/llvm/lib/Support/MSP430Attributes.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Support/MSP430Attributes.cpp @@ -0,0 +1,22 @@ +//===-- MSP430Attributes.cpp - MSP430 Attributes --------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/MSP430Attributes.h" + +using namespace llvm; +using namespace llvm::MSP430Attrs; + +static constexpr TagNameItem TagData[] = {{TagISA, "Tag_ISA"}, + {TagCodeModel, "Tag_Code_Model"}, + {TagDataModel, "Tag_Data_Model"}, + {TagEnumSize, "Tag_Enum_Size"}}; + +constexpr TagNameMap MSP430AttributeTags{TagData}; +const TagNameMap &llvm::MSP430Attrs::getMSP430AttributeTags() { + return MSP430AttributeTags; +} diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp --- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp @@ -17,8 +17,10 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/MSP430Attributes.h" using namespace llvm; +using namespace llvm::MSP430Attrs; namespace llvm { @@ -54,15 +56,14 @@ Streamer.emitInt8(1); // Attribute vector length. Streamer.emitInt32(11); - // OFBA_MSPABI_Tag_ISA(4) = 1, MSP430 - Streamer.emitInt8(4); - Streamer.emitInt8(1); - // OFBA_MSPABI_Tag_Code_Model(6) = 1, Small - Streamer.emitInt8(6); - Streamer.emitInt8(1); - // OFBA_MSPABI_Tag_Data_Model(8) = 1, Small - Streamer.emitInt8(8); - Streamer.emitInt8(1); + + Streamer.emitInt8(TagISA); + Streamer.emitInt8(STI.hasFeature(MSP430::FeatureX) ? ISAMSP430X : ISAMSP430); + Streamer.emitInt8(TagCodeModel); + Streamer.emitInt8(CMSmall); + Streamer.emitInt8(TagDataModel); + Streamer.emitInt8(DMSmall); + // Don't emit TagEnumSize, for full GCC compatibility. } MCELFStreamer &MSP430TargetELFStreamer::getStreamer() { diff --git a/llvm/test/CodeGen/MSP430/build-attrs.ll b/llvm/test/CodeGen/MSP430/build-attrs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/MSP430/build-attrs.ll @@ -0,0 +1,41 @@ +; Test that the -mcpu= option sets the correct ELF build attributes. + +; RUN: llc -mtriple=msp430 -filetype=obj < %s \ +; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430,SMALL +; RUN: llc -mtriple=msp430 -mcpu=generic -filetype=obj < %s \ +; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430,SMALL +; RUN: llc -mtriple=msp430 -mcpu=msp430 -filetype=obj < %s \ +; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430,SMALL +; RUN: llc -mtriple=msp430 -mcpu=msp430x -filetype=obj < %s \ +; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430X,SMALL + +; COMMON: BuildAttributes { +; COMMON: FormatVersion: 0x41 +; COMMON: SectionLength: 22 +; COMMON: Vendor: mspabi +; COMMON: Tag: Tag_File (0x1) +; COMMON: Size: 11 + +; MSP430: Tag: 4 +; MSP430-NEXT: Value: 1 +; MSP430-NEXT: TagName: ISA +; MSP430-NEXT: Description: MSP430 + +; MSP430X: Tag: 4 +; MSP430X-NEXT: Value: 2 +; MSP430X-NEXT: TagName: ISA +; MSP430X-NEXT: Description: MSP430X + +; SMALL: Tag: 6 +; SMALL-NEXT: Value: 1 +; SMALL-NEXT: TagName: Code_Model +; SMALL-NEXT: Description: Small + +; SMALL: Tag: 8 +; SMALL-NEXT: Value: 1 +; SMALL-NEXT: TagName: Data_Model +; SMALL-NEXT: Description: Small + +define void @foo() { + ret void +} diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -49,6 +49,8 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/LEB128.h" +#include "llvm/Support/MSP430AttributeParser.h" +#include "llvm/Support/MSP430Attributes.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MipsABIFlags.h" #include "llvm/Support/RISCVAttributeParser.h" @@ -2558,6 +2560,7 @@ switch (Obj.getHeader().e_machine) { case EM_ARM: case EM_RISCV: + case EM_MSP430: printAttributes(); break; case EM_MIPS: { @@ -2598,6 +2601,10 @@ AttrShType = ELF::SHT_RISCV_ATTRIBUTES; AttrParser = std::make_unique(&W); break; + case EM_MSP430: + AttrShType = ELF::SHT_MSP430_ATTRIBUTES; + AttrParser = std::make_unique(&W); + break; default: llvm_unreachable("ELF attributes not implemented for target"); return;