for england james?

This commit is contained in:
KholdFuzion committed 2026-08-16 17:30:25 -04:00
1 parent 9fbe1fd5a8
commit cc14d64e7d
340 files changed
+86028 -148402

No files matched your search

+1 -1
View File
@@ -13,7 +13,7 @@ endif
default: all
armips: armips.cpp
$(CXX) $(CXXFLAGS) -fno-exceptions -fno-rtti -pipe $^ -o $@ -lpthread $(ARMIPS_FLAGS)
$(CXX) $(CXXFLAGS) -fmax-errors=2 -fno-exceptions -fno-rtti -pipe $^ -o $@ -lpthread $(ARMIPS_FLAGS)
n64cksum_SOURCES := n64cksum.c utils.c
n64cksum_CFLAGS := -DN64CKSUM_STANDALONE
Binary file not shown.
+1
View File
@@ -56,6 +56,7 @@ SOFTWARE.
#include <cstring>
#include <cmath>
#include <clocale>
#include <cstdint>
#include <sstream>
#include <iomanip>
+124 -2
View File
@@ -486,7 +486,7 @@ class GlobalState:
address = (8 * self.valuectr) & 0x7FFF
return 'v{} := p{}({}); v{}^ := {};'.format(tp, tp, address, tp, val)
Function = namedtuple('Function', ['text_glabels', 'asm_conts', 'late_rodata_dummy_bytes', 'jtbl_rodata_size', 'late_rodata_asm_conts', 'fn_desc', 'data'])
Function = namedtuple('Function', ['text_glabels', 'asm_conts', 'late_rodata_dummy_bytes', 'jtbl_rodata_size', 'late_rodata_asm_conts', 'late_rodata_carrier', 'fn_desc', 'data'])
class GlobalAsmBlock:
@@ -773,7 +773,17 @@ class GlobalAsmBlock:
late_rodata_fn_output.append('')
text_name = None
if self.fn_section_sizes['.text'] > 0 or late_rodata_fn_output:
late_rodata_carrier = None
if self.fn_section_sizes['.text'] == 0 and late_rodata_fn_output:
# Keep the dummy constants at this point in the compiler's rodata
# stream. The generated function is removed again in fixup_objfile.
late_rodata_carrier = state.make_name('late_rodata_carrier')
src[0] = ' '.join(
[state.func_prologue(late_rodata_carrier)] +
late_rodata_fn_output +
[state.func_epilogue()]
)
elif self.fn_section_sizes['.text'] > 0:
text_name = state.make_name('func')
src[0] = state.func_prologue(text_name)
src[self.num_lines] = state.func_epilogue()
@@ -855,6 +865,7 @@ class GlobalAsmBlock:
late_rodata_dummy_bytes=late_rodata_dummy_bytes,
jtbl_rodata_size=jtbl_rodata_size,
late_rodata_asm_conts=self.late_rodata_asm_conts,
late_rodata_carrier=late_rodata_carrier,
fn_desc=self.fn_desc,
data={
'.text': (text_name, self.fn_section_sizes['.text']),
@@ -1078,12 +1089,33 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
late_rodata_source_name_start = None
late_rodata_source_name_end = None
late_rodata_carrier_ranges = []
omitted_late_rodata_carriers = set()
text_section = objfile.find_section('.text')
for function in functions:
if function.late_rodata_carrier is None:
continue
carrier = next(
(symbol for symbol in objfile.symbol_entries
if symbol.name == function.late_rodata_carrier),
None)
if carrier is None:
# The surrounding preprocessor condition omitted this block.
omitted_late_rodata_carriers.add(function.late_rodata_carrier)
continue
if carrier.st_shndx != text_section.index or carrier.st_size == 0:
raise Failure("could not determine generated late rodata carrier size, " + function.fn_desc)
late_rodata_carrier_ranges.append(
(carrier.st_value, carrier.st_value + carrier.st_size))
# Generate an assembly file with all the assembly we need to fill in. For
# simplicity we pad with nops/.space so that addresses match exactly, so we
# don't have to fix up relocations/symbol references.
all_text_glabels = set()
func_sizes = {}
for function in functions:
if function.late_rodata_carrier in omitted_late_rodata_carriers:
continue
ifdefed = False
for sectype, (temp_name, size) in function.data.items():
if temp_name is None:
@@ -1452,8 +1484,98 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
sh_type=reltab.sh_type, sh_flags=0,
sh_link=objfile.symtab.index, sh_info=target.index,
sh_addralign=4, sh_entsize=sh_entsize, data=b'')
target.relocated_by.append(target_reltab)
target_reltab.relocations = []
target_reltab.relocations.extend(reltab.relocations)
target_reltab.data += new_data
# Data-only .late_rodata blocks use temporary C functions to make IDO
# emit their dummy constants at the right point in .rodata. Remove
# those functions and close the gaps in later text symbols and
# relocation offsets.
if late_rodata_carrier_ranges:
ranges = sorted(late_rodata_carrier_ranges)
for (_, end), (next_start, _) in zip(ranges, ranges[1:]):
if end > next_start:
raise Failure("overlapping generated late rodata carriers")
def removed_before(pos):
return sum(end - start for start, end in ranges if end <= pos)
def inside_carrier(pos):
return any(start <= pos < end for start, end in ranges)
new_text = bytearray()
cursor = 0
for start, end in ranges:
new_text.extend(text_section.data[cursor:start])
cursor = end
new_text.extend(text_section.data[cursor:])
text_section.data = bytes(new_text)
# REL relocations store their addends in section contents. Adjust
# section-relative text pointers (most notably jump tables) before
# shifting the symbols they are based on.
for target_section in objfile.sections:
section_data = bytearray(target_section.data)
changed = False
for reltab in target_section.relocated_by:
for rel in reltab.relocations:
symbol = new_syms[rel.sym_index]
if symbol.st_shndx != text_section.index or \
rel.rel_type != R_MIPS_32:
continue
addend, = fmt.unpack(
'I', section_data[rel.r_offset:rel.r_offset + 4])
target = symbol.st_value + addend
addend -= (
removed_before(target) -
removed_before(symbol.st_value)
)
section_data[rel.r_offset:rel.r_offset + 4] = \
fmt.pack('I', addend)
changed = True
if changed:
target_section.data = bytes(section_data)
for symbol in new_syms:
if symbol.st_shndx != text_section.index:
continue
if symbol.st_type == STT_SECTION and symbol.st_value == 0:
continue
elif not inside_carrier(symbol.st_value):
symbol.st_value -= removed_before(symbol.st_value)
text_end = max(
(symbol.st_value + symbol.st_size
for symbol in new_syms
if symbol.st_shndx == text_section.index and
symbol.st_type != STT_SECTION),
default=0
)
aligned_text_end = (
(text_end + text_section.sh_addralign - 1) //
text_section.sh_addralign * text_section.sh_addralign
)
text_section.data = text_section.data[:aligned_text_end]
text_section.data += b'\0' * (aligned_text_end - len(text_section.data))
for symbol in new_syms:
if symbol.st_shndx == text_section.index and \
symbol.st_type == STT_SECTION and symbol.st_value == 0:
symbol.st_size = len(text_section.data)
for reltab in text_section.relocated_by:
relocations = []
for rel in reltab.relocations:
if inside_carrier(rel.r_offset):
continue
rel.r_offset -= removed_before(rel.r_offset)
relocations.append(rel)
reltab.relocations = relocations
reltab.data = b''.join(rel.to_bin() for rel in relocations)
objfile.symtab.data = b''.join(symbol.to_bin() for symbol in new_syms)
objfile.write(objfile_name)
finally:
s_file.close()
+12 -5
View File
@@ -290,13 +290,13 @@ def apply_build_map(stats: StatResults, version: str):
# followed by a hex address (capturing everything after "0x"), followed by any whitespace (at least one).
# It then matches a build path, based on version, capturing everything after the version and slash
# up to the file extension, followed by end of line.
p1 = re.compile(r"^ \.text\s+0x00000000([0-9a-f]{8})\s+0x([0-9a-f]+)\s+build\/" + re.escape(version_code) + r"\/([^\s]+)$")
p1 = re.compile(r"^ \.text\s+0x(?:00000000)?([0-9a-f]{8})\s+0x([0-9a-f]+)\s+build\/" + re.escape(version_code) + r"\/([^\s]+)$")
# regex to match subsequent lines after the above regex matches. This will
# match any whitespace, then 64 bit address (capturing the lower 32 bits), then
# any whitespace (at least one), then capture the remaining non-whitespace-text until end of line (in capture group).
# That last capture group is the function name.
p2 = re.compile(r"^\s+0x00000000([0-9a-f]{8})\s+(\S+)$")
p2 = re.compile(r"^\s+0x(?:00000000)?([0-9a-f]{8})\s+(\S+)$")
current_sfc = None
current_fi = None
@@ -675,8 +675,8 @@ def main():
if print_method == 'non_matching' and not run_report:
mtime_use_os = True
if not qlocal:
print(subprocess.run(['git', 'diff', 'origin/master', '--name-only', '"@{10 minutes ago}"']).stdout)
#if not qlocal:
# print(subprocess.run(['git', 'diff', 'origin/master', '--name-only', '"@{10 minutes ago}"']).stdout)
# Default to using git log to get the file's modified date.
# Git log will be much slower, but cloning a new repo (i.e., github actions online)
# will reset all the modified timestamps to the same value, so will need to
@@ -698,20 +698,27 @@ def main():
src_completed_list = [
'_start.s',
'aspboot.s',
'boot.s',
'bootcode.s',
'getra.s',
'gspboot.s',
'osMapTLB.s',
'random.s',
'rom_header.s',
'rspboot.s',
'tlb_random.s',
'tlb_hardwire.s',
'tlb_resolve.s']
# files to count as complete, in src/libultrare directory
src_libultrare_completed_list = [
'ultra80069080.s']
search = []
search.append(SearchDir('src', False, completed=src_completed_list))
search.append(SearchDir('src/game', False))
search.append(SearchDir('src/inflate', False))
search.append(SearchDir('src/libultrare', True))
search.append(SearchDir('src/libultrare', True, completed=src_libultrare_completed_list))
stats = StatResults()
+25 -5
View File
@@ -1,5 +1,15 @@
IRIX_ROOT := ../irix/root
# Vendored from https://github.com/Decompollaborate/rabbitizer (pinned at
# decompals/ido-static-recomp @ d5aec59's subrepo commit
# 72bf240f468d30286888212b5fb773fae94340f6) - replaces the old libcapstone
# dependency as of the decompals rewrite (2022-10-16).
RABBITIZER := rabbitizer
RABBITIZER_LIB := $(RABBITIZER)/build/librabbitizerpp.a
# Source pinned to decompals/ido-static-recomp @ d5aec59
RECOMP_PACKAGE_VERSION := decompals/ido-static-recomp @ d5aec59
cc: OPT_CFLAGS := -O2
cfe: OPT_CFLAGS := -O2
uopt: OPT_CFLAGS := -O2
@@ -14,14 +24,24 @@ ugen_c.c: RECOMP_FLAGS := --conservative
all: cc cfe uopt ugen as1 acpp copt ujoin uld umerge usplit err.english.cc
clean:
$(RM) cc* cfe* uopt* ugen* as1* acpp* copt* ujoin* uld* umerge* usplit* err.english.cc $(RECOMP) libc_impl.o
$(RM) cc* cfe* uopt* ugen* as1* acpp* copt* ujoin* uld* umerge* usplit* err.english.cc $(RECOMP) libc_impl.o version_info.o
$(MAKE) -C $(RABBITIZER) distclean
$(RECOMP): recomp.cpp
$(CXX) $^ -o $@ -std=c++11 -O2 -Wno-switch `pkg-config --cflags --libs capstone`
$(RABBITIZER_LIB):
$(MAKE) -C $(RABBITIZER) static CC=$(CC) CXX=$(CXX) DEBUG=0
$(RECOMP): recomp.cpp $(RABBITIZER_LIB)
$(CXX) recomp.cpp -o $@ -std=c++17 -O2 -Wno-switch \
-I $(RABBITIZER)/include -I $(RABBITIZER)/cplusplus/include \
-L $(RABBITIZER)/build -lrabbitizerpp -ldl -Wl,-export-dynamic
libc_impl.o: libc_impl.c libc_impl.h
$(CC) $< -c -fno-strict-aliasing -O2 -DIDO53
version_info.o: version_info.c
$(CC) $< -c -O2 -DIDO53 \
-DPACKAGE_VERSION='"$(RECOMP_PACKAGE_VERSION)"' -DDATETIME='"n/a"'
err.english.cc: $(IRIX_ROOT)/usr/lib/err.english.cc
cp $^ $@
@@ -31,7 +51,7 @@ cc_c.c: $(IRIX_ROOT)/usr/bin/cc $(RECOMP)
%_c.c: $(IRIX_ROOT)/usr/lib/% $(RECOMP)
./$(RECOMP) $(RECOMP_FLAGS) $< > $@
%: %_c.c libc_impl.o
$(CC) libc_impl.o $< -o $@ $(OPT_CFLAGS) -fno-strict-aliasing -lm -no-pie
%: %_c.c libc_impl.o version_info.o
$(CC) libc_impl.o version_info.o $< -o $@ $(OPT_CFLAGS) -fno-strict-aliasing -lm -no-pie
.PHONY: all clean
+150
View File
@@ -0,0 +1,150 @@
# `ido5.3_recomp`
This directory builds a native x86-64 Linux copy of the original SGI IRIX
5.3 IDO compiler toolchain (`cc`, `cfe`, `uopt`, `ugen`, `as1`, `acpp`,
`copt`, `ujoin`, `uld`, `umerge`, `usplit`, plus the `err.english.cc`
message table `cc` reads at runtime). This is what the root `Makefile`
invokes when building with `IDO_RECOMP=YES` (the default) — see
[`docs/SetupGuide.md`](../../docs/SetupGuide.md#recompile-ido) for how that
fits into the overall build.
## Where this comes from
The original IDO 5.3 binaries only ever ran on real IRIX (MIPS) hardware or
under an emulator like `qemu-irix`. [`decompals/ido-static-recomp`
](https://github.com/decompals/ido-static-recomp) is a *static
recompiler*: a tool (`recomp.cpp` in this directory) that disassembles one
of those original MIPS ELF binaries and emits equivalent C source, which is
then compiled normally with a host C compiler (`gcc`). The result is a
program that behaves like the original IRIX binary but runs natively,
without any emulation overhead — much faster to compile GoldenEye's C
source with than running the real thing under `qemu-irix`.
`decompals/ido-static-recomp` is itself a fork of
[`Emill/ido-static-recomp`](https://github.com/Emill/ido-static-recomp)
(the original author's repo) that has become the actively maintained
version. **This directory's source is a vendored copy of
`decompals/ido-static-recomp`, not a submodule** — the relevant files
(`recomp.cpp`, `libc_impl.c`, `libc_impl.h`, `header.h`, `helpers.h`,
`elf.h`, `version_info.c`) are copied in directly rather than referenced as
a git submodule or fetched at build time, so this repo can be built
offline/reproducibly without depending on that repo staying available.
## What's tracked here vs. generated
Only source files and this `Makefile`/`README.md` are committed to git:
* `recomp.cpp`, `libc_impl.c`, `libc_impl.h`, `header.h`, `helpers.h`,
`elf.h`, `version_info.c` — the recompiler and the IRIX-syscall runtime
shim (`libc_impl.*`) the recompiled binaries link against
* `rabbitizer/` — vendored dependency, see below
* `Makefile`, `.gitignore`, this `README.md`
Everything else in this directory when you look at it locally (`recomp`,
`cc`, `cfe`, `uopt`, `ugen`, `as1`, `acpp`, `copt`, `ujoin`, `uld`,
`umerge`, `usplit`, `err.english.cc`, the intermediate `*_c.c` files,
`*.o`) is build output, covered by `.gitignore`, and gets regenerated from
scratch by `make`.
## Building
### Automatically (normal case)
A plain `make` from the repo root builds this toolchain automatically if
`tools/ido5.3_recomp/cc` doesn't exist yet — wired up via `tools/Makefile`
(`$(MAKE) -C ido5.3_recomp` runs as a dependency whenever `cc` is missing)
and `scripts/make/build_tools.sh`, which the root `Makefile`'s
`prerequisites` target calls. You don't need to do anything extra for this
in the common case.
### Manually
```bash
cd tools/ido5.3_recomp
make
```
This requires the original SGI IRIX 5.3 IDO binaries to be present at
`../irix/root/usr/{bin,lib}/*` (checked into this repo — `cc` is under
`usr/bin`, everything else recompiled is under `usr/lib`). The recipe
(per binary): run `./recomp <irix binary> > <name>_c.c`, then compile that
generated C against `libc_impl.o` (the IRIX syscall/runtime shim) and
`version_info.o` with `gcc`.
`ugen` needs `recomp --conservative` specifically — the original `ugen`
binary relies on undefined-behavior stack reads, and `--conservative`
makes `recomp` emit C that reproduces that behavior safely instead of
leaving it to chance under a different compiler/optimization level.
`make clean` removes all generated binaries/intermediate files and also
runs `make -C rabbitizer distclean`.
## Rabbitizer (the vendored dependency)
`recomp` needs a MIPS instruction disassembler to make sense of the
original IRIX binaries' machine code before it can emit equivalent C.
Older versions of this tool used the general-purpose `libcapstone`
library for that (a system package, `libcapstone-dev`). As of decompals'
rewrite in October 2022, upstream replaced Capstone with
[`rabbitizer`](https://github.com/Decompollaborate/rabbitizer) — a small,
purpose-built MIPS/RSP/R5900 disassembly library maintained by the same
decompilation-tooling group, with better support for the instruction
quirks recomp actually cares about.
**"Vendored in" means the `rabbitizer/` subdirectory here is a plain copy
of rabbitizer's source**, not a git submodule/subrepo and not a system
package — there's nothing to `apt install` for it. Upstream
`decompals/ido-static-recomp` tracks rabbitizer as a `git subrepo` (see
their `tools/rabbitizer/.gitrepo`) pinned at commit
`72bf240f468d30286888212b5fb773fae94340f6`; the copy here was taken from
that same commit, with the Python bindings directory and standalone test
programs stripped out (`recomp` only needs the C/C++ static library, not
rabbitizer's Python module or its own test suite).
It's built automatically as a dependency of `recomp` — the `Makefile`
here runs `make -C rabbitizer static` first, which produces
`rabbitizer/build/librabbitizer.a` and `librabbitizerpp.a` (both
gitignored build output), and `recomp` links against the C++ one.
To refresh rabbitizer to a newer version: check what commit current
`decompals/ido-static-recomp` pins in `tools/rabbitizer/.gitrepo`, fetch
[`Decompollaborate/rabbitizer`](https://github.com/Decompollaborate/rabbitizer)
at that commit, and replace this `rabbitizer/` directory with it (again
trimming the Python bindings/tests if you want to keep the vendored copy
minimal — they aren't required for `make static`).
## Version pinning / updating to a newer decompals release
The recompiler source here is currently pinned to
`decompals/ido-static-recomp` @ commit `d5aec59` (`origin/main` HEAD at
the time it was last updated, 17 commits past tag `v1.2`). This is
recorded in two places: a comment at the top of this `Makefile`, and the
`RECOMP_PACKAGE_VERSION` variable baked into every built binary — check it
with `./cc --version` (or any other built binary) after building.
To pick up a newer version:
1. Clone or update a local checkout of
[`decompals/ido-static-recomp`](https://github.com/decompals/ido-static-recomp)
and check out whatever commit/tag you want to move to.
2. Copy `recomp.cpp`, `libc_impl.c`, `libc_impl.h`, `header.h`,
`helpers.h`, `elf.h`, and `version_info.c` from that checkout over the
copies in this directory. Diff first — upstream's `main` root `Makefile`
is much bigger than this one (it builds IDO 7.1 too, multiple binary
sets, universal macOS builds, etc.); this `Makefile` only needs to keep
pace with whatever those individual source files require to compile.
3. If rabbitizer's pinned commit changed upstream, refresh `rabbitizer/`
per the section above.
4. Update the pinned-commit comment at the top of this `Makefile` and the
`RECOMP_PACKAGE_VERSION` variable.
5. `make clean && make` here, then — **this is the important part** — do a
full clean rebuild of the ROM for all three regions from the repo root
(`make clean && make VERSION=US && make VERSION=EU && make VERSION=JP`)
and confirm `scripts/make/checksum.sh` still reports `MATCH!` for each.
This project's entire premise is a byte-identical ROM; a recomp version
bump that changes how any of these programs behaves when compiling
GoldenEye's actual source is a real regression even if everything
"builds successfully." If a mismatch shows up, bisect by swapping
individual binaries (`cc`, `cfe`, `uopt`, `ugen`, `as1`, `uld`,
`umerge`, `ujoin`, `usplit`, `acpp`, `copt`) between old and new builds
to isolate which one changed behavior.
+33 -9
View File
@@ -13,18 +13,42 @@
#define RM_RP 2
#define RM_RM 3
union FloatReg {
float f[2];
uint32_t w[2];
double d;
};
#define cvt_w_d(f) \
((fcsr & RM_RZ) ? ((isnan(f) || f <= -2147483649.0 || f >= 2147483648.0) ? (fcsr |= 0x40, 2147483647) : (int)f) : (assert(0), 0))
#define cvt_w_s(f) cvt_w_d((double)f)
static union FloatReg f0 = {{0, 0}}, f2 = {{0, 0}}, f4 = {{0, 0}}, f6 = {{0, 0}}, f8 = {{0, 0}},
f10 = {{0, 0}}, f12 = {{0, 0}}, f14 = {{0, 0}}, f16 = {{0, 0}}, f18 = {{0, 0}}, f20 = {{0, 0}},
f22 = {{0, 0}}, f24 = {{0, 0}}, f26 = {{0, 0}}, f28 = {{0, 0}}, f30 = {{0, 0}};
static union FloatReg
f0 = {{0, 0}},
f1 = {{0, 0}},
f2 = {{0, 0}},
f3 = {{0, 0}},
f4 = {{0, 0}},
f5 = {{0, 0}},
f6 = {{0, 0}},
f7 = {{0, 0}},
f8 = {{0, 0}},
f9 = {{0, 0}},
f10 = {{0, 0}},
f11 = {{0, 0}},
f12 = {{0, 0}},
f13 = {{0, 0}},
f14 = {{0, 0}},
f15 = {{0, 0}},
f16 = {{0, 0}},
f17 = {{0, 0}},
f18 = {{0, 0}},
f19 = {{0, 0}},
f20 = {{0, 0}},
f21 = {{0, 0}},
f22 = {{0, 0}},
f23 = {{0, 0}},
f24 = {{0, 0}},
f25 = {{0, 0}},
f26 = {{0, 0}},
f27 = {{0, 0}},
f28 = {{0, 0}},
f29 = {{0, 0}},
f30 = {{0, 0}},
f31 = {{0, 0}};
static uint32_t fcsr = 1;
+26
View File
@@ -3,6 +3,8 @@
#include <stdint.h>
#define MEM_F64(a) (double_from_memory(mem, a))
#define MEM_F32(a) (*(float *)(mem + a))
#define MEM_U32(a) (*(uint32_t *)(mem + a))
#define MEM_S32(a) (*(int32_t *)(mem + a))
#define MEM_U16(a) (*(uint16_t *)(mem + ((a) ^ 2)))
@@ -10,4 +12,28 @@
#define MEM_U8(a) (*(uint8_t *)(mem + ((a) ^ 3)))
#define MEM_S8(a) (*(int8_t *)(mem + ((a) ^ 3)))
#if !defined(__GNUC__) && !defined(__clang__)
#define __attribute__(x)
#endif
#if __STDC_VERSION__ >= 202000L
#define FALLTHROUGH [[fallthrough]]
#define NODISCARD [[nodiscard]]
#define NORETURN [[noreturn]]
#define UNUSED [[maybe_unused]]
#else
#define FALLTHROUGH __attribute__((fallthrough))
#define NODISCARD __attribute__((warn_unused_result))
#define NORETURN _Noreturn
#define UNUSED __attribute__((unused))
#endif
#if defined(_MSC_VER)
# define UNREACHABLE __assume(0)
#elif defined(__GNUC__) || defined(__clang__)
# define UNREACHABLE __builtin_unreachable()
#else
# define UNREACHABLE
#endif
#endif
File diff suppressed because it is too large. Load diff
+50 -5
View File
@@ -1,5 +1,18 @@
#ifndef LIBC_IMPL_H
#define LIBC_IMPL_H
#include <stdint.h>
union FloatReg {
float f[2];
uint32_t w[2];
//double d;
};
typedef uint64_t (*fptr_trampoline)(uint8_t* mem, uint32_t sp, uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3,
uint32_t fp_dest);
void mmap_initial_data_range(uint8_t *mem, uint32_t start, uint32_t end);
void setup_libc_data(uint8_t *mem);
@@ -31,6 +44,8 @@ int wrapper_atol(uint8_t *mem, uint32_t nptr_addr);
double wrapper_atof(uint8_t *mem, uint32_t nptr_addr);
int wrapper_strtol(uint8_t *mem, uint32_t nptr_addr, uint32_t endptr_addr, int base);
uint32_t wrapper_strtoul(uint8_t *mem, uint32_t nptr_addr, uint32_t endptr_addr, int base);
int64_t wrapper_strtoll(uint8_t *mem, uint32_t nptr_addr, uint32_t endptr_addr, int base);
uint64_t wrapper_strtoull(uint8_t *mem, uint32_t nptr_addr, uint32_t endptr_addr, int base);
double wrapper_strtod(uint8_t *mem, uint32_t nptr_addr, uint32_t endptr_addr);
uint32_t wrapper_strchr(uint8_t *mem, uint32_t str_addr, int c);
uint32_t wrapper_strrchr(uint8_t *mem, uint32_t str_addr, int c);
@@ -39,6 +54,7 @@ uint32_t wrapper_strpbrk(uint8_t *mem, uint32_t str_addr, uint32_t accept_addr);
int wrapper_fstat(uint8_t *mem, int fildes, uint32_t buf_addr);
int wrapper_stat(uint8_t *mem, uint32_t pathname_addr, uint32_t buf_addr);
int wrapper_ftruncate(uint8_t *mem, int fd, int length);
int wrapper_truncate(uint8_t *mem, uint32_t pathname_addr, int length);
void wrapper_bcopy(uint8_t *mem, uint32_t src_addr, uint32_t dst_addr, uint32_t len);
uint32_t wrapper_memcpy(uint8_t *mem, uint32_t dst_addr, uint32_t src_addr, uint32_t len);
uint32_t wrapper_memccpy(uint8_t *mem, uint32_t dst_addr, uint32_t src_addr, int c, uint32_t len);
@@ -48,6 +64,7 @@ uint32_t wrapper_fopen(uint8_t *mem, uint32_t path_addr, uint32_t mode_addr);
uint32_t wrapper_freopen(uint8_t *mem, uint32_t path_addr, uint32_t mode_addr, uint32_t fp_addr);
int wrapper_fclose(uint8_t *mem, uint32_t fp_addr);
int wrapper_fflush(uint8_t *mem, uint32_t fp_addr);
int wrapper_fchown(uint8_t *mem, int fd, int owner, int group);
int wrapper_ftell(uint8_t *mem, uint32_t fp_addr);
void wrapper_rewind(uint8_t *mem, uint32_t fp_addr);
int wrapper_fseek(uint8_t *mem, uint32_t fp_addr, int offset, int origin);
@@ -101,10 +118,10 @@ int wrapper_time(uint8_t *mem, uint32_t tloc_addr);
void wrapper_bzero(uint8_t *mem, uint32_t str_addr, uint32_t n);
int wrapper_fp_class_d(double d);
double wrapper_ldexp(double d, int i);
int64_t wrapper___ll_mul(int64_t a0, int64_t a1);
uint64_t wrapper___ll_mul(uint64_t a0, uint64_t a1);
int64_t wrapper___ll_div(int64_t a0, int64_t a1);
int64_t wrapper___ll_rem(uint64_t a0, int64_t a1);
int64_t wrapper___ll_lshift(int64_t a0, uint64_t shift);
uint64_t wrapper___ll_lshift(uint64_t a0, uint64_t shift);
int64_t wrapper___ll_rshift(int64_t a0, uint64_t shift);
uint64_t wrapper___ull_div(uint64_t a0, uint64_t a1);
uint64_t wrapper___ull_rem(uint64_t a0, uint64_t a1);
@@ -137,8 +154,8 @@ int wrapper_getpagesize(uint8_t *mem);
int wrapper_strerror(uint8_t *mem, int errnum);
int wrapper_ioctl(uint8_t *mem, int fd, uint32_t request, uint32_t sp);
int wrapper_fcntl(uint8_t *mem, int fd, int cmd, uint32_t sp);
uint32_t wrapper_signal(uint8_t *mem, int signum, uint64_t (*trampoline)(uint8_t *mem, uint32_t sp, uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t fp_dest), uint32_t handler_addr, uint32_t sp);
uint32_t wrapper_sigset(uint8_t *mem, int signum, uint64_t (*trampoline)(uint8_t *mem, uint32_t sp, uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t fp_dest), uint32_t disp_addr, uint32_t sp);
uint32_t wrapper_signal(uint8_t *mem, int signum, fptr_trampoline trampoline, uint32_t handler_addr, uint32_t sp);
uint32_t wrapper_sigset(uint8_t *mem, int signum, fptr_trampoline trampoline, uint32_t disp_addr, uint32_t sp);
int wrapper_get_fpc_csr(uint8_t *mem);
int wrapper_set_fpc_csr(uint8_t *mem, int csr);
int wrapper_setjmp(uint8_t *mem, uint32_t addr);
@@ -157,7 +174,35 @@ int wrapper_fork(uint8_t *mem);
int wrapper_system(uint8_t *mem, uint32_t command_addr);
uint32_t wrapper_tsearch(uint8_t *mem, uint32_t key_addr, uint32_t rootp_addr, uint32_t compar_addr);
uint32_t wrapper_tfind(uint8_t *mem, uint32_t key_addr, uint32_t rootp_addr, uint32_t compar_addr);
uint32_t wrapper_qsort(uint8_t *mem, uint32_t base_addr, uint32_t num, uint32_t size, uint64_t (*trampoline)(uint8_t *mem, uint32_t sp, uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t fp_dest), uint32_t compare_addr, uint32_t sp);
uint32_t wrapper_qsort(uint8_t *mem, uint32_t base_addr, uint32_t num, uint32_t size, fptr_trampoline trampoline, uint32_t compare_addr, uint32_t sp);
uint32_t wrapper_regcmp(uint8_t *mem, uint32_t string1_addr, uint32_t sp);
uint32_t wrapper_regex(uint8_t *mem, uint32_t re_addr, uint32_t subject_addr, uint32_t sp);
void wrapper___assert(uint8_t *mem, uint32_t assertion_addr, uint32_t file_addr, int line);
void wrapper_twalk(uint8_t *mem, uint32_t root_addr, fptr_trampoline trampoline, uint32_t action_addr, uint32_t sp);
int32_t wrapper_msync(uint8_t *mem, uint32_t addr_addr, uint32_t len, int32_t flags);
int32_t wrapper_mkdir(uint8_t *mem, uint32_t path_addr, uint32_t mode);
int32_t wrapper_fputc(uint8_t *mem, int32_t ch, uint32_t stream_addr);
int32_t wrapper_getopt(uint8_t *mem, int32_t argc, uint32_t argv_addr, uint32_t optstring_addr);
int32_t wrapper_link(uint8_t *mem, uint32_t oldpath_addr, uint32_t newpath_addr);
int32_t wrapper_vsprintf(uint8_t *mem, uint32_t buffer_addr, uint32_t format_addr, uint32_t vlist_addr);
double wrapper_fabs(double x);
int32_t wrapper_sysid(uint8_t *mem, uint32_t unknown_parameter_addr);
uint32_t wrapper_realpath(uint8_t *mem, uint32_t path_addr, uint32_t resolved_path_addr);
int32_t wrapper_fsync(uint8_t *mem, int32_t fd);
uint32_t wrapper_sleep(uint8_t *mem, uint32_t seconds);
int32_t wrapper_socket(uint8_t *mem, int32_t domain, int32_t type, int32_t protocol);
int32_t wrapper_connect(uint8_t *mem, int32_t sockfd, uint32_t addr_addr, uint32_t addrlen);
int32_t wrapper_recv(uint8_t *mem, int32_t sockfd, uint32_t buf_addr, uint32_t len, int32_t flags);
int32_t wrapper_send(uint8_t *mem, int32_t sockfd, uint32_t buf_addr, uint32_t len, int32_t flags);
int32_t wrapper_shutdown(uint8_t *mem, int32_t socket, int32_t how);
int32_t wrapper_sscanf(uint8_t *mem, uint32_t str_addr, uint32_t format_addr, uint32_t sp);
// C++ functions
uint32_t wrapper___nw__FUi(uint8_t *mem, uint32_t size);
void wrapper___dl__FPv(uint8_t *mem, uint32_t data_addr);
union FloatReg FloatReg_from_double(double d);
double double_from_FloatReg(union FloatReg floatreg);
double double_from_memory(uint8_t *mem, uint32_t address);
#endif
+215
View File
@@ -0,0 +1,215 @@
# https://raw.githubusercontent.com/github/gitignore/main/C.gitignore
# https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
.vscode/
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Decompollaborate
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.
+140
View File
@@ -0,0 +1,140 @@
# Build options can be changed by modifying the makefile or by building with 'make SETTING=value'.
DEBUG ?= 0
WERROR ?= 0
ASAN ?= 0
EXPERIMENTAL ?= 0
SANITY_CHECKS ?= 1
CC := clang
CXX := clang++
AR := ar
IINC := -I include
IINC_XX := -I include -I cplusplus/include
CSTD := -std=c11
CXXSTD := -std=c++17
CFLAGS := -fPIC
CXXFLAGS := -fPIC
LDFLAGS := -Lbuild -lrabbitizer
LDXXFLAGS := -Lbuild -lrabbitizerpp
WARNINGS := -Wall -Wextra -Wpedantic
# WARNINGS := -Wall -Wextra -Wpedantic -Wpadded
WARNINGS += -Werror=vla -Werror=switch -Werror=implicit-fallthrough -Werror=unused-function -Werror=unused-parameter -Werror=shadow
WARNINGS_C := -Werror=implicit-function-declaration -Werror=incompatible-pointer-types
WARNINGS_CXX :=
ifeq ($(CC),gcc)
WARNINGS += -Wno-cast-function-type
endif
ifeq ($(DEBUG),0)
OPTFLAGS := -Os -g
else
OPTFLAGS := -O0 -g3
CFLAGS += -DDEVELOPMENT=1
CXXFLAGS += -DDEVELOPMENT=1
endif
ifneq ($(WERROR),0)
WARNINGS += -Werror
endif
ifneq ($(ASAN),0)
CFLAGS += -fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined
CXXFLAGS += -fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined
endif
ifneq ($(EXPERIMENTAL),0)
CFLAGS += -DEXPERIMENTAL
CXXFLAGS += -DEXPERIMENTAL
endif
ifneq ($(SANITY_CHECKS),0)
CFLAGS += -DRAB_SANITY_CHECKS=1
CXXFLAGS += -DRAB_SANITY_CHECKS=1
endif
SRC_DIRS := $(shell find src -type d)
C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c))
H_FILES := $(foreach dir,$(IINC),$(wildcard $(dir)/**/*.h))
O_FILES := $(foreach f,$(C_FILES:.c=.o),build/$f)
SRCXX_DIRS := $(shell find cplusplus/src -type d)
CXX_FILES := $(foreach dir,$(SRCXX_DIRS),$(wildcard $(dir)/*.cpp))
HXX_FILES := $(foreach dir,$(IINC_XX),$(wildcard $(dir)/**/*.hpp))
OXX_FILES := $(foreach f,$(CXX_FILES:.cpp=.o),build/$f)
DEP_FILES := $(O_FILES:%.o=%.d) $(OXX_FILES:%.o=%.d)
TESTS_DIRS := $(shell find tests -type d)
STATIC_LIB := build/librabbitizer.a
DYNAMIC_LIB := build/librabbitizer.so
STATIC_LIB_XX := build/librabbitizerpp.a
DYNAMIC_LIB_XX := build/librabbitizerpp.so
# create build directories
$(shell mkdir -p $(foreach dir,$(SRC_DIRS) $(SRCXX_DIRS) $(TESTS_DIRS),build/$(dir)))
# Dependencies of libraries
$(STATIC_LIB): $(O_FILES)
$(DYNAMIC_LIB): $(O_FILES)
$(STATIC_LIB_XX): $(O_FILES) $(OXX_FILES)
$(DYNAMIC_LIB_XX): $(O_FILES) $(OXX_FILES)
#### Main Targets ###
all: static tests
static: $(STATIC_LIB) $(STATIC_LIB_XX)
dynamic: $(DYNAMIC_LIB) $(DYNAMIC_LIB_XX)
clean:
$(RM) -rf build
distclean: clean
$(RM) -rf dist rabbitizer.egg-info .mypy_cache
format:
clang-format-11 -i -style=file $(C_FILES)
clang-format-11 -i -style=file $(CXX_FILES)
tidy:
clang-tidy-11 -p . --fix --fix-errors $(C_FILES) $(H_FILES) -- $(CSTD) $(OPTFLAGS) $(IINC) $(WARNINGS) $(WARNINGS_C) $(CFLAGS)
tests: build/test.elf build/rsptest.elf build/r5900test.elf build/registersTrackerTest.elf build/tests/cplusplus/test.elf
.PHONY: all clean distclean format tidy tests
.DEFAULT_GOAL := all
.SECONDARY:
#### Various Recipes ####
build/%.elf: %.c | $(STATIC_LIB)
$(CC) -MMD $(CSTD) $(OPTFLAGS) $(IINC) $(WARNINGS) $(WARNINGS_C) $(CFLAGS) -o $@ $^ $(LDFLAGS)
build/%.elf: %.cpp | $(STATIC_LIB_XX)
$(CXX) -MMD $(CXXSTD) $(OPTFLAGS) $(IINC_XX) $(WARNINGS) $(WARNINGS_CXX) $(CXXFLAGS) -o $@ $^ $(LDXXFLAGS)
build/%.a:
$(AR) rcs $@ $^
build/%.so:
$(CC) -shared -o $@ $^
build/%.o: %.c
# The -MMD flags additionaly creates a .d file with the same name as the .o file.
$(CC) -MMD -c $(CSTD) $(OPTFLAGS) $(IINC) $(WARNINGS) $(WARNINGS_C) $(CFLAGS) -o $@ $<
build/%.o: %.cpp
# The -MMD flags additionaly creates a .d file with the same name as the .o file.
$(CXX) -MMD -c $(CXXSTD) $(OPTFLAGS) $(IINC_XX) $(WARNINGS) $(WARNINGS_CXX) $(CXXFLAGS) -o $@ $<
-include $(DEP_FILES)
+55
View File
@@ -0,0 +1,55 @@
# rabbitizer
[![PyPI - Downloads](https://img.shields.io/pypi/dm/rabbitizer)](https://pypi.org/project/rabbitizer/)
![GitHub](https://img.shields.io/github/license/Decompollaborate/rabbitizer)
![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/Decompollaborate/rabbitizer)
![PyPI](https://img.shields.io/pypi/v/rabbitizer)
![GitHub contributors](https://img.shields.io/github/contributors/Decompollaborate/rabbitizer?logo=purple)
A MIPS instruction decoder API.
Currently supports all the CPU instructions for MIPS I, II, III and IV.
## Installing
The recommended way to install is using from the PyPi release, via `pip`:
```bash
pip install rabbitizer
```
In case you want to mess with the latest development version without wanting to clone the repository, then you could use the following command:
```bash
pip install git+https://github.com/Decompollaborate/rabbitizer.git@develop
```
NOTE: Installing the development version is not recommended. Proceed at your own risk.
## Features
- Should produces matching assembly.
- Fully written in C for fast decoding.
- Python bindings.
- The minimal Python version is 3.7, older versions are not guaranteed to work.
- Includes some minor tools to build your own pointer/symbol detection.
- Configurable, many features can be turned on and off.
- MIPS instructions features:
- Named registers for MIPS VR4300's coprocessors.
- Support for many pseudoinstructions.
- Properly handle move to/from coprocessor instructions.
- Support for numeric, o32, n32 and n64 ABI register names.
- Some workarounds for some specific compilers/assemblers:
- `SN64`:
- `div`/`divu` fix: tweaks a bit the produced `div`, `divu` and `break` instructions.
- N64 RSP instruction decoding support.
- RSP decoding has been tested to build back to matching assemblies with [armips](https://github.com/Kingcom/armips/).
- R5900 (PS2's Emotion Engine processor) decoding support.
## References
- R5900:
- EmotionEngine instruction decoding: <https://psi-rockin.github.io/ps2tek/#eeinstructiondecoding>
- Official documentation from Toshiba: <https://wiki.qemu.org/images/2/2a/C790.pdf>
- VU instruction manual: <http://lukasz.dk/files/vu-instruction-manual.pdf>
- GNU binutils: <https://github.com/bminor/binutils-gdb/blob/master/opcodes/mips-opc.c>
@@ -0,0 +1,36 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_LO_PAIRING_INFO_HPP
#define RABBITIZER_LO_PAIRING_INFO_HPP
#pragma once
#include "analysis/RabbitizerLoPairingInfo.h"
namespace rabbitizer {
class LoPairingInfo {
protected:
RabbitizerLoPairingInfo pairingInfo;
public:
LoPairingInfo();
LoPairingInfo(const RabbitizerLoPairingInfo &pairingInfo);
/**
* Returns a pointer to the inner RabbitizerLoPairingInfo.
* It is recommended to not mess with it unless you know what you are doing.
*/
RabbitizerLoPairingInfo *getCPtr();
const RabbitizerLoPairingInfo *getCPtr() const;
int getInstrOffset() const;
int64_t getValue() const;
bool shouldProcess() const;
bool isGpRel() const;
bool isGpGot() const;
};
};
#endif
@@ -0,0 +1,49 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_REGISTERS_TRACKER_HPP
#define RABBITIZER_REGISTERS_TRACKER_HPP
#pragma once
#include "analysis/RabbitizerRegistersTracker.h"
#include "analysis/LoPairingInfo.hpp"
#include "instructions/InstructionBase.hpp"
namespace rabbitizer {
class RegistersTracker {
protected:
RabbitizerRegistersTracker tracker;
public:
RegistersTracker();
RegistersTracker(const RegistersTracker &other);
virtual ~RegistersTracker();
/**
* Returns a pointer to the inner RabbitizerRegistersTracker.
* It is recommended to not mess with it unless you know what you are doing.
*/
RabbitizerRegistersTracker *getCPtr();
const RabbitizerRegistersTracker *getCPtr() const;
bool moveRegisters(const InstructionBase &instr);
void overwriteRegisters(const InstructionBase &instr, int instrOffset);
void unsetRegistersAfterFuncCall(const InstructionBase &instr, const InstructionBase &prevInstr);
bool getAddressIfCanSetType(const InstructionBase &instr, int instrOffset, uint32_t *dstAddress) const;
bool getJrInfo(const InstructionBase &instr, int *dstOffset, uint32_t *dstAddress) const;
void processLui(const InstructionBase &instr, int instrOffset);
void processLui(const InstructionBase &instr, int instrOffset, const InstructionBase &prevInstr);
void processGpLoad(const InstructionBase &instr, int instrOffset);
bool getLuiOffsetForConstant(const InstructionBase &instr, int *dstOffset) const;
void processConstant(const InstructionBase &instr, uint32_t value, int offset);
LoPairingInfo preprocessLoAndGetInfo(const InstructionBase &instr, int instrOffset);
void processLo(const InstructionBase &instr, uint32_t value, int offset);
bool hasLoButNoHi(const InstructionBase &instr) const;
};
};
#endif
@@ -0,0 +1,38 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRID_HPP
#define RABBITIZER_INSTRID_HPP
#pragma once
#include <string>
namespace rabbitizer {
namespace InstrId {
#define RABBITIZER_DEF_INSTR_ID(prefix, caseBits, name, ...) \
prefix##_##name,
#define RABBITIZER_DEF_INSTR_ID_ALTNAME(prefix, caseBits, name, altname, ...) \
RABBITIZER_DEF_INSTR_ID(prefix, caseBits, name, __VA_ARGS__)
enum class UniqueId {
#include "instructions/instr_id/RabbitizerInstrId_cpu.inc"
#include "instructions/instr_id/RabbitizerInstrId_rsp.inc"
#include "instructions/instr_id/RabbitizerInstrId_r5900.inc"
ALL_MAX = RABBITIZER_DEF_INSTR_ID(r5900, , MAX, )
};
#undef RABBITIZER_DEF_INSTR_ID
#undef RABBITIZER_DEF_INSTR_ID_ALTNAME
std::string getOpcodeName(UniqueId uniqueId);
};
};
#endif
@@ -0,0 +1,253 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRUCTION_BASE_HPP
#define RABBITIZER_INSTRUCTION_BASE_HPP
#pragma once
#include <string>
#include <string_view>
#include "instructions/RabbitizerInstruction.h"
#include "instructions/Registers.hpp"
#include "instructions/OperandType.hpp"
#include "instructions/InstrId.hpp"
namespace rabbitizer {
class InstructionBase {
protected:
RabbitizerInstruction instr;
InstructionBase() = default;
virtual ~InstructionBase() = default;
public:
/**
* Returns a pointer to the inner RabbitizerInstruction.
* It is recommended to not mess with it unless you know what you are doing.
*/
RabbitizerInstruction *getCPtr();
const RabbitizerInstruction *getCPtr() const;
/* getters */
uint8_t Get_opcode() const;
uint8_t Get_sa() const;
uint8_t Get_function() const;
Registers::Cpu::GprO32 GetO32_rs() const;
Registers::Cpu::GprO32 GetO32_rt() const;
Registers::Cpu::GprO32 GetO32_rd() const;
Registers::Cpu::GprN32 GetN32_rs() const;
Registers::Cpu::GprN32 GetN32_rt() const;
Registers::Cpu::GprN32 GetN32_rd() const;
Registers::Cpu::Cop0 Get_cop0d() const;
uint32_t Get_instr_index() const;
uint16_t Get_immediate() const;
Registers::Cpu::Cop1O32 GetO32_fs() const;
Registers::Cpu::Cop1O32 GetO32_ft() const;
Registers::Cpu::Cop1O32 GetO32_fd() const;
Registers::Cpu::Cop1N32 GetN32_fs() const;
Registers::Cpu::Cop1N32 GetN32_ft() const;
Registers::Cpu::Cop1N32 GetN32_fd() const;
Registers::Cpu::Cop1N64 GetN64_fs() const;
Registers::Cpu::Cop1N64 GetN64_ft() const;
Registers::Cpu::Cop1N64 GetN64_fd() const;
Registers::Cpu::Cop1Control Get_cop1cs() const;
Registers::Cpu::Cop2 Get_cop2t() const;
uint8_t Get_op() const;
uint32_t Get_code() const;
uint32_t Get_code_upper() const;
uint32_t Get_code_lower() const;
uint32_t Get_copraw() const;
uint8_t Get_fmt() const;
uint8_t Get_fc() const;
uint8_t Get_cond() const;
uint8_t Get_tf() const;
uint8_t Get_nd() const;
uint8_t Get_bc_fmt() const;
uint8_t Get_stype() const;
/* getters */
/* setters */
void Set_opcode(uint8_t val);
void Set_sa(uint8_t val);
void Set_function(uint8_t val);
void Set_rs(Registers::Cpu::GprO32 val);
void Set_rt(Registers::Cpu::GprO32 val);
void Set_rd(Registers::Cpu::GprO32 val);
void Set_rs(Registers::Cpu::GprN32 val);
void Set_rt(Registers::Cpu::GprN32 val);
void Set_rd(Registers::Cpu::GprN32 val);
void Set_cop0d(Registers::Cpu::Cop0 val);
void Set_instr_index(uint32_t val);
void Set_immediate(uint16_t val);
void Set_fs(Registers::Cpu::Cop1O32 val);
void Set_ft(Registers::Cpu::Cop1O32 val);
void Set_fd(Registers::Cpu::Cop1O32 val);
void Set_fs(Registers::Cpu::Cop1N32 val);
void Set_ft(Registers::Cpu::Cop1N32 val);
void Set_fd(Registers::Cpu::Cop1N32 val);
void Set_fs(Registers::Cpu::Cop1N64 val);
void Set_ft(Registers::Cpu::Cop1N64 val);
void Set_fd(Registers::Cpu::Cop1N64 val);
void Set_cop1cs(Registers::Cpu::Cop1Control val);
void Set_cop2t(Registers::Cpu::Cop2 val);
void Set_op(uint8_t val);
void Set_code(uint32_t val);
void Set_code_upper(uint32_t val);
void Set_code_lower(uint32_t val);
void Set_copraw(uint32_t val);
void Set_fmt(uint8_t val);
void Set_fc(uint8_t val);
void Set_cond(uint8_t val);
void Set_tf(uint8_t val);
void Set_nd(uint8_t val);
void Set_bc_fmt(uint8_t val);
void Set_stype(uint8_t val);
/* setters */
/* more getters */
uint32_t getRaw() const;
InstrId::UniqueId getUniqueId() const;
uint32_t getVram() const;
bool isInHandwrittenFunction() const;
int32_t getProcessedImmediate() const;
uint32_t getInstrIndexAsVram() const;
int32_t getBranchOffset() const;
int32_t getGenericBranchOffset(uint32_t currentVram) const;
std::string getOpcodeName() const;
/* more getters */
/* */
void blankOut();
/* Instruction examination */
bool isImplemented() const;
bool isLikelyHandwritten() const;
bool isNop() const;
bool isUnconditionalBranch() const;
bool isJrRa() const;
bool isJrNotRa() const;
bool hasDelaySlot() const;
std::string mapInstrToType() const;
bool sameOpcode(const InstructionBase &other) const;
bool sameOpcodeButDifferentArguments(const InstructionBase &other) const;
bool hasOperand(OperandType operand) const;
bool hasOperandAlias(OperandType operand) const;
uint32_t getValidBits() const;
bool isValid() const;
/* Instruction examination */
/* Instruction descriptor */
bool isUnknownType() const;
bool isJType() const;
bool isIType() const;
bool isRType() const;
bool isRegimmType() const;
// TODO
// RabbitizerInstrSuffix instrSuffix() const;
bool isBranch() const;
bool isBranchLikely() const;
bool isJump() const;
bool isTrap() const;
bool isFloat() const;
bool isDouble() const;
bool isUnsigned() const;
bool modifiesRt() const;
bool modifiesRd() const;
bool notEmitedByCompilers() const;
bool canBeHi() const;
bool canBeLo() const;
bool doesLink() const;
bool doesDereference() const;
bool doesLoad() const;
bool doesStore() const;
bool maybeIsMove() const;
bool isPseudo() const;
/* Instruction descriptor */
/* Disassembly */
bool mustDisasmAsData() const;
std::string disassembleOperands() const;
std::string disassembleOperands(std::string_view immOverride) const;
std::string disassembleInstruction(int extraLJust) const;
std::string disassembleInstruction(int extraLJust, std::string_view immOverride) const;
std::string disassembleAsData(int extraLJust) const;
std::string disassemble(int extraLJust) const;
std::string disassemble(int extraLJust, std::string_view immOverride) const;
/* Disassembly */
};
};
#endif
@@ -0,0 +1,20 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRUCTION_CPU_HPP
#define RABBITIZER_INSTRUCTION_CPU_HPP
#pragma once
#include "InstructionBase.hpp"
namespace rabbitizer {
class InstructionCpu : public InstructionBase {
public:
InstructionCpu(uint32_t word, uint32_t vram);
virtual ~InstructionCpu();
};
};
#endif
@@ -0,0 +1,41 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRUCTION_R5900_HPP
#define RABBITIZER_INSTRUCTION_R5900_HPP
#pragma once
#include "InstructionBase.hpp"
namespace rabbitizer {
class InstructionR5900 : public InstructionBase {
public:
InstructionR5900(uint32_t word, uint32_t vram);
virtual ~InstructionR5900();
Registers::R5900::VF GetR5900_vfs() const;
Registers::R5900::VF GetR5900_vft() const;
Registers::R5900::VF GetR5900_vfd() const;
Registers::R5900::VI GetR5900_vis() const;
Registers::R5900::VI GetR5900_vit() const;
Registers::R5900::VI GetR5900_vid() const;
uint8_t GetR5900_mmi_function() const;
uint8_t GetR5900_fhi_flo() const;
uint8_t GetR5900_xyzw_x() const;
uint8_t GetR5900_xyzw_y() const;
uint8_t GetR5900_xyzw_z() const;
uint8_t GetR5900_xyzw_w() const;
uint8_t GetR5900_n() const;
uint8_t GetR5900_l() const;
uint8_t GetR5900_m() const;
uint8_t GetR5900_imm5() const;
};
};
#endif
@@ -0,0 +1,40 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRUCTION_RSP_HPP
#define RABBITIZER_INSTRUCTION_RSP_HPP
#pragma once
#include "InstructionBase.hpp"
namespace rabbitizer {
class InstructionRsp : public InstructionBase {
public:
InstructionRsp(uint32_t word, uint32_t vram);
virtual ~InstructionRsp();
Registers::Rsp::Gpr GetRsp_rs() const;
Registers::Rsp::Gpr GetRsp_rt() const;
Registers::Rsp::Gpr GetRsp_rd() const;
Registers::Rsp::Cop0 GetRsp_cop0d() const;
Registers::Rsp::Cop2 GetRsp_cop2t() const;
Registers::Rsp::Cop2Control GetRsp_cop2cd() const;
Registers::Rsp::Vector GetRsp_vs() const;
Registers::Rsp::Vector GetRsp_vt() const;
Registers::Rsp::Vector GetRsp_vd() const;
uint8_t GetRsp_elementhigh() const;
uint8_t GetRsp_elementlow() const;
uint8_t GetRsp_index() const;
uint8_t GetRsp_de() const;
};
};
#endif
@@ -0,0 +1,27 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_OPERAND_TYPE_HPP
#define RABBITIZER_OPERAND_TYPE_HPP
#pragma once
namespace rabbitizer {
#define RAB_DEF_OPERAND(prefix, operand) \
prefix##_##operand,
enum class OperandType {
RAB_DEF_OPERAND(ALL, INVALID)
#include "instructions/operands/RabbitizerOperandType_cpu.inc"
#include "instructions/operands/RabbitizerOperandType_rsp.inc"
#include "instructions/operands/RabbitizerOperandType_r5900.inc"
RAB_DEF_OPERAND(ALL, MAX)
};
#undef RAB_DEF_OPERAND
};
#endif
@@ -0,0 +1,94 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_REGISTER_HPP
#define RABBITIZER_REGISTER_HPP
#pragma once
namespace rabbitizer {
namespace Registers {
#define RABBITIZER_DEF_REG(prefix, name, numeric) \
prefix##_##name
#define RABBITIZER_DEF_REG_NODOLLAR(prefix, name, numeric) \
prefix##_##name
namespace Cpu {
enum class GprO32 {
#include "instructions/registers/RabbitizerRegister_GprO32.inc"
};
enum class GprN32 {
#include "instructions/registers/RabbitizerRegister_GprN32.inc"
};
enum class Cop0 {
#include "instructions/registers/RabbitizerRegister_Cop0.inc"
};
// Float registers
enum class Cop1O32 {
#include "instructions/registers/RabbitizerRegister_Cop1O32.inc"
};
enum class Cop1N32 {
#include "instructions/registers/RabbitizerRegister_Cop1N32.inc"
};
enum class Cop1N64 {
#include "instructions/registers/RabbitizerRegister_Cop1N64.inc"
};
enum class Cop1Control {
#include "instructions/registers/RabbitizerRegister_Cop1Control.inc"
};
enum class Cop2 {
#include "instructions/registers/RabbitizerRegister_Cop2.inc"
};
};
namespace Rsp {
enum class Gpr {
#include "instructions/registers/RabbitizerRegister_RspGpr.inc"
};
enum class Cop0 {
#include "instructions/registers/RabbitizerRegister_RspCop0.inc"
};
enum class Cop2 {
#include "instructions/registers/RabbitizerRegister_RspCop2.inc"
};
enum class Cop2Control {
#include "instructions/registers/RabbitizerRegister_RspCop2Control.inc"
};
enum class Vector {
#include "instructions/registers/RabbitizerRegister_RspVector.inc"
};
};
namespace R5900 {
enum class VF {
#include "instructions/registers/RabbitizerRegister_R5900VF.inc"
};
enum class VI {
#include "instructions/registers/RabbitizerRegister_R5900VI.inc"
};
};
#undef RABBITIZER_DEF_REG
#undef RABBITIZER_DEF_REG_NODOLLAR
};
};
#endif
@@ -0,0 +1,26 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_HPP
#define RABBITIZER_HPP
#pragma once
#include "common/RabbitizerVersion.h"
#include "common/RabbitizerConfig.h"
#include "instructions/OperandType.hpp"
#include "instructions/InstrId.hpp"
//#include "instructions/InstrSuffix.hpp"
//#include "instructions/InstrDescriptor.hpp"
#include "instructions/Registers.hpp"
#include "instructions/InstructionBase.hpp"
#include "instructions/InstructionCpu.hpp"
#include "instructions/InstructionRsp.hpp"
#include "instructions/InstructionR5900.hpp"
#include "analysis/LoPairingInfo.hpp"
#include "analysis/RegistersTracker.hpp"
#endif
@@ -0,0 +1,34 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "analysis/LoPairingInfo.hpp"
using namespace rabbitizer;
LoPairingInfo::LoPairingInfo() : pairingInfo{} {
}
LoPairingInfo::LoPairingInfo(const RabbitizerLoPairingInfo &newPairingInfo) : pairingInfo{ newPairingInfo } {
}
RabbitizerLoPairingInfo *LoPairingInfo::getCPtr() {
return &this->pairingInfo;
}
const RabbitizerLoPairingInfo *LoPairingInfo::getCPtr() const {
return &this->pairingInfo;
}
int LoPairingInfo::getInstrOffset() const {
return this->pairingInfo.instrOffset;
}
int64_t LoPairingInfo::getValue() const {
return this->pairingInfo.value;
}
bool LoPairingInfo::shouldProcess() const {
return this->pairingInfo.shouldProcess;
}
bool LoPairingInfo::isGpRel() const {
return this->pairingInfo.isGpRel;
}
bool LoPairingInfo::isGpGot() const {
return this->pairingInfo.isGpGot;
}
@@ -0,0 +1,64 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "analysis/RegistersTracker.hpp"
using namespace rabbitizer;
RegistersTracker::RegistersTracker() {
RabbitizerRegistersTracker_init(&this->tracker, NULL);
}
RegistersTracker::RegistersTracker(const RegistersTracker &other) {
RabbitizerRegistersTracker_init(&this->tracker, &other.tracker);
}
RegistersTracker::~RegistersTracker() {
RabbitizerRegistersTracker_destroy(&this->tracker);
}
RabbitizerRegistersTracker *RegistersTracker::getCPtr() {
return &this->tracker;
}
const RabbitizerRegistersTracker *RegistersTracker::getCPtr() const {
return &this->tracker;
}
bool RegistersTracker::moveRegisters(const InstructionBase &instr) {
return RabbitizerRegistersTracker_moveRegisters(&this->tracker, instr.getCPtr());
}
void RegistersTracker::overwriteRegisters(const InstructionBase &instr, int instrOffset) {
RabbitizerRegistersTracker_overwriteRegisters(&this->tracker, instr.getCPtr(), instrOffset);
}
void RegistersTracker::unsetRegistersAfterFuncCall(const InstructionBase &instr, const InstructionBase &prevInstr) {
RabbitizerRegistersTracker_unsetRegistersAfterFuncCall(&this->tracker, instr.getCPtr(), prevInstr.getCPtr());
}
bool RegistersTracker::getAddressIfCanSetType(const InstructionBase &instr, int instrOffset, uint32_t *dstAddress) const {
return RabbitizerRegistersTracker_getAddressIfCanSetType(&this->tracker, instr.getCPtr(), instrOffset, dstAddress);
}
bool RegistersTracker::getJrInfo(const InstructionBase &instr, int *dstOffset, uint32_t *dstAddress) const {
return RabbitizerRegistersTracker_getJrInfo(&this->tracker, instr.getCPtr(), dstOffset, dstAddress);
}
void RegistersTracker::processLui(const InstructionBase &instr, int instrOffset) {
RabbitizerRegistersTracker_processLui(&this->tracker, instr.getCPtr(), instrOffset, NULL);
}
void RegistersTracker::processLui(const InstructionBase &instr, int instrOffset, const InstructionBase &prevInstr) {
RabbitizerRegistersTracker_processLui(&this->tracker, instr.getCPtr(), instrOffset, prevInstr.getCPtr());
}
void RegistersTracker::processGpLoad(const InstructionBase &instr, int instrOffset) {
RabbitizerRegistersTracker_processGpLoad(&this->tracker, instr.getCPtr(), instrOffset);
}
bool RegistersTracker::getLuiOffsetForConstant(const InstructionBase &instr, int *dstOffset) const {
return RabbitizerRegistersTracker_getLuiOffsetForConstant(&this->tracker, instr.getCPtr(), dstOffset);
}
void RegistersTracker::processConstant(const InstructionBase &instr, uint32_t value, int offset) {
RabbitizerRegistersTracker_processConstant(&this->tracker, instr.getCPtr(), value, offset);
}
LoPairingInfo RegistersTracker::preprocessLoAndGetInfo(const InstructionBase &instr, int instrOffset) {
return RabbitizerRegistersTracker_preprocessLoAndGetInfo(&this->tracker, instr.getCPtr(), instrOffset);
}
void RegistersTracker::processLo(const InstructionBase &instr, uint32_t value, int offset) {
RabbitizerRegistersTracker_processLo(&this->tracker, instr.getCPtr(), value, offset);
}
bool RegistersTracker::hasLoButNoHi(const InstructionBase &instr) const {
return RabbitizerRegistersTracker_hasLoButNoHi(&this->tracker, instr.getCPtr());
}
@@ -0,0 +1,14 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "instructions/InstrId.hpp"
#include "instructions/RabbitizerInstrId.h"
using namespace rabbitizer;
std::string InstrId::getOpcodeName(InstrId::UniqueId uniqueId) {
RabbitizerInstrId id = static_cast<RabbitizerInstrId>(uniqueId);
return std::string(RabbitizerInstrId_getOpcodeName(id));
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,15 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "instructions/InstructionCpu.hpp"
using namespace rabbitizer;
InstructionCpu::InstructionCpu(uint32_t word, uint32_t vram) : InstructionBase() {
RabbitizerInstruction_init(&this->instr, word, vram);
RabbitizerInstruction_processUniqueId(&this->instr);
}
InstructionCpu::~InstructionCpu() {
RabbitizerInstruction_destroy(&this->instr);
}
@@ -0,0 +1,118 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "instructions/InstructionR5900.hpp"
#include <stdexcept>
#include "instructions/RabbitizerInstructionR5900.h"
using namespace rabbitizer;
InstructionR5900::InstructionR5900(uint32_t word, uint32_t vram) : InstructionBase() {
RabbitizerInstructionR5900_init(&this->instr, word, vram);
RabbitizerInstructionR5900_processUniqueId(&this->instr);
}
InstructionR5900::~InstructionR5900() {
RabbitizerInstructionR5900_destroy(&this->instr);
}
Registers::R5900::VF InstructionR5900::GetR5900_vfs() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_rs)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'vfs' operand.");
}
#endif
return static_cast<Registers::R5900::VF>(RAB_INSTR_R5900_GET_vfs(&this->instr));
}
Registers::R5900::VF InstructionR5900::GetR5900_vft() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_rt)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'vft' operand.");
}
#endif
return static_cast<Registers::R5900::VF>(RAB_INSTR_R5900_GET_vft(&this->instr));
}
Registers::R5900::VF InstructionR5900::GetR5900_vfd() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_rd)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'vfd' operand.");
}
#endif
return static_cast<Registers::R5900::VF>(RAB_INSTR_R5900_GET_vfd(&this->instr));
}
Registers::R5900::VI InstructionR5900::GetR5900_vis() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_rs)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'vis' operand.");
}
#endif
return static_cast<Registers::R5900::VI>(RAB_INSTR_R5900_GET_vis(&this->instr));
}
Registers::R5900::VI InstructionR5900::GetR5900_vit() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_rt)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'vit' operand.");
}
#endif
return static_cast<Registers::R5900::VI>(RAB_INSTR_R5900_GET_vit(&this->instr));
}
Registers::R5900::VI InstructionR5900::GetR5900_vid() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_rd)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'vid' operand.");
}
#endif
return static_cast<Registers::R5900::VI>(RAB_INSTR_R5900_GET_vid(&this->instr));
}
uint8_t InstructionR5900::GetR5900_mmi_function() const {
return RAB_INSTR_R5900_GET_mmi_function(&this->instr);
}
uint8_t InstructionR5900::GetR5900_fhi_flo() const {
return RAB_INSTR_R5900_GET_fhi_flo(&this->instr);
}
uint8_t InstructionR5900::GetR5900_xyzw_x() const {
return RAB_INSTR_R5900_GET_xyzw_x(&this->instr);
}
uint8_t InstructionR5900::GetR5900_xyzw_y() const {
return RAB_INSTR_R5900_GET_xyzw_y(&this->instr);
}
uint8_t InstructionR5900::GetR5900_xyzw_z() const {
return RAB_INSTR_R5900_GET_xyzw_z(&this->instr);
}
uint8_t InstructionR5900::GetR5900_xyzw_w() const {
return RAB_INSTR_R5900_GET_xyzw_w(&this->instr);
}
uint8_t InstructionR5900::GetR5900_n() const {
return RAB_INSTR_R5900_GET_n(&this->instr);
}
uint8_t InstructionR5900::GetR5900_l() const {
return RAB_INSTR_R5900_GET_l(&this->instr);
}
uint8_t InstructionR5900::GetR5900_m() const {
return RAB_INSTR_R5900_GET_m(&this->instr);
}
uint8_t InstructionR5900::GetR5900_imm5() const {
return RAB_INSTR_R5900_GET_imm5(&this->instr);
}
@@ -0,0 +1,128 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "instructions/InstructionRsp.hpp"
#include <stdexcept>
#include "instructions/RabbitizerInstructionRsp.h"
using namespace rabbitizer;
InstructionRsp::InstructionRsp(uint32_t word, uint32_t vram) : InstructionBase() {
RabbitizerInstructionRsp_init(&this->instr, word, vram);
RabbitizerInstructionRsp_processUniqueId(&this->instr);
}
InstructionRsp::~InstructionRsp() {
RabbitizerInstructionRsp_destroy(&this->instr);
}
Registers::Rsp::Gpr InstructionRsp::GetRsp_rs() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_rs)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'rs' operand.");
}
#endif
return static_cast<Registers::Rsp::Gpr>(RAB_INSTR_GET_rs(&this->instr));
}
Registers::Rsp::Gpr InstructionRsp::GetRsp_rt() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_rt)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'rt' operand.");
}
#endif
return static_cast<Registers::Rsp::Gpr>(RAB_INSTR_GET_rt(&this->instr));
}
Registers::Rsp::Gpr InstructionRsp::GetRsp_rd() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_rd)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'rd' operand.");
}
#endif
return static_cast<Registers::Rsp::Gpr>(RAB_INSTR_GET_rd(&this->instr));
}
Registers::Rsp::Cop0 InstructionRsp::GetRsp_cop0d() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_cop0d)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'cop0d' operand.");
}
#endif
return static_cast<Registers::Rsp::Cop0>(RAB_INSTR_GET_cop0d(&this->instr));
}
Registers::Rsp::Cop2 InstructionRsp::GetRsp_cop2t() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_cop2t)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'cop2t' operand.");
}
#endif
return static_cast<Registers::Rsp::Cop2>(RAB_INSTR_RSP_GET_cop2t(&this->instr));
}
Registers::Rsp::Cop2Control InstructionRsp::GetRsp_cop2cd() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_cop2t)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'cop2cd' operand.");
}
#endif
return static_cast<Registers::Rsp::Cop2Control>(RAB_INSTR_RSP_GET_cop2cd(&this->instr));
}
Registers::Rsp::Vector InstructionRsp::GetRsp_vs() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_vs)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'vs' operand.");
}
#endif
return static_cast<Registers::Rsp::Vector>(RAB_INSTR_RSP_GET_vs(&this->instr));
}
Registers::Rsp::Vector InstructionRsp::GetRsp_vt() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_vt)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'vt' operand.");
}
#endif
return static_cast<Registers::Rsp::Vector>(RAB_INSTR_RSP_GET_vt(&this->instr));
}
Registers::Rsp::Vector InstructionRsp::GetRsp_vd() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::rsp_vd)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have 'vd' operand.");
}
#endif
return static_cast<Registers::Rsp::Vector>(RAB_INSTR_RSP_GET_vd(&this->instr));
}
uint8_t InstructionRsp::GetRsp_elementhigh() const {
return RAB_INSTR_RSP_GET_elementhigh(&this->instr);
}
uint8_t InstructionRsp::GetRsp_elementlow() const {
return RAB_INSTR_RSP_GET_elementlow(&this->instr);
}
uint8_t InstructionRsp::GetRsp_index() const {
return RAB_INSTR_RSP_GET_index(&this->instr);
}
uint8_t InstructionRsp::GetRsp_de() const {
return RAB_INSTR_RSP_GET_de(&this->instr);
}
@@ -0,0 +1,34 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_LO_PAIRING_INFO_H
#define RABBITIZER_LO_PAIRING_INFO_H
#pragma once
#include <stdbool.h>
#include "common/Utils.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct RabbitizerLoPairingInfo {
int instrOffset;
int64_t value; // could be either an unsigned 32 bits number or a signed one, so use 64 bits to ensure it fits
bool shouldProcess;
bool isGpRel;
bool isGpGot;
} RabbitizerLoPairingInfo;
NON_NULL(1)
void RabbitizerLoPairingInfo_Init(RabbitizerLoPairingInfo *self);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,65 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_REGISTERS_TRACKER_H
#define RABBITIZER_REGISTERS_TRACKER_H
#pragma once
#include "common/Utils.h"
#include "RabbitizerTrackedRegisterState.h"
#include "RabbitizerLoPairingInfo.h"
#include "instructions/RabbitizerInstruction.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RAB_REGISTERS_COUNT 32
typedef struct RabbitizerRegistersTracker {
RabbitizerTrackedRegisterState registers[RAB_REGISTERS_COUNT];
} RabbitizerRegistersTracker;
// TODO: Change functions which use parameters as a way to return values into actual structs returned by the functions
NON_NULL(1)
void RabbitizerRegistersTracker_init(RabbitizerRegistersTracker *self, const RabbitizerRegistersTracker *other);
NON_NULL(1)
void RabbitizerRegistersTracker_destroy(RabbitizerRegistersTracker *self);
NON_NULL(1, 2)
bool RabbitizerRegistersTracker_moveRegisters(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr);
NON_NULL(1, 2)
void RabbitizerRegistersTracker_overwriteRegisters(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset);
NON_NULL(1, 2, 3)
void RabbitizerRegistersTracker_unsetRegistersAfterFuncCall(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, const RabbitizerInstruction *prevInstr);
NON_NULL(1, 2, 4)
bool RabbitizerRegistersTracker_getAddressIfCanSetType(const RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset, uint32_t *dstAddress);
NON_NULL(1, 2, 3, 4)
bool RabbitizerRegistersTracker_getJrInfo(const RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int *dstOffset, uint32_t *dstAddress);
// prevInstr can be NULL
NON_NULL(1, 2)
void RabbitizerRegistersTracker_processLui(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset, const RabbitizerInstruction *prevInstr);
NON_NULL(1, 2)
void RabbitizerRegistersTracker_processGpLoad(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset);
NON_NULL(1, 2, 3)
bool RabbitizerRegistersTracker_getLuiOffsetForConstant(const RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int *dstOffset);
NON_NULL(1, 2)
void RabbitizerRegistersTracker_processConstant(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, uint32_t value, int offset);
NON_NULL(1, 2, 4, 5) // deprecated
bool RabbitizerRegistersTracker_getLuiOffsetForLo(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset, int *dstOffset, bool *dstIsGp);
NODISCARD NON_NULL(1, 2)
RabbitizerLoPairingInfo RabbitizerRegistersTracker_preprocessLoAndGetInfo(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset);
NON_NULL(1, 2)
void RabbitizerRegistersTracker_processLo(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, uint32_t value, int offset);
NON_NULL(1, 2)
bool RabbitizerRegistersTracker_hasLoButNoHi(const RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,80 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_TRACKED_REGISTER_STATE_H
#define RABBITIZER_TRACKED_REGISTER_STATE_H
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "common/Utils.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct RabbitizerTrackedRegisterState {
int registerNum;
bool hasLuiValue;
int luiOffset; // The offset of last lui which set a value to this register
bool luiSetOnBranchLikely;
bool hasGpGot;
int gpGotOffset;
bool hasLoValue;
int loOffset;
bool dereferenced;
int dereferenceOffset;
uint32_t value;
} RabbitizerTrackedRegisterState;
NON_NULL(1)
void RabbitizerTrackedRegisterState_init(RabbitizerTrackedRegisterState *self, int registerNum);
NON_NULL(1)
void RabbitizerTrackedRegisterState_destroy(RabbitizerTrackedRegisterState *self);
NON_NULL(1)
void RabbitizerTrackedRegisterState_clear(RabbitizerTrackedRegisterState *self);
NON_NULL(1)
void RabbitizerTrackedRegisterState_clearHi(RabbitizerTrackedRegisterState *self);
NON_NULL(1)
void RabbitizerTrackedRegisterState_clearGp(RabbitizerTrackedRegisterState *self);
NON_NULL(1)
void RabbitizerTrackedRegisterState_clearLo(RabbitizerTrackedRegisterState *self);
NON_NULL(1, 2)
void RabbitizerTrackedRegisterState_copyState(RabbitizerTrackedRegisterState *self, const RabbitizerTrackedRegisterState *other);
NON_NULL(1)
void RabbitizerTrackedRegisterState_setHi(RabbitizerTrackedRegisterState *self, uint32_t value, int offset);
NON_NULL(1)
void RabbitizerTrackedRegisterState_setGpLoad(RabbitizerTrackedRegisterState *self, uint32_t value, int offset);
NON_NULL(1)
void RabbitizerTrackedRegisterState_setLo(RabbitizerTrackedRegisterState *self, uint32_t value, int offset);
NON_NULL(1)
void RabbitizerTrackedRegisterState_deref(RabbitizerTrackedRegisterState *self, int offset);
NON_NULL(1, 2)
void RabbitizerTrackedRegisterState_dereferenceState(RabbitizerTrackedRegisterState *self, const RabbitizerTrackedRegisterState *other, int offset);
NODISCARD NON_NULL(1) PURE
bool RabbitizerTrackedRegisterState_hasAnyValue(const RabbitizerTrackedRegisterState *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerTrackedRegisterState_wasSetInCurrentOffset(const RabbitizerTrackedRegisterState *self, int offset);
NON_NULL(1)
void RabbitizerTrackedRegisterState_fprint(const RabbitizerTrackedRegisterState *self, FILE* outFile);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,7 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_ABI(NUMERIC),
RABBITIZER_DEF_ABI(O32),
RABBITIZER_DEF_ABI(N32),
RABBITIZER_DEF_ABI(N64),
@@ -0,0 +1,83 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_CONFIG_H
#define RABBITIZER_CONFIG_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#define RABBITIZER_DEF_ABI(name) RABBITIZER_ABI_##name
typedef enum RabbitizerAbi {
#include "Abi.inc"
RABBITIZER_DEF_ABI(MAX),
} RabbitizerAbi;
#undef RABBITIZER_DEF_ABI
RabbitizerAbi RabbitizerAbi_fromStr(const char *name);
typedef struct RabbitizerConfig_RegisterNames {
bool namedRegisters; // Enables using named registers. This option takes precedence over the other named register options
RabbitizerAbi gprAbiNames; // The ABI names to be used for general purpose registers when disassembling the main processor's instructions
RabbitizerAbi fprAbiNames; // The ABI names to be used for floating point registers when disassembling the floating point (coprocessor 1) instructions
bool userFpcCsr; // Use FpcCsr as register $31 for the FP control/status register
bool vr4300Cop0NamedRegisters; // Use named registers for VR4300's coprocessor 0 registers
bool vr4300RspCop0NamedRegisters; // Use named registers for VR4300's RSP's coprocessor 0 registers
} RabbitizerConfig_RegisterNames;
typedef struct RabbitizerConfig_PseudoInstr {
bool enablePseudos; // Produce pseudo instructions (like `move` or `b`) whenever those may match the desired original instruction
bool pseudoBeqz;
bool pseudoBnez;
bool pseudoB;
bool pseudoMove;
bool pseudoNot;
bool pseudoNegu;
bool pseudoBal;
} RabbitizerConfig_PseudoInstr;
typedef struct RabbitizerConfig_ToolchainTweaks {
bool treatJAsUnconditionalBranch; //! @deprecated
/**
* Enables a few fixes for SN64's assembler related to div/divu instructions
*
* - SN64's assembler doesn't like assembling `div $0, a, b` with .set noat active.
* Removing the $0 fixes this issue (but not for handwritten asm)
*
* - SN64's assembler expands div to have break if dividing by zero
* However, the break it generates is different than the one it generates with `break N`
* So we replace break instrutions for SN64 with the exact word that the assembler generates when expanding div
*/
bool sn64DivFix;
} RabbitizerConfig_ToolchainTweaks;
typedef struct RabbitizerConfig_Misc {
int opcodeLJust; // The minimal number of characters to left-align the opcode name
bool unknownInstrComment; // Generate a pseudo-disassembly comment when disassembling non implemented instructions
bool omit0XOnSmallImm;
bool upperCaseImm;
} RabbitizerConfig_Misc;
typedef struct RabbitizerConfig {
RabbitizerConfig_RegisterNames regNames;
RabbitizerConfig_PseudoInstr pseudos;
RabbitizerConfig_ToolchainTweaks toolchainTweaks;
RabbitizerConfig_Misc misc;
} RabbitizerConfig;
extern RabbitizerConfig RabbitizerConfig_Cfg;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,33 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_VERSION_H
#define RABBITIZER_VERSION_H
#include "Utils.h"
#ifdef __cplusplus
extern "C" {
#endif
// Header version
#define RAB_VERSION_MAJOR 1
#define RAB_VERSION_MINOR 2
#define RAB_VERSION_PATCH 3
#define RAB_VERSION_STR RAB_STRINGIFY(RAB_VERSION_MAJOR) "." RAB_STRINGIFY(RAB_VERSION_MINOR) "." RAB_STRINGIFY(RAB_VERSION_PATCH)
// Compiled library version
extern const int RabVersion_Major;
extern const int RabVersion_Minor;
extern const int RabVersion_Patch;
extern const char RabVersion_Str[];
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,116 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_UTILS_H
#define RABBITIZER_UTILS_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(__GNUC__) && !defined(__clang__)
#define __attribute__(x)
#endif
#if __STDC_VERSION__ >= 202000L
#define CONST [[gnu::const]]
#define DEPRECATED(reason) [[deprecated (reason)]]
#define FALLTHROUGH [[fallthrough]]
#define NODISCARD [[nodiscard]]
#define NORETURN [[noreturn]]
#define NON_NULL(...) [[gnu::nonnull (__VA_ARGS__)]]
#define PURE [[gnu::pure]]
#define RETURNS_NON_NULL [[gnu::returns_nonnull]]
#define UNUSED [[maybe_unused]]
#else
#define CONST __attribute__((const))
#define DEPRECATED(reason) __attribute__((deprecated (reason)))
#define FALLTHROUGH __attribute__((fallthrough))
#define NODISCARD __attribute__((warn_unused_result))
#define NORETURN _Noreturn
#define NON_NULL(...) __attribute__((nonnull (__VA_ARGS__)))
#define PURE __attribute__((pure))
#define RETURNS_NON_NULL __attribute__((returns_nonnull))
#define UNUSED __attribute__((unused))
#endif
#if defined(_MSC_VER)
# define UNREACHABLE __assume(0)
#elif defined(__GNUC__) || defined(__clang__)
# define UNREACHABLE __builtin_unreachable()
#else
# define UNREACHABLE
#endif
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof((arr)[0]))
#define RAB_STRINGIFY(x) #x
#define MASK(v, w) ((v) & ((1 << (w)) - 1))
/*
* the SHIFT macros take a value, a shift amount, and a width.
*
* For the left shift, the lower bits of the value are masked,
* then shifted left.
*
* For the right shift, the value is shifted right, then the lower bits
* are masked.
*
* (NOTE: SHIFTL(v, 0, 32) won't work, just use an assignment)
*
*/
#define SHIFTL(v, s, w) (MASK((v), (w)) << (s))
#define SHIFTR(v, s, w) (MASK((v) >> (s), (w)))
#define BITREPACK(fullword, v, s, w) ((SHIFTR((fullword), (s)+(w), 32-((s)+(w))) << ((s)+(w))) | SHIFTL((v), (s), (w)) | MASK((fullword), (s)))
#define BITREPACK_RIGHT(fullword, v, s, w) (SHIFTL((v), (s), (w)) | MASK((fullword), (s)))
#define RABUTILS_BUFFER_ADVANCE(buffer, totalSize, expression) \
do { \
size_t __tempSize = expression; \
(buffer) += __tempSize; \
(totalSize) += __tempSize; \
} while (0)
#define RABUTILS_BUFFER_WRITE_CHAR(buffer, totalSize, character) \
do { \
*(buffer) = (character); \
RABUTILS_BUFFER_ADVANCE(buffer, totalSize, 1); \
} while (0)
#define RABUTILS_BUFFER_SPRINTF(buffer, totalSize, format, ...) \
do { \
int _len = sprintf(buffer, format, __VA_ARGS__); \
assert(_len > 0); \
RABUTILS_BUFFER_ADVANCE(buffer, totalSize, _len); \
} while (0)
#define RABUTILS_BUFFER_CPY(buffer, totalSize, string) \
do { \
size_t _tempSize = strlen(string); \
memcpy(buffer, string, _tempSize); \
RABUTILS_BUFFER_ADVANCE(buffer, totalSize, _tempSize); \
} while (0)
CONST NODISCARD
int32_t RabbitizerUtils_From2Complement(uint32_t number, int bits);
NON_NULL(1)
size_t RabbitizerUtils_CharFill(char *dst, int count, char fillchar);
NON_NULL(1, 3)
size_t RabbitizerUtils_escapeString(char *dst, size_t dstSize, const char *src, size_t srcSize);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_INSTR_CATEGORY(CPU),
RABBITIZER_DEF_INSTR_CATEGORY(RSP), // N64
RABBITIZER_DEF_INSTR_CATEGORY(R5900), // PS2's Emotion Engine
@@ -0,0 +1,141 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRDESCRIPTOR_H
#define RABBITIZER_INSTRDESCRIPTOR_H
#pragma once
#include <stdbool.h>
#include "common/Utils.h"
#include "RabbitizerOperandType.h"
#include "RabbitizerInstrId.h"
#include "RabbitizerInstrSuffix.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum RabbitizerInstrType {
RABBITIZER_INSTR_TYPE_UNKNOWN,
RABBITIZER_INSTR_TYPE_J,
RABBITIZER_INSTR_TYPE_I,
RABBITIZER_INSTR_TYPE_R,
RABBITIZER_INSTR_TYPE_REGIMM,
RABBITIZER_INSTR_TYPE_MAX,
} RabbitizerInstrType;
typedef enum RabbitizerArchitectureVersion {
RABBITIZER_ARCHVERSION_INVALID=-1,
RABBITIZER_ARCHVERSION_UNKNOWN,
RABBITIZER_ARCHVERSION_MIPS_I,
RABBITIZER_ARCHVERSION_MIPS_II,
RABBITIZER_ARCHVERSION_MIPS_III,
RABBITIZER_ARCHVERSION_MIPS_IV
} RabbitizerArchitectureVersion;
typedef struct RabbitizerInstrDescriptor {
RabbitizerOperandType operands[4];
RabbitizerInstrType instrType;
RabbitizerInstrSuffix instrSuffix;
bool isBranch;
bool isBranchLikely;
bool isJump;
bool isTrap;
bool isFloat;
bool isDouble;
bool isUnsigned;
bool modifiesRt;
bool modifiesRd;
bool notEmitedByCompilers;
bool canBeHi;
bool canBeLo;
bool doesLink; // "and link" family of instructions
bool doesDereference;
bool doesLoad; // loads data from memory
bool doesStore; // stores data to memory
bool maybeIsMove;
bool isPseudo;
RabbitizerArchitectureVersion architectureVersion; // TODO: consider removing
} RabbitizerInstrDescriptor;
// TODO: less redundant name
extern const RabbitizerInstrDescriptor RabbitizerInstrDescriptor_Descriptors[];
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isUnknownType(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isJType(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isIType(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isRType(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isRegimmType(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
RabbitizerInstrSuffix RabbitizerInstrDescriptor_instrSuffix(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isBranch(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isBranchLikely(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isJump(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isTrap(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isFloat(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isDouble(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isUnsigned(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_modifiesRt(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_modifiesRd(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_notEmitedByCompilers(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_canBeHi(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_canBeLo(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_doesLink(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_doesDereference(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_doesLoad(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_doesStore(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_maybeIsMove(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstrDescriptor_isPseudo(const RabbitizerInstrDescriptor *self);
NODISCARD NON_NULL(1) PURE
RabbitizerArchitectureVersion RabbitizerInstrDescriptor_getArchitectureVersion(const RabbitizerInstrDescriptor *self);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,46 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRID_H
#define RABBITIZER_INSTRID_H
#pragma once
#include "common/Utils.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RABBITIZER_DEF_INSTR_ID(prefix, caseBits, name, ...) \
RABBITIZER_INSTR_ID_##prefix##_##name,
#define RABBITIZER_DEF_INSTR_ID_ALTNAME(prefix, caseBits, name, altname, ...) \
RABBITIZER_DEF_INSTR_ID(prefix, caseBits, name, __VA_ARGS__)
typedef enum RabbitizerInstrId {
#include "instructions/instr_id/RabbitizerInstrId_cpu.inc"
#include "instructions/instr_id/RabbitizerInstrId_rsp.inc"
#include "instructions/instr_id/RabbitizerInstrId_r5900.inc"
RABBITIZER_INSTR_ID_ALL_MAX = RABBITIZER_DEF_INSTR_ID(r5900, , MAX, )
} RabbitizerInstrId;
#undef RABBITIZER_DEF_INSTR_ID
#undef RABBITIZER_DEF_INSTR_ID_ALTNAME
extern const char *RabbitizerInstrId_Names[];
CONST NODISCARD RETURNS_NON_NULL
const char *RabbitizerInstrId_getOpcodeName(RabbitizerInstrId uniqueId);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,36 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRSUFFIX_H
#define RABBITIZER_INSTRSUFFIX_H
#pragma once
#include "common/Utils.h"
#ifdef __cplusplus
extern "C" {
#endif
struct RabbitizerInstruction;
typedef enum RabbitizerInstrSuffix {
RABINSTRSUFFIX_NONE,
RABINSTRSUFFIX_R5900_xyzw,
RABINSTRSUFFIX_MAX
} RabbitizerInstrSuffix;
CONST NODISCARD NON_NULL(1)
size_t RabbitizerInstrSuffix_getSizeForBuffer(const struct RabbitizerInstruction *self, RabbitizerInstrSuffix instrSuffix);
CONST NODISCARD NON_NULL(1, 2)
size_t RabbitizerInstrSuffix_processSuffix(const struct RabbitizerInstruction *self, char *dst, RabbitizerInstrSuffix instrSuffix);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,263 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRUCTION_H
#define RABBITIZER_INSTRUCTION_H
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "common/Utils.h"
#include "RabbitizerInstrId.h"
#include "RabbitizerInstrDescriptor.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RABBITIZER_DEF_INSTR_CATEGORY(name) RABBITIZER_INSTRCAT_##name
typedef enum RabbitizerInstrCategory {
#include "instructions/InstrCategory.inc"
RABBITIZER_DEF_INSTR_CATEGORY(MAX),
} RabbitizerInstrCategory;
#undef RABBITIZER_DEF_INSTR_CATEGORY
typedef struct RabbitizerInstruction {
uint32_t word;
uint32_t _mandatorybits;
RabbitizerInstrId uniqueId;
const RabbitizerInstrDescriptor *descriptor;
uint32_t vram;
bool _handwrittenCategory;
bool inHandwrittenFunction;
RabbitizerInstrCategory category;
} RabbitizerInstruction;
#define RAB_INSTR_GET_opcode(self) (SHIFTR((self)->word, 26, 6))
#define RAB_INSTR_GET_rs(self) (SHIFTR((self)->word, 21, 5))
#define RAB_INSTR_GET_rt(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_GET_rd(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_GET_sa(self) (SHIFTR((self)->word, 6, 5))
#define RAB_INSTR_GET_function(self) (SHIFTR((self)->word, 0, 6))
#define RAB_INSTR_GET_cop0d(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_GET_instr_index(self) (SHIFTR((self)->word, 0, 26))
#define RAB_INSTR_GET_immediate(self) (SHIFTR((self)->word, 0, 16))
#define RAB_INSTR_GET_fs(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_GET_ft(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_GET_fd(self) (SHIFTR((self)->word, 6, 5))
#define RAB_INSTR_GET_cop1cs(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_GET_op(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_GET_code(self) (SHIFTR((self)->word, 6, 20))
#define RAB_INSTR_GET_code_upper(self) (SHIFTR((self)->word, 16, 10))
#define RAB_INSTR_GET_code_lower(self) (SHIFTR((self)->word, 6, 10))
#define RAB_INSTR_GET_copraw(self) (SHIFTR((self)->word, 0, 25))
#define RAB_INSTR_GET_fmt(self) (SHIFTR((self)->word, 21, 5))
#define RAB_INSTR_GET_fc(self) (SHIFTR((self)->word, 4, 2))
#define RAB_INSTR_GET_cond(self) (SHIFTR((self)->word, 0, 4))
#define RAB_INSTR_GET_cop2t(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_GET_tf(self) (SHIFTR((self)->word, 16, 1))
#define RAB_INSTR_GET_nd(self) (SHIFTR((self)->word, 17, 1))
#define RAB_INSTR_GET_bc_fmt(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_GET_stype(self) (SHIFTR((self)->word, 6, 5))
#define RAB_INSTR_PACK_opcode(word, value) (BITREPACK_RIGHT((word), (value), 26, 6))
#define RAB_INSTR_PACK_rs(word, value) (BITREPACK((word), (value), 21, 5))
#define RAB_INSTR_PACK_rt(word, value) (BITREPACK((word), (value), 16, 5))
#define RAB_INSTR_PACK_rd(word, value) (BITREPACK((word), (value), 11, 5))
#define RAB_INSTR_PACK_sa(word, value) (BITREPACK((word), (value), 6, 5))
#define RAB_INSTR_PACK_function(word, value) (BITREPACK((word), (value), 0, 6))
#define RAB_INSTR_PACK_cop0d(word, value) (BITREPACK((word), (value), 11, 5))
#define RAB_INSTR_PACK_instr_index(word, value) (BITREPACK((word), (value), 0, 26))
#define RAB_INSTR_PACK_immediate(word, value) (BITREPACK((word), (value), 0, 16))
#define RAB_INSTR_PACK_code(word, value) (BITREPACK((word), (value), 6, 20))
#define RAB_INSTR_PACK_code_upper(word, value) (BITREPACK((word), (value), 16, 10))
#define RAB_INSTR_PACK_code_lower(word, value) (BITREPACK((word), (value), 6, 10))
#define RAB_INSTR_PACK_copraw(word, value) (BITREPACK((word), (value), 0, 25))
#define RAB_INSTR_PACK_fmt(word, value) (BITREPACK((word), (value), 21, 5))
#define RAB_INSTR_PACK_fc(word, value) (BITREPACK((word), (value), 4, 2))
#define RAB_INSTR_PACK_cond(word, value) (BITREPACK((word), (value), 0, 4))
#define RAB_INSTR_PACK_fs(word, value) (BITREPACK((word), (value), 11, 5))
#define RAB_INSTR_PACK_ft(word, value) (BITREPACK((word), (value), 16, 5))
#define RAB_INSTR_PACK_fd(word, value) (BITREPACK((word), (value), 6, 5))
#define RAB_INSTR_PACK_cop1cs(word, value) (BITREPACK((word), (value), 11, 5))
#define RAB_INSTR_PACK_op(word, value) (BITREPACK((word), (value), 16, 5))
#define RAB_INSTR_PACK_cop2t(word, value) (BITREPACK((word), (value), 16, 5))
#define RAB_INSTR_PACK_tf(word, value) (BITREPACK((word), (value), 16, 1))
#define RAB_INSTR_PACK_nd(word, value) (BITREPACK((word), (value), 17, 1))
#define RAB_INSTR_PACK_bc_fmt(word, value) (BITREPACK((word), (value), 16, 5))
#define RAB_INSTR_PACK_stype(word, value) (BITREPACK((word), (value), 6, 5))
NON_NULL(1)
void RabbitizerInstruction_init(RabbitizerInstruction *self, uint32_t word, uint32_t vram);
NON_NULL(1)
void RabbitizerInstruction_destroy(RabbitizerInstruction* self);
/* Process uniqueId */
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Normal(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Special(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Regimm(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor0_BC0(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor0_Tlb(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor0(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor1_BC1(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor1_FpuS(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor1_FpuD(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor1_FpuW(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor1_FpuL(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor1(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId_Coprocessor2(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstruction_processUniqueId(RabbitizerInstruction *self);
/* Process uniqueId */
/* General getters */
NODISCARD NON_NULL(1) PURE
uint32_t RabbitizerInstruction_getRaw(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
uint32_t RabbitizerInstruction_getImmediate(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
int32_t RabbitizerInstruction_getProcessedImmediate(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
uint32_t RabbitizerInstruction_getInstrIndex(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
uint32_t RabbitizerInstruction_getInstrIndexAsVram(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
int32_t RabbitizerInstruction_getBranchOffset(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
int32_t RabbitizerInstruction_getGenericBranchOffset(const RabbitizerInstruction *self, uint32_t currentVram);
/* General getters */
NON_NULL(1)
void RabbitizerInstruction_blankOut(RabbitizerInstruction *self);
/* Instruction examination */
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isImplemented(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isLikelyHandwritten(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isNop(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isUnconditionalBranch(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isJrRa(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isJrNotRa(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_hasDelaySlot(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
const char *RabbitizerInstruction_mapInstrToType(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1, 2) PURE
bool RabbitizerInstruction_sameOpcode(const RabbitizerInstruction *self, const RabbitizerInstruction *other);
NODISCARD NON_NULL(1, 2) PURE
bool RabbitizerInstruction_sameOpcodeButDifferentArguments(const RabbitizerInstruction *self, const RabbitizerInstruction *other);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_hasOperand(const RabbitizerInstruction *self, RabbitizerOperandType operand);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_hasOperandAlias(const RabbitizerInstruction *self, RabbitizerOperandType operand);
NODISCARD NON_NULL(1) PURE
uint32_t RabbitizerInstruction_getValidBits(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_isValid(const RabbitizerInstruction *self);
/* Instruction examination */
/* Disassembly */
NODISCARD NON_NULL(1) PURE
bool RabbitizerInstruction_mustDisasmAsData(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
size_t RabbitizerInstruction_getSizeForBufferOperandsDisasm(const RabbitizerInstruction *self, size_t immOverrideLength);
NON_NULL(1, 2)
size_t RabbitizerInstruction_disassembleOperands(const RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
NODISCARD NON_NULL(1) PURE
size_t RabbitizerInstruction_getSizeForBufferInstrDisasm(const RabbitizerInstruction *self, size_t immOverrideLength, int extraLJust);
NON_NULL(1, 2)
size_t RabbitizerInstruction_disassembleInstruction(const RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength, int extraLJust);
NODISCARD NON_NULL(1) PURE
size_t RabbitizerInstruction_getSizeForBufferDataDisasm(const RabbitizerInstruction *self, int extraLJust);
NON_NULL(1, 2)
size_t RabbitizerInstruction_disassembleAsData(const RabbitizerInstruction *self, char *dst, int extraLJust);
NODISCARD NON_NULL(1) PURE
size_t RabbitizerInstruction_getSizeForBuffer(const RabbitizerInstruction *self, size_t immOverrideLength, int extraLJust);
NON_NULL(1, 2)
size_t RabbitizerInstruction_disassemble(const RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength, int extraLJust);
/* Disassembly */
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,87 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRUCTION_R5900_H
#define RABBITIZER_INSTRUCTION_R5900_H
#pragma once
#include "RabbitizerInstruction.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RAB_INSTR_R5900_GET_mmi_function(self) (SHIFTR((self)->word, 6, 5))
#define RAB_INSTR_R5900_GET_fhi_flo(self) ((SHIFTR((self)->word, 6, 5) << 2) | SHIFTR((self)->word, 0, 2))
#define RAB_INSTR_R5900_GET_vfs(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_R5900_GET_vft(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_R5900_GET_vfd(self) (SHIFTR((self)->word, 6, 5))
#define RAB_INSTR_R5900_GET_xyzw_x(self) (SHIFTR((self)->word, 24, 1))
#define RAB_INSTR_R5900_GET_xyzw_y(self) (SHIFTR((self)->word, 23, 1))
#define RAB_INSTR_R5900_GET_xyzw_z(self) (SHIFTR((self)->word, 22, 1))
#define RAB_INSTR_R5900_GET_xyzw_w(self) (SHIFTR((self)->word, 21, 1))
#define RAB_INSTR_R5900_GET_n(self) (SHIFTR((self)->word, 0, 2))
#define RAB_INSTR_R5900_GET_l(self) (SHIFTR((self)->word, 21, 2))
#define RAB_INSTR_R5900_GET_m(self) (SHIFTR((self)->word, 23, 2))
#define RAB_INSTR_R5900_GET_vis(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_R5900_GET_vit(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_R5900_GET_vid(self) (SHIFTR((self)->word, 6, 5))
#define RAB_INSTR_R5900_GET_imm5(self) (SHIFTR((self)->word, 6, 5))
#define RAB_INSTR_R5900_PACK_mmi_function(word, value) (BITREPACK((word), (value), 6, 5))
#define RAB_INSTR_R5900_PACK_fhi_flo(word, value) (BITREPACK(BITREPACK((word), (value) >> 2, 6, 5), (value), 0, 2))
#define RAB_INSTR_R5900_PACK_vfs(word, value) (BITREPACK((word), (value), 11, 5))
#define RAB_INSTR_R5900_PACK_vft(word, value) (BITREPACK((word), (value), 16, 5))
#define RAB_INSTR_R5900_PACK_vfd(word, value) (BITREPACK((word), (value), 6, 5))
#define RAB_INSTR_R5900_PACK_xyzw_x(word, value) (BITREPACK((word), (value), 24, 1))
#define RAB_INSTR_R5900_PACK_xyzw_y(word, value) (BITREPACK((word), (value), 23, 1))
#define RAB_INSTR_R5900_PACK_xyzw_z(word, value) (BITREPACK((word), (value), 22, 1))
#define RAB_INSTR_R5900_PACK_xyzw_w(word, value) (BITREPACK((word), (value), 21, 1))
#define RAB_INSTR_R5900_PACK_n(word, value) (BITREPACK((word), (value), 0, 2))
#define RAB_INSTR_R5900_PACK_l(word, value) (BITREPACK((word), (value), 21, 2))
#define RAB_INSTR_R5900_PACK_m(word, value) (BITREPACK((word), (value), 23, 2))
#define RAB_INSTR_R5900_PACK_vis(word, value) (BITREPACK((word), (value), 11, 5))
#define RAB_INSTR_R5900_PACK_vit(word, value) (BITREPACK((word), (value), 16, 5))
#define RAB_INSTR_R5900_PACK_vid(word, value) (BITREPACK((word), (value), 6, 5))
#define RAB_INSTR_R5900_PACK_imm5(word, value) (BITREPACK((word), (value), 6, 5))
NON_NULL(1)
void RabbitizerInstructionR5900_init(RabbitizerInstruction *self, uint32_t word, uint32_t vram);
NON_NULL(1)
void RabbitizerInstructionR5900_destroy(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR5900_processUniqueId_Normal(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR5900_processUniqueId_Special(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR5900_processUniqueId_Regimm(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR5900_processUniqueId_Coprocessor0(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR5900_processUniqueId_Coprocessor1(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR5900_processUniqueId_Coprocessor2(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR5900_processUniqueId_MMI(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR5900_processUniqueId(RabbitizerInstruction *self);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,70 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRUCTION_RSP_H
#define RABBITIZER_INSTRUCTION_RSP_H
#pragma once
#include "RabbitizerInstruction.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RAB_INSTR_RSP_GET_cop2t(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_RSP_GET_cop2cd(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_RSP_GET_vs(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_RSP_GET_vt(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_RSP_GET_vd(self) (SHIFTR((self)->word, 6, 5))
#define RAB_INSTR_RSP_GET_elementhigh(self) (SHIFTR((self)->word, 21, 4))
#define RAB_INSTR_RSP_GET_elementlow(self) (SHIFTR((self)->word, 7, 4))
#define RAB_INSTR_RSP_GET_OFFSET_VECTOR_RAW(self) (SHIFTR((self)->word, 0, 7))
#define RAB_INSTR_RSP_GET_index(self) (SHIFTR((self)->word, 7, 4))
#define RAB_INSTR_RSP_GET_de(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_RSP_PACK_cop2t(word, value) (BITREPACK((word), value, 16, 5))
#define RAB_INSTR_RSP_PACK_cop2cd(word, value) (BITREPACK((word), value, 11, 5))
#define RAB_INSTR_RSP_PACK_vs(word, value) (BITREPACK((word), value, 11, 5))
#define RAB_INSTR_RSP_PACK_vt(word, value) (BITREPACK((word), value, 16, 5))
#define RAB_INSTR_RSP_PACK_vd(word, value) (BITREPACK((word), value, 6, 5))
#define RAB_INSTR_RSP_PACK_elementhigh(word, value) (BITREPACK((word), value, 21, 4))
#define RAB_INSTR_RSP_PACK_elementlow(word, value) (BITREPACK((word), value, 7, 4))
#define RAB_INSTR_RSP_PACK_index(word, value) (BITREPACK((word), value, 7, 4))
#define RAB_INSTR_RSP_PACK_offset(word, value) (BITREPACK((word), value, 0, 7))
#define RAB_INSTR_RSP_PACK_de(word, value) (BITREPACK((word), value, 11, 5))
NON_NULL(1)
void RabbitizerInstructionRsp_init(RabbitizerInstruction *self, uint32_t word, uint32_t vram);
NON_NULL(1)
void RabbitizerInstructionRsp_destroy(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionRsp_processUniqueId_Normal(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionRsp_processUniqueId_Special(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionRsp_processUniqueId_Regimm(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionRsp_processUniqueId(RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
uint16_t RabbitizerInstructionRsp_GetOffsetVector(const RabbitizerInstruction *self);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,33 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_OPERAND_TYPE_H
#define RABBITIZER_OPERAND_TYPE_H
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define RAB_DEF_OPERAND(prefix, operand) \
RAB_OPERAND_##prefix##_##operand,
typedef enum RabbitizerOperandType {
RAB_DEF_OPERAND(ALL, INVALID)
#include "operands/RabbitizerOperandType_cpu.inc"
#include "operands/RabbitizerOperandType_rsp.inc"
#include "operands/RabbitizerOperandType_r5900.inc"
RAB_DEF_OPERAND(ALL, MAX)
} RabbitizerOperandType;
#undef RAB_DEF_OPERAND
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,143 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_REGISTER_H
#define RABBITIZER_REGISTER_H
#pragma once
#include <stdint.h>
#include "common/Utils.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RABBITIZER_DEF_REG(prefix, name, numeric) \
RABBITIZER_REG_##prefix##_##name
#define RABBITIZER_DEF_REG_NODOLLAR(prefix, name, numeric) \
RABBITIZER_REG_##prefix##_##name
typedef enum RabbitizerRegister_GprO32 {
#include "instructions/registers/RabbitizerRegister_GprO32.inc"
} RabbitizerRegister_GprO32;
typedef enum RabbitizerRegister_GprN32 {
#include "instructions/registers/RabbitizerRegister_GprN32.inc"
} RabbitizerRegister_GprN32;
typedef enum RabbitizerRegister_Cop0 {
#include "instructions/registers/RabbitizerRegister_Cop0.inc"
} RabbitizerRegister_Cop0;
// Float registers
typedef enum RabbitizerRegister_Cop1O32 {
#include "instructions/registers/RabbitizerRegister_Cop1O32.inc"
} RabbitizerRegister_Cop1O32;
typedef enum RabbitizerRegister_Cop1N32 {
#include "instructions/registers/RabbitizerRegister_Cop1N32.inc"
} RabbitizerRegister_Cop1N32;
typedef enum RabbitizerRegister_Cop1N64 {
#include "instructions/registers/RabbitizerRegister_Cop1N64.inc"
} RabbitizerRegister_Cop1N64;
typedef enum RabbitizerRegister_Cop1Control {
#include "instructions/registers/RabbitizerRegister_Cop1Control.inc"
} RabbitizerRegister_Cop1Control;
typedef enum RabbitizerRegister_Cop2 {
#include "instructions/registers/RabbitizerRegister_Cop2.inc"
} RabbitizerRegister_Cop2;
/* RSP */
typedef enum RabbitizerRegister_RspGpr {
#include "instructions/registers/RabbitizerRegister_RspGpr.inc"
} RabbitizerRegister_RspGpr;
typedef enum RabbitizerRegister_RspCop0 {
#include "instructions/registers/RabbitizerRegister_RspCop0.inc"
} RabbitizerRegister_RspCop0;
typedef enum RabbitizerRegister_RspCop2 {
#include "instructions/registers/RabbitizerRegister_RspCop2.inc"
} RabbitizerRegister_RspCop2;
typedef enum RabbitizerRegister_RspCop2Control {
#include "instructions/registers/RabbitizerRegister_RspCop2Control.inc"
} RabbitizerRegister_RspCop2Control;
typedef enum RabbitizerRegister_RspVector {
#include "instructions/registers/RabbitizerRegister_RspVector.inc"
} RabbitizerRegister_RspVector;
/* RSP */
/* R5900 */
typedef enum RabbitizerRegister_R5900VF {
#include "instructions/registers/RabbitizerRegister_R5900VF.inc"
} RabbitizerRegister_R5900VF;
typedef enum RabbitizerRegister_R5900VI {
#include "instructions/registers/RabbitizerRegister_R5900VI.inc"
} RabbitizerRegister_R5900VI;
/* R5900 */
#undef RABBITIZER_DEF_REG
#undef RABBITIZER_DEF_REG_NODOLLAR
extern const char *RabbitizerRegister_GprO32_Names[][2];
extern const char *RabbitizerRegister_GprN32_Names[][2];
extern const char *RabbitizerRegister_Cop0_Names[][2];
extern const char *RabbitizerRegister_Cop1O32_Names[][2];
extern const char *RabbitizerRegister_Cop1N32_Names[][2];
extern const char *RabbitizerRegister_Cop1N64_Names[][2];
extern const char *RabbitizerRegister_Cop2_Names[][2];
extern const char *RabbitizerRegister_RspGpr_Names[][2];
extern const char *RabbitizerRegister_RspCop0_Names[][2];
extern const char *RabbitizerRegister_RspVector_Names[][2];
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameGpr(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameCop0(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameCop1(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameCop1Control(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameCop2(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameRspGpr(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameRspCop0(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameRspCop2(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameRspCop2Control(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameRspVector(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameR5900VF(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameR5900VI(uint8_t regValue);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,40 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_INSTR_ID(cpu, , INVALID, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate})
#include "instructions/instr_id/cpu/cpu_normal.inc"
#include "instructions/instr_id/cpu/cpu_special.inc"
#include "instructions/instr_id/cpu/cpu_regimm.inc"
#include "instructions/instr_id/cpu/cpu_cop0.inc"
#include "instructions/instr_id/cpu/cpu_cop0_bc0.inc"
#include "instructions/instr_id/cpu/cpu_cop0_tlb.inc"
#include "instructions/instr_id/cpu/cpu_cop1.inc"
#include "instructions/instr_id/cpu/cpu_cop1_bc1.inc"
#include "instructions/instr_id/cpu/cpu_cop1_fpu_s.inc"
#include "instructions/instr_id/cpu/cpu_cop1_fpu_d.inc"
#include "instructions/instr_id/cpu/cpu_cop1_fpu_w.inc"
#include "instructions/instr_id/cpu/cpu_cop1_fpu_l.inc"
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_00, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_01, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_02, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_03, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_04, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_05, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_06, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_07, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_08, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_09, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_10, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_11, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_12, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_13, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_14, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_15, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_16, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_17, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_18, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , USERDEF_19, .operands={0})
RABBITIZER_DEF_INSTR_ID(cpu, , MAX, .operands={0})
@@ -0,0 +1,46 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_INSTR_ID(r5900, , INVALID, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .architectureVersion=-1)
#include "instructions/instr_id/r5900/r5900_normal.inc"
#include "instructions/instr_id/r5900/r5900_special.inc"
#include "instructions/instr_id/r5900/r5900_regimm.inc"
#include "instructions/instr_id/r5900/r5900_mmi.inc"
#include "instructions/instr_id/r5900/r5900_mmi_0.inc"
#include "instructions/instr_id/r5900/r5900_mmi_1.inc"
#include "instructions/instr_id/r5900/r5900_mmi_2.inc"
#include "instructions/instr_id/r5900/r5900_mmi_3.inc"
#include "instructions/instr_id/r5900/r5900_cop0_tlb.inc"
#include "instructions/instr_id/r5900/r5900_cop1_fpu_s.inc"
#include "instructions/instr_id/r5900/r5900_cop2.inc"
#include "instructions/instr_id/r5900/r5900_cop2_bc2.inc"
#include "instructions/instr_id/r5900/r5900_cop2_special1.inc"
#include "instructions/instr_id/r5900/r5900_cop2_special2.inc"
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_00, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_01, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_02, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_03, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_04, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_05, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_06, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_07, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_08, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_09, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_10, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_11, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_12, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_13, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_14, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_15, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_16, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_17, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_18, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , USERDEF_19, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, , MAX, .operands={0})
@@ -0,0 +1,41 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// RSP instructions
RABBITIZER_DEF_INSTR_ID(rsp, , INVALID, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
#include "instructions/instr_id/rsp/rsp_cop2.inc"
#include "instructions/instr_id/rsp/rsp_cop2_vu.inc"
#include "instructions/instr_id/rsp/rsp_normal_lwc2.inc"
#include "instructions/instr_id/rsp/rsp_normal_swc2.inc"
// CPU instructions but with rsp registers
#include "instructions/instr_id/rsp/rsp_normal.inc"
#include "instructions/instr_id/rsp/rsp_special.inc"
#include "instructions/instr_id/rsp/rsp_regimm.inc"
#include "instructions/instr_id/rsp/rsp_cop0.inc"
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_00, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_01, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_02, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_03, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_04, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_05, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_06, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_07, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_08, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_09, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_10, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_11, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_12, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_13, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_14, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_15, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_16, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_17, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_18, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , USERDEF_19, .operands={0})
RABBITIZER_DEF_INSTR_ID(rsp, , MAX, .operands={0})
@@ -0,0 +1,10 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP rt, cop0d
RABBITIZER_DEF_INSTR_ID(cpu, 0x00, mfc0, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_cop0d}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .modifiesRt=true, .notEmitedByCompilers=true) // Move word From CP0
RABBITIZER_DEF_INSTR_ID(cpu, 0x01, dmfc0, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_cop0d}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .modifiesRt=true) // Doubleword Move From CP0
RABBITIZER_DEF_INSTR_ID(cpu, 0x02, cfc0, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_cop0d}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .modifiesRt=true) // Move control word From CP0
RABBITIZER_DEF_INSTR_ID(cpu, 0x04, mtc0, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_cop0d}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .notEmitedByCompilers=true) // Move word to CP0
RABBITIZER_DEF_INSTR_ID(cpu, 0x05, dmtc0, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_cop0d}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN) // Doubleword Move To CP0
RABBITIZER_DEF_INSTR_ID(cpu, 0x06, ctc0, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_cop0d}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN) // Move control word To CP0
@@ -0,0 +1,8 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP IMM
RABBITIZER_DEF_INSTR_ID(cpu, 0x00, bc0f, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isBranch=true) // Branch on FP False
RABBITIZER_DEF_INSTR_ID(cpu, 0x01, bc0t, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isBranch=true) // Branch on FP True
RABBITIZER_DEF_INSTR_ID(cpu, 0x02, bc0fl, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isBranch=true, .isBranchLikely=true) // Branch on FP False Likely
RABBITIZER_DEF_INSTR_ID(cpu, 0x03, bc0tl, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isBranch=true, .isBranchLikely=true) // Branch on FP True Likely
@@ -0,0 +1,12 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP
RABBITIZER_DEF_INSTR_ID(cpu, 0x01, tlbr, .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .notEmitedByCompilers=true) // Read Indexed TLB Entry
RABBITIZER_DEF_INSTR_ID(cpu, 0x02, tlbwi, .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .notEmitedByCompilers=true) // Write Indexed TLB Entry
RABBITIZER_DEF_INSTR_ID(cpu, 0x06, tlbwr, .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN) // Write Random TLB Entry
RABBITIZER_DEF_INSTR_ID(cpu, 0x08, tlbp, .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .notEmitedByCompilers=true) // Probe TLB for Matching Entry
RABBITIZER_DEF_INSTR_ID(cpu, 0x18, eret, .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .notEmitedByCompilers=true) // Return from Exception
@@ -0,0 +1,12 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP rt, fs
RABBITIZER_DEF_INSTR_ID(cpu, 0x00, mfc1, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true, .modifiesRt=true) // Move Word From Floating-Point
RABBITIZER_DEF_INSTR_ID(cpu, 0x01, dmfc1, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true, .modifiesRt=true) // Doubleword Move From Floating-Point
RABBITIZER_DEF_INSTR_ID(cpu, 0x04, mtc1, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Move Word to Floating-Point
RABBITIZER_DEF_INSTR_ID(cpu, 0x05, dmtc1, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Doubleword Move To Floating-Point
// OP rt, cop1cs
RABBITIZER_DEF_INSTR_ID(cpu, 0x02, cfc1, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_cop1cs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true, .modifiesRt=true) // Move Control Word from Floating-Point
RABBITIZER_DEF_INSTR_ID(cpu, 0x06, ctc1, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_cop1cs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Move Control Word to Floating-Point
@@ -0,0 +1,8 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP IMM
RABBITIZER_DEF_INSTR_ID(cpu, 0x00, bc1f, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isBranch=true)
RABBITIZER_DEF_INSTR_ID(cpu, 0x01, bc1t, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isBranch=true)
RABBITIZER_DEF_INSTR_ID(cpu, 0x02, bc1fl, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isBranch=true, .isBranchLikely=true)
RABBITIZER_DEF_INSTR_ID(cpu, 0x03, bc1tl, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isBranch=true, .isBranchLikely=true)
@@ -0,0 +1,48 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP fd, fs, ft
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x00, add_d, add.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Add
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x01, sub_d, sub.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Sub
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x02, mul_d, mul.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Multiply
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x03, div_d, div.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Divide
// OP fd, fs
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x04, sqrt_d, sqrt.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Square Root
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x05, abs_d, abs.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Absolute Value
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x06, mov_d, mov.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Move
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x07, neg_d, neg.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Negate
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x08, round_l_d, round.l.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Round to Long Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x09, trunc_l_d, trunc.l.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Truncate to Long Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0A, ceil_l_d, ceil.l.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Ceiling Convert to Long Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0B, floor_l_d, floor.l.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Floor Convert to Long Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0C, round_w_d, round.w.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Round to Word Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0D, trunc_w_d, trunc.w.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Truncate to Word Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0E, ceil_w_d, ceil.w.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Ceiling Convert to Word Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0F, floor_w_d, floor.w.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Floor Convert to Word Fixed-Point
// OP fd, fs
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x20, cvt_s_d, cvt.s.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true, .isDouble=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x24, cvt_w_d, cvt.w.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true, .isDouble=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x25, cvt_l_d, cvt.l.d, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true, .isDouble=true)
// OP fs, ft
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x30, c_f_d, c.f.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x31, c_un_d, c.un.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x32, c_eq_d, c.eq.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x33, c_ueq_d, c.ueq.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x34, c_olt_d, c.olt.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x35, c_ult_d, c.ult.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x36, c_ole_d, c.ole.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x37, c_ule_d, c.ule.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x38, c_df_d, c.df.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x39, c_ngle_d, c.ngle.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3A, c_deq_d, c.deq.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3B, c_ngl_d, c.ngl.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3C, c_lt_d, c.lt.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3D, c_nge_d, c.nge.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3E, c_le_d, c.le.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3F, c_ngt_d, c.ngt.d, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
@@ -0,0 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP fd, fs
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x20, cvt_s_l, cvt.s.l, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x21, cvt_d_l, cvt.d.l, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true, .isDouble=true)
@@ -0,0 +1,48 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP fd, fs, ft
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x00, add_s, add.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Add
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x01, sub_s, sub.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Sub
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x02, mul_s, mul.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Multiply
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x03, div_s, div.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Divide
// OP fd, fs
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x04, sqrt_s, sqrt.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Square Root
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x05, abs_s, abs.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Absolute Value
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x06, mov_s, mov.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Move
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x07, neg_s, neg.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Negate
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x08, round_l_s, round.l.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Round to Long Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x09, trunc_l_s, trunc.l.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Truncate to Long Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0A, ceil_l_s, ceil.l.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Ceiling Convert to Long Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0B, floor_l_s, floor.l.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Floor Convert to Long Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0C, round_w_s, round.w.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Round to Word Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0D, trunc_w_s, trunc.w.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Truncate to Word Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0E, ceil_w_s, ceil.w.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Ceiling Convert to Word Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x0F, floor_w_s, floor.w.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true) // Floating-Point Floor Convert to Word Fixed-Point
// OP fd, fs
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x21, cvt_d_s, cvt.d.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true, .isDouble=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x24, cvt_w_s, cvt.w.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x25, cvt_l_s, cvt.l.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
// OP fs, ft
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x30, c_f_s, c.f.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x31, c_un_s, c.un.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x32, c_eq_s, c.eq.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x33, c_ueq_s, c.ueq.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x34, c_olt_s, c.olt.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x35, c_ult_s, c.ult.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x36, c_ole_s, c.ole.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x37, c_ule_s, c.ule.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x38, c_sf_s, c.sf.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x39, c_ngle_s, c.ngle.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3A, c_seq_s, c.seq.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3B, c_ngl_s, c.ngl.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3C, c_lt_s, c.lt.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3D, c_nge_s, c.nge.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3E, c_le_s, c.le.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x3F, c_ngt_s, c.ngt.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
@@ -0,0 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP fd, fs
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x20, cvt_s_w, cvt.s.w, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, 0x21, cvt_d_w, cvt.d.w, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .isFloat=true, .isDouble=true)
@@ -0,0 +1,83 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP LABEL
RABBITIZER_DEF_INSTR_ID(cpu, 0x02, j, .operands={RAB_OPERAND_cpu_label}, .instrType=RABBITIZER_INSTR_TYPE_J, .isJump=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Jump
RABBITIZER_DEF_INSTR_ID(cpu, 0x03, jal, .operands={RAB_OPERAND_cpu_label}, .instrType=RABBITIZER_INSTR_TYPE_J, .isJump=true, .doesLink=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Jump And Link
// OP rs, rt, IMM
RABBITIZER_DEF_INSTR_ID(cpu, 0x04, beq, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch on EQual
RABBITIZER_DEF_INSTR_ID(cpu, 0x05, bne, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch on Not Equal
RABBITIZER_DEF_INSTR_ID(cpu, 0x14, beql, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .isBranchLikely=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Branch on EQual Likely
RABBITIZER_DEF_INSTR_ID(cpu, 0x15, bnel, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .isBranchLikely=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Branch on Not Equal Likely
// OP rs, IMM
RABBITIZER_DEF_INSTR_ID(cpu, 0x06, blez, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch on Less than or Equal to Zero
RABBITIZER_DEF_INSTR_ID(cpu, 0x16, blezl, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .isBranchLikely=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Branch on Less than or Equal to Zero Likely
RABBITIZER_DEF_INSTR_ID(cpu, 0x07, bgtz, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch on Greater Than Zero
RABBITIZER_DEF_INSTR_ID(cpu, 0x17, bgtzl, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .isBranchLikely=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Branch on Greater Than Zero Likely
// OP rt, rs, IMM
RABBITIZER_DEF_INSTR_ID(cpu, 0x08, addi, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .notEmitedByCompilers=true, .canBeLo=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Add Immediate
RABBITIZER_DEF_INSTR_ID(cpu, 0x09, addiu, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Add Immediate Unsigned Word
RABBITIZER_DEF_INSTR_ID(cpu, 0x0A, slti, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Set on Less Than Immediate
RABBITIZER_DEF_INSTR_ID(cpu, 0x0B, sltiu, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Set on Less Than Immediate Unsigned
RABBITIZER_DEF_INSTR_ID(cpu, 0x0C, andi, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .isUnsigned=true, .modifiesRt=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // And Immediate
RABBITIZER_DEF_INSTR_ID(cpu, 0x0D, ori, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .isUnsigned=true, .modifiesRt=true, .canBeLo=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Or Immediate
RABBITIZER_DEF_INSTR_ID(cpu, 0x0E, xori, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .isUnsigned=true, .modifiesRt=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // eXclusive OR Immediate
RABBITIZER_DEF_INSTR_ID(cpu, 0x18, daddi, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword add Immediate
RABBITIZER_DEF_INSTR_ID(cpu, 0x19, daddiu, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword add Immediate Unsigned
// OP rt, IMM
RABBITIZER_DEF_INSTR_ID(cpu, 0x0F, lui, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .isUnsigned=true, .modifiesRt=true, .canBeHi=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Upper Immediate
// OP rt, IMM(base)
RABBITIZER_DEF_INSTR_ID(cpu, 0x1A, ldl, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Load Doubleword Left
RABBITIZER_DEF_INSTR_ID(cpu, 0x1B, ldr, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Load Doubleword Right
RABBITIZER_DEF_INSTR_ID(cpu, 0x20, lb, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Byte
RABBITIZER_DEF_INSTR_ID(cpu, 0x21, lh, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Halfword
RABBITIZER_DEF_INSTR_ID(cpu, 0x22, lwl, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Word Left
RABBITIZER_DEF_INSTR_ID(cpu, 0x23, lw, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Word
RABBITIZER_DEF_INSTR_ID(cpu, 0x24, lbu, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Byte Insigned
RABBITIZER_DEF_INSTR_ID(cpu, 0x25, lhu, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Halfword Unsigned
RABBITIZER_DEF_INSTR_ID(cpu, 0x26, lwr, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Word Right
RABBITIZER_DEF_INSTR_ID(cpu, 0x27, lwu, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Load Word Unsigned
RABBITIZER_DEF_INSTR_ID(cpu, 0x28, sb, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Byte
RABBITIZER_DEF_INSTR_ID(cpu, 0x29, sh, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Halfword
RABBITIZER_DEF_INSTR_ID(cpu, 0x2A, swl, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Word Left
RABBITIZER_DEF_INSTR_ID(cpu, 0x2B, sw, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Word
RABBITIZER_DEF_INSTR_ID(cpu, 0x2C, sdl, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Store Doubleword Left
RABBITIZER_DEF_INSTR_ID(cpu, 0x2D, sdr, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Store Doubleword Right
RABBITIZER_DEF_INSTR_ID(cpu, 0x2E, swr, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Word Right
RABBITIZER_DEF_INSTR_ID(cpu, 0x30, ll, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Load Linked word
RABBITIZER_DEF_INSTR_ID(cpu, 0x33, pref, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_IV) // Prefetch
RABBITIZER_DEF_INSTR_ID(cpu, 0x34, lld, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Load Linked Doubleword
RABBITIZER_DEF_INSTR_ID(cpu, 0x37, ld, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Load Doubleword
RABBITIZER_DEF_INSTR_ID(cpu, 0x38, sc, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Store Conditional word
RABBITIZER_DEF_INSTR_ID(cpu, 0x3C, scd, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Store Conditional Doubleword
RABBITIZER_DEF_INSTR_ID(cpu, 0x3F, sd, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Store Doubleword
// OP op, IMM(base)
RABBITIZER_DEF_INSTR_ID(cpu, 0x2F, cache, .operands={RAB_OPERAND_cpu_op, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .notEmitedByCompilers=true) // Cache
// OP ft, IMM(base)
RABBITIZER_DEF_INSTR_ID(cpu, 0x31, lwc1, .operands={RAB_OPERAND_cpu_ft, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .isFloat=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Word to Coprocessor z
RABBITIZER_DEF_INSTR_ID(cpu, 0x35, ldc1, .operands={RAB_OPERAND_cpu_ft, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .isFloat=true, .isDouble=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Load Doubleword to Coprocessor z
RABBITIZER_DEF_INSTR_ID(cpu, 0x39, swc1, .operands={RAB_OPERAND_cpu_ft, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .isFloat=true, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Word from Coprocessor z
RABBITIZER_DEF_INSTR_ID(cpu, 0x3D, sdc1, .operands={RAB_OPERAND_cpu_ft, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .isFloat=true, .isDouble=true, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Store Doubleword from Coprocessor z
// OP cop2t, IMM(base)
RABBITIZER_DEF_INSTR_ID(cpu, 0x32, lwc2, .operands={RAB_OPERAND_cpu_cop2t, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Word to Coprocessor z
RABBITIZER_DEF_INSTR_ID(cpu, 0x36, ldc2, .operands={RAB_OPERAND_cpu_cop2t, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Load Doubleword to Coprocessor z
RABBITIZER_DEF_INSTR_ID(cpu, 0x3A, swc2, .operands={RAB_OPERAND_cpu_cop2t, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Word from Coprocessor z
RABBITIZER_DEF_INSTR_ID(cpu, 0x3E, sdc2, .operands={RAB_OPERAND_cpu_cop2t, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Store Doubleword from Coprocessor z
// Pseudo-Instruction Unique IDs
// OP IMM
RABBITIZER_DEF_INSTR_ID(cpu, -0x03, b, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .isPseudo=true) // Branch (unconditional)
// OP rs, IMM
RABBITIZER_DEF_INSTR_ID(cpu, -0x04, beqz, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .isPseudo=true) // Branch on EQual Zero
RABBITIZER_DEF_INSTR_ID(cpu, -0x05, bnez, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_I, .isBranch=true, .isPseudo=true) // Branch on Not Equal Zero
@@ -0,0 +1,25 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP rs, IMM
RABBITIZER_DEF_INSTR_ID(cpu, 0x00, bltz, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch on Less Than Zero
RABBITIZER_DEF_INSTR_ID(cpu, 0x01, bgez, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch on Greater than or Equal to Zero
RABBITIZER_DEF_INSTR_ID(cpu, 0x02, bltzl, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .isBranchLikely=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Branch on Less Than Zero Likely
RABBITIZER_DEF_INSTR_ID(cpu, 0x03, bgezl, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .isBranchLikely=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Branch on Greater than or Equal to Zero Likely
RABBITIZER_DEF_INSTR_ID(cpu, 0x08, tgei, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II)
RABBITIZER_DEF_INSTR_ID(cpu, 0x09, tgeiu, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II)
RABBITIZER_DEF_INSTR_ID(cpu, 0x0A, tlti, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II)
RABBITIZER_DEF_INSTR_ID(cpu, 0x0B, tltiu, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II)
RABBITIZER_DEF_INSTR_ID(cpu, 0x0C, teqi, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II)
RABBITIZER_DEF_INSTR_ID(cpu, 0x0E, tnei, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II)
RABBITIZER_DEF_INSTR_ID(cpu, 0x10, bltzal, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .doesLink=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch on Less Than Zero and Link
RABBITIZER_DEF_INSTR_ID(cpu, 0x11, bgezal, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .doesLink=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch on Greater Than or Equal to Zero and Link
RABBITIZER_DEF_INSTR_ID(cpu, 0x12, bltzall, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .isBranchLikely=true, .doesLink=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Branch on Less Than Zero and Link Likely
RABBITIZER_DEF_INSTR_ID(cpu, 0x13, bgezall, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .isBranchLikely=true, .doesLink=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Branch on Greater Than or Equal to Zero and Link Likely
// Pseudo-Instruction Unique IDs
RABBITIZER_DEF_INSTR_ID(cpu, -0x11, bal, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .doesLink=true, .isPseudo=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch and Link
@@ -0,0 +1,93 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP rd, rt, sa
RABBITIZER_DEF_INSTR_ID(cpu, 0x00, sll, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Shift word Left Logical
RABBITIZER_DEF_INSTR_ID(cpu, 0x02, srl, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Shift word Right Logical
RABBITIZER_DEF_INSTR_ID(cpu, 0x03, sra, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Shift word Right Arithmetic
RABBITIZER_DEF_INSTR_ID(cpu, 0x38, dsll, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Shift Left Logical
RABBITIZER_DEF_INSTR_ID(cpu, 0x3A, dsrl, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Shift Right Logical
RABBITIZER_DEF_INSTR_ID(cpu, 0x3B, dsra, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Shift Right Arithmetic
RABBITIZER_DEF_INSTR_ID(cpu, 0x3C, dsll32, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Shift Left Logical plus 32
RABBITIZER_DEF_INSTR_ID(cpu, 0x3E, dsrl32, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Shift Right Logical plus 32
RABBITIZER_DEF_INSTR_ID(cpu, 0x3F, dsra32, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Shift Right Arithmetic plus 32
// OP rd, rt, rs
RABBITIZER_DEF_INSTR_ID(cpu, 0x14, dsllv, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Shift Left Logical Variable
RABBITIZER_DEF_INSTR_ID(cpu, 0x16, dsrlv, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Shift Right Logical Variable
RABBITIZER_DEF_INSTR_ID(cpu, 0x17, dsrav, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Shift Right Arithmetic Variable
RABBITIZER_DEF_INSTR_ID(cpu, 0x04, sllv, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Shift word Left Logical Variable
RABBITIZER_DEF_INSTR_ID(cpu, 0x06, srlv, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Shift word Right Logical Variable
RABBITIZER_DEF_INSTR_ID(cpu, 0x07, srav, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Shift word Right Arithmetic Variable
// OP rs
RABBITIZER_DEF_INSTR_ID(cpu, 0x11, mthi, .operands={RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Move To HI register
RABBITIZER_DEF_INSTR_ID(cpu, 0x13, mtlo, .operands={RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Move To LO register
RABBITIZER_DEF_INSTR_ID(cpu, 0x08, jr, .operands={RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .isJump=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Jump Register
RABBITIZER_DEF_INSTR_ID(cpu, 0x09, jalr, .operands={RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .isJump=true, .modifiesRd=true, .doesLink=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Jump And Link Register
// OP rd, rs
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, -0x09, jalr_rd, jalr, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .isJump=true, .modifiesRd=true, .doesLink=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Jump And Link Register // Special case for rd != 31
// OP rd
RABBITIZER_DEF_INSTR_ID(cpu, 0x10, mfhi, .operands={RAB_OPERAND_cpu_rd}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Move From HI register
RABBITIZER_DEF_INSTR_ID(cpu, 0x12, mflo, .operands={RAB_OPERAND_cpu_rd}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Move From LO register
// OP rd, rs, rt
RABBITIZER_DEF_INSTR_ID(cpu, 0x0A, movz, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_IV) // MOVe conditional on Zero
RABBITIZER_DEF_INSTR_ID(cpu, 0x0B, movn, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_IV) // MOVe conditional on Not zero
RABBITIZER_DEF_INSTR_ID(cpu, 0x1A, div, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // DIVide word
RABBITIZER_DEF_INSTR_ID(cpu, 0x1B, divu, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // DIVide Unsigned word
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, -0x1A, sn64_div, div, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // DIVide word
RABBITIZER_DEF_INSTR_ID_ALTNAME(cpu, -0x1B, sn64_divu, divu, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // DIVide Unsigned word
RABBITIZER_DEF_INSTR_ID(cpu, 0x1E, ddiv, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword DIVide
RABBITIZER_DEF_INSTR_ID(cpu, 0x1F, ddivu, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword DIVide Unsigned
// RABBITIZER_DEF_INSTR_ID(cpu, , ddiv, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III)
// RABBITIZER_DEF_INSTR_ID(cpu, , ddivu, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III)
RABBITIZER_DEF_INSTR_ID(cpu, 0x20, add, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .notEmitedByCompilers=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // ADD word
RABBITIZER_DEF_INSTR_ID(cpu, 0x21, addu, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .maybeIsMove=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // ADD Unsigned word
RABBITIZER_DEF_INSTR_ID(cpu, 0x22, sub, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Subtract word
RABBITIZER_DEF_INSTR_ID(cpu, 0x23, subu, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // SUBtract Unsigned word
RABBITIZER_DEF_INSTR_ID(cpu, 0x24, and, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // AND
RABBITIZER_DEF_INSTR_ID(cpu, 0x25, or, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .maybeIsMove=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // OR
RABBITIZER_DEF_INSTR_ID(cpu, 0x26, xor, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // eXclusive OR
RABBITIZER_DEF_INSTR_ID(cpu, 0x27, nor, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Not OR
RABBITIZER_DEF_INSTR_ID(cpu, 0x2A, slt, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Set on Less Than
RABBITIZER_DEF_INSTR_ID(cpu, 0x2B, sltu, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Set on Less Than Unsigned
RABBITIZER_DEF_INSTR_ID(cpu, 0x2C, dadd, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Add
RABBITIZER_DEF_INSTR_ID(cpu, 0x2D, daddu, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .maybeIsMove=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword Add Unsigned
RABBITIZER_DEF_INSTR_ID(cpu, 0x2E, dsub, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword SUBtract
RABBITIZER_DEF_INSTR_ID(cpu, 0x2F, dsubu, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword SUBtract Unsigned
// OP code
RABBITIZER_DEF_INSTR_ID(cpu, 0x0C, syscall, .operands={RAB_OPERAND_cpu_code}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // SYStem CALL
RABBITIZER_DEF_INSTR_ID(cpu, 0x0D, break, .operands={RAB_OPERAND_cpu_code}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Break
RABBITIZER_DEF_INSTR_ID(cpu, 0x0F, sync, .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Sync
// OP rs, rt
RABBITIZER_DEF_INSTR_ID(cpu, 0x18, mult, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // MULTtiply word
RABBITIZER_DEF_INSTR_ID(cpu, 0x19, multu, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // MULTtiply Unsigned word
RABBITIZER_DEF_INSTR_ID(cpu, 0x1C, dmult, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword MULTiply
RABBITIZER_DEF_INSTR_ID(cpu, 0x1D, dmultu, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_III) // Doubleword MULTiply Unsigned
RABBITIZER_DEF_INSTR_ID(cpu, 0x30, tge, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_code_lower}, .instrType=RABBITIZER_INSTR_TYPE_R, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Trap if Greater or Equal
RABBITIZER_DEF_INSTR_ID(cpu, 0x31, tgeu, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_code_lower}, .instrType=RABBITIZER_INSTR_TYPE_R, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Trap if Greater or Equal Unsigned
RABBITIZER_DEF_INSTR_ID(cpu, 0x32, tlt, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_code_lower}, .instrType=RABBITIZER_INSTR_TYPE_R, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Trap if Less Than
RABBITIZER_DEF_INSTR_ID(cpu, 0x33, tltu, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_code_lower}, .instrType=RABBITIZER_INSTR_TYPE_R, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Trap if Less Than Unsigned
RABBITIZER_DEF_INSTR_ID(cpu, 0x34, teq, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_code_lower}, .instrType=RABBITIZER_INSTR_TYPE_R, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Trap if EQual
RABBITIZER_DEF_INSTR_ID(cpu, 0x36, tne, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_code_lower}, .instrType=RABBITIZER_INSTR_TYPE_R, .isTrap=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Trap if Not Equal
// Pseudo-Instruction Unique IDs
// OP
RABBITIZER_DEF_INSTR_ID(cpu, -0x01, nop, .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_R, .isPseudo=true) // No OPeration
// OP rd, rs
RABBITIZER_DEF_INSTR_ID(cpu, -0x25, move, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .maybeIsMove=true, .isPseudo=true) // Move
RABBITIZER_DEF_INSTR_ID(cpu, -0x27, not, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .isPseudo=true) // Not
// OP rd, rt
RABBITIZER_DEF_INSTR_ID(cpu, -0x23, negu, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .isPseudo=true)
@@ -0,0 +1,23 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31--------26-25------21--------------------------------5--------0
| = COP0 | TLB | | fmt |
------6----------5-----------------------------------------------
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
000 | --- | TLBR | TLBWI | --- | --- | --- | TLBWR | --- |
001 | TLBP | --- | --- | --- | --- | --- | --- | --- |
010 | --- | --- | --- | --- | --- | --- | --- | --- |
011 | ERET | --- | --- | --- | --- | --- | --- | --- |
100 | --- | --- | --- | --- | --- | --- | --- | --- |
101 | --- | --- | --- | --- | --- | --- | --- | --- |
110 | --- | --- | --- | --- | --- | --- | --- | --- |
111 | EI | DI | --- | --- | --- | --- | --- | --- |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*/
// The other instructions are implemented using the main CPU table
RABBITIZER_DEF_INSTR_ID(r5900, 0x38, ei, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, 0x39, di, .operands={0})
@@ -0,0 +1,46 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31--------26-25------21 -------------------------------5--------0
| = COP1 | = S | | function|
------6----------5-----------------------------------------6-----
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
000 | ADD.S | SUB.S | MUL.S | DIV.S | SQRT.S| ABS.S | MOV.S | NEG.S |
001 | --- | --- | --- | --- | --- | --- | --- | --- |
010 | --- | --- | --- | --- | --- | --- |RSQRT.S| --- |
011 | ADDA.S| SUBA.S| MULA.S| --- | MADD.S| MSUB.S|MADDA.S|MSUBA.S|
100 | --- | --- | --- | --- | CVT.W | --- | --- | --- |
101 | MAX.S | MIN.S | --- | --- | --- | --- | --- | --- |
110 | C.F | --- | C.EQ | --- | C.LT | --- | C.LE | --- |
111 | --- | --- | --- | --- | --- | --- | --- | --- |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*/
// The other instructions are implemented using the main CPU table
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x04, c1__sqrt_s, c1, .operands={RAB_OPERAND_cpu_copraw})
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x16, rsqrt_s, rsqrt.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point Reciprocal SQuare RooT
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x18, adda_s, adda.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point ADD to Accumulator
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x19, suba_s, suba.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point SUBtract to Accumulator
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x1A, mula_s, mula.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point MULtiply to Accumulator
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x1C, madd_s, madd.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point Multiply-ADD
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x1D, msub_s, msub.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point Multiply abd SUBtract
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x1E, madda_s, madda.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point Multiply-ADD Accumulator
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x1F, msuba_s, msuba.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point Multiply SUBtract from Accumulator
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x28, max_s, max.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point MAXimum
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x29, min_s, min.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true) // floating point MINimum
// Due to the R5900's FPU being non properly complaint the instruction cvt.w.s always behaves as trunc.w.s because is because EE can only do round-to-zero.
// Assemblers like GAS workaround this issue by decoding cvt.w.s as trunc.w.s, so we mimic that behaviour to allow assembling with GAS.
// Here's some reading about the binutils rationale:
// https://sourceware.org/legacy-ml/binutils/2012-11/msg00360.html
// https://sourceware.org/pipermail/binutils/2013-January/079863.html
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x24, trunc_w_s, trunc.w.s, .operands={RAB_OPERAND_cpu_fd, RAB_OPERAND_cpu_fs}, .isFloat=true) // Floating-Point Truncate to Word Fixed-Point
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x34, c_lt_s, c.lt.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true)
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, 0x36, c_le_s, c.le.s, .operands={RAB_OPERAND_cpu_fs, RAB_OPERAND_cpu_ft}, .isFloat=true)
@@ -0,0 +1,21 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31--------26-25------21 ----------------------------------------0
| = COP2 | fmt | |
------6----------5-----------------------------------------------
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
00 | --- | QMFC2 | CFC2 | --- | --- | QMTC2 | CTC2 | --- |
01 | *1 | --- | --- | --- | --- | --- | --- | --- |
10 | *2 | *2 | *2 | *2 | *2 | *2 | *2 | *2 |
11 | *2 | *2 | *2 | *2 | *2 | *2 | *2 | *2 |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*1 = BC instructions, see BC2 list *2 =see special1 table
*/
// TODO: properties
RABBITIZER_DEF_INSTR_ID(r5900, 0x01, qmfc2, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_r5900_vfs})
RABBITIZER_DEF_INSTR_ID(r5900, 0x02, cfc2, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_r5900_vis})
RABBITIZER_DEF_INSTR_ID(r5900, 0x05, qmtc2, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_r5900_vfs})
RABBITIZER_DEF_INSTR_ID(r5900, 0x06, ctc2, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_r5900_vis})
@@ -0,0 +1,21 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31--------26-25------21-20------16------------------------------0
| = COP0 | BC2 | fmt | |
------6----------5----------5------------------------------------
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
00 | BC2F | BC2T | BC2FL | BC2TL | --- | --- | --- | --- |
01 | --- | --- | --- | --- | --- | --- | --- | --- |
10 | --- | --- | --- | --- | --- | --- | --- | --- |
11 | --- | --- | --- | --- | --- | --- | --- | --- |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*/
// TODO: operands and properties
RABBITIZER_DEF_INSTR_ID(r5900, 0x00, bc2f, .operands={RAB_OPERAND_cpu_branch_target_label}, .isBranch=true)
RABBITIZER_DEF_INSTR_ID(r5900, 0x01, bc2t, .operands={RAB_OPERAND_cpu_branch_target_label}, .isBranch=true)
RABBITIZER_DEF_INSTR_ID(r5900, 0x02, bc2fl, .operands={RAB_OPERAND_cpu_branch_target_label}, .isBranch=true, .isBranchLikely=true)
RABBITIZER_DEF_INSTR_ID(r5900, 0x03, bc2tl, .operands={RAB_OPERAND_cpu_branch_target_label}, .isBranch=true, .isBranchLikely=true)
@@ -0,0 +1,82 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26-25-----21-20-----------------------------5--------0
| =COP2 | Special1 | |function|
------6----------5------------------------------------------6----
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
000 |VADDx |VADDy |VADDz |VADDw |VSUBx |VSUBy |VSUBz |VSUBw |
001 |VMADDx |VMADDy |VMADDz |VMADDw |VMSUBx |VMSUBy |VMSUBz |VMSUBw |
010 |VMAXx |VMAXy |VMAXz |VMAXw |VMINIx |VMINIy |VMINIz |VMINIw |
011 |VMULx |VMULy |VMULz |VMULw |VMULq |VMAXi |VMULi |VMINIi |
100 |VADDq |VMADDq |VADDi |VMADDi |VSUBq |VMSUBq |VSUbi |VMSUBi |
101 |VADD |VMADD |VMUL |VMAX |VSUB |VMSUB |VOPMSUB|VMINI |
110 |VIADD |VISUB |VIADDI | --- |VIAND |VIOR | --- | --- |
111 |VCALLMS|VCALLMSR| --- | --- | *1 | *1 | *1 | *1 |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*1=see special2 table
*/
// TODO: properties
RABBITIZER_DEF_INSTR_ID(r5900, 0x00, vaddx, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // ADD broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x01, vaddy, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // ADD broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x02, vaddz, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // ADD broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x03, vaddw, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // ADD broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x04, vsubx, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // SUBtract broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x05, vsuby, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // SUBtract broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x06, vsubz, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // SUBtract broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x07, vsubw, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // SUBtract broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x08, vmaddx, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-ADD broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x09, vmaddy, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-ADD broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0A, vmaddz, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-ADD broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0B, vmaddw, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-ADD broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0C, vmsubx, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-SUBtract broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0D, vmsuby, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-SUBtract broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0E, vmsubz, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-SUBtract broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0F, vmsubw, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-SUBtract broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x10, vmaxx, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MAXimum broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x11, vmaxy, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MAXimum broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x12, vmaxz, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MAXimum broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x13, vmaxw, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MAXimum broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x14, vminix, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MINimum broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x15, vminiy, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MINimum broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x16, vminiz, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MINimum broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x17, vminiw, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MINimum broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x18, vmulx, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MULtiply broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x19, vmuly, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MULtiply broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x1A, vmulz, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MULtiply broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x1B, vmulw, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MULtiply broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x1C, vmulq, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MULtiply Q
RABBITIZER_DEF_INSTR_ID(r5900, 0x1D, vmaxi, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MAXimum I
RABBITIZER_DEF_INSTR_ID(r5900, 0x1E, vmuli, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MULtiply I
RABBITIZER_DEF_INSTR_ID(r5900, 0x1F, vminii, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MINImum I
RABBITIZER_DEF_INSTR_ID(r5900, 0x20, vaddq, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // ADD Q
RABBITIZER_DEF_INSTR_ID(r5900, 0x21, vmaddq, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-ADD Q
RABBITIZER_DEF_INSTR_ID(r5900, 0x22, vaddi, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // ADD I
RABBITIZER_DEF_INSTR_ID(r5900, 0x23, vmaddi, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-ADD I
RABBITIZER_DEF_INSTR_ID(r5900, 0x24, vsubq, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // SUBtract Q
RABBITIZER_DEF_INSTR_ID(r5900, 0x25, vmsubq, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-SUBtract Q
RABBITIZER_DEF_INSTR_ID(r5900, 0x26, vsubi, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // SUBtract I
RABBITIZER_DEF_INSTR_ID(r5900, 0x27, vmsubi, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-SUBtract I
RABBITIZER_DEF_INSTR_ID(r5900, 0x28, vadd, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // ADD
RABBITIZER_DEF_INSTR_ID(r5900, 0x29, vmadd, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-ADD
RABBITIZER_DEF_INSTR_ID(r5900, 0x2A, vmul, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MULtiply
RABBITIZER_DEF_INSTR_ID(r5900, 0x2B, vmax, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MAXimum
RABBITIZER_DEF_INSTR_ID(r5900, 0x2C, vsub, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // SUBtract
RABBITIZER_DEF_INSTR_ID(r5900, 0x2D, vmsub, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply-SUBtract
RABBITIZER_DEF_INSTR_ID(r5900, 0x2E, vopmsub, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Outer product post decrement
RABBITIZER_DEF_INSTR_ID(r5900, 0x2F, vmini, .operands={RAB_OPERAND_r5900_vfdxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // MINImum
RABBITIZER_DEF_INSTR_ID(r5900, 0x30, viadd, .operands={RAB_OPERAND_r5900_vid, RAB_OPERAND_r5900_vis, RAB_OPERAND_r5900_vit}) // Integer ADD
RABBITIZER_DEF_INSTR_ID(r5900, 0x31, visub, .operands={RAB_OPERAND_r5900_vid, RAB_OPERAND_r5900_vis, RAB_OPERAND_r5900_vit}) // Integer SUBtract
RABBITIZER_DEF_INSTR_ID(r5900, 0x32, viaddi, .operands={RAB_OPERAND_r5900_vit, RAB_OPERAND_r5900_vis, RAB_OPERAND_r5900_immediate5}) // Integer ADD Immediate
RABBITIZER_DEF_INSTR_ID(r5900, 0x34, viand, .operands={RAB_OPERAND_r5900_vid, RAB_OPERAND_r5900_vis, RAB_OPERAND_r5900_vit}) // Integer AND
RABBITIZER_DEF_INSTR_ID(r5900, 0x35, vior, .operands={RAB_OPERAND_r5900_vid, RAB_OPERAND_r5900_vis, RAB_OPERAND_r5900_vit}) // Integer OR
// TODO: operands and properties
RABBITIZER_DEF_INSTR_ID(r5900, 0x38, vcallms, .operands={0})
RABBITIZER_DEF_INSTR_ID(r5900, 0x39, vcallmsr, .operands={RAB_OPERAND_r5900_vis})
@@ -0,0 +1,125 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26-25-----21-20------------------11-10------6-5-2-1--0
| =COP2 | Special2 | | fhi |1111|flo|
------6----------5-----------------------------------------------
Note: opcode is flo | (fhi * 4).
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
0000 |VADDAx |VADDAy |VADDAz |VADDAw |VSUBAx |VSUBAy |VSUBAz |VSUBAw |
0001 |VMADDAx|VMADDAy|VMADDAz|VMADDAw|VMSUBAx|VMSUBAy|VMSUBAz|VMSUBAw|
0010 |VITOF0 |VITOF4 |VITOF12|VITOF15|VFTOI0 |VFTOI4 |VFTOI12|VFTOI15|
0011 |VMULAx |VMULAy |VMULAz |VMULAw |VMULAq |VABS |VMULAi |VCLIPw |
0100 |VADDAq |VMADDAq|VADDAi |VMADDAi|VSUBAq |VMSUBAq|VSUBAi |VMSUBAi|
0101 |VADDA |VMADDA |VMULA | --- |VSUBA |VMSUBA |VOPMULA|VNOP |
0110 |VMOVE |VMR32 | --- | --- |VLQI |VSQI |VLQD |VSQD |
0111 |VDIV |VSQRT |VRSQRT |VWAITQ |VMTIR |VMFIR |VILWR |VISWR |
1000 |VRNEXT |VRGET |VRINIT |VRXOR | --- | --- | --- | --- |
1001 | --- | --- | --- | --- | --- | --- | --- | --- |
1010 | --- | --- | --- | --- | --- | --- | --- | --- |
1011 | --- | --- | --- | --- | --- | --- | --- | --- |
1100 | --- | --- | --- | --- | --- | --- | --- | --- |
1101 | --- | --- | --- | --- | --- | --- | --- | --- |
1110 | --- | --- | --- | --- | --- | --- | --- | --- |
1111 | --- | --- | --- | --- | --- | --- | --- | --- |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*/
// TODO: operands and properties
RABBITIZER_DEF_INSTR_ID(r5900, 0x00, vaddax, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Add accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x01, vadday, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Add accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x02, vaddaz, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Add accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x03, vaddaw, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Add accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x04, vsubax, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and substract accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x05, vsubay, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and substract accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x06, vsubaz, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and substract accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x07, vsubaw, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and substract accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x08, vmaddax, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw) // Multiply and add accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x09, vmadday, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw) // Multiply and add accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0A, vmaddaz, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw) // Multiply and add accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0B, vmaddaw, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw) // Multiply and add accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0C, vmsubax, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and substract accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0D, vmsubay, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and substract accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0E, vmsubaz, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and substract accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x0F, vmsubaw, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and substract accumulator broadcast
RABBITIZER_DEF_INSTR_ID(r5900, 0x10, vitof0, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Integer to floating point
RABBITIZER_DEF_INSTR_ID(r5900, 0x11, vitof4, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Integer to floating point
RABBITIZER_DEF_INSTR_ID(r5900, 0x12, vitof12, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Integer to floating point
RABBITIZER_DEF_INSTR_ID(r5900, 0x13, vitof15, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Integer to floating point
RABBITIZER_DEF_INSTR_ID(r5900, 0x14, vftoi0, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Floating to integer
RABBITIZER_DEF_INSTR_ID(r5900, 0x15, vftoi4, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Floating to integer
RABBITIZER_DEF_INSTR_ID(r5900, 0x16, vftoi12, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Floating to integer
RABBITIZER_DEF_INSTR_ID(r5900, 0x17, vftoi15, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Floating to integer
RABBITIZER_DEF_INSTR_ID(r5900, 0x18, vmulax, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw)
RABBITIZER_DEF_INSTR_ID(r5900, 0x19, vmulay, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw)
RABBITIZER_DEF_INSTR_ID(r5900, 0x1A, vmulaz, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw)
RABBITIZER_DEF_INSTR_ID(r5900, 0x1B, vmulaw, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw)
// TODO
RABBITIZER_DEF_INSTR_ID(r5900, 0x1C, vmulaq, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw)
RABBITIZER_DEF_INSTR_ID(r5900, 0x1D, vabs, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Absolute
// TODO
RABBITIZER_DEF_INSTR_ID(r5900, 0x1E, vmulai, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw)
RABBITIZER_DEF_INSTR_ID(r5900, 0x1F, vclipw, .operands={RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftn}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Clip
RABBITIZER_DEF_INSTR_ID(r5900, 0x20, vaddaq, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Add accumulator Q
RABBITIZER_DEF_INSTR_ID(r5900, 0x21, vmaddaq, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and add accumulator Q
RABBITIZER_DEF_INSTR_ID(r5900, 0x22, vaddai, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Add accumulator I
RABBITIZER_DEF_INSTR_ID(r5900, 0x23, vmaddai, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and add accumulator I
RABBITIZER_DEF_INSTR_ID(r5900, 0x24, vsubaq, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Subtract accumulator Q
RABBITIZER_DEF_INSTR_ID(r5900, 0x25, vmsubaq, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_Q}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and Subtract accumulator Q
RABBITIZER_DEF_INSTR_ID(r5900, 0x26, vsubai, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Subtract accumulator I
RABBITIZER_DEF_INSTR_ID(r5900, 0x27, vmsubai, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_I}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and Subtract accumulator I
RABBITIZER_DEF_INSTR_ID(r5900, 0x28, vadda, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Add accumulator
RABBITIZER_DEF_INSTR_ID(r5900, 0x29, vmadda, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and add accumulator
// TODO
RABBITIZER_DEF_INSTR_ID(r5900, 0x2A, vmula, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw)
RABBITIZER_DEF_INSTR_ID(r5900, 0x2C, vsuba, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true)
RABBITIZER_DEF_INSTR_ID(r5900, 0x2D, vmsuba, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Multiply and substract accumulator
RABBITIZER_DEF_INSTR_ID(r5900, 0x2E, vopmula, .operands={RAB_OPERAND_r5900_ACCxyzw, RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vftxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Outer product pre increment
RABBITIZER_DEF_INSTR_ID(r5900, 0x2F, vnop, .operands={0}) // No operation
RABBITIZER_DEF_INSTR_ID(r5900, 0x30, vmove, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Move floating point registers
RABBITIZER_DEF_INSTR_ID(r5900, 0x31, vmr32, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vfsxyzw}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Move and rotate per word
RABBITIZER_DEF_INSTR_ID(r5900, 0x34, vlqi, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vis_postincr}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Load quadraword post increment
RABBITIZER_DEF_INSTR_ID(r5900, 0x35, vsqi, .operands={RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vit_postincr}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Store quadraword post increment
RABBITIZER_DEF_INSTR_ID(r5900, 0x36, vlqd, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vis_predecr}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Load quadraword pre decrement
RABBITIZER_DEF_INSTR_ID(r5900, 0x37, vsqd, .operands={RAB_OPERAND_r5900_vfsxyzw, RAB_OPERAND_r5900_vit_predecr}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Store quadraword pre decrement
RABBITIZER_DEF_INSTR_ID(r5900, 0x38, vdiv, .operands={RAB_OPERAND_r5900_Q, RAB_OPERAND_r5900_vfsl, RAB_OPERAND_r5900_vftm})
RABBITIZER_DEF_INSTR_ID(r5900, 0x39, vsqrt, .operands={RAB_OPERAND_r5900_Q, RAB_OPERAND_r5900_vftm})
RABBITIZER_DEF_INSTR_ID(r5900, 0x3A, vrsqrt, .operands={RAB_OPERAND_r5900_Q, RAB_OPERAND_r5900_vfsl,RAB_OPERAND_r5900_vftm})
RABBITIZER_DEF_INSTR_ID(r5900, 0x3B, vwaitq, .operands={0}) // Wait Q operation
RABBITIZER_DEF_INSTR_ID(r5900, 0x3C, vmtir, .operands={RAB_OPERAND_r5900_vit, RAB_OPERAND_r5900_vfsl})
RABBITIZER_DEF_INSTR_ID(r5900, 0x3D, vmfir, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_vis}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // Move from integer register
RABBITIZER_DEF_INSTR_ID(r5900, 0x3E, vilwr, .operands={RAB_OPERAND_r5900_vit, RAB_OPERAND_r5900_vis}, .isFloat=true, .doesDereference=true, .doesLoad=true) // Integer load word register
RABBITIZER_DEF_INSTR_ID(r5900, 0x3F, viswr, .operands={RAB_OPERAND_r5900_vit, RAB_OPERAND_r5900_vis}, .isFloat=true, .doesDereference=true, .doesStore=true) // Integer store word register
/*
"vilwr.w", RAB_OPERAND_r5900_vit,(RAB_OPERAND_r5900_vis)
"vilwr.x", RAB_OPERAND_r5900_vit,(RAB_OPERAND_r5900_vis)
"vilwr.y", RAB_OPERAND_r5900_vit,(RAB_OPERAND_r5900_vis)
"vilwr.z", RAB_OPERAND_r5900_vit,(RAB_OPERAND_r5900_vis)
"viswr.w", RAB_OPERAND_r5900_vit,(RAB_OPERAND_r5900_vis)
"viswr.x", RAB_OPERAND_r5900_vit,(RAB_OPERAND_r5900_vis)
"viswr.y", RAB_OPERAND_r5900_vit,(RAB_OPERAND_r5900_vis)
"viswr.z", RAB_OPERAND_r5900_vit,(RAB_OPERAND_r5900_vis)
*/
RABBITIZER_DEF_INSTR_ID(r5900, 0x40, vrnext, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_R}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // R next
RABBITIZER_DEF_INSTR_ID(r5900, 0x41, vrget, .operands={RAB_OPERAND_r5900_vftxyzw, RAB_OPERAND_r5900_R}, .instrSuffix=RABINSTRSUFFIX_R5900_xyzw, .isFloat=true) // R move
// TODO
RABBITIZER_DEF_INSTR_ID(r5900, 0x42, vrinit, .operands={RAB_OPERAND_r5900_R, RAB_OPERAND_r5900_vfsl})
RABBITIZER_DEF_INSTR_ID(r5900, 0x43, vrxor, .operands={RAB_OPERAND_r5900_R, RAB_OPERAND_r5900_vfsl})
@@ -0,0 +1,49 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26------------------------------------------5--------0
| = MMI | | function|
------6----------------------------------------------------6-----
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
000 | MADD | MADDU | --- | --- | PLZCW | --- | --- | --- |
001 | *1 | *2 | --- | --- | --- | --- | --- | --- |
010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | --- | --- | --- | --- |
011 | MULT1 | MULTU1| DIV1 | DIVU1 | --- | --- | --- | --- |
100 | MADD1 | MADDU1| --- | --- | --- | --- | --- | --- |
101 | *3 | *4 | --- | --- | --- | --- | --- | --- |
110 | PMFHL | PMTHL | --- | --- | PSLLH | --- | PSRLH | PSRAH |
111 | --- | --- | --- | --- | PSLLW | --- | PSRLW | PSRAW |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*1 = MMI0 list *2 = MMI2 list
*3 = MMI1 list *4 = MMI3 list
*/
RABBITIZER_DEF_INSTR_ID(r5900, 0x00, madd, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Multiply-ADD word
RABBITIZER_DEF_INSTR_ID(r5900, 0x01, maddu, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Multiply-ADD Unsigned word
RABBITIZER_DEF_INSTR_ID(r5900, 0x04, plzcw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs}, .modifiesRd=true) // Parallel Leading Zero or one Count Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x10, mfhi1, .operands={RAB_OPERAND_cpu_rd}, .modifiesRd=true) // Move From HI1 register
RABBITIZER_DEF_INSTR_ID(r5900, 0x11, mthi1, .operands={RAB_OPERAND_cpu_rs}) // Move To HI1 register
RABBITIZER_DEF_INSTR_ID(r5900, 0x12, mflo1, .operands={RAB_OPERAND_cpu_rd}) // Move From LO1 register
RABBITIZER_DEF_INSTR_ID(r5900, 0x13, mtlo1, .operands={RAB_OPERAND_cpu_rs}) // Move To LO1 register
RABBITIZER_DEF_INSTR_ID(r5900, 0x18, mult1, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // MULTiply word pipeline 1
RABBITIZER_DEF_INSTR_ID(r5900, 0x19, multu1, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // MULTiply Unsigned word pipeline 1
RABBITIZER_DEF_INSTR_ID(r5900, 0x1A, div1, .operands={RAB_OPERAND_cpu_zero, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}) // DIVide word pipeline 1
RABBITIZER_DEF_INSTR_ID(r5900, 0x1B, divu1, .operands={RAB_OPERAND_cpu_zero, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}) // DIVide Unsigned word pipeline 1
RABBITIZER_DEF_INSTR_ID(r5900, 0x20, madd1, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Multiply-ADD word pipeline 1
RABBITIZER_DEF_INSTR_ID(r5900, 0x21, maddu1, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Multiply-ADD Unsigned word pipeline 1
// TODO: check this two instruction, it is supposed to have an extra .fmt
RABBITIZER_DEF_INSTR_ID(r5900, 0x30, pmfhl, .operands={RAB_OPERAND_cpu_rd}, .modifiesRd=true) // Parallel Move From Hi/Lo register
RABBITIZER_DEF_INSTR_ID(r5900, 0x31, pmthl, .operands={RAB_OPERAND_cpu_rs}) // Parallel Move To Hi/Lo register
RABBITIZER_DEF_INSTR_ID(r5900, 0x34, psllh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .modifiesRd=true) // Parallel Shift Left Logical Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x36, psrlh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .modifiesRd=true) // Parallel Shift Right Logical Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x37, psrah, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .modifiesRd=true) // Parallel Shift Right Arithmetic Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x3C, psllw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .modifiesRd=true) // Parallel Shift Left Logical Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x3E, psrlw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .modifiesRd=true) // Parallel Shift Right Logical Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x3F, psraw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_sa}, .modifiesRd=true) // Parallel Shift Right Arithmetic Word
@@ -0,0 +1,50 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26------------------------------10--------6-5--------0
| | |function | MMI0 |
------6----------------------------------------------------6-----
|---00--|---01--|---10--|---11--| lo
000 |PADDW | PSUBW | PCGTW | PMAXW |
001 |PADDH | PSUBH | PCGTH | PMAXH |
010 |PADDB | PSUBB | PCGTB | --- |
011 | --- | --- | --- | --- |
100 |PADDSW |PSUBSW |PEXTLW | PPACW |
101 |PADDSH |PSUBSH |PEXTLH | PPACH |
110 |PADDSB |PSUBSB |PEXTLB | PPACB |
111 | --- | --- | PEXT5 | PPAC5 |
hi |-------|-------|-------|-------|
*/
RABBITIZER_DEF_INSTR_ID(r5900, 0x00, paddw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADD Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x01, psubw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel SUBtract Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x02, pcgtw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Compare for Greater Than Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x03, pmaxw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel MAXimum Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x04, paddh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADD Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x05, psubh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel SUBtract Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x06, pcgth, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Compare for Greater Than Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x07, pmaxh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel MAXimum Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x08, paddb, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADD Byte
RABBITIZER_DEF_INSTR_ID(r5900, 0x09, psubb, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel SUBtract Byte
RABBITIZER_DEF_INSTR_ID(r5900, 0x0A, pcgtb, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Compare for Greater Than Byte
RABBITIZER_DEF_INSTR_ID(r5900, 0x10, paddsw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADD with Signed saturation Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x11, psubsw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel SUBtract with Signed saturation Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x12, pextlw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXTend Lower from Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x13, ppacw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel PACk to Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x14, paddsh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADD with Signed saturation Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x15, psubsh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel SUBtract with Signed saturation Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x16, pextlh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXTend Lower from Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x17, ppach, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel PACk to Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x18, paddsb, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADD with Signed saturation Bytes
RABBITIZER_DEF_INSTR_ID(r5900, 0x19, psubsb, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel SUBtract with Signed saturation Bytes
RABBITIZER_DEF_INSTR_ID(r5900, 0x1A, pextlb, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXTend Lower from Bytes
RABBITIZER_DEF_INSTR_ID(r5900, 0x1B, ppacb, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel PACk to Bytes
RABBITIZER_DEF_INSTR_ID(r5900, 0x1E, pext5, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXTend from 5-bits
RABBITIZER_DEF_INSTR_ID(r5900, 0x1F, ppac5, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel PACk to 5-bits
@@ -0,0 +1,43 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26------------------------------------------5--------0
| | |function | MMI1 |
------6----------------------------------------------------6-----
|---00--|---01--|---10--|---11--| lo
000 | --- | PABSW | PCEQW | PMINW |
001 |PADSBH | PABSH | PCEQH | PMINH |
010 | --- | --- | PCEQB | --- |
011 | --- | --- | --- | --- |
100 |PADDUW |PSUBUW |PEXTUW | --- |
101 |PADDUH |PSUBUH |PEXTUH | --- |
110 |PADDUB |PSUBUB |PEXTUB | QFSRV |
111 | --- | --- | --- | --- |
hi |-------|-------|-------|-------|
*/
// TODO: operands and properties
RABBITIZER_DEF_INSTR_ID(r5900, 0x01, pabsw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ABSolute Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x02, pceqw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Compare for EQual Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x03, pminw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel MINimum Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x04, padsbh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADd/SuBtract Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x05, pabsh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ABSolute Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x06, pceqh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Compare for EQual Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x07, pminh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel MINimum Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x0A, pceqb, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Compare for EQual Byte
RABBITIZER_DEF_INSTR_ID(r5900, 0x10, padduw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADD Unsigned saturation Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x11, psubuw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel SUBtract Unsigned saturation Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x12, pextuw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXTend Upper from Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x14, padduh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADD Unsigned saturation Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x15, psubuh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel SUBtract Unsigned saturation Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x16, pextuh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXTend Upper from Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x18, paddub, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ADD Unsigned saturation Byte
RABBITIZER_DEF_INSTR_ID(r5900, 0x19, psubub, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel SUBtract Unsigned saturation Byte
RABBITIZER_DEF_INSTR_ID(r5900, 0x1A, pextub, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXTend Upper from Byte
RABBITIZER_DEF_INSTR_ID(r5900, 0x1B, qfsrv, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Quadword Funnel Shift Right Variable
@@ -0,0 +1,48 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26------------------------------------------5--------0
| | |function | MMI2 |
------6----------------------------------------------------6-----
|---00--|---01--|---10--|---11--| lo
000 |PMADDW | --- |PSLLVW |PSRLVW |
001 |PMSUBW | --- | --- | --- |
010 |PMFHI |PMFLO |PINTH | --- |
011 |PMULTW |PDIVW |PCPYLD | --- |
100 |PMADDH |PHMADH | PAND | PXOR |
101 |PMSUBH |PHMSBH | --- | --- |
110 | --- | --- | PEXEH | PREVH |
111 |PMULTH |PDIVBW | PEXEW |PROT3W |
hi |-------|-------|-------|-------|
*/
RABBITIZER_DEF_INSTR_ID(r5900, 0x00, pmaddw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Multiply-ADD Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x02, psllvw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs}, .modifiesRd=true) // Parallel Shift Left Logical Variable Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x03, psrlvw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs}, .modifiesRd=true) // Parallel Shift Right Logical Variable Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x04, pmsubw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Multiply-SUBtract Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x08, pmfhi, .operands={RAB_OPERAND_cpu_rd}, .modifiesRd=true) // Parallel Move From HI register
RABBITIZER_DEF_INSTR_ID(r5900, 0x09, pmflo, .operands={RAB_OPERAND_cpu_rd}, .modifiesRd=true) // Parallel Move From LO register
RABBITIZER_DEF_INSTR_ID(r5900, 0x0A, pinth, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel INTerleave Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x0C, pmultw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel MULTiply Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x0D, pdivw, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}) // Parallel DIVide Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x0E, pcpyld, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel CoPY Lower Doubleword
RABBITIZER_DEF_INSTR_ID(r5900, 0x10, pmaddh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Multiply-ADD Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x11, phmadh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Horizontal Multiply-ADd Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x12, pand, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel AND
RABBITIZER_DEF_INSTR_ID(r5900, 0x13, pxor, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel eXclusive OR
RABBITIZER_DEF_INSTR_ID(r5900, 0x14, pmsubh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Multiply-SUBtract Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x15, phmsbh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Horizontal Multiply-Subtract Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x1A, pexeh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXchange Even Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x1B, prevh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel REVerse Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x1C, pmulth, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Multiply Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x1D, pdivbw, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel DIVide Broadcast Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x1E, pexew, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXchange Even Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x1F, prot3w, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel ROTate 3 Words left
@@ -0,0 +1,37 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26------------------------------------------5--------0
| | |function | MMI3 |
------6----------------------------------------------------6-----
|---00--|---01--|---10--|---11--| lo
000 |PMADDUW| --- | --- |PSRAVW |
001 | --- | --- | --- | --- |
010 |PMTHI | PMTLO |PINTEH | --- |
011 |PMULTUW| PDIVUW|PCPYUD | --- |
100 | --- | --- | POR | PNOR |
101 | --- | --- | --- | --- |
110 | --- | --- | PEXCH | PCPYH |
111 | --- | --- | PEXCW | --- |
hi |-------|-------|-------|-------|
*/
RABBITIZER_DEF_INSTR_ID(r5900, 0x00, pmadduw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Multiply-ADD Unsigned Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x03, psravw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_rs}, .modifiesRd=true) // Parallel Shift Right Arithmetic Variable Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x08, pmthi, .operands={RAB_OPERAND_cpu_rs}) // Parallel Move To HI register
RABBITIZER_DEF_INSTR_ID(r5900, 0x09, pmtlo, .operands={RAB_OPERAND_cpu_rs}) // Parallel Move To LO register
RABBITIZER_DEF_INSTR_ID(r5900, 0x0A, pinteh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel INTerleave Even Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x0C, pmultuw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel MULTiply Unsigned Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x0D, pdivuw, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}) // Prallel DIVide Unsigned Word
RABBITIZER_DEF_INSTR_ID(r5900, 0x0E, pcpyud, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel CoPY Upper Doubleword
RABBITIZER_DEF_INSTR_ID(r5900, 0x12, por, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel OR
RABBITIZER_DEF_INSTR_ID(r5900, 0x13, pnor, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel Not OR
RABBITIZER_DEF_INSTR_ID(r5900, 0x1A, pexch, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXchange Center Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x1B, pcpyh, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel CoPY Halfword
RABBITIZER_DEF_INSTR_ID(r5900, 0x1E, pexcw, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .modifiesRd=true) // Parallel EXchange Center Word
@@ -0,0 +1,31 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26---------------------------------------------------0
| opcode | |
------6----------------------------------------------------------
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
000 | *1 | *2 | J | JAL | BEQ | BNE | BLEZ | BGTZ |
001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI |
010 | *3 | *4 | *5 | --- | BEQL | BNEL | BLEZL | BGTZL |
011 | DADDI |DADDIU | LDL | LDR | *6 | --- | LQ | SQ |
100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU |
101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE |
110 | --- | LWC1 | --- | PREF | --- | --- | LQC2 | LD |
111 | --- | SWC1 | --- | --- | --- | --- | SQC2 | SD |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*1 = SPECIAL, see SPECIAL list *2 = REGIMM, see REGIMM list
*3 = COP0 *4 = COP1
*5 = COP2 *6 = MMI table
*/
// The other instructions are implemented using the main CPU table
RABBITIZER_DEF_INSTR_ID(r5900, 0x1E, lq, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true) // Load Quadword
RABBITIZER_DEF_INSTR_ID(r5900, 0x1F, sq, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true) // Store Quadword
RABBITIZER_DEF_INSTR_ID(r5900, 0x36, lqc2, .operands={RAB_OPERAND_r5900_vft, RAB_OPERAND_cpu_immediate_base}, .canBeLo=true, .doesDereference=true, .doesLoad=true)
RABBITIZER_DEF_INSTR_ID(r5900, 0x3E, sqc2, .operands={RAB_OPERAND_r5900_vft, RAB_OPERAND_cpu_immediate_base}, .canBeLo=true, .doesDereference=true, .doesStore=true)
@@ -0,0 +1,20 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26----------20-------16------------------------------0
| = REGIMM | | rt | |
------6---------------------5------------------------------------
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
00 | BLTZ | BGEZ | BLTZL | BGEZL | --- | --- | --- | --- |
01 | TGEI | TGEIU | TLTI | TLTIU | TEQI | --- | TNEI | --- |
10 | BLTZAL| BGEZAL|BLTZALL|BGEZALL| --- | --- | --- | --- |
11 | MTSAB | MTSAH | --- | --- | --- | --- | --- | --- |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*/
// The other instructions are implemented using the main CPU table
// OP rs, IMM
RABBITIZER_DEF_INSTR_ID(r5900, 0x18, mtsab, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM)
RABBITIZER_DEF_INSTR_ID(r5900, 0x19, mtsah, .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM)
@@ -0,0 +1,27 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/*
31---------26------------------------------------------5--------0
| = SPECIAL | | function|
------6----------------------------------------------------6-----
|--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
000 | SLL | --- | SRL | SRA | SLLV | --- | SRLV | SRAV |
001 | JR | JALR | MOVZ | MOVN |SYSCALL| BREAK | --- | SYNC |
010 | MFHI | MTHI | MFLO | MTLO | DSLLV | --- | DSRLV | DSRAV |
011 | MULT | MULTU | DIV | DIVU | ---- | --- | ---- | ----- |
100 | ADD | ADDU | SUB | SUBU | AND | OR | XOR | NOR |
101 | MFSA | MTSA | SLT | SLTU | DADD | DADDU | DSUB | DSUBU |
110 | TGE | TGEU | TLT | TLTU | TEQ | --- | TNE | --- |
111 | DSLL | --- | DSRL | DSRA |DSLL32 | --- |DSRL32 |DSRA32 |
hi |-------|-------|-------|-------|-------|-------|-------|-------|
*/
// The other instructions are implemented using the main CPU table
RABBITIZER_DEF_INSTR_ID_ALTNAME(r5900, -0x0F, sync_p, sync.p, .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_R, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_II) // Sync
RABBITIZER_DEF_INSTR_ID(r5900, 0x18, mult, .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // MULTtiply word
RABBITIZER_DEF_INSTR_ID(r5900, 0x28, mfsa, .operands={RAB_OPERAND_cpu_rd}, .modifiesRd=true) // Move From Shift Amount register
RABBITIZER_DEF_INSTR_ID(r5900, 0x29, mtsa, .operands={RAB_OPERAND_cpu_rs}) // Move To Shift Amount register
@@ -0,0 +1,6 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP rt, cop0d
RABBITIZER_DEF_INSTR_ID(rsp, 0x00, mfc0, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_cop0d}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .modifiesRt=true, .notEmitedByCompilers=true) // Move word From CP0
RABBITIZER_DEF_INSTR_ID(rsp, 0x04, mtc0, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_cop0d}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN, .notEmitedByCompilers=true) // Move word to CP0
@@ -0,0 +1,10 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP cop2t, vd[index]
RABBITIZER_DEF_INSTR_ID(rsp, 0x00, mfc2, .operands={RAB_OPERAND_rsp_cop2t, RAB_OPERAND_rsp_vs_index}, .modifiesRt=true)
RABBITIZER_DEF_INSTR_ID(rsp, 0x04, mtc2, .operands={RAB_OPERAND_rsp_cop2t, RAB_OPERAND_rsp_vs_index})
// OP rt, cop2cd
RABBITIZER_DEF_INSTR_ID(rsp, 0x02, cfc2, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_rsp_cop2cd}, .modifiesRt=true)
RABBITIZER_DEF_INSTR_ID(rsp, 0x06, ctc2, .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_rsp_cop2cd})
@@ -0,0 +1,53 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP vd, vs, vt[elementhigh]
RABBITIZER_DEF_INSTR_ID(rsp, 0x00, vmulf, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x01, vmulu, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x02, vrndp, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x03, vmulq, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x04, vmudl, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x05, vmudm, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x06, vmudn, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x07, vmudh, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x08, vmacf, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x09, vmacu, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x0A, vrndn, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x0B, vmacq, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x0C, vmadl, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x0D, vmadm, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x0E, vmadn, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x0F, vmadh, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x10, vadd, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x11, vsub, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x13, vabs, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x14, vaddc, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x15, vsubc, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x1D, vsar, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x28, vand, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x29, vnand, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x2A, vor, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x2B, vnor, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x2C, vxor, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x2D, vnxor, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x20, vlt, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x21, veq, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x22, vne, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x23, vge, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x24, vcl, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x25, vch, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x26, vcr, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x27, vmrg, .operands={RAB_OPERAND_rsp_vd, RAB_OPERAND_rsp_vs, RAB_OPERAND_rsp_vt_elementhigh})
// OP vd[de], vt[elementhigh]
RABBITIZER_DEF_INSTR_ID(rsp, 0x30, vrcp, .operands={RAB_OPERAND_rsp_vd_de, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x31, vrcpl, .operands={RAB_OPERAND_rsp_vd_de, RAB_OPERAND_rsp_vt_elementhigh}) // operands may be wrong
RABBITIZER_DEF_INSTR_ID(rsp, 0x32, vrcph, .operands={RAB_OPERAND_rsp_vd_de, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x33, vmov, .operands={RAB_OPERAND_rsp_vd_de, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x34, vrsq, .operands={RAB_OPERAND_rsp_vd_de, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x35, vrsql, .operands={RAB_OPERAND_rsp_vd_de, RAB_OPERAND_rsp_vt_elementhigh})
RABBITIZER_DEF_INSTR_ID(rsp, 0x36, vrsqh, .operands={RAB_OPERAND_rsp_vd_de, RAB_OPERAND_rsp_vt_elementhigh})
// OP
RABBITIZER_DEF_INSTR_ID(rsp, 0x37, vnop, .operands={0})
@@ -0,0 +1,53 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP LABEL
RABBITIZER_DEF_INSTR_ID(rsp, 0x02, j, .operands={RAB_OPERAND_cpu_label}, .instrType=RABBITIZER_INSTR_TYPE_J, .isJump=true) // Jump
RABBITIZER_DEF_INSTR_ID(rsp, 0x03, jal, .operands={RAB_OPERAND_cpu_label}, .instrType=RABBITIZER_INSTR_TYPE_J, .isJump=true, .doesLink=true) // Jump And Link
// OP rs, rt, IMM
RABBITIZER_DEF_INSTR_ID(rsp, 0x04, beq, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true) // Branch on EQual
RABBITIZER_DEF_INSTR_ID(rsp, 0x05, bne, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true) // Branch on Not Equal
// OP rs, IMM
RABBITIZER_DEF_INSTR_ID(rsp, 0x06, blez, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true) // Branch on Less than or Equal to Zero
RABBITIZER_DEF_INSTR_ID(rsp, 0x07, bgtz, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true) // Branch on Greater Than Zero
// OP rt, rs, IMM
RABBITIZER_DEF_INSTR_ID(rsp, 0x08, addi, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .notEmitedByCompilers=true, .canBeLo=true) // Add Immediate
RABBITIZER_DEF_INSTR_ID(rsp, 0x09, addiu, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true) // Add Immediate Unsigned Word
RABBITIZER_DEF_INSTR_ID(rsp, 0x0A, slti, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true) // Set on Less Than Immediate
RABBITIZER_DEF_INSTR_ID(rsp, 0x0B, sltiu, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true) // Set on Less Than Immediate Unsigned
RABBITIZER_DEF_INSTR_ID(rsp, 0x0C, andi, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .isUnsigned=true, .modifiesRt=true) // And Immediate
RABBITIZER_DEF_INSTR_ID(rsp, 0x0D, ori, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .isUnsigned=true, .modifiesRt=true, .canBeLo=true) // Or Immediate
RABBITIZER_DEF_INSTR_ID(rsp, 0x0E, xori, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .isUnsigned=true, .modifiesRt=true) // eXclusive OR Immediate
// OP rt, IMM
RABBITIZER_DEF_INSTR_ID(rsp, 0x0F, lui, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_I, .isUnsigned=true, .modifiesRt=true, .canBeHi=true) // Load Upper Immediate
// OP rt, IMM(base)
RABBITIZER_DEF_INSTR_ID(rsp, 0x20, lb, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Byte
RABBITIZER_DEF_INSTR_ID(rsp, 0x21, lh, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Halfword
RABBITIZER_DEF_INSTR_ID(rsp, 0x23, lw, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Word
RABBITIZER_DEF_INSTR_ID(rsp, 0x24, lbu, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Byte Insigned
RABBITIZER_DEF_INSTR_ID(rsp, 0x25, lhu, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Halfword Unsigned
RABBITIZER_DEF_INSTR_ID(rsp, 0x28, sb, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Byte
RABBITIZER_DEF_INSTR_ID(rsp, 0x29, sh, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Halfword
RABBITIZER_DEF_INSTR_ID(rsp, 0x2B, sw, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Word
RABBITIZER_DEF_INSTR_ID(rsp, 0x33, pref, .operands={RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .canBeLo=true, .doesDereference=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_IV) // Prefetch
RABBITIZER_DEF_INSTR_ID(rsp, 0x2F, cache, .operands={RAB_OPERAND_cpu_op, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .notEmitedByCompilers=true) // Cache
// OP ft, IMM(base)
RABBITIZER_DEF_INSTR_ID(rsp, 0x31, lwc1, .operands={RAB_OPERAND_cpu_ft, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .isFloat=true, .canBeLo=true, .doesDereference=true, .doesLoad=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Load Word to Coprocessor z
RABBITIZER_DEF_INSTR_ID(rsp, 0x39, swc1, .operands={RAB_OPERAND_cpu_ft, RAB_OPERAND_rsp_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .isFloat=true, .canBeLo=true, .doesDereference=true, .doesStore=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Store Word from Coprocessor z
// Pseudo-Instruction Unique IDs
// OP IMM
RABBITIZER_DEF_INSTR_ID(rsp, -0x03, b, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true) // Branch (unconditional)
// OP rs, IMM
RABBITIZER_DEF_INSTR_ID(rsp, -0x04, beqz, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true) // Branch on EQual Zero
RABBITIZER_DEF_INSTR_ID(rsp, -0x05, bnez, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true) // Branch on Not Equal Zero
@@ -0,0 +1,15 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP vt[elementlow], offset(vs)
RABBITIZER_DEF_INSTR_ID(rsp, 0x00, lbv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x01, lsv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x02, llv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x03, ldv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x04, lqv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x05, lrv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x06, lpv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x07, luv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x08, lhv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x09, lfv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x0B, ltv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
@@ -0,0 +1,17 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP vt[elementlow], offset(vs)
RABBITIZER_DEF_INSTR_ID(rsp, 0x00, sbv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x01, ssv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x02, slv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x03, sdv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x04, sqv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x05, srv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x06, spv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x07, suv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x08, shv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x09, sfv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, 0x0B, stv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
RABBITIZER_DEF_INSTR_ID(rsp, -0x07, swv, .operands={RAB_OPERAND_rsp_vt_elementlow, RAB_OPERAND_rsp_offset_rs})
@@ -0,0 +1,14 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP rs, IMM
RABBITIZER_DEF_INSTR_ID(rsp, 0x00, bltz, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true) // Branch on Less Than Zero
RABBITIZER_DEF_INSTR_ID(rsp, 0x01, bgez, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true) // Branch on Greater than or Equal to Zero
RABBITIZER_DEF_INSTR_ID(rsp, 0x10, bltzal, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .doesLink=true) // Branch on Less Than Zero and Link
RABBITIZER_DEF_INSTR_ID(rsp, 0x11, bgezal, .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .doesLink=true) // Branch on Greater Than or Equal to Zero and Link
// Pseudo-Instruction Unique IDs
RABBITIZER_DEF_INSTR_ID(rsp, -0x11, bal, .operands={RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .doesLink=true, .isPseudo=true, .architectureVersion=RABBITIZER_ARCHVERSION_MIPS_I) // Branch and Link
@@ -0,0 +1,49 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
// OP rd, rt, sa
RABBITIZER_DEF_INSTR_ID(rsp, 0x00, sll, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Shift word Left Logical
RABBITIZER_DEF_INSTR_ID(rsp, 0x02, srl, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Shift word Right Logical
RABBITIZER_DEF_INSTR_ID(rsp, 0x03, sra, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt, RAB_OPERAND_cpu_sa}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Shift word Right Arithmetic
// OP rd, rt, rs
RABBITIZER_DEF_INSTR_ID(rsp, 0x04, sllv, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Shift word Left Logical Variable
RABBITIZER_DEF_INSTR_ID(rsp, 0x06, srlv, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Shift word Right Logical Variable
RABBITIZER_DEF_INSTR_ID(rsp, 0x07, srav, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt, RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Shift word Right Arithmetic Variable
// OP rs
RABBITIZER_DEF_INSTR_ID(rsp, 0x08, jr, .operands={RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .isJump=true) // Jump Register
RABBITIZER_DEF_INSTR_ID(rsp, 0x09, jalr, .operands={RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .isJump=true, .modifiesRd=true, .doesLink=true) // Jump And Link Register
// OP rd, rs
RABBITIZER_DEF_INSTR_ID_ALTNAME(rsp, -0x09, jalr_rd, jalr, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .isJump=true, .modifiesRd=true, .doesLink=true) // Jump And Link Register // Special case for rd != 31
// OP rd, rs, rt
RABBITIZER_DEF_INSTR_ID(rsp, 0x0A, movz, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // MOVe conditional on Zero
RABBITIZER_DEF_INSTR_ID(rsp, 0x0B, movn, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // MOVe conditional on Not zero
RABBITIZER_DEF_INSTR_ID(rsp, 0x20, add, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .notEmitedByCompilers=true) // ADD word
RABBITIZER_DEF_INSTR_ID(rsp, 0x21, addu, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // ADD Unsigned word
RABBITIZER_DEF_INSTR_ID(rsp, 0x22, sub, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Subtract word
RABBITIZER_DEF_INSTR_ID(rsp, 0x23, subu, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // SUBtract Unsigned word
RABBITIZER_DEF_INSTR_ID(rsp, 0x24, and, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // AND
RABBITIZER_DEF_INSTR_ID(rsp, 0x25, or, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // OR
RABBITIZER_DEF_INSTR_ID(rsp, 0x26, xor, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // eXclusive OR
RABBITIZER_DEF_INSTR_ID(rsp, 0x27, nor, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Not OR
RABBITIZER_DEF_INSTR_ID(rsp, 0x2A, slt, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Set on Less Than
RABBITIZER_DEF_INSTR_ID(rsp, 0x2B, sltu, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Set on Less Than Unsigned
// OP code
RABBITIZER_DEF_INSTR_ID(rsp, 0x0D, break, .operands={RAB_OPERAND_cpu_code}, .instrType=RABBITIZER_INSTR_TYPE_R) // Break
// Pseudo-Instruction Unique IDs
// OP
RABBITIZER_DEF_INSTR_ID(rsp, -0x01, nop, .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_R) // No OPeration
// OP rd, rs
RABBITIZER_DEF_INSTR_ID(rsp, -0x25, move, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Move
RABBITIZER_DEF_INSTR_ID(rsp, -0x27, not, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true) // Not
// OP rd, rt
RABBITIZER_DEF_INSTR_ID(rsp, -0x23, negu, .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true)
@@ -0,0 +1,25 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RAB_DEF_OPERAND(cpu, rs)
RAB_DEF_OPERAND(cpu, rt)
RAB_DEF_OPERAND(cpu, rd)
RAB_DEF_OPERAND(cpu, sa)
RAB_DEF_OPERAND(cpu, zero) // $zero
// RAB_DEF_OPERAND(cpu, function)
RAB_DEF_OPERAND(cpu, cop0d)
RAB_DEF_OPERAND(cpu, fs)
RAB_DEF_OPERAND(cpu, ft)
RAB_DEF_OPERAND(cpu, fd)
RAB_DEF_OPERAND(cpu, cop1cs) // Coprocessor 1 control fs
RAB_DEF_OPERAND(cpu, cop2t)
RAB_DEF_OPERAND(cpu, op)
RAB_DEF_OPERAND(cpu, code)
RAB_DEF_OPERAND(cpu, code_lower)
RAB_DEF_OPERAND(cpu, copraw)
RAB_DEF_OPERAND(cpu, label)
RAB_DEF_OPERAND(cpu, immediate)
RAB_DEF_OPERAND(cpu, branch_target_label)
// composed/aliased operands
RAB_DEF_OPERAND(cpu, immediate_base)
@@ -0,0 +1,33 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RAB_DEF_OPERAND(r5900, I)
RAB_DEF_OPERAND(r5900, Q)
RAB_DEF_OPERAND(r5900, R)
RAB_DEF_OPERAND(r5900, ACC)
RAB_DEF_OPERAND(r5900, ACCxyzw)
RAB_DEF_OPERAND(r5900, vfs)
RAB_DEF_OPERAND(r5900, vft)
RAB_DEF_OPERAND(r5900, vfd)
RAB_DEF_OPERAND(r5900, vfsxyzw)
RAB_DEF_OPERAND(r5900, vftxyzw)
RAB_DEF_OPERAND(r5900, vfdxyzw)
RAB_DEF_OPERAND(r5900, vfsn)
RAB_DEF_OPERAND(r5900, vftn)
RAB_DEF_OPERAND(r5900, vfdn)
RAB_DEF_OPERAND(r5900, vfsl)
RAB_DEF_OPERAND(r5900, vftl)
RAB_DEF_OPERAND(r5900, vfdl)
RAB_DEF_OPERAND(r5900, vfsm)
RAB_DEF_OPERAND(r5900, vftm)
RAB_DEF_OPERAND(r5900, vfdm)
RAB_DEF_OPERAND(r5900, vis)
RAB_DEF_OPERAND(r5900, vit)
RAB_DEF_OPERAND(r5900, vid)
RAB_DEF_OPERAND(r5900, vis_predecr)
RAB_DEF_OPERAND(r5900, vit_predecr)
RAB_DEF_OPERAND(r5900, vid_predecr)
RAB_DEF_OPERAND(r5900, vis_postincr)
RAB_DEF_OPERAND(r5900, vit_postincr)
RAB_DEF_OPERAND(r5900, vid_postincr)
RAB_DEF_OPERAND(r5900, immediate5)
@@ -0,0 +1,24 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RAB_DEF_OPERAND(rsp, rs)
RAB_DEF_OPERAND(rsp, rt)
RAB_DEF_OPERAND(rsp, rd)
RAB_DEF_OPERAND(rsp, cop0d)
RAB_DEF_OPERAND(rsp, cop2t)
RAB_DEF_OPERAND(rsp, cop2cd) // Coprocessor 2 control rd
RAB_DEF_OPERAND(rsp, vs)
RAB_DEF_OPERAND(rsp, vt)
RAB_DEF_OPERAND(rsp, vd)
// RAB_DEF_OPERAND(rsp, elementhigh)
// RAB_DEF_OPERAND(rsp, elementlow)
// RAB_DEF_OPERAND(rsp, index)
// RAB_DEF_OPERAND(rsp, offset)
// composed/aliased operands
RAB_DEF_OPERAND(rsp, vt_elementhigh)
RAB_DEF_OPERAND(rsp, vt_elementlow)
RAB_DEF_OPERAND(rsp, vd_de)
RAB_DEF_OPERAND(rsp, vs_index)
RAB_DEF_OPERAND(rsp, offset_rs)
RAB_DEF_OPERAND(rsp, immediate_base)
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG_NODOLLAR(COP0, Index, 0),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Random, 1),
RABBITIZER_DEF_REG_NODOLLAR(COP0, EntryLo0, 2),
RABBITIZER_DEF_REG_NODOLLAR(COP0, EntryLo1, 3),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Context, 4),
RABBITIZER_DEF_REG_NODOLLAR(COP0, PageMask, 5),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Wired, 6),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Reserved07, 7),
RABBITIZER_DEF_REG_NODOLLAR(COP0, BadVaddr, 8),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Count, 9),
RABBITIZER_DEF_REG_NODOLLAR(COP0, EntryHi, 10),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Compare, 11),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Status, 12),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Cause, 13),
RABBITIZER_DEF_REG_NODOLLAR(COP0, EPC, 14),
RABBITIZER_DEF_REG_NODOLLAR(COP0, PRevID, 15),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Config, 16),
RABBITIZER_DEF_REG_NODOLLAR(COP0, LLAddr, 17),
RABBITIZER_DEF_REG_NODOLLAR(COP0, WatchLo, 18),
RABBITIZER_DEF_REG_NODOLLAR(COP0, WatchHi, 19),
RABBITIZER_DEF_REG_NODOLLAR(COP0, XContext, 20),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Reserved21, 21),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Reserved22, 22),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Reserved23, 23),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Reserved24, 24),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Reserved25, 25),
RABBITIZER_DEF_REG_NODOLLAR(COP0, PErr, 26),
RABBITIZER_DEF_REG_NODOLLAR(COP0, CacheErr, 27),
RABBITIZER_DEF_REG_NODOLLAR(COP0, TagLo, 28),
RABBITIZER_DEF_REG_NODOLLAR(COP0, TagHi, 29),
RABBITIZER_DEF_REG_NODOLLAR(COP0, ErrorEPC, 30),
RABBITIZER_DEF_REG_NODOLLAR(COP0, Reserved31, 31),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(COP1_CONTROL, 0, 0),
RABBITIZER_DEF_REG(COP1_CONTROL, 1, 1),
RABBITIZER_DEF_REG(COP1_CONTROL, 2, 2),
RABBITIZER_DEF_REG(COP1_CONTROL, 3, 3),
RABBITIZER_DEF_REG(COP1_CONTROL, 4, 4),
RABBITIZER_DEF_REG(COP1_CONTROL, 5, 5),
RABBITIZER_DEF_REG(COP1_CONTROL, 6, 6),
RABBITIZER_DEF_REG(COP1_CONTROL, 7, 7),
RABBITIZER_DEF_REG(COP1_CONTROL, 8, 8),
RABBITIZER_DEF_REG(COP1_CONTROL, 9, 9),
RABBITIZER_DEF_REG(COP1_CONTROL, 10, 10),
RABBITIZER_DEF_REG(COP1_CONTROL, 11, 11),
RABBITIZER_DEF_REG(COP1_CONTROL, 12, 12),
RABBITIZER_DEF_REG(COP1_CONTROL, 13, 13),
RABBITIZER_DEF_REG(COP1_CONTROL, 14, 14),
RABBITIZER_DEF_REG(COP1_CONTROL, 15, 15),
RABBITIZER_DEF_REG(COP1_CONTROL, 16, 16),
RABBITIZER_DEF_REG(COP1_CONTROL, 17, 17),
RABBITIZER_DEF_REG(COP1_CONTROL, 18, 18),
RABBITIZER_DEF_REG(COP1_CONTROL, 19, 19),
RABBITIZER_DEF_REG(COP1_CONTROL, 20, 20),
RABBITIZER_DEF_REG(COP1_CONTROL, 21, 21),
RABBITIZER_DEF_REG(COP1_CONTROL, 22, 22),
RABBITIZER_DEF_REG(COP1_CONTROL, 23, 23),
RABBITIZER_DEF_REG(COP1_CONTROL, 24, 24),
RABBITIZER_DEF_REG(COP1_CONTROL, 25, 25),
RABBITIZER_DEF_REG(COP1_CONTROL, 26, 26),
RABBITIZER_DEF_REG(COP1_CONTROL, 27, 27),
RABBITIZER_DEF_REG(COP1_CONTROL, 28, 28),
RABBITIZER_DEF_REG(COP1_CONTROL, 29, 29),
RABBITIZER_DEF_REG(COP1_CONTROL, 30, 30),
RABBITIZER_DEF_REG(COP1_CONTROL, FpcCsr, 31),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(COP1_N32, fv0, f0),
RABBITIZER_DEF_REG(COP1_N32, ft14, f1),
RABBITIZER_DEF_REG(COP1_N32, fv1, f2),
RABBITIZER_DEF_REG(COP1_N32, ft15, f3),
RABBITIZER_DEF_REG(COP1_N32, ft0, f4),
RABBITIZER_DEF_REG(COP1_N32, ft1, f5),
RABBITIZER_DEF_REG(COP1_N32, ft2, f6),
RABBITIZER_DEF_REG(COP1_N32, ft3, f7),
RABBITIZER_DEF_REG(COP1_N32, ft4, f8),
RABBITIZER_DEF_REG(COP1_N32, ft5, f9),
RABBITIZER_DEF_REG(COP1_N32, ft6, f10),
RABBITIZER_DEF_REG(COP1_N32, ft7, f11),
RABBITIZER_DEF_REG(COP1_N32, fa0, f12),
RABBITIZER_DEF_REG(COP1_N32, fa1, f13),
RABBITIZER_DEF_REG(COP1_N32, fa2, f14),
RABBITIZER_DEF_REG(COP1_N32, fa3, f15),
RABBITIZER_DEF_REG(COP1_N32, fa4, f16),
RABBITIZER_DEF_REG(COP1_N32, fa5, f17),
RABBITIZER_DEF_REG(COP1_N32, fa6, f18),
RABBITIZER_DEF_REG(COP1_N32, fa7, f19),
RABBITIZER_DEF_REG(COP1_N32, fs0, f20),
RABBITIZER_DEF_REG(COP1_N32, ft8, f21),
RABBITIZER_DEF_REG(COP1_N32, fs1, f22),
RABBITIZER_DEF_REG(COP1_N32, ft9, f23),
RABBITIZER_DEF_REG(COP1_N32, fs2, f24),
RABBITIZER_DEF_REG(COP1_N32, ft10, f25),
RABBITIZER_DEF_REG(COP1_N32, fs3, f26),
RABBITIZER_DEF_REG(COP1_N32, ft11, f27),
RABBITIZER_DEF_REG(COP1_N32, fs4, f28),
RABBITIZER_DEF_REG(COP1_N32, ft12, f29),
RABBITIZER_DEF_REG(COP1_N32, fs5, f30),
RABBITIZER_DEF_REG(COP1_N32, ft13, f31),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(COP1_N64, fv0, f0),
RABBITIZER_DEF_REG(COP1_N64, ft12, f1),
RABBITIZER_DEF_REG(COP1_N64, fv1, f2),
RABBITIZER_DEF_REG(COP1_N64, ft13, f3),
RABBITIZER_DEF_REG(COP1_N64, ft0, f4),
RABBITIZER_DEF_REG(COP1_N64, ft1, f5),
RABBITIZER_DEF_REG(COP1_N64, ft2, f6),
RABBITIZER_DEF_REG(COP1_N64, ft3, f7),
RABBITIZER_DEF_REG(COP1_N64, ft4, f8),
RABBITIZER_DEF_REG(COP1_N64, ft5, f9),
RABBITIZER_DEF_REG(COP1_N64, ft6, f10),
RABBITIZER_DEF_REG(COP1_N64, ft7, f11),
RABBITIZER_DEF_REG(COP1_N64, fa0, f12),
RABBITIZER_DEF_REG(COP1_N64, fa1, f13),
RABBITIZER_DEF_REG(COP1_N64, fa2, f14),
RABBITIZER_DEF_REG(COP1_N64, fa3, f15),
RABBITIZER_DEF_REG(COP1_N64, fa4, f16),
RABBITIZER_DEF_REG(COP1_N64, fa5, f17),
RABBITIZER_DEF_REG(COP1_N64, fa6, f18),
RABBITIZER_DEF_REG(COP1_N64, fa7, f19),
RABBITIZER_DEF_REG(COP1_N64, ft8, f20),
RABBITIZER_DEF_REG(COP1_N64, ft9, f21),
RABBITIZER_DEF_REG(COP1_N64, ft10, f22),
RABBITIZER_DEF_REG(COP1_N64, ft11, f23),
RABBITIZER_DEF_REG(COP1_N64, fs0, f24),
RABBITIZER_DEF_REG(COP1_N64, fs1, f25),
RABBITIZER_DEF_REG(COP1_N64, fs2, f26),
RABBITIZER_DEF_REG(COP1_N64, fs3, f27),
RABBITIZER_DEF_REG(COP1_N64, fs4, f28),
RABBITIZER_DEF_REG(COP1_N64, fs5, f29),
RABBITIZER_DEF_REG(COP1_N64, fs6, f30),
RABBITIZER_DEF_REG(COP1_N64, fs7, f31),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(COP1_O32, fv0, f0),
RABBITIZER_DEF_REG(COP1_O32, fv0f, f1),
RABBITIZER_DEF_REG(COP1_O32, fv1, f2),
RABBITIZER_DEF_REG(COP1_O32, fv1f, f3),
RABBITIZER_DEF_REG(COP1_O32, ft0, f4),
RABBITIZER_DEF_REG(COP1_O32, ft0f, f5),
RABBITIZER_DEF_REG(COP1_O32, ft1, f6),
RABBITIZER_DEF_REG(COP1_O32, ft1f, f7),
RABBITIZER_DEF_REG(COP1_O32, ft2, f8),
RABBITIZER_DEF_REG(COP1_O32, ft2f, f9),
RABBITIZER_DEF_REG(COP1_O32, ft3, f10),
RABBITIZER_DEF_REG(COP1_O32, ft3f, f11),
RABBITIZER_DEF_REG(COP1_O32, fa0, f12),
RABBITIZER_DEF_REG(COP1_O32, fa0f, f13),
RABBITIZER_DEF_REG(COP1_O32, fa1, f14),
RABBITIZER_DEF_REG(COP1_O32, fa1f, f15),
RABBITIZER_DEF_REG(COP1_O32, ft4, f16),
RABBITIZER_DEF_REG(COP1_O32, ft4f, f17),
RABBITIZER_DEF_REG(COP1_O32, ft5, f18),
RABBITIZER_DEF_REG(COP1_O32, ft5f, f19),
RABBITIZER_DEF_REG(COP1_O32, fs0, f20),
RABBITIZER_DEF_REG(COP1_O32, fs0f, f21),
RABBITIZER_DEF_REG(COP1_O32, fs1, f22),
RABBITIZER_DEF_REG(COP1_O32, fs1f, f23),
RABBITIZER_DEF_REG(COP1_O32, fs2, f24),
RABBITIZER_DEF_REG(COP1_O32, fs2f, f25),
RABBITIZER_DEF_REG(COP1_O32, fs3, f26),
RABBITIZER_DEF_REG(COP1_O32, fs3f, f27),
RABBITIZER_DEF_REG(COP1_O32, fs4, f28),
RABBITIZER_DEF_REG(COP1_O32, fs4f, f29),
RABBITIZER_DEF_REG(COP1_O32, fs5, f30),
RABBITIZER_DEF_REG(COP1_O32, fs5f, f31),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(COP2, 0, 0),
RABBITIZER_DEF_REG(COP2, 1, 1),
RABBITIZER_DEF_REG(COP2, 2, 2),
RABBITIZER_DEF_REG(COP2, 3, 3),
RABBITIZER_DEF_REG(COP2, 4, 4),
RABBITIZER_DEF_REG(COP2, 5, 5),
RABBITIZER_DEF_REG(COP2, 6, 6),
RABBITIZER_DEF_REG(COP2, 7, 7),
RABBITIZER_DEF_REG(COP2, 8, 8),
RABBITIZER_DEF_REG(COP2, 9, 9),
RABBITIZER_DEF_REG(COP2, 10, 10),
RABBITIZER_DEF_REG(COP2, 11, 11),
RABBITIZER_DEF_REG(COP2, 12, 12),
RABBITIZER_DEF_REG(COP2, 13, 13),
RABBITIZER_DEF_REG(COP2, 14, 14),
RABBITIZER_DEF_REG(COP2, 15, 15),
RABBITIZER_DEF_REG(COP2, 16, 16),
RABBITIZER_DEF_REG(COP2, 17, 17),
RABBITIZER_DEF_REG(COP2, 18, 18),
RABBITIZER_DEF_REG(COP2, 19, 19),
RABBITIZER_DEF_REG(COP2, 20, 20),
RABBITIZER_DEF_REG(COP2, 21, 21),
RABBITIZER_DEF_REG(COP2, 22, 22),
RABBITIZER_DEF_REG(COP2, 23, 23),
RABBITIZER_DEF_REG(COP2, 24, 24),
RABBITIZER_DEF_REG(COP2, 25, 25),
RABBITIZER_DEF_REG(COP2, 26, 26),
RABBITIZER_DEF_REG(COP2, 27, 27),
RABBITIZER_DEF_REG(COP2, 28, 28),
RABBITIZER_DEF_REG(COP2, 29, 29),
RABBITIZER_DEF_REG(COP2, 30, 30),
RABBITIZER_DEF_REG(COP2, 31, 31),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(GPR_N32, zero, 0),
RABBITIZER_DEF_REG(GPR_N32, at, 1),
RABBITIZER_DEF_REG(GPR_N32, v0, 2),
RABBITIZER_DEF_REG(GPR_N32, v1, 3),
RABBITIZER_DEF_REG(GPR_N32, a0, 4),
RABBITIZER_DEF_REG(GPR_N32, a1, 5),
RABBITIZER_DEF_REG(GPR_N32, a2, 6),
RABBITIZER_DEF_REG(GPR_N32, a3, 7),
RABBITIZER_DEF_REG(GPR_N32, a4, 8),
RABBITIZER_DEF_REG(GPR_N32, a5, 9),
RABBITIZER_DEF_REG(GPR_N32, a6, 10),
RABBITIZER_DEF_REG(GPR_N32, a7, 11),
RABBITIZER_DEF_REG(GPR_N32, t0, 12),
RABBITIZER_DEF_REG(GPR_N32, t1, 13),
RABBITIZER_DEF_REG(GPR_N32, t2, 14),
RABBITIZER_DEF_REG(GPR_N32, t3, 15),
RABBITIZER_DEF_REG(GPR_N32, s0, 16),
RABBITIZER_DEF_REG(GPR_N32, s1, 17),
RABBITIZER_DEF_REG(GPR_N32, s2, 18),
RABBITIZER_DEF_REG(GPR_N32, s3, 19),
RABBITIZER_DEF_REG(GPR_N32, s4, 20),
RABBITIZER_DEF_REG(GPR_N32, s5, 21),
RABBITIZER_DEF_REG(GPR_N32, s6, 22),
RABBITIZER_DEF_REG(GPR_N32, s7, 23),
RABBITIZER_DEF_REG(GPR_N32, t8, 24),
RABBITIZER_DEF_REG(GPR_N32, t9, 25),
RABBITIZER_DEF_REG(GPR_N32, k0, 26),
RABBITIZER_DEF_REG(GPR_N32, k1, 27),
RABBITIZER_DEF_REG(GPR_N32, gp, 28),
RABBITIZER_DEF_REG(GPR_N32, sp, 29),
RABBITIZER_DEF_REG(GPR_N32, fp, 30),
RABBITIZER_DEF_REG(GPR_N32, ra, 31),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(GPR_O32, zero, 0),
RABBITIZER_DEF_REG(GPR_O32, at, 1),
RABBITIZER_DEF_REG(GPR_O32, v0, 2),
RABBITIZER_DEF_REG(GPR_O32, v1, 3),
RABBITIZER_DEF_REG(GPR_O32, a0, 4),
RABBITIZER_DEF_REG(GPR_O32, a1, 5),
RABBITIZER_DEF_REG(GPR_O32, a2, 6),
RABBITIZER_DEF_REG(GPR_O32, a3, 7),
RABBITIZER_DEF_REG(GPR_O32, t0, 8),
RABBITIZER_DEF_REG(GPR_O32, t1, 9),
RABBITIZER_DEF_REG(GPR_O32, t2, 10),
RABBITIZER_DEF_REG(GPR_O32, t3, 11),
RABBITIZER_DEF_REG(GPR_O32, t4, 12),
RABBITIZER_DEF_REG(GPR_O32, t5, 13),
RABBITIZER_DEF_REG(GPR_O32, t6, 14),
RABBITIZER_DEF_REG(GPR_O32, t7, 15),
RABBITIZER_DEF_REG(GPR_O32, s0, 16),
RABBITIZER_DEF_REG(GPR_O32, s1, 17),
RABBITIZER_DEF_REG(GPR_O32, s2, 18),
RABBITIZER_DEF_REG(GPR_O32, s3, 19),
RABBITIZER_DEF_REG(GPR_O32, s4, 20),
RABBITIZER_DEF_REG(GPR_O32, s5, 21),
RABBITIZER_DEF_REG(GPR_O32, s6, 22),
RABBITIZER_DEF_REG(GPR_O32, s7, 23),
RABBITIZER_DEF_REG(GPR_O32, t8, 24),
RABBITIZER_DEF_REG(GPR_O32, t9, 25),
RABBITIZER_DEF_REG(GPR_O32, k0, 26),
RABBITIZER_DEF_REG(GPR_O32, k1, 27),
RABBITIZER_DEF_REG(GPR_O32, gp, 28),
RABBITIZER_DEF_REG(GPR_O32, sp, 29),
RABBITIZER_DEF_REG(GPR_O32, fp, 30),
RABBITIZER_DEF_REG(GPR_O32, ra, 31),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(R5900_VF, vf0, 0),
RABBITIZER_DEF_REG(R5900_VF, vf1, 1),
RABBITIZER_DEF_REG(R5900_VF, vf2, 2),
RABBITIZER_DEF_REG(R5900_VF, vf3, 3),
RABBITIZER_DEF_REG(R5900_VF, vf4, 4),
RABBITIZER_DEF_REG(R5900_VF, vf5, 5),
RABBITIZER_DEF_REG(R5900_VF, vf6, 6),
RABBITIZER_DEF_REG(R5900_VF, vf7, 7),
RABBITIZER_DEF_REG(R5900_VF, vf8, 8),
RABBITIZER_DEF_REG(R5900_VF, vf9, 9),
RABBITIZER_DEF_REG(R5900_VF, vf10, 10),
RABBITIZER_DEF_REG(R5900_VF, vf11, 11),
RABBITIZER_DEF_REG(R5900_VF, vf12, 12),
RABBITIZER_DEF_REG(R5900_VF, vf13, 13),
RABBITIZER_DEF_REG(R5900_VF, vf14, 14),
RABBITIZER_DEF_REG(R5900_VF, vf15, 15),
RABBITIZER_DEF_REG(R5900_VF, vf16, 16),
RABBITIZER_DEF_REG(R5900_VF, vf17, 17),
RABBITIZER_DEF_REG(R5900_VF, vf18, 18),
RABBITIZER_DEF_REG(R5900_VF, vf19, 19),
RABBITIZER_DEF_REG(R5900_VF, vf20, 20),
RABBITIZER_DEF_REG(R5900_VF, vf21, 21),
RABBITIZER_DEF_REG(R5900_VF, vf22, 22),
RABBITIZER_DEF_REG(R5900_VF, vf23, 23),
RABBITIZER_DEF_REG(R5900_VF, vf24, 24),
RABBITIZER_DEF_REG(R5900_VF, vf25, 25),
RABBITIZER_DEF_REG(R5900_VF, vf26, 26),
RABBITIZER_DEF_REG(R5900_VF, vf27, 27),
RABBITIZER_DEF_REG(R5900_VF, vf28, 28),
RABBITIZER_DEF_REG(R5900_VF, vf29, 29),
RABBITIZER_DEF_REG(R5900_VF, vf30, 30),
RABBITIZER_DEF_REG(R5900_VF, vf31, 31),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(R5900_VI, vi0, 0),
RABBITIZER_DEF_REG(R5900_VI, vi1, 1),
RABBITIZER_DEF_REG(R5900_VI, vi2, 2),
RABBITIZER_DEF_REG(R5900_VI, vi3, 3),
RABBITIZER_DEF_REG(R5900_VI, vi4, 4),
RABBITIZER_DEF_REG(R5900_VI, vi5, 5),
RABBITIZER_DEF_REG(R5900_VI, vi6, 6),
RABBITIZER_DEF_REG(R5900_VI, vi7, 7),
RABBITIZER_DEF_REG(R5900_VI, vi8, 8),
RABBITIZER_DEF_REG(R5900_VI, vi9, 9),
RABBITIZER_DEF_REG(R5900_VI, vi10, 10),
RABBITIZER_DEF_REG(R5900_VI, vi11, 11),
RABBITIZER_DEF_REG(R5900_VI, vi12, 12),
RABBITIZER_DEF_REG(R5900_VI, vi13, 13),
RABBITIZER_DEF_REG(R5900_VI, vi14, 14),
RABBITIZER_DEF_REG(R5900_VI, vi15, 15),
RABBITIZER_DEF_REG(R5900_VI, vi16, 16),
RABBITIZER_DEF_REG(R5900_VI, vi17, 17),
RABBITIZER_DEF_REG(R5900_VI, vi18, 18),
RABBITIZER_DEF_REG(R5900_VI, vi19, 19),
RABBITIZER_DEF_REG(R5900_VI, vi20, 20),
RABBITIZER_DEF_REG(R5900_VI, vi21, 21),
RABBITIZER_DEF_REG(R5900_VI, vi22, 22),
RABBITIZER_DEF_REG(R5900_VI, vi23, 23),
RABBITIZER_DEF_REG(R5900_VI, vi24, 24),
RABBITIZER_DEF_REG(R5900_VI, vi25, 25),
RABBITIZER_DEF_REG(R5900_VI, vi26, 26),
RABBITIZER_DEF_REG(R5900_VI, vi27, 27),
RABBITIZER_DEF_REG(R5900_VI, vi28, 28),
RABBITIZER_DEF_REG(R5900_VI, vi29, 29),
RABBITIZER_DEF_REG(R5900_VI, vi30, 30),
RABBITIZER_DEF_REG(R5900_VI, vi31, 31),
@@ -0,0 +1,19 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, SP_MEM_ADDR, 0),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, SP_DRAM_ADDR, 1),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, SP_RD_LEN, 2),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, SP_WR_LEN, 3),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, SP_STATUS, 4),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, SP_DMA_FULL, 5),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, SP_DMA_BUSY, 6),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, SP_SEMAPHORE, 7),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, DPC_START, 8),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, DPC_END, 9),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, DPC_CURRENT, 10),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, DPC_STATUS, 11),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, DPC_CLOCK, 12),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, DPC_BUFBUSY, 13),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, DPC_PIPEBUSY, 14),
RABBITIZER_DEF_REG_NODOLLAR(RSP_COP0, DPC_TMEM, 15),
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_REG(RSP_COP2, 0, 0),
RABBITIZER_DEF_REG(RSP_COP2, 1, 1),
RABBITIZER_DEF_REG(RSP_COP2, 2, 2),
RABBITIZER_DEF_REG(RSP_COP2, 3, 3),
RABBITIZER_DEF_REG(RSP_COP2, 4, 4),
RABBITIZER_DEF_REG(RSP_COP2, 5, 5),
RABBITIZER_DEF_REG(RSP_COP2, 6, 6),
RABBITIZER_DEF_REG(RSP_COP2, 7, 7),
RABBITIZER_DEF_REG(RSP_COP2, 8, 8),
RABBITIZER_DEF_REG(RSP_COP2, 9, 9),
RABBITIZER_DEF_REG(RSP_COP2, 10, 10),
RABBITIZER_DEF_REG(RSP_COP2, 11, 11),
RABBITIZER_DEF_REG(RSP_COP2, 12, 12),
RABBITIZER_DEF_REG(RSP_COP2, 13, 13),
RABBITIZER_DEF_REG(RSP_COP2, 14, 14),
RABBITIZER_DEF_REG(RSP_COP2, 15, 15),
RABBITIZER_DEF_REG(RSP_COP2, 16, 16),
RABBITIZER_DEF_REG(RSP_COP2, 17, 17),
RABBITIZER_DEF_REG(RSP_COP2, 18, 18),
RABBITIZER_DEF_REG(RSP_COP2, 19, 19),
RABBITIZER_DEF_REG(RSP_COP2, 20, 20),
RABBITIZER_DEF_REG(RSP_COP2, 21, 21),
RABBITIZER_DEF_REG(RSP_COP2, 22, 22),
RABBITIZER_DEF_REG(RSP_COP2, 23, 23),
RABBITIZER_DEF_REG(RSP_COP2, 24, 24),
RABBITIZER_DEF_REG(RSP_COP2, 25, 25),
RABBITIZER_DEF_REG(RSP_COP2, 26, 26),
RABBITIZER_DEF_REG(RSP_COP2, 27, 27),
RABBITIZER_DEF_REG(RSP_COP2, 28, 28),
RABBITIZER_DEF_REG(RSP_COP2, 29, 29),
RABBITIZER_DEF_REG(RSP_COP2, 30, 30),
RABBITIZER_DEF_REG(RSP_COP2, 31, 31),
Loaded 100 of 340 files, more files were not shown because too many files have changed in this diff. Show more