/**//* * addex Add Extended * .424 */ void ppc_opc_addex() ...{ int rD, rA, rB; PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, rA, rB); uint32 a = gCPU.gpr[rA]; uint32 b = gCPU.gpr[rB]; uint32 ca = ((gCPU.xer&XER_CA)?1:0); gCPU.gpr[rD] = a + b + ca; // update xer if (ppc_carry_3(a, b, ca)) ...{ gCPU.xer |= XER_CA; }else...{ gCPU.xer &=~XER_CA; } if (gCPU.current_opc & PPC_OPC_Rc) ...{ // update cr0 flags ppc_update_cr0(gCPU.gpr[rD]); } }
每一条指令都根据其实际意思,取出对应的操作符,然后修改虚拟CPU的状态.
在Dynamips里面,实现的原理也是类似的,但是其没有使用form,而是直接翻译指令.
/**//* ADDC - Add Carrying */ static fastcall int ppc32_exec_ADDC(cpu_ppc_t *cpu,ppc_insn_t insn) ...{ int rd = bits(insn,21,25); int ra = bits(insn,16,20); int rb = bits(insn,11,15); register m_uint32_t a,b,d; a = cpu->gpr[ra]; b = cpu->gpr[rb]; d = a + b; ppc32_exec_ca_sum(cpu,d,a,b); cpu->gpr[rd] = d; return(0); }
我们可以看到它是通过bits这个函数来转换的.这样子写就不是那么优雅.
/**//* Extract bits from a 32-bit values */ static inline int bits(m_uint32_t val,int start,int end) ...{ return((val >> start) & ((1<< (end-start+1)) -1)); }