Merge pull request #32 from Decompollaborate/develop

1.7.0
This commit is contained in:
Anghelo Carvajal 2023-04-30 13:01:06 -04:00 committed by GitHub
commit 4f5f6142b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 392 additions and 33 deletions

59
.github/workflows/check_format.yml vendored Normal file
View File

@ -0,0 +1,59 @@
name: Check for format changes
# Build on every branch push, tag push, and pull request change:
on: [push, pull_request]
jobs:
check_format:
name: Check format
runs-on: ubuntu-latest
steps:
- name: Checkout reposistory
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
- name: Install dependencies
run: sudo apt install clang-format-11
- name: make format
run: make -j $(nproc) format
- name: Check if there are format changes
id: format_changes
uses: tj-actions/verify-changed-files@v14
- name: format changes
if: steps.format_changes.outputs.files_changed == 'true'
run: |
echo "Changed files: ${{ steps.format_changes.outputs.changed_files }}"
echo "Please run \`make format\` and commit the result"
exit 1
check_tidy:
name: Check tidy
runs-on: ubuntu-latest
steps:
- name: Checkout reposistory
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
- name: Install dependencies
run: sudo apt install clang-tidy-11
- name: make tidy
run: make -j $(nproc) tidy
- name: Check if there are tidy changes
id: tidy_changes
uses: tj-actions/verify-changed-files@v14
- name: tidy changes
if: steps.tidy_changes.outputs.files_changed == 'true'
run: |
echo "Changed files: ${{ steps.tidy_changes.outputs.changed_files }}"
echo "Please run \`make tidy\` and commit the result"
exit 1

59
.github/workflows/check_tables.yml vendored Normal file
View File

@ -0,0 +1,59 @@
name: Check for ungenerated tables
# Build on every branch push, tag push, and pull request change:
on: [push, pull_request]
jobs:
check_tables:
name: Check tables
runs-on: ubuntu-latest
steps:
- name: Checkout reposistory
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
- name: clean everything
run: make -j $(nproc) distclean
- name: make tables
run: make -j $(nproc) tables
- name: Check if there are tables changes
id: tables_changes
uses: tj-actions/verify-changed-files@v14
- name: tables changes
if: steps.tables_changes.outputs.files_changed == 'true'
run: |
echo "Changed files: ${{ steps.tables_changes.outputs.changed_files }}"
echo "Please run \`make distclean && make tables\` and commit the result"
exit 1
check_rust_tables:
name: Check Rust tables
runs-on: ubuntu-latest
steps:
- name: Checkout reposistory
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
- name: clean everything
run: make -j $(nproc) -C rust distclean
- name: make Rust tables
run: make -j $(nproc) -C rust tables
- name: Check if there are Rust tables changes
id: rust_tables_changes
uses: tj-actions/verify-changed-files@v14
- name: Rust tables changes
if: steps.rust_tables_changes.outputs.files_changed == 'true'
run: |
echo "Changed files: ${{ steps.rust_tables_changes.outputs.changed_files }}"
echo "Please run \`make -C rust distclean && make -C rust tables\` and commit the result"
exit 1

View File

@ -5,7 +5,7 @@ on: [push, pull_request]
jobs:
build_repo:
name: Build repo
name: Build repo and run tests
runs-on: ubuntu-latest
steps:

View File

@ -5,7 +5,7 @@ on: [push, pull_request]
jobs:
build_rust:
name: Build rust stuff
name: Build Rust stuff and run Rust tests
runs-on: ubuntu-latest
steps:

View File

@ -1,7 +1,11 @@
name: Build and upload to PyPI
# Build on every branch push, tag push, and pull request change:
on: [push, pull_request]
# Only run on releases
on:
push:
# Pattern matched against refs/tags
tags:
- '**' # Push events to every tag including hierarchical tags like v1.0/beta
jobs:
build_wheels:
@ -12,10 +16,10 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build wheels
uses: pypa/cibuildwheel@v2.12.1
uses: pypa/cibuildwheel@v2.12.3
env:
CIBW_ARCHS_WINDOWS: "auto"
CIBW_ARCHS_LINUX: "auto"
@ -29,7 +33,7 @@ jobs:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build sdist
run: pipx run build --sdist

View File

