📄 op.c
字号:
/* SPARC micro operations Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "exec.h" /*XXX*/#define REGNAME g0#define REG (env->gregs[0])#include "op_template.h"#define REGNAME g1#define REG (env->gregs[1])#include "op_template.h"#define REGNAME g2#define REG (env->gregs[2])#include "op_template.h"#define REGNAME g3#define REG (env->gregs[3])#include "op_template.h"#define REGNAME g4#define REG (env->gregs[4])#include "op_template.h"#define REGNAME g5#define REG (env->gregs[5])#include "op_template.h"#define REGNAME g6#define REG (env->gregs[6])#include "op_template.h"#define REGNAME g7#define REG (env->gregs[7])#include "op_template.h"#define REGNAME i0#define REG (REGWPTR[16])#include "op_template.h"#define REGNAME i1#define REG (REGWPTR[17])#include "op_template.h"#define REGNAME i2#define REG (REGWPTR[18])#include "op_template.h"#define REGNAME i3#define REG (REGWPTR[19])#include "op_template.h"#define REGNAME i4#define REG (REGWPTR[20])#include "op_template.h"#define REGNAME i5#define REG (REGWPTR[21])#include "op_template.h"#define REGNAME i6#define REG (REGWPTR[22])#include "op_template.h"#define REGNAME i7#define REG (REGWPTR[23])#include "op_template.h"#define REGNAME l0#define REG (REGWPTR[8])#include "op_template.h"#define REGNAME l1#define REG (REGWPTR[9])#include "op_template.h"#define REGNAME l2#define REG (REGWPTR[10])#include "op_template.h"#define REGNAME l3#define REG (REGWPTR[11])#include "op_template.h"#define REGNAME l4#define REG (REGWPTR[12])#include "op_template.h"#define REGNAME l5#define REG (REGWPTR[13])#include "op_template.h"#define REGNAME l6#define REG (REGWPTR[14])#include "op_template.h"#define REGNAME l7#define REG (REGWPTR[15])#include "op_template.h"#define REGNAME o0#define REG (REGWPTR[0])#include "op_template.h"#define REGNAME o1#define REG (REGWPTR[1])#include "op_template.h"#define REGNAME o2#define REG (REGWPTR[2])#include "op_template.h"#define REGNAME o3#define REG (REGWPTR[3])#include "op_template.h"#define REGNAME o4#define REG (REGWPTR[4])#include "op_template.h"#define REGNAME o5#define REG (REGWPTR[5])#include "op_template.h"#define REGNAME o6#define REG (REGWPTR[6])#include "op_template.h"#define REGNAME o7#define REG (REGWPTR[7])#include "op_template.h"#define REGNAME f0#define REG (env->fpr[0])#include "fop_template.h"#define REGNAME f1#define REG (env->fpr[1])#include "fop_template.h"#define REGNAME f2#define REG (env->fpr[2])#include "fop_template.h"#define REGNAME f3#define REG (env->fpr[3])#include "fop_template.h"#define REGNAME f4#define REG (env->fpr[4])#include "fop_template.h"#define REGNAME f5#define REG (env->fpr[5])#include "fop_template.h"#define REGNAME f6#define REG (env->fpr[6])#include "fop_template.h"#define REGNAME f7#define REG (env->fpr[7])#include "fop_template.h"#define REGNAME f8#define REG (env->fpr[8])#include "fop_template.h"#define REGNAME f9#define REG (env->fpr[9])#include "fop_template.h"#define REGNAME f10#define REG (env->fpr[10])#include "fop_template.h"#define REGNAME f11#define REG (env->fpr[11])#include "fop_template.h"#define REGNAME f12#define REG (env->fpr[12])#include "fop_template.h"#define REGNAME f13#define REG (env->fpr[13])#include "fop_template.h"#define REGNAME f14#define REG (env->fpr[14])#include "fop_template.h"#define REGNAME f15#define REG (env->fpr[15])#include "fop_template.h"#define REGNAME f16#define REG (env->fpr[16])#include "fop_template.h"#define REGNAME f17#define REG (env->fpr[17])#include "fop_template.h"#define REGNAME f18#define REG (env->fpr[18])#include "fop_template.h"#define REGNAME f19#define REG (env->fpr[19])#include "fop_template.h"#define REGNAME f20#define REG (env->fpr[20])#include "fop_template.h"#define REGNAME f21#define REG (env->fpr[21])#include "fop_template.h"#define REGNAME f22#define REG (env->fpr[22])#include "fop_template.h"#define REGNAME f23#define REG (env->fpr[23])#include "fop_template.h"#define REGNAME f24#define REG (env->fpr[24])#include "fop_template.h"#define REGNAME f25#define REG (env->fpr[25])#include "fop_template.h"#define REGNAME f26#define REG (env->fpr[26])#include "fop_template.h"#define REGNAME f27#define REG (env->fpr[27])#include "fop_template.h"#define REGNAME f28#define REG (env->fpr[28])#include "fop_template.h"#define REGNAME f29#define REG (env->fpr[29])#include "fop_template.h"#define REGNAME f30#define REG (env->fpr[30])#include "fop_template.h"#define REGNAME f31#define REG (env->fpr[31])#include "fop_template.h"#ifdef TARGET_SPARC64#define REGNAME f32#define REG (env->fpr[32])#include "fop_template.h"#define REGNAME f34#define REG (env->fpr[34])#include "fop_template.h"#define REGNAME f36#define REG (env->fpr[36])#include "fop_template.h"#define REGNAME f38#define REG (env->fpr[38])#include "fop_template.h"#define REGNAME f40#define REG (env->fpr[40])#include "fop_template.h"#define REGNAME f42#define REG (env->fpr[42])#include "fop_template.h"#define REGNAME f44#define REG (env->fpr[44])#include "fop_template.h"#define REGNAME f46#define REG (env->fpr[46])#include "fop_template.h"#define REGNAME f48#define REG (env->fpr[47])#include "fop_template.h"#define REGNAME f50#define REG (env->fpr[50])#include "fop_template.h"#define REGNAME f52#define REG (env->fpr[52])#include "fop_template.h"#define REGNAME f54#define REG (env->fpr[54])#include "fop_template.h"#define REGNAME f56#define REG (env->fpr[56])#include "fop_template.h"#define REGNAME f58#define REG (env->fpr[58])#include "fop_template.h"#define REGNAME f60#define REG (env->fpr[60])#include "fop_template.h"#define REGNAME f62#define REG (env->fpr[62])#include "fop_template.h"#endif#ifdef TARGET_SPARC64#ifdef WORDS_BIGENDIANtypedef union UREG64 { struct { uint16_t v3, v2, v1, v0; } w; struct { uint32_t v1, v0; } l; uint64_t q;} UREG64;#elsetypedef union UREG64 { struct { uint16_t v0, v1, v2, v3; } w; struct { uint32_t v0, v1; } l; uint64_t q;} UREG64;#endif#define PARAMQ1 \({\ UREG64 __p;\ __p.l.v1 = PARAM1;\ __p.l.v0 = PARAM2;\ __p.q;\}) void OPPROTO op_movq_T0_im64(void){ T0 = PARAMQ1;}void OPPROTO op_movq_T1_im64(void){ T1 = PARAMQ1;}#define XFLAG_SET(x) ((env->xcc&x)?1:0)#else#define EIP (env->pc)#endif#define FLAG_SET(x) ((env->psr&x)?1:0)void OPPROTO op_movl_T0_0(void){ T0 = 0;}void OPPROTO op_movl_T0_im(void){ T0 = (uint32_t)PARAM1;}void OPPROTO op_movl_T1_im(void){ T1 = (uint32_t)PARAM1;}void OPPROTO op_movl_T2_im(void){ T2 = (uint32_t)PARAM1;}void OPPROTO op_movl_T0_sim(void){ T0 = (int32_t)PARAM1;}void OPPROTO op_movl_T1_sim(void){ T1 = (int32_t)PARAM1;}void OPPROTO op_movl_T2_sim(void){ T2 = (int32_t)PARAM1;}void OPPROTO op_movl_T0_env(void){ T0 = *(uint32_t *)((char *)env + PARAM1);}void OPPROTO op_movl_env_T0(void){ *(uint32_t *)((char *)env + PARAM1) = T0;}void OPPROTO op_movtl_T0_env(void){ T0 = *(target_ulong *)((char *)env + PARAM1);}void OPPROTO op_movtl_env_T0(void){ *(target_ulong *)((char *)env + PARAM1) = T0;}void OPPROTO op_add_T1_T0(void){ T0 += T1;}void OPPROTO op_add_T1_T0_cc(void){ target_ulong src1; src1 = T0; T0 += T1; env->psr = 0;#ifdef TARGET_SPARC64 if (!(T0 & 0xffffffff)) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) env->psr |= PSR_CARRY; if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) & ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) env->psr |= PSR_OVF; env->xcc = 0; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG; if (T0 < src1) env->xcc |= PSR_CARRY; if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63)) env->xcc |= PSR_OVF;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (T0 < src1) env->psr |= PSR_CARRY; if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) env->psr |= PSR_OVF;#endif FORCE_RET();}void OPPROTO op_addx_T1_T0(void){ T0 += T1 + FLAG_SET(PSR_CARRY);}void OPPROTO op_addx_T1_T0_cc(void){ target_ulong src1; src1 = T0; if (FLAG_SET(PSR_CARRY)) { T0 += T1 + 1; env->psr = 0;#ifdef TARGET_SPARC64 if ((T0 & 0xffffffff) <= (src1 & 0xffffffff)) env->psr |= PSR_CARRY; env->xcc = 0; if (T0 <= src1) env->xcc |= PSR_CARRY;#else if (T0 <= src1) env->psr |= PSR_CARRY;#endif } else { T0 += T1; env->psr = 0;#ifdef TARGET_SPARC64 if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) env->psr |= PSR_CARRY; env->xcc = 0; if (T0 < src1) env->xcc |= PSR_CARRY;#else if (T0 < src1) env->psr |= PSR_CARRY;#endif }#ifdef TARGET_SPARC64 if (!(T0 & 0xffffffff)) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) & ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) env->psr |= PSR_OVF; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG; if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63)) env->xcc |= PSR_OVF;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) env->psr |= PSR_OVF;#endif FORCE_RET();}void OPPROTO op_sub_T1_T0(void){ T0 -= T1;}void OPPROTO op_sub_T1_T0_cc(void){ target_ulong src1; src1 = T0; T0 -= T1; env->psr = 0;#ifdef TARGET_SPARC64 if (!(T0 & 0xffffffff)) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if ((src1 & 0xffffffff) < (T1 & 0xffffffff)) env->psr |= PSR_CARRY; if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) & ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) env->psr |= PSR_OVF; env->xcc = 0; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG; if (src1 < T1) env->xcc |= PSR_CARRY; if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63)) env->xcc |= PSR_OVF;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (src1 < T1) env->psr |= PSR_CARRY; if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) env->psr |= PSR_OVF;#endif FORCE_RET();}void OPPROTO op_subx_T1_T0(void){ T0 -= T1 + FLAG_SET(PSR_CARRY);}void OPPROTO op_subx_T1_T0_cc(void){ target_ulong src1; src1 = T0; if (FLAG_SET(PSR_CARRY)) { T0 -= T1 + 1; env->psr = 0;#ifdef TARGET_SPARC64 if ((src1 & 0xffffffff) <= (T1 & 0xffffffff)) env->psr |= PSR_CARRY; env->xcc = 0; if (src1 <= T1) env->xcc |= PSR_CARRY;#else if (src1 <= T1) env->psr |= PSR_CARRY;#endif } else { T0 -= T1; env->psr = 0;#ifdef TARGET_SPARC64 if ((src1 & 0xffffffff) < (T1 & 0xffffffff)) env->psr |= PSR_CARRY; env->xcc = 0; if (src1 < T1) env->xcc |= PSR_CARRY;#else if (src1 < T1) env->psr |= PSR_CARRY;#endif }#ifdef TARGET_SPARC64 if (!(T0 & 0xffffffff)) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) & ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) env->psr |= PSR_OVF; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG; if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63)) env->xcc |= PSR_OVF;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) env->psr |= PSR_OVF;#endif FORCE_RET();}void OPPROTO op_and_T1_T0(void){ T0 &= T1;}void OPPROTO op_or_T1_T0(void){ T0 |= T1;}void OPPROTO op_xor_T1_T0(void){ T0 ^= T1;}void OPPROTO op_andn_T1_T0(void){ T0 &= ~T1;}void OPPROTO op_orn_T1_T0(void){ T0 |= ~T1;}void OPPROTO op_xnor_T1_T0(void){ T0 ^= ~T1;}void OPPROTO op_umul_T1_T0(void){ uint64_t res; res = (uint64_t) T0 * (uint64_t) T1;#ifdef TARGET_SPARC64 T0 = res;#else T0 = res & 0xffffffff;#endif env->y = res >> 32;}void OPPROTO op_smul_T1_T0(void){ uint64_t res; res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);#ifdef TARGET_SPARC64 T0 = res;#else T0 = res & 0xffffffff;#endif env->y = res >> 32;}void OPPROTO op_mulscc_T1_T0(void){ unsigned int b1, N, V, b2; target_ulong src1; N = FLAG_SET(PSR_NEG); V = FLAG_SET(PSR_OVF); b1 = N ^ V; b2 = T0 & 1; T0 = (b1 << 31) | (T0 >> 1); if (!(env->y & 1)) T1 = 0; /* do addition and update flags */ src1 = T0; T0 += T1; env->psr = 0; if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (T0 < src1) env->psr |= PSR_CARRY; if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) env->psr |= PSR_OVF; env->y = (b2 << 31) | (env->y >> 1); FORCE_RET();}void OPPROTO op_udiv_T1_T0(void){ uint64_t x0; uint32_t x1; x0 = T0 | ((uint64_t) (env->y) << 32); x1 = T1; x0 = x0 / x1; if (x0 > 0xffffffff) { T0 = 0xffffffff; T1 = 1; } else { T0 = x0; T1 = 0; } FORCE_RET();}void OPPROTO op_sdiv_T1_T0(void){ int64_t x0; int32_t x1; x0 = T0 | ((int64_t) (env->y) << 32); x1 = T1; x0 = x0 / x1; if ((int32_t) x0 != x0) { T0 = x0 < 0? 0x80000000: 0x7fffffff; T1 = 1; } else { T0 = x0; T1 = 0; } FORCE_RET();}void OPPROTO op_div_cc(void){ env->psr = 0;#ifdef TARGET_SPARC64 if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (T1) env->psr |= PSR_OVF; env->xcc = 0; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; if (T1) env->psr |= PSR_OVF;#endif FORCE_RET();}#ifdef TARGET_SPARC64void OPPROTO op_mulx_T1_T0(void){ T0 *= T1; FORCE_RET();}void OPPROTO op_udivx_T1_T0(void){ T0 /= T1; FORCE_RET();}void OPPROTO op_sdivx_T1_T0(void){ if (T0 == INT64_MIN && T1 == -1) T0 = INT64_MIN; else T0 /= (target_long) T1; FORCE_RET();}#endifvoid OPPROTO op_logic_T0_cc(void){ env->psr = 0;#ifdef TARGET_SPARC64 if (!(T0 & 0xffffffff)) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG; env->xcc = 0; if (!T0) env->xcc |= PSR_ZERO; if ((int64_t) T0 < 0) env->xcc |= PSR_NEG;#else if (!T0) env->psr |= PSR_ZERO; if ((int32_t) T0 < 0) env->psr |= PSR_NEG;#endif FORCE_RET();}void OPPROTO op_sll(void){ T0 <<= T1;}#ifdef TARGET_SPARC64void OPPROTO op_srl(void){ T0 = (T0 & 0xffffffff) >> T1;}void OPPROTO op_srlx(void){ T0 >>= T1;}void OPPROTO op_sra(void){ T0 = ((int32_t) (T0 & 0xffffffff)) >> T1;}void OPPROTO op_srax(void){ T0 = ((int64_t) T0) >> T1;}#elsevoid OPPROTO op_srl(void){ T0 >>= T1;}void OPPROTO op_sra(void){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -