From bf0bb4b851a8109631376c8e3e48ff995b4454ed Mon Sep 17 00:00:00 2001 From: Pheenoh Date: Sat, 26 Dec 2020 13:03:37 -0500 Subject: [PATCH] move asm in TUs to files, add diff.py --- .gitignore | 5 +- asm/JUtility/JUTResFont.s | 4 - diff.py | 1602 +++++++++++++++++ .../JSystem/JUtility/asm/JUTResFont__dtor.s | 38 + .../SComponent/c_phase/asm/func_80266678.s | 28 + .../SComponent/c_phase/asm/func_802666D8.s | 61 + include/d/d_item/d_item/d_item.h | 2 + .../f_pc/f_pc_create_req/asm/func_80020BA0.s | 32 + include/f/f_pc/f_pc_pause/asm/func_80023844.s | 9 + libs/JSystem/JUtility/JUTResFont.cpp | 65 +- libs/SSystem/SComponent/c_phase.cpp | 127 +- obj_files.mk | 1 - src/f/f_pc/f_pc_create_req.cpp | 50 +- src/f/f_pc/f_pc_pause.cpp | 25 +- 14 files changed, 1781 insertions(+), 268 deletions(-) delete mode 100644 asm/JUtility/JUTResFont.s create mode 100644 diff.py create mode 100644 include/JSystem/JUtility/asm/JUTResFont__dtor.s create mode 100644 include/SComponent/c_phase/asm/func_80266678.s create mode 100644 include/SComponent/c_phase/asm/func_802666D8.s create mode 100644 include/f/f_pc/f_pc_create_req/asm/func_80020BA0.s create mode 100644 include/f/f_pc/f_pc_pause/asm/func_80023844.s diff --git a/.gitignore b/.gitignore index 97bc4f785e..39c78de543 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,7 @@ vtable.lcf *.dump # IDE -.vscode/ \ No newline at end of file +.vscode/ + +# Python +__pycache__/ \ No newline at end of file diff --git a/asm/JUtility/JUTResFont.s b/asm/JUtility/JUTResFont.s deleted file mode 100644 index 6e57e6e726..0000000000 --- a/asm/JUtility/JUTResFont.s +++ /dev/null @@ -1,4 +0,0 @@ -.include "macros.inc" - -.section .text, "ax" # 802def48 - diff --git a/diff.py b/diff.py new file mode 100644 index 0000000000..5c20423176 --- /dev/null +++ b/diff.py @@ -0,0 +1,1602 @@ +#!/usr/bin/env python3 +# PYTHON_ARGCOMPLETE_OK +import argparse +import sys +from typing import ( + Any, + Dict, + List, + Match, + NamedTuple, + NoReturn, + Optional, + Set, + Tuple, + Union, + Callable, + Pattern, +) + + +def fail(msg: str) -> NoReturn: + print(msg, file=sys.stderr) + sys.exit(1) + + +# Prefer to use diff_settings.py from the current working directory +sys.path.insert(0, ".") +try: + import diff_settings +except ModuleNotFoundError: + fail("Unable to find diff_settings.py in the same directory.") +sys.path.pop(0) + +# ==== COMMAND-LINE ==== + +try: + import argcomplete # type: ignore +except ModuleNotFoundError: + argcomplete = None + +parser = argparse.ArgumentParser(description="Diff MIPS or AArch64 assembly.") + +start_argument = parser.add_argument( + "start", + help="Function name or address to start diffing from.", +) + +if argcomplete: + + def complete_symbol( + prefix: str, parsed_args: argparse.Namespace, **kwargs: object + ) -> List[str]: + if not prefix or prefix.startswith("-"): + # skip reading the map file, which would + # result in a lot of useless completions + return [] + config: Dict[str, Any] = {} + diff_settings.apply(config, parsed_args) # type: ignore + mapfile = config.get("mapfile") + if not mapfile: + return [] + completes = [] + with open(mapfile) as f: + data = f.read() + # assume symbols are prefixed by a space character + search = f" {prefix}" + pos = data.find(search) + while pos != -1: + # skip the space character in the search string + pos += 1 + # assume symbols are suffixed by either a space + # character or a (unix-style) line return + spacePos = data.find(" ", pos) + lineReturnPos = data.find("\n", pos) + if lineReturnPos == -1: + endPos = spacePos + elif spacePos == -1: + endPos = lineReturnPos + else: + endPos = min(spacePos, lineReturnPos) + if endPos == -1: + match = data[pos:] + pos = -1 + else: + match = data[pos:endPos] + pos = data.find(search, endPos) + completes.append(match) + return completes + + setattr(start_argument, "completer", complete_symbol) + +parser.add_argument( + "end", + nargs="?", + help="Address to end diff at.", +) +parser.add_argument( + "-o", + dest="diff_obj", + action="store_true", + help="Diff .o files rather than a whole binary. This makes it possible to " + "see symbol names. (Recommended)", +) +parser.add_argument( + "-e", + "--elf", + dest="diff_elf_symbol", + metavar="SYMBOL", + help="Diff a given function in two ELFs, one being stripped and the other " + "one non-stripped. Requires objdump from binutils 2.33+.", +) +parser.add_argument( + "--source", + action="store_true", + help="Show source code (if possible). Only works with -o and -e.", +) +parser.add_argument( + "--inlines", + action="store_true", + help="Show inline function calls (if possible). Only works with -o and -e.", +) +parser.add_argument( + "--base-asm", + dest="base_asm", + metavar="FILE", + help="Read assembly from given file instead of configured base img.", +) +parser.add_argument( + "--write-asm", + dest="write_asm", + metavar="FILE", + help="Write the current assembly output to file, e.g. for use with --base-asm.", +) +parser.add_argument( + "-m", + "--make", + dest="make", + action="store_true", + help="Automatically run 'make' on the .o file or binary before diffing.", +) +parser.add_argument( + "-l", + "--skip-lines", + dest="skip_lines", + type=int, + default=0, + metavar="LINES", + help="Skip the first N lines of output.", +) +parser.add_argument( + "-s", + "--stop-jr-ra", + dest="stop_jrra", + action="store_true", + help="Stop disassembling at the first 'jr ra'. Some functions have multiple return points, so use with care!", +) +parser.add_argument( + "-i", + "--ignore-large-imms", + dest="ignore_large_imms", + action="store_true", + help="Pretend all large enough immediates are the same.", +) +parser.add_argument( + "-I", + "--ignore-addr-diffs", + action="store_true", + help="Ignore address differences. Currently only affects AArch64.", +) +parser.add_argument( + "-B", + "--no-show-branches", + dest="show_branches", + action="store_false", + help="Don't visualize branches/branch targets.", +) +parser.add_argument( + "-S", + "--base-shift", + dest="base_shift", + type=str, + default="0", + help="Diff position X in our img against position X + shift in the base img. " + 'Arithmetic is allowed, so e.g. |-S "0x1234 - 0x4321"| is a reasonable ' + "flag to pass if it is known that position 0x1234 in the base img syncs " + "up with position 0x4321 in our img. Not supported together with -o.", +) +parser.add_argument( + "-w", + "--watch", + dest="watch", + action="store_true", + help="Automatically update when source/object files change. " + "Recommended in combination with -m.", +) +parser.add_argument( + "-3", + "--threeway=prev", + dest="threeway", + action="store_const", + const="prev", + help="Show a three-way diff between target asm, current asm, and asm " + "prior to -w rebuild. Requires -w.", +) +parser.add_argument( + "-b", + "--threeway=base", + dest="threeway", + action="store_const", + const="base", + help="Show a three-way diff between target asm, current asm, and asm " + "when diff.py was started. Requires -w.", +) +parser.add_argument( + "--width", + dest="column_width", + type=int, + default=50, + help="Sets the width of the left and right view column.", +) +parser.add_argument( + "--algorithm", + dest="algorithm", + default="levenshtein", + choices=["levenshtein", "difflib"], + help="Diff algorithm to use. Levenshtein gives the minimum diff, while difflib " + "aims for long sections of equal opcodes. Defaults to %(default)s.", +) +parser.add_argument( + "--max-size", + "--max-lines", + dest="max_lines", + type=int, + default=1024, + help="The maximum length of the diff, in lines.", +) + +# Project-specific flags, e.g. different versions/make arguments. +add_custom_arguments_fn = getattr(diff_settings, "add_custom_arguments", None) +if add_custom_arguments_fn: + add_custom_arguments_fn(parser) + +if argcomplete: + argcomplete.autocomplete(parser) + +# ==== IMPORTS ==== + +# (We do imports late to optimize auto-complete performance.) + +import re +import os +import ast +import subprocess +import difflib +import string +import itertools +import threading +import queue +import time + + +MISSING_PREREQUISITES = ( + "Missing prerequisite python module {}. " + "Run `python3 -m pip install --user colorama ansiwrap watchdog python-Levenshtein cxxfilt` to install prerequisites (cxxfilt only needed with --source)." +) + +try: + from colorama import Fore, Style, Back # type: ignore + import ansiwrap # type: ignore + import watchdog # type: ignore +except ModuleNotFoundError as e: + fail(MISSING_PREREQUISITES.format(e.name)) + +# ==== CONFIG ==== + +args = parser.parse_args() + +# Set imgs, map file and make flags in a project-specific manner. +config: Dict[str, Any] = {} +diff_settings.apply(config, args) # type: ignore + +arch: str = config.get("arch", "mips") +baseimg: Optional[str] = config.get("baseimg") +myimg: Optional[str] = config.get("myimg") +mapfile: Optional[str] = config.get("mapfile") +makeflags: List[str] = config.get("makeflags", []) +source_directories: Optional[List[str]] = config.get("source_directories") +objdump_executable: Optional[str] = config.get("objdump_executable") +map_format: str = config.get("map_format", "gnu") +mw_build_dir: str = config.get("mw_build_dir", "build/") + +MAX_FUNCTION_SIZE_LINES: int = args.max_lines +MAX_FUNCTION_SIZE_BYTES: int = MAX_FUNCTION_SIZE_LINES * 4 + +COLOR_ROTATION: List[str] = [ + Fore.MAGENTA, + Fore.CYAN, + Fore.GREEN, + Fore.RED, + Fore.LIGHTYELLOW_EX, + Fore.LIGHTMAGENTA_EX, + Fore.LIGHTCYAN_EX, + Fore.LIGHTGREEN_EX, + Fore.LIGHTBLACK_EX, +] + +BUFFER_CMD: List[str] = ["tail", "-c", str(10 ** 9)] +LESS_CMD: List[str] = ["less", "-SRic", "-#6"] + +DEBOUNCE_DELAY: float = 0.1 +FS_WATCH_EXTENSIONS: List[str] = [".c", ".h"] + +# ==== LOGIC ==== + +ObjdumpCommand = Tuple[List[str], str, Optional[str]] + +if args.algorithm == "levenshtein": + try: + import Levenshtein # type: ignore + except ModuleNotFoundError as e: + fail(MISSING_PREREQUISITES.format(e.name)) + +if args.source: + try: + import cxxfilt # type: ignore + except ModuleNotFoundError as e: + fail(MISSING_PREREQUISITES.format(e.name)) + +if args.threeway and not args.watch: + fail("Threeway diffing requires -w.") + +if objdump_executable is None: + for objdump_cand in ["mips-linux-gnu-objdump", "mips64-elf-objdump"]: + try: + subprocess.check_call( + [objdump_cand, "--version"], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + objdump_executable = objdump_cand + break + except subprocess.CalledProcessError: + pass + except FileNotFoundError: + pass + +if not objdump_executable: + fail( + "Missing binutils; please ensure mips-linux-gnu-objdump or mips64-elf-objdump exist, or configure objdump_executable." + ) + + +def maybe_eval_int(expr: str) -> Optional[int]: + try: + ret = ast.literal_eval(expr) + if not isinstance(ret, int): + raise Exception("not an integer") + return ret + except Exception: + return None + + +def eval_int(expr: str, emsg: str) -> int: + ret = maybe_eval_int(expr) + if ret is None: + fail(emsg) + return ret + + +def eval_line_num(expr: str) -> int: + return int(expr.strip().replace(":", ""), 16) + + +def run_make(target: str) -> None: + subprocess.check_call(["make"] + makeflags + [target]) + + +def run_make_capture_output(target: str) -> "subprocess.CompletedProcess[bytes]": + return subprocess.run( + ["make"] + makeflags + [target], + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + + +def restrict_to_function(dump: str, fn_name: str) -> str: + out: List[str] = [] + search = f"<{fn_name}>:" + found = False + for line in dump.split("\n"): + if found: + if len(out) >= MAX_FUNCTION_SIZE_LINES: + break + out.append(line) + elif search in line: + found = True + return "\n".join(out) + + +def maybe_get_objdump_source_flags() -> List[str]: + if not args.source: + return [] + + flags = [ + "--source", + "--source-comment=│ ", + "-l", + ] + + if args.inlines: + flags.append("--inlines") + + return flags + + +def run_objdump(cmd: ObjdumpCommand) -> str: + flags, target, restrict = cmd + assert objdump_executable, "checked previously" + out = subprocess.check_output( + [objdump_executable] + arch_flags + flags + [target], universal_newlines=True + ) + if restrict is not None: + return restrict_to_function(out, restrict) + return out + + +base_shift: int = eval_int( + args.base_shift, "Failed to parse --base-shift (-S) argument as an integer." +) + + +def search_map_file(fn_name: str) -> Tuple[Optional[str], Optional[int]]: + if not mapfile: + fail(f"No map file configured; cannot find function {fn_name}.") + + try: + with open(mapfile) as f: + contents = f.read() + except Exception: + fail(f"Failed to open map file {mapfile} for reading.") + + if map_format == 'gnu': + lines = contents.split("\n") + + try: + cur_objfile = None + ram_to_rom = None + cands = [] + last_line = "" + for line in lines: + if line.startswith(" .text"): + cur_objfile = line.split()[3] + if "load address" in line: + tokens = last_line.split() + line.split() + ram = int(tokens[1], 0) + rom = int(tokens[5], 0) + ram_to_rom = rom - ram + if line.endswith(" " + fn_name): + ram = int(line.split()[0], 0) + if cur_objfile is not None and ram_to_rom is not None: + cands.append((cur_objfile, ram + ram_to_rom)) + last_line = line + except Exception as e: + import traceback + + traceback.print_exc() + fail(f"Internal error while parsing map file") + + if len(cands) > 1: + fail(f"Found multiple occurrences of function {fn_name} in map file.") + if len(cands) == 1: + return cands[0] + elif map_format == 'mw': + # ram elf rom object name + find = re.findall(re.compile(r' \S+ \S+ (\S+) (\S+) . ' + fn_name + r'(?: \(entry of \.(?:init|text)\))? \t(\S+)'), contents) + if len(find) > 1: + fail(f"Found multiple occurrences of function {fn_name} in map file.") + if len(find) == 1: + rom = int(find[0][1],16) + objname = find[0][2] + # The metrowerks linker map format does not contain the full object path, so we must complete it manually. + objfiles = [os.path.join(dirpath, f) for dirpath, _, filenames in os.walk(mw_build_dir) for f in filenames if f == objname] + if len(objfiles) > 1: + all_objects = "\n".join(objfiles) + fail(f"Found multiple objects of the same name {objname} in {mw_build_dir}, cannot determine which to diff against: \n{all_objects}") + if len(objfiles) == 1: + objfile = objfiles[0] + # TODO Currently the ram-rom conversion only works for diffing ELF executables, but it would likely be more convenient to diff DOLs. + # At this time it is recommended to always use -o when running the diff script as this mode does not make use of the ram-rom conversion + return objfile, rom + else: + fail(f"Linker map format {map_format} unrecognised.") + return None, None + + +def dump_elf() -> Tuple[str, ObjdumpCommand, ObjdumpCommand]: + if not baseimg or not myimg: + fail("Missing myimg/baseimg in config.") + if base_shift: + fail("--base-shift not compatible with -e") + + start_addr = eval_int(args.start, "Start address must be an integer expression.") + + if args.end is not None: + end_addr = eval_int(args.end, "End address must be an integer expression.") + else: + end_addr = start_addr + MAX_FUNCTION_SIZE_BYTES + + flags1 = [ + f"--start-address={start_addr}", + f"--stop-address={end_addr}", + ] + + flags2 = [ + f"--disassemble={args.diff_elf_symbol}", + ] + + objdump_flags = ["-drz", "-j", ".text"] + return ( + myimg, + (objdump_flags + flags1, baseimg, None), + (objdump_flags + flags2 + maybe_get_objdump_source_flags(), myimg, None), + ) + + +def dump_objfile() -> Tuple[str, ObjdumpCommand, ObjdumpCommand]: + if base_shift: + fail("--base-shift not compatible with -o") + if args.end is not None: + fail("end address not supported together with -o") + if args.start.startswith("0"): + fail("numerical start address not supported with -o; pass a function name") + + objfile, _ = search_map_file(args.start) + if not objfile: + fail("Not able to find .o file for function.") + + if args.make: + run_make(objfile) + + if not os.path.isfile(objfile): + fail(f"Not able to find .o file for function: {objfile} is not a file.") + + refobjfile = objfile + if not os.path.isfile(refobjfile): + fail(f'Please ensure an OK .o file exists at "{refobjfile}".') + + objdump_flags = ["-drz"] + return ( + objfile, + (objdump_flags, refobjfile, args.start), + (objdump_flags + maybe_get_objdump_source_flags(), objfile, args.start), + ) + + +def dump_binary() -> Tuple[str, ObjdumpCommand, ObjdumpCommand]: + if not baseimg or not myimg: + fail("Missing myimg/baseimg in config.") + if args.make: + run_make(myimg) + start_addr = maybe_eval_int(args.start) + if start_addr is None: + _, start_addr = search_map_file(args.start) + if start_addr is None: + fail("Not able to find function in map file.") + if args.end is not None: + end_addr = eval_int(args.end, "End address must be an integer expression.") + else: + end_addr = start_addr + MAX_FUNCTION_SIZE_BYTES + objdump_flags = ["-Dz", "-bbinary", "-EB"] + flags1 = [ + f"--start-address={start_addr + base_shift}", + f"--stop-address={end_addr + base_shift}", + ] + flags2 = [f"--start-address={start_addr}", f"--stop-address={end_addr}"] + return ( + myimg, + (objdump_flags + flags1, baseimg, None), + (objdump_flags + flags2, myimg, None), + ) + + +def ansi_ljust(s: str, width: int) -> str: + """Like s.ljust(width), but accounting for ANSI colors.""" + needed: int = width - ansiwrap.ansilen(s) + if needed > 0: + return s + " " * needed + else: + return s + + +if arch == "mips": + re_int = re.compile(r"[0-9]+") + re_comment = re.compile(r"<.*?>") + re_reg = re.compile( + r"\$?\b(a[0-3]|t[0-9]|s[0-8]|at|v[01]|f[12]?[0-9]|f3[01]|k[01]|fp|ra|zero)\b" + ) + re_sprel = re.compile(r"(?<=,)([0-9]+|0x[0-9a-f]+)\(sp\)") + re_large_imm = re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}") + re_imm = re.compile(r"(\b|-)([0-9]+|0x[0-9a-fA-F]+)\b(?!\(sp)|%(lo|hi)\([^)]*\)") + forbidden = set(string.ascii_letters + "_") + arch_flags = ["-m", "mips:4300"] + branch_likely_instructions = { + "beql", + "bnel", + "beqzl", + "bnezl", + "bgezl", + "bgtzl", + "blezl", + "bltzl", + "bc1tl", + "bc1fl", + } + branch_instructions = branch_likely_instructions.union( + { + "b", + "beq", + "bne", + "beqz", + "bnez", + "bgez", + "bgtz", + "blez", + "bltz", + "bc1t", + "bc1f", + } + ) + instructions_with_address_immediates = branch_instructions.union({"jal", "j"}) +elif arch == "aarch64": + re_int = re.compile(r"[0-9]+") + re_comment = re.compile(r"(<.*?>|//.*$)") + # GPRs and FP registers: X0-X30, W0-W30, [DSHQ]0..31 + # The zero registers and SP should not be in this list. + re_reg = re.compile(r"\$?\b([dshq][12]?[0-9]|[dshq]3[01]|[xw][12]?[0-9]|[xw]30)\b") + re_sprel = re.compile(r"sp, #-?(0x[0-9a-fA-F]+|[0-9]+)\b") + re_large_imm = re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}") + re_imm = re.compile(r"(?|//.*$)") + re_reg = re.compile(r"\$?\b([rf][0-9]+)\b") + re_sprel = re.compile(r"(?<=,)(-?[0-9]+|-?0x[0-9a-f]+)\(r1\)") + re_large_imm = re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}") + re_imm = re.compile(r"(\b|-)([0-9]+|0x[0-9a-fA-F]+)\b(?!\(r1)|[^@]*@(ha|h|lo)") + arch_flags = [] + forbidden = set(string.ascii_letters + "_") + branch_likely_instructions = set() + branch_instructions = { + "b", + "beq", + "beq+", + "beq-", + "bne", + "bne+", + "bne-", + "blt", + "blt+", + "blt-", + "ble", + "ble+", + "ble-", + "bdnz", + "bdnz+", + "bdnz-", + "bge", + "bge+", + "bge-", + "bgt", + "bgt+", + "bgt-", + } + instructions_with_address_immediates = branch_instructions.union({"bl"}) +else: + fail(f"Unknown architecture: {arch}") + + +def hexify_int(row: str, pat: Match[str]) -> str: + full = pat.group(0) + if len(full) <= 1: + # leave one-digit ints alone + return full + start, end = pat.span() + if start and row[start - 1] in forbidden: + return full + if end < len(row) and row[end] in forbidden: + return full + return hex(int(full)) + + +def parse_relocated_line(line: str) -> Tuple[str, str, str]: + try: + ind2 = line.rindex(",") + except ValueError: + try: + ind2 = line.rindex("\t") + except ValueError: + ind2 = line.rindex(" ") + before = line[: ind2 + 1] + after = line[ind2 + 1 :] + ind2 = after.find("(") + if ind2 == -1: + imm, after = after, "" + else: + imm, after = after[:ind2], after[ind2:] + if imm == "0x0": + imm = "0" + return before, imm, after + + +def process_mips_reloc(row: str, prev: str) -> str: + before, imm, after = parse_relocated_line(prev) + repl = row.split()[-1] + if imm != "0": + # MIPS uses relocations with addends embedded in the code as immediates. + # If there is an immediate, show it as part of the relocation. Ideally + # we'd show this addend in both %lo/%hi, but annoyingly objdump's output + # doesn't include enough information to pair up %lo's and %hi's... + # TODO: handle unambiguous cases where all addends for a symbol are the + # same, or show "+???". + mnemonic = prev.split()[0] + if mnemonic in instructions_with_address_immediates and not imm.startswith("0x"): + imm = "0x" + imm + repl += "+" + imm if int(imm, 0) > 0 else imm + if "R_MIPS_LO16" in row: + repl = f"%lo({repl})" + elif "R_MIPS_HI16" in row: + # Ideally we'd pair up R_MIPS_LO16 and R_MIPS_HI16 to generate a + # correct addend for each, but objdump doesn't give us the order of + # the relocations, so we can't find the right LO16. :( + repl = f"%hi({repl})" + elif "R_MIPS_26" in row: + # Function calls + pass + elif "R_MIPS_PC16" in row: + # Branch to glabel. This gives confusing output, but there's not much + # we can do here. + pass + else: + assert False, f"unknown relocation type '{row}' for line '{prev}'" + return before + repl + after + + +def process_ppc_reloc(row: str, prev: str) -> str: + assert any(r in row for r in ["R_PPC_REL24", "R_PPC_ADDR16", "R_PPC_EMB_SDA21"]), f"unknown relocation type '{row}' for line '{prev}'" + before, imm, after = parse_relocated_line(prev) + repl = row.split()[-1] + if "R_PPC_REL24" in row: + # function calls + pass + elif "R_PPC_ADDR16_HI" in row: + # absolute hi of addr + repl = f"{repl}@h" + elif "R_PPC_ADDR16_HA" in row: + # adjusted hi of addr + repl = f"{repl}@ha" + elif "R_PPC_ADDR16_LO" in row: + # lo of addr + repl = f"{repl}@l" + elif "R_PPC_ADDR16" in row: + # 16-bit absolute addr + if "+0x7" in repl: + # remove the very large addends as they are an artifact of (label-_SDA(2)_BASE_) + # computations and are unimportant in a diff setting. + if int(repl.split("+")[1],16) > 0x70000000: + repl = repl.split("+")[0] + elif "R_PPC_EMB_SDA21" in row: + # small data area + pass + return before + repl + after + + +def pad_mnemonic(line: str) -> str: + if "\t" not in line: + return line + mn, args = line.split("\t", 1) + return f"{mn:<7s} {args}" + + +class Line(NamedTuple): + mnemonic: str + diff_row: str + original: str + normalized_original: str + line_num: str + branch_target: Optional[str] + source_lines: List[str] + comment: Optional[str] + + +class DifferenceNormalizer: + def normalize(self, mnemonic: str, row: str) -> str: + """This should be called exactly once for each line.""" + row = self._normalize_arch_specific(mnemonic, row) + if args.ignore_large_imms: + row = re.sub(re_large_imm, "", row) + return row + + def _normalize_arch_specific(self, mnemonic: str, row: str) -> str: + return row + + +class DifferenceNormalizerAArch64(DifferenceNormalizer): + def __init__(self) -> None: + super().__init__() + self._adrp_pair_registers: Set[str] = set() + + def _normalize_arch_specific(self, mnemonic: str, row: str) -> str: + if args.ignore_addr_diffs: + row = self._normalize_adrp_differences(mnemonic, row) + row = self._normalize_bl(mnemonic, row) + return row + + def _normalize_bl(self, mnemonic: str, row: str) -> str: + if mnemonic != "bl": + return row + + row, _ = split_off_branch(row) + return row + + def _normalize_adrp_differences(self, mnemonic: str, row: str) -> str: + """Identifies ADRP + LDR/ADD pairs that are used to access the GOT and + suppresses any immediate differences. + + Whenever an ADRP is seen, the destination register is added to the set of registers + that are part of an ADRP + LDR/ADD pair. Registers are removed from the set as soon + as they are used for an LDR or ADD instruction which completes the pair. + + This method is somewhat crude but should manage to detect most such pairs. + """ + row_parts = row.split("\t", 1) + if mnemonic == "adrp": + self._adrp_pair_registers.add(row_parts[1].strip().split(",")[0]) + row, _ = split_off_branch(row) + elif mnemonic == "ldr": + for reg in self._adrp_pair_registers: + # ldr xxx, [reg] + # ldr xxx, [reg, ] + if f", [{reg}" in row_parts[1]: + self._adrp_pair_registers.remove(reg) + return normalize_imms(row) + elif mnemonic == "add": + for reg in self._adrp_pair_registers: + # add reg, reg, + if row_parts[1].startswith(f"{reg}, {reg}, "): + self._adrp_pair_registers.remove(reg) + return normalize_imms(row) + + return row + + +def make_difference_normalizer() -> DifferenceNormalizer: + if arch == "aarch64": + return DifferenceNormalizerAArch64() + return DifferenceNormalizer() + + +def process(lines: List[str]) -> List[Line]: + normalizer = make_difference_normalizer() + skip_next = False + source_lines = [] + if not args.diff_obj: + lines = lines[7:] + if lines and not lines[-1]: + lines.pop() + + output: List[Line] = [] + stop_after_delay_slot = False + for row in lines: + if args.diff_obj and (">:" in row or not row): + continue + + if args.source and (row and row[0] != " "): + source_lines.append(row) + continue + + if "R_AARCH64_" in row: + # TODO: handle relocation + continue + + if "R_MIPS_" in row: + # N.B. Don't transform the diff rows, they already ignore immediates + # if output[-1].diff_row != "": + # output[-1] = output[-1].replace(diff_row=process_mips_reloc(row, output[-1].row_with_imm)) + new_original = process_mips_reloc(row, output[-1].original) + output[-1] = output[-1]._replace(original=new_original) + continue + + if "R_PPC_" in row: + new_original = process_ppc_reloc(row, output[-1].original) + output[-1] = output[-1]._replace(original=new_original) + continue + + m_comment = re.search(re_comment, row) + comment = m_comment[0] if m_comment else None + row = re.sub(re_comment, "", row) + row = row.rstrip() + tabs = row.split("\t") + row = "\t".join(tabs[2:]) + line_num = tabs[0].strip() + + if "\t" in row: + row_parts = row.split("\t", 1) + else: + # powerpc-eabi-objdump doesn't use tabs + row_parts = [part.lstrip() for part in row.split(" ", 1)] + mnemonic = row_parts[0].strip() + + if mnemonic not in instructions_with_address_immediates: + row = re.sub(re_int, lambda m: hexify_int(row, m), row) + original = row + normalized_original = normalizer.normalize(mnemonic, original) + if skip_next: + skip_next = False + row = "" + mnemonic = "" + if mnemonic in branch_likely_instructions: + skip_next = True + row = re.sub(re_reg, "", row) + row = re.sub(re_sprel, "addr(sp)", row) + row_with_imm = row + if mnemonic in instructions_with_address_immediates: + row = row.strip() + row, _ = split_off_branch(row) + row += "" + else: + row = normalize_imms(row) + + branch_target = None + if mnemonic in branch_instructions: + target = row_parts[1].strip().split(",")[-1] + if mnemonic in branch_likely_instructions: + target = hex(int(target, 16) - 4)[2:] + branch_target = target.strip() + + output.append( + Line( + mnemonic=mnemonic, + diff_row=row, + original=original, + normalized_original=normalized_original, + line_num=line_num, + branch_target=branch_target, + source_lines=source_lines, + comment=comment, + ) + ) + source_lines = [] + + if args.stop_jrra and mnemonic == "jr" and row_parts[1].strip() == "ra": + stop_after_delay_slot = True + elif stop_after_delay_slot: + break + + return output + + +def format_single_line_diff(line1: str, line2: str, column_width: int) -> str: + return ansi_ljust(line1, column_width) + line2 + + +class SymbolColorer: + symbol_colors: Dict[str, str] + + def __init__(self, base_index: int) -> None: + self.color_index = base_index + self.symbol_colors = {} + + def color_symbol(self, s: str, t: Optional[str] = None) -> str: + try: + color = self.symbol_colors[s] + except: + color = COLOR_ROTATION[self.color_index % len(COLOR_ROTATION)] + self.color_index += 1 + self.symbol_colors[s] = color + t = t or s + return f"{color}{t}{Fore.RESET}" + + +def normalize_imms(row: str) -> str: + return re.sub(re_imm, "", row) + + +def normalize_stack(row: str) -> str: + return re.sub(re_sprel, "addr(sp)", row) + + +def split_off_branch(line: str) -> Tuple[str, str]: + parts = line.split(",") + if len(parts) < 2: + parts = line.split(None, 1) + off = len(line) - len(parts[-1]) + return line[:off], line[off:] + +ColorFunction = Callable[[str], str] + +def color_fields(pat: Pattern[str], out1: str, out2: str, color1: ColorFunction, color2: Optional[ColorFunction]=None) -> Tuple[str, str]: + diffs = [of.group() != nf.group() for (of, nf) in zip(pat.finditer(out1), pat.finditer(out2))] + + it = iter(diffs) + def maybe_color(color: ColorFunction, s: str) -> str: + return color(s) if next(it, False) else f"{Style.RESET_ALL}{s}" + + out1 = pat.sub(lambda m: maybe_color(color1, m.group()), out1) + it = iter(diffs) + out2 = pat.sub(lambda m: maybe_color(color2 or color1, m.group()), out2) + + return out1, out2 + + +def color_branch_imms(br1: str, br2: str) -> Tuple[str, str]: + if br1 != br2: + br1 = f"{Fore.LIGHTBLUE_EX}{br1}{Style.RESET_ALL}" + br2 = f"{Fore.LIGHTBLUE_EX}{br2}{Style.RESET_ALL}" + return br1, br2 + + +def diff_sequences_difflib( + seq1: List[str], seq2: List[str] +) -> List[Tuple[str, int, int, int, int]]: + differ = difflib.SequenceMatcher(a=seq1, b=seq2, autojunk=False) + return differ.get_opcodes() + + +def diff_sequences( + seq1: List[str], seq2: List[str] +) -> List[Tuple[str, int, int, int, int]]: + if ( + args.algorithm != "levenshtein" + or len(seq1) * len(seq2) > 4 * 10 ** 8 + or len(seq1) + len(seq2) >= 0x110000 + ): + return diff_sequences_difflib(seq1, seq2) + + # The Levenshtein library assumes that we compare strings, not lists. Convert. + # (Per the check above we know we have fewer than 0x110000 unique elements, so chr() works.) + remapping: Dict[str, str] = {} + + def remap(seq: List[str]) -> str: + seq = seq[:] + for i in range(len(seq)): + val = remapping.get(seq[i]) + if val is None: + val = chr(len(remapping)) + remapping[seq[i]] = val + seq[i] = val + return "".join(seq) + + rem1 = remap(seq1) + rem2 = remap(seq2) + return Levenshtein.opcodes(rem1, rem2) # type: ignore + + +def diff_lines( + lines1: List[Line], + lines2: List[Line], +) -> List[Tuple[Optional[Line], Optional[Line]]]: + ret = [] + for (tag, i1, i2, j1, j2) in diff_sequences( + [line.mnemonic for line in lines1], + [line.mnemonic for line in lines2], + ): + for line1, line2 in itertools.zip_longest(lines1[i1:i2], lines2[j1:j2]): + if tag == "replace": + if line1 is None: + tag = "insert" + elif line2 is None: + tag = "delete" + elif tag == "insert": + assert line1 is None + elif tag == "delete": + assert line2 is None + ret.append((line1, line2)) + + return ret + + +class OutputLine: + base: Optional[str] + fmt2: str + key2: Optional[str] + + def __init__(self, base: Optional[str], fmt2: str, key2: Optional[str]) -> None: + self.base = base + self.fmt2 = fmt2 + self.key2 = key2 + + def __eq__(self, other: object) -> bool: + if not isinstance(other, OutputLine): + return NotImplemented + return self.key2 == other.key2 + + def __hash__(self) -> int: + return hash(self.key2) + + +def do_diff(basedump: str, mydump: str) -> List[OutputLine]: + output: List[OutputLine] = [] + + lines1 = process(basedump.split("\n")) + lines2 = process(mydump.split("\n")) + + sc1 = SymbolColorer(0) + sc2 = SymbolColorer(0) + sc3 = SymbolColorer(4) + sc4 = SymbolColorer(4) + sc5 = SymbolColorer(0) + sc6 = SymbolColorer(0) + bts1: Set[str] = set() + bts2: Set[str] = set() + + if args.show_branches: + for (lines, btset, sc) in [ + (lines1, bts1, sc5), + (lines2, bts2, sc6), + ]: + for line in lines: + bt = line.branch_target + if bt is not None: + btset.add(bt + ":") + sc.color_symbol(bt + ":") + + for (line1, line2) in diff_lines(lines1, lines2): + line_color1 = line_color2 = sym_color = Fore.RESET + line_prefix = " " + if line1 and line2 and line1.diff_row == line2.diff_row: + if line1.normalized_original == line2.normalized_original: + out1 = line1.original + out2 = line2.original + elif line1.diff_row == "": + out1 = f"{Style.BRIGHT}{Fore.LIGHTBLACK_EX}{line1.original}" + out2 = f"{Style.BRIGHT}{Fore.LIGHTBLACK_EX}{line2.original}" + else: + mnemonic = line1.original.split()[0] + out1, out2 = line1.original, line2.original + branch1 = branch2 = "" + if mnemonic in instructions_with_address_immediates: + out1, branch1 = split_off_branch(line1.original) + out2, branch2 = split_off_branch(line2.original) + branchless1 = out1 + branchless2 = out2 + out1, out2 = color_fields(re_imm, out1, out2, lambda s: f"{Fore.LIGHTBLUE_EX}{s}{Style.RESET_ALL}") + + same_relative_target = False + if line1.branch_target is not None and line2.branch_target is not None: + relative_target1 = eval_line_num(line1.branch_target) - eval_line_num(line1.line_num) + relative_target2 = eval_line_num(line2.branch_target) - eval_line_num(line2.line_num) + same_relative_target = relative_target1 == relative_target2 + + if not same_relative_target: + branch1, branch2 = color_branch_imms(branch1, branch2) + + out1 += branch1 + out2 += branch2 + if normalize_imms(branchless1) == normalize_imms(branchless2): + if not same_relative_target: + # only imms differences + sym_color = Fore.LIGHTBLUE_EX + line_prefix = "i" + else: + out1, out2 = color_fields(re_sprel, out1, out2, sc3.color_symbol, sc4.color_symbol) + if normalize_stack(branchless1) == normalize_stack(branchless2): + # only stack differences (luckily stack and imm + # differences can't be combined in MIPS, so we + # don't have to think about that case) + sym_color = Fore.YELLOW + line_prefix = "s" + else: + # regs differences and maybe imms as well + out1, out2 = color_fields(re_reg, out1, out2, sc1.color_symbol, sc2.color_symbol) + line_color1 = line_color2 = sym_color = Fore.YELLOW + line_prefix = "r" + elif line1 and line2: + line_prefix = "|" + line_color1 = Fore.LIGHTBLUE_EX + line_color2 = Fore.LIGHTBLUE_EX + sym_color = Fore.LIGHTBLUE_EX + out1 = line1.original + out2 = line2.original + elif line1: + line_prefix = "<" + line_color1 = sym_color = Fore.RED + out1 = line1.original + out2 = "" + elif line2: + line_prefix = ">" + line_color2 = sym_color = Fore.GREEN + out1 = "" + out2 = line2.original + + if args.source and line2 and line2.comment: + out2 += f" {line2.comment}" + + def format_part( + out: str, + line: Optional[Line], + line_color: str, + btset: Set[str], + sc: SymbolColorer, + ) -> Optional[str]: + if line is None: + return None + in_arrow = " " + out_arrow = "" + if args.show_branches: + if line.line_num in btset: + in_arrow = sc.color_symbol(line.line_num, "~>") + line_color + if line.branch_target is not None: + out_arrow = " " + sc.color_symbol(line.branch_target + ":", "~>") + out = pad_mnemonic(out) + return f"{line_color}{line.line_num} {in_arrow} {out}{Style.RESET_ALL}{out_arrow}" + + part1 = format_part(out1, line1, line_color1, bts1, sc5) + part2 = format_part(out2, line2, line_color2, bts2, sc6) + key2 = line2.original if line2 else None + + mid = f"{sym_color}{line_prefix}" + + if line2: + for source_line in line2.source_lines: + color = Style.DIM + # File names and function names + if source_line and source_line[0] != "│": + color += Style.BRIGHT + # Function names + if source_line.endswith("():"): + # Underline. Colorama does not provide this feature, unfortunately. + color += "\u001b[4m" + try: + source_line = cxxfilt.demangle( + source_line[:-3], external_only=False + ) + except: + pass + output.append( + OutputLine( + None, + f" {color}{source_line}{Style.RESET_ALL}", + source_line, + ) + ) + + fmt2 = mid + " " + (part2 or "") + output.append(OutputLine(part1, fmt2, key2)) + + return output + + +def chunk_diff(diff: List[OutputLine]) -> List[Union[List[OutputLine], OutputLine]]: + cur_right: List[OutputLine] = [] + chunks: List[Union[List[OutputLine], OutputLine]] = [] + for output_line in diff: + if output_line.base is not None: + chunks.append(cur_right) + chunks.append(output_line) + cur_right = [] + else: + cur_right.append(output_line) + chunks.append(cur_right) + return chunks + + +def format_diff( + old_diff: List[OutputLine], new_diff: List[OutputLine] +) -> Tuple[str, List[str]]: + old_chunks = chunk_diff(old_diff) + new_chunks = chunk_diff(new_diff) + output: List[Tuple[str, OutputLine, OutputLine]] = [] + assert len(old_chunks) == len(new_chunks), "same target" + empty = OutputLine("", "", None) + for old_chunk, new_chunk in zip(old_chunks, new_chunks): + if isinstance(old_chunk, list): + assert isinstance(new_chunk, list) + if not old_chunk and not new_chunk: + # Most of the time lines sync up without insertions/deletions, + # and there's no interdiffing to be done. + continue + differ = difflib.SequenceMatcher(a=old_chunk, b=new_chunk, autojunk=False) + for (tag, i1, i2, j1, j2) in differ.get_opcodes(): + if tag in ["equal", "replace"]: + for i, j in zip(range(i1, i2), range(j1, j2)): + output.append(("", old_chunk[i], new_chunk[j])) + if tag in ["insert", "replace"]: + for j in range(j1 + i2 - i1, j2): + output.append(("", empty, new_chunk[j])) + if tag in ["delete", "replace"]: + for i in range(i1 + j2 - j1, i2): + output.append(("", old_chunk[i], empty)) + else: + assert isinstance(new_chunk, OutputLine) + assert new_chunk.base + # old_chunk.base and new_chunk.base have the same text since + # both diffs are based on the same target, but they might + # differ in color. Use the new version. + output.append((new_chunk.base, old_chunk, new_chunk)) + + # TODO: status line, with e.g. approximate permuter score? + width = args.column_width + if args.threeway: + header_line = "TARGET".ljust(width) + " CURRENT".ljust(width) + " PREVIOUS" + diff_lines = [ + ansi_ljust(base, width) + + ansi_ljust(new.fmt2, width) + + (old.fmt2 or "-" if old != new else "") + for (base, old, new) in output + ] + else: + header_line = "" + diff_lines = [ + ansi_ljust(base, width) + new.fmt2 + for (base, old, new) in output + if base or new.key2 is not None + ] + return header_line, diff_lines + + +def debounced_fs_watch( + targets: List[str], + outq: "queue.Queue[Optional[float]]", + debounce_delay: float, +) -> None: + import watchdog.events # type: ignore + import watchdog.observers # type: ignore + + class WatchEventHandler(watchdog.events.FileSystemEventHandler): # type: ignore + def __init__( + self, queue: "queue.Queue[float]", file_targets: List[str] + ) -> None: + self.queue = queue + self.file_targets = file_targets + + def on_modified(self, ev: object) -> None: + if isinstance(ev, watchdog.events.FileModifiedEvent): + self.changed(ev.src_path) + + def on_moved(self, ev: object) -> None: + if isinstance(ev, watchdog.events.FileMovedEvent): + self.changed(ev.dest_path) + + def should_notify(self, path: str) -> bool: + for target in self.file_targets: + if path == target: + return True + if args.make and any( + path.endswith(suffix) for suffix in FS_WATCH_EXTENSIONS + ): + return True + return False + + def changed(self, path: str) -> None: + if self.should_notify(path): + self.queue.put(time.time()) + + def debounce_thread() -> NoReturn: + listenq: "queue.Queue[float]" = queue.Queue() + file_targets: List[str] = [] + event_handler = WatchEventHandler(listenq, file_targets) + observer = watchdog.observers.Observer() + observed = set() + for target in targets: + if os.path.isdir(target): + observer.schedule(event_handler, target, recursive=True) + else: + file_targets.append(target) + target = os.path.dirname(target) or "." + if target not in observed: + observed.add(target) + observer.schedule(event_handler, target) + observer.start() + while True: + t = listenq.get() + more = True + while more: + delay = t + debounce_delay - time.time() + if delay > 0: + time.sleep(delay) + # consume entire queue + more = False + try: + while True: + t = listenq.get(block=False) + more = True + except queue.Empty: + pass + outq.put(t) + + th = threading.Thread(target=debounce_thread, daemon=True) + th.start() + + +class Display: + basedump: str + mydump: str + emsg: Optional[str] + last_diff_output: Optional[List[OutputLine]] + pending_update: Optional[Tuple[str, bool]] + ready_queue: "queue.Queue[None]" + watch_queue: "queue.Queue[Optional[float]]" + less_proc: "Optional[subprocess.Popen[bytes]]" + + def __init__(self, basedump: str, mydump: str) -> None: + self.basedump = basedump + self.mydump = mydump + self.emsg = None + self.last_diff_output = None + + def run_less(self) -> "Tuple[subprocess.Popen[bytes], subprocess.Popen[bytes]]": + if self.emsg is not None: + output = self.emsg + else: + diff_output = do_diff(self.basedump, self.mydump) + last_diff_output = self.last_diff_output or diff_output + if args.threeway != "base" or not self.last_diff_output: + self.last_diff_output = diff_output + header, diff_lines = format_diff(last_diff_output, diff_output) + header_lines = [header] if header else [] + output = "\n".join(header_lines + diff_lines[args.skip_lines :]) + + # Pipe the output through 'tail' and only then to less, to ensure the + # write call doesn't block. ('tail' has to buffer all its input before + # it starts writing.) This also means we don't have to deal with pipe + # closure errors. + buffer_proc = subprocess.Popen( + BUFFER_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) + less_proc = subprocess.Popen(LESS_CMD, stdin=buffer_proc.stdout) + assert buffer_proc.stdin + assert buffer_proc.stdout + buffer_proc.stdin.write(output.encode()) + buffer_proc.stdin.close() + buffer_proc.stdout.close() + return (buffer_proc, less_proc) + + def run_sync(self) -> None: + proca, procb = self.run_less() + procb.wait() + proca.wait() + + def run_async(self, watch_queue: "queue.Queue[Optional[float]]") -> None: + self.watch_queue = watch_queue + self.ready_queue = queue.Queue() + self.pending_update = None + dthread = threading.Thread(target=self.display_thread) + dthread.start() + self.ready_queue.get() + + def display_thread(self) -> None: + proca, procb = self.run_less() + self.less_proc = procb + self.ready_queue.put(None) + while True: + ret = procb.wait() + proca.wait() + self.less_proc = None + if ret != 0: + # fix the terminal + os.system("tput reset") + if ret != 0 and self.pending_update is not None: + # killed by program with the intent to refresh + msg, error = self.pending_update + self.pending_update = None + if not error: + self.mydump = msg + self.emsg = None + else: + self.emsg = msg + proca, procb = self.run_less() + self.less_proc = procb + self.ready_queue.put(None) + else: + # terminated by user, or killed + self.watch_queue.put(None) + self.ready_queue.put(None) + break + + def progress(self, msg: str) -> None: + # Write message to top-left corner + sys.stdout.write("\x1b7\x1b[1;1f{}\x1b8".format(msg + " ")) + sys.stdout.flush() + + def update(self, text: str, error: bool) -> None: + if not error and not self.emsg and text == self.mydump: + self.progress("Unchanged. ") + return + self.pending_update = (text, error) + if not self.less_proc: + return + self.less_proc.kill() + self.ready_queue.get() + + def terminate(self) -> None: + if not self.less_proc: + return + self.less_proc.kill() + self.ready_queue.get() + + +def main() -> None: + if args.diff_elf_symbol: + make_target, basecmd, mycmd = dump_elf() + elif args.diff_obj: + make_target, basecmd, mycmd = dump_objfile() + else: + make_target, basecmd, mycmd = dump_binary() + + if args.write_asm is not None: + mydump = run_objdump(mycmd) + with open(args.write_asm, "w") as f: + f.write(mydump) + print(f"Wrote assembly to {args.write_asm}.") + sys.exit(0) + + if args.base_asm is not None: + with open(args.base_asm) as f: + basedump = f.read() + else: + basedump = run_objdump(basecmd) + + mydump = run_objdump(mycmd) + + display = Display(basedump, mydump) + + if not args.watch: + display.run_sync() + else: + if not args.make: + yn = input( + "Warning: watch-mode (-w) enabled without auto-make (-m). " + "You will have to run make manually. Ok? (Y/n) " + ) + if yn.lower() == "n": + return + if args.make: + watch_sources = None + watch_sources_for_target_fn = getattr( + diff_settings, "watch_sources_for_target", None + ) + if watch_sources_for_target_fn: + watch_sources = watch_sources_for_target_fn(make_target) + watch_sources = watch_sources or source_directories + if not watch_sources: + fail("Missing source_directories config, don't know what to watch.") + else: + watch_sources = [make_target] + q: "queue.Queue[Optional[float]]" = queue.Queue() + debounced_fs_watch(watch_sources, q, DEBOUNCE_DELAY) + display.run_async(q) + last_build = 0.0 + try: + while True: + t = q.get() + if t is None: + break + if t < last_build: + continue + last_build = time.time() + if args.make: + display.progress("Building...") + ret = run_make_capture_output(make_target) + if ret.returncode != 0: + display.update( + ret.stderr.decode("utf-8-sig", "replace") + or ret.stdout.decode("utf-8-sig", "replace"), + error=True, + ) + continue + mydump = run_objdump(mycmd) + display.update(mydump, error=False) + except KeyboardInterrupt: + display.terminate() + + +main() diff --git a/include/JSystem/JUtility/asm/JUTResFont__dtor.s b/include/JSystem/JUtility/asm/JUTResFont__dtor.s new file mode 100644 index 0000000000..5b4c35ae31 --- /dev/null +++ b/include/JSystem/JUtility/asm/JUTResFont__dtor.s @@ -0,0 +1,38 @@ +/* 802DF000 002DBF40 94 21 FF F0 */ stwu r1,-0x10(r1) +/* 802DF004 002DBF44 7C 08 02 A6 */ mflr r0 +/* 802DF008 002DBF48 90 01 00 14 */ stw r0,0x14(r1) +/* 802DF00C 002DBF4C 93 E1 00 0C */ stw r31,0xc(r1) +/* 802DF010 002DBF50 93 C1 00 08 */ stw r30,8(r1) +/* 802DF014 002DBF54 7C 7E 1B 79 */ or. r30,r3,r3 +/* 802DF018 002DBF58 7C 9F 23 78 */ mr r31,r4 +/* 802DF01C 002DBF5C 41 82 00 54 */ beq lbl_802DF070 +/* 802DF020 002DBF60 3C 80 80 3D */ lis r4,lbl_803CC5A0@ha +/* 802DF024 002DBF64 38 04 C5 A0 */ addi r0,r4,lbl_803CC5A0@l +/* 802DF028 002DBF68 90 1E 00 00 */ stw r0,0(r30) +/* 802DF02C 002DBF6C 88 1E 00 04 */ lbz r0,4(r30) +/* 802DF030 002DBF70 28 00 00 00 */ cmplwi r0,0 +/* 802DF034 002DBF74 41 82 00 18 */ beq lbl_802DF04C +/* 802DF038 002DBF78 48 00 00 55 */ bl deleteMemBlocks_ResFont__10JUTResFontFv +/* 802DF03C 002DBF7C 7F C3 F3 78 */ mr r3,r30 +/* 802DF040 002DBF80 48 00 00 71 */ bl initialize_state__10JUTResFontFv +/* 802DF044 002DBF84 7F C3 F3 78 */ mr r3,r30 +/* 802DF048 002DBF88 4B FF FC DD */ bl initialize_state__7JUTFontFv +lbl_802DF04C: +/* 802DF04C 002DBF8C 28 1E 00 00 */ cmplwi r30,0 +/* 802DF050 002DBF90 41 82 00 10 */ beq lbl_802DF060 +/* 802DF054 002DBF94 3C 60 80 3A */ lis r3,lbl_803A31F0@ha +/* 802DF058 002DBF98 38 03 31 F0 */ addi r0,r3,lbl_803A31F0@l +/* 802DF05C 002DBF9C 90 1E 00 00 */ stw r0,0(r30) +lbl_802DF060: +/* 802DF060 002DBFA0 7F E0 07 35 */ extsh.r0,r31 +/* 802DF064 002DBFA4 40 81 00 0C */ ble lbl_802DF070 +/* 802DF068 002DBFA8 7F C3 F3 78 */ mr r3,r30 +/* 802DF06C 002DBFAC 4B FE FC D1 */ bl __dl__FPv +lbl_802DF070: +/* 802DF070 002DBFB0 7F C3 F3 78 */ mr r3,r30 +/* 802DF074 002DBFB4 83 E1 00 0C */ lwz r31,0xc(r1) +/* 802DF078 002DBFB8 83 C1 00 08 */ lwz r30,8(r1) +/* 802DF07C 002DBFBC 80 01 00 14 */ lwz r0,0x14(r1) +/* 802DF080 002DBFC0 7C 08 03 A6 */ mtlr r0 +/* 802DF084 002DBFC4 38 21 00 10 */ addi r1,r1,0x10 +/* 802DF088 002DBFC8 4E 80 00 20 */ blr \ No newline at end of file diff --git a/include/SComponent/c_phase/asm/func_80266678.s b/include/SComponent/c_phase/asm/func_80266678.s new file mode 100644 index 0000000000..4eb68aec8f --- /dev/null +++ b/include/SComponent/c_phase/asm/func_80266678.s @@ -0,0 +1,28 @@ +/* 80266678 002635B8 94 21 FF F0 */ stwu r1,-0x10(r1) +/* 8026667C 002635BC 7C 08 02 A6 */ mflr r0 +/* 80266680 002635C0 90 01 00 14 */ stw r0,0x14(r1) +/* 80266684 002635C4 80 A3 00 00 */ lwz r5,0(r3) +/* 80266688 002635C8 28 05 00 00 */ cmplwi r5,0 +/* 8026668C 002635CC 41 82 00 38 */ beq lbl_802666C4 +/* 80266690 002635D0 80 83 00 04 */ lwz r4,4(r3) +/* 80266694 002635D4 38 04 00 01 */ addi r0,r4,1 +/* 80266698 002635D8 90 03 00 04 */ stw r0,4(r3) +/* 8026669C 002635DC 80 03 00 04 */ lwz r0,4(r3) +/* 802666A0 002635E0 54 00 10 3A */ slwi r0,r0,2 +/* 802666A4 002635E4 7C 05 00 2E */ lwzx r0,r5,r0 +/* 802666A8 002635E8 28 00 00 00 */ cmplwi r0,0 +/* 802666AC 002635EC 41 82 00 08 */ beq lbl_802666B4 +/* 802666B0 002635F0 40 82 00 0C */ bne lbl_802666BC +lbl_802666B4: +/* 802666B4 002635F4 4B FF FF B5 */ bl cPhs_Compleate +/* 802666B8 002635F8 48 00 00 10 */ b lbl_802666C8 +lbl_802666BC: +/* 802666BC 002635FC 38 60 00 01 */ li r3,1 +/* 802666C0 00263600 48 00 00 08 */ b lbl_802666C8 +lbl_802666C4: +/* 802666C4 00263604 38 60 00 04 */ li r3,4 +lbl_802666C8: +/* 802666C8 00263608 80 01 00 14 */ lwz r0,0x14(r1) +/* 802666CC 0026360C 7C 08 03 A6 */ mtlr r0 +/* 802666D0 00263610 38 21 00 10 */ addi r1,r1,0x10 +/* 802666D4 00263614 4E 80 00 20 */ blr \ No newline at end of file diff --git a/include/SComponent/c_phase/asm/func_802666D8.s b/include/SComponent/c_phase/asm/func_802666D8.s new file mode 100644 index 0000000000..3fa4be969b --- /dev/null +++ b/include/SComponent/c_phase/asm/func_802666D8.s @@ -0,0 +1,61 @@ +/* 802666D8 00263618 94 21 FF F0 */ stwu r1,-0x10(r1) +/* 802666DC 0026361C 7C 08 02 A6 */ mflr r0 +/* 802666E0 00263620 90 01 00 14 */ stw r0,0x14(r1) +/* 802666E4 00263624 93 E1 00 0C */ stw r31,0xc(r1) +/* 802666E8 00263628 7C 7F 1B 78 */ mr r31,r3 +/* 802666EC 0026362C 80 A3 00 00 */ lwz r5,0(r3) +/* 802666F0 00263630 28 05 00 00 */ cmplwi r5,0 +/* 802666F4 00263634 41 82 00 A0 */ beq lbl_80266794 +/* 802666F8 00263638 80 1F 00 04 */ lwz r0,4(r31) +/* 802666FC 0026363C 54 00 10 3A */ slwi r0,r0,2 +/* 80266700 00263640 7C 83 23 78 */ mr r3,r4 +/* 80266704 00263644 7D 85 00 2E */ lwzx r12,r5,r0 +/* 80266708 00263648 7D 89 03 A6 */ mtctr r12 +/* 8026670C 0026364C 4E 80 04 21 */ bctrl +/* 80266710 00263650 2C 03 00 03 */ cmpwi r3,3 +/* 80266714 00263654 41 82 00 5C */ beq lbl_80266770 +/* 80266718 00263658 40 80 00 14 */ bge lbl_8026672C +/* 8026671C 0026365C 2C 03 00 01 */ cmpwi r3,1 +/* 80266720 00263660 41 82 00 1C */ beq lbl_8026673C +/* 80266724 00263664 40 80 00 24 */ bge lbl_80266748 +/* 80266728 00263668 48 00 00 70 */ b lbl_80266798 +lbl_8026672C: +/* 8026672C 0026366C 2C 03 00 05 */ cmpwi r3,5 +/* 80266730 00263670 41 82 00 50 */ beq lbl_80266780 +/* 80266734 00263674 40 80 00 64 */ bge lbl_80266798 +/* 80266738 00263678 48 00 00 2C */ b lbl_80266764 +lbl_8026673C: +/* 8026673C 0026367C 7F E3 FB 78 */ mr r3,r31 +/* 80266740 00263680 4B FF FF 39 */ bl cPhs_Next +/* 80266744 00263684 48 00 00 54 */ b lbl_80266798 +lbl_80266748: +/* 80266748 00263688 7F E3 FB 78 */ mr r3,r31 +/* 8026674C 0026368C 4B FF FF 2D */ bl cPhs_Next +/* 80266750 00263690 2C 03 00 01 */ cmpwi r3,1 +/* 80266754 00263694 38 60 00 04 */ li r3,4 +/* 80266758 00263698 40 82 00 40 */ bne lbl_80266798 +/* 8026675C 0026369C 38 60 00 02 */ li r3,2 +/* 80266760 002636A0 48 00 00 38 */ b lbl_80266798 +lbl_80266764: +/* 80266764 002636A4 7F E3 FB 78 */ mr r3,r31 +/* 80266768 002636A8 4B FF FF 01 */ bl cPhs_Compleate +/* 8026676C 002636AC 48 00 00 2C */ b lbl_80266798 +lbl_80266770: +/* 80266770 002636B0 7F E3 FB 78 */ mr r3,r31 +/* 80266774 002636B4 4B FF FE CD */ bl cPhs_UnCompleate +/* 80266778 002636B8 38 60 00 03 */ li r3,3 +/* 8026677C 002636BC 48 00 00 1C */ b lbl_80266798 +lbl_80266780: +/* 80266780 002636C0 7F E3 FB 78 */ mr r3,r31 +/* 80266784 002636C4 4B FF FE BD */ bl cPhs_UnCompleate +/* 80266788 002636C8 38 60 00 05 */ li r3,5 +/* 8026678C 002636CC 48 00 00 0C */ b lbl_80266798 +/* 80266790 002636D0 48 00 00 08 */ b lbl_80266798 +lbl_80266794: +/* 80266794 002636D4 4B FF FE D5 */ bl cPhs_Compleate +lbl_80266798: +/* 80266798 002636D8 83 E1 00 0C */ lwz r31,0xc(r1) +/* 8026679C 002636DC 80 01 00 14 */ lwz r0,0x14(r1) +/* 802667A0 002636E0 7C 08 03 A6 */ mtlr r0 +/* 802667A4 002636E4 38 21 00 10 */ addi r1,r1,0x10 +/* 802667A8 002636E8 4E 80 00 20 */ blr \ No newline at end of file diff --git a/include/d/d_item/d_item/d_item.h b/include/d/d_item/d_item/d_item.h index 8a08078186..1ef68a5b99 100644 --- a/include/d/d_item/d_item/d_item.h +++ b/include/d/d_item/d_item/d_item.h @@ -1,6 +1,8 @@ #ifndef D_ITEM_H_ #define D_ITEM_H_ +#include "global.h" + int checkItemGet(u8, int); extern int (*item_func_ptr[256])(void); diff --git a/include/f/f_pc/f_pc_create_req/asm/func_80020BA0.s b/include/f/f_pc/f_pc_create_req/asm/func_80020BA0.s new file mode 100644 index 0000000000..64385768df --- /dev/null +++ b/include/f/f_pc/f_pc_create_req/asm/func_80020BA0.s @@ -0,0 +1,32 @@ +/* 80020BA0 0001DAE0 94 21 FF F0 */ stwu r1, -0x10(r1) +/* 80020BA4 0001DAE4 7C 08 02 A6 */ mflr r0 +/* 80020BA8 0001DAE8 90 01 00 14 */ stw r0, 0x14(r1) +/* 80020BAC 0001DAEC 93 E1 00 0C */ stw r31, 0xc(r1) +/* 80020BB0 0001DAF0 7C 7F 1B 78 */ mr r31,r3 +/* 80020BB4 0001DAF4 4B FF FF 6D */ bl fpcCtRq_CreateQTo +/* 80020BB8 0001DAF8 80 7F 00 34 */ lwz r3, 0x34(r31) +/* 80020BBC 0001DAFC 28 03 00 00 */ cmplwi r3, 0 +/* 80020BC0 0001DB00 41 82 00 20 */ beq lbl_80020BE0 +/* 80020BC4 0001DB04 80 63 00 08 */ lwz r3,8(r3) +/* 80020BC8 0001DB08 7F E4 FB 78 */ mr r4,r31 +/* 80020BCC 0001DB0C 48 00 18 5D */ bl fpcMtd_Method +/* 80020BD0 0001DB10 2C 03 00 00 */ cmpwi r3, 0 +/* 80020BD4 0001DB14 40 82 00 0C */ bne lbl_80020BE0 +/* 80020BD8 0001DB18 38 60 00 00 */ li r3,0 +/* 80020BDC 0001DB1C 48 00 00 24 */ b lbl_80020C00 +lbl_80020BE0 : +/* 80020BE0 0001DB20 80 7F 00 40 */ lwz r3,0x40(r31) +/* 80020BE4 0001DB24 28 03 00 00 */ cmplwi r3,0 +/* 80020BE8 0001DB28 41 82 00 0C */ beq lbl_80020BF4 +/* 80020BEC 0001DB2C 38 00 00 00 */ li r0,0 +/* 80020BF0 0001DB30 90 03 00 14 */ stw r0,0x14(r3) +lbl_80020BF4 : +/* 80020BF4 0001DB34 7F E3 FB 78 */ mr r3,r31 +/* 80020BF8 0001DB38 48 24 26 69 */ bl cMl_NS_free +/* 80020BFC 0001DB3C 38 60 00 01 */ li r3,1 +lbl_80020C00 : +/* 80020C00 0001DB40 83 E1 00 0C */ lwz r31,0xc(r1) +/* 80020C04 0001DB44 80 01 00 14 */ lwz r0,0x14(r1) +/* 80020C08 0001DB48 7C 08 03 A6 */ mtlr r0 +/* 80020C0C 0001DB4C 38 21 00 10 */ addi r1,r1,0x10 +/* 80020C10 0001DB50 4E 80 00 20 */ blr \ No newline at end of file diff --git a/include/f/f_pc/f_pc_pause/asm/func_80023844.s b/include/f/f_pc/f_pc_pause/asm/func_80023844.s new file mode 100644 index 0000000000..c479981966 --- /dev/null +++ b/include/f/f_pc/f_pc_pause/asm/func_80023844.s @@ -0,0 +1,9 @@ +/* 80023844 00020784 54 84 06 3E */ clrlwi r4, r4, 0x18 +/* 80023848 00020788 88 03 00 0B */ lbz r0, 0xb(r3) +/* 8002384C 0002078C 7C 80 00 38 */ and r0,r4,r0 +/* 80023850 00020790 7C 64 00 50 */ subf r3,r4,r0 +/* 80023854 00020794 30 03 FF FF */ addic r0,r3,-1 +/* 80023858 00020798 7C 00 19 10 */ subfe r0,r0,r3 +/* 8002385C 0002079C 7C 00 00 34 */ cntlzw r0,r0 +/* 80023860 000207A0 54 03 D9 7E */ srwi r3,r0,5 +/* 80023864 000207A4 4E 80 00 20 */ blr \ No newline at end of file diff --git a/libs/JSystem/JUtility/JUTResFont.cpp b/libs/JSystem/JUtility/JUTResFont.cpp index 2bfc841600..acb6382635 100644 --- a/libs/JSystem/JUtility/JUTResFont.cpp +++ b/libs/JSystem/JUtility/JUTResFont.cpp @@ -49,70 +49,7 @@ JUTResFont::~JUTResFont() { #else asm JUTResFont::~JUTResFont() { nofralloc - /* 802DF000 002DBF40 94 21 FF F0 */ stwu r1, - -0x10(r1) - /* 802DF004 002DBF44 7C 08 02 A6 */ mflr r0 - /* 802DF008 002DBF48 90 01 00 14 */ stw r0, - 0x14(r1) - /* 802DF00C 002DBF4C 93 E1 00 0C */ stw r31, - 0xc(r1) - /* 802DF010 002DBF50 93 C1 00 08 */ stw r30, - 8(r1) - /* 802DF014 002DBF54 7C 7E 1B 79 */ - or.r30, - r3, - r3 - /* 802DF018 002DBF58 7C 9F 23 78 */ mr r31, - r4 - /* 802DF01C 002DBF5C 41 82 00 54 */ beq lbl_802DF070 - /* 802DF020 002DBF60 3C 80 80 3D */ lis r4, - lbl_803CC5A0 @ha - /* 802DF024 002DBF64 38 04 C5 A0 */ addi r0, - r4, - lbl_803CC5A0 @l - /* 802DF028 002DBF68 90 1E 00 00 */ stw r0, - 0(r30) - /* 802DF02C 002DBF6C 88 1E 00 04 */ lbz r0, - 4(r30) - /* 802DF030 002DBF70 28 00 00 00 */ cmplwi r0, - 0 - /* 802DF034 002DBF74 41 82 00 18 */ beq lbl_802DF04C - /* 802DF038 002DBF78 48 00 00 55 */ bl deleteMemBlocks_ResFont__10JUTResFontFv - /* 802DF03C 002DBF7C 7F C3 F3 78 */ mr r3, - r30 - /* 802DF040 002DBF80 48 00 00 71 */ bl initialize_state__10JUTResFontFv - /* 802DF044 002DBF84 7F C3 F3 78 */ mr r3, - r30 - /* 802DF048 002DBF88 4B FF FC DD */ bl initialize_state__7JUTFontFv lbl_802DF04C : - /* 802DF04C 002DBF8C 28 1E 00 00 */ cmplwi r30, - 0 - /* 802DF050 002DBF90 41 82 00 10 */ beq lbl_802DF060 - /* 802DF054 002DBF94 3C 60 80 3A */ lis r3, - lbl_803A31F0 @ha - /* 802DF058 002DBF98 38 03 31 F0 */ addi r0, - r3, - lbl_803A31F0 @l - /* 802DF05C 002DBF9C 90 1E 00 00 */ stw r0, - 0(r30)lbl_802DF060 : - /* 802DF060 002DBFA0 7F E0 07 35 */ extsh.r0, - r31 - /* 802DF064 002DBFA4 40 81 00 0C */ ble lbl_802DF070 - /* 802DF068 002DBFA8 7F C3 F3 78 */ mr r3, - r30 - /* 802DF06C 002DBFAC 4B FE FC D1 */ bl __dl__FPv lbl_802DF070 : - /* 802DF070 002DBFB0 7F C3 F3 78 */ mr r3, - r30 - /* 802DF074 002DBFB4 83 E1 00 0C */ lwz r31, - 0xc(r1) - /* 802DF078 002DBFB8 83 C1 00 08 */ lwz r30, - 8(r1) - /* 802DF07C 002DBFBC 80 01 00 14 */ lwz r0, - 0x14(r1) - /* 802DF080 002DBFC0 7C 08 03 A6 */ mtlr r0 - /* 802DF084 002DBFC4 38 21 00 10 */ addi r1, - r1, - 0x10 - /* 802DF088 002DBFC8 4E 80 00 20 */ blr +#include "JSystem/JUtility/asm/JUTResFont__dtor.s" } #endif diff --git a/libs/SSystem/SComponent/c_phase.cpp b/libs/SSystem/SComponent/c_phase.cpp index 7b6a8439fc..a815b2ab63 100644 --- a/libs/SSystem/SComponent/c_phase.cpp +++ b/libs/SSystem/SComponent/c_phase.cpp @@ -39,49 +39,7 @@ int cPhs_Next(request_of_phase_process_class* pPhase) { #else asm int cPhs_Next(request_of_phase_process_class* pPhase) { nofralloc - /* 80266678 002635B8 94 21 FF F0 */ stwu r1, - -0x10(r1) - /* 8026667C 002635BC 7C 08 02 A6 */ mflr r0 - /* 80266680 002635C0 90 01 00 14 */ stw r0, - 0x14(r1) - /* 80266684 002635C4 80 A3 00 00 */ lwz r5, - 0(r3) - /* 80266688 002635C8 28 05 00 00 */ cmplwi r5, - 0 - /* 8026668C 002635CC 41 82 00 38 */ beq lbl_802666C4 - /* 80266690 002635D0 80 83 00 04 */ lwz r4, - 4(r3) - /* 80266694 002635D4 38 04 00 01 */ addi r0, - r4, - 1 - /* 80266698 002635D8 90 03 00 04 */ stw r0, - 4(r3) - /* 8026669C 002635DC 80 03 00 04 */ lwz r0, - 4(r3) - /* 802666A0 002635E0 54 00 10 3A */ slwi r0, - r0, - 2 - /* 802666A4 002635E4 7C 05 00 2E */ lwzx r0, - r5, - r0 - /* 802666A8 002635E8 28 00 00 00 */ cmplwi r0, - 0 - /* 802666AC 002635EC 41 82 00 08 */ beq lbl_802666B4 - /* 802666B0 002635F0 40 82 00 0C */ bne lbl_802666BC lbl_802666B4 : - /* 802666B4 002635F4 4B FF FF B5 */ bl cPhs_Compleate - /* 802666B8 002635F8 48 00 00 10 */ b lbl_802666C8 lbl_802666BC : - /* 802666BC 002635FC 38 60 00 01 */ li r3, - 1 - /* 802666C0 00263600 48 00 00 08 */ b lbl_802666C8 lbl_802666C4 : - /* 802666C4 00263604 38 60 00 04 */ li r3, - 4 lbl_802666C8 : - /* 802666C8 00263608 80 01 00 14 */ lwz r0, - 0x14(r1) - /* 802666CC 0026360C 7C 08 03 A6 */ mtlr r0 - /* 802666D0 00263610 38 21 00 10 */ addi r1, - r1, - 0x10 - /* 802666D4 00263614 4E 80 00 20 */ blr +#include "SComponent/c_phase/asm/func_80266678.s" } #endif @@ -119,88 +77,7 @@ int cPhs_Do(request_of_phase_process_class* pPhase, void* pUserData) { #else asm int cPhs_Do(request_of_phase_process_class* pPhase, void* pUserData) { nofralloc - /* 802666D8 00263618 94 21 FF F0 */ stwu r1, - -0x10(r1) - /* 802666DC 0026361C 7C 08 02 A6 */ mflr r0 - /* 802666E0 00263620 90 01 00 14 */ stw r0, - 0x14(r1) - /* 802666E4 00263624 93 E1 00 0C */ stw r31, - 0xc(r1) - /* 802666E8 00263628 7C 7F 1B 78 */ mr r31, - r3 - /* 802666EC 0026362C 80 A3 00 00 */ lwz r5, - 0(r3) - /* 802666F0 00263630 28 05 00 00 */ cmplwi r5, - 0 - /* 802666F4 00263634 41 82 00 A0 */ beq lbl_80266794 - /* 802666F8 00263638 80 1F 00 04 */ lwz r0, - 4(r31) - /* 802666FC 0026363C 54 00 10 3A */ slwi r0, - r0, - 2 - /* 80266700 00263640 7C 83 23 78 */ mr r3, - r4 - /* 80266704 00263644 7D 85 00 2E */ lwzx r12, - r5, - r0 - /* 80266708 00263648 7D 89 03 A6 */ mtctr r12 - /* 8026670C 0026364C 4E 80 04 21 */ bctrl - /* 80266710 00263650 2C 03 00 03 */ cmpwi r3, - 3 - /* 80266714 00263654 41 82 00 5C */ beq lbl_80266770 - /* 80266718 00263658 40 80 00 14 */ bge lbl_8026672C - /* 8026671C 0026365C 2C 03 00 01 */ cmpwi r3, - 1 - /* 80266720 00263660 41 82 00 1C */ beq lbl_8026673C - /* 80266724 00263664 40 80 00 24 */ bge lbl_80266748 - /* 80266728 00263668 48 00 00 70 */ b lbl_80266798 lbl_8026672C : - /* 8026672C 0026366C 2C 03 00 05 */ cmpwi r3, - 5 - /* 80266730 00263670 41 82 00 50 */ beq lbl_80266780 - /* 80266734 00263674 40 80 00 64 */ bge lbl_80266798 - /* 80266738 00263678 48 00 00 2C */ b lbl_80266764 lbl_8026673C : - /* 8026673C 0026367C 7F E3 FB 78 */ mr r3, - r31 - /* 80266740 00263680 4B FF FF 39 */ bl cPhs_Next - /* 80266744 00263684 48 00 00 54 */ b lbl_80266798 lbl_80266748 : - /* 80266748 00263688 7F E3 FB 78 */ mr r3, - r31 - /* 8026674C 0026368C 4B FF FF 2D */ bl cPhs_Next - /* 80266750 00263690 2C 03 00 01 */ cmpwi r3, - 1 - /* 80266754 00263694 38 60 00 04 */ li r3, - 4 - /* 80266758 00263698 40 82 00 40 */ bne lbl_80266798 - /* 8026675C 0026369C 38 60 00 02 */ li r3, - 2 - /* 80266760 002636A0 48 00 00 38 */ b lbl_80266798 lbl_80266764 : - /* 80266764 002636A4 7F E3 FB 78 */ mr r3, - r31 - /* 80266768 002636A8 4B FF FF 01 */ bl cPhs_Compleate - /* 8026676C 002636AC 48 00 00 2C */ b lbl_80266798 lbl_80266770 : - /* 80266770 002636B0 7F E3 FB 78 */ mr r3, - r31 - /* 80266774 002636B4 4B FF FE CD */ bl cPhs_UnCompleate - /* 80266778 002636B8 38 60 00 03 */ li r3, - 3 - /* 8026677C 002636BC 48 00 00 1C */ b lbl_80266798 lbl_80266780 : - /* 80266780 002636C0 7F E3 FB 78 */ mr r3, - r31 - /* 80266784 002636C4 4B FF FE BD */ bl cPhs_UnCompleate - /* 80266788 002636C8 38 60 00 05 */ li r3, - 5 - /* 8026678C 002636CC 48 00 00 0C */ b lbl_80266798 - /* 80266790 002636D0 48 00 00 08 */ b lbl_80266798 lbl_80266794 : - /* 80266794 002636D4 4B FF FE D5 */ bl cPhs_Compleate lbl_80266798 : - /* 80266798 002636D8 83 E1 00 0C */ lwz r31, - 0xc(r1) - /* 8026679C 002636DC 80 01 00 14 */ lwz r0, - 0x14(r1) - /* 802667A0 002636E0 7C 08 03 A6 */ mtlr r0 - /* 802667A4 002636E4 38 21 00 10 */ addi r1, - r1, - 0x10 - /* 802667A8 002636E8 4E 80 00 20 */ blr +#include "SComponent/c_phase/asm/func_802666D8.s" } #endif diff --git a/obj_files.mk b/obj_files.mk index cff2f64707..92c8a7fdbd 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -478,7 +478,6 @@ TEXT_O_FILES := \ $(BUILD_DIR)/asm/JUtility/JUTGraphFifo.o \ $(BUILD_DIR)/asm/JUtility/JUTFont.o \ $(BUILD_DIR)/libs/JSystem/JUtility/JUTFont.o \ - $(BUILD_DIR)/asm/JUtility/JUTResFont.o \ $(BUILD_DIR)/libs/JSystem/JUtility/JUTResFont.o \ $(BUILD_DIR)/asm/JUtility/JUTDbPrint.o \ $(BUILD_DIR)/asm/JUtility/JUTGamePad.o \ diff --git a/src/f/f_pc/f_pc_create_req.cpp b/src/f/f_pc/f_pc_create_req.cpp index 01f57a9f48..dc13bf0ab7 100644 --- a/src/f/f_pc/f_pc_create_req.cpp +++ b/src/f/f_pc/f_pc_create_req.cpp @@ -53,55 +53,7 @@ bool fpcCtRq_Delete(create_request* pReq) { #else asm bool fpcCtRq_Delete(create_request* pReq) { nofralloc - /* 80020BA0 0001DAE0 94 21 FF F0 */ stwu r1, - -0x10(r1) - /* 80020BA4 0001DAE4 7C 08 02 A6 */ mflr r0 - /* 80020BA8 0001DAE8 90 01 00 14 */ stw r0, - 0x14(r1) - /* 80020BAC 0001DAEC 93 E1 00 0C */ stw r31, - 0xc(r1) - /* 80020BB0 0001DAF0 7C 7F 1B 78 */ mr r31, - r3 - /* 80020BB4 0001DAF4 4B FF FF 6D */ bl fpcCtRq_CreateQTo - /* 80020BB8 0001DAF8 80 7F 00 34 */ lwz r3, - 0x34(r31) - /* 80020BBC 0001DAFC 28 03 00 00 */ cmplwi r3, - 0 - /* 80020BC0 0001DB00 41 82 00 20 */ beq lbl_80020BE0 - /* 80020BC4 0001DB04 80 63 00 08 */ lwz r3, - 8(r3) - /* 80020BC8 0001DB08 7F E4 FB 78 */ mr r4, - r31 - /* 80020BCC 0001DB0C 48 00 18 5D */ bl fpcMtd_Method - /* 80020BD0 0001DB10 2C 03 00 00 */ cmpwi r3, - 0 - /* 80020BD4 0001DB14 40 82 00 0C */ bne lbl_80020BE0 - /* 80020BD8 0001DB18 38 60 00 00 */ li r3, - 0 - /* 80020BDC 0001DB1C 48 00 00 24 */ b lbl_80020C00 lbl_80020BE0 : - /* 80020BE0 0001DB20 80 7F 00 40 */ lwz r3, - 0x40(r31) - /* 80020BE4 0001DB24 28 03 00 00 */ cmplwi r3, - 0 - /* 80020BE8 0001DB28 41 82 00 0C */ beq lbl_80020BF4 - /* 80020BEC 0001DB2C 38 00 00 00 */ li r0, - 0 - /* 80020BF0 0001DB30 90 03 00 14 */ stw r0, - 0x14(r3)lbl_80020BF4 : - /* 80020BF4 0001DB34 7F E3 FB 78 */ mr r3, - r31 - /* 80020BF8 0001DB38 48 24 26 69 */ bl cMl_NS_free - /* 80020BFC 0001DB3C 38 60 00 01 */ li r3, - 1 lbl_80020C00 : - /* 80020C00 0001DB40 83 E1 00 0C */ lwz r31, - 0xc(r1) - /* 80020C04 0001DB44 80 01 00 14 */ lwz r0, - 0x14(r1) - /* 80020C08 0001DB48 7C 08 03 A6 */ mtlr r0 - /* 80020C0C 0001DB4C 38 21 00 10 */ addi r1, - r1, - 0x10 - /* 80020C10 0001DB50 4E 80 00 20 */ blr +#include "f/f_pc/f_pc_create_req/asm/func_80020BA0.s" } #endif diff --git a/src/f/f_pc/f_pc_pause.cpp b/src/f/f_pc/f_pc_pause.cpp index c880436b4e..811403431a 100644 --- a/src/f/f_pc/f_pc_pause.cpp +++ b/src/f/f_pc/f_pc_pause.cpp @@ -18,30 +18,7 @@ bool fpcPause_IsEnable(void* pProcess, u8 flag) { #else asm bool fpcPause_IsEnable(void* pProcess, u8 flag) { nofralloc - /* 80023844 00020784 54 84 06 3E */ clrlwi r4, - r4, - 0x18 - /* 80023848 00020788 88 03 00 0B */ lbz r0, - 0xb(r3) - /* 8002384C 0002078C 7C 80 00 38 */ - and r0, - r4, - r0 - /* 80023850 00020790 7C 64 00 50 */ subf r3, - r4, - r0 - /* 80023854 00020794 30 03 FF FF */ addic r0, - r3, - -1 - /* 80023858 00020798 7C 00 19 10 */ subfe r0, - r0, - r3 - /* 8002385C 0002079C 7C 00 00 34 */ cntlzw r0, - r0 - /* 80023860 000207A0 54 03 D9 7E */ srwi r3, - r0, - 5 - /* 80023864 000207A4 4E 80 00 20 */ blr +#include "f/f_pc/f_pc_pause/asm/func_80023844.s" } #endif