Add R3000GTE instruction set support (#31)

* initial gte setup

* starting to parse gte instructions

* R3000_GTE -> R3000GTE

* decode all the non-operand instructions

* remove printfs, whoops

* decode gte with operands

* cleanups

* bindings stuffs

* RabbitizerInstrId_isValid

* fix missing include
This commit is contained in:
Anghelo Carvajal 2023-04-29 23:07:07 -04:00 committed by GitHub
parent 89254307cc
commit 8237818ff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 1493 additions and 3 deletions

View File

@ -111,6 +111,7 @@ clean:
distclean: clean
$(RM) -rf dist *.egg-info .mypy_cache
$(RM) -rf $(TABLE_GENERATED)
$(RM) -rf $(DEP_FILES) $(TABLE_DEP_FILES)
$(RM) -rf target/
format:

View File

@ -93,6 +93,12 @@ See this crate at <https://crates.io/crates/rabbitizer>.
- Nintendo Ultra64 RSP Programmers Guide: <https://ultra64.ca/files/documentation/silicon-graphics/SGI_Nintendo_64_RSP_Programmers_Guide.pdf>
- N64brew Reality Signal Processor/CPU Core: <https://n64brew.dev/wiki/Reality_Signal_Processor/CPU_Core>
- R3000 GTE:
- PSYQ SDK headers: <https://github.com/FoxdieTeam/psyq_sdk/blob/master/psyq_4.4/INCLUDE/INLINE_A.H>
- no$psx documentation: <https://problemkaputt.de/psxspx-gte-opcode-summary.htm>
- no$psx documentation: <http://problemkaputt.de/psx-spx.htm#geometrytransformationenginegte>
- <http://www.raphnet.net/electronique/psx_adaptor/Playstation.txt>
- R5900:
- EmotionEngine instruction decoding: <https://psi-rockin.github.io/ps2tek/#eeinstructiondecoding>
- Official documentation from Toshiba: <https://wiki.qemu.org/images/2/2a/C790.pdf>

View File

@ -45,6 +45,11 @@ rsp_vs_index,
rsp_offset_rs,
rsp_immediate_base,
rsp_maybe_rd_rs,
r3000gte_sf,
r3000gte_mx,
r3000gte_v,
r3000gte_cv,
r3000gte_lm,
r5900_I,
r5900_Q,
r5900_R,

View File

@ -9,6 +9,7 @@ enum class OperandType {
#include "instructions/operands/RabbitizerOperandType_cpu.inc"
#include "instructions/operands/RabbitizerOperandType_rsp.inc"
#include "instructions/operands/RabbitizerOperandType_r3000gte.inc"
#include "instructions/operands/RabbitizerOperandType_r5900.inc"
RAB_DEF_OPERAND(ALL, MAX)

View File

@ -414,6 +414,50 @@ rsp_USERDEF_17,
rsp_USERDEF_18,
rsp_USERDEF_19,
rsp_MAX,
r3000gte_INVALID,
r3000gte_RTPS,
r3000gte_RTPT,
r3000gte_DPCL,
r3000gte_DPCS,
r3000gte_DPCT,
r3000gte_INTPL,
r3000gte_NCS,
r3000gte_NCT,
r3000gte_NCDS,
r3000gte_NCDT,
r3000gte_NCCS,
r3000gte_NCCT,
r3000gte_CDP,
r3000gte_CC,
r3000gte_NCLIP,
r3000gte_AVSZ3,
r3000gte_AVSZ4,
r3000gte_MVMVA,
r3000gte_SQR,
r3000gte_OP,
r3000gte_GPF,
r3000gte_GPL,
r3000gte_USERDEF_00,
r3000gte_USERDEF_01,
r3000gte_USERDEF_02,
r3000gte_USERDEF_03,
r3000gte_USERDEF_04,
r3000gte_USERDEF_05,
r3000gte_USERDEF_06,
r3000gte_USERDEF_07,
r3000gte_USERDEF_08,
r3000gte_USERDEF_09,
r3000gte_USERDEF_10,
r3000gte_USERDEF_11,
r3000gte_USERDEF_12,
r3000gte_USERDEF_13,
r3000gte_USERDEF_14,
r3000gte_USERDEF_15,
r3000gte_USERDEF_16,
r3000gte_USERDEF_17,
r3000gte_USERDEF_18,
r3000gte_USERDEF_19,
r3000gte_MAX,
r5900_INVALID,
r5900_lq,
r5900_sq,

View File

@ -12,6 +12,8 @@ enum class UniqueId {
#include "instructions/instr_id/RabbitizerInstrId_rsp.inc"
#include "instructions/instr_id/RabbitizerInstrId_r3000gte.inc"
#include "instructions/instr_id/RabbitizerInstrId_r5900.inc"
ALL_MAX = RABBITIZER_DEF_INSTR_ID(r5900, , MAX, )

View File

@ -1,6 +1,7 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-FileCopyrightText: © 2022-2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_INSTR_CATEGORY(CPU),
RABBITIZER_DEF_INSTR_CATEGORY(RSP), // N64
RABBITIZER_DEF_INSTR_CATEGORY(R3000GTE), // R3000 CPU with PS1's Geometry Transformation Engine extension
RABBITIZER_DEF_INSTR_CATEGORY(R5900), // PS2's Emotion Engine

View File

@ -9,6 +9,7 @@
typedef enum RabbitizerInstrCategory {
RABBITIZER_INSTRCAT_CPU,
RABBITIZER_INSTRCAT_RSP,
RABBITIZER_INSTRCAT_R3000GTE,
RABBITIZER_INSTRCAT_R5900,
RABBITIZER_INSTRCAT_MAX,
} RabbitizerInstrCategory;

View File

@ -414,6 +414,50 @@ RABBITIZER_INSTR_ID_rsp_USERDEF_17,
RABBITIZER_INSTR_ID_rsp_USERDEF_18,
RABBITIZER_INSTR_ID_rsp_USERDEF_19,
RABBITIZER_INSTR_ID_rsp_MAX,
RABBITIZER_INSTR_ID_r3000gte_INVALID,
RABBITIZER_INSTR_ID_r3000gte_RTPS,
RABBITIZER_INSTR_ID_r3000gte_RTPT,
RABBITIZER_INSTR_ID_r3000gte_DPCL,
RABBITIZER_INSTR_ID_r3000gte_DPCS,
RABBITIZER_INSTR_ID_r3000gte_DPCT,
RABBITIZER_INSTR_ID_r3000gte_INTPL,
RABBITIZER_INSTR_ID_r3000gte_NCS,
RABBITIZER_INSTR_ID_r3000gte_NCT,
RABBITIZER_INSTR_ID_r3000gte_NCDS,
RABBITIZER_INSTR_ID_r3000gte_NCDT,
RABBITIZER_INSTR_ID_r3000gte_NCCS,
RABBITIZER_INSTR_ID_r3000gte_NCCT,
RABBITIZER_INSTR_ID_r3000gte_CDP,
RABBITIZER_INSTR_ID_r3000gte_CC,
RABBITIZER_INSTR_ID_r3000gte_NCLIP,
RABBITIZER_INSTR_ID_r3000gte_AVSZ3,
RABBITIZER_INSTR_ID_r3000gte_AVSZ4,
RABBITIZER_INSTR_ID_r3000gte_MVMVA,
RABBITIZER_INSTR_ID_r3000gte_SQR,
RABBITIZER_INSTR_ID_r3000gte_OP,
RABBITIZER_INSTR_ID_r3000gte_GPF,
RABBITIZER_INSTR_ID_r3000gte_GPL,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_00,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_01,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_02,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_03,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_04,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_05,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_06,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_07,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_08,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_09,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_10,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_11,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_12,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_13,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_14,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_15,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_16,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_17,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_18,
RABBITIZER_INSTR_ID_r3000gte_USERDEF_19,
RABBITIZER_INSTR_ID_r3000gte_MAX,
RABBITIZER_INSTR_ID_r5900_INVALID,
RABBITIZER_INSTR_ID_r5900_lq,
RABBITIZER_INSTR_ID_r5900_sq,

View File

@ -12,6 +12,8 @@ typedef enum RabbitizerInstrId {
#include "instr_id/RabbitizerInstrId_rsp.inc"
#include "instr_id/RabbitizerInstrId_r3000gte.inc"
#include "instr_id/RabbitizerInstrId_r5900.inc"
RABBITIZER_INSTR_ID_ALL_MAX = RABBITIZER_DEF_INSTR_ID(r5900, , MAX, )

View File

@ -45,6 +45,11 @@ RAB_OPERAND_rsp_vs_index,
RAB_OPERAND_rsp_offset_rs,
RAB_OPERAND_rsp_immediate_base,
RAB_OPERAND_rsp_maybe_rd_rs,
RAB_OPERAND_r3000gte_sf,
RAB_OPERAND_r3000gte_mx,
RAB_OPERAND_r3000gte_v,
RAB_OPERAND_r3000gte_cv,
RAB_OPERAND_r3000gte_lm,
RAB_OPERAND_r5900_I,
RAB_OPERAND_r5900_Q,
RAB_OPERAND_r5900_R,

View File

@ -9,6 +9,7 @@ typedef enum RabbitizerOperandType {
#include "operands/RabbitizerOperandType_cpu.inc"
#include "operands/RabbitizerOperandType_rsp.inc"
#include "instructions/operands/RabbitizerOperandType_r3000gte.inc"
#include "operands/RabbitizerOperandType_r5900.inc"
RAB_DEF_OPERAND(ALL, MAX)

View File

@ -43,6 +43,11 @@ size_t RabbitizerOperandType_process_rsp_vs_index (const struct RabbitizerInstru
size_t RabbitizerOperandType_process_rsp_offset_rs (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_rsp_immediate_base (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_rsp_maybe_rd_rs (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_r3000gte_sf (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_r3000gte_mx (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_r3000gte_v (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_r3000gte_cv (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_r3000gte_lm (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_r5900_I (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_r5900_Q (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);
size_t RabbitizerOperandType_process_r5900_R (const struct RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength);

View File

@ -5,6 +5,7 @@
#include "operands/RabbitizerOperandType_cpu.inc"
#include "operands/RabbitizerOperandType_rsp.inc"
#include "instructions/operands/RabbitizerOperandType_r3000gte.inc"
#include "operands/RabbitizerOperandType_r5900.inc"
#undef RAB_DEF_OPERAND

View File

@ -28,10 +28,13 @@ typedef enum RabbitizerInstrType {
RABBITIZER_INSTR_TYPE_MAX,
} RabbitizerInstrType;
#define OPERAND_COUNT_MAX 5
// Please note the members of this struct may be renamed or removed without further notice.
// For consistent usage please use the functions instead
typedef struct RabbitizerInstrDescriptor {
RabbitizerOperandType operands[4];
RabbitizerOperandType operands[OPERAND_COUNT_MAX+1];
RabbitizerInstrType instrType;
RabbitizerInstrSuffix instrSuffix;

View File

@ -0,0 +1,61 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRUCTION_R3000GTE_H
#define RABBITIZER_INSTRUCTION_R3000GTE_H
#pragma once
#include "RabbitizerInstruction.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RAB_INSTR_R3000GTE_GET_FAKE_OPCODE(self) (SHIFTR((self)->word, 20, 5))
#define RAB_INSTR_R3000GTE_GET_sf(self) (SHIFTR((self)->word, 19, 1))
#define RAB_INSTR_R3000GTE_GET_mx(self) (SHIFTR((self)->word, 17, 2))
#define RAB_INSTR_R3000GTE_GET_v(self) (SHIFTR((self)->word, 15, 2))
#define RAB_INSTR_R3000GTE_GET_cv(self) (SHIFTR((self)->word, 13, 2))
#define RAB_INSTR_R3000GTE_GET_lm(self) (SHIFTR((self)->word, 10, 1))
#define RAB_INSTR_R3000GTE_PACK_FAKE_OPCODE(word, value) (BITREPACK((word), (value), 20, 5))
#define RAB_INSTR_R3000GTE_PACK_sf(word, value) (BITREPACK((word), (value), 19, 1))
#define RAB_INSTR_R3000GTE_PACK_mx(word, value) (BITREPACK((word), (value), 17, 2))
#define RAB_INSTR_R3000GTE_PACK_v(word, value) (BITREPACK((word), (value), 15, 2))
#define RAB_INSTR_R3000GTE_PACK_cv(word, value) (BITREPACK((word), (value), 13, 2))
#define RAB_INSTR_R3000GTE_PACK_lm(word, value) (BITREPACK((word), (value), 10, 1))
NON_NULL(1)
void RabbitizerInstructionR3000GTE_init(RabbitizerInstruction *self, uint32_t word, uint32_t vram);
NON_NULL(1)
void RabbitizerInstructionR3000GTE_destroy(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR3000GTE_processUniqueId_Normal(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR3000GTE_processUniqueId_Special(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR3000GTE_processUniqueId_Regimm(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor0(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor1(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor2(RabbitizerInstruction *self);
NON_NULL(1)
void RabbitizerInstructionR3000GTE_processUniqueId(RabbitizerInstruction *self);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,96 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RABBITIZER_DEF_INSTR_ID(
r3000gte, , INVALID,
.operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate},
.instrType=RABBITIZER_INSTR_TYPE_UNKNOWN
)
#include "r3000gte/r3000gte_cop2_gte.inc"
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_00,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_01,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_02,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_03,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_04,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_05,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_06,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_07,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_08,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_09,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_10,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_11,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_12,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_13,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_14,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_15,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_16,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_17,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_18,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , USERDEF_19,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, , MAX,
.operands={0}
)

View File

@ -0,0 +1,114 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
/* Indexed by "function" operand */
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x01, RTPS,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x30, RTPT,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x29, DPCL,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x10, DPCS,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x2A, DPCT,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x11, INTPL,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x1E, NCS,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x20, NCT,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x13, NCDS,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x16, NCDT,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x1B, NCCS,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x3F, NCCT,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x14, CDP,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x1C, CC,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x06, NCLIP,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x2D, AVSZ3,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x2E, AVSZ4,
.operands={0}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x12, MVMVA,
.operands={RAB_OPERAND_r3000gte_sf, RAB_OPERAND_r3000gte_mx, RAB_OPERAND_r3000gte_v, RAB_OPERAND_r3000gte_cv, RAB_OPERAND_r3000gte_lm}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x28, SQR,
.operands={RAB_OPERAND_r3000gte_sf}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x0C, OP,
.operands={RAB_OPERAND_r3000gte_sf}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x3D, GPF,
.operands={RAB_OPERAND_r3000gte_sf}
)
RABBITIZER_DEF_INSTR_ID(
r3000gte, 0x3E, GPL,
.operands={RAB_OPERAND_r3000gte_sf}
)

View File

@ -0,0 +1,8 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
RAB_DEF_OPERAND(r3000gte, sf)
RAB_DEF_OPERAND(r3000gte, mx)
RAB_DEF_OPERAND(r3000gte, v)
RAB_DEF_OPERAND(r3000gte, cv)
RAB_DEF_OPERAND(r3000gte, lm)

View File

@ -17,6 +17,7 @@
#include "instructions/RabbitizerRegisterDescriptor.h"
#include "instructions/RabbitizerInstruction.h"
#include "instructions/RabbitizerInstructionRsp.h"
#include "instructions/RabbitizerInstructionR3000GTE.h"
#include "instructions/RabbitizerInstructionR5900.h"
#include "analysis/RabbitizerTrackedRegisterState.h"

View File

@ -11,6 +11,7 @@ from .Enum import Enum
class InstrCategory:
CPU: Enum
RSP: Enum
R3000GTE: Enum
R5900: Enum
MAX: Enum

View File

@ -377,6 +377,31 @@ class InstrId:
rsp_negu: Enum
rsp_MAX: Enum
r3000gte_INVALID: Enum
r3000gte_RTPS: Enum
r3000gte_RTPT: Enum
r3000gte_DPCL: Enum
r3000gte_DPCS: Enum
r3000gte_DPCT: Enum
r3000gte_INTPL: Enum
r3000gte_NCS: Enum
r3000gte_NCT: Enum
r3000gte_NCDS: Enum
r3000gte_NCDT: Enum
r3000gte_NCCS: Enum
r3000gte_NCCT: Enum
r3000gte_CDP: Enum
r3000gte_CC: Enum
r3000gte_NCLIP: Enum
r3000gte_AVSZ3: Enum
r3000gte_AVSZ4: Enum
r3000gte_MVMVA: Enum
r3000gte_SQR: Enum
r3000gte_OP: Enum
r3000gte_GPF: Enum
r3000gte_GPL: Enum
r3000gte_MAX: Enum
r5900_INVALID: Enum
r5900_lq: Enum
r5900_sq: Enum

View File

@ -49,6 +49,12 @@ class OperandType:
rsp_immediate_base: Enum
rsp_maybe_rd_rs: Enum
r3000gte_sf: Enum
r3000gte_mx: Enum
r3000gte_v: Enum
r3000gte_cv: Enum
r3000gte_lm: Enum
r5900_I: Enum
r5900_Q: Enum
r5900_R: Enum

View File

@ -13,6 +13,8 @@ RabbitizerEnumMetadata rabbitizer_enum_InstrId_enumvalues[] = {
#include "instructions/instr_id/RabbitizerInstrId_rsp.inc"
#include "instructions/instr_id/RabbitizerInstrId_r3000gte.inc"
#include "instructions/instr_id/RabbitizerInstrId_r5900.inc"
RABBITIZER_DEF_INSTR_ID(ALL, , MAX, )

View File

@ -12,6 +12,7 @@ RabbitizerEnumMetadata rabbitizer_enum_OperandType_enumvalues[] = {
#include "instructions/operands/RabbitizerOperandType_cpu.inc"
#include "instructions/operands/RabbitizerOperandType_rsp.inc"
#include "instructions/operands/RabbitizerOperandType_r3000gte.inc"
#include "instructions/operands/RabbitizerOperandType_r5900.inc"
RAB_DEF_OPERAND(ALL, MAX)

View File

@ -4,6 +4,7 @@
#include "rabbitizer_module.h"
#include "instructions/RabbitizerInstructionRsp.h"
#include "instructions/RabbitizerInstructionR3000GTE.h"
#include "instructions/RabbitizerInstructionR5900.h"
#include "common/RabbitizerConfig.h"
@ -44,6 +45,11 @@ static int rabbitizer_type_Instruction_init(PyRabbitizerInstruction *self, PyObj
RabbitizerInstructionRsp_processUniqueId(&self->instr);
break;
case RABBITIZER_INSTRCAT_R3000GTE:
RabbitizerInstructionR3000GTE_init(&self->instr, word, vram);
RabbitizerInstructionR3000GTE_processUniqueId(&self->instr);
break;
case RABBITIZER_INSTRCAT_R5900:
RabbitizerInstructionR5900_init(&self->instr, word, vram);
RabbitizerInstructionR5900_processUniqueId(&self->instr);

View File

@ -19,6 +19,8 @@ pub enum InstrId {
#include "instructions/instr_id/RabbitizerInstrId_rsp.inc"
#include "instructions/instr_id/RabbitizerInstrId_r3000gte.inc"
#include "instructions/instr_id/RabbitizerInstrId_r5900.inc"
}

View File

@ -16,6 +16,7 @@ pub enum OperandType {
#include "instructions/operands/RabbitizerOperandType_cpu.inc"
#include "instructions/operands/RabbitizerOperandType_rsp.inc"
#include "instructions/operands/RabbitizerOperandType_r3000gte.inc"
#include "instructions/operands/RabbitizerOperandType_r5900.inc"
RAB_DEF_OPERAND(ALL, MAX)

View File

@ -9,6 +9,7 @@
const char *const RabbitizerInstrCategory_Names[] = {
[RABBITIZER_INSTRCAT_CPU] = "CPU",
[RABBITIZER_INSTRCAT_RSP] = "RSP",
[RABBITIZER_INSTRCAT_R3000GTE] = "R3000GTE",
[RABBITIZER_INSTRCAT_R5900] = "R5900",
};

View File

@ -414,6 +414,50 @@ const RabbitizerInstrDescriptor RabbitizerInstrDescriptor_Descriptors[] = {
[RABBITIZER_INSTR_ID_rsp_USERDEF_18] = { .operands={0} },
[RABBITIZER_INSTR_ID_rsp_USERDEF_19] = { .operands={0} },
[RABBITIZER_INSTR_ID_rsp_MAX] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_INVALID] = { .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN },
[RABBITIZER_INSTR_ID_r3000gte_RTPS] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_RTPT] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_DPCL] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_DPCS] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_DPCT] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_INTPL] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_NCS] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_NCT] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_NCDS] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_NCDT] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_NCCS] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_NCCT] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_CDP] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_CC] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_NCLIP] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_AVSZ3] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_AVSZ4] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_MVMVA] = { .operands={RAB_OPERAND_r3000gte_sf, RAB_OPERAND_r3000gte_mx, RAB_OPERAND_r3000gte_v, RAB_OPERAND_r3000gte_cv, RAB_OPERAND_r3000gte_lm} },
[RABBITIZER_INSTR_ID_r3000gte_SQR] = { .operands={RAB_OPERAND_r3000gte_sf} },
[RABBITIZER_INSTR_ID_r3000gte_OP] = { .operands={RAB_OPERAND_r3000gte_sf} },
[RABBITIZER_INSTR_ID_r3000gte_GPF] = { .operands={RAB_OPERAND_r3000gte_sf} },
[RABBITIZER_INSTR_ID_r3000gte_GPL] = { .operands={RAB_OPERAND_r3000gte_sf} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_00] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_01] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_02] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_03] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_04] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_05] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_06] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_07] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_08] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_09] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_10] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_11] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_12] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_13] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_14] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_15] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_16] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_17] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_18] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_19] = { .operands={0} },
[RABBITIZER_INSTR_ID_r3000gte_MAX] = { .operands={0} },
[RABBITIZER_INSTR_ID_r5900_INVALID] = { .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate}, .instrType=RABBITIZER_INSTR_TYPE_UNKNOWN },
[RABBITIZER_INSTR_ID_r5900_lq] = { .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .modifiesRt=true, .readsRs=true, .canBeLo=true, .doesDereference=true, .doesLoad=true },
[RABBITIZER_INSTR_ID_r5900_sq] = { .operands={RAB_OPERAND_cpu_rt, RAB_OPERAND_cpu_immediate_base}, .instrType=RABBITIZER_INSTR_TYPE_I, .readsRs=true, .readsRt=true, .canBeLo=true, .doesDereference=true, .doesStore=true },

