Dr. Brian Robert Callahan

academic, developer, with an eye towards a brighter techno-social life


Enabling LLVM with m68k (and more) support on OpenBSD

It is an exciting time in OpenBSD land. The in-base compiler was recently updated to LLVM 16.0.6, a nice upgrade over the 13.0.0 series compiler previously included in base. Additionally, there is a port of LLVM 17.0.4 available in ports, though I don't remember seeing it in packages.

One big difference between the ports compiler and the in-base compiler is that the in-base compiler only targets the host machine; the ports compiler by contrast targets all the platforms that LLVM can target. I was very excited by the inclusion of LLVM 17.0.4, because I wanted to play around with the C-SKY and m68k targets.

Unfortunately, LLVM does not build those targets by default, even if you do what OpenBSD does and say you want all the targets. That is because these targets are considered experimental, and as such are hidden behind yet another configuration option.

Let's get an actually complete LLVM.

The patch

There are a number of experimental targets: ARC, CSKY, DirectX, M68k, SPIRV, and Xtensa. I've enabled all of them; if we are going to gain a few experimental targets, we might as well gain them all.

You can add this patch to your ports tree in the devel/llvm directory:

Index: Makefile.inc
RCS file: /cvs/ports/devel/llvm/Makefile.inc,v
retrieving revision 1.12
diff -u -p -r1.12 Makefile.inc
--- Makefile.inc	11 Nov 2023 15:31:31 -0000	1.12
+++ Makefile.inc	19 Nov 2023 21:53:02 -0000
@@ -72,6 +72,7 @@ CONFIGURE_ARGS +=	\
Index: 17/pkg/PLIST-main
RCS file: /cvs/ports/devel/llvm/17/pkg/PLIST-main,v
retrieving revision
diff -u -p -r1.1.1.1 PLIST-main
--- 17/pkg/PLIST-main	13 Nov 2023 18:25:41 -0000
+++ 17/pkg/PLIST-main	19 Nov 2023 21:53:02 -0000
@@ -3310,6 +3310,10 @@ ${LLVM_BASE}/lib/cmake/llvm/llvm-driver-
 @static-lib ${LLVM_BASE}/lib/libLLVMAMDGPUInfo.a
 @static-lib ${LLVM_BASE}/lib/libLLVMAMDGPUTargetMCA.a
 @static-lib ${LLVM_BASE}/lib/libLLVMAMDGPUUtils.a
+@static-lib ${LLVM_BASE}/lib/libLLVMARCCodeGen.a
+@static-lib ${LLVM_BASE}/lib/libLLVMARCDesc.a
+@static-lib ${LLVM_BASE}/lib/libLLVMARCDisassembler.a
+@static-lib ${LLVM_BASE}/lib/libLLVMARCInfo.a
 @static-lib ${LLVM_BASE}/lib/libLLVMARMAsmParser.a
 @static-lib ${LLVM_BASE}/lib/libLLVMARMCodeGen.a
 @static-lib ${LLVM_BASE}/lib/libLLVMARMDesc.a
@@ -3336,6 +3340,11 @@ ${LLVM_BASE}/lib/cmake/llvm/llvm-driver-
 @static-lib ${LLVM_BASE}/lib/libLLVMBitstreamReader.a
 @static-lib ${LLVM_BASE}/lib/libLLVMCFGuard.a
 @static-lib ${LLVM_BASE}/lib/libLLVMCFIVerify.a
+@static-lib ${LLVM_BASE}/lib/libLLVMCSKYAsmParser.a
+@static-lib ${LLVM_BASE}/lib/libLLVMCSKYCodeGen.a
+@static-lib ${LLVM_BASE}/lib/libLLVMCSKYDesc.a
+@static-lib ${LLVM_BASE}/lib/libLLVMCSKYDisassembler.a
+@static-lib ${LLVM_BASE}/lib/libLLVMCSKYInfo.a
 @static-lib ${LLVM_BASE}/lib/libLLVMCodeGen.a
 @static-lib ${LLVM_BASE}/lib/libLLVMCodeGenTypes.a
 @static-lib ${LLVM_BASE}/lib/libLLVMCore.a
@@ -3344,6 +3353,7 @@ ${LLVM_BASE}/lib/cmake/llvm/llvm-driver-
 @static-lib ${LLVM_BASE}/lib/libLLVMDWARFLinker.a
 @static-lib ${LLVM_BASE}/lib/libLLVMDWARFLinkerParallel.a
 @static-lib ${LLVM_BASE}/lib/libLLVMDWP.a
+@static-lib ${LLVM_BASE}/lib/libLLVMDXILBitWriter.a
 @static-lib ${LLVM_BASE}/lib/libLLVMDebugInfoBTF.a
 @static-lib ${LLVM_BASE}/lib/libLLVMDebugInfoCodeView.a
 @static-lib ${LLVM_BASE}/lib/libLLVMDebugInfoDWARF.a
