summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira Akashi <rubenru09@aol.com>2021-05-15 00:18:51 +0100
committerGitHub <noreply@github.com>2021-05-15 00:18:51 +0100
commitbcf5b6ad0b36d49af906dd90a540a6bed98c2d61 (patch)
tree9723a5bda81a9611d262a8ad75f686d5eddaaa19
parent7c23a2eb8252a9c62d0a77d5c2bb79e22c8fc32f (diff)
parentf8eea1781835757af03f64e4493c3657ab2ff7f1 (diff)
Merge branch 'master' into render_begin_end_labels
-rw-r--r--.travis/calcrom/calcrom.cpp2
-rw-r--r--Makefile9
-rw-r--r--asm/GSvolume.s4
-rw-r--r--asm/SDK/MTX/vec.s8
-rw-r--r--asm/code_800400E8.s8
-rw-r--r--asm/code_801E6BF8.s2
-rw-r--r--asm/code_801EE044.s6
-rw-r--r--asm/code_801F40E0.s10
-rw-r--r--asm/code_80207C4C.s6
-rw-r--r--asm/code_8020B4F8.s4
-rw-r--r--asm/code_8020D250.s10
-rw-r--r--asm/code_8020F998.s6
-rw-r--r--asm/code_80213694.s12
-rw-r--r--asm/code_8021D424.s6
-rw-r--r--asm/code_80224B10.s4
-rw-r--r--asm/code_80232D24.s4
-rw-r--r--src/code_801DD8C0.cpp67
-rw-r--r--tools/pragma/LICENSE21
-rw-r--r--tools/pragma/README.md40
-rw-r--r--tools/pragma/pragma.py329
20 files changed, 444 insertions, 114 deletions
diff --git a/.travis/calcrom/calcrom.cpp b/.travis/calcrom/calcrom.cpp
index d9c589b..586561a 100644
--- a/.travis/calcrom/calcrom.cpp
+++ b/.travis/calcrom/calcrom.cpp
@@ -48,7 +48,7 @@ get_files(const char *fpath, const struct stat *sb,
if (tflag == FTW_F) {
string fpath_s(fpath);
string ext = fpath_s.substr(fpath_s.rfind('.'), 4);
- if (ext == ".c" || ext == ".cpp" || ".s")
+ if (ext == ".c" || ext == ".cpp" || ext == ".s")
files.push_back(fpath_s);
}
return 0;
diff --git a/Makefile b/Makefile
index 69b7c42..876487d 100644
--- a/Makefile
+++ b/Makefile
@@ -84,12 +84,13 @@ SHA1SUM := sha1sum
PYTHON := python3
POSTPROC := tools/postprocess/postprocess.py
+PRAGMAPROC := tools/pragma/pragma.py
# Options
INCLUDES := -i . -I- -i include -i include/SDK -i include/MSL_C -include include/types.h
ASFLAGS := -mgekko -I include
LDFLAGS := -map $(MAP) -fp hard -nodefaults
-CFLAGS := -Cpp_exceptions off -proc gekko -fp hard -O4,p -nodefaults -msgstyle gcc -ipa file $(INCLUDES) -W all
+CFLAGS := -Cpp_exceptions off -proc gekko -fp hard -O4,p -nodefaults -msgstyle gcc -ipa file $(INCLUDES) -W all -w nopragmas
# for postprocess.py
PROCFLAGS := -fsymbol-fixup
@@ -101,7 +102,7 @@ SBSS_PDHR := 10
infoshell = $(foreach line, $(shell $1 | sed "s/ /__SPACE__/g"), $(info $(subst __SPACE__, ,$(line))))
TOOLS_DIR = tools
-TOOLDIRS = $(filter-out $(TOOLS_DIR)/mwcc_compiler $(TOOLS_DIR)/postprocess,$(wildcard $(TOOLS_DIR)/*))
+TOOLDIRS = $(filter-out $(TOOLS_DIR)/mwcc_compiler $(TOOLS_DIR)/postprocess $(TOOLS_DIR)/pragma,$(wildcard $(TOOLS_DIR)/*))
TOOLBASE = $(TOOLDIRS:$(TOOLS_DIR)/%=%)
TOOLS = $(foreach tool,$(TOOLBASE),$(TOOLS_DIR)/$(tool)/$(tool)$(EXE))
@@ -154,7 +155,7 @@ $(BUILD_DIR)/%.o: %.s
$(PYTHON) $(POSTPROC) $(PROCFLAGS) $@
$(BUILD_DIR)/%.o: %.cpp
- $(CC) $(CFLAGS) -lang c++ -c -o $@ $<
+ $(PYTHON) $(PRAGMAPROC) "$(CC)" "$(CFLAGS) -lang c++ -c" $@ $<
$(BUILD_DIR)/%.o: %.c
- $(CC) $(CFLAGS) -lang c99 -c -o $@ $<
+ $(PYTHON) $(PRAGMAPROC) "$(CC)" "$(CFLAGS) -lang c99 -c" $@ $<
diff --git a/asm/GSvolume.s b/asm/GSvolume.s
index 7cfe0d3..e29a47b 100644
--- a/asm/GSvolume.s
+++ b/asm/GSvolume.s
@@ -1528,7 +1528,7 @@ lbl_801E05C4:
/* 801E05F8 001DC258 D0 01 00 6C */ stfs f0, 0x6c(r1)
/* 801E05FC 001DC25C C0 05 00 08 */ lfs f0, 8(r5)
/* 801E0600 001DC260 D0 01 00 70 */ stfs f0, 0x70(r1)
-/* 801E0604 001DC264 48 09 C7 C5 */ bl PSQUATDotProduct
+/* 801E0604 001DC264 48 09 C7 C5 */ bl PSVECDotProduct
/* 801E0608 001DC268 FC 01 F8 40 */ fcmpo cr0, f1, f31
/* 801E060C 001DC26C FF C0 08 90 */ fmr f30, f1
/* 801E0610 001DC270 4C 41 13 82 */ cror 2, 1, 2
@@ -1553,7 +1553,7 @@ lbl_801E064C:
/* 801E0658 001DC2B8 48 09 C6 91 */ bl PSVECSubtract
/* 801E065C 001DC2BC 38 61 00 50 */ addi r3, r1, 0x50
/* 801E0660 001DC2C0 38 81 00 68 */ addi r4, r1, 0x68
-/* 801E0664 001DC2C4 48 09 C7 65 */ bl PSQUATDotProduct
+/* 801E0664 001DC2C4 48 09 C7 65 */ bl PSVECDotProduct
/* 801E0668 001DC2C8 FC 01 F8 40 */ fcmpo cr0, f1, f31
/* 801E066C 001DC2CC 41 81 01 1C */ bgt lbl_801E0788
/* 801E0670 001DC2D0 FC 01 F0 40 */ fcmpo cr0, f1, f30
diff --git a/asm/SDK/MTX/vec.s b/asm/SDK/MTX/vec.s
index ba5f316..3031b5f 100644
--- a/asm/SDK/MTX/vec.s
+++ b/asm/SDK/MTX/vec.s
@@ -85,8 +85,8 @@ PSVECMag:
/* 8027CDC0 00278A20 EC 21 00 32 */ fmuls f1, f1, f0
/* 8027CDC4 00278A24 4E 80 00 20 */ blr
-.global PSQUATDotProduct
-PSQUATDotProduct:
+.global PSVECDotProduct
+PSVECDotProduct:
/* 8027CDC8 00278A28 E0 43 00 04 */ psq_l f2, 4(r3), 0, qr0
/* 8027CDCC 00278A2C E0 64 00 04 */ psq_l f3, 4(r4), 0, qr0
/* 8027CDD0 00278A30 10 42 00 F2 */ ps_mul f2, f2, f3
@@ -151,7 +151,7 @@ C_VECHalfAngle:
/* 8027CEA4 00278B04 4B FF FE 21 */ bl PSVECAdd
/* 8027CEA8 00278B08 38 61 00 08 */ addi r3, r1, 8
/* 8027CEAC 00278B0C 7C 64 1B 78 */ mr r4, r3
-/* 8027CEB0 00278B10 4B FF FF 19 */ bl PSQUATDotProduct
+/* 8027CEB0 00278B10 4B FF FF 19 */ bl PSVECDotProduct
/* 8027CEB4 00278B14 C0 02 A0 B0 */ lfs f0, lbl_806426B0-_SDA2_BASE_(r2)
/* 8027CEB8 00278B18 FC 01 00 40 */ fcmpo cr0, f1, f0
/* 8027CEBC 00278B1C 40 81 00 14 */ ble lbl_8027CED0
@@ -199,7 +199,7 @@ C_VECReflect:
/* 8027CF50 00278BB0 4B FF FD D9 */ bl PSVECNormalize
/* 8027CF54 00278BB4 38 61 00 14 */ addi r3, r1, 0x14
/* 8027CF58 00278BB8 38 81 00 08 */ addi r4, r1, 8
-/* 8027CF5C 00278BBC 4B FF FE 6D */ bl PSQUATDotProduct
+/* 8027CF5C 00278BBC 4B FF FE 6D */ bl PSVECDotProduct
/* 8027CF60 00278BC0 C0 62 A0 B4 */ lfs f3, lbl_806426B4-_SDA2_BASE_(r2)
/* 8027CF64 00278BC4 7F E3 FB 78 */ mr r3, r31
/* 8027CF68 00278BC8 C0 41 00 08 */ lfs f2, 8(r1)
diff --git a/asm/code_800400E8.s b/asm/code_800400E8.s
index c190445..b371b51 100644
--- a/asm/code_800400E8.s
+++ b/asm/code_800400E8.s
@@ -2259,13 +2259,13 @@ func_80041ED4:
/* 80041F6C 0003DBCC 48 23 AD BD */ bl PSVECNormalize
/* 80041F70 0003DBD0 38 61 00 5C */ addi r3, r1, 0x5c
/* 80041F74 0003DBD4 38 81 00 68 */ addi r4, r1, 0x68
-/* 80041F78 0003DBD8 48 23 AE 51 */ bl PSQUATDotProduct
+/* 80041F78 0003DBD8 48 23 AE 51 */ bl PSVECDotProduct
/* 80041F7C 0003DBDC C8 42 83 30 */ lfd f2, lbl_80640930-_SDA2_BASE_(r2)
/* 80041F80 0003DBE0 48 19 26 65 */ bl pow
/* 80041F84 0003DBE4 FF C0 08 18 */ frsp f30, f1
/* 80041F88 0003DBE8 38 61 00 68 */ addi r3, r1, 0x68
/* 80041F8C 0003DBEC 7C 64 1B 78 */ mr r4, r3
-/* 80041F90 0003DBF0 48 23 AE 39 */ bl PSQUATDotProduct
+/* 80041F90 0003DBF0 48 23 AE 39 */ bl PSVECDotProduct
/* 80041F94 0003DBF4 FF E0 08 90 */ fmr f31, f1
/* 80041F98 0003DBF8 C8 22 83 38 */ lfd f1, lbl_80640938-_SDA2_BASE_(r2)
/* 80041F9C 0003DBFC C8 42 83 30 */ lfd f2, lbl_80640930-_SDA2_BASE_(r2)
@@ -2284,7 +2284,7 @@ lbl_80041FC4:
lbl_80041FCC:
/* 80041FCC 0003DC2C 38 61 00 5C */ addi r3, r1, 0x5c
/* 80041FD0 0003DC30 38 81 00 68 */ addi r4, r1, 0x68
-/* 80041FD4 0003DC34 48 23 AD F5 */ bl PSQUATDotProduct
+/* 80041FD4 0003DC34 48 23 AD F5 */ bl PSVECDotProduct
/* 80041FD8 0003DC38 C0 1E 00 00 */ lfs f0, 0(r30)
/* 80041FDC 0003DC3C FC 20 08 50 */ fneg f1, f1
/* 80041FE0 0003DC40 7F E3 FB 78 */ mr r3, r31
@@ -4983,7 +4983,7 @@ lbl_800445F0:
/* 800446C4 00040324 D0 41 00 38 */ stfs f2, 0x38(r1)
/* 800446C8 00040328 D0 21 00 3C */ stfs f1, 0x3c(r1)
/* 800446CC 0004032C D0 01 00 40 */ stfs f0, 0x40(r1)
-/* 800446D0 00040330 48 23 86 F9 */ bl PSQUATDotProduct
+/* 800446D0 00040330 48 23 86 F9 */ bl PSVECDotProduct
/* 800446D4 00040334 FC 01 F8 40 */ fcmpo cr0, f1, f31
/* 800446D8 00040338 4C 40 13 82 */ cror 2, 0, 2
/* 800446DC 0004033C 40 82 00 40 */ bne lbl_8004471C
diff --git a/asm/code_801E6BF8.s b/asm/code_801E6BF8.s
index ed0a118..a0eec77 100644
--- a/asm/code_801E6BF8.s
+++ b/asm/code_801E6BF8.s
@@ -2583,7 +2583,7 @@ lbl_801E91E4:
/* 801E9250 001E4EB0 48 09 3B 99 */ bl PSVECCrossProduct
/* 801E9254 001E4EB4 38 61 00 14 */ addi r3, r1, 0x14
/* 801E9258 001E4EB8 38 81 00 20 */ addi r4, r1, 0x20
-/* 801E925C 001E4EBC 48 09 3B 6D */ bl PSQUATDotProduct
+/* 801E925C 001E4EBC 48 09 3B 6D */ bl PSVECDotProduct
/* 801E9260 001E4EC0 C0 02 97 98 */ lfs f0, lbl_80641D98-_SDA2_BASE_(r2)
/* 801E9264 001E4EC4 FC 01 00 40 */ fcmpo cr0, f1, f0
/* 801E9268 001E4EC8 4C 41 13 82 */ cror 2, 1, 2
diff --git a/asm/code_801EE044.s b/asm/code_801EE044.s
index 7ce6fa1..27940a4 100644
--- a/asm/code_801EE044.s
+++ b/asm/code_801EE044.s
@@ -1177,7 +1177,7 @@ lbl_801EF10C:
/* 801EF130 001EAD90 D0 41 00 40 */ stfs f2, 0x40(r1)
/* 801EF134 001EAD94 D0 21 00 44 */ stfs f1, 0x44(r1)
/* 801EF138 001EAD98 D0 01 00 48 */ stfs f0, 0x48(r1)
-/* 801EF13C 001EAD9C 48 08 DC 8D */ bl PSQUATDotProduct
+/* 801EF13C 001EAD9C 48 08 DC 8D */ bl PSVECDotProduct
/* 801EF140 001EADA0 EC 21 F0 24 */ fdivs f1, f1, f30
/* 801EF144 001EADA4 7F 44 D3 78 */ mr r4, r26
/* 801EF148 001EADA8 38 61 00 30 */ addi r3, r1, 0x30
@@ -1328,7 +1328,7 @@ lbl_801EF350:
/* 801EF35C 001EAFBC 48 08 D9 8D */ bl PSVECSubtract
/* 801EF360 001EAFC0 7F E3 FB 78 */ mr r3, r31
/* 801EF364 001EAFC4 7F 24 CB 78 */ mr r4, r25
-/* 801EF368 001EAFC8 48 08 DA 61 */ bl PSQUATDotProduct
+/* 801EF368 001EAFC8 48 08 DA 61 */ bl PSVECDotProduct
/* 801EF36C 001EAFCC EC 21 F0 24 */ fdivs f1, f1, f30
/* 801EF370 001EAFD0 7F 44 D3 78 */ mr r4, r26
/* 801EF374 001EAFD4 38 61 00 38 */ addi r3, r1, 0x38
@@ -4119,7 +4119,7 @@ lbl_801F1A20:
/* 801F1A2C 001ED68C 48 08 B2 BD */ bl PSVECSubtract
/* 801F1A30 001ED690 7F E4 FB 78 */ mr r4, r31
/* 801F1A34 001ED694 38 61 00 14 */ addi r3, r1, 0x14
-/* 801F1A38 001ED698 48 08 B3 91 */ bl PSQUATDotProduct
+/* 801F1A38 001ED698 48 08 B3 91 */ bl PSVECDotProduct
/* 801F1A3C 001ED69C 80 7D 01 64 */ lwz r3, 0x164(r29)
/* 801F1A40 001ED6A0 83 E1 00 2C */ lwz r31, 0x2c(r1)
/* 801F1A44 001ED6A4 80 63 00 20 */ lwz r3, 0x20(r3)
diff --git a/asm/code_801F40E0.s b/asm/code_801F40E0.s
index 98f6996..3f1a624 100644
--- a/asm/code_801F40E0.s
+++ b/asm/code_801F40E0.s
@@ -3325,15 +3325,15 @@ lbl_801F6CD0:
lbl_801F6D40:
/* 801F6D40 001F29A0 7F 43 D3 78 */ mr r3, r26
/* 801F6D44 001F29A4 38 81 01 04 */ addi r4, r1, 0x104
-/* 801F6D48 001F29A8 48 08 60 81 */ bl PSQUATDotProduct
+/* 801F6D48 001F29A8 48 08 60 81 */ bl PSVECDotProduct
/* 801F6D4C 001F29AC D0 21 00 EC */ stfs f1, 0xec(r1)
/* 801F6D50 001F29B0 7F 43 D3 78 */ mr r3, r26
/* 801F6D54 001F29B4 38 81 00 F8 */ addi r4, r1, 0xf8
-/* 801F6D58 001F29B8 48 08 60 71 */ bl PSQUATDotProduct
+/* 801F6D58 001F29B8 48 08 60 71 */ bl PSVECDotProduct
/* 801F6D5C 001F29BC D0 21 00 F0 */ stfs f1, 0xf0(r1)
/* 801F6D60 001F29C0 7F 43 D3 78 */ mr r3, r26
/* 801F6D64 001F29C4 38 81 01 10 */ addi r4, r1, 0x110
-/* 801F6D68 001F29C8 48 08 60 61 */ bl PSQUATDotProduct
+/* 801F6D68 001F29C8 48 08 60 61 */ bl PSVECDotProduct
/* 801F6D6C 001F29CC C0 41 00 EC */ lfs f2, 0xec(r1)
/* 801F6D70 001F29D0 C0 01 00 C8 */ lfs f0, 0xc8(r1)
/* 801F6D74 001F29D4 D0 21 00 F4 */ stfs f1, 0xf4(r1)
@@ -3673,7 +3673,7 @@ lbl_801F7204:
/* 801F7234 001F2E94 48 08 5A B5 */ bl PSVECSubtract
/* 801F7238 001F2E98 38 61 00 20 */ addi r3, r1, 0x20
/* 801F723C 001F2E9C 38 81 01 10 */ addi r4, r1, 0x110
-/* 801F7240 001F2EA0 48 08 5B 89 */ bl PSQUATDotProduct
+/* 801F7240 001F2EA0 48 08 5B 89 */ bl PSVECDotProduct
/* 801F7244 001F2EA4 EF 81 E0 28 */ fsubs f28, f1, f28
/* 801F7248 001F2EA8 C0 02 98 00 */ lfs f0, lbl_80641E00-_SDA2_BASE_(r2)
/* 801F724C 001F2EAC FC 1C 00 40 */ fcmpo cr0, f28, f0
@@ -6188,7 +6188,7 @@ lbl_801F9590:
/* 801F959C 001F51FC 48 08 37 4D */ bl PSVECSubtract
/* 801F95A0 001F5200 7F E4 FB 78 */ mr r4, r31
/* 801F95A4 001F5204 38 61 00 14 */ addi r3, r1, 0x14
-/* 801F95A8 001F5208 48 08 38 21 */ bl PSQUATDotProduct
+/* 801F95A8 001F5208 48 08 38 21 */ bl PSVECDotProduct
/* 801F95AC 001F520C 80 7D 00 04 */ lwz r3, 4(r29)
/* 801F95B0 001F5210 83 E1 00 2C */ lwz r31, 0x2c(r1)
/* 801F95B4 001F5214 80 63 00 18 */ lwz r3, 0x18(r3)
diff --git a/asm/code_80207C4C.s b/asm/code_80207C4C.s
index fd1a480..1421850 100644
--- a/asm/code_80207C4C.s
+++ b/asm/code_80207C4C.s
@@ -3660,7 +3660,7 @@ lbl_8020AEDC:
/* 8020AEE8 00206B48 48 07 1E 01 */ bl PSVECSubtract
/* 8020AEEC 00206B4C 38 7F 22 3C */ addi r3, r31, 0x223c
/* 8020AEF0 00206B50 38 81 00 14 */ addi r4, r1, 0x14
-/* 8020AEF4 00206B54 48 07 1E D5 */ bl PSQUATDotProduct
+/* 8020AEF4 00206B54 48 07 1E D5 */ bl PSVECDotProduct
/* 8020AEF8 00206B58 FF E0 08 90 */ fmr f31, f1
/* 8020AEFC 00206B5C 83 9D 00 2C */ lwz r28, 0x2c(r29)
/* 8020AF00 00206B60 7F BB EB 78 */ mr r27, r29
@@ -3672,7 +3672,7 @@ lbl_8020AF08:
/* 8020AF14 00206B74 48 07 1D D5 */ bl PSVECSubtract
/* 8020AF18 00206B78 38 7F 22 3C */ addi r3, r31, 0x223c
/* 8020AF1C 00206B7C 38 81 00 08 */ addi r4, r1, 8
-/* 8020AF20 00206B80 48 07 1E A9 */ bl PSQUATDotProduct
+/* 8020AF20 00206B80 48 07 1E A9 */ bl PSVECDotProduct
/* 8020AF24 00206B84 FC 01 F8 40 */ fcmpo cr0, f1, f31
/* 8020AF28 00206B88 4C 41 13 82 */ cror 2, 1, 2
/* 8020AF2C 00206B8C 41 82 00 14 */ beq lbl_8020AF40
@@ -3846,7 +3846,7 @@ lbl_8020B17C:
/* 8020B17C 00206DDC 3C 60 80 49 */ lis r3, lbl_80493620@ha
/* 8020B180 00206DE0 7F C4 F3 78 */ mr r4, r30
/* 8020B184 00206DE4 38 63 36 20 */ addi r3, r3, lbl_80493620@l
-/* 8020B188 00206DE8 48 07 1C 41 */ bl PSQUATDotProduct
+/* 8020B188 00206DE8 48 07 1C 41 */ bl PSVECDotProduct
/* 8020B18C 00206DEC C0 02 99 9C */ lfs f0, lbl_80641F9C-_SDA2_BASE_(r2)
/* 8020B190 00206DF0 FC 01 00 40 */ fcmpo cr0, f1, f0
/* 8020B194 00206DF4 4C 41 13 82 */ cror 2, 1, 2
diff --git a/asm/code_8020B4F8.s b/asm/code_8020B4F8.s
index 4859ddc..e3b8187 100644
--- a/asm/code_8020B4F8.s
+++ b/asm/code_8020B4F8.s
@@ -1452,7 +1452,7 @@ lbl_8020C914:
/* 8020C920 00208580 48 07 03 C9 */ bl PSVECSubtract
/* 8020C924 00208584 38 7F 22 3C */ addi r3, r31, 0x223c
/* 8020C928 00208588 38 81 00 14 */ addi r4, r1, 0x14
-/* 8020C92C 0020858C 48 07 04 9D */ bl PSQUATDotProduct
+/* 8020C92C 0020858C 48 07 04 9D */ bl PSVECDotProduct
/* 8020C930 00208590 FF E0 08 90 */ fmr f31, f1
/* 8020C934 00208594 83 9D 00 2C */ lwz r28, 0x2c(r29)
/* 8020C938 00208598 7F BB EB 78 */ mr r27, r29
@@ -1464,7 +1464,7 @@ lbl_8020C940:
/* 8020C94C 002085AC 48 07 03 9D */ bl PSVECSubtract
/* 8020C950 002085B0 38 7F 22 3C */ addi r3, r31, 0x223c
/* 8020C954 002085B4 38 81 00 08 */ addi r4, r1, 8
-/* 8020C958 002085B8 48 07 04 71 */ bl PSQUATDotProduct
+/* 8020C958 002085B8 48 07 04 71 */ bl PSVECDotProduct
/* 8020C95C 002085BC FC 01 F8 40 */ fcmpo cr0, f1, f31
/* 8020C960 002085C0 4C 41 13 82 */ cror 2, 1, 2
/* 8020C964 002085C4 41 82 00 14 */ beq lbl_8020C978
diff --git a/asm/code_8020D250.s b/asm/code_8020D250.s
index 3088a25..7debc42 100644
--- a/asm/code_8020D250.s
+++ b/asm/code_8020D250.s
@@ -561,7 +561,7 @@ func_8020D9F0:
/* 8020DA3C 0020969C 3C 60 80 49 */ lis r3, lbl_8049223C@ha
/* 8020DA40 002096A0 38 81 00 90 */ addi r4, r1, 0x90
/* 8020DA44 002096A4 38 63 22 3C */ addi r3, r3, lbl_8049223C@l
-/* 8020DA48 002096A8 48 06 F3 81 */ bl PSQUATDotProduct
+/* 8020DA48 002096A8 48 06 F3 81 */ bl PSVECDotProduct
/* 8020DA4C 002096AC C0 42 9A 38 */ lfs f2, lbl_80642038-_SDA2_BASE_(r2)
/* 8020DA50 002096B0 C0 0D A1 CC */ lfs f0, lbl_8063F48C-_SDA_BASE_(r13)
/* 8020DA54 002096B4 EC 02 00 2A */ fadds f0, f2, f0
@@ -974,7 +974,7 @@ lbl_8020DF98:
/* 8020E038 00209C98 48 01 59 D5 */ bl func_80223A0C
/* 8020E03C 00209C9C 38 61 01 08 */ addi r3, r1, 0x108
/* 8020E040 00209CA0 38 81 00 D8 */ addi r4, r1, 0xd8
-/* 8020E044 00209CA4 48 06 ED 85 */ bl PSQUATDotProduct
+/* 8020E044 00209CA4 48 06 ED 85 */ bl PSVECDotProduct
/* 8020E048 00209CA8 38 61 01 08 */ addi r3, r1, 0x108
/* 8020E04C 00209CAC 7C 64 1B 78 */ mr r4, r3
/* 8020E050 00209CB0 48 06 EC BD */ bl PSVECScale
@@ -1009,7 +1009,7 @@ lbl_8020DF98:
/* 8020E0C4 00209D24 48 01 59 49 */ bl func_80223A0C
/* 8020E0C8 00209D28 38 61 00 FC */ addi r3, r1, 0xfc
/* 8020E0CC 00209D2C 38 81 00 D8 */ addi r4, r1, 0xd8
-/* 8020E0D0 00209D30 48 06 EC F9 */ bl PSQUATDotProduct
+/* 8020E0D0 00209D30 48 06 EC F9 */ bl PSVECDotProduct
/* 8020E0D4 00209D34 38 61 00 FC */ addi r3, r1, 0xfc
/* 8020E0D8 00209D38 7C 64 1B 78 */ mr r4, r3
/* 8020E0DC 00209D3C 48 06 EC 31 */ bl PSVECScale
@@ -1610,7 +1610,7 @@ lbl_8020E954:
/* 8020E960 0020A5C0 48 06 E3 89 */ bl PSVECSubtract
/* 8020E964 0020A5C4 38 7F 22 3C */ addi r3, r31, 0x223c
/* 8020E968 0020A5C8 38 81 00 14 */ addi r4, r1, 0x14
-/* 8020E96C 0020A5CC 48 06 E4 5D */ bl PSQUATDotProduct
+/* 8020E96C 0020A5CC 48 06 E4 5D */ bl PSVECDotProduct
/* 8020E970 0020A5D0 FF E0 08 90 */ fmr f31, f1
/* 8020E974 0020A5D4 83 9D 00 2C */ lwz r28, 0x2c(r29)
/* 8020E978 0020A5D8 7F BB EB 78 */ mr r27, r29
@@ -1622,7 +1622,7 @@ lbl_8020E980:
/* 8020E98C 0020A5EC 48 06 E3 5D */ bl PSVECSubtract
/* 8020E990 0020A5F0 38 7F 22 3C */ addi r3, r31, 0x223c
/* 8020E994 0020A5F4 38 81 00 08 */ addi r4, r1, 8
-/* 8020E998 0020A5F8 48 06 E4 31 */ bl PSQUATDotProduct
+/* 8020E998 0020A5F8 48 06 E4 31 */ bl PSVECDotProduct
/* 8020E99C 0020A5FC FC 01 F8 40 */ fcmpo cr0, f1, f31
/* 8020E9A0 0020A600 4C 41 13 82 */ cror 2, 1, 2
/* 8020E9A4 0020A604 41 82 00 14 */ beq lbl_8020E9B8
diff --git a/asm/code_8020F998.s b/asm/code_8020F998.s
index 30fdbe4..d05581e 100644
--- a/asm/code_8020F998.s
+++ b/asm/code_8020F998.s
@@ -790,7 +790,7 @@ func_80210450:
/* 802104A4 0020C104 3C 60 80 49 */ lis r3, lbl_8049223C@ha
/* 802104A8 0020C108 38 81 00 0C */ addi r4, r1, 0xc
/* 802104AC 0020C10C 38 63 22 3C */ addi r3, r3, lbl_8049223C@l
-/* 802104B0 0020C110 48 06 C9 19 */ bl PSQUATDotProduct
+/* 802104B0 0020C110 48 06 C9 19 */ bl PSVECDotProduct
/* 802104B4 0020C114 FF E0 08 90 */ fmr f31, f1
/* 802104B8 0020C118 38 7D 00 4C */ addi r3, r29, 0x4c
/* 802104BC 0020C11C 48 06 C8 C9 */ bl PSVECMag
@@ -1853,7 +1853,7 @@ lbl_80211440:
/* 8021144C 0020D0AC 48 06 B8 9D */ bl PSVECSubtract
/* 80211450 0020D0B0 38 7F 22 3C */ addi r3, r31, 0x223c
/* 80211454 0020D0B4 38 81 00 14 */ addi r4, r1, 0x14
-/* 80211458 0020D0B8 48 06 B9 71 */ bl PSQUATDotProduct
+/* 80211458 0020D0B8 48 06 B9 71 */ bl PSVECDotProduct
/* 8021145C 0020D0BC FF E0 08 90 */ fmr f31, f1
/* 80211460 0020D0C0 83 9D 00 2C */ lwz r28, 0x2c(r29)
/* 80211464 0020D0C4 7F BB EB 78 */ mr r27, r29
@@ -1865,7 +1865,7 @@ lbl_8021146C:
/* 80211478 0020D0D8 48 06 B8 71 */ bl PSVECSubtract
/* 8021147C 0020D0DC 38 7F 22 3C */ addi r3, r31, 0x223c
/* 80211480 0020D0E0 38 81 00 08 */ addi r4, r1, 8
-/* 80211484 0020D0E4 48 06 B9 45 */ bl PSQUATDotProduct
+/* 80211484 0020D0E4 48 06 B9 45 */ bl PSVECDotProduct
/* 80211488 0020D0E8 FC 01 F8 40 */ fcmpo cr0, f1, f31
/* 8021148C 0020D0EC 4C 41 13 82 */ cror 2, 1, 2
/* 80211490 0020D0F0 41 82 00 14 */ beq lbl_802114A4
diff --git a/asm/code_80213694.s b/asm/code_80213694.s
index 3641e79..ea7193e 100644
--- a/asm/code_80213694.s
+++ b/asm/code_80213694.s
@@ -3842,7 +3842,7 @@ lbl_80216E2C:
/* 80216E34 00212A94 48 06 5E F5 */ bl PSVECNormalize
/* 80216E38 00212A98 7F C3 F3 78 */ mr r3, r30
/* 80216E3C 00212A9C 7F E4 FB 78 */ mr r4, r31
-/* 80216E40 00212AA0 48 06 5F 89 */ bl PSQUATDotProduct
+/* 80216E40 00212AA0 48 06 5F 89 */ bl PSVECDotProduct
/* 80216E44 00212AA4 C0 42 9B 3C */ lfs f2, lbl_8064213C-_SDA2_BASE_(r2)
/* 80216E48 00212AA8 FC 01 10 40 */ fcmpo cr0, f1, f2
/* 80216E4C 00212AAC 4C 41 13 82 */ cror 2, 1, 2
@@ -4266,7 +4266,7 @@ lbl_8021738C:
/* 80217434 00213094 48 06 58 F5 */ bl PSVECNormalize
/* 80217438 00213098 38 61 00 2C */ addi r3, r1, 0x2c
/* 8021743C 0021309C 38 81 00 20 */ addi r4, r1, 0x20
-/* 80217440 002130A0 48 06 59 89 */ bl PSQUATDotProduct
+/* 80217440 002130A0 48 06 59 89 */ bl PSVECDotProduct
/* 80217444 002130A4 FC 00 0A 10 */ fabs f0, f1
/* 80217448 002130A8 80 78 00 00 */ lwz r3, 0(r24)
/* 8021744C 002130AC C0 43 00 D0 */ lfs f2, 0xd0(r3)
@@ -4297,7 +4297,7 @@ lbl_80217464:
/* 802174A8 00213108 48 06 58 81 */ bl PSVECNormalize
/* 802174AC 0021310C 38 61 00 2C */ addi r3, r1, 0x2c
/* 802174B0 00213110 38 81 00 20 */ addi r4, r1, 0x20
-/* 802174B4 00213114 48 06 59 15 */ bl PSQUATDotProduct
+/* 802174B4 00213114 48 06 59 15 */ bl PSVECDotProduct
/* 802174B8 00213118 FC 00 0A 10 */ fabs f0, f1
/* 802174BC 0021311C 80 78 00 00 */ lwz r3, 0(r24)
/* 802174C0 00213120 C0 43 00 D0 */ lfs f2, 0xd0(r3)
@@ -4355,7 +4355,7 @@ lbl_80217520:
/* 80217580 002131E0 48 06 57 A9 */ bl PSVECNormalize
/* 80217584 002131E4 38 61 00 14 */ addi r3, r1, 0x14
/* 80217588 002131E8 38 81 00 20 */ addi r4, r1, 0x20
-/* 8021758C 002131EC 48 06 58 3D */ bl PSQUATDotProduct
+/* 8021758C 002131EC 48 06 58 3D */ bl PSVECDotProduct
/* 80217590 002131F0 FC 01 D8 40 */ fcmpo cr0, f1, f27
/* 80217594 002131F4 4C 41 13 82 */ cror 2, 1, 2
/* 80217598 002131F8 40 82 00 0C */ bne lbl_802175A4
@@ -4381,7 +4381,7 @@ lbl_802175C0:
/* 802175DC 0021323C 48 06 54 75 */ bl PSMTXMultVecSR
/* 802175E0 00213240 38 61 00 2C */ addi r3, r1, 0x2c
/* 802175E4 00213244 38 81 00 20 */ addi r4, r1, 0x20
-/* 802175E8 00213248 48 06 57 E1 */ bl PSQUATDotProduct
+/* 802175E8 00213248 48 06 57 E1 */ bl PSVECDotProduct
/* 802175EC 0021324C FC 00 0A 10 */ fabs f0, f1
/* 802175F0 00213250 80 78 00 00 */ lwz r3, 0(r24)
/* 802175F4 00213254 C0 43 00 D0 */ lfs f2, 0xd0(r3)
@@ -4408,7 +4408,7 @@ lbl_8021760C:
/* 80217640 002132A0 48 06 56 E9 */ bl PSVECNormalize
/* 80217644 002132A4 38 61 00 2C */ addi r3, r1, 0x2c
/* 80217648 002132A8 38 81 00 20 */ addi r4, r1, 0x20
-/* 8021764C 002132AC 48 06 57 7D */ bl PSQUATDotProduct
+/* 8021764C 002132AC 48 06 57 7D */ bl PSVECDotProduct
/* 80217650 002132B0 FC 00 0A 10 */ fabs f0, f1
/* 80217654 002132B4 80 78 00 00 */ lwz r3, 0(r24)
/* 80217658 002132B8 C0 43 00 D0 */ lfs f2, 0xd0(r3)
diff --git a/asm/code_8021D424.s b/asm/code_8021D424.s
index b9a2c6c..a9b85b5 100644
--- a/asm/code_8021D424.s
+++ b/asm/code_8021D424.s
@@ -490,7 +490,7 @@ lbl_8021DADC:
lbl_8021DB18:
/* 8021DB18 00219778 7E 64 9B 78 */ mr r4, r19
/* 8021DB1C 0021977C 38 61 00 6C */ addi r3, r1, 0x6c
-/* 8021DB20 00219780 48 05 F2 A9 */ bl PSQUATDotProduct
+/* 8021DB20 00219780 48 05 F2 A9 */ bl PSVECDotProduct
/* 8021DB24 00219784 FC 17 08 40 */ fcmpo cr0, f23, f1
/* 8021DB28 00219788 FF 00 08 90 */ fmr f24, f1
/* 8021DB2C 0021978C 40 81 00 2C */ ble lbl_8021DB58
@@ -531,7 +531,7 @@ lbl_8021DB98:
/* 8021DBA8 00219808 48 05 F1 65 */ bl PSVECScale
/* 8021DBAC 0021980C 38 61 00 60 */ addi r3, r1, 0x60
/* 8021DBB0 00219810 38 81 00 6C */ addi r4, r1, 0x6c
-/* 8021DBB4 00219814 48 05 F2 15 */ bl PSQUATDotProduct
+/* 8021DBB4 00219814 48 05 F2 15 */ bl PSVECDotProduct
/* 8021DBB8 00219818 C0 42 9B 98 */ lfs f2, lbl_80642198-_SDA2_BASE_(r2)
/* 8021DBBC 0021981C C0 02 9B 84 */ lfs f0, lbl_80642184-_SDA2_BASE_(r2)
/* 8021DBC0 00219820 EE E2 00 72 */ fmuls f23, f2, f1
@@ -683,7 +683,7 @@ lbl_8021DDB8:
/* 8021DDD4 00219A34 48 05 EF 15 */ bl PSVECSubtract
/* 8021DDD8 00219A38 38 61 00 6C */ addi r3, r1, 0x6c
/* 8021DDDC 00219A3C 38 81 00 0C */ addi r4, r1, 0xc
-/* 8021DDE0 00219A40 48 05 EF E9 */ bl PSQUATDotProduct
+/* 8021DDE0 00219A40 48 05 EF E9 */ bl PSVECDotProduct
/* 8021DDE4 00219A44 EC 17 00 72 */ fmuls f0, f23, f1
/* 8021DDE8 00219A48 D0 1A 00 38 */ stfs f0, 0x38(r26)
/* 8021DDEC 00219A4C 48 00 5A 45 */ bl func_80223830
diff --git a/asm/code_80224B10.s b/asm/code_80224B10.s
index 94e9c84..78c156d 100644
--- a/asm/code_80224B10.s
+++ b/asm/code_80224B10.s
@@ -737,7 +737,7 @@ lbl_802254E0:
lbl_802254E8:
/* 802254E8 00221148 7C 64 1B 78 */ mr r4, r3
/* 802254EC 0022114C 7F E3 FB 78 */ mr r3, r31
-/* 802254F0 00221150 48 05 78 D9 */ bl PSQUATDotProduct
+/* 802254F0 00221150 48 05 78 D9 */ bl PSVECDotProduct
/* 802254F4 00221154 38 00 00 02 */ li r0, 2
/* 802254F8 00221158 D0 3E 00 04 */ stfs f1, 4(r30)
/* 802254FC 0022115C B0 1E 00 00 */ sth r0, 0(r30)
@@ -779,7 +779,7 @@ lbl_8022557C:
/* 80225580 002211E0 48 05 77 A9 */ bl PSVECNormalize
/* 80225584 002211E4 38 61 00 6C */ addi r3, r1, 0x6c
/* 80225588 002211E8 38 81 00 60 */ addi r4, r1, 0x60
-/* 8022558C 002211EC 48 05 78 3D */ bl PSQUATDotProduct
+/* 8022558C 002211EC 48 05 78 3D */ bl PSVECDotProduct
/* 80225590 002211F0 C0 02 9C 8C */ lfs f0, lbl_8064228C-_SDA2_BASE_(r2)
/* 80225594 002211F4 FC 01 00 40 */ fcmpo cr0, f1, f0
/* 80225598 002211F8 4C 41 13 82 */ cror 2, 1, 2
diff --git a/asm/code_80232D24.s b/asm/code_80232D24.s
index ea1b19f..d2d02b4 100644
--- a/asm/code_80232D24.s
+++ b/asm/code_80232D24.s
@@ -110,7 +110,7 @@ lbl_80232E90:
/* 80232EB4 0022EB14 D0 41 00 4C */ stfs f2, 0x4c(r1)
/* 80232EB8 0022EB18 D0 21 00 50 */ stfs f1, 0x50(r1)
/* 80232EBC 0022EB1C D0 01 00 54 */ stfs f0, 0x54(r1)
-/* 80232EC0 0022EB20 48 04 9F 09 */ bl PSQUATDotProduct
+/* 80232EC0 0022EB20 48 04 9F 09 */ bl PSVECDotProduct
/* 80232EC4 0022EB24 FF 80 08 90 */ fmr f28, f1
/* 80232EC8 0022EB28 FC 01 E8 40 */ fcmpo cr0, f1, f29
/* 80232ECC 0022EB2C 40 80 00 30 */ bge lbl_80232EFC
@@ -274,7 +274,7 @@ lbl_802330F8:
/* 8023311C 0022ED7C D0 41 00 4C */ stfs f2, 0x4c(r1)
/* 80233120 0022ED80 D0 21 00 50 */ stfs f1, 0x50(r1)
/* 80233124 0022ED84 D0 01 00 54 */ stfs f0, 0x54(r1)
-/* 80233128 0022ED88 48 04 9C A1 */ bl PSQUATDotProduct
+/* 80233128 0022ED88 48 04 9C A1 */ bl PSVECDotProduct
/* 8023312C 0022ED8C FF 80 08 90 */ fmr f28, f1
/* 80233130 0022ED90 FC 01 E8 40 */ fcmpo cr0, f1, f29
/* 80233134 0022ED94 40 80 00 30 */ bge lbl_80233164
diff --git a/src/code_801DD8C0.cpp b/src/code_801DD8C0.cpp
index 89c315c..bc86aa9 100644
--- a/src/code_801DD8C0.cpp
+++ b/src/code_801DD8C0.cpp
@@ -44,8 +44,9 @@ static inline void inline_ClearFunction(gUnkClass7* ptr)
ptr->unk6 &= ~0x1;
}
-#ifdef NONMATCHING
-// r4/r6 regswap
+#ifndef NONMATCHING
+#pragma regswap 801DDA28 801DDA80 r4 r6 801DD8C0
+#endif
void GSanimationObject::func_801DD9C8(float p2)
{
if (unk4) {
@@ -70,68 +71,6 @@ void GSanimationObject::func_801DD9C8(float p2)
}
}
}
-#else
-asm void GSanimationObject::func_801DD9C8(float p2)
-{
- nofralloc
-/* 801DD9C8 001D9628 94 21 FF F0 */ stwu r1, -0x10(r1)
-/* 801DD9CC 001D962C 7C 08 02 A6 */ mflr r0
-/* 801DD9D0 001D9630 90 01 00 14 */ stw r0, 0x14(r1)
-/* 801DD9D4 001D9634 93 E1 00 0C */ stw r31, 0xc(r1)
-/* 801DD9D8 001D9638 7C 7F 1B 78 */ mr r31, r3
-/* 801DD9DC 001D963C 80 83 00 04 */ lwz r4, 4(r3)
-/* 801DD9E0 001D9640 2C 04 00 00 */ cmpwi r4, 0
-/* 801DD9E4 001D9644 41 82 00 9C */ beq lbl_801DDA80
-/* 801DD9E8 001D9648 80 04 00 00 */ lwz r0, 0(r4)
-/* 801DD9EC 001D964C 38 60 00 00 */ li r3, 0
-/* 801DD9F0 001D9650 2C 00 00 00 */ cmpwi r0, 0
-/* 801DD9F4 001D9654 41 82 00 14 */ beq lbl_801DDA08
-/* 801DD9F8 001D9658 A0 04 00 06 */ lhz r0, 6(r4)
-/* 801DD9FC 001D965C 54 00 07 FF */ clrlwi. r0, r0, 0x1f
-/* 801DDA00 001D9660 41 82 00 08 */ beq lbl_801DDA08
-/* 801DDA04 001D9664 38 60 00 01 */ li r3, 1
-lbl_801DDA08:
-/* 801DDA08 001D9668 2C 03 00 00 */ cmpwi r3, 0
-/* 801DDA0C 001D966C 41 82 00 74 */ beq lbl_801DDA80
-/* 801DDA10 001D9670 7C 83 23 78 */ mr r3, r4
-/* 801DDA14 001D9674 4B FF FB B5 */ bl func_801DD5C8
-/* 801DDA18 001D9678 80 7F 00 04 */ lwz r3, 4(r31)
-/* 801DDA1C 001D967C 7F E4 FB 78 */ mr r4, r31
-/* 801DDA20 001D9680 38 A0 00 00 */ li r5, 0
-/* 801DDA24 001D9684 4B FF FD D9 */ bl func_801DD7FC
-/* 801DDA28 001D9688 80 DF 00 04 */ lwz r6, 4(r31)
-/* 801DDA2C 001D968C 38 80 00 01 */ li r4, 1
-/* 801DDA30 001D9690 A0 A6 00 06 */ lhz r5, 6(r6)
-/* 801DDA34 001D9694 54 A0 07 39 */ rlwinm. r0, r5, 0, 0x1c, 0x1c
-/* 801DDA38 001D9698 40 82 00 2C */ bne lbl_801DDA64
-/* 801DDA3C 001D969C 80 06 00 00 */ lwz r0, 0(r6)
-/* 801DDA40 001D96A0 38 60 00 00 */ li r3, 0
-/* 801DDA44 001D96A4 2C 00 00 00 */ cmpwi r0, 0
-/* 801DDA48 001D96A8 41 82 00 10 */ beq lbl_801DDA58
-/* 801DDA4C 001D96AC 54 A0 07 FF */ clrlwi. r0, r5, 0x1f
-/* 801DDA50 001D96B0 41 82 00 08 */ beq lbl_801DDA58
-/* 801DDA54 001D96B4 38 60 00 01 */ li r3, 1
-lbl_801DDA58:
-/* 801DDA58 001D96B8 2C 03 00 00 */ cmpwi r3, 0
-/* 801DDA5C 001D96BC 41 82 00 08 */ beq lbl_801DDA64
-/* 801DDA60 001D96C0 38 80 00 00 */ li r4, 0
-lbl_801DDA64:
-/* 801DDA64 001D96C4 2C 04 00 00 */ cmpwi r4, 0
-/* 801DDA68 001D96C8 41 82 00 18 */ beq lbl_801DDA80
-/* 801DDA6C 001D96CC A0 66 00 06 */ lhz r3, 6(r6)
-/* 801DDA70 001D96D0 54 60 06 F7 */ rlwinm. r0, r3, 0, 0x1b, 0x1b
-/* 801DDA74 001D96D4 40 82 00 0C */ bne lbl_801DDA80
-/* 801DDA78 001D96D8 54 60 04 3C */ rlwinm r0, r3, 0, 0x10, 0x1e
-/* 801DDA7C 001D96DC B0 06 00 06 */ sth r0, 6(r6)
-lbl_801DDA80:
-/* 801DDA80 001D96E0 80 01 00 14 */ lwz r0, 0x14(r1)
-/* 801DDA84 001D96E4 83 E1 00 0C */ lwz r31, 0xc(r1)
-/* 801DDA88 001D96E8 7C 08 03 A6 */ mtlr r0
-/* 801DDA8C 001D96EC 38 21 00 10 */ addi r1, r1, 0x10
-/* 801DDA90 001D96F0 4E 80 00 20 */ blr
-}
-#pragma peephole on
-#endif
// Search the linked list referenced by unk0 for a node with the specified id
gUnkClass8* GSanimationObject::func_801DDA94(u16 id)
diff --git a/tools/pragma/LICENSE b/tools/pragma/LICENSE
new file mode 100644
index 0000000..3b8d049
--- /dev/null
+++ b/tools/pragma/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Max Parisi https://github.com/mparisi20
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/tools/pragma/README.md b/tools/pragma/README.md
new file mode 100644
index 0000000..3823b42
--- /dev/null
+++ b/tools/pragma/README.md
@@ -0,0 +1,40 @@
+# pragma.py
+#### Pragma processor for GameCube/Wii decompilation projects
+###### by Max Parisi
+
+This is a custom pragma processor meant for use with matching decompilation projects for GameCube and Wii games. It currently adds support for `#pragma regswap` and `#pragma iswap`.
+
+If some reconstructed C/C++ source code compiles to object binary whose only differences with a target binary are misassigned registers, you can use `#pragma regswap`
+to correct the register assignment. This is an alternative to the strategy of inlining the desired assembly that aims to be more compact, self-documenting, and convenient.
+
+`pragma.py` will compile your source code, then perform the register and instruction swaps by patching the range of the object file specified in each pragma invocation.
+
+## Usage
+Invoke `#pragma regswap` one or more times in a C or C++ source file with the following parameters:
+```
+#pragma regswap start end regA regB startFile
+```
+
+where,
+* `start` - absolute address of start of affected region in hexadecimal format
+* `end` - absolute address of end of affected region (in hex)
+* `regA` - register to be swapped with `regB` (r0-r31 or f0-f31)
+* `regB` - register to swapped with `regA` (r0-r31 or f0-f31)
+* `startFile` - absolute address of the first function provided by this file (in hex)
+
+Invoke `#pragma iswap` with the following parameters:
+```
+#pragma iswap addrA addrB startFile
+```
+where,
+* `addrA` and `addrB` - absolute addresses of the instructions to be swapped
+
+
+Then, invoke the pragma processor:
+```
+python3 pragma.py [-h] cc cflags output source
+```
+
+
+## Future Work
+* Support for more architectures besides Gekko/Broadway PowerPC
diff --git a/tools/pragma/pragma.py b/tools/pragma/pragma.py
new file mode 100644
index 0000000..2a935a9
--- /dev/null
+++ b/tools/pragma/pragma.py
@@ -0,0 +1,329 @@
+# pragma.py
+# By mparisi20
+# github.com/mparisi20/pragma_processor
+
+# #pragma regswap usage:
+# #pragma regswap start end regA regB startFile
+
+# start: absolute address of start of affected region (hex)
+# end: absolute address of end of affected region (hex)
+# regA: register to swap (r0-r31 or f0-f31)
+# regB: register to swap (r0-r31 or f0-f31)
+# startFile: absolute address of the first function provided by this file (hex)
+
+#pragma iswap addrA addrB startFile
+
+import os
+import sys
+import argparse
+import subprocess
+import tempfile
+import re
+
+# 10-bit extension field for instructions with opcode 31
+op31_map = {
+ 'mask': 0x3ff,
+ 'data':
+ {
+ frozenset([0, 32, 4, 86, 470, 54, 278, 246, 1014, 982]): (11, 16),
+
+ frozenset([28, 60, 284, 476, 124, 444, 412, 316, 24, 792,
+ 536, 119, 87, 375, 343, 311, 279, 55, 23, 247,
+ 215, 439, 407, 183, 151, 790, 534, 918, 662, 533,
+ 661, 20, 150, 631, 599, 567, 535, 759, 727, 983,
+ 695, 663, 310, 438]): (6, 11, 16),
+
+ frozenset([26, 954, 922, 824, 597, 725]): (6, 11),
+
+ frozenset([19, 83, 339, 371, 144, 146, 467, 595, 210]): (6,),
+
+ frozenset([659, 242]): (6, 16),
+
+ frozenset([306]): (16,)
+ }
+ }
+
+# lower 9 bits
+op31_mask9_map = {
+ 'mask': 0x1ff,
+ 'data':
+ {
+ frozenset([266, 10, 138, 491, 459, 75, 11, 235, 40, 8, 136]): (6, 11, 16),
+ frozenset([234, 202, 104, 232, 200]): (6, 11)
+ }
+ }
+
+# 10-bit extension field for instructions with opcode 63
+op63_map = {
+ 'mask': 0x3ff,
+ 'data':
+ {
+ frozenset([14, 15, 12, 264, 72, 136, 40]): (6, 16),
+ frozenset([32, 0]): (11, 16),
+ frozenset([583, 711]): (6,)
+ }
+ }
+
+# lower 5 bits
+op63_mask5_map = {
+ 'mask': 0x1f,
+ 'data':
+ {
+ frozenset([21, 18, 20]): (6, 11, 16),
+ frozenset([25]): (6, 11, 21),
+ frozenset([26]): (6, 16),
+ frozenset([23, 29, 28, 31, 30]): (6, 11, 16, 21)
+ }
+ }
+
+# lower 5 bits of the 10-bit extension field for instructions with opcode 59
+op59_mask5_map = {
+ 'mask': 0x1f,
+ 'data':
+ {
+ frozenset([21, 18, 20]): (6, 11, 16),
+ frozenset([25]): (6, 11, 21),
+ frozenset([24]): (6, 16),
+ frozenset([29, 28, 31, 30]): (6, 11, 16, 21)
+ }
+ }
+
+# 10-bit extension field for instructions with opcode 4
+op4_map = {
+ 'mask': 0x3ff,
+ 'data':
+ {
+ frozenset([40, 72, 136, 264]): (6, 16),
+ frozenset([0, 32, 64, 96, 1014]): (11, 16),
+ frozenset([528, 560, 592, 624]): (6, 11, 16)
+ }
+ }
+
+# lower 6 bits
+op4_mask6_map = {
+ 'mask': 0x3f,
+ 'data':
+ {
+ frozenset([6, 7, 38, 39]): (6, 11, 16)
+ }
+ }
+
+# lower 5 bits
+op4_mask5_map = {
+ 'mask': 0x1f,
+ 'data':
+ {
+ frozenset([18, 20, 21]): (6, 11, 16),
+ frozenset([23, 28, 29, 30, 31, 10, 11, 14, 15]): (6, 11, 16, 21),
+ frozenset([24, 26]): (6, 16),
+ frozenset([25, 12, 13]): (6, 11, 21)
+ }
+ }
+
+# 6-bit opcode field for miscellaneous opcodes
+misc_opcode_map = {
+ 'mask': 0x3f,
+ 'data':
+ {
+ frozenset([14, 12, 13, 15, 7, 8, 28, 29, 24, 25,
+ 26, 27, 20, 21, 34, 35, 42, 43, 40, 41,
+ 32, 33, 38, 39, 44, 45, 36, 37, 46, 47,
+ 50, 51, 48, 49, 54, 55, 52, 53, 56, 57,
+ 60, 61]): (6, 11),
+
+ frozenset([11, 10, 3]): (11,),
+
+ frozenset([23]): (6, 11, 16)
+ }
+ }
+
+class FloatInfo:
+ def __init__(self, is_float, int_regs):
+ self.is_float = is_float
+ self.int_regs = int_regs
+
+class PPCInstr:
+
+ INSTR_SIZE = 32
+ REG_FIELD_SIZE = 5
+
+ def __init__(self, val):
+ self.v = val
+
+ def get_field(self, left, right):
+ return (self.v >> (self.INSTR_SIZE - right - 1)) & ((1 << (right - left + 1)) - 1)
+
+ def set_field(self, left, right, val):
+ width = right - left + 1
+ mask = (1 << width) - 1
+ shift = self.INSTR_SIZE - width - left
+ self.v = self.v & ~(mask << shift) | ((val & mask) << shift)
+
+ def get_opcode(self):
+ return self.get_field(0, 5)
+
+ def get_ext_opcode(self):
+ return self.get_field(21, 30)
+
+ def search_opcode_maps(self, opcode, *maps):
+ for map in maps:
+ masked_opcode = opcode & map['mask']
+ for k in map['data'].keys():
+ if masked_opcode in k:
+ return map['data'][k]
+
+ # returns a tuple containing the bit position of each register field
+ # or None if the instruction does not use registers
+ def get_reg_fields(self):
+ opcode = self.get_opcode()
+ ext_opcode = self.get_ext_opcode()
+ if opcode == 31:
+ return self.search_opcode_maps(ext_opcode, op31_map, op31_mask9_map)
+ elif opcode == 59:
+ return self.search_opcode_maps(ext_opcode, op59_mask5_map)
+ elif opcode == 63:
+ return self.search_opcode_maps(ext_opcode, op63_map, op63_mask5_map)
+ elif opcode == 4:
+ return self.search_opcode_maps(ext_opcode, op4_map, op4_mask6_map, op4_mask5_map)
+ else:
+ return self.search_opcode_maps(opcode, misc_opcode_map)
+
+ def uses_float_regs(self):
+ op = self.get_opcode()
+ ext_op = self.get_ext_opcode()
+ if op in {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61}:
+ return FloatInfo(True, (11,))
+ elif (op == 4 and ext_op & 0x3F in {6, 7, 38, 39}) or (op == 31 and ext_op in {535, 567, 599, 631, 663, 695, 727, 759, 983}):
+ return FloatInfo(True, (11, 16))
+ elif op in {4, 59, 63}:
+ return FloatInfo(True, ())
+ return FloatInfo(False, ())
+
+ # edit the PPC instruction to swap the registers
+ def swap_registers(self, regA, regB):
+ info = self.uses_float_regs()
+ reg_fields = self.get_reg_fields()
+ if not reg_fields:
+ return
+ for left in reg_fields:
+ right = left + self.REG_FIELD_SIZE - 1
+ currReg = self.get_field(left, right)
+ # since r0-r31 occupy 0-31 and f0-31 occupy 32-63,
+ # subtract 32 from regA/regB if the next register field is for a floating point register
+ dec = 0 if not info.is_float or left in info.int_regs else -32
+ if currReg == regA + dec:
+ self.set_field(left, right, regB + dec)
+ elif currReg == regB + dec:
+ self.set_field(left, right, regA + dec)
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument("cc",
+ help="path to a C/C++ compiler")
+parser.add_argument("cflags",
+ help="all flags and options to be invoked with cc")
+parser.add_argument("output",
+ help="path to the outputted object file")
+parser.add_argument("source",
+ help="path to the C/C++ source file")
+args = parser.parse_args()
+
+def parse_reg(str):
+ if str[0] == 'r' or str[0] == 'f':
+ reg = int(str[1:])
+ if reg >= 0 and reg <= 31:
+ return reg if str[0] == 'r' else reg + 32
+ raise ValueError("Failed to parse register argument (can be r0...r31 or f0...f31)")
+
+class RegswapTask:
+ def __init__(self, start, end, regA, regB):
+ self.start = start # .text section byte offset
+ self.end = end # .text section byte offset
+ self.regA = regA
+ self.regB = regB
+
+class IswapTask:
+ def __init__(self, src, dst):
+ self.src = src # .text section byte offset
+ self.dst = dst # .text section byte offset
+
+regswap_tasks = []
+iswap_tasks = []
+with open(args.source, "r") as src:
+ regswap_pattern = re.compile("[ \t]*#pragma[ \t]+regswap[ \t]+")
+ iswap_pattern = re.compile("[ \t]*#pragma[ \t]+iswap[ \t]+")
+ for line in src:
+ if regswap_pattern.match(line):
+ params = line.split()[2:]
+ if len(params) != 5:
+ raise ValueError("ERROR: " + str(len(params)) + " arguments passed to #pragma regswap (expected 5)")
+ start = int(params[0], base=16)
+ end = int(params[1], base=16)
+ regA = parse_reg(params[2])
+ regB = parse_reg(params[3])
+ start_file = int(params[4], base=16)
+ if not (start % 4 == 0 and end % 4 == 0 and start_file % 4 == 0):
+ raise ValueError("Invalid start, end, or start_file arguments (should have 4 byte aligment)")
+ if not (start >= start_file and end > start):
+ raise ValueError("Invalid start, end, or start_file arguments (end must be > start, and start >= start_file)")
+ regswap_tasks.append(RegswapTask(start-start_file, end-start_file, regA, regB))
+ elif iswap_pattern.match(line):
+ params = line.split()[2:]
+ if len(params) != 3:
+ raise ValueError("ERROR: " + str(len(params)) + " arguments passed to #pragma iswap (expected 3)")
+ src = int(params[0], base=16)
+ dst = int(params[1], base=16)
+ start_file = int(params[2], base=16)
+ if not (src % 4 == 0 and dst % 4 == 0 and start_file % 4 == 0):
+ raise ValueError("Invalid src, dst, or start_file arguments (should have 4 byte aligment)")
+ if not (src >= start_file and dst > src):
+ raise ValueError("Invalid src, dst, or start_file arguments (dst must be > src, and src >= start_file)")
+ iswap_tasks.append(IswapTask(src-start_file, dst-start_file))
+
+ subprocess.run([*args.cc.strip().split(' '), *args.cflags.split(' '), "-o", args.output, args.source])
+
+instrs = []
+TEXT_INDEX = 1 # NOTE: assumes that mwcceppc always places the .text section header at index 1
+SHDR_32_SIZE = 40 # size of an Elf32_Shdr object
+
+if regswap_tasks or iswap_tasks:
+ with open(args.output, "rb") as f:
+ if f.read(7) != b'\x7FELF\x01\x02\x01':
+ raise ValueError("compiler output is not an current version ELF file for a 32-bit big endian architecture")
+ f.seek(0x20)
+ e_shoff = int.from_bytes(f.read(4), byteorder='big')
+ f.seek(0x30)
+ e_shnum = int.from_bytes(f.read(2), byteorder='big')
+ if e_shoff == 0 or e_shnum < 2:
+ raise ValueError("ELF file must contain at least two sections")
+
+ # get .text section sh_offset and sh_size members
+ f.seek(e_shoff + TEXT_INDEX*SHDR_32_SIZE + 0x10)
+ text_offset = int.from_bytes(f.read(4), byteorder='big')
+ text_size = int.from_bytes(f.read(4), byteorder='big')
+
+ # read .text section contents into buffer
+ f.seek(text_offset)
+ for i in range(text_size // 4):
+ instrs.append(PPCInstr(int.from_bytes(f.read(4), byteorder='big')))
+
+ # perform regswap tasks
+ for task in regswap_tasks:
+ if task.end > text_size:
+ raise ValueError("End address " + (task.end + start_file) + " is past the end of the ELF file's .text section")
+ for i in range(task.start // 4, task.end // 4):
+ instrs[i].swap_registers(task.regA, task.regB)
+
+ # perform iswap tasks
+ for task in iswap_tasks:
+ if task.dst > text_size:
+ raise ValueError("End address " + (task.dst + start_file) + " is past the end of the ELF file's .text section")
+ a = task.src // 4
+ b = task.dst // 4
+ instrs[a], instrs[b] = instrs[b], instrs[a]
+
+ # write patched .text section back to the ELF
+ with open(args.output, "rb+") as f:
+ f.seek(text_offset)
+ for instr in instrs:
+ f.write(instr.v.to_bytes(4, byteorder='big'))