1132 lines
17 KiB
C
1132 lines
17 KiB
C
/*
|
|
|
|
This is a header file that can create
|
|
SHIL_MODE == 0) Shil opcode enums
|
|
SHIL_MODE == 1) Shil opcode classes/portable C implementation ("canonical" implementation)
|
|
SHIL_MODE == 2) Shil opcode classes declaration
|
|
SHIL_MODE == 3) The routing table for canonical implementations
|
|
SHIL_MODE == 4) opcode name list (for logging/disass)
|
|
*/
|
|
|
|
#define fsca_impl fsca_table
|
|
|
|
#if SHIL_MODE==0
|
|
//generate enums ..
|
|
#define SHIL_START enum shilop {
|
|
#define SHIL_END shop_max, };
|
|
|
|
#define shil_opc(name) shop_##name,
|
|
#define shil_opc_end()
|
|
|
|
#define shil_canonical(rv,name,args,code)
|
|
#define shil_compile(code)
|
|
#elif SHIL_MODE==1
|
|
//generate structs ...
|
|
#define SHIL_START
|
|
#define SHIL_END
|
|
|
|
#define shil_opc(name) struct shil_opcl_##name {
|
|
#define shil_opc_end() };
|
|
|
|
#define shil_canonical(rv,name,args,code) struct name { static rv impl args { code } };
|
|
|
|
#define shil_cf_arg_u32(x) ngen_CC_Param(op,&op->x,CPT_u32);
|
|
#define shil_cf_arg_f32(x) ngen_CC_Param(op,&op->x,CPT_f32);
|
|
#define shil_cf_arg_ptr(x) ngen_CC_Param(op,&op->x,CPT_ptr);
|
|
#define shil_cf_rv_u32(x) ngen_CC_Param(op,&op->x,CPT_u32rv);
|
|
#define shil_cf_rv_f32(x) ngen_CC_Param(op,&op->x,CPT_f32rv);
|
|
#define shil_cf_rv_u64(x) ngen_CC_Param(op,&op->rd,CPT_u64rvL); ngen_CC_Param(op,&op->rd2,CPT_u64rvH);
|
|
#define shil_cf(x) ngen_CC_Call(op, (void *)&x::impl);
|
|
|
|
#define shil_compile(code) static void compile(shil_opcode* op) { ngen_CC_Start(op); code ngen_CC_Finish(op); }
|
|
#elif SHIL_MODE==2
|
|
//generate struct declarations ...
|
|
#define SHIL_START
|
|
#define SHIL_END
|
|
|
|
#define shil_opc(name) struct shil_opcl_##name {
|
|
#define shil_opc_end() };
|
|
|
|
#define shil_canonical(rv,name,args,code) struct name { static rv impl args; };
|
|
#define shil_compile(code) static void compile(shil_opcode* op);
|
|
#elif SHIL_MODE==3
|
|
//generate struct list ...
|
|
|
|
|
|
#define SHIL_START \
|
|
shil_chfp* shil_chf[] = {
|
|
|
|
#define SHIL_END };
|
|
|
|
#define shil_opc(name) &shil_opcl_##name::compile,
|
|
#define shil_opc_end()
|
|
|
|
#define shil_canonical(rv,name,args,code)
|
|
#define shil_compile(code)
|
|
#elif SHIL_MODE==4
|
|
//generate name strings ..
|
|
#define SHIL_START const char* shilop_str[]={
|
|
#define SHIL_END };
|
|
|
|
#define shil_opc(name) #name,
|
|
#define shil_opc_end()
|
|
|
|
#define shil_canonical(rv,name,args,code)
|
|
#define shil_compile(code)
|
|
#else
|
|
#error Invalid SHIL_MODE
|
|
#endif
|
|
|
|
|
|
|
|
#if SHIL_MODE==1 || SHIL_MODE==2
|
|
//only in structs we use the code :)
|
|
#include <cmath>
|
|
#include "types.h"
|
|
#include "shil.h"
|
|
#include "decoder.h"
|
|
#include "../sh4_rom.h"
|
|
|
|
#define BIN_OP_I_BASE(code,type,rtype) \
|
|
shil_canonical \
|
|
( \
|
|
rtype,f1,(type r1,type r2), \
|
|
code \
|
|
) \
|
|
\
|
|
shil_compile \
|
|
( \
|
|
shil_cf_arg_##type(rs2); \
|
|
shil_cf_arg_##type(rs1); \
|
|
shil_cf(f1); \
|
|
shil_cf_rv_##rtype(rd); \
|
|
)
|
|
|
|
#define UN_OP_I_BASE(code,type) \
|
|
shil_canonical \
|
|
( \
|
|
type,f1,(type r1), \
|
|
code \
|
|
) \
|
|
\
|
|
shil_compile \
|
|
( \
|
|
shil_cf_arg_##type(rs1); \
|
|
shil_cf(f1); \
|
|
shil_cf_rv_##type(rd); \
|
|
)
|
|
|
|
|
|
#define BIN_OP_I(z) BIN_OP_I_BASE( return r1 z r2; ,u32,u32)
|
|
|
|
#define BIN_OP_I2(tp,z) BIN_OP_I_BASE( return ((tp) r1) z ((tp) r2); ,u32,u32)
|
|
#define BIN_OP_I3(z,w) BIN_OP_I_BASE( return (r1 z r2) w; ,u32,u32)
|
|
#define BIN_OP_I4(tp,z,rt,pt) BIN_OP_I_BASE( return ((tp)(pt)r1) z ((tp)(pt)r2); ,u32,rt)
|
|
|
|
#define BIN_OP_F(z) BIN_OP_I_BASE( return fixNaN(r1 z r2); ,f32,f32)
|
|
#define BIN_OP_FU(z) BIN_OP_I_BASE( return fixNaN(r1 z r2); ,f32,u32)
|
|
|
|
#define UN_OP_I(z) UN_OP_I_BASE( return z (r1); ,u32)
|
|
#define UN_OP_F(z) UN_OP_I_BASE( return z (r1); ,f32)
|
|
|
|
#define shil_recimp() \
|
|
shil_compile( \
|
|
die("This opcode requires native dynarec implementation"); \
|
|
)
|
|
|
|
#else
|
|
|
|
#define BIN_OP_I(z)
|
|
|
|
#define BIN_OP_I2(tp,z)
|
|
#define BIN_OP_I3(z,w)
|
|
#define BIN_OP_I4(tp,z,rt,k)
|
|
|
|
#define BIN_OP_F(z)
|
|
#define BIN_OP_FU(z)
|
|
|
|
#define UN_OP_I(z)
|
|
#define UN_OP_F(z)
|
|
#define shil_recimp()
|
|
#endif
|
|
|
|
|
|
|
|
SHIL_START
|
|
|
|
|
|
//shop_mov32
|
|
shil_opc(mov32)
|
|
shil_recimp()
|
|
shil_opc_end()
|
|
|
|
//shop_mov64
|
|
shil_opc(mov64)
|
|
shil_recimp()
|
|
shil_opc_end()
|
|
|
|
//Special opcodes
|
|
shil_opc(jdyn)
|
|
shil_recimp()
|
|
shil_opc_end()
|
|
|
|
shil_opc(jcond)
|
|
shil_recimp()
|
|
shil_opc_end()
|
|
|
|
//shop_ifb
|
|
shil_opc(ifb)
|
|
shil_recimp()
|
|
shil_opc_end()
|
|
|
|
//mem io
|
|
shil_opc(readm)
|
|
shil_recimp()
|
|
shil_opc_end()
|
|
|
|
shil_opc(writem)
|
|
shil_recimp()
|
|
shil_opc_end()
|
|
|
|
//Canonical impl. opcodes !
|
|
shil_opc(sync_sr)
|
|
shil_canonical
|
|
(
|
|
void, f1, (),
|
|
UpdateSR();
|
|
)
|
|
shil_compile
|
|
(
|
|
shil_cf(f1);
|
|
)
|
|
shil_opc_end()
|
|
|
|
shil_opc(sync_fpscr)
|
|
shil_canonical
|
|
(
|
|
void, f1, (),
|
|
UpdateFPSCR();
|
|
)
|
|
shil_compile
|
|
(
|
|
shil_cf(f1);
|
|
)
|
|
shil_opc_end()
|
|
|
|
//shop_and
|
|
shil_opc(and)
|
|
BIN_OP_I(&)
|
|
shil_opc_end()
|
|
|
|
//shop_or
|
|
shil_opc(or)
|
|
BIN_OP_I(|)
|
|
shil_opc_end()
|
|
|
|
//shop_xor
|
|
shil_opc(xor)
|
|
BIN_OP_I(^)
|
|
shil_opc_end()
|
|
|
|
//shop_not
|
|
shil_opc(not)
|
|
UN_OP_I(~)
|
|
shil_opc_end()
|
|
|
|
//shop_add
|
|
shil_opc(add)
|
|
BIN_OP_I(+)
|
|
shil_opc_end()
|
|
|
|
//shop_sub
|
|
shil_opc(sub)
|
|
BIN_OP_I(-)
|
|
shil_opc_end()
|
|
|
|
//shop_neg
|
|
shil_opc(neg)
|
|
UN_OP_I(-)
|
|
shil_opc_end()
|
|
|
|
//shop_shl,
|
|
shil_opc(shl)
|
|
BIN_OP_I2(u32,<<)
|
|
shil_opc_end()
|
|
|
|
//shop_shr
|
|
shil_opc(shr)
|
|
BIN_OP_I2(u32,>>)
|
|
shil_opc_end()
|
|
|
|
//shop_sar
|
|
shil_opc(sar)
|
|
BIN_OP_I2(s32,>>)
|
|
shil_opc_end()
|
|
|
|
//shop_adc //add with carry
|
|
shil_opc(adc)
|
|
shil_canonical
|
|
(
|
|
u64,f1,(u32 r1,u32 r2,u32 C),
|
|
u64 res=(u64)r1+r2+C;
|
|
|
|
u64 rv;
|
|
((u32*)&rv)[0]=res;
|
|
((u32*)&rv)[1]=res>>32;
|
|
|
|
return rv;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs3);
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u64(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
|
|
//shop_sbc // substract with carry
|
|
shil_opc(sbc)
|
|
shil_canonical
|
|
(
|
|
u64,f1,(u32 r1,u32 r2,u32 C),
|
|
u64 res=(u64)r1-r2-C;
|
|
|
|
u64 rv;
|
|
((u32*)&rv)[0]=res;
|
|
((u32*)&rv)[1]=(res>>32)&1; //alternatively: res>>63
|
|
|
|
return rv;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs3);
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u64(rd);
|
|
)
|
|
shil_opc_end()
|
|
|
|
//shop_negc - Negate with carry
|
|
shil_opc(negc)
|
|
shil_canonical
|
|
(
|
|
u64,f1,(u32 r1, u32 C),
|
|
u64 res = -(u64)r1 - C;
|
|
|
|
u64 rv;
|
|
((u32*)&rv)[0]=res;
|
|
((u32*)&rv)[1]=(res>>32)&1;
|
|
|
|
return rv;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u64(rd);
|
|
)
|
|
shil_opc_end()
|
|
|
|
//shop_ror
|
|
shil_opc(ror)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(u32 r1,u32 amt),
|
|
return (r1>>amt)|(r1<<(32-amt));
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
|
|
//shop_rocl
|
|
shil_opc(rocl)
|
|
shil_canonical
|
|
(
|
|
u64,f1,(u32 r1,u32 r2),
|
|
u64 rv;
|
|
((u32*)&rv)[0]=(r1<<1)|r2;
|
|
((u32*)&rv)[1]=r1>>31;
|
|
return rv;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u64(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_rocr
|
|
shil_opc(rocr)
|
|
shil_canonical
|
|
(
|
|
u64,f1,(u32 r1,u32 r2),
|
|
u64 rv;
|
|
((u32*)&rv)[0]=(r1>>1)|(r2<<31);
|
|
((u32*)&rv)[1]=r1&1;
|
|
return rv;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u64(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_swaplb -- swap low bytes
|
|
shil_opc(swaplb)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(u32 r1),
|
|
return (r1 & 0xFFFF0000) | ((r1&0xFF)<<8) | ((r1>>8)&0xFF);
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
|
|
//shop_swap -- swap all bytes in word
|
|
shil_opc(swap)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(u32 r1),
|
|
return (r1 >>24) | ((r1 >>16)&0xFF00) |((r1&0xFF00)<<8) | (r1<<24);
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_shld
|
|
shil_opc(shld)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(u32 r1,u32 r2),
|
|
u32 sgn = r2 & 0x80000000;
|
|
if (sgn == 0)
|
|
return r1 << (r2 & 0x1F);
|
|
else if ((r2 & 0x1F) == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
return r1 >> ((~r2 & 0x1F) + 1);
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
shil_opc_end()
|
|
|
|
//shop_shad
|
|
shil_opc(shad)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(s32 r1,u32 r2),
|
|
u32 sgn = r2 & 0x80000000;
|
|
if (sgn == 0)
|
|
return r1 << (r2 & 0x1F);
|
|
else if ((r2 & 0x1F) == 0)
|
|
{
|
|
return r1>>31;
|
|
}
|
|
else
|
|
return r1 >> ((~r2 & 0x1F) + 1);
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_ext_s8
|
|
shil_opc(ext_s8)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(u32 r1),
|
|
return (s8)r1;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
|
|
//shop_ext_s16
|
|
shil_opc(ext_s16)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(u32 r1),
|
|
return (s16)r1;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_mul_u16
|
|
shil_opc(mul_u16)
|
|
BIN_OP_I4(u16,*,u32,u32)
|
|
shil_opc_end()
|
|
|
|
//shop_mul_s16
|
|
shil_opc(mul_s16)
|
|
BIN_OP_I4(s16,*,u32,u32)
|
|
shil_opc_end()
|
|
|
|
//no difference between signed and unsigned when only the lower
|
|
//32 bis are used !
|
|
//shop_mul_i32
|
|
shil_opc(mul_i32)
|
|
BIN_OP_I4(s32,*,u32,u32)
|
|
shil_opc_end()
|
|
|
|
//shop_mul_u64
|
|
shil_opc(mul_u64)
|
|
BIN_OP_I4(u64,*,u64,u32)
|
|
shil_opc_end()
|
|
|
|
//shop_mul_s64
|
|
shil_opc(mul_s64)
|
|
BIN_OP_I4(s64,*,u64,s32)
|
|
shil_opc_end()
|
|
|
|
//shop_div32u //divide 32 bits, unsigned
|
|
shil_opc(div32u)
|
|
shil_canonical
|
|
(
|
|
u64,f1,(u32 r1, u32 r2, u32 r3),
|
|
u64 dividend = ((u64)r3 << 32) | r1;
|
|
u32 quo;
|
|
u32 rem;
|
|
if (r2)
|
|
{
|
|
quo = dividend / r2;
|
|
rem = dividend % r2;
|
|
}
|
|
else
|
|
{
|
|
quo = 0;
|
|
rem = dividend;
|
|
}
|
|
|
|
u64 rv;
|
|
((u32*)&rv)[0]=quo;
|
|
((u32*)&rv)[1]=rem;
|
|
return rv;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs3);
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u64(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_div32s //divide 32 bits, signed
|
|
shil_opc(div32s)
|
|
shil_canonical
|
|
(
|
|
u64,f1,(u32 r1, s32 r2, s32 r3),
|
|
s64 dividend = ((s64)r3 << 32) | r1;
|
|
// 1's complement -> 2's complement
|
|
if (dividend < 0)
|
|
dividend++;
|
|
|
|
s32 quo = (s32)(r2 ? dividend / r2 : 0);
|
|
s32 rem = dividend - quo * r2;
|
|
u32 negative = (r3 ^ r2) & 0x80000000;
|
|
// 2's complement -> 1's complement
|
|
if (negative)
|
|
quo--;
|
|
else if (r3 < 0)
|
|
rem--;
|
|
|
|
u64 rv;
|
|
((u32*)&rv)[0]=quo;
|
|
((u32*)&rv)[1]=rem;
|
|
return rv;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs3);
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u64(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_div32p2 //div32, fixup step (part 2)
|
|
shil_opc(div32p2)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(s32 a,s32 b,u32 T),
|
|
// the sign of the quotient is stored in bit 31 of T
|
|
if (!(T & 0x80000000))
|
|
{
|
|
if (!(T & 1))
|
|
a -= b;
|
|
}
|
|
else
|
|
{
|
|
// 2's complement -> 1's complement
|
|
if (b > 0)
|
|
a--;
|
|
if (T & 1)
|
|
a += b;
|
|
}
|
|
|
|
return a;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs3);
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//debug_3
|
|
shil_opc(debug_3)
|
|
shil_canonical
|
|
(
|
|
void,f1,(u32 r1,u32 r2,u32 r3),
|
|
INFO_LOG(DYNAREC, "debug_3: %08X, %08X, %08X", r1, r2, r3);
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs3);
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//debug_1
|
|
shil_opc(debug_1)
|
|
shil_canonical
|
|
(
|
|
void,f1,(u32 r1),
|
|
INFO_LOG(DYNAREC, "debug_1: %08X", r1);
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_cvt_f2i_t //float to integer : truncate
|
|
shil_opc(cvt_f2i_t)
|
|
|
|
#if HOST_CPU == CPU_X86 || HOST_CPU == CPU_X64
|
|
shil_canonical
|
|
(
|
|
u32,f1,(f32 f1),
|
|
if (f1 > 2147483520.0f) // IEEE 754: 0x4effffff
|
|
return 0x7fffffff;
|
|
else
|
|
{
|
|
s32 res = (s32)f1;
|
|
|
|
// Fix result sign for Intel CPUs
|
|
if ((u32)res == 0x80000000 && f1 == f1 && *(s32 *)&f1 > 0)
|
|
res = 0x7fffffff;
|
|
|
|
return res;
|
|
}
|
|
)
|
|
#else
|
|
shil_canonical
|
|
(
|
|
u32,f1,(f32 f1),
|
|
if (f1 > 2147483520.0f) // IEEE 754: 0x4effffff
|
|
return 0x7fffffff;
|
|
else
|
|
return (s32)f1;
|
|
)
|
|
#endif
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_f32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_cvt_i2f_n //integer to float : nearest
|
|
shil_opc(cvt_i2f_n)
|
|
shil_canonical
|
|
(
|
|
f32,f1,(u32 r1),
|
|
return (float)(s32)r1;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_f32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_cvt_i2f_z //integer to float : round to zero
|
|
shil_opc(cvt_i2f_z)
|
|
shil_canonical
|
|
(
|
|
f32,f1,(u32 r1),
|
|
return (float)(s32)r1;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_f32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
|
|
//pref !
|
|
shil_opc(pref)
|
|
shil_canonical
|
|
(
|
|
void,f1,(u32 r1),
|
|
if ((r1>>26) == 0x38) do_sqw_mmu(r1);
|
|
)
|
|
|
|
shil_canonical
|
|
(
|
|
void,f2,(u32 r1),
|
|
if ((r1>>26) == 0x38) do_sqw_nommu(r1,sq_both);
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs1);
|
|
if (CCN_MMUCR.AT)
|
|
{
|
|
shil_cf(f1);
|
|
}
|
|
else
|
|
{
|
|
shil_cf(f2);
|
|
}
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//shop_test
|
|
shil_opc(test)
|
|
BIN_OP_I3(&,== 0)
|
|
shil_opc_end()
|
|
|
|
//shop_seteq //equal
|
|
shil_opc(seteq)
|
|
BIN_OP_I2(s32,==)
|
|
shil_opc_end()
|
|
|
|
//shop_setge //>=, signed (greater equal)
|
|
shil_opc(setge)
|
|
BIN_OP_I2(s32,>=)
|
|
shil_opc_end()
|
|
|
|
//shop_setgt //>, signed (greater than)
|
|
shil_opc(setgt)
|
|
BIN_OP_I2(s32,>)
|
|
shil_opc_end()
|
|
|
|
//shop_setae //>=, unsigned (above equal)
|
|
shil_opc(setae)
|
|
BIN_OP_I2(u32,>=)
|
|
shil_opc_end()
|
|
|
|
//shop_setab //>, unsigned (above)
|
|
shil_opc(setab)
|
|
BIN_OP_I2(u32,>)
|
|
shil_opc_end()
|
|
|
|
//shop_setpeq //set if any pair of bytes is equal
|
|
shil_opc(setpeq)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(u32 r1,u32 r2),
|
|
u32 temp = r1 ^ r2;
|
|
|
|
if ( (temp&0xFF000000) && (temp&0x00FF0000) && (temp&0x0000FF00) && (temp&0x000000FF) )
|
|
return 0;
|
|
else
|
|
return 1;
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
//here come the moving points
|
|
|
|
//shop_fadd
|
|
shil_opc(fadd)
|
|
BIN_OP_F(+)
|
|
shil_opc_end()
|
|
|
|
//shop_fsub
|
|
shil_opc(fsub)
|
|
BIN_OP_F(-)
|
|
shil_opc_end()
|
|
|
|
//shop_fmul
|
|
shil_opc(fmul)
|
|
BIN_OP_F(*)
|
|
shil_opc_end()
|
|
|
|
//shop_fdiv
|
|
shil_opc(fdiv)
|
|
BIN_OP_F(/)
|
|
shil_opc_end()
|
|
|
|
//shop_fabs
|
|
shil_opc(fabs)
|
|
UN_OP_F(fabsf)
|
|
shil_opc_end()
|
|
|
|
//shop_fneg
|
|
shil_opc(fneg)
|
|
UN_OP_F(-)
|
|
shil_opc_end()
|
|
|
|
//shop_fsqrt
|
|
shil_opc(fsqrt)
|
|
UN_OP_F(sqrtf)
|
|
shil_opc_end()
|
|
|
|
//shop_fipr
|
|
shil_opc(fipr)
|
|
|
|
#if HOST_CPU == CPU_X86 || HOST_CPU == CPU_X64
|
|
shil_canonical
|
|
(
|
|
f32,f1,(const float* fn, const float* fm),
|
|
|
|
double idp = (double)fn[0] * fm[0];
|
|
idp += (double)fn[1] * fm[1];
|
|
idp += (double)fn[2] * fm[2];
|
|
idp += (double)fn[3] * fm[3];
|
|
|
|
return fixNaN((float)idp);
|
|
)
|
|
#else
|
|
shil_canonical
|
|
(
|
|
f32,f1,(float* fn, float* fm),
|
|
|
|
float idp = fn[0] * fm[0];
|
|
idp+=fn[1]*fm[1];
|
|
idp+=fn[2]*fm[2];
|
|
idp+=fn[3]*fm[3];
|
|
|
|
return fixNaN(idp);
|
|
)
|
|
#endif
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_ptr(rs2);
|
|
shil_cf_arg_ptr(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_f32(rd);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
|
|
|
|
//shop_ftrv
|
|
shil_opc(ftrv)
|
|
#if HOST_CPU == CPU_X86 || HOST_CPU == CPU_X64
|
|
shil_canonical
|
|
(
|
|
void,f1,(float* fd, const float* fn, const float* fm),
|
|
|
|
double v1 = (double)fm[0] * fn[0] +
|
|
(double)fm[4] * fn[1] +
|
|
(double)fm[8] * fn[2] +
|
|
(double)fm[12] * fn[3];
|
|
|
|
double v2 = (double)fm[1] * fn[0] +
|
|
(double)fm[5] * fn[1] +
|
|
(double)fm[9] * fn[2] +
|
|
(double)fm[13] * fn[3];
|
|
|
|
double v3 = (double)fm[2] * fn[0] +
|
|
(double)fm[6] * fn[1] +
|
|
(double)fm[10] * fn[2] +
|
|
(double)fm[14] * fn[3];
|
|
|
|
double v4 = (double)fm[3] * fn[0] +
|
|
(double)fm[7] * fn[1] +
|
|
(double)fm[11] * fn[2] +
|
|
(double)fm[15] * fn[3];
|
|
|
|
fd[0] = fixNaN((float)v1);
|
|
fd[1] = fixNaN((float)v2);
|
|
fd[2] = fixNaN((float)v3);
|
|
fd[3] = fixNaN((float)v4);
|
|
)
|
|
#else
|
|
shil_canonical
|
|
(
|
|
void,f1,(float* fd,float* fn, float* fm),
|
|
|
|
float v1 = fm[0] * fn[0] +
|
|
fm[4] * fn[1] +
|
|
fm[8] * fn[2] +
|
|
fm[12] * fn[3];
|
|
|
|
float v2 = fm[1] * fn[0] +
|
|
fm[5] * fn[1] +
|
|
fm[9] * fn[2] +
|
|
fm[13] * fn[3];
|
|
|
|
float v3 = fm[2] * fn[0] +
|
|
fm[6] * fn[1] +
|
|
fm[10] * fn[2] +
|
|
fm[14] * fn[3];
|
|
|
|
float v4 = fm[3] * fn[0] +
|
|
fm[7] * fn[1] +
|
|
fm[11] * fn[2] +
|
|
fm[15] * fn[3];
|
|
|
|
fd[0] = fixNaN(v1);
|
|
fd[1] = fixNaN(v2);
|
|
fd[2] = fixNaN(v3);
|
|
fd[3] = fixNaN(v4);
|
|
)
|
|
#endif
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_ptr(rs2);
|
|
shil_cf_arg_ptr(rs1);
|
|
shil_cf_arg_ptr(rd);
|
|
shil_cf(f1);
|
|
)
|
|
shil_opc_end()
|
|
|
|
//shop_fmac
|
|
shil_opc(fmac)
|
|
shil_canonical
|
|
(
|
|
f32,f1,(float fn, float f0,float fm),
|
|
return fixNaN(fn + f0 * fm);
|
|
)
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_f32(rs3);
|
|
shil_cf_arg_f32(rs2);
|
|
shil_cf_arg_f32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_f32(rd);
|
|
)
|
|
shil_opc_end()
|
|
|
|
//shop_fsrra
|
|
shil_opc(fsrra)
|
|
UN_OP_F(1/sqrtf)
|
|
shil_opc_end()
|
|
|
|
|
|
//shop_fsca
|
|
shil_opc(fsca)
|
|
|
|
shil_canonical
|
|
(
|
|
void,fsca_native,(float* fd,u32 fixed),
|
|
|
|
u32 pi_index=fixed&0xFFFF;
|
|
|
|
float rads=pi_index/(65536.0f/2)*(3.14159265f)/*pi*/;
|
|
|
|
fd[0] = sinf(rads);
|
|
fd[1] = cosf(rads);
|
|
)
|
|
shil_canonical
|
|
(
|
|
void,fsca_table,(float* fd,u32 fixed),
|
|
|
|
u32 pi_index=fixed&0xFFFF;
|
|
|
|
fd[0] = sin_table[pi_index].u[0];
|
|
fd[1] = sin_table[pi_index].u[1];
|
|
)
|
|
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf_arg_ptr(rd);
|
|
shil_cf(fsca_impl);
|
|
)
|
|
|
|
shil_opc_end()
|
|
|
|
|
|
//shop_fseteq
|
|
shil_opc(fseteq)
|
|
BIN_OP_FU(==)
|
|
shil_opc_end()
|
|
|
|
//shop_fsetgt
|
|
shil_opc(fsetgt)
|
|
BIN_OP_FU(>)
|
|
shil_opc_end()
|
|
|
|
|
|
|
|
//shop_frswap
|
|
shil_opc(frswap)
|
|
shil_canonical
|
|
(
|
|
void,f1,(u64* fd1, u64* fd2, const u64* fs1, const u64* fs2),
|
|
|
|
u64 temp;
|
|
for (int i=0;i<8;i++)
|
|
{
|
|
temp=fs1[i];
|
|
fd1[i]=fs2[i];
|
|
fd2[i]=temp;
|
|
}
|
|
)
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_ptr(rs2);
|
|
shil_cf_arg_ptr(rs1);
|
|
shil_cf_arg_ptr(rd);
|
|
shil_cf_arg_ptr(rd2);
|
|
shil_cf(f1);
|
|
)
|
|
shil_opc_end()
|
|
|
|
//shop_xtrct
|
|
shil_opc(xtrct)
|
|
shil_canonical
|
|
(
|
|
u32,f1,(u32 r1, u32 r2),
|
|
return (r1 >> 16) | (r2 << 16);
|
|
)
|
|
shil_compile
|
|
(
|
|
shil_cf_arg_u32(rs2);
|
|
shil_cf_arg_u32(rs1);
|
|
shil_cf(f1);
|
|
shil_cf_rv_u32(rd);
|
|
)
|
|
shil_opc_end()
|
|
|
|
SHIL_END
|
|
|
|
|
|
//undefine stuff
|
|
#undef SHIL_MODE
|
|
|
|
#undef SHIL_START
|
|
#undef SHIL_END
|
|
|
|
#undef shil_opc
|
|
#undef shil_opc_end
|
|
|
|
#undef shil_canonical
|
|
#undef shil_compile
|
|
|
|
|
|
#undef BIN_OP_I
|
|
|
|
#undef BIN_OP_I2
|
|
#undef BIN_OP_I3
|
|
#undef BIN_OP_I4
|
|
|
|
#undef BIN_OP_F
|
|
|
|
#undef UN_OP_I
|
|
#undef UN_OP_F
|
|
#undef BIN_OP_FU
|
|
#undef shil_recimp
|