@@ -3354,6 +3364,10 @@ ${LLVM_BASE}/lib/cmake/llvm/llvm-driver-
 @static-lib ${LLVM_BASE}/lib/libLLVMDebuginfod.a
 @static-lib ${LLVM_BASE}/lib/libLLVMDemangle.a
 @static-lib ${LLVM_BASE}/lib/libLLVMDiff.a
+@static-lib ${LLVM_BASE}/lib/libLLVMDirectXCodeGen.a
+@static-lib ${LLVM_BASE}/lib/libLLVMDirectXDesc.a
+@static-lib ${LLVM_BASE}/lib/libLLVMDirectXInfo.a
+@static-lib ${LLVM_BASE}/lib/libLLVMDirectXPointerTypeAnalysis.a
 @static-lib ${LLVM_BASE}/lib/libLLVMDlltoolDriver.a
 @static-lib ${LLVM_BASE}/lib/libLLVMExecutionEngine.a
 @static-lib ${LLVM_BASE}/lib/libLLVMExegesis.a
@@ -3395,6 +3409,11 @@ ${LLVM_BASE}/lib/cmake/llvm/llvm-driver-
 @static-lib ${LLVM_BASE}/lib/libLLVMLoongArchDesc.a
 @static-lib ${LLVM_BASE}/lib/libLLVMLoongArchDisassembler.a
 @static-lib ${LLVM_BASE}/lib/libLLVMLoongArchInfo.a
+@static-lib ${LLVM_BASE}/lib/libLLVMM68kAsmParser.a
+@static-lib ${LLVM_BASE}/lib/libLLVMM68kCodeGen.a
+@static-lib ${LLVM_BASE}/lib/libLLVMM68kDesc.a
+@static-lib ${LLVM_BASE}/lib/libLLVMM68kDisassembler.a
+@static-lib ${LLVM_BASE}/lib/libLLVMM68kInfo.a
 @static-lib ${LLVM_BASE}/lib/libLLVMMC.a
 @static-lib ${LLVM_BASE}/lib/libLLVMMCA.a
 @static-lib ${LLVM_BASE}/lib/libLLVMMCDisassembler.a
@@ -3437,6 +3456,9 @@ ${LLVM_BASE}/lib/cmake/llvm/llvm-driver-
 @static-lib ${LLVM_BASE}/lib/libLLVMRISCVTargetMCA.a
 @static-lib ${LLVM_BASE}/lib/libLLVMRemarks.a
 @static-lib ${LLVM_BASE}/lib/libLLVMRuntimeDyld.a
+@static-lib ${LLVM_BASE}/lib/libLLVMSPIRVCodeGen.a
+@static-lib ${LLVM_BASE}/lib/libLLVMSPIRVDesc.a
+@static-lib ${LLVM_BASE}/lib/libLLVMSPIRVInfo.a
 @static-lib ${LLVM_BASE}/lib/libLLVMScalarOpts.a
 @static-lib ${LLVM_BASE}/lib/libLLVMSelectionDAG.a
 @static-lib ${LLVM_BASE}/lib/libLLVMSparcAsmParser.a
@@ -3483,6 +3505,11 @@ ${LLVM_BASE}/lib/cmake/llvm/llvm-driver-
 @static-lib ${LLVM_BASE}/lib/libLLVMXCoreDisassembler.a
 @static-lib ${LLVM_BASE}/lib/libLLVMXCoreInfo.a
 @static-lib ${LLVM_BASE}/lib/libLLVMXRay.a
+@static-lib ${LLVM_BASE}/lib/libLLVMXtensaAsmParser.a
+@static-lib ${LLVM_BASE}/lib/libLLVMXtensaCodeGen.a
+@static-lib ${LLVM_BASE}/lib/libLLVMXtensaDesc.a
+@static-lib ${LLVM_BASE}/lib/libLLVMXtensaDisassembler.a
+@static-lib ${LLVM_BASE}/lib/libLLVMXtensaInfo.a
 @static-lib ${LLVM_BASE}/lib/libLLVMipo.a
 @lib ${LLVM_BASE}/lib/libLTO.so.${LIBLTO_VERSION}
 @lib ${LLVM_BASE}/lib/libRemarks.so.${LIBRemarks_VERSION}

And then build the LLVM 17 port (devel/llvm/17) as usual. Alternatively, you can download the pre-built package.


The M68k, CSKY, and DirectX targets appear to work fine. The ARC target segfaulted on some simple code, but that could have been me. I could not get the SPIRV or Xtensa targets to work: the SPIRV target appears to be missing some needed executable and I could not figure out an Xtensa target name that clang would accept. Overall, good enough for me; though I would like to know what target name clang is looking for with the Xtensa target.


Now I can run clang-17 -target m68k-unknown-openbsd7.4 -S file.c and get some m68k assembly back. Or I can run clang-17 -target m68k-unknown-openbsd7.4 -c file.c and get an object file back that I can query with llvm-objdump-17 and the other tools. Now, you probably don't want to use an obviously non-existent target (unless...), but it is nice to be able to do some development on these experimental targets. Unfortunately, LLD does not support either M68k or CSKY, so you'll still likely need the GNU binutils to have a complete development environment; anyone want to add support for these so we can get an OpenBSD/csky port going?