Skip to content

[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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/lib/BinaryFormat/MachO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

Expand All @@ -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);
}

Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Object/MachOObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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();
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ add_llvm_component_library(LLVMRISCVDesc
RISCVBaseInfo.cpp
RISCVELFObjectWriter.cpp
RISCVInstPrinter.cpp
RISCVMachObjectWriter.cpp
RISCVMCAsmInfo.cpp
RISCVMCCodeEmitter.cpp
RISCVMCExpr.cpp
Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class MCObjectTargetWriter;
class raw_ostream;

class RISCVAsmBackend : public MCAsmBackend {
protected:
const MCSubtargetInfo &STI;
uint8_t OSABI;
bool Is64Bit;
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
6 changes: 6 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -28,6 +29,11 @@ class RISCVMCAsmInfo : public MCAsmInfoELF {
MCStreamer &Streamer) const override;
};

class RISCVMCAsmInfoDarwin : public MCAsmInfoDarwin {
public:
explicit RISCVMCAsmInfoDarwin();
};

} // namespace llvm

#endif
7 changes: 6 additions & 1 deletion llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ 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();
assert(MAI && "Missing MCAsmInfo.");

unsigned SP = MRI.getDwarfRegNum(RISCV::X2, true);
MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, SP, 0);
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
56 changes: 56 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVMachObjectWriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//===-- 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"
Copy link
Member

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.

#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/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);
}
16 changes: 15 additions & 1 deletion llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
static StringRef computeDataLayout(const Triple &TT,
const TargetOptions &Options) {
StringRef ABIName = Options.MCOptions.getABIName();
if (TT.isOSBinFormatMachO()) {
assert(TT.isArch32Bit() && "Invalid triple.");
assert((ABIName != "ilp32e") && "Invalid ABI.");
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";
Expand All @@ -175,6 +180,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,
Expand All @@ -184,7 +198,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.
Expand Down
13 changes: 13 additions & 0 deletions llvm/test/CodeGen/RISCV/riscv-macho.ll
Original file line number Diff line number Diff line change
@@ -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
}
26 changes: 26 additions & 0 deletions llvm/test/MC/RISCV/riscv-macho.s
Original file line number Diff line number Diff line change
@@ -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
Loading