-
Notifications
You must be signed in to change notification settings - Fork 14.2k
[RISCV] Add basic Mach-O triple support. #141682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Based on a patch written by Tim Northover (https://github.com/TNorthover).
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-backend-risc-v Author: Francesco Petrogalli (fpetrogalli) ChangesBased on a patch written by Tim Full diff: https://github.com/llvm/llvm-project/pull/141682.diff 13 Files Affected:
diff --git a/llvm/lib/BinaryFormat/MachO.cpp b/llvm/lib/BinaryFormat/MachO.cpp
index f46b9d5147ff1..369b5ba927136 100644
--- a/llvm/lib/BinaryFormat/MachO.cpp
+++ b/llvm/lib/BinaryFormat/MachO.cpp
@@ -74,6 +74,10 @@ static Error unsupported(const char *Str, const Triple &T) {
T.str().c_str());
}
+static MachO::CPUSubTypeRISCV getRISCVSubType(const Triple &T) {
+ return MachO::CPU_SUBTYPE_RISCV_ALL;
+}
+
Expected<uint32_t> MachO::getCPUType(const Triple &T) {
if (!T.isOSBinFormatMachO())
return unsupported("type", T);
@@ -89,6 +93,8 @@ Expected<uint32_t> MachO::getCPUType(const Triple &T) {
return MachO::CPU_TYPE_POWERPC;
if (T.getArch() == Triple::ppc64)
return MachO::CPU_TYPE_POWERPC64;
+ if (T.getArch() == Triple::riscv32)
+ return MachO::CPU_TYPE_RISCV;
return unsupported("type", T);
}
@@ -103,6 +109,8 @@ Expected<uint32_t> MachO::getCPUSubType(const Triple &T) {
return getARM64SubType(T);
if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64)
return getPowerPCSubType(T);
+ if (T.getArch() == Triple::riscv32)
+ return getRISCVSubType(T);
return unsupported("subtype", T);
}
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 5db264207ffb7..d0713dc77303b 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -2668,6 +2668,8 @@ StringRef MachOObjectFile::getFileFormatName() const {
return "Mach-O arm64 (ILP32)";
case MachO::CPU_TYPE_POWERPC:
return "Mach-O 32-bit ppc";
+ case MachO::CPU_TYPE_RISCV:
+ return "Mach-O 32-bit RISC-V";
default:
return "Mach-O 32-bit unknown";
}
@@ -2701,6 +2703,8 @@ Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType, uint32_t CPUSubType)
return Triple::ppc;
case MachO::CPU_TYPE_POWERPC64:
return Triple::ppc64;
+ case MachO::CPU_TYPE_RISCV:
+ return Triple::riscv32;
default:
return Triple::UnknownArch;
}
@@ -2838,6 +2842,15 @@ Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
default:
return Triple();
}
+ case MachO::CPU_TYPE_RISCV:
+ switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) {
+ case MachO::CPU_SUBTYPE_RISCV_ALL:
+ if (ArchFlag)
+ *ArchFlag = "riscv32";
+ return Triple("riscv32-apple-macho");
+ default:
+ return Triple();
+ }
default:
return Triple();
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
index e68c956f888e4..1a8dd50327dde 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
@@ -3,6 +3,7 @@ add_llvm_component_library(LLVMRISCVDesc
RISCVBaseInfo.cpp
RISCVELFObjectWriter.cpp
RISCVInstPrinter.cpp
+ RISCVMachObjectWriter.cpp
RISCVMCAsmInfo.cpp
RISCVMCCodeEmitter.cpp
RISCVMCExpr.cpp
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index f7f39439249e8..19f05522755c4 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCMachObjectWriter.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
@@ -757,11 +758,28 @@ RISCVAsmBackend::createObjectTargetWriter() const {
return createRISCVELFObjectWriter(OSABI, Is64Bit);
}
+class DarwinRISCVAsmBackend : public RISCVAsmBackend {
+public:
+ DarwinRISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
+ const MCTargetOptions &Options)
+ : RISCVAsmBackend(STI, OSABI, Is64Bit, Options) {}
+
+ std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const override {
+ const Triple &TT = STI.getTargetTriple();
+ uint32_t CPUType = cantFail(MachO::getCPUType(TT));
+ uint32_t CPUSubType = cantFail(MachO::getCPUSubType(TT));
+ return createRISCVMachObjectWriter(CPUType, CPUSubType);
+ }
+};
+
MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
const Triple &TT = STI.getTargetTriple();
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
+ if (TT.isOSBinFormatMachO())
+ return new DarwinRISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), Options);
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index 4dffbb82e07c7..061332796e78c 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -22,6 +22,7 @@ class MCObjectTargetWriter;
class raw_ostream;
class RISCVAsmBackend : public MCAsmBackend {
+protected:
const MCSubtargetInfo &STI;
uint8_t OSABI;
bool Is64Bit;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
index e75bc521d47ca..4b9402391fe2c 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
@@ -47,3 +47,16 @@ const MCExpr *RISCVMCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
assert(Encoding & dwarf::DW_EH_PE_sdata4 && "Unexpected encoding");
return RISCVMCExpr::create(ME, ELF::R_RISCV_32_PCREL, Ctx);
}
+
+RISCVMCAsmInfoDarwin::RISCVMCAsmInfoDarwin() {
+ CodePointerSize = 4;
+ PrivateGlobalPrefix = "L";
+ PrivateLabelPrefix = "L";
+ SeparatorString = "%%";
+ CommentString = ";";
+ AlignmentIsInBytes = false;
+ SupportsDebugInformation = true;
+ ExceptionsType = ExceptionHandling::DwarfCFI;
+ Data16bitsDirective = "\t.half\t";
+ Data32bitsDirective = "\t.word\t";
+}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
index bceeb1256471d..73271f6278f5f 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
@@ -13,6 +13,7 @@
#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCASMINFO_H
#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCASMINFO_H
+#include "llvm/MC/MCAsmInfoDarwin.h"
#include "llvm/MC/MCAsmInfoELF.h"
namespace llvm {
@@ -28,6 +29,11 @@ class RISCVMCAsmInfo : public MCAsmInfoELF {
MCStreamer &Streamer) const override;
};
+class RISCVMCAsmInfoDarwin : public MCAsmInfoDarwin {
+public:
+ explicit RISCVMCAsmInfoDarwin();
+};
+
} // namespace llvm
#endif
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
index d1bc6aa9a1e33..9d2caa1106ef5 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
@@ -58,7 +58,11 @@ static MCRegisterInfo *createRISCVMCRegisterInfo(const Triple &TT) {
static MCAsmInfo *createRISCVMCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TT,
const MCTargetOptions &Options) {
- MCAsmInfo *MAI = new RISCVMCAsmInfo(TT);
+ MCAsmInfo *MAI = nullptr;
+ if (TT.isOSBinFormatELF())
+ MAI = new RISCVMCAsmInfo(TT);
+ else if (TT.isOSBinFormatMachO())
+ MAI = new RISCVMCAsmInfoDarwin();
unsigned SP = MRI.getDwarfRegNum(RISCV::X2, true);
MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, SP, 0);
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
index bdee7ed4f011e..2a4afdb05d0f1 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
@@ -36,6 +36,9 @@ MCAsmBackend *createRISCVAsmBackend(const Target &T, const MCSubtargetInfo &STI,
std::unique_ptr<MCObjectTargetWriter> createRISCVELFObjectWriter(uint8_t OSABI,
bool Is64Bit);
+std::unique_ptr<MCObjectTargetWriter>
+createRISCVMachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype);
+
} // namespace llvm
// Defines symbolic names for RISC-V registers.
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMachObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMachObjectWriter.cpp
new file mode 100644
index 0000000000000..aa1f6122f6992
--- /dev/null
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMachObjectWriter.cpp
@@ -0,0 +1,57 @@
+//===-- RISCVMachObjectWriter.cpp - RISC-V Mach Object Writer -------------===//
+//
+// 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 "MCTargetDesc/RISCVFixupKinds.h"
+#include "MCTargetDesc/RISCVMCExpr.h"
+#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/MCAsmInfo.h"
+// #include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCFragment.h"
+#include "llvm/MC/MCMachObjectWriter.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <cstdint>
+
+using namespace llvm;
+
+namespace {
+
+class RISCVMachObjectWriter : public MCMachObjectTargetWriter {
+public:
+ RISCVMachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype)
+ : MCMachObjectTargetWriter(false, CPUType, CPUSubtype) {}
+
+ void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue) override;
+};
+
+} // end anonymous namespace
+
+void RISCVMachObjectWriter::recordRelocation(
+ MachObjectWriter *Writer, MCAssembler &Asm, const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) {
+ llvm_unreachable("unimplemented");
+}
+
+std::unique_ptr<MCObjectTargetWriter>
+llvm::createRISCVMachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype) {
+ return std::make_unique<RISCVMachObjectWriter>(CPUType, CPUSubtype);
+}
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 15dd4d57727dd..779a2bde1166a 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -156,6 +156,9 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
static StringRef computeDataLayout(const Triple &TT,
const TargetOptions &Options) {
StringRef ABIName = Options.MCOptions.getABIName();
+ if (TT.isOSBinFormatMachO())
+ return "e-m:o-p:32:32-i64:64-n32-S128";
+
if (TT.isArch64Bit()) {
if (ABIName == "lp64e")
return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S64";
@@ -175,6 +178,15 @@ static Reloc::Model getEffectiveRelocModel(const Triple &TT,
return RM.value_or(Reloc::Static);
}
+static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
+ if (TT.isOSBinFormatELF())
+ return std::make_unique<RISCVELFTargetObjectFile>();
+ else if (TT.isOSBinFormatMachO())
+ return std::make_unique<TargetLoweringObjectFileMachO>();
+ else
+ return std::unique_ptr<TargetLoweringObjectFile>();
+}
+
RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
@@ -184,7 +196,7 @@ RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT,
: CodeGenTargetMachineImpl(T, computeDataLayout(TT, Options), TT, CPU, FS,
Options, getEffectiveRelocModel(TT, RM),
getEffectiveCodeModel(CM, CodeModel::Small), OL),
- TLOF(std::make_unique<RISCVELFTargetObjectFile>()) {
+ TLOF(createTLOF(TT)) {
initAsmInfo();
// RISC-V supports the MachineOutliner.
diff --git a/llvm/test/CodeGen/RISCV/riscv-macho.ll b/llvm/test/CodeGen/RISCV/riscv-macho.ll
new file mode 100644
index 0000000000000..19d5fc026bbee
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/riscv-macho.ll
@@ -0,0 +1,13 @@
+; RUN: llc -mtriple=riscv32-apple-macho %s -o - | FileCheck %s
+; RUN: llc -mtriple=riscv32-apple-macho -filetype=obj %s -o %t.o
+; RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=CHECK-OBJ
+
+; CHECK-LABEL: _main:
+; CHECK: li a0, 0
+; CHECK: ret
+
+; CHECK-OBJ: li a0, 0
+; CHECK-OBJ: ret
+define i32 @main() nounwind {
+ ret i32 0
+}
diff --git a/llvm/test/MC/RISCV/riscv-macho.s b/llvm/test/MC/RISCV/riscv-macho.s
new file mode 100644
index 0000000000000..f2cec7bf08ebb
--- /dev/null
+++ b/llvm/test/MC/RISCV/riscv-macho.s
@@ -0,0 +1,26 @@
+; RUN: llvm-mc -triple riscv32-apple-macho %s -o - | FileCheck %s
+; RUN: llvm-mc -triple riscv32-apple-macho -filetype=obj %s -o %t.o
+; RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=CHECK-DIS
+; RUN: llvm-nm %t.o | FileCheck %s --check-prefix=CHECK-SYMS
+
+ nop
+ .half 42
+ .word 42
+Lfoo:
+lfoo:
+foo:
+
+; CHECK: nop
+; CHECK: .half 42
+; CHECK: .word 42
+
+; CHECK-DIS: file format mach-o 32-bit risc-v
+; CHECK-DIS: Disassembly of section __TEXT,__text:
+; CHECK-DIS: nop
+; CHECK-DIS: 002a <unknown>
+; CHECK-DIS: 002a <unknown>
+; CHECK-DIS: 0000 <unknown>
+
+; CHECK-SYMS-NOT: Lfoo
+; CHECK-SYMS: foo
+; CHECK-SYMS: lfoo
|
What does "basic support" mean? What do you expect to work with this? Is there a specification, or at least list of constants etc, for this from Apple? I don't see it in my system's |
This is also rather timely given we were just discussing a hypothetical Mach-O (or COFF) RISC-V in #138644 (comment) |
This is just adding the module Maybe I should change the commit message to
Unfortunately there is not much that is available online. My plan is to add add the tests with the expected behavior once this basic patch is in. |
Yes I am aware of the changes in #138644 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
//===----------------------------------------------------------------------===// | ||
|
||
#include "MCTargetDesc/RISCVFixupKinds.h" | ||
#include "MCTargetDesc/RISCVMCExpr.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RISCVMCExpr.h has been deleted. This file doesn't need the header.
Based on a patch written by Tim
Northover (https://github.com/TNorthover).