@ -4,7 +4,7 @@
[package]
name = "rabbitizer"
# Version should be synced with include/common/RabbitizerVersion.h
version = "1.6.2"
version = "1.7.0"
edition = "2021"
authors = ["Anghelo Carvajal <angheloalf95@gmail.com>"]
description = "MIPS instruction decoder"

View File

@ -105,6 +105,8 @@ all: static tests
static: $(STATIC_LIB) $(STATIC_LIB_XX)
dynamic: $(DYNAMIC_LIB) $(DYNAMIC_LIB_XX)
tables: $(TABLE_GENERATED)
clean:
$(RM) -rf build
@ -123,7 +125,7 @@ tidy:
tests: $(TESTS_ELFS)
.PHONY: all clean distclean format tidy tests
.PHONY: all static dynamic tables clean distclean format tidy tests
.DEFAULT_GOAL := all
.SECONDARY:

View File

@ -0,0 +1,28 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_INSTRUCTION_R3000GTE_HPP
#define RABBITIZER_INSTRUCTION_R3000GTE_HPP
#pragma once
#include "InstructionBase.hpp"
namespace rabbitizer {
class InstructionR3000GTE : public InstructionBase {
public:
InstructionR3000GTE(uint32_t word, uint32_t vram);
virtual ~InstructionR3000GTE();
uint8_t GetR3000GTE_fakeOpcode() const;
uint8_t GetR3000GTE_sf() const;
uint8_t GetR3000GTE_mx() const;
uint8_t GetR3000GTE_v() const;
uint8_t GetR3000GTE_cv() const;
uint8_t GetR3000GTE_lm() const;
};
};
#endif

View File

@ -1,4 +1,4 @@
/* SPDX-FileCopyrightText: © 2022 Decompollaborate */
/* SPDX-FileCopyrightText: © 2022-2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#ifndef RABBITIZER_HPP
@ -17,6 +17,7 @@
#include "instructions/InstructionBase.hpp"
#include "instructions/InstructionCpu.hpp"
#include "instructions/InstructionRsp.hpp"
#include "instructions/InstructionR3000GTE.hpp"
#include "instructions/InstructionR5900.hpp"
#include "analysis/LoPairingInfo.hpp"

View File

@ -0,0 +1,38 @@
/* SPDX-FileCopyrightText: © 2023 Decompollaborate */
/* SPDX-License-Identifier: MIT */
#include "instructions/InstructionR3000GTE.hpp"
#include "instructions/RabbitizerInstructionR3000GTE.h"
using namespace rabbitizer;
InstructionR3000GTE::InstructionR3000GTE(uint32_t word, uint32_t vram) : InstructionBase() {
RabbitizerInstructionR3000GTE_init(&this->instr, word, vram);
RabbitizerInstructionR3000GTE_processUniqueId(&this->instr);
}
InstructionR3000GTE::~InstructionR3000GTE() {
RabbitizerInstructionR3000GTE_destroy(&this->instr);
}
uint8_t InstructionR3000GTE::GetR3000GTE_fakeOpcode() const {
return RAB_INSTR_R3000GTE_GET_FAKE_OPCODE(&this->instr);
}
uint8_t InstructionR3000GTE::GetR3000GTE_sf() const {
return RAB_INSTR_R3000GTE_GET_sf(&this->instr);
}
uint8_t InstructionR3000GTE::GetR3000GTE_mx() const {
return RAB_INSTR_R3000GTE_GET_mx(&this->instr);
}
uint8_t InstructionR3000GTE::GetR3000GTE_v() const {
return RAB_INSTR_R3000GTE_GET_v(&this->instr);
}
uint8_t InstructionR3000GTE::GetR3000GTE_cv() const {
return RAB_INSTR_R3000GTE_GET_cv(&this->instr);
}
uint8_t InstructionR3000GTE::GetR3000GTE_lm() const {
return RAB_INSTR_R3000GTE_GET_lm(&this->instr);
}

View File

