diff --git a/asm/MetroidPrime/CControlMapper.s b/asm/MetroidPrime/CControlMapper.s index 2c3f6e18..667aaf86 100644 --- a/asm/MetroidPrime/CControlMapper.s +++ b/asm/MetroidPrime/CControlMapper.s @@ -2083,9 +2083,9 @@ lbl_8000D734: /* 8000D74C 0000A6AC 38 84 E0 50 */ addi r4, r4, "__dt__Q24rstl21reserved_vectorFv"@l /* 8000D750 0000A6B0 38 A5 78 F8 */ addi r5, r5, lbl_804578F8@l /* 8000D754 0000A6B4 48 37 BF 39 */ bl __register_global_object -/* 8000D758 0000A6B8 3C 60 80 3E */ lis r3, lbl_803D8598@ha +/* 8000D758 0000A6B8 3C 60 80 3E */ lis r3, __ptmf_null@ha /* 8000D75C 0000A6BC 83 BF 00 68 */ lwz r29, 0x68(r31) -/* 8000D760 0000A6C0 38 63 85 98 */ addi r3, r3, lbl_803D8598@l +/* 8000D760 0000A6C0 38 63 85 98 */ addi r3, r3, __ptmf_null@l /* 8000D764 0000A6C4 3B 9F 01 08 */ addi r28, r31, 0x108 /* 8000D768 0000A6C8 80 03 00 04 */ lwz r0, 4(r3) /* 8000D76C 0000A6CC 93 A1 01 20 */ stw r29, 0x120(r1) diff --git a/asm/MetroidPrime/Enemies/CAi.s b/asm/MetroidPrime/Enemies/CAi.s index 0c2800ef..10b3290f 100644 --- a/asm/MetroidPrime/Enemies/CAi.s +++ b/asm/MetroidPrime/Enemies/CAi.s @@ -2347,8 +2347,8 @@ GetStateFunc__10CAiFuncMapCFPCc: /* 800A3218 000A0178 38 61 00 1C */ addi r3, r1, 0x1c /* 800A321C 000A017C 93 A1 00 44 */ stw r29, 0x44(r1) /* 800A3220 000A0180 80 04 00 04 */ lwz r0, 4(r4) -/* 800A3224 000A0184 3C 80 80 3E */ lis r4, lbl_803D8598@ha -/* 800A3228 000A0188 84 C4 85 98 */ lwzu r6, lbl_803D8598@l(r4) +/* 800A3224 000A0184 3C 80 80 3E */ lis r4, __ptmf_null@ha +/* 800A3228 000A0188 84 C4 85 98 */ lwzu r6, __ptmf_null@l(r4) /* 800A322C 000A018C 89 2D A2 C4 */ lbz r9, lbl_805A8E84@sda21(r13) /* 800A3230 000A0190 54 00 20 36 */ slwi r0, r0, 4 /* 800A3234 000A0194 81 1F 00 0C */ lwz r8, 0xc(r31) diff --git a/asm/MetroidPrime/Enemies/CStateMachine.s b/asm/MetroidPrime/Enemies/CStateMachine.s index c2d6a2ef..d5c05ac8 100644 --- a/asm/MetroidPrime/Enemies/CStateMachine.s +++ b/asm/MetroidPrime/Enemies/CStateMachine.s @@ -188,9 +188,9 @@ lbl_8007F840: /* 8007F858 0007C7B8 80 1C 00 2C */ lwz r0, 0x2c(r28) /* 8007F85C 0007C7BC 2C 00 00 00 */ cmpwi r0, 0 /* 8007F860 0007C7C0 41 82 03 0C */ beq lbl_8007FB6C -/* 8007F864 0007C7C4 3C 60 80 3E */ lis r3, lbl_803D8598@ha +/* 8007F864 0007C7C4 3C 60 80 3E */ lis r3, __ptmf_null@ha /* 8007F868 0007C7C8 C3 E2 89 80 */ lfs f31, lbl_805AA6A0@sda21(r2) -/* 8007F86C 0007C7CC 3A 23 85 98 */ addi r17, r3, lbl_803D8598@l +/* 8007F86C 0007C7CC 3A 23 85 98 */ addi r17, r3, __ptmf_null@l /* 8007F870 0007C7D0 3A 00 00 00 */ li r16, 0 /* 8007F874 0007C7D4 48 00 00 B4 */ b lbl_8007F928 lbl_8007F878: @@ -303,9 +303,9 @@ lbl_8007F9C0: /* 8007F9F8 0007C958 7C 00 00 34 */ cntlzw r0, r0 /* 8007F9FC 0007C95C 54 14 D9 7E */ srwi r20, r0, 5 /* 8007FA00 0007C960 40 80 00 D8 */ bge lbl_8007FAD8 -/* 8007FA04 0007C964 3C 80 80 3E */ lis r4, lbl_803D8598@ha +/* 8007FA04 0007C964 3C 80 80 3E */ lis r4, __ptmf_null@ha /* 8007FA08 0007C968 38 60 00 00 */ li r3, 0 -/* 8007FA0C 0007C96C 38 C4 85 98 */ addi r6, r4, lbl_803D8598@l +/* 8007FA0C 0007C96C 38 C4 85 98 */ addi r6, r4, __ptmf_null@l /* 8007FA10 0007C970 80 1E 00 14 */ lwz r0, 0x14(r30) /* 8007FA14 0007C974 80 FE 00 18 */ lwz r7, 0x18(r30) /* 8007FA18 0007C978 80 A6 00 00 */ lwz r5, 0(r6) @@ -862,4 +862,3 @@ lbl_803CD628: # ROM: 0x3CA628 .asciz "??(??)" .balign 4 - diff --git a/asm/Runtime/ptmf.s b/asm/Runtime/ptmf.s index a34733d9..ae2d2d3e 100644 --- a/asm/Runtime/ptmf.s +++ b/asm/Runtime/ptmf.s @@ -3,8 +3,8 @@ .section .rodata .balign 8 -.global lbl_803D8598 -lbl_803D8598: +.global __ptmf_null +__ptmf_null: .skip 16 .section .text, "ax" diff --git a/configure.py b/configure.py index 6224b14c..bd629f81 100755 --- a/configure.py +++ b/configure.py @@ -842,11 +842,11 @@ LIBS = [ "cflags": "$cflags_runtime", "objects": [ ["Runtime/__mem", True], - "Runtime/__va_arg", + ["Runtime/__va_arg", True], ["Runtime/global_destructor_chain", True], ["Runtime/CPlusLibPPC", True], "Runtime/NMWException", - "Runtime/ptmf", + ["Runtime/ptmf", True], "Runtime/runtime", ["Runtime/__init_cpp_exceptions", True], "Runtime/Gecko_ExceptionPPC", diff --git a/obj_files.mk b/obj_files.mk index d13d9045..0366d761 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -717,11 +717,11 @@ VI_FILES :=\ MSL_PPCEABI_BARE_H :=\ $(BUILD_DIR)/src/Runtime/__mem.o\ - $(BUILD_DIR)/asm/Runtime/__va_arg.o\ + $(BUILD_DIR)/src/Runtime/__va_arg.o\ $(BUILD_DIR)/src/Runtime/global_destructor_chain.o\ $(BUILD_DIR)/src/Runtime/CPlusLibPPC.o\ $(BUILD_DIR)/asm/Runtime/NMWException.o\ - $(BUILD_DIR)/asm/Runtime/ptmf.o\ + $(BUILD_DIR)/src/Runtime/ptmf.o\ $(BUILD_DIR)/asm/Runtime/runtime.o\ $(BUILD_DIR)/src/Runtime/__init_cpp_exceptions.o\ $(BUILD_DIR)/asm/Runtime/Gecko_ExceptionPPC.o\ diff --git a/src/Runtime/__va_arg.c b/src/Runtime/__va_arg.c new file mode 100644 index 00000000..fd0e182a --- /dev/null +++ b/src/Runtime/__va_arg.c @@ -0,0 +1,57 @@ +typedef struct { + char gpr; + char fpr; + char reserved[2]; + char* input_arg_area; + char* reg_save_area; +} va_list[1]; + +typedef enum { + ARGPOINTER, + WORD, + DOUBLEWORD, + REAL, +} _va_arg_type; + +#define ALIGN(addr, amount) (((unsigned int)(addr) + ((amount)-1)) & ~((amount)-1)) + +void* __va_arg(va_list ap, _va_arg_type type) { + char* addr; + char* curGprPtr = &(ap->gpr); + int curGpr = ap->gpr; + int max = 8; + int size = 4; + int inc = 1; + int even = 0; + int fprOffset = 0; + int regSize = 4; + + if (type == 3) { + curGprPtr = &(ap->fpr); + curGpr = ap->fpr; + size = 8; + fprOffset = 8 * 4; + regSize = 8; + } + if (type == 2) { + size = 8; + max = max - 1; + if (curGpr & 1) + even = 1; + inc = 2; + } + if (curGpr < max) { + curGpr += even; + addr = ap->reg_save_area + fprOffset + (curGpr * regSize); + *curGprPtr = curGpr + inc; + } else { + *curGprPtr = 8; + addr = ap->input_arg_area; + addr = (char*)ALIGN(addr, size); + ap->input_arg_area = addr + size; + } + if (type == ARGPOINTER) + addr = *((char**)addr); + + return addr; +} diff --git a/src/Runtime/ptmf.c b/src/Runtime/ptmf.c new file mode 100644 index 00000000..7561d2fb --- /dev/null +++ b/src/Runtime/ptmf.c @@ -0,0 +1,45 @@ + +typedef struct PTMF { + long this_delta; // delta to this pointer + long vtbl_offset; // offset in vtable (-1: not a virtual function) + union { + void* func_addr; // nonvirtual function address + long ventry_offset; // offset of virtual function entry in vtable + } func_data; +} PTMF; + +const PTMF __ptmf_null = { 0, 0, 0 }; + +/* clang-format off*/ +asm void __ptmf_test(register PTMF* ptmf) { + nofralloc + + lwz r5, PTMF.this_delta(ptmf) + lwz r6, PTMF.vtbl_offset(ptmf) + lwz r7, PTMF.func_data(ptmf) + li r3, 1 + cmpwi cr0, r5, 0 + cmpwi cr6, r6, 0 + cmpwi cr7, r7, 0 + bnelr cr0 + bnelr cr6 + bnelr cr7 + li r3, 0 + blr +} + +asm void __ptmf_scall(...) { + nofralloc + lwz r0, PTMF.this_delta(r12) + lwz r11, PTMF.vtbl_offset(r12) + lwz r12, PTMF.func_data(r12) + add r3, r3, r0 + cmpwi r11, 0 + blt @1 + lwzx r12, r3, r12 + lwzx r12, r12, r11 +@1 + mtctr r12 + bctr +} +/* clang-format - on*/