From 718c9c00118acc70b81aade01f5c392bc7964cb7 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 19 Dec 2020 00:45:39 -0500 Subject: add pragma.py to tools, edit Makefile, add example #pragma regswap usage to code_801DD8C0.cpp --- Makefile | 9 +- src/code_801DD8C0.cpp | 67 +---------- tools/pragma/pragma.py | 299 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 307 insertions(+), 68 deletions(-) create mode 100644 tools/pragma/pragma.py diff --git a/Makefile b/Makefile index 69b7c42..a3ab689 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" $@ $< -fix-regswaps $(BUILD_DIR)/%.o: %.c - $(CC) $(CFLAGS) -lang c99 -c -o $@ $< + $(PYTHON) $(PRAGMAPROC) $(CC) "$(CFLAGS) -lang c99 -c" $@ $< -fix-regswaps 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/pragma.py b/tools/pragma/pragma.py new file mode 100644 index 0000000..61d52de --- /dev/null +++ b/tools/pragma/pragma.py @@ -0,0 +1,299 @@ +""" + +./tools/pragma/pragma.py "$(CFLAGS)" -fix-regswaps + +#pragma regswap start end regA regB startFile + +pragma is only meaningful when you're trying to build a matching ROM. +Modders don't care about regswaps. They care about shiftability. +Modding projects must ignore #pragma regswap to avoid corrupting the ROM +(add a Makefile option, "make mod" or similar) + +makefile executes... +$(CC) $(CFLAGS) -lang c++ -c -o $@ $< + +$(PYTHON) $(PRAGMA) $(CC) "$(CFLAGS) -lang c++ -c" $@ $< -fix-regswaps + +""" + +# pragma.py +# github.com/mparisi20 + +# usage: pragma.py cc cflags output source [-fix-regswaps] + +# TODO: add instruction swap option +# TODO: add "#pragma startaddr 80000000" to avoid rewriting the start address in each regswap pragma? + + +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 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 + # TODO: exception handling? + 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) + + # edit the PPC instruction to swap the registers + def swap_registers(self, regA, regB): + DEBUG_v = hex(self.v) + reg_fields = self.get_reg_fields() + print(str(reg_fields) + ", " + DEBUG_v) + if reg_fields is None: + return + for left in reg_fields: + right = left + self.REG_FIELD_SIZE - 1 + currReg = self.get_field(left, right) + if currReg == regA: + self.set_field(left, right, regB) + elif currReg == regB: + self.set_field(left, right, regA) + + +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") +parser.add_argument("-fix-regswaps", + help="execute #pragma regswap", action="store_true") +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 + 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 + +regswap_tasks = [] +with open(args.source, "r") as src: + regswap_pattern = re.compile("[ \t]*#pragma[ \t]+regswap[ \t]+") + for line in src: + if regswap_pattern.match(line): + if args.fix_regswaps: + params = line.split()[2:] + if len(params) != 5: + raise ValueError("ERROR: " + 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)) + subprocess.run([args.cc, *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 args.fix_regswaps and len(regswap_tasks) != 0: + 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) + + # 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')) -- cgit v1.2.3 From 128935015a3fd7f53404315c268c3d2424af4dc7 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 19 Dec 2020 11:48:42 -0500 Subject: fix bugs in pragma.py, add license/readme --- tools/pragma/LICENSE | 21 +++++++++++++++++++++ tools/pragma/README.md | 35 +++++++++++++++++++++++++++++++++++ tools/pragma/pragma.py | 38 +++++++++++++------------------------- 3 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 tools/pragma/LICENSE create mode 100644 tools/pragma/README.md 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..2f9074c --- /dev/null +++ b/tools/pragma/README.md @@ -0,0 +1,35 @@ +# 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`. + +If some reconstructed C/C++ source code compiles to object binary whose only differences with a target binary are misallocated registers, you can use `#pragma regswap` +to correct the register allocation. 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 fix the regswaps 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) + + + +Then, invoke the pragma processor with the `-fix-regswaps` option: +``` +python3 pragma.py [-h] [-fix-regswaps] cc cflags output source +``` + + +## Future Work +* Add support for an instruction-swap pragma (`#pragma iswap ...`) +* Support for more architectures besides Gekko/Broadway PowerPC diff --git a/tools/pragma/pragma.py b/tools/pragma/pragma.py index 61d52de..f721c65 100644 --- a/tools/pragma/pragma.py +++ b/tools/pragma/pragma.py @@ -1,29 +1,18 @@ -""" - -./tools/pragma/pragma.py "$(CFLAGS)" -fix-regswaps - -#pragma regswap start end regA regB startFile - -pragma is only meaningful when you're trying to build a matching ROM. -Modders don't care about regswaps. They care about shiftability. -Modding projects must ignore #pragma regswap to avoid corrupting the ROM -(add a Makefile option, "make mod" or similar) - -makefile executes... -$(CC) $(CFLAGS) -lang c++ -c -o $@ $< - -$(PYTHON) $(PRAGMA) $(CC) "$(CFLAGS) -lang c++ -c" $@ $< -fix-regswaps - -""" - # pragma.py -# github.com/mparisi20 +# By mparisi20 +# github.com/mparisi20/pragma_processor -# usage: pragma.py cc cflags output source [-fix-regswaps] +# #pragma regswap usage: +# #pragma regswap start end regA regB startFile -# TODO: add instruction swap option -# TODO: add "#pragma startaddr 80000000" to avoid rewriting the start address in each regswap pragma? +# 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) +# TODO: add support for an instruction swap pragma +# TODO: add "#pragma startaddr " to avoid rewriting the start address in each regswap pragma? import os import sys @@ -181,7 +170,6 @@ class PPCInstr: # returns a tuple containing the bit position of each register field # or None if the instruction does not use registers - # TODO: exception handling? def get_reg_fields(self): opcode = self.get_opcode() ext_opcode = self.get_ext_opcode() @@ -198,9 +186,9 @@ class PPCInstr: # edit the PPC instruction to swap the registers def swap_registers(self, regA, regB): - DEBUG_v = hex(self.v) + # DEBUG_v = hex(self.v) reg_fields = self.get_reg_fields() - print(str(reg_fields) + ", " + DEBUG_v) + # print(str(reg_fields) + ", " + DEBUG_v) if reg_fields is None: return for left in reg_fields: -- cgit v1.2.3 From 4f3e87d037cfc6efcafc605e309edc71179cbb7a Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 19 Dec 2020 12:39:50 -0500 Subject: argument parsing issue in pragma.py when compiler is invoked through wine --- Makefile | 10 +++++----- tools/pragma/pragma.py | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index a3ab689..6141243 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ EXE := .exe WINE := else EXE := -WINE := wine +WINE := wine endif ifeq ($(NOWINE),1) @@ -77,8 +77,8 @@ MWCC_VERSION := 3.0 AS := $(DEVKITPPC)/bin/powerpc-eabi-as OBJCOPY := $(DEVKITPPC)/bin/powerpc-eabi-objcopy CPP := cpp -P -CC := $(WINE) tools/mwcc_compiler/GC/$(MWCC_VERSION)/mwcceppc.exe -LD := $(WINE) tools/mwcc_compiler/GC/$(MWCC_VERSION)/mwldeppc.exe +CC := $(WINE)tools/mwcc_compiler/GC/$(MWCC_VERSION)/mwcceppc.exe +LD := $(WINE)tools/mwcc_compiler/GC/$(MWCC_VERSION)/mwldeppc.exe ELF2DOL := tools/elf2dol/elf2dol$(EXE) SHA1SUM := sha1sum PYTHON := python3 @@ -155,7 +155,7 @@ $(BUILD_DIR)/%.o: %.s $(PYTHON) $(POSTPROC) $(PROCFLAGS) $@ $(BUILD_DIR)/%.o: %.cpp - $(PYTHON) $(PRAGMAPROC) $(CC) "$(CFLAGS) -lang c++ -c" $@ $< -fix-regswaps + $(PYTHON) $(PRAGMAPROC) "$(CC)" "$(CFLAGS) -lang c++ -c" $@ $< -fix-regswaps $(BUILD_DIR)/%.o: %.c - $(PYTHON) $(PRAGMAPROC) $(CC) "$(CFLAGS) -lang c99 -c" $@ $< -fix-regswaps + $(PYTHON) $(PRAGMAPROC) "$(CC)" "$(CFLAGS) -lang c99 -c" $@ $< -fix-regswaps diff --git a/tools/pragma/pragma.py b/tools/pragma/pragma.py index f721c65..8550a9f 100644 --- a/tools/pragma/pragma.py +++ b/tools/pragma/pragma.py @@ -246,7 +246,8 @@ with open(args.source, "r") as src: 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)) - subprocess.run([args.cc, *args.cflags.split(' '), "-o", args.output, args.source]) + print(*args.cc.split(' ')) + subprocess.run([*args.cc.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 -- cgit v1.2.3 From 9b63835774172d148b82625ec6be1229947cab69 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 19 Dec 2020 12:45:16 -0500 Subject: trim whitespace off cc argument in pragma.py --- Makefile | 6 +++--- tools/pragma/pragma.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 6141243..b897334 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ EXE := .exe WINE := else EXE := -WINE := wine +WINE := wine endif ifeq ($(NOWINE),1) @@ -77,8 +77,8 @@ MWCC_VERSION := 3.0 AS := $(DEVKITPPC)/bin/powerpc-eabi-as OBJCOPY := $(DEVKITPPC)/bin/powerpc-eabi-objcopy CPP := cpp -P -CC := $(WINE)tools/mwcc_compiler/GC/$(MWCC_VERSION)/mwcceppc.exe -LD := $(WINE)tools/mwcc_compiler/GC/$(MWCC_VERSION)/mwldeppc.exe +CC := $(WINE) tools/mwcc_compiler/GC/$(MWCC_VERSION)/mwcceppc.exe +LD := $(WINE) tools/mwcc_compiler/GC/$(MWCC_VERSION)/mwldeppc.exe ELF2DOL := tools/elf2dol/elf2dol$(EXE) SHA1SUM := sha1sum PYTHON := python3 diff --git a/tools/pragma/pragma.py b/tools/pragma/pragma.py index 8550a9f..75e0450 100644 --- a/tools/pragma/pragma.py +++ b/tools/pragma/pragma.py @@ -246,8 +246,7 @@ with open(args.source, "r") as src: 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)) - print(*args.cc.split(' ')) - subprocess.run([*args.cc.split(' '), *args.cflags.split(' '), "-o", args.output, args.source]) + 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 -- cgit v1.2.3 From 1379d3a8730bed8b8c049314c353ef0cf2d75ff4 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 24 Dec 2020 14:44:41 -0500 Subject: rename PSQUATDotProduct to PSVECDotProduct (was a typo) --- asm/GSvolume.s | 4 ++-- asm/SDK/MTX/vec.s | 8 ++++---- asm/code_800400E8.s | 8 ++++---- asm/code_801E6BF8.s | 2 +- asm/code_801EE044.s | 6 +++--- asm/code_801F40E0.s | 10 +++++----- asm/code_80207C4C.s | 6 +++--- asm/code_8020B4F8.s | 4 ++-- asm/code_8020D250.s | 10 +++++----- asm/code_8020F998.s | 6 +++--- asm/code_80213694.s | 12 ++++++------ asm/code_8021D424.s | 6 +++--- asm/code_80224B10.s | 4 ++-- asm/code_80232D24.s | 4 ++-- 14 files changed, 45 insertions(+), 45 deletions(-) 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 39d1173..ecbcee0 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 659a4ad..f898a2a 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 8b7775b..d2b12fa 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 d5bcb0c..32d52c5 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 55fdda8..f594c57 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 18d653b..e4414e2 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 9a25a7c..5314442 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 ae9e611..d18bd87 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 12838a4..421ae43 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 e428458..1d2f761 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 -- cgit v1.2.3 From 892c994feed64d3b8ea86c2eeaa8083dca4c7474 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 22 Jan 2021 14:02:16 -0500 Subject: fixed bug in #pragma regswap where swapping rA and rB would also swap fA and fB, and added #pragma iswap --- Makefile | 4 +-- tools/pragma/README.md | 19 ++++++---- tools/pragma/pragma.py | 96 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 83 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index b897334..876487d 100644 --- a/Makefile +++ b/Makefile @@ -155,7 +155,7 @@ $(BUILD_DIR)/%.o: %.s $(PYTHON) $(POSTPROC) $(PROCFLAGS) $@ $(BUILD_DIR)/%.o: %.cpp - $(PYTHON) $(PRAGMAPROC) "$(CC)" "$(CFLAGS) -lang c++ -c" $@ $< -fix-regswaps + $(PYTHON) $(PRAGMAPROC) "$(CC)" "$(CFLAGS) -lang c++ -c" $@ $< $(BUILD_DIR)/%.o: %.c - $(PYTHON) $(PRAGMAPROC) "$(CC)" "$(CFLAGS) -lang c99 -c" $@ $< -fix-regswaps + $(PYTHON) $(PRAGMAPROC) "$(CC)" "$(CFLAGS) -lang c99 -c" $@ $< diff --git a/tools/pragma/README.md b/tools/pragma/README.md index 2f9074c..3823b42 100644 --- a/tools/pragma/README.md +++ b/tools/pragma/README.md @@ -2,12 +2,12 @@ #### 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`. +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 misallocated registers, you can use `#pragma regswap` -to correct the register allocation. This is an alternative to the strategy of inlining the desired assembly that aims to be more compact, self-documenting, and convenient. +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 fix the regswaps by patching the range of the object file specified in each pragma invocation. +`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: @@ -22,14 +22,19 @@ where, * `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 with the `-fix-regswaps` option: +Then, invoke the pragma processor: ``` -python3 pragma.py [-h] [-fix-regswaps] cc cflags output source +python3 pragma.py [-h] cc cflags output source ``` ## Future Work -* Add support for an instruction-swap pragma (`#pragma iswap ...`) * Support for more architectures besides Gekko/Broadway PowerPC diff --git a/tools/pragma/pragma.py b/tools/pragma/pragma.py index 75e0450..2a935a9 100644 --- a/tools/pragma/pragma.py +++ b/tools/pragma/pragma.py @@ -11,8 +11,7 @@ # regB: register to swap (r0-r31 or f0-f31) # startFile: absolute address of the first function provided by this file (hex) -# TODO: add support for an instruction swap pragma -# TODO: add "#pragma startaddr " to avoid rewriting the start address in each regswap pragma? +#pragma iswap addrA addrB startFile import os import sys @@ -138,6 +137,11 @@ misc_opcode_map = { } } +class FloatInfo: + def __init__(self, is_float, int_regs): + self.is_float = is_float + self.int_regs = int_regs + class PPCInstr: INSTR_SIZE = 32 @@ -184,20 +188,33 @@ class PPCInstr: 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): - # DEBUG_v = hex(self.v) + info = self.uses_float_regs() reg_fields = self.get_reg_fields() - # print(str(reg_fields) + ", " + DEBUG_v) - if reg_fields is None: + if not reg_fields: return for left in reg_fields: right = left + self.REG_FIELD_SIZE - 1 currReg = self.get_field(left, right) - if currReg == regA: - self.set_field(left, right, regB) - elif currReg == regB: - self.set_field(left, right, regA) + # 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() @@ -209,15 +226,13 @@ parser.add_argument("output", help="path to the outputted object file") parser.add_argument("source", help="path to the C/C++ source file") -parser.add_argument("-fix-regswaps", - help="execute #pragma regswap", action="store_true") 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 + 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: @@ -227,32 +242,51 @@ class RegswapTask: 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): - if args.fix_regswaps: - params = line.split()[2:] - if len(params) != 5: - raise ValueError("ERROR: " + 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)) + 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 args.fix_regswaps and len(regswap_tasks) != 0: +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") @@ -279,6 +313,14 @@ if args.fix_regswaps and len(regswap_tasks) != 0: 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: -- cgit v1.2.3 From 984748ba7e2cff0eb7c8f77e6546dae7997f89fb Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 29 Jan 2021 14:53:11 -0500 Subject: fix bug in calcrom get_files function --- .travis/calcrom/calcrom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; -- cgit v1.2.3