View File

@ -8,6 +8,7 @@
const RabbitizerInstrDescriptor RabbitizerInstrDescriptor_Descriptors[] = {
#include "instructions/instr_id/RabbitizerInstrId_cpu.inc"
#include "instructions/instr_id/RabbitizerInstrId_rsp.inc"
#include "instructions/instr_id/RabbitizerInstrId_r3000gte.inc"
#include "instructions/instr_id/RabbitizerInstrId_r5900.inc"
};

View File

@ -414,6 +414,50 @@ const char *RabbitizerInstrId_Names[] = {
[RABBITIZER_INSTR_ID_rsp_USERDEF_18] = "USERDEF_18",
[RABBITIZER_INSTR_ID_rsp_USERDEF_19] = "USERDEF_19",
[RABBITIZER_INSTR_ID_rsp_MAX] = "MAX",
[RABBITIZER_INSTR_ID_r3000gte_INVALID] = "INVALID",
[RABBITIZER_INSTR_ID_r3000gte_RTPS] = "RTPS",
[RABBITIZER_INSTR_ID_r3000gte_RTPT] = "RTPT",
[RABBITIZER_INSTR_ID_r3000gte_DPCL] = "DPCL",
[RABBITIZER_INSTR_ID_r3000gte_DPCS] = "DPCS",
[RABBITIZER_INSTR_ID_r3000gte_DPCT] = "DPCT",
[RABBITIZER_INSTR_ID_r3000gte_INTPL] = "INTPL",
[RABBITIZER_INSTR_ID_r3000gte_NCS] = "NCS",
[RABBITIZER_INSTR_ID_r3000gte_NCT] = "NCT",
[RABBITIZER_INSTR_ID_r3000gte_NCDS] = "NCDS",
[RABBITIZER_INSTR_ID_r3000gte_NCDT] = "NCDT",
[RABBITIZER_INSTR_ID_r3000gte_NCCS] = "NCCS",
[RABBITIZER_INSTR_ID_r3000gte_NCCT] = "NCCT",
[RABBITIZER_INSTR_ID_r3000gte_CDP] = "CDP",
[RABBITIZER_INSTR_ID_r3000gte_CC] = "CC",
[RABBITIZER_INSTR_ID_r3000gte_NCLIP] = "NCLIP",
[RABBITIZER_INSTR_ID_r3000gte_AVSZ3] = "AVSZ3",
[RABBITIZER_INSTR_ID_r3000gte_AVSZ4] = "AVSZ4",
[RABBITIZER_INSTR_ID_r3000gte_MVMVA] = "MVMVA",
[RABBITIZER_INSTR_ID_r3000gte_SQR] = "SQR",
[RABBITIZER_INSTR_ID_r3000gte_OP] = "OP",
[RABBITIZER_INSTR_ID_r3000gte_GPF] = "GPF",
[RABBITIZER_INSTR_ID_r3000gte_GPL] = "GPL",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_00] = "USERDEF_00",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_01] = "USERDEF_01",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_02] = "USERDEF_02",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_03] = "USERDEF_03",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_04] = "USERDEF_04",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_05] = "USERDEF_05",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_06] = "USERDEF_06",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_07] = "USERDEF_07",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_08] = "USERDEF_08",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_09] = "USERDEF_09",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_10] = "USERDEF_10",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_11] = "USERDEF_11",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_12] = "USERDEF_12",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_13] = "USERDEF_13",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_14] = "USERDEF_14",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_15] = "USERDEF_15",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_16] = "USERDEF_16",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_17] = "USERDEF_17",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_18] = "USERDEF_18",
[RABBITIZER_INSTR_ID_r3000gte_USERDEF_19] = "USERDEF_19",
[RABBITIZER_INSTR_ID_r3000gte_MAX] = "MAX",
[RABBITIZER_INSTR_ID_r5900_INVALID] = "INVALID",
[RABBITIZER_INSTR_ID_r5900_lq] = "lq",
[RABBITIZER_INSTR_ID_r5900_sq] = "sq",

