flycast/core/hw/sh4/dyna/shil.h

151 lines
2.9 KiB
C++

#pragma once
#include "hw/sh4/sh4_if.h"
struct shil_opcode;
typedef void shil_chfp(shil_opcode* op);
extern shil_chfp* shil_chf[];
enum shil_param_type
{
FMT_NULL,
FMT_IMM,
FMT_I32,
FMT_F32,
FMT_F64,
FMT_V4,
FMT_V16,
FMT_REG_BASE = FMT_I32,
FMT_VECTOR_BASE = FMT_V4,
FMT_MASK = 0xFFFF,
};
/*
formats : 16u 16s 32u 32s, 32f, 64f
param types: r32, r64
*/
#define SHIL_MODE 0
#include "shil_canonical.h"
struct shil_param
{
shil_param()
{
type = FMT_NULL;
_imm = 0xFFFFFFFF;
memset(version, 0, sizeof(version));
}
shil_param(u32 imm)
{
this->type = FMT_IMM;
_imm = imm;
memset(version, 0, sizeof(version));
}
shil_param(Sh4RegType reg)
{
if (reg >= reg_fr_0 && reg <= reg_xf_15)
{
type = FMT_F32;
_imm = reg;
}
else if (reg >= regv_dr_0 && reg <= regv_dr_14)
{
type = FMT_F64;
_imm = (reg - regv_dr_0) * 2 + reg_fr_0;
}
else if (reg >= regv_xd_0 && reg <= regv_xd_14)
{
type = FMT_F64;
_imm = (reg - regv_xd_0) * 2 + reg_xf_0;
}
else if (reg >= regv_fv_0 && reg <= regv_fv_12)
{
type = FMT_V4;
_imm = (reg - regv_fv_0) * 4 + reg_fr_0;
}
else if (reg == regv_xmtrx)
{
type = FMT_V16;
_imm = reg_xf_0;
}
else if (reg == regv_fmtrx)
{
type = FMT_V16;
_imm = reg_fr_0;
}
else
{
type = FMT_I32;
_reg = reg;
}
memset(version, 0, sizeof(version));
}
union
{
u32 _imm;
Sh4RegType _reg;
};
u32 type;
u16 version[16];
bool is_null() const { return type==FMT_NULL; }
bool is_imm() const { return type==FMT_IMM; }
bool is_reg() const { return type>=FMT_REG_BASE; }
bool is_r32i() const { return type==FMT_I32; }
bool is_r32f() const { return type==FMT_F32; }
u32 is_r32fv() const { return type >= FMT_VECTOR_BASE ? count() : 0; }
bool is_r64f() const { return type==FMT_F64; }
bool is_r32() const { return is_r32i() || is_r32f(); }
bool is_imm_s8() const { return is_imm() && (int8_t)_imm == (int32_t)_imm; }
u32* reg_ptr() const { verify(is_reg()); return GetRegPtr(_reg); }
s32 reg_nofs() const { verify(is_reg()); return (s32)((u8*)GetRegPtr(_reg) - (u8*)GetRegPtr(reg_xf_0)-sizeof(Sh4cntx)); }
u32 reg_aofs() const { return -reg_nofs(); }
u32 imm_value() const { verify(is_imm()); return _imm; }
u32 count() const { return type == FMT_F64 ? 2 :
type == FMT_V4 ? 4 :
type == FMT_V16 ? 16 : 1; } //count of hardware regs
/*
Imms:
is_imm
regs:
integer regs : is_r32i,is_r32,count=1
fpu regs, single view : is_r32f,is_r32,count=1
fpu regs, double view : is_r64f,count=2
fpu regs, quad view : is_r32fv=4, count=4
fpu regs, matrix view : is_r32fv=16, count=16
*/
};
struct shil_opcode
{
shilop op;
u32 size; // memory access size
shil_param rd, rd2;
shil_param rs1, rs2, rs3;
u16 host_offs;
u16 guest_offs;
bool delay_slot;
std::string dissasm() const;
};
const char* shil_opcode_name(int op);
std::string name_reg(Sh4RegType reg);