@ -13,8 +13,8 @@ extern "C" {
// Header version
#define RAB_VERSION_MAJOR 1
#define RAB_VERSION_MINOR 6
#define RAB_VERSION_PATCH 2
#define RAB_VERSION_MINOR 7
#define RAB_VERSION_PATCH 0
#define RAB_VERSION_STR RAB_STRINGIFY(RAB_VERSION_MAJOR) "." RAB_STRINGIFY(RAB_VERSION_MINOR) "." RAB_STRINGIFY(RAB_VERSION_PATCH)

View File

@ -4,7 +4,7 @@
[project]
name = "rabbitizer"
# Version should be synced with include/common/RabbitizerVersion.h
version = "1.6.2"
version = "1.7.0"
description = "MIPS instruction decoder"
# license = "MIT"
readme = "README.md"

View File

@ -36,8 +36,8 @@ static PyObject *rabbitizer_enum_Abi_fromStr(UNUSED PyObject *self, PyObject *ar
}
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction) rabbitizer_enum_Abi_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction) rabbitizer_enum_Abi_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_enum_Abi_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_enum_Abi_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
static PyMethodDef rabbitizer_enum_Abi_methods[] = {
METHOD_ARGS(fromStr, ""),

View File

@ -38,8 +38,8 @@ static PyObject *rabbitizer_enum_InstrCategory_fromStr(UNUSED PyObject *self, Py
}
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction) rabbitizer_enum_InstrCategory_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction) rabbitizer_enum_InstrCategory_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_enum_InstrCategory_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_enum_InstrCategory_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
static PyMethodDef rabbitizer_enum_InstrCategory_methods[] = {
METHOD_ARGS(fromStr, ""),

View File

@ -171,8 +171,8 @@ static PyObject *rabbitizer_type_Enum___reduce__(PyRabbitizerEnum *self, UNUSED
}
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction)rabbitizer_type_Enum_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction)rabbitizer_type_Enum_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_type_Enum_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_type_Enum_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
static PyMethodDef rabbitizer_type_Enum_methods[] = {

View File

@ -50,8 +50,8 @@ static PyObject *rabbitizer_submodule_Utils_escapeString(UNUSED PyObject *self,
}
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction) rabbitizer_submodule_Utils_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction) rabbitizer_submodule_Utils_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_submodule_Utils_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_submodule_Utils_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
static PyMethodDef rabbitizer_submodule_Utils_methods[] = {
METHOD_ARGS(from2Complement, ""),

View File

@ -494,8 +494,8 @@ static PyObject *rabbitizer_type_Instruction___reduce__(PyRabbitizerInstruction
}
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction)rabbitizer_type_Instruction_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction)rabbitizer_type_Instruction_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_type_Instruction_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_type_Instruction_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
static PyMethodDef rabbitizer_type_Instruction_methods[] = {

View File

@ -245,8 +245,8 @@ static PyObject *rabbitizer_type_RegistersTracker_hasLoButNoHi(PyRabbitizerRegis
}
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction)rabbitizer_type_RegistersTracker_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction)rabbitizer_type_RegistersTracker_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
#define METHOD_NO_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_type_RegistersTracker_##name, METH_NOARGS, PyDoc_STR(docs) }
#define METHOD_ARGS(name, docs) { #name, (PyCFunction) (void *) rabbitizer_type_RegistersTracker_##name, METH_VARARGS | METH_KEYWORDS, PyDoc_STR(docs) }
static PyMethodDef rabbitizer_type_RegistersTracker_methods[] = {
METHOD_ARGS(moveRegisters, ""),

View File

@ -9,7 +9,9 @@ TABLE_GENERATED := $(TABLE_TEMPLATES:%.tablers.template=%.rs)
TABLE_DEP_FILES := $(TABLE_GENERATED:%.rs=%.tablers.d)
all: $(TABLE_GENERATED)
all: tables
tables: $(TABLE_GENERATED)
clean:
$(RM) -rf $(TABLE_GENERATED)
@ -17,7 +19,7 @@ clean:
distclean: clean
.PHONY: all clean distclean
.PHONY: all tables clean distclean
.DEFAULT_GOAL := all
.SECONDARY:

View File

@ -9,6 +9,7 @@
pub enum InstrCategory {
CPU,
RSP,
R3000GTE,
R5900,
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

@ -36,6 +36,13 @@ extern "C" {
fn RabbitizerInstructionRsp_processUniqueId(self_: *mut Instruction);
}
extern "C" {
fn RabbitizerInstructionR3000GTE_init(self_: *mut Instruction, word: u32, vram: u32);
fn RabbitizerInstructionR3000GTE_destroy(self_: *mut Instruction);
fn RabbitizerInstructionR3000GTE_processUniqueId(self_: *mut Instruction);
}
extern "C" {
fn RabbitizerInstructionR5900_init(self_: *mut Instruction, word: u32, vram: u32);
fn RabbitizerInstructionR5900_destroy(self_: *mut Instruction);
@ -165,6 +172,9 @@ impl Drop for Instruction {
instr_category_enum::InstrCategory::RSP => {
RabbitizerInstructionRsp_destroy(self);
}
instr_category_enum::InstrCategory::R3000GTE => {
RabbitizerInstructionR3000GTE_destroy(self);
}
instr_category_enum::InstrCategory::R5900 => {
RabbitizerInstructionR5900_destroy(self);
}
@ -189,6 +199,10 @@ impl Instruction {
RabbitizerInstructionRsp_init(instr.as_mut_ptr(), word, vram);
RabbitizerInstructionRsp_processUniqueId(instr.as_mut_ptr());
}
instr_category_enum::InstrCategory::R3000GTE => {
RabbitizerInstructionR3000GTE_init(instr.as_mut_ptr(), word, vram);
RabbitizerInstructionR3000GTE_processUniqueId(instr.as_mut_ptr());
}
instr_category_enum::InstrCategory::R5900 => {
RabbitizerInstructionR5900_init(instr.as_mut_ptr(), word, vram);
RabbitizerInstructionR5900_processUniqueId(instr.as_mut_ptr());

View File

@ -31,6 +31,13 @@ pub use register_descriptor::RegisterDescriptor;
mod tests {
use super::*;
#[derive(Default, Debug, Clone)]
struct TestEntry {
word: u32,
imm_override: Option<String>,
expected_str: String,
}
#[test]
fn it_works() {
assert_eq!(
@ -75,4 +82,88 @@ mod tests {
fn test_register_descriptor() {
assert!(registers::GprO32::a0.descriptor().is_clobbered_by_func_call());
}
#[test]
fn test_r3000gte_instructions() {
let entries = [
TestEntry { word: 0x4A180001, imm_override: None, expected_str: "RTPS".to_string() },
TestEntry { word: 0x4A280030, imm_override: None, expected_str: "RTPT".to_string() },
TestEntry { word: 0x4A680029, imm_override: None, expected_str: "DPCL".to_string() },
TestEntry { word: 0x4A780010, imm_override: None, expected_str: "DPCS".to_string() },
TestEntry { word: 0x4AF8002A, imm_override: None, expected_str: "DPCT".to_string() },
TestEntry { word: 0x4A980011, imm_override: None, expected_str: "INTPL".to_string() },
TestEntry { word: 0x4AC8041E, imm_override: None, expected_str: "NCS".to_string() },
TestEntry { word: 0x4AD80420, imm_override: None, expected_str: "NCT".to_string() },
TestEntry { word: 0x4AE80413, imm_override: None, expected_str: "NCDS".to_string() },
TestEntry { word: 0x4AF80416, imm_override: None, expected_str: "NCDT".to_string() },
TestEntry { word: 0x4B08041B, imm_override: None, expected_str: "NCCS".to_string() },
TestEntry { word: 0x4B18043F, imm_override: None, expected_str: "NCCT".to_string() },
TestEntry { word: 0x4B280414, imm_override: None, expected_str: "CDP".to_string() },
TestEntry { word: 0x4B38041C, imm_override: None, expected_str: "CC".to_string() },
TestEntry { word: 0x4B400006, imm_override: None, expected_str: "NCLIP".to_string() },
TestEntry { word: 0x4B58002D, imm_override: None, expected_str: "AVSZ3".to_string() },
TestEntry { word: 0x4B68002E, imm_override: None, expected_str: "AVSZ4".to_string() },
TestEntry { word: 0x4A400012, imm_override: None, expected_str: "MVMVA 0, 0, 0, 0, 0".to_string() },
TestEntry { word: 0x4AA00428, imm_override: None, expected_str: "SQR 0".to_string() },
TestEntry { word: 0x4B70000C, imm_override: None, expected_str: "OP 0".to_string() },
TestEntry { word: 0x4B90003D, imm_override: None, expected_str: "GPF 0".to_string() },
TestEntry { word: 0x4BA0003E, imm_override: None, expected_str: "GPL 0".to_string() },
TestEntry { word: 0x4A486012, imm_override: None, expected_str: "MVMVA 1, 0, 0, 3, 0".to_string() },
TestEntry { word: 0x4A48E012, imm_override: None, expected_str: "MVMVA 1, 0, 1, 3, 0".to_string() },
TestEntry { word: 0x4A496012, imm_override: None, expected_str: "MVMVA 1, 0, 2, 3, 0".to_string() },
TestEntry { word: 0x4A49E012, imm_override: None, expected_str: "MVMVA 1, 0, 3, 3, 0".to_string() },
TestEntry { word: 0x4A41E012, imm_override: None, expected_str: "MVMVA 0, 0, 3, 3, 0".to_string() },
TestEntry { word: 0x4A480012, imm_override: None, expected_str: "MVMVA 1, 0, 0, 0, 0".to_string() },
TestEntry { word: 0x4A488012, imm_override: None, expected_str: "MVMVA 1, 0, 1, 0, 0".to_string() },
TestEntry { word: 0x4A490012, imm_override: None, expected_str: "MVMVA 1, 0, 2, 0, 0".to_string() },
TestEntry { word: 0x4A498012, imm_override: None, expected_str: "MVMVA 1, 0, 3, 0, 0".to_string() },
TestEntry { word: 0x4A482012, imm_override: None, expected_str: "MVMVA 1, 0, 0, 1, 0".to_string() },
TestEntry { word: 0x4A48A012, imm_override: None, expected_str: "MVMVA 1, 0, 1, 1, 0".to_string() },
TestEntry { word: 0x4A492012, imm_override: None, expected_str: "MVMVA 1, 0, 2, 1, 0".to_string() },
TestEntry { word: 0x4A49A012, imm_override: None, expected_str: "MVMVA 1, 0, 3, 1, 0".to_string() },
TestEntry { word: 0x4A4A6412, imm_override: None, expected_str: "MVMVA 1, 1, 0, 3, 1".to_string() },
TestEntry { word: 0x4A4A6012, imm_override: None, expected_str: "MVMVA 1, 1, 0, 3, 0".to_string() },
TestEntry { word: 0x4A4AE012, imm_override: None, expected_str: "MVMVA 1, 1, 1, 3, 0".to_string() },
TestEntry { word: 0x4A4B6012, imm_override: None, expected_str: "MVMVA 1, 1, 2, 3, 0".to_string() },
TestEntry { word: 0x4A4BE012, imm_override: None, expected_str: "MVMVA 1, 1, 3, 3, 0".to_string() },
TestEntry { word: 0x4A4A0012, imm_override: None, expected_str: "MVMVA 1, 1, 0, 0, 0".to_string() },
TestEntry { word: 0x4A4A8012, imm_override: None, expected_str: "MVMVA 1, 1, 1, 0, 0".to_string() },
TestEntry { word: 0x4A4B0012, imm_override: None, expected_str: "MVMVA 1, 1, 2, 0, 0".to_string() },
TestEntry { word: 0x4A4B8012, imm_override: None, expected_str: "MVMVA 1, 1, 3, 0, 0".to_string() },
TestEntry { word: 0x4A4A2012, imm_override: None, expected_str: "MVMVA 1, 1, 0, 1, 0".to_string() },
TestEntry { word: 0x4A4AA012, imm_override: None, expected_str: "MVMVA 1, 1, 1, 1, 0".to_string() },
TestEntry { word: 0x4A4B2012, imm_override: None, expected_str: "MVMVA 1, 1, 2, 1, 0".to_string() },
TestEntry { word: 0x4A4BA012, imm_override: None, expected_str: "MVMVA 1, 1, 3, 1, 0".to_string() },
TestEntry { word: 0x4A4DA412, imm_override: None, expected_str: "MVMVA 1, 2, 3, 1, 1".to_string() },
TestEntry { word: 0x4A4C6012, imm_override: None, expected_str: "MVMVA 1, 2, 0, 3, 0".to_string() },
TestEntry { word: 0x4A4CE012, imm_override: None, expected_str: "MVMVA 1, 2, 1, 3, 0".to_string() },
TestEntry { word: 0x4A4D6012, imm_override: None, expected_str: "MVMVA 1, 2, 2, 3, 0".to_string() },
TestEntry { word: 0x4A4DE012, imm_override: None, expected_str: "MVMVA 1, 2, 3, 3, 0".to_string() },
TestEntry { word: 0x4A4C0012, imm_override: None, expected_str: "MVMVA 1, 2, 0, 0, 0".to_string() },
TestEntry { word: 0x4A4C8012, imm_override: None, expected_str: "MVMVA 1, 2, 1, 0, 0".to_string() },
TestEntry { word: 0x4A4D0012, imm_override: None, expected_str: "MVMVA 1, 2, 2, 0, 0".to_string() },
TestEntry { word: 0x4A4D8012, imm_override: None, expected_str: "MVMVA 1, 2, 3, 0, 0".to_string() },
TestEntry { word: 0x4A4C2012, imm_override: None, expected_str: "MVMVA 1, 2, 0, 1, 0".to_string() },
TestEntry { word: 0x4A4CA012, imm_override: None, expected_str: "MVMVA 1, 2, 1, 1, 0".to_string() },
TestEntry { word: 0x4A4D2012, imm_override: None, expected_str: "MVMVA 1, 2, 2, 1, 0".to_string() },
TestEntry { word: 0x4A4DA012, imm_override: None, expected_str: "MVMVA 1, 2, 3, 1, 0".to_string() },
TestEntry { word: 0x4AA80428, imm_override: None, expected_str: "SQR 1".to_string() },
TestEntry { word: 0x4AA80428, imm_override: None, expected_str: "SQR 1".to_string() },
TestEntry { word: 0x4B78000C, imm_override: None, expected_str: "OP 1".to_string() },
TestEntry { word: 0x4B70000C, imm_override: None, expected_str: "OP 0".to_string() },
TestEntry { word: 0x4B98003D, imm_override: None, expected_str: "GPF 1".to_string() },
TestEntry { word: 0x4B90003D, imm_override: None, expected_str: "GPF 0".to_string() },
TestEntry { word: 0x4BA8003E, imm_override: None, expected_str: "GPL 1".to_string() },
TestEntry { word: 0x4BA0003E, imm_override: None, expected_str: "GPL 0".to_string() },
];
for entry in entries.iter() {
let instr = instruction::Instruction::new(entry.word, 0x80000000, instr_category_enum::InstrCategory::R3000GTE);
assert_eq!(
instr.disassemble(entry.imm_override.as_ref().map(|x| x.as_str()), 0),
entry.expected_str
);
}
}
}

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

@ -23,3 +23,10 @@ pub fn shiftl(v: u32, s: u32, w: u32) -> u32 {
pub fn shiftr(v: u32, s: u32, w: u32) -> u32 {
mask(v >> s, w)
}
pub fn convert_option_string_to_option_str(input: &Option<String>) -> Option<&str> {
match input {
None => None,
Some(x) => Some(x.as_str())
}
}

View File

@ -1,25 +1,29 @@
# SPDX-FileCopyrightText: © 2022 Decompollaborate
# SPDX-FileCopyrightText: © 2022-2023 Decompollaborate
# SPDX-License-Identifier: MIT
from setuptools import setup, Extension
from pathlib import Path
import platform
bindingsPath = Path("rabbitizer")
srcPath = Path("src")
sourcesList = [str(x) for x in bindingsPath.glob("**/*.c")] + [str(x) for x in srcPath.glob("**/*.c")]
extraCompileArgs = ["-std=c11", "-Wall", "-g",]
if platform.system() == "Linux":
extraCompileArgs += ["-Os", "-Wextra",]
extraCompileArgs += ["-Werror=vla", "-Werror=switch", "-Werror=implicit-fallthrough", "-Werror=unused-function", "-Werror=unused-parameter", "-Werror=shadow", "-Werror=switch"]
extraCompileArgs += ["-Werror=implicit-function-declaration", "-Werror=incompatible-pointer-types"]
extraCompileArgs += ["-Werror"]
setup(
ext_modules=[
Extension(
name="rabbitizer",
sources=sourcesList,
include_dirs=["include", "rabbitizer"],
extra_compile_args = [
"-std=c11",
"-Wall",
"-g",
],
extra_compile_args = extraCompileArgs,
),
],
)