View File

@ -8,6 +8,7 @@
const char *RabbitizerInstrId_Names[] = {
#include "instructions/instr_id/RabbitizerInstrId_cpu.inc"
#include "instructions/instr_id/RabbitizerInstrId_rsp.inc"
#include "instructions/instr_id/RabbitizerInstrId_r3000gte.inc"
#include "instructions/instr_id/RabbitizerInstrId_r5900.inc"
};

View File

@ -251,6 +251,15 @@ bool RabbitizerInstrDescriptor_hasOperandAlias(const RabbitizerInstrDescriptor *
break;
/* rsp */
/* r3000gte */
case RAB_OPERAND_r3000gte_sf:
case RAB_OPERAND_r3000gte_mx:
case RAB_OPERAND_r3000gte_v:
case RAB_OPERAND_r3000gte_cv:
case RAB_OPERAND_r3000gte_lm:
break;
/* r3000gte */
/* r5900 */
case RAB_OPERAND_r5900_I:
case RAB_OPERAND_r5900_Q:

View File

@ -11,9 +11,11 @@ bool RabbitizerInstrId_isValid(RabbitizerInstrId uniqueId) {
switch (uniqueId) {
case RABBITIZER_INSTR_ID_cpu_INVALID:
case RABBITIZER_INSTR_ID_rsp_INVALID:
case RABBITIZER_INSTR_ID_r3000gte_INVALID:
case RABBITIZER_INSTR_ID_r5900_INVALID:
case RABBITIZER_INSTR_ID_cpu_MAX:
case RABBITIZER_INSTR_ID_rsp_MAX:
case RABBITIZER_INSTR_ID_r3000gte_MAX:
case RABBITIZER_INSTR_ID_r5900_MAX:
// case RABBITIZER_INSTR_ID_ALL_MAX: Same as last MAX
return false;
@ -24,7 +26,12 @@ bool RabbitizerInstrId_isValid(RabbitizerInstrId uniqueId) {
}
const char *RabbitizerInstrId_getOpcodeName(RabbitizerInstrId uniqueId) {
const char *name;
assert(uniqueId >= RABBITIZER_INSTR_ID_cpu_INVALID && uniqueId < RABBITIZER_INSTR_ID_ALL_MAX);
return RabbitizerInstrId_Names[uniqueId];
name = RabbitizerInstrId_Names[uniqueId];
assert(name != NULL);
return name;
}

View File

@ -8,6 +8,7 @@
#include "common/RabbitizerConfig.h"
#include "instructions/RabbitizerRegister.h"
#include "instructions/RabbitizerInstructionRsp.h"
#include "instructions/RabbitizerInstructionR3000GTE.h"
#include "instructions/RabbitizerInstructionR5900.h"
void RabbitizerInstruction_init(RabbitizerInstruction *self, uint32_t word, uint32_t vram) {
@ -266,6 +267,28 @@ void RabbitizerInstruction_blankOut(RabbitizerInstruction *self) {
break;
/* rsp */
/* r3000gte */
case RAB_OPERAND_r3000gte_sf:
self->word = RAB_INSTR_R3000GTE_PACK_sf(self->word, 0);
break;
case RAB_OPERAND_r3000gte_mx:
self->word = RAB_INSTR_R3000GTE_PACK_mx(self->word, 0);
break;
case RAB_OPERAND_r3000gte_v:
self->word = RAB_INSTR_R3000GTE_PACK_v(self->word, 0);
break;
case RAB_OPERAND_r3000gte_cv:
self->word = RAB_INSTR_R3000GTE_PACK_cv(self->word, 0);
break;
case RAB_OPERAND_r3000gte_lm:
self->word = RAB_INSTR_R3000GTE_PACK_lm(self->word, 0);
break;
/* r3000gte */
/* r5900 */
case RAB_OPERAND_r5900_I:
case RAB_OPERAND_r5900_Q:

View File

@ -7,6 +7,7 @@
#include "common/RabbitizerConfig.h"
#include "instructions/RabbitizerInstructionRsp.h"
#include "instructions/RabbitizerInstructionR3000GTE.h"
#include "instructions/RabbitizerInstructionR5900.h"
#include "instructions/RabbitizerRegister.h"
@ -316,6 +317,28 @@ uint32_t RabbitizerInstruction_getValidBits(const RabbitizerInstruction *self) {
break;
/* rsp */
/* r3000gte */
case RAB_OPERAND_r3000gte_sf:
validbits = RAB_INSTR_R3000GTE_PACK_sf(validbits, ~0);
break;
case RAB_OPERAND_r3000gte_mx:
validbits = RAB_INSTR_R3000GTE_PACK_mx(validbits, ~0);
break;
case RAB_OPERAND_r3000gte_v:
validbits = RAB_INSTR_R3000GTE_PACK_v(validbits, ~0);
break;
case RAB_OPERAND_r3000gte_cv:
validbits = RAB_INSTR_R3000GTE_PACK_cv(validbits, ~0);
break;
case RAB_OPERAND_r3000gte_lm:
validbits = RAB_INSTR_R3000GTE_PACK_lm(validbits, ~0);
break;
/* r3000gte */
/* r5900 */
case RAB_OPERAND_r5900_I:
case RAB_OPERAND_r5900_Q:

View File

@ -44,6 +44,11 @@ const OperandCallback instrOpercandCallbacks[] = {
[RAB_OPERAND_rsp_offset_rs] = RabbitizerOperandType_process_rsp_offset_rs,
[RAB_OPERAND_rsp_immediate_base] = RabbitizerOperandType_process_rsp_immediate_base,
[RAB_OPERAND_rsp_maybe_rd_rs] = RabbitizerOperandType_process_rsp_maybe_rd_rs,
[RAB_OPERAND_r3000gte_sf] = RabbitizerOperandType_process_r3000gte_sf,
[RAB_OPERAND_r3000gte_mx] = RabbitizerOperandType_process_r3000gte_mx,
[RAB_OPERAND_r3000gte_v] = RabbitizerOperandType_process_r3000gte_v,
[RAB_OPERAND_r3000gte_cv] = RabbitizerOperandType_process_r3000gte_cv,
[RAB_OPERAND_r3000gte_lm] = RabbitizerOperandType_process_r3000gte_lm,
[RAB_OPERAND_r5900_I] = RabbitizerOperandType_process_r5900_I,
[RAB_OPERAND_r5900_Q] = RabbitizerOperandType_process_r5900_Q,
[RAB_OPERAND_r5900_R] = RabbitizerOperandType_process_r5900_R,

View File

@ -6,6 +6,7 @@
const OperandCallback instrOpercandCallbacks[] = {
#include "instructions/operands/RabbitizerOperandType_cpu.inc"
#include "instructions/operands/RabbitizerOperandType_rsp.inc"
#include "instructions/operands/RabbitizerOperandType_r3000gte.inc"
#include "instructions/operands/RabbitizerOperandType_r5900.inc"
};

View File

@ -0,0 +1,17 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "instructions/RabbitizerInstructionR3000GTE.h"
void RabbitizerInstructionR3000GTE_init(RabbitizerInstruction *self, uint32_t word, uint32_t vram) {
RabbitizerInstruction_init(self, word, vram);
self->uniqueId = RABBITIZER_INSTR_ID_r3000gte_INVALID;
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId];
self->category = RABBITIZER_INSTRCAT_R3000GTE;
}
void RabbitizerInstructionR3000GTE_destroy(RabbitizerInstruction *self) {
RabbitizerInstruction_destroy(self);
}

View File

@ -0,0 +1,50 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "instructions/RabbitizerInstructionR3000GTE.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "common/Utils.h"
size_t RabbitizerOperandType_process_r3000gte_sf(const struct RabbitizerInstruction *self, char *dst,
UNUSED const char *immOverride, UNUSED size_t immOverrideLength) {
size_t totalSize = 0;
RABUTILS_BUFFER_SPRINTF(dst, totalSize, "%i", RAB_INSTR_R3000GTE_GET_sf(self));
return totalSize;
}
size_t RabbitizerOperandType_process_r3000gte_mx(const struct RabbitizerInstruction *self, char *dst,
UNUSED const char *immOverride, UNUSED size_t immOverrideLength) {
size_t totalSize = 0;
RABUTILS_BUFFER_SPRINTF(dst, totalSize, "%i", RAB_INSTR_R3000GTE_GET_mx(self));
return totalSize;
}
size_t RabbitizerOperandType_process_r3000gte_v(const struct RabbitizerInstruction *self, char *dst,
UNUSED const char *immOverride, UNUSED size_t immOverrideLength) {
size_t totalSize = 0;
RABUTILS_BUFFER_SPRINTF(dst, totalSize, "%i", RAB_INSTR_R3000GTE_GET_v(self));
return totalSize;
}
size_t RabbitizerOperandType_process_r3000gte_cv(const struct RabbitizerInstruction *self, char *dst,
UNUSED const char *immOverride, UNUSED size_t immOverrideLength) {
size_t totalSize = 0;
RABUTILS_BUFFER_SPRINTF(dst, totalSize, "%i", RAB_INSTR_R3000GTE_GET_cv(self));
return totalSize;
}
size_t RabbitizerOperandType_process_r3000gte_lm(const struct RabbitizerInstruction *self, char *dst,
UNUSED const char *immOverride, UNUSED size_t immOverrideLength) {
size_t totalSize = 0;
RABUTILS_BUFFER_SPRINTF(dst, totalSize, "%i", RAB_INSTR_R3000GTE_GET_lm(self));
return totalSize;
}

View File

@ -0,0 +1,117 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "instructions/RabbitizerInstructionR3000GTE.h"
#include "common/RabbitizerConfig.h"
#include "stdio.h"
#define RABBITIZER_DEF_INSTR_ID(prefix, caseBits, name, ...) \
case (caseBits): \
self->uniqueId = RABBITIZER_INSTR_ID_##prefix##_##name; \
break;
#define RABBITIZER_DEF_INSTR_ID_ALTNAME(prefix, caseBits, name, altname, ...) \
RABBITIZER_DEF_INSTR_ID(prefix, caseBits, name, __VA_ARGS__)
void RabbitizerInstructionR3000GTE_processUniqueId_Normal(RabbitizerInstruction *self) {
RabbitizerInstruction_processUniqueId_Normal(self);
}
void RabbitizerInstructionR3000GTE_processUniqueId_Special(RabbitizerInstruction *self) {
RabbitizerInstruction_processUniqueId_Special(self);
}
void RabbitizerInstructionR3000GTE_processUniqueId_Regimm(RabbitizerInstruction *self) {
RabbitizerInstruction_processUniqueId_Regimm(self);
}
void RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor0(RabbitizerInstruction *self) {
RabbitizerInstruction_processUniqueId_Coprocessor0(self);
}
void RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor1(RabbitizerInstruction *self) {
RabbitizerInstruction_processUniqueId_Coprocessor1(self);
}
void RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor2_gte(RabbitizerInstruction *self) {
uint32_t function = RAB_INSTR_GET_function(self);
self->_mandatorybits = RAB_INSTR_PACK_function(self->_mandatorybits, function);
// GTE instructions are weird
self->_mandatorybits =
RAB_INSTR_R3000GTE_PACK_FAKE_OPCODE(self->_mandatorybits, RAB_INSTR_R3000GTE_GET_FAKE_OPCODE(self));
self->_mandatorybits = RAB_INSTR_R3000GTE_PACK_sf(self->_mandatorybits, RAB_INSTR_R3000GTE_GET_sf(self));
self->_mandatorybits = RAB_INSTR_R3000GTE_PACK_mx(self->_mandatorybits, RAB_INSTR_R3000GTE_GET_mx(self));
self->_mandatorybits = RAB_INSTR_R3000GTE_PACK_v(self->_mandatorybits, RAB_INSTR_R3000GTE_GET_v(self));
self->_mandatorybits = RAB_INSTR_R3000GTE_PACK_cv(self->_mandatorybits, RAB_INSTR_R3000GTE_GET_cv(self));
self->_mandatorybits = RAB_INSTR_R3000GTE_PACK_lm(self->_mandatorybits, RAB_INSTR_R3000GTE_GET_lm(self));
switch (function) {
#include "instructions/instr_id/r3000gte/r3000gte_cop2_gte.inc"
}
}
void RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor2(RabbitizerInstruction *self) {
uint8_t fmt = RAB_INSTR_GET_fmt(self);
bool fetchDescriptor = true;
self->_mandatorybits = RAB_INSTR_PACK_fmt(self->_mandatorybits, fmt);
switch (fmt) {
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15:
case 0x16:
case 0x17:
case 0x18:
case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
case 0x1D:
RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor2_gte(self);
break;
default:
RabbitizerInstruction_processUniqueId_Coprocessor2(self);
fetchDescriptor = false;
break;
}
if (fetchDescriptor) {
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId];
}
}
#undef RABBITIZER_DEF_INSTR_ID
#undef RABBITIZER_DEF_INSTR_ID_ALTNAME
void RabbitizerInstructionR3000GTE_processUniqueId(RabbitizerInstruction *self) {
uint32_t opcode = RAB_INSTR_GET_opcode(self);
self->_mandatorybits = RAB_INSTR_PACK_opcode(self->_mandatorybits, opcode);
switch (opcode) {
default:
RabbitizerInstructionR3000GTE_processUniqueId_Normal(self);
break;
case 0x00:
RabbitizerInstructionR3000GTE_processUniqueId_Special(self);
break;
case 0x01:
RabbitizerInstructionR3000GTE_processUniqueId_Regimm(self);
break;
case 0x10:
RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor0(self);
break;
case 0x11:
RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor1(self);
break;
case 0x12:
RabbitizerInstructionR3000GTE_processUniqueId_Coprocessor2(self);
break;
}
}

View File

@ -0,0 +1,8 @@
.set noreorder
.section .text
.global gte_rtps_b
RTPS
jr $ra
nop

View File

@ -0,0 +1,91 @@
;
; GTE commands without nops
;
RTPS macro
dw $0000007f
endm
RTPT macro
dw $000000bf
endm
DCPL macro
dw $00000dff
endm
DPCS macro
dw $00000e3f
endm
DPCT macro
dw $00000e7f
endm
INTPL macro
dw $00000ebf
endm
NCS macro
dw $00000f7f
endm
NCT macro
dw $00000fbf
endm
NCDS macro
dw $00000fff
endm
NCDT macro
dw $0000103f
endm
NCCS macro
dw $0000107f
endm
NCCT macro
dw $000010bf
endm
CDP macro
dw $000010ff
endm
CC macro
dw $0000113f
endm
NCLIP macro
dw $0000117f
endm
AVSZ3 macro
dw $000011bf
endm
AVSZ4 macro
dw $000011ff
endm
MVMVA macro sf,mx,v,cv,lm
dw $000013bf|sf<<25|mx<<23|v<<21|cv<<19|lm<<18
endm
SQR macro sf
dw $000013ff|sf<<25
endm
OP macro sf
dw $0000143f|sf<<25
endm
GPF macro sf
dw $0000147f|sf<<25
endm
GPL macro sf
dw $000014bf|sf<<25
endm

View File

@ -0,0 +1,424 @@
.macro RTPS
.word 0x4A180001
.endm
.macro RTPT
.word 0x4A280030
.endm
.macro DPCL
.word 0x4A680029
.endm
.macro DPCS
.word 0x4A780010
.endm
.macro DPCT
.word 0x4AF8002A
.endm
.macro INTPL
.word 0x4A980011
.endm
.macro NCS
.word 0x4AC8041E
.endm
.macro NCT
.word 0x4AD80420
.endm
.macro NCDS
.word 0x4AE80413
.endm
.macro NCDT
.word 0x4AF80416
.endm
.macro NCCS
.word 0x4B08041B
.endm
.macro NCCT
.word 0x4B18043F
.endm
.macro CDP
.word 0x4B280414
.endm
.macro CC
.word 0x4B38041C
.endm
.macro NCLIP
.word 0x4B400006
.endm
.macro AVSZ3
.word 0x4B58002D
.endm
.macro AVSZ4
.word 0x4B68002E
.endm
.macro MVMVA sf, mx, v, cv, lm
.word 0x4A400012
.endm
.macro SQR sf
.word 0x4AA00428
.endm
.macro OP sf
.word 0x4B70000C
.endm
.macro GPF sf
.word 0x4B90003D
.endm
.macro GPL sf
.word 0x4BA0003E
.endm
.macro rtv0
.word 0x4A486012
.endm
.macro rtv1
.word 0x4A48E012
.endm
.macro rtv2
.word 0x4A496012
.endm
.macro rtir12
.word 0x4A49E012
.endm
.macro rtir0
.word 0x4A41E012
.endm
.macro rtv0tr
.word 0x4A480012
.endm
.macro rtv1tr
.word 0x4A488012
.endm
.macro rtv2tr
.word 0x4A490012
.endm
.macro rtirtr
.word 0x4A498012
.endm
.macro rtv0bk
.word 0x4A482012
.endm
.macro rtv1bk
.word 0x4A48A012
.endm
.macro rtv2bk
.word 0x4A492012
.endm
.macro rtirbk
.word 0x4A49A012
.endm
.macro ll
.word 0x4A4A6412
.endm
.macro llv0
.word 0x4A4A6012
.endm
.macro llv1
.word 0x4A4AE012
.endm
.macro llv2
.word 0x4A4B6012
.endm
.macro llvir
.word 0x4A4BE012
.endm
.macro llv0tr
.word 0x4A4A0012
.endm
.macro llv1tr
.word 0x4A4A8012
.endm
.macro llv2tr
.word 0x4A4B0012
.endm
.macro llirtr
.word 0x4A4B8012
.endm
.macro llv0bk
.word 0x4A4A2012
.endm
.macro llv1bk
.word 0x4A4AA012
.endm
.macro llv2bk
.word 0x4A4B2012
.endm
.macro llirbk
.word 0x4A4BA012
.endm
.macro lc
.word 0x4A4DA412
.endm
.macro lcv0
.word 0x4A4C6012
.endm
.macro lcv1
.word 0x4A4CE012
.endm
.macro lcv2
.word 0x4A4D6012
.endm
.macro lcvir
.word 0x4A4DE012
.endm
.macro lcv0tr
.word 0x4A4C0012
.endm
.macro lcv1tr
.word 0x4A4C8012
.endm
.macro lcv2tr
.word 0x4A4D0012
.endm
.macro lcirtr
.word 0x4A4D8012
.endm
.macro lev0bk
.word 0x4A4C2012
.endm
.macro lev1bk
.word 0x4A4CA012
.endm
.macro lev2bk
.word 0x4A4D2012
.endm
.macro leirbk
.word 0x4A4DA012
.endm
.macro sqr12
.word 0x4AA80428
.endm
.macro sqr0
.word 0x4AA80428
.endm
.macro op12
.word 0x4B78000C
.endm
.macro op0
.word 0x4B70000C
.endm
.macro gpf12
.word 0x4B98003D
.endm
.macro gpf0
.word 0x4B90003D
.endm
.macro gpl12
.word 0x4BA8003E
.endm
.macro gpl0
.word 0x4BA0003E
.endm
/* DPCS macro */
/* dw $00000e3f */
/* endm */
/* */
/* DPCT macro */
/* dw $00000e7f */
/* endm */
/* */
/* INTPL macro */
/* dw $00000ebf */
/* endm */
/* */
/* NCS macro */
/* dw $00000f7f */
/* endm */
/* */
/* NCT macro */
/* dw $00000fbf */
/* endm */
/* */
/* NCDS macro */
/* dw $00000fff */
/* endm */
/* */
/* NCDT macro */
/* dw $0000103f */
/* endm */
/* */
/* NCCS macro */
/* dw $0000107f */
/* endm */
/* */
/* NCCT macro */
/* dw $000010bf */
/* endm */
/* */
/* CDP macro */
/* dw $000010ff */
/* endm */
/* */
/* CC macro */
/* dw $0000113f */
/* endm */
/* */
/* NCLIP macro */
/* dw $0000117f */
/* endm */
/* */
/* AVSZ3 macro */
/* dw $000011bf */
/* endm */
/* */
/* AVSZ4 macro */
/* dw $000011ff */
/* endm */
/* */
/* MVMVA macro sf,mx,v,cv,lm */
/* dw $000013bf|sf<<25|mx<<23|v<<21|cv<<19|lm<<18 */
/* endm */
/* */
/* SQR macro sf */
/* dw $000013ff|sf<<25 */
/* endm */
/* */
/* OP macro sf */
/* dw $0000143f|sf<<25 */
/* endm */
/* */
/* GPF macro sf */
/* dw $0000147f|sf<<25 */
/* endm */
/* */
/* GPL macro sf */
/* dw $000014bf|sf<<25 */
/* endm */
/* RTPS 15 0x4A180001 Perspective transform */
/* RTPT 23 0x4A280030 Perspective transform on 3 points */
/* MVMVA 8 0x4A400012 Multiply vector by matrix and vector addition. */
/* DPCL 8 0x4A680029 Depth Cue Color light */
/* DPCS 8 0x4A780010 Depth Cueing */
/* DPCT 17 0x4AF8002A Depth cue color RGB0,RGB1,RGB2 */
/* INTPL 8 0x4A980011 Interpolation of vector and far color */
/* SQR 5 0x4AA00428 Square of vector */
/* NCS 14 0x4AC8041E Normal color v0 */
/* NCT 30 0x4AD80420 Normal color v0, v1, v2 */
/* NCDS 19 0x4AE80413 Normal color depth cuev0 */
/* NCDT 44 0x4AF80416 Normal color depth cue v0, v1, v2 */
/* NCCS 17 0x4B08041B Normal color col. v0 */
/* NCCT 39 0x4B18043F Normal color col.v0, v1, v2 */
/* CDP 13 0x4B280414 Color Depth Queue */
/* CC 11 0x4B38041C Color Col. */
/* NCLIP 8 0x4B400006 Normal clipping */
/* AVSZ3 5 0x4B58002D Average of three Z values */
/* AVSZ4 6 0x4B68002E Average of four Z values */
/* OP 6 0x4B70000C Outer Product */
/* GPF 6 0x4B90003D General purpose interpolation */
/* GPL 5 0x4BA0003E general purpose interpolation */
/* rtv0 - 0x4A486012 v0 * rotmatrix */
/* rtv1 - 0x4A48E012 v1 * rotmatrix */
/* rtv2 - 0x4A496012 v2 * rotmatrix */
/* rtir12 - 0x4A49E012 ir * rotmatrix */
/* rtir0 - 0x4A41E012 ir * rotmatrix */
/* rtv0tr - 0x4A480012 v0 * rotmatrix + tr vector */
/* rtv1tr - 0x4A488012 v1 * rotmatrix + tr vector */
/* rtv2tr - 0x4A490012 v2 * rotmatrix + tr vector */
/* rtirtr - 0x4A498012 ir * rotmatrix + tr vector */
/* rtv0bk - 0x4A482012 v0 * rotmatrix + bk vector */
/* rtv1bk - 0x4A48A012 v1 * rotmatrix + bk vector */
/* rtv2bk - 0x4A492012 v2 * rotmatrix + bk vector */
/* rtirbk - 0x4A49A012 ir * rotmatrix + bk vector */
/* ll - 0x4A4A6412 v0 * light matrix. Lower limit result to 0 */
/* llv0 - 0x4A4A6012 v0 * light matrix */
/* llv1 - 0x4A4AE012 v1 * light matrix */
/* llv2 - 0x4A4B6012 v2 * light matrix */
/* llvir - 0x4A4BE012 ir * light matrix */
/* llv0tr - 0x4A4A0012 v0 * light matrix + tr vector */
/* llv1tr - 0x4A4A8012 v1 * light matrix + tr vector */
/* llv2tr - 0x4A4B0012 v2 * light matrix + tr vector */
/* llirtr - 0x4A4B8012 ir * light matrix + tr vector */
/* llv0bk - 0x4A4A2012 v0 * light matrix + bk vector */
/* llv1bk - 0x4A4AA012 v1 * light matrix + bk vector */
/* llv2bk - 0x4A4B2012 v2 * light matrix + bk vector */
/* llirbk - 0x4A4BA012 ir * light matrix + bk vector */
/* lc - 0x4A4DA412 v0 * color matrix, Lower limit clamped to 0 */
/* lcv0 - 0x4A4C6012 v0 * color matrix */
/* lcv1 - 0x4A4CE012 v1 * color matrix */
/* lcv2 - 0x4A4D6012 v2 * color matrix */
/* lcvir - 0x4A4DE012 ir * color matrix */
/* lcv0tr - 0x4A4C0012 v0 * color matrix + tr vector */
/* lcv1tr - 0x4A4C8012 v1 * color matrix + tr vector */
/* lcv2tr - 0x4A4D0012 v2 * color matrix + tr vector */
/* lcirtr - 0x4A4D8012 ir * color matrix + tr vector */
/* lev0bk - 0x4A4C2012 v0 * color matrix + bk vector */
/* lev1bk - 0x4A4CA012 v1 * color matrix + bk vector */
/* lev2bk - 0x4A4D2012 v2 * color matrix + bk vector */
/* leirbk - 0x4A4DA012 ir * color matrix + bk vector */
/* sqr12 - 0x4AA80428 square of ir 1,19,12 */
/* sqr0 - 0x4AA80428 square of ir 1,31, 0 */
/* op12 - 0x4B78000C outer product 1,19,12 */
/* op0 - 0x4B70000C outer product 1,31, 0 */
/* gpf12 - 0x4B98003D general purpose interpolation 1,19,12 */
/* gpf0 - 0x4B90003D general purpose interpolation 1,31, 0 */
/* gpl12 - 0x4BA8003E general purpose interpolation 1,19,12 */
/* gpl0 - 0x4BA0003E general purpose interpolation 1,31, 0 */

View File

@ -0,0 +1,130 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "rabbitizer.h"
#include <string.h>
#include <stdlib.h>
#include <assert.h>
size_t strlen_null(const char *string) {
if (string == NULL) {
return 0;
}
return strlen(string);
}
typedef struct TestEntry {
uint32_t word;
const char *immOverride;
const char *expectedStr;
} TestEntry;
const TestEntry entries[] = {
{ 0x4A180001, NULL, "RTPS" },
{ 0x4A280030, NULL, "RTPT" },
{ 0x4A680029, NULL, "DPCL" },
{ 0x4A780010, NULL, "DPCS" },
{ 0x4AF8002A, NULL, "DPCT" },
{ 0x4A980011, NULL, "INTPL" },
{ 0x4AC8041E, NULL, "NCS" },
{ 0x4AD80420, NULL, "NCT" },
{ 0x4AE80413, NULL, "NCDS" },
{ 0x4AF80416, NULL, "NCDT" },
{ 0x4B08041B, NULL, "NCCS" },
{ 0x4B18043F, NULL, "NCCT" },
{ 0x4B280414, NULL, "CDP" },
{ 0x4B38041C, NULL, "CC" },
{ 0x4B400006, NULL, "NCLIP" },
{ 0x4B58002D, NULL, "AVSZ3" },
{ 0x4B68002E, NULL, "AVSZ4" },
{ 0x4A400012, NULL, "MVMVA 0, 0, 0, 0, 0" },
{ 0x4AA00428, NULL, "SQR 0" },
{ 0x4B70000C, NULL, "OP 0" },
{ 0x4B90003D, NULL, "GPF 0" },
{ 0x4BA0003E, NULL, "GPL 0" },
{ 0x4A486012, NULL, "MVMVA 1, 0, 0, 3, 0" },
{ 0x4A48E012, NULL, "MVMVA 1, 0, 1, 3, 0" },
{ 0x4A496012, NULL, "MVMVA 1, 0, 2, 3, 0" },
{ 0x4A49E012, NULL, "MVMVA 1, 0, 3, 3, 0" },
{ 0x4A41E012, NULL, "MVMVA 0, 0, 3, 3, 0" },
{ 0x4A480012, NULL, "MVMVA 1, 0, 0, 0, 0" },
{ 0x4A488012, NULL, "MVMVA 1, 0, 1, 0, 0" },
{ 0x4A490012, NULL, "MVMVA 1, 0, 2, 0, 0" },
{ 0x4A498012, NULL, "MVMVA 1, 0, 3, 0, 0" },
{ 0x4A482012, NULL, "MVMVA 1, 0, 0, 1, 0" },
{ 0x4A48A012, NULL, "MVMVA 1, 0, 1, 1, 0" },
{ 0x4A492012, NULL, "MVMVA 1, 0, 2, 1, 0" },
{ 0x4A49A012, NULL, "MVMVA 1, 0, 3, 1, 0" },
{ 0x4A4A6412, NULL, "MVMVA 1, 1, 0, 3, 1" },
{ 0x4A4A6012, NULL, "MVMVA 1, 1, 0, 3, 0" },
{ 0x4A4AE012, NULL, "MVMVA 1, 1, 1, 3, 0" },
{ 0x4A4B6012, NULL, "MVMVA 1, 1, 2, 3, 0" },
{ 0x4A4BE012, NULL, "MVMVA 1, 1, 3, 3, 0" },
{ 0x4A4A0012, NULL, "MVMVA 1, 1, 0, 0, 0" },
{ 0x4A4A8012, NULL, "MVMVA 1, 1, 1, 0, 0" },
{ 0x4A4B0012, NULL, "MVMVA 1, 1, 2, 0, 0" },
{ 0x4A4B8012, NULL, "MVMVA 1, 1, 3, 0, 0" },
{ 0x4A4A2012, NULL, "MVMVA 1, 1, 0, 1, 0" },
{ 0x4A4AA012, NULL, "MVMVA 1, 1, 1, 1, 0" },
{ 0x4A4B2012, NULL, "MVMVA 1, 1, 2, 1, 0" },
{ 0x4A4BA012, NULL, "MVMVA 1, 1, 3, 1, 0" },
{ 0x4A4DA412, NULL, "MVMVA 1, 2, 3, 1, 1" },
{ 0x4A4C6012, NULL, "MVMVA 1, 2, 0, 3, 0" },
{ 0x4A4CE012, NULL, "MVMVA 1, 2, 1, 3, 0" },
{ 0x4A4D6012, NULL, "MVMVA 1, 2, 2, 3, 0" },
{ 0x4A4DE012, NULL, "MVMVA 1, 2, 3, 3, 0" },
{ 0x4A4C0012, NULL, "MVMVA 1, 2, 0, 0, 0" },
{ 0x4A4C8012, NULL, "MVMVA 1, 2, 1, 0, 0" },
{ 0x4A4D0012, NULL, "MVMVA 1, 2, 2, 0, 0" },
{ 0x4A4D8012, NULL, "MVMVA 1, 2, 3, 0, 0" },
{ 0x4A4C2012, NULL, "MVMVA 1, 2, 0, 1, 0" },
{ 0x4A4CA012, NULL, "MVMVA 1, 2, 1, 1, 0" },
{ 0x4A4D2012, NULL, "MVMVA 1, 2, 2, 1, 0" },
{ 0x4A4DA012, NULL, "MVMVA 1, 2, 3, 1, 0" },
{ 0x4AA80428, NULL, "SQR 1" },
{ 0x4AA80428, NULL, "SQR 1" },
{ 0x4B78000C, NULL, "OP 1" },
{ 0x4B70000C, NULL, "OP 0" },
{ 0x4B98003D, NULL, "GPF 1" },
{ 0x4B90003D, NULL, "GPF 0" },
{ 0x4BA8003E, NULL, "GPL 1" },
{ 0x4BA0003E, NULL, "GPL 0" },
};
int main() {
int errorCount = 0;
size_t i;
for (i = 0; i < ARRAY_COUNT(entries); i++) {
const TestEntry *entry = &entries[i];
RabbitizerInstruction instr;
char *buffer;
size_t bufferSize;
size_t immOverrideLength = strlen_null(entry->immOverride);
RabbitizerInstructionR3000GTE_init(&instr, entry->word, 0);
RabbitizerInstructionR3000GTE_processUniqueId(&instr);
bufferSize = RabbitizerInstruction_getSizeForBuffer(&instr, immOverrideLength, 0);
buffer = malloc(bufferSize + 1);
assert(buffer != NULL);
RabbitizerInstruction_disassemble(&instr, buffer, entry->immOverride, immOverrideLength, 0);
if (entry->expectedStr == NULL) {
printf("Word '0x%08X' doesn't have a expected str, got '%s'\n", entry->word, buffer);
errorCount++;
} else if (strcmp(buffer, entry->expectedStr) != 0) {
fprintf(stderr, "Error on word '0x%08X'. Expected '%s', got '%s'\n", entry->word, entry->expectedStr, buffer);
errorCount++;
}
free(buffer);
RabbitizerInstructionR3000GTE_destroy(&instr);
}
return errorCount;
}

47
tests/c/r3000gte.c Normal file
View File

@ -0,0 +1,47 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "instructions/RabbitizerInstructionR3000GTE.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
uint32_t word;
RabbitizerInstruction instr;
char *buffer;
int extraLJust = 5;
#if 1
uint32_t validbits;
#endif
word = 0x4A180001; // RTPS
RabbitizerInstructionR3000GTE_init(&instr, word, 0x00100000);
RabbitizerInstructionR3000GTE_processUniqueId(&instr);
buffer = malloc(RabbitizerInstruction_getSizeForBuffer(&instr, 0, extraLJust) + 1);
assert(buffer != NULL);
RabbitizerInstruction_disassemble(&instr, buffer, NULL, 0, extraLJust);
printf("%08X: %s\n", word, buffer);
#if 1
validbits = RabbitizerInstruction_getValidBits(&instr);
printf("word: %08X\n", instr.word);
printf("mandatory bits: %08X\n", instr._mandatorybits);
printf("valid bits: %08X\n", validbits);
printf("invalid bits: %08X\n", (~validbits) & instr.word);
#endif
free(buffer);
RabbitizerInstructionR3000GTE_destroy(&instr);
return 0;
}

View File

@ -7,4 +7,5 @@ set -e
./build/tests/c/instruction_checks/jalr.elf
./build/tests/c/instruction_checks/plain_disassembly.elf
./build/tests/c/instruction_checks/r3000gte_disasm.elf
./build/tests/c/instruction_checks/r5900_trunc_cvt.elf