diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index b1e5316..63926b7 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -16,4 +16,7 @@ jobs: run: make -j $(nproc) WERROR=1 - name: Run logic checks - run: ./tests/c/logic_checks/run_logic_checks.sh + run: ./tests/run_logic_checks.sh + + - name: Run instruction checks + run: ./tests/run_instruction_checks.sh diff --git a/.github/workflows/publish_crate.yml b/.github/workflows/publish_crate.yml index 818166f..06c5de8 100644 --- a/.github/workflows/publish_crate.yml +++ b/.github/workflows/publish_crate.yml @@ -18,9 +18,9 @@ jobs: toolchain: stable override: true + - name: Build Rust tests + run: cargo test + - name: Upload crate if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} - - - name: Build Rust bindings - run: cargo build --release diff --git a/tests/c/instruction_checks/jalr.c b/tests/c/instruction_checks/jalr.c new file mode 100644 index 0000000..ff21712 --- /dev/null +++ b/tests/c/instruction_checks/jalr.c @@ -0,0 +1,92 @@ +/* SPDX-FileCopyrightText: © 2022 Decompollaborate */ +/* SPDX-License-Identifier: MIT */ + +#include "rabbitizer.h" + +#include +#include +#include +#include + +#define STR_STARTS_WITH(str, prefix) (strncmp((str), (prefix), strlen((prefix))) == 0) +#define INSTR_OPCODE_PREFIX "jalr " + +int main() { + uint32_t word = 0x00000009; // jalr + RabbitizerInstruction instr; + size_t rs; + int errorCount = 0; + + for (rs = 0; rs < RAB_REGISTERS_COUNT; rs++) { + uint32_t shifted_rs = RAB_INSTR_PACK_rs(0, rs); + size_t rd; + + for (rd = 0; rd < RAB_REGISTERS_COUNT; rd++) { + uint32_t shifted_rd = RAB_INSTR_PACK_rd(0, rd); + char buffer[0x100]; + char *bufferPtr = buffer; + uint32_t new_word = word | shifted_rd | shifted_rs; + + memset(buffer, 0, sizeof(buffer)); + + RabbitizerInstruction_init(&instr, new_word, 0x80000000); + RabbitizerInstruction_processUniqueId(&instr); + + RabbitizerInstruction_disassemble(&instr, buffer, NULL, 0, 0); + + if (!STR_STARTS_WITH(bufferPtr, INSTR_OPCODE_PREFIX)) { + fprintf(stderr, "Error in word 0x%08X. Missing '%s'\n", new_word, INSTR_OPCODE_PREFIX); + errorCount++; + } else { + const char *rsName = RabbitizerRegister_getNameGpr(rs); + bufferPtr += strlen(INSTR_OPCODE_PREFIX); + + if (rd == RABBITIZER_REG_GPR_O32_ra) { + if (!STR_STARTS_WITH(bufferPtr, rsName)) { + fprintf(stderr, "Error in word 0x%08X. Expected '%s', got '%s'\n", new_word, rsName, bufferPtr); + errorCount++; + } else { + bufferPtr += strlen(rsName); + + if (*bufferPtr != '\0') { + fprintf(stderr, "Error in word 0x%08X. Extraneous character found '%c'. String: '%s'\n", new_word, *bufferPtr, bufferPtr); + errorCount++; + } + } + } else { + const char *rdName = RabbitizerRegister_getNameGpr(rd); + + if (!STR_STARTS_WITH(bufferPtr, rdName)) { + fprintf(stderr, "Error in word 0x%08X. Expected '%s', got '%s'\n", new_word, rdName, bufferPtr); + errorCount++; + } else { + bufferPtr += strlen(rdName); + + if (!STR_STARTS_WITH(bufferPtr, ", ")) { + fprintf(stderr, "Error in word 0x%08X. Expected '%s', got '%s'\n", new_word, ", ", bufferPtr); + errorCount++; + } else { + bufferPtr += strlen(", "); + + if (!STR_STARTS_WITH(bufferPtr, rsName)) { + fprintf(stderr, "Error in word 0x%08X. Expected '%s', got '%s'\n", new_word, rsName, bufferPtr); + errorCount++; + } else { + bufferPtr += strlen(rsName); + + if (*bufferPtr != '\0') { + fprintf(stderr, "Error in word 0x%08X. Extraneous character found '%c'. String: '%s'\n", new_word, *bufferPtr, bufferPtr); + errorCount++; + } + } + } + } + } + } + + RabbitizerInstruction_destroy(&instr); + } + } + + return errorCount; +} diff --git a/tests/run_instruction_checks.sh b/tests/run_instruction_checks.sh new file mode 100755 index 0000000..4e7207e --- /dev/null +++ b/tests/run_instruction_checks.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: © 2022 Decompollaborate +# SPDX-License-Identifier: MIT + +set -e + +./build/tests/c/instruction_checks/jalr.elf diff --git a/tests/c/logic_checks/run_logic_checks.sh b/tests/run_logic_checks.sh similarity index 100% rename from tests/c/logic_checks/run_logic_checks.sh rename to tests/run_logic_checks.sh