📄 integer.c
字号:
/*************************************************************************** integer.c - description ------------------- begin : Wed Sep 26 2001 copyright : (C) 2001 Universite Paris Sud and CEA author : Gilles Mouchard email : gilles.mouchard@lri.fr, gilles.mouchard@cea.fr ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include <integer.h>#include <ppcemul.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <xmlize.h>UInt32 ROTL(UInt32 v, UInt8 n){ return (v << n) | ((v >> (32 - n)) & ((1 << n) - 1));}UInt32 MASK(UInt8 mb, UInt8 me){ return(((mb > me) ? ~(((UInt32)-1 >> mb) ^ ((me >= 31) ? 0 : (UInt32) -1 >> (me + 1))): (((UInt32)-1 >> mb) ^ ((me >= 31) ? 0 : (UInt32) -1 >> (me + 1)))));}#define COMPUTE_CR0(r) (CR = (CR & 0xfffffff) | (XER_SO ? 0x10000000 : 0) | (((sword_t)(r) < 0) ? 0x80000000 : (((sword_t)(r) > 0) ? 0x40000000 : 0x20000000)))BOOL Carry(UInt32 a, UInt32 b){ UInt32 c, x, y; int i; if((a == 0) || (b == 0)) return 0; c = 0; for(i = 0; i < 32; i++) { x = (a >> i) & 0x1; y = (b >> i) & 0x1; c = x * y | x * c | y * c; } return c;}#define MAX_INT 0x7fffffffBOOL Overflow(SInt32 a, SInt32 b){ return ((a > 0) && (b > 0) && (MAX_INT - a < b)) || ((a < 0) && (b < 0) && (-MAX_INT - a > b));}BOOL Underflow(SInt32 a, SInt32 b){ return ((a > 0) && (b < 0) && (MAX_INT + b < a)) || ((a < 0) && (b > 0) && (-MAX_INT + b > a));}void addi_impl(ppc_inst_t inst){ GPR(RD) = RA ? GPR(RA) + SEXT16(IMM) : SEXT16(IMM);}void addic_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t b = SEXT16(IMM); GPR(RD) = a + b; if(Carry(a, b)) SET_XER_CA; else RESET_XER_CA;}void addicd_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t b = SEXT16(IMM); word_t result = a + b; GPR(RD) = result; if(Carry(a, b)) SET_XER_CA; else RESET_XER_CA; COMPUTE_CR0(result);} void addis_impl(ppc_inst_t inst){ GPR(RD) = RA ? GPR(RA) + (SEXT16(IMM) << 16) : SEXT16(IMM) << 16;}void andid_impl(ppc_inst_t inst){ word_t result = GPR(RS) & IMM; GPR(RA) = result; if((sword_t) result < 0) SET_CR0_LT; else RESET_CR0_LT; if((sword_t) result > 0) SET_CR0_GT; else RESET_CR0_GT; if(result == 0) SET_CR0_EQ; else RESET_CR0_EQ; if(XER_SO) SET_CR0_SO; else RESET_CR0_SO;}void andisd_impl(ppc_inst_t inst){ word_t result = GPR(RS) & (IMM << 16); GPR(RA) = result; if((sword_t) result < 0) SET_CR0_LT; else RESET_CR0_LT; if((sword_t) result > 0) SET_CR0_GT; else RESET_CR0_GT; if(result == 0) SET_CR0_EQ; else RESET_CR0_EQ; if(XER_SO) SET_CR0_SO; else RESET_CR0_SO;}void cmpi_impl(ppc_inst_t inst){ word_t result = GPR(RA) - SEXT16(IMM); if((sword_t) result < 0) SET_CR_LT(CRFD); else RESET_CR_LT(CRFD); if((sword_t) result > 0) SET_CR_GT(CRFD); else RESET_CR_GT(CRFD); if(result == 0) SET_CR_EQ(CRFD); else RESET_CR_EQ(CRFD); if(XER_SO) SET_CR_SO(CRFD); else RESET_CR_SO(CRFD);}void cmpli_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t b = IMM; if(a < b) SET_CR_LT(CRFD); else RESET_CR_LT(CRFD); if(a > b) SET_CR_GT(CRFD); else RESET_CR_GT(CRFD); if(a == b) SET_CR_EQ(CRFD); else RESET_CR_EQ(CRFD); if(XER_SO) SET_CR_SO(CRFD); else RESET_CR_SO(CRFD);}void mulli_impl(ppc_inst_t inst){ GPR(RD) = GPR(RA) * SEXT16(IMM);} void ori_impl(ppc_inst_t inst){ GPR(RA) = GPR(RS) | IMM;}void oris_impl(ppc_inst_t inst){ GPR(RA) = GPR(RS) | (IMM << 16);}void subfic_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t b = SEXT16(IMM); GPR(RD) = b - a; if(a == 0 || Carry(-a, b)) SET_XER_CA; else RESET_XER_CA;}void twi_impl(ppc_inst_t inst) { abort(); }void xori_impl(ppc_inst_t inst){ GPR(RA) = GPR(RS) ^ IMM;}void xoris_impl(ppc_inst_t inst){ GPR(RA) = GPR(RS) ^ (IMM << 16);}void rlwimix_impl(ppc_inst_t inst){ word_t r = ROTL(GPR(RS), SH); word_t m = MASK(MB, ME); word_t result = (r & m) | (GPR(RA) & (~m)); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void rlwinmx_impl(ppc_inst_t inst){ word_t r = ROTL(GPR(RS), SH); word_t m = MASK(MB, ME); word_t result = r & m; GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void rlwnmx_impl(ppc_inst_t inst){ word_t r = ROTL(GPR(RS), GPR(RB) & 0x1f); word_t m = MASK(MB, ME); word_t result = r & m; GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void andx_impl(ppc_inst_t inst){ UInt32 result = GPR(RS) & GPR(RB); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void andcx_impl(ppc_inst_t inst){ word_t result = GPR(RS) & (~GPR(RB)); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void cmp_impl(ppc_inst_t inst){ word_t result = GPR(RA) - GPR(RB); if((sword_t) result < 0) SET_CR_LT(CRFD); else RESET_CR_LT(CRFD); if((sword_t) result > 0) SET_CR_GT(CRFD); else RESET_CR_GT(CRFD); if(result == 0) SET_CR_EQ(CRFD); else RESET_CR_EQ(CRFD); if(XER_SO) SET_CR_SO(CRFD); else RESET_CR_SO(CRFD);}void cmpl_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t b = GPR(RB); if(a < b) SET_CR_LT(CRFD); else RESET_CR_LT(CRFD); if(a > b) SET_CR_GT(CRFD); else RESET_CR_GT(CRFD); if(a == b) SET_CR_EQ(CRFD); else RESET_CR_EQ(CRFD); if(XER_SO) SET_CR_SO(CRFD); else RESET_CR_SO(CRFD);}void cntlzwx_impl(ppc_inst_t inst){ word_t n = 0; word_t m = 1 << 31; while(n < 32) { if(GPR(RS) & m) break; m >>= 1; n++; } GPR(RA) = n; if(Rc) COMPUTE_CR0(n);}void eqvx_impl(ppc_inst_t inst){ word_t result = ~(GPR(RS) ^ GPR(RB)); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void extsbx_impl(ppc_inst_t inst){ word_t result = (word_t)(sword_t)(sbyte_t)(byte_t) GPR(RS); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void extshx_impl(ppc_inst_t inst){ word_t result = (word_t)(sword_t)(shalfword_t)(halfword_t) GPR(RS); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void nandx_impl(ppc_inst_t inst){ word_t result = ~(GPR(RS) & GPR(RB)); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void norx_impl(ppc_inst_t inst){ word_t result = ~(GPR(RS) | GPR(RB)); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void orx_impl(ppc_inst_t inst){ word_t result = GPR(RS) | GPR(RB); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void orcx_impl(ppc_inst_t inst){ word_t result = GPR(RS) | (~GPR(RB)); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void slwx_impl(ppc_inst_t inst){ word_t n = GPR(RB); word_t result; if(n & 0x20) result = 0; else result = GPR(RS) << (n & 0x1f); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void srawx_impl(ppc_inst_t inst){ word_t n = GPR(RB); sword_t result; sword_t src = GPR(RS); if(n == 0) { result = src; RESET_XER_CA; } else if(n & 0x20) { if(src < 0) { result = 0xffffffff; if(src & 0x7fffffff) SET_XER_CA; else RESET_XER_CA; } else { result = 0; RESET_XER_CA; } } else { n = n & 0x1f; result = (sword_t) src >> n; if(src < 0 && (src << (32 - n)) != 0) SET_XER_CA; else RESET_XER_CA; } GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void srawix_impl(ppc_inst_t inst){ word_t n = SH; sword_t result; sword_t src = GPR(RS); if(n == 0) { result = src; RESET_XER_CA; } else { result = src >> n; if(src < 0 && (src << (32 - n)) != 0) SET_XER_CA; else RESET_XER_CA; } GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void srwx_impl(ppc_inst_t inst){ word_t result = GPR(RS) >> (GPR(RB) & 0x1f); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void tw_impl(ppc_inst_t inst) { abort(); }void xorx_impl(ppc_inst_t inst){ word_t result = GPR(RS) ^ GPR(RB); GPR(RA) = result; if(Rc) COMPUTE_CR0(result);}void addx_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t b = GPR(RB); word_t result = a + b; GPR(RD) = result; if(OE) { if(Overflow(a, b)) { SET_XER_OV; SET_XER_SO; } else RESET_XER_OV; } if(Rc) COMPUTE_CR0(result);}void addcx_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t b = GPR(RB); word_t result = a + b; GPR(RD) = result; if(Carry(a, b)) SET_XER_CA; else RESET_XER_CA; if(OE) { if(Overflow(a, b)) { SET_XER_OV; SET_XER_SO; } else RESET_XER_OV; } if(Rc) COMPUTE_CR0(result);}void addex_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t b = GPR(RB); word_t c = XER_CA; word_t result = a + b + c; GPR(RD) = result; if(Carry(a, b) || (c != 0 && Carry(a + b, c))) SET_XER_CA; else RESET_XER_CA; if(OE) { if(Overflow(a, b) || Overflow(a + b, c)) { SET_XER_OV; SET_XER_SO; } else { RESET_XER_OV; } } if(Rc) COMPUTE_CR0(result);}void addmex_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t c = XER_CA; word_t result = a + c - 1; GPR(RD) = result; if(Carry(a, c - 1)) SET_XER_CA; else RESET_XER_CA; if(OE) { if(Overflow(a, c - 1)) { SET_XER_OV; SET_XER_SO; } else { RESET_XER_OV; } } if(Rc) COMPUTE_CR0(result);}void addzex_impl(ppc_inst_t inst){ word_t a = GPR(RA); word_t c = XER_CA; word_t result = a + c; GPR(RD) = result; if(Carry(a, c)) SET_XER_CA; else RESET_XER_CA; if(OE) { if(Overflow(a, c)) { SET_XER_OV; SET_XER_SO; } else { RESET_XER_OV; } } if(Rc) COMPUTE_CR0(result);}void divwx_impl(ppc_inst_t inst){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -