rabbitizer/include/instructions/RabbitizerInstruction.h
Angie 0c678ab6df remove specific registers from instruction struct
do bitwise operations to access them instead
2022-07-03 08:34:26 -04:00

170 lines
7.3 KiB
C

/* 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"
#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;
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_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_op(self) (SHIFTR((self)->word, 16, 5))
#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_cop0d(self) (SHIFTR((self)->word, 11, 5))
#define RAB_INSTR_GET_cop2t(self) (SHIFTR((self)->word, 16, 5))
#define RAB_INSTR_SET_opcode(self, value) ((self)->word = BITREPACK((self)->word, value, 26, 6))
#define RAB_INSTR_SET_rs(self, value) ((self)->word = BITREPACK((self)->word, value, 21, 5))
#define RAB_INSTR_SET_rt(self, value) ((self)->word = BITREPACK((self)->word, value, 16, 5))
#define RAB_INSTR_SET_rd(self, value) ((self)->word = BITREPACK((self)->word, value, 11, 5))
#define RAB_INSTR_SET_sa(self, value) ((self)->word = BITREPACK((self)->word, value, 6, 5))
#define RAB_INSTR_SET_function(self, value) ((self)->word = BITREPACK((self)->word, value, 0, 6))
#define RAB_INSTR_SET_instr_index(self, value) ((self)->word = BITREPACK((self)->word, value, 0, 26))
#define RAB_INSTR_SET_immediate(self, value) ((self)->word = BITREPACK((self)->word, value, 0, 16))
#define RAB_INSTR_SET_code(self, value) ((self)->word = BITREPACK((self)->word, value, 6, 20))
#define RAB_INSTR_SET_fs(self, value) ((self)->word = BITREPACK((self)->word, value, 11, 5))
#define RAB_INSTR_SET_ft(self, value) ((self)->word = BITREPACK((self)->word, value, 16, 5))
#define RAB_INSTR_SET_fd(self, value) ((self)->word = BITREPACK((self)->word, value, 6, 5))
void RabbitizerInstruction_init(RabbitizerInstruction *self, uint32_t word);
void RabbitizerInstruction_destroy(RabbitizerInstruction* self);
/* Process uniqueId */
void RabbitizerInstruction_processUniqueId_Normal(RabbitizerInstruction *self);
void RabbitizerInstruction_processUniqueId_Special(RabbitizerInstruction *self);
void RabbitizerInstruction_processUniqueId_Regimm(RabbitizerInstruction *self);
void RabbitizerInstruction_processUniqueId_Coprocessor0(RabbitizerInstruction *self);
void RabbitizerInstruction_processUniqueId_Coprocessor1(RabbitizerInstruction *self);
void RabbitizerInstruction_processUniqueId_Coprocessor2(RabbitizerInstruction *self);
void RabbitizerInstruction_processUniqueId(RabbitizerInstruction *self);
/* Process uniqueId */
/* Register getters */
uint8_t RabbitizerInstruction_getFs(const RabbitizerInstruction* self);
uint8_t RabbitizerInstruction_getFt(const RabbitizerInstruction* self);
uint8_t RabbitizerInstruction_getFd(const RabbitizerInstruction* self);
/* Register getters */
/* Coprocessor stuffs */
uint8_t RabbitizerInstruction_getFmt(const RabbitizerInstruction *self);
uint8_t RabbitizerInstruction_getTf(const RabbitizerInstruction *self);
uint8_t RabbitizerInstruction_getNd(const RabbitizerInstruction *self);
uint8_t RabbitizerInstruction_getFc(const RabbitizerInstruction *self);
uint8_t RabbitizerInstruction_getCond(const RabbitizerInstruction *self);
/* Coprocessor stuffs */
/* General getters */
uint32_t RabbitizerInstruction_getRaw(const RabbitizerInstruction *self);
uint32_t RabbitizerInstruction_getImmediate(const RabbitizerInstruction *self);
uint32_t RabbitizerInstruction_getInstrIndex(const RabbitizerInstruction *self);
uint32_t RabbitizerInstruction_getInstrIndexAsVram(const RabbitizerInstruction *self);
int32_t RabbitizerInstruction_getBranchOffset(const RabbitizerInstruction *self);
int32_t RabbitizerInstruction_getGenericBranchOffset(const RabbitizerInstruction *self, uint32_t currentVram);
/* General getters */
void RabbitizerInstruction_blankOut(RabbitizerInstruction *self);
/* Instruction examination */
bool RabbitizerInstruction_isImplemented(const RabbitizerInstruction *self);
bool RabbitizerInstruction_isLikelyHandwritten(const RabbitizerInstruction *self);
bool RabbitizerInstruction_isNop(const RabbitizerInstruction *self);
bool RabbitizerInstruction_isUnconditionalBranch(const RabbitizerInstruction *self);
bool RabbitizerInstruction_isJrRa(const RabbitizerInstruction *self);
bool RabbitizerInstruction_isJrNotRa(const RabbitizerInstruction *self);
const char *RabbitizerInstruction_mapInstrToType(const RabbitizerInstruction *self);
bool RabbitizerInstruction_sameOpcode(const RabbitizerInstruction *self, const RabbitizerInstruction *other);
bool RabbitizerInstruction_sameOpcodeButDifferentArguments(const RabbitizerInstruction *self, const RabbitizerInstruction *other);
/* Instruction examination */
/* Disassembly */
bool RabbitizerInstruction_mustDisasmAsData(const RabbitizerInstruction *self);
size_t RabbitizerInstruction_getSizeForBufferInstrDisasm(const RabbitizerInstruction *self, size_t immOverrideLength, int extraLJust);
size_t RabbitizerInstruction_disassembleInstruction(const RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength, int extraLJust);
size_t RabbitizerInstruction_getSizeForBufferDataDisasm(const RabbitizerInstruction *self, int extraLJust);
size_t RabbitizerInstruction_disassembleAsData(const RabbitizerInstruction *self, char *dst, int extraLJust);
size_t RabbitizerInstruction_getSizeForBuffer(const RabbitizerInstruction *self, size_t immOverrideLength, int extraLJust);
size_t RabbitizerInstruction_disassemble(const RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength, int extraLJust);
/* Disassembly */
#endif