66# Licenced under Academic Free License version 2.0
77# Review ps2sdk README & LICENSE files for further details.
88
9- IOP_CC_VERSION := $(shell $(IOP_CC ) -dumpversion)
9+ # Comma definition for use in $(addprefix)
10+ comma := ,
1011
1112IOP_OBJS_DIR ?= obj/
1213IOP_SRC_DIR ?= src/
1314IOP_INC_DIR ?= include/
1415
15- ifeq ($(IOP_CC_VERSION ) ,3.2.2)
16- ASFLAGS_TARGET = -march=r3000
17- endif
18-
19- ifeq ($(IOP_CC_VERSION ) ,3.2.3)
20- ASFLAGS_TARGET = -march=r3000
21- endif
22-
2316# include dir
2417IOP_INCS := $(IOP_INCS ) -I$(IOP_SRC_DIR ) -I$(IOP_SRC_DIR ) include -I$(IOP_INC_DIR ) -I$(PS2SDKSRC ) /iop/kernel/include -I$(PS2SDKSRC ) /common/include
2518
@@ -33,6 +26,63 @@ IOP_OPTFLAGS ?= -Os
3326# Warning compiler flags
3427IOP_WARNFLAGS ?= -Wall -Werror
3528
29+ ifeq ($(IOP_USE_LLVM ) ,1)
30+ # =====================
31+ # LLVM/Clang settings
32+ # =====================
33+
34+ # Target flags for IOP (MIPS R3000 - 32-bit little endian)
35+ # -mabi=32: Use O32 ABI (standard 32-bit MIPS ABI)
36+ # -mno-abicalls: Match GCC's default non-PIC code generation
37+ IOP_TARGET_FLAGS := --target=mipsel-none-elf -march=mips1 -mcpu=mips1 -mabi=32 -mno-abicalls
38+
39+ # Debug information flags (LLVM compatible)
40+ IOP_DBGINFOFLAGS ?= -gdwarf-4
41+
42+ # C compiler flags for LLVM/Clang
43+ # -fno-builtin prevents built-in functions from being included
44+ # -msoft-float ensures software floating point (IOP has no FPU)
45+ # -G0 disables small data section optimization
46+ # -mno-explicit-relocs ensures paired HI16/LO16 relocations (required for IRX1 format)
47+ # -mllvm --mno-check-zero-division disables trap instructions for division by zero
48+ # (required because MIPS1 doesn't have trap instructions)
49+ # -Qunused-arguments silences warnings about unused arguments when used with linker
50+ # -U__mips -D__mips=1 fixes LLVM incorrectly setting __mips=32 for MIPS-I
51+ IOP_CFLAGS := $(IOP_TARGET_FLAGS ) -D_IOP -U__mips -D__mips=1 -ffreestanding -fno-builtin -fno-builtin-memset -fno-builtin-memcpy -fno-builtin-memmove -msoft-float -mno-explicit-relocs -G0 -fomit-frame-pointer -mllvm --mno-check-zero-division -Qunused-arguments $(IOP_OPTFLAGS ) $(IOP_WARNFLAGS ) $(IOP_DBGINFOFLAGS ) $(IOP_INCS ) $(IOP_CFLAGS )
52+ ifeq ($(DEBUG ) ,1)
53+ IOP_CFLAGS += -DDEBUG
54+ endif
55+
56+ # Import/export table flags for LLVM
57+ IOP_IETABLE_CFLAGS :=
58+
59+ # Linker flags for LLVM/Clang with LLD
60+ # -nostdlib: don't link standard libraries
61+ # -Wl,-r: create relocatable output
62+ # -Wl,--no-gc-sections: keep all sections
63+ IOP_LDFLAGS := -nostdlib -fuse-ld=lld -Wl,-r -Wl,--no-gc-sections $(IOP_LDFLAGS )
64+
65+ # Assembler flags for LLVM (using clang as assembler)
66+ IOP_ASFLAGS := $(IOP_TARGET_FLAGS ) -msoft-float $(IOP_ASFLAGS )
67+
68+ # Default link file for LLVM (LLD-compatible)
69+ IOP_LINKFILE_DEFAULT := $(PS2SDKSRC ) /iop/startup/src/linkfile.lld
70+
71+ else
72+ # =====================
73+ # GCC settings (default)
74+ # =====================
75+
76+ IOP_CC_VERSION := $(shell $(IOP_CC ) -dumpversion)
77+
78+ ifeq ($(IOP_CC_VERSION ) ,3.2.2)
79+ ASFLAGS_TARGET = -march=r3000
80+ endif
81+
82+ ifeq ($(IOP_CC_VERSION ) ,3.2.3)
83+ ASFLAGS_TARGET = -march=r3000
84+ endif
85+
3686# Debug information flags
3787IOP_DBGINFOFLAGS ?= -gdwarf-2 -gz
3888
@@ -73,10 +123,16 @@ endif
73123# Assembler flags
74124IOP_ASFLAGS := $(ASFLAGS_TARGET ) -EL -G0 $(IOP_ASFLAGS )
75125
126+ endif
127+
76128# Default link file
77129ifeq ($(IOP_LINKFILE ) ,)
130+ ifeq ($(IOP_USE_LLVM ) ,1)
131+ IOP_LINKFILE := $(PS2SDKSRC ) /iop/startup/src/linkfile.lld
132+ else
78133IOP_LINKFILE := $(PS2SDKSRC ) /iop/startup/src/linkfile
79134endif
135+ endif
80136
81137IOP_OBJS := $(IOP_OBJS:%=$(IOP_OBJS_DIR ) % )
82138
@@ -102,9 +158,17 @@ $(IOP_OBJS_DIR)%.o: $(IOP_SRC_DIR)%.S
102158 $(DIR_GUARD )
103159 $(IOP_C_COMPILE ) -c $< -o $@
104160
161+ ifeq ($(IOP_USE_LLVM ) ,1)
162+ # For LLVM, use clang as assembler (requires -c flag)
163+ $(IOP_OBJS_DIR ) % .o : $(IOP_SRC_DIR ) % .s
164+ $(DIR_GUARD )
165+ $(IOP_AS ) $(IOP_ASFLAGS ) -c $< -o $@
166+ else
167+ # For GCC, use binutils as (no -c flag needed)
105168$(IOP_OBJS_DIR ) % .o : $(IOP_SRC_DIR ) % .s
106169 $(DIR_GUARD )
107170 $(IOP_AS ) $(IOP_ASFLAGS ) $< -o $@
171+ endif
108172
109173.INTERMEDIATE :: $(IOP_LIB ) _tmp$(MAKE_CURPID ) $(IOP_OBJS_DIR ) build-imports.c $(IOP_OBJS_DIR ) build-exports.c
110174
@@ -137,14 +201,30 @@ $(IOP_OBJS_DIR)exports.o: $(IOP_OBJS_DIR)build-exports.c
137201 $(DIR_GUARD )
138202 $(IOP_C_COMPILE ) $(IOP_IETABLE_CFLAGS ) -c $< -o $@
139203
204+ ifeq ($(IOP_USE_LLVM ) ,1)
205+ # For LLVM, use clang as linker driver with lld
206+ $(IOP_BIN_ELF ) : $(IOP_OBJS ) $(IOP_LIB_ARCHIVES ) $(IOP_ADDITIONAL_DEPS )
207+ $(DIR_GUARD )
208+ $(IOP_C_COMPILE ) -Wl,-T,$(IOP_LINKFILE ) $(IOP_OPTFLAGS ) -o $@ $(IOP_OBJS ) $(IOP_LDFLAGS ) $(IOP_LIB_ARCHIVES ) $(IOP_LIBS )
209+ else
210+ # For GCC, use gcc as linker driver
140211$(IOP_BIN_ELF ) : $(IOP_OBJS ) $(IOP_LIB_ARCHIVES ) $(IOP_ADDITIONAL_DEPS )
141212 $(DIR_GUARD )
142213 $(IOP_C_COMPILE ) -T$(IOP_LINKFILE ) $(IOP_OPTFLAGS ) -o $@ $(IOP_OBJS ) $(IOP_LDFLAGS ) $(IOP_LIB_ARCHIVES ) $(IOP_LIBS )
214+ endif
143215
216+ ifeq ($(IOP_USE_LLVM ) ,1)
217+ # For LLVM, also remove LLVM-specific sections
218+ $(IOP_BIN_STRIPPED_ELF ) : $(IOP_BIN_ELF )
219+ $(DIR_GUARD )
220+ $(IOP_STRIP ) --strip-unneeded --remove-section=.pdr --remove-section=.comment --remove-section=.mdebug.abi32 --remove-section=.gnu.attributes --remove-section=.llvm_addrsig --remove-section=.note.GNU-stack -o $@ $<
221+ else
144222$(IOP_BIN_STRIPPED_ELF ) : $(IOP_BIN_ELF )
145223 $(DIR_GUARD )
146224 $(IOP_STRIP ) --strip-unneeded --remove-section=.pdr --remove-section=.comment --remove-section=.mdebug.abi32 --remove-section=.gnu.attributes -o $@ $<
225+ endif
147226
227+ # Use IRX1 format for both GCC and LLVM (IRX2 not supported by PS2 loadcore)
148228$(IOP_BIN ) : $(IOP_BIN_STRIPPED_ELF ) $(PS2SDKSRC ) /tools/srxfixup/bin/srxfixup
149229 $(PS2SDKSRC ) /tools/srxfixup/bin/srxfixup --irx1 -o $@ $<
150230
0 commit comments