2017-08-18 05:08:22 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
2022-09-26 02:31:54 +00:00
|
|
|
typedef void (*ASM_SYNTAX_FN)(uint32_t * opcode);
|
2017-08-18 05:08:22 +00:00
|
|
|
|
2022-09-26 02:31:54 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const char * name;
|
2017-09-13 10:36:03 +00:00
|
|
|
uint32_t val;
|
2022-09-26 02:31:54 +00:00
|
|
|
uint32_t (*base)(uint32_t val); // Value shift
|
|
|
|
const ASM_SYNTAX_FN * syntax; // Arguments
|
2018-01-21 09:36:20 +00:00
|
|
|
} ASM_INSTRUCTION;
|
2017-08-18 05:08:22 +00:00
|
|
|
|
2022-09-26 02:31:54 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const char * name;
|
2017-09-13 10:36:03 +00:00
|
|
|
uint32_t val;
|
2018-01-21 09:36:20 +00:00
|
|
|
} ASM_REGISTER;
|
2017-08-18 05:08:22 +00:00
|
|
|
|
2018-01-21 09:36:20 +00:00
|
|
|
enum ASM_PARSE_ERROR
|
2017-08-18 05:08:22 +00:00
|
|
|
{
|
2017-09-13 10:36:03 +00:00
|
|
|
ERR_NONE,
|
|
|
|
ERR_EXPECTED_REG,
|
|
|
|
ERR_INVALID_REG,
|
2018-01-21 09:36:20 +00:00
|
|
|
ERR_EXPECTED_VAL,
|
|
|
|
ERR_UNKNOWN_CMD
|
2017-08-18 05:08:22 +00:00
|
|
|
};
|
|
|
|
|
2018-01-21 09:36:20 +00:00
|
|
|
class CAssembler
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
static uint32_t m_Address;
|
|
|
|
static ASM_PARSE_ERROR m_ParseError;
|
|
|
|
|
2017-08-18 05:08:22 +00:00
|
|
|
public:
|
2022-09-26 02:31:54 +00:00
|
|
|
static bool AssembleLine(const char * line, uint32_t * opcode, uint32_t address = 0x00000000);
|
2018-01-21 09:36:20 +00:00
|
|
|
|
|
|
|
private:
|
2020-10-26 17:01:21 +00:00
|
|
|
static const ASM_SYNTAX_FN syn_jump[];
|
|
|
|
static const ASM_SYNTAX_FN syn_loadstore[];
|
|
|
|
static const ASM_SYNTAX_FN syn_arith[];
|
|
|
|
static const ASM_SYNTAX_FN syn_arith2[];
|
|
|
|
static const ASM_SYNTAX_FN syn_shiftv[];
|
|
|
|
static const ASM_SYNTAX_FN syn_arith_i[];
|
|
|
|
static const ASM_SYNTAX_FN syn_load_i[];
|
|
|
|
static const ASM_SYNTAX_FN syn_branch_z[];
|
|
|
|
static const ASM_SYNTAX_FN syn_branch[];
|
|
|
|
static const ASM_SYNTAX_FN syn_branch_unc[];
|
|
|
|
static const ASM_SYNTAX_FN syn_trap_i[];
|
|
|
|
static const ASM_SYNTAX_FN syn_shift[];
|
|
|
|
static const ASM_SYNTAX_FN syn_mf[];
|
|
|
|
static const ASM_SYNTAX_FN syn_jr[];
|
|
|
|
static const ASM_SYNTAX_FN syn_jalr[];
|
|
|
|
static const ASM_SYNTAX_FN syn_cop1_arith[];
|
|
|
|
static const ASM_SYNTAX_FN syn_cop1[];
|
|
|
|
static const ASM_SYNTAX_FN syn_cop1_cmp[];
|
|
|
|
static const ASM_SYNTAX_FN syn_cop_mv[];
|
|
|
|
static const ASM_SYNTAX_FN syn_cache[];
|
|
|
|
static const ASM_SYNTAX_FN syn_syscall[];
|
|
|
|
|
|
|
|
static const ASM_INSTRUCTION m_Instructions[];
|
|
|
|
static const ASM_REGISTER m_Registers[];
|
|
|
|
|
2022-09-26 02:31:54 +00:00
|
|
|
static char * m_TokContext;
|
2018-01-21 09:36:20 +00:00
|
|
|
|
2022-09-26 02:31:54 +00:00
|
|
|
static const ASM_REGISTER * LookupRegister(char * name);
|
|
|
|
static const ASM_INSTRUCTION * LookupInstruction(char * name, int nFallback);
|
|
|
|
|
|
|
|
static void StrToLower(char * str);
|
2018-01-21 09:36:20 +00:00
|
|
|
|
|
|
|
static uint32_t pop_reg();
|
|
|
|
static uint32_t pop_val();
|
2022-09-26 02:31:54 +00:00
|
|
|
|
2018-01-21 09:36:20 +00:00
|
|
|
static uint32_t base_op(uint32_t val);
|
|
|
|
static uint32_t base_spec(uint32_t val);
|
|
|
|
static uint32_t base_spec_jalr_ra(uint32_t val);
|
|
|
|
static uint32_t base_regimm(uint32_t val);
|
|
|
|
static uint32_t base_cop1_s(uint32_t val);
|
|
|
|
static uint32_t base_cop1_d(uint32_t val);
|
2020-10-26 17:01:21 +00:00
|
|
|
static uint32_t base_cop1_w(uint32_t val);
|
|
|
|
static uint32_t base_cop1_l(uint32_t val);
|
2018-01-21 09:36:20 +00:00
|
|
|
static uint32_t base_cop1_bc(uint32_t val);
|
|
|
|
static uint32_t base_cop0_co(uint32_t val);
|
|
|
|
static uint32_t base_cop0_mv(uint32_t val);
|
|
|
|
static uint32_t base_cop1_mv(uint32_t val);
|
|
|
|
|
2022-09-26 02:31:54 +00:00
|
|
|
static void arg_reg_t(uint32_t * opcode);
|
|
|
|
static void arg_reg_s(uint32_t * opcode);
|
|
|
|
static void arg_reg_d(uint32_t * opcode);
|
|
|
|
static void arg_reg_ft(uint32_t * opcode);
|
|
|
|
static void arg_reg_fs(uint32_t * opcode);
|
|
|
|
static void arg_reg_fd(uint32_t * opcode);
|
|
|
|
static void arg_jump(uint32_t * opcode);
|
|
|
|
static void arg_imm16(uint32_t * opcode);
|
|
|
|
static void arg_bra_target(uint32_t * opcode);
|
|
|
|
static void arg_shamt(uint32_t * opcode);
|
|
|
|
static void arg_cache_op(uint32_t * opcode);
|
|
|
|
static void arg_syscall_code(uint32_t * opcode);
|
2017-08-18 05:08:22 +00:00
|
|
|
};
|