|
|
1.1 root 1: /*
2: * Cisco router simulation platform.
3: * Copyright (c) 2005,2006 Christophe Fillot ([email protected])
4: */
5:
6: #include <stdio.h>
7: #include <stdlib.h>
8: #include <unistd.h>
9: #include <string.h>
10: #include <sys/types.h>
11: #include <sys/stat.h>
12: #include <sys/mman.h>
13: #include <fcntl.h>
14:
15: #include "cpu.h"
16: #include "ppc32_jit.h"
17: #include "ppc32_x86_trans.h"
18: #include "memory.h"
19:
1.1.1.2 ! root 20: /* ======================================================================= */
! 21:
1.1 root 22: /* Macros for CPU structure access */
23: #define REG_OFFSET(reg) (OFFSET(cpu_ppc_t,gpr[(reg)]))
24: #define MEMOP_OFFSET(op) (OFFSET(cpu_ppc_t,mem_op_fn[(op)]))
25:
26: #define DECLARE_INSN(name) \
27: static int ppc32_emit_##name(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, \
28: ppc_insn_t insn)
29:
1.1.1.2 ! root 30: /* EFLAGS to Condition Register (CR) field - signed */
! 31: static m_uint32_t eflags_to_cr_signed[256] = {
! 32: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
! 33: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
! 34: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
! 35: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
! 36: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
! 37: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
! 38: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
! 39: 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
! 40: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
! 41: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
! 42: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
! 43: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
! 44: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
! 45: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
! 46: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
! 47: 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
! 48: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
! 49: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
! 50: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
! 51: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
! 52: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
! 53: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
! 54: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
! 55: 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
! 56: 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
! 57: 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
! 58: 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
! 59: 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
! 60: 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
! 61: 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
! 62: 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
! 63: 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
! 64: };
! 65:
! 66: /* EFLAGS to Condition Register (CR) field - unsigned */
! 67: static m_uint32_t eflags_to_cr_unsigned[256] = {
! 68: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 69: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 70: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 71: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 72: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 73: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 74: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 75: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 76: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 77: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 78: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 79: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 80: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 81: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 82: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 83: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 84: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 85: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 86: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 87: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 88: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 89: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 90: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 91: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
! 92: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 93: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 94: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 95: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 96: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 97: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 98: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 99: 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a,
! 100: };
! 101:
1.1 root 102: /* Dump regs */
103: static void ppc32_emit_dump_regs(ppc32_jit_tcb_t *b);
104:
105: /* Load a 32 bit immediate value */
106: static inline void ppc32_load_imm(ppc32_jit_tcb_t *b,u_int reg,m_uint32_t val)
107: {
108: if (val)
109: x86_mov_reg_imm(b->jit_ptr,reg,val);
110: else
111: x86_alu_reg_reg(b->jit_ptr,X86_XOR,reg,reg);
112: }
113:
114: /* Set the Instruction Address (IA) register */
115: void ppc32_set_ia(ppc32_jit_tcb_t *b,m_uint32_t new_ia)
116: {
117: x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),new_ia,4);
118: }
119:
120: /* Set the Link Register (LR) */
121: void ppc32_set_lr(ppc32_jit_tcb_t *b,m_uint32_t new_lr)
122: {
123: x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),new_lr,4);
124: }
125:
1.1.1.2 ! root 126: /*
! 127: * Try to branch directly to the specified JIT block without returning to
! 128: * main loop.
! 129: */
! 130: static void ppc32_try_direct_far_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
! 131: m_uint32_t new_ia)
! 132: {
! 133: m_uint32_t new_page,ia_hash,ia_offset;
! 134: u_char *test1,*test2,*test3;
! 135:
! 136: new_page = new_ia & PPC32_MIN_PAGE_MASK;
! 137: ia_offset = (new_ia & PPC32_MIN_PAGE_IMASK) >> 2;
! 138: ia_hash = ppc32_jit_get_ia_hash(new_ia);
! 139:
! 140: /* Get JIT block info in %edx */
! 141: x86_mov_reg_membase(b->jit_ptr,X86_EBX,
! 142: X86_EDI,OFFSET(cpu_ppc_t,exec_blk_map),4);
! 143: x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EBX,ia_hash*sizeof(void *),4);
! 144:
! 145: /* no JIT block found ? */
! 146: x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
! 147: test1 = b->jit_ptr;
! 148: x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
! 149:
! 150: /* Check block IA */
! 151: x86_mov_reg_imm(b->jit_ptr,X86_EAX,new_page);
! 152: x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDX,
! 153: OFFSET(ppc32_jit_tcb_t,start_ia));
! 154: test2 = b->jit_ptr;
! 155: x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1);
! 156:
! 157: /* Jump to the code */
! 158: x86_mov_reg_membase(b->jit_ptr,X86_ESI,
! 159: X86_EDX,OFFSET(ppc32_jit_tcb_t,jit_insn_ptr),4);
! 160: x86_mov_reg_membase(b->jit_ptr,X86_EBX,
! 161: X86_ESI,ia_offset * sizeof(void *),4);
! 162:
! 163: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
! 164: test3 = b->jit_ptr;
! 165: x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
! 166: x86_jump_reg(b->jit_ptr,X86_EBX);
! 167:
! 168: /* Returns to caller... */
! 169: x86_patch(test1,b->jit_ptr);
! 170: x86_patch(test2,b->jit_ptr);
! 171: x86_patch(test3,b->jit_ptr);
! 172:
! 173: ppc32_set_ia(b,new_ia);
! 174: ppc32_jit_tcb_push_epilog(b);
! 175: }
! 176:
1.1 root 177: /* Set Jump */
178: static void ppc32_set_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
179: m_uint32_t new_ia,int local_jump)
180: {
181: int return_to_caller = FALSE;
182: u_char *jump_ptr;
183:
184: #if 0
185: if (cpu->sym_trace && !local_jump)
186: return_to_caller = TRUE;
187: #endif
188:
189: if (!return_to_caller && ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr)) {
190: if (jump_ptr) {
191: x86_jump_code(b->jit_ptr,jump_ptr);
192: } else {
193: ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia);
194: x86_jump32(b->jit_ptr,0);
195: }
196: } else {
1.1.1.2 ! root 197: if (cpu->exec_blk_direct_jump) {
! 198: /* Block lookup optimization */
! 199: ppc32_try_direct_far_jump(cpu,b,new_ia);
! 200: } else {
! 201: ppc32_set_ia(b,new_ia);
! 202: ppc32_jit_tcb_push_epilog(b);
! 203: }
1.1 root 204: }
205: }
206:
207: /* Load a GPR into the specified host register */
208: static forced_inline void ppc32_load_gpr(ppc32_jit_tcb_t *b,u_int host_reg,
209: u_int ppc_reg)
210: {
211: x86_mov_reg_membase(b->jit_ptr,host_reg,X86_EDI,REG_OFFSET(ppc_reg),4);
212: }
213:
214: /* Store contents for a host register into a GPR register */
215: static forced_inline void ppc32_store_gpr(ppc32_jit_tcb_t *b,u_int ppc_reg,
216: u_int host_reg)
217: {
218: x86_mov_membase_reg(b->jit_ptr,X86_EDI,REG_OFFSET(ppc_reg),host_reg,4);
219: }
220:
221: /* Apply an ALU operation on a GPR register and a host register */
222: static forced_inline void ppc32_alu_gpr(ppc32_jit_tcb_t *b,u_int op,
223: u_int host_reg,u_int ppc_reg)
224: {
225: x86_alu_reg_membase(b->jit_ptr,op,host_reg,X86_EDI,REG_OFFSET(ppc_reg));
226: }
227:
228: /*
229: * Update CR from %eflags
1.1.1.2 ! root 230: * %eax, %edx, %esi are modified.
1.1 root 231: */
232: static void ppc32_update_cr(ppc32_jit_tcb_t *b,int field,int is_signed)
233: {
1.1.1.2 ! root 234: /* Get status bits from EFLAGS */
! 235: x86_mov_reg_imm(b->jit_ptr,X86_EAX,0);
! 236: x86_lahf(b->jit_ptr);
! 237: x86_xchg_ah_al(b->jit_ptr);
1.1 root 238:
1.1.1.2 ! root 239: if (is_signed)
! 240: x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_signed);
! 241: else
! 242: x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_unsigned);
1.1 root 243:
1.1.1.2 ! root 244: x86_mov_reg_memindex(b->jit_ptr,X86_EAX,X86_EDX,0,X86_EAX,2,4);
1.1 root 245:
246: /* Check XER Summary of Overflow and report it */
1.1.1.2 ! root 247: x86_mov_reg_membase(b->jit_ptr,X86_ESI,X86_EDI,OFFSET(cpu_ppc_t,xer),4);
! 248: //x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_XER_SO);
! 249: //x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_ESI,PPC32_XER_SO_BIT);
! 250: //x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ESI);
! 251:
! 252: /* Store modified CR field */
! 253: x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(field),
! 254: X86_EAX,4);
1.1 root 255: }
256:
257: /*
258: * Update CR0 from %eflags
259: * %eax, %ecx, %edx, %esi are modified.
260: */
261: static void ppc32_update_cr0(ppc32_jit_tcb_t *b)
262: {
263: ppc32_update_cr(b,0,TRUE);
264: }
265:
266: /* Basic C call */
267: static forced_inline void ppc32_emit_basic_c_call(ppc32_jit_tcb_t *b,void *f)
268: {
269: x86_mov_reg_imm(b->jit_ptr,X86_EBX,f);
270: x86_call_reg(b->jit_ptr,X86_EBX);
271: }
272:
273: /* Emit a simple call to a C function without any parameter */
274: static void ppc32_emit_c_call(ppc32_jit_tcb_t *b,void *f)
275: {
276: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
277: ppc32_emit_basic_c_call(b,f);
278: }
279:
280: /* Memory operation */
281: static void ppc32_emit_memop(ppc32_jit_tcb_t *b,int op,int base,int offset,
282: int target,int update)
283: {
284: m_uint32_t val = sign_extend(offset,16);
285: u_char *test1;
286:
287: /* Save PC for exception handling */
288: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
289:
290: /* EDX = sign-extended offset */
291: ppc32_load_imm(b,X86_EDX,val);
292:
293: /* EDX = GPR[base] + sign-extended offset */
294: if (update || (base != 0))
295: ppc32_alu_gpr(b,X86_ADD,X86_EDX,base);
296:
297: if (update)
298: x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EDX,4);
299:
300: /* ECX = target register */
301: x86_mov_reg_imm(b->jit_ptr,X86_ECX,target);
302:
303: /* EAX = CPU instance pointer */
304: x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
305:
306: /* Call memory function */
307: x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(op));
308:
309: /* Exception ? */
310: x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
311: test1 = b->jit_ptr;
312: x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
313: ppc32_jit_tcb_push_epilog(b);
314: x86_patch(test1,b->jit_ptr);
315:
316: if (update)
317: ppc32_store_gpr(b,base,X86_ESI);
318: }
319:
320: /* Memory operation (indexed) */
321: static void ppc32_emit_memop_idx(ppc32_jit_tcb_t *b,int op,int ra,int rb,
322: int target,int update)
323: {
324: u_char *test1;
325:
326: /* Save PC for exception handling */
327: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
328:
329: /* EDX = $rb */
330: ppc32_load_gpr(b,X86_EDX,rb);
331:
332: /* EDX = $rb + $ra */
333: if (update || (ra != 0))
334: ppc32_alu_gpr(b,X86_ADD,X86_EDX,ra);
335:
336: if (update)
337: x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EDX,4);
338:
339: /* ECX = target register */
340: x86_mov_reg_imm(b->jit_ptr,X86_ECX,target);
341:
342: /* EAX = CPU instance pointer */
343: x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
344:
345: /* Call memory function */
346: x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(op));
347:
348: /* Exception ? */
349: x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
350: test1 = b->jit_ptr;
351: x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
352: ppc32_jit_tcb_push_epilog(b);
353: x86_patch(test1,b->jit_ptr);
354:
355: if (update)
356: ppc32_store_gpr(b,ra,X86_ESI);
357: }
358:
359: typedef void (*memop_fast_access)(ppc32_jit_tcb_t *b,int target);
360:
361: /* Fast LBZ */
362: static void ppc32_memop_fast_lbz(ppc32_jit_tcb_t *b,int target)
363: {
364: x86_clear_reg(b->jit_ptr,X86_ECX);
365: x86_mov_reg_memindex(b->jit_ptr,X86_ECX,X86_EAX,0,X86_EBX,0,1);
366: ppc32_store_gpr(b,target,X86_ECX);
367: }
368:
369: /* Fast STB */
370: static void ppc32_memop_fast_stb(ppc32_jit_tcb_t *b,int target)
371: {
372: ppc32_load_gpr(b,X86_EDX,target);
373: x86_mov_memindex_reg(b->jit_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,1);
374: }
375:
376: /* Fast LWZ */
377: static void ppc32_memop_fast_lwz(ppc32_jit_tcb_t *b,int target)
378: {
379: x86_mov_reg_memindex(b->jit_ptr,X86_EAX,X86_EAX,0,X86_EBX,0,4);
380: x86_bswap(b->jit_ptr,X86_EAX);
381: ppc32_store_gpr(b,target,X86_EAX);
382: }
383:
384: /* Fast STW */
385: static void ppc32_memop_fast_stw(ppc32_jit_tcb_t *b,int target)
386: {
387: ppc32_load_gpr(b,X86_EDX,target);
388: x86_bswap(b->jit_ptr,X86_EDX);
389: x86_mov_memindex_reg(b->jit_ptr,X86_EAX,0,X86_EBX,0,X86_EDX,4);
390: }
391:
392: /* Fast memory operation */
393: static void ppc32_emit_memop_fast(ppc32_jit_tcb_t *b,int write_op,int opcode,
394: int base,int offset,int target,
395: memop_fast_access op_handler)
396: {
397: m_uint32_t val = sign_extend(offset,16);
398: u_char *test1,*test2,*p_exception,*p_exit;
399:
400: test2 = NULL;
401:
402: /* EBX = sign-extended offset */
403: ppc32_load_imm(b,X86_EBX,val);
404:
405: /* EBX = GPR[base] + sign-extended offset */
406: if (base != 0)
407: ppc32_alu_gpr(b,X86_ADD,X86_EBX,base);
408:
409: /* EAX = mts32_entry index */
410: x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EBX,4);
411: x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,MTS32_HASH_SHIFT);
412: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,MTS32_HASH_MASK);
413:
414: /* EDX = mts32_entry */
415: x86_mov_reg_membase(b->jit_ptr,X86_EDX,
416: X86_EDI,OFFSET(cpu_ppc_t,mts_cache[PPC32_MTS_DCACHE]),
417: 4);
418: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,4);
419: x86_alu_reg_reg(b->jit_ptr,X86_ADD,X86_EDX,X86_EAX);
420:
421: /* Compare virtual page address (ESI = vpage) */
422: x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EBX,4);
423: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_MASK);
424:
425: x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_ESI,X86_EDX,
426: OFFSET(mts32_entry_t,gvpa));
427: test1 = b->jit_ptr;
428: x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
429:
430: /* Test if we are writing to a COW page */
431: if (write_op) {
432: x86_test_membase_imm(b->jit_ptr,X86_EDX,OFFSET(mts32_entry_t,flags),
1.1.1.2 ! root 433: MTS_FLAG_COW|MTS_FLAG_EXEC);
1.1 root 434: test2 = b->jit_ptr;
435: x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
436: }
437:
438: /* EBX = offset in page, EAX = Host Page Address */
439: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,PPC32_MIN_PAGE_IMASK);
440: x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDX,OFFSET(mts32_entry_t,hpa),4);
441:
442: /* Memory access */
443: op_handler(b,target);
444:
445: p_exit = b->jit_ptr;
446: x86_jump8(b->jit_ptr,0);
447:
448: /* === Slow lookup === */
449: x86_patch(test1,b->jit_ptr);
450: if (test2)
451: x86_patch(test2,b->jit_ptr);
452:
453: /* Update IA (EBX = vaddr) */
454: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
455:
456: /* EDX = virtual address */
457: x86_mov_reg_reg(b->jit_ptr,X86_EDX,X86_EBX,4);
458:
459: /* ECX = target register */
460: x86_mov_reg_imm(b->jit_ptr,X86_ECX,target);
461:
462: /* EAX = CPU instance pointer */
463: x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
464:
465: /* Call memory function */
466: x86_call_membase(b->jit_ptr,X86_EDI,MEMOP_OFFSET(opcode));
467:
468: /* Check for exception */
469: x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
470: p_exception = b->jit_ptr;
471: x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
472: ppc32_jit_tcb_push_epilog(b);
473:
474: x86_patch(p_exit,b->jit_ptr);
475: x86_patch(p_exception,b->jit_ptr);
476: }
477:
478: /* Virtual Breakpoint */
479: void ppc32_emit_breakpoint(ppc32_jit_tcb_t *b)
480: {
481: x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
482: ppc32_emit_c_call(b,ppc32_run_breakpoint);
483: }
484:
485: /* Unknown opcode handler */
486: static asmlinkage void ppc32_unknown_opcode(cpu_ppc_t *cpu,m_uint32_t opcode)
487: {
488: printf("PPC32: unhandled opcode 0x%8.8x at 0x%8.8x (lr=0x%8.8x)\n",
489: opcode,cpu->ia,cpu->lr);
490:
491: ppc32_dump_regs(cpu->gen);
492: exit(1);
493: }
494:
495: /* Emit unhandled instruction code */
496: static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
497: ppc_insn_t opcode)
498: {
499: u_char *test1;
500:
501: #if 0
502: x86_mov_reg_imm(b->jit_ptr,X86_EAX,opcode);
503: x86_alu_reg_imm(b->jit_ptr,X86_SUB,X86_ESP,4);
504: x86_push_reg(b->jit_ptr,X86_EAX);
505: x86_push_reg(b->jit_ptr,X86_EDI);
506: ppc32_emit_c_call(b,ppc32_unknown_opcode);
507: x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,12);
508: #endif
509:
510: /* Update IA */
511: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
512:
513: /* Fallback to non-JIT mode */
514: x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDI,4);
515: x86_mov_reg_imm(b->jit_ptr,X86_EDX,opcode);
516:
517: ppc32_emit_c_call(b,ppc32_exec_single_insn_ext);
518: x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
519: test1 = b->jit_ptr;
520: x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
521: ppc32_jit_tcb_push_epilog(b);
522:
523: x86_patch(test1,b->jit_ptr);
524: return(0);
525: }
526:
527: /* Dump regs */
528: static void ppc32_emit_dump_regs(ppc32_jit_tcb_t *b)
529: {
530: x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,OFFSET(cpu_ppc_t,gen),4);
531: x86_push_reg(b->jit_ptr,X86_EAX);
532: ppc32_emit_c_call(b,ppc32_dump_regs);
533: x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESP,4);
534: }
535:
536: /* Increment the number of executed instructions (performance debugging) */
537: void ppc32_inc_perf_counter(ppc32_jit_tcb_t *b)
538: {
539: x86_alu_membase_imm(b->jit_ptr,X86_ADD,
540: X86_EDI,OFFSET(cpu_ppc_t,perf_counter),1);
541: x86_alu_membase_imm(b->jit_ptr,X86_ADC,
542: X86_EDI,OFFSET(cpu_ppc_t,perf_counter)+4,0);
543: }
544:
1.1.1.2 ! root 545: /* Check if there are pending IRQ */
! 546: void ppc32_check_pending_irq(ppc32_jit_tcb_t *b)
! 547: {
! 548: u_char *test1;
! 549:
! 550: /* Check the pending IRQ flag */
! 551: x86_mov_reg_membase(b->jit_ptr,X86_EAX,
! 552: X86_EDI,OFFSET(cpu_ppc_t,irq_check),4);
! 553: x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
! 554: test1 = b->jit_ptr;
! 555: x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1);
! 556:
! 557: /* Save PC */
! 558: ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2));
! 559: ppc32_jit_tcb_push_epilog(b);
! 560:
! 561: x86_patch(test1,b->jit_ptr);
! 562: }
! 563:
1.1 root 564: /* ======================================================================== */
565:
566: /* BLR - Branch to Link Register */
567: DECLARE_INSN(BLR)
568: {
569: x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
570: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),X86_EDX,4);
571:
572: /* set the return address */
573: if (insn & 1)
574: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
575:
576: ppc32_jit_tcb_push_epilog(b);
577: return(0);
578: }
579:
580: /* BCTR - Branch to Count Register */
581: DECLARE_INSN(BCTR)
582: {
583: x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
584: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),X86_EDX,4);
585:
586: /* set the return address */
587: if (insn & 1)
588: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
589:
590: ppc32_jit_tcb_push_epilog(b);
591: return(0);
592: }
593:
594: /* MFLR - Move From Link Register */
595: DECLARE_INSN(MFLR)
596: {
597: int rd = bits(insn,21,25);
598:
599: x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
600: ppc32_store_gpr(b,rd,X86_EDX);
601: return(0);
602: }
603:
604: /* MTLR - Move To Link Register */
605: DECLARE_INSN(MTLR)
606: {
607: int rs = bits(insn,21,25);
608:
609: ppc32_load_gpr(b,X86_EDX,rs);
610: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),X86_EDX,4);
611: return(0);
612: }
613:
614: /* MFCTR - Move From Counter Register */
615: DECLARE_INSN(MFCTR)
616: {
617: int rd = bits(insn,21,25);
618:
619: x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,ctr),4);
620: ppc32_store_gpr(b,rd,X86_EDX);
621: return(0);
622: }
623:
624: /* MTCTR - Move To Counter Register */
625: DECLARE_INSN(MTCTR)
626: {
627: int rs = bits(insn,21,25);
628:
629: ppc32_load_gpr(b,X86_EDX,rs);
630: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr),X86_EDX,4);
631: return(0);
632: }
633:
634: /* MFTBU - Move from Time Base (Up) */
635: DECLARE_INSN(MFTBU)
636: {
637: int rd = bits(insn,21,25);
638:
639: x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
640: ppc32_store_gpr(b,rd,X86_EDX);
641: return(0);
642: }
643:
644: #define PPC32_TB_INCREMENT 50
645:
646: /* MFTBL - Move from Time Base (Lo) */
647: DECLARE_INSN(MFTBL)
648: {
649: int rd = bits(insn,21,25);
650:
651: /* Increment the time base register */
652: x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,tb),4);
653: x86_mov_reg_membase(b->jit_ptr,X86_EBX,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,4);
654: x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_EDX,PPC32_TB_INCREMENT);
655: x86_alu_reg_imm(b->jit_ptr,X86_ADC,X86_EBX,0);
656: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb),X86_EDX,4);
657: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,tb)+4,X86_EBX,4);
658:
659: ppc32_store_gpr(b,rd,X86_EDX);
660: return(0);
661: }
662:
663: /* ADD */
664: DECLARE_INSN(ADD)
665: {
666: int rd = bits(insn,21,25);
667: int ra = bits(insn,16,20);
668: int rb = bits(insn,11,15);
669:
670: /* $rd = $ra + $rb */
671: ppc32_load_gpr(b,X86_EBX,ra);
672: ppc32_alu_gpr(b,X86_ADD,X86_EBX,rb);
673: ppc32_store_gpr(b,rd,X86_EBX);
674:
675: if (insn & 1)
676: ppc32_update_cr0(b);
677:
678: return(0);
679: }
680:
681: /* ADDC */
682: DECLARE_INSN(ADDC)
683: {
684: int rd = bits(insn,21,25);
685: int ra = bits(insn,16,20);
686: int rb = bits(insn,11,15);
687:
688: /* $rd = $ra + $rb */
689: ppc32_load_gpr(b,X86_EBX,ra);
690: ppc32_alu_gpr(b,X86_ADD,X86_EBX,rb);
691: ppc32_store_gpr(b,rd,X86_EBX);
692:
693: /* store the carry flag */
694: x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
695: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
696: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
697:
698: if (insn & 1) {
699: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
700: ppc32_update_cr0(b);
701: }
702:
703: return(0);
704: }
705:
706: /* ADDE - Add Extended */
707: DECLARE_INSN(ADDE)
708: {
709: int rd = bits(insn,21,25);
710: int ra = bits(insn,16,20);
711: int rb = bits(insn,11,15);
712:
713: /* $ra + carry */
714: ppc32_load_gpr(b,X86_ESI,ra);
715: x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_ESI,
716: X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
717: x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
718:
719: /* add $rb */
720: ppc32_alu_gpr(b,X86_ADD,X86_ESI,rb);
721: x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
722:
723: ppc32_store_gpr(b,rd,X86_ESI);
724:
725: /* store the carry flag */
726: x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
727: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
728:
729: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
730:
731: /* update cr0 */
732: if (insn & 1) {
733: x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
734: ppc32_update_cr0(b);
735: }
736:
737: return(0);
738: }
739:
740: /* ADDI - ADD Immediate */
741: DECLARE_INSN(ADDI)
742: {
743: int rd = bits(insn,21,25);
744: int ra = bits(insn,16,20);
745: int imm = bits(insn,0,15);
746: m_uint32_t tmp = sign_extend_32(imm,16);
747:
748: ppc32_load_imm(b,X86_EBX,tmp);
749:
750: if (ra != 0)
751: x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EBX,X86_EDI,REG_OFFSET(ra));
752:
753: ppc32_store_gpr(b,rd,X86_EBX);
754: return(0);
755: }
756:
757: /* ADDIC - ADD Immediate with Carry */
758: DECLARE_INSN(ADDIC)
759: {
760: int rd = bits(insn,21,25);
761: int ra = bits(insn,16,20);
762: int imm = bits(insn,0,15);
763: m_uint32_t tmp = sign_extend_32(imm,16);
764:
765: ppc32_load_imm(b,X86_EAX,tmp);
766: ppc32_alu_gpr(b,X86_ADD,X86_EAX,ra);
767: ppc32_store_gpr(b,rd,X86_EAX);
768: x86_set_membase(b->jit_ptr,X86_CC_C,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
769: return(0);
770: }
771:
772: /* ADDIC. */
773: DECLARE_INSN(ADDIC_dot)
774: {
775: int rd = bits(insn,21,25);
776: int ra = bits(insn,16,20);
777: int imm = bits(insn,0,15);
778: m_uint32_t tmp = sign_extend_32(imm,16);
779:
780: ppc32_load_imm(b,X86_EAX,tmp);
781: ppc32_alu_gpr(b,X86_ADD,X86_EAX,ra);
782: ppc32_store_gpr(b,rd,X86_EAX);
783: x86_set_membase(b->jit_ptr,X86_CC_C,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),FALSE);
784:
785: x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
786: ppc32_update_cr0(b);
787: return(0);
788: }
789:
790: /* ADDIS - ADD Immediate Shifted */
791: DECLARE_INSN(ADDIS)
792: {
793: int rd = bits(insn,21,25);
794: int ra = bits(insn,16,20);
795: m_uint32_t imm = bits(insn,0,15);
796:
797: ppc32_load_imm(b,X86_EBX,imm << 16);
798:
799: if (ra != 0)
800: x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_EBX,X86_EDI,REG_OFFSET(ra));
801:
802: ppc32_store_gpr(b,rd,X86_EBX);
803: return(0);
804: }
805:
806: /* AND */
807: DECLARE_INSN(AND)
808: {
809: int rs = bits(insn,21,25);
810: int ra = bits(insn,16,20);
811: int rb = bits(insn,11,15);
812:
813: ppc32_load_gpr(b,X86_EBX,rs);
814: ppc32_alu_gpr(b,X86_AND,X86_EBX,rb);
815: ppc32_store_gpr(b,ra,X86_EBX);
816:
817: if (insn & 1)
818: ppc32_update_cr0(b);
819:
820: return(0);
821: }
822:
823: /* ANDC */
824: DECLARE_INSN(ANDC)
825: {
826: int rs = bits(insn,21,25);
827: int ra = bits(insn,16,20);
828: int rb = bits(insn,11,15);
829:
830: /* $ra = $rs & ~$rb */
831: ppc32_load_gpr(b,X86_EBX,rb);
832: x86_not_reg(b->jit_ptr,X86_EBX);
833: ppc32_alu_gpr(b,X86_AND,X86_EBX,rs);
834: ppc32_store_gpr(b,ra,X86_EBX);
835:
836: if (insn & 1)
837: ppc32_update_cr0(b);
838:
839: return(0);
840: }
841:
842: /* AND Immediate */
843: DECLARE_INSN(ANDI)
844: {
845: int rs = bits(insn,21,25);
846: int ra = bits(insn,16,20);
847: m_uint16_t imm = bits(insn,0,15);
848:
849: /* $ra = $rs & imm */
850: ppc32_load_imm(b,X86_EBX,imm);
851: ppc32_alu_gpr(b,X86_AND,X86_EBX,rs);
852: ppc32_store_gpr(b,ra,X86_EBX);
853:
854: ppc32_update_cr0(b);
855: return(0);
856: }
857:
858: /* AND Immediate Shifted */
859: DECLARE_INSN(ANDIS)
860: {
861: int rs = bits(insn,21,25);
862: int ra = bits(insn,16,20);
863: m_uint32_t imm = bits(insn,0,15);
864:
865: /* $ra = $rs & imm */
866: ppc32_load_imm(b,X86_EBX,imm << 16);
867: ppc32_alu_gpr(b,X86_AND,X86_EBX,rs);
868: ppc32_store_gpr(b,ra,X86_EBX);
869:
870: ppc32_update_cr0(b);
871: return(0);
872: }
873:
874: /* B - Branch */
875: DECLARE_INSN(B)
876: {
877: m_uint32_t offset = bits(insn,2,25);
878: m_uint64_t new_ia;
879:
880: /* compute the new ia */
881: new_ia = b->start_ia + ((b->ppc_trans_pos-1) << 2);
882: new_ia += sign_extend(offset << 2,26);
883: ppc32_set_jump(cpu,b,new_ia,1);
884: return(0);
885: }
886:
887: /* BA - Branch Absolute */
888: DECLARE_INSN(BA)
889: {
890: m_uint32_t offset = bits(insn,2,25);
891: m_uint64_t new_ia;
892:
893: /* compute the new ia */
894: new_ia = sign_extend(offset << 2,26);
895: ppc32_set_jump(cpu,b,new_ia,1);
896: return(0);
897: }
898:
899: /* BL - Branch and Link */
900: DECLARE_INSN(BL)
901: {
902: m_uint32_t offset = bits(insn,2,25);
903: m_uint64_t new_ia;
904:
905: /* compute the new ia */
906: new_ia = b->start_ia + ((b->ppc_trans_pos-1) << 2);
907: new_ia += sign_extend(offset << 2,26);
908:
909: /* set the return address */
910: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
911:
912: ppc32_set_jump(cpu,b,new_ia,1);
913: return(0);
914: }
915:
916: /* BLA - Branch and Link Absolute */
917: DECLARE_INSN(BLA)
918: {
919: m_uint32_t offset = bits(insn,2,25);
920: m_uint64_t new_ia;
921:
922: /* compute the new ia */
923: new_ia = sign_extend(offset << 2,26);
924:
925: /* set the return address */
926: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
927:
928: ppc32_set_jump(cpu,b,new_ia,1);
929: return(0);
930: }
931:
932: /* BC - Branch Conditional (Condition Check only) */
933: DECLARE_INSN(BCC)
934: {
935: int bo = bits(insn,21,25);
936: int bi = bits(insn,16,20);
937: int bd = bits(insn,2,15);
1.1.1.2 ! root 938: u_int cr_field,cr_bit;
1.1 root 939: m_uint32_t new_ia;
940: u_char *jump_ptr;
941: int local_jump;
942: int cond;
943:
944: /* Get the wanted value for the condition bit */
945: cond = (bo >> 3) & 0x1;
946:
947: /* Set the return address */
948: if (insn & 1)
949: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
950:
951: /* Compute the new ia */
952: new_ia = sign_extend_32(bd << 2,16);
953: if (!(insn & 0x02))
954: new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2);
955:
956: /* Test the condition bit */
1.1.1.2 ! root 957: cr_field = ppc32_get_cr_field(bi);
! 958: cr_bit = ppc32_get_cr_bit(bi);
! 959:
! 960: x86_test_membase_imm(b->jit_ptr,
! 961: X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
! 962: (1 << cr_bit));
1.1 root 963:
964: local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
965:
966: /*
967: * Optimize the jump, depending if the destination is in the same
968: * page or not.
969: */
970: if (local_jump) {
971: if (jump_ptr) {
972: x86_branch(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,jump_ptr,FALSE);
973: } else {
974: ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia);
975: x86_branch32(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,0,FALSE);
976: }
977: } else {
978: jump_ptr = b->jit_ptr;
979: x86_branch32(b->jit_ptr,(cond) ? X86_CC_Z : X86_CC_NZ,0,FALSE);
980: ppc32_set_jump(cpu,b,new_ia,TRUE);
981: x86_patch(jump_ptr,b->jit_ptr);
982: }
983:
984: return(0);
985: }
986:
987: /* BC - Branch Conditional */
988: DECLARE_INSN(BC)
989: {
990: int bo = bits(insn,21,25);
991: int bi = bits(insn,16,20);
992: int bd = bits(insn,2,15);
1.1.1.2 ! root 993: u_int cr_field,cr_bit;
1.1 root 994: m_uint32_t new_ia;
995: u_char *jump_ptr;
996: int local_jump;
997: int cond,ctr;
998:
999: /* Get the wanted value for the condition bit and CTR value */
1000: cond = (bo >> 3) & 0x1;
1001: ctr = (bo >> 1) & 0x1;
1002:
1003: /* Set the return address */
1004: if (insn & 1)
1005: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
1006:
1007: /* Compute the new ia */
1008: new_ia = sign_extend_32(bd << 2,16);
1009: if (!(insn & 0x02))
1010: new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2);
1011:
1012: x86_mov_reg_imm(b->jit_ptr,X86_EAX,1);
1013:
1014: /* Decrement the count register */
1015: if (!(bo & 0x04)) {
1016: x86_dec_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
1017: x86_set_reg(b->jit_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,X86_EBX,FALSE);
1018: x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_EBX);
1019: }
1020:
1021: /* Test the condition bit */
1022: if (!((bo >> 4) & 0x01)) {
1.1.1.2 ! root 1023: cr_field = ppc32_get_cr_field(bi);
! 1024: cr_bit = ppc32_get_cr_bit(bi);
! 1025:
! 1026: x86_test_membase_imm(b->jit_ptr,
! 1027: X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
! 1028: (1 << cr_bit));
! 1029:
1.1 root 1030: x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE);
1031: x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX);
1032: }
1033:
1034: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x01);
1035:
1036: local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
1037:
1038: /*
1039: * Optimize the jump, depending if the destination is in the same
1040: * page or not.
1041: */
1042: if (local_jump) {
1043: if (jump_ptr) {
1044: x86_branch(b->jit_ptr,X86_CC_NZ,jump_ptr,FALSE);
1045: } else {
1046: ppc32_jit_tcb_record_patch(b,b->jit_ptr,new_ia);
1047: x86_branch32(b->jit_ptr,X86_CC_NZ,0,FALSE);
1048: }
1049: } else {
1050: jump_ptr = b->jit_ptr;
1051: x86_branch32(b->jit_ptr,X86_CC_Z,0,FALSE);
1052: ppc32_set_jump(cpu,b,new_ia,TRUE);
1053: x86_patch(jump_ptr,b->jit_ptr);
1054: }
1055:
1056: return(0);
1057: }
1058:
1059: /* BCLR - Branch Conditional to Link register */
1060: DECLARE_INSN(BCLR)
1061: {
1062: int bo = bits(insn,21,25);
1063: int bi = bits(insn,16,20);
1064: int bd = bits(insn,2,15);
1.1.1.2 ! root 1065: u_int cr_field,cr_bit;
1.1 root 1066: m_uint32_t new_ia;
1067: u_char *jump_ptr;
1068: int cond,ctr;
1069:
1070: /* Get the wanted value for the condition bit and CTR value */
1071: cond = (bo >> 3) & 0x1;
1072: ctr = (bo >> 1) & 0x1;
1073:
1074: /* Compute the new ia */
1075: new_ia = sign_extend_32(bd << 2,16);
1076: if (!(insn & 0x02))
1077: new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2);
1078:
1079: ppc32_load_imm(b,X86_EAX,1);
1080:
1081: /* Decrement the count register */
1082: if (!(bo & 0x04)) {
1083: x86_dec_membase(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ctr));
1084: x86_set_reg(b->jit_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,X86_EBX,FALSE);
1085: x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_EBX);
1086: }
1087:
1088: /* Test the condition bit */
1089: if (!((bo >> 4) & 0x01)) {
1.1.1.2 ! root 1090: cr_field = ppc32_get_cr_field(bi);
! 1091: cr_bit = ppc32_get_cr_bit(bi);
! 1092:
! 1093: x86_test_membase_imm(b->jit_ptr,
! 1094: X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field),
! 1095: (1 << cr_bit));
! 1096:
1.1 root 1097: x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE);
1098: x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX);
1099: }
1100:
1101: /* Set the return address */
1102: x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,lr),4);
1103:
1104: if (insn & 1)
1105: ppc32_set_lr(b,b->start_ia + (b->ppc_trans_pos << 2));
1106:
1107: /* Branching */
1108: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x01);
1109:
1110: jump_ptr = b->jit_ptr;
1111: x86_branch32(b->jit_ptr,X86_CC_Z,0,FALSE);
1112:
1113: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EDX,0xFFFFFFFC);
1114: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,ia),X86_EDX,4);
1115: ppc32_jit_tcb_push_epilog(b);
1116:
1117: x86_patch(jump_ptr,b->jit_ptr);
1118: return(0);
1119: }
1120:
1121: /* CMP - Compare */
1122: DECLARE_INSN(CMP)
1123: {
1124: int rd = bits(insn,23,25);
1125: int ra = bits(insn,16,20);
1126: int rb = bits(insn,11,15);
1127:
1128: ppc32_load_gpr(b,X86_EBX,ra);
1129: ppc32_alu_gpr(b,X86_CMP,X86_EBX,rb);
1130: ppc32_update_cr(b,rd,TRUE);
1131: return(0);
1132: }
1133:
1134: /* CMPI - Compare Immediate */
1135: DECLARE_INSN(CMPI)
1136: {
1137: int rd = bits(insn,23,25);
1138: int ra = bits(insn,16,20);
1139: m_uint16_t imm = bits(insn,0,15);
1140: m_uint32_t tmp = sign_extend_32(imm,16);
1141:
1142: ppc32_load_imm(b,X86_EBX,tmp);
1143: ppc32_load_gpr(b,X86_ESI,ra);
1144: x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ESI,X86_EBX);
1145:
1146: ppc32_update_cr(b,rd,TRUE);
1147: return(0);
1148: }
1149:
1150: /* CMPL - Compare Logical */
1151: DECLARE_INSN(CMPL)
1152: {
1153: int rd = bits(insn,23,25);
1154: int ra = bits(insn,16,20);
1155: int rb = bits(insn,11,15);
1156:
1157: ppc32_load_gpr(b,X86_EAX,ra);
1158: ppc32_alu_gpr(b,X86_CMP,X86_EAX,rb);
1159: ppc32_update_cr(b,rd,FALSE);
1160: return(0);
1161: }
1162:
1163: /* CMPLI - Compare Immediate */
1164: DECLARE_INSN(CMPLI)
1165: {
1166: int rd = bits(insn,23,25);
1167: int ra = bits(insn,16,20);
1168: m_uint16_t imm = bits(insn,0,15);
1169:
1170: ppc32_load_imm(b,X86_EBX,imm);
1171: ppc32_load_gpr(b,X86_ESI,ra);
1172: x86_alu_reg_reg(b->jit_ptr,X86_CMP,X86_ESI,X86_EBX);
1173:
1174: ppc32_update_cr(b,rd,FALSE);
1175: return(0);
1176: }
1177:
1178: /* CRAND - Condition Register AND */
1179: DECLARE_INSN(CRAND)
1180: {
1181: int bd = bits(insn,21,25);
1182: int bb = bits(insn,16,20);
1183: int ba = bits(insn,11,15);
1184:
1185: /* test $ba bit */
1.1.1.2 ! root 1186: x86_test_membase_imm(b->jit_ptr,
! 1187: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
! 1188: (1 << ppc32_get_cr_bit(ba)));
1.1 root 1189: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1190:
1191: /* test $bb bit */
1.1.1.2 ! root 1192: x86_test_membase_imm(b->jit_ptr,
! 1193: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
! 1194: (1 << ppc32_get_cr_bit(bb)));
1.1 root 1195: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1196:
1197: /* result of AND between $ba and $bb */
1198: x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EBX,X86_EAX);
1199: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1200:
1201: /* set/clear $bd bit depending on the result */
1.1.1.2 ! root 1202: x86_alu_membase_imm(b->jit_ptr,X86_AND,
! 1203: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1204: ~(1 << ppc32_get_cr_bit(bd)));
! 1205:
! 1206: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
! 1207: x86_alu_membase_reg(b->jit_ptr,X86_OR,
! 1208: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1209: X86_EBX);
1.1 root 1210: return(0);
1211: }
1212:
1213: /* CRANDC - Condition Register AND with Complement */
1214: DECLARE_INSN(CRANDC)
1215: {
1216: int bd = bits(insn,21,25);
1217: int bb = bits(insn,16,20);
1218: int ba = bits(insn,11,15);
1219:
1220: /* test $ba bit */
1.1.1.2 ! root 1221: x86_test_membase_imm(b->jit_ptr,
! 1222: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
! 1223: (1 << ppc32_get_cr_bit(ba)));
1.1 root 1224: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1225:
1226: /* test $bb bit */
1.1.1.2 ! root 1227: x86_test_membase_imm(b->jit_ptr,
! 1228: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
! 1229: (1 << ppc32_get_cr_bit(bb)));
1.1 root 1230: x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE);
1231:
1232: /* result of AND between $ba and $bb */
1233: x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EBX,X86_EAX);
1234: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1235:
1236: /* set/clear $bd bit depending on the result */
1.1.1.2 ! root 1237: x86_alu_membase_imm(b->jit_ptr,X86_AND,
! 1238: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1239: ~(1 << ppc32_get_cr_bit(bd)));
! 1240:
! 1241: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
! 1242: x86_alu_membase_reg(b->jit_ptr,X86_OR,
! 1243: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1244: X86_EBX);
1.1 root 1245: return(0);
1246: }
1247:
1248: /* CREQV - Condition Register EQV */
1249: DECLARE_INSN(CREQV)
1250: {
1251: int bd = bits(insn,21,25);
1252: int bb = bits(insn,16,20);
1253: int ba = bits(insn,11,15);
1254:
1255: /* test $ba bit */
1.1.1.2 ! root 1256: x86_test_membase_imm(b->jit_ptr,
! 1257: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
! 1258: (1 << ppc32_get_cr_bit(ba)));
1.1 root 1259: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1260:
1261: /* test $bb bit */
1.1.1.2 ! root 1262: x86_test_membase_imm(b->jit_ptr,
! 1263: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
! 1264: (1 << ppc32_get_cr_bit(bb)));
1.1 root 1265: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1266:
1267: /* result of XOR between $ba and $bb */
1268: x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EAX);
1269: x86_not_reg(b->jit_ptr,X86_EBX);
1270: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1271:
1272: /* set/clear $bd bit depending on the result */
1.1.1.2 ! root 1273: x86_alu_membase_imm(b->jit_ptr,X86_AND,
! 1274: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1275: ~(1 << ppc32_get_cr_bit(bd)));
! 1276:
! 1277: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
! 1278: x86_alu_membase_reg(b->jit_ptr,X86_OR,
! 1279: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1280: X86_EBX);
1.1 root 1281: return(0);
1282: }
1283:
1284: /* CRNAND - Condition Register NAND */
1285: DECLARE_INSN(CRNAND)
1286: {
1287: int bd = bits(insn,21,25);
1288: int bb = bits(insn,16,20);
1289: int ba = bits(insn,11,15);
1290:
1291: /* test $ba bit */
1.1.1.2 ! root 1292: x86_test_membase_imm(b->jit_ptr,
! 1293: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
! 1294: (1 << ppc32_get_cr_bit(ba)));
1.1 root 1295: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1296:
1297: /* test $bb bit */
1.1.1.2 ! root 1298: x86_test_membase_imm(b->jit_ptr,
! 1299: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
! 1300: (1 << ppc32_get_cr_bit(bb)));
1.1 root 1301: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1302:
1303: /* result of NAND between $ba and $bb */
1304: x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EBX,X86_EAX);
1305: x86_not_reg(b->jit_ptr,X86_EBX);
1306: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1307:
1308: /* set/clear $bd bit depending on the result */
1.1.1.2 ! root 1309: x86_alu_membase_imm(b->jit_ptr,X86_AND,
! 1310: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1311: ~(1 << ppc32_get_cr_bit(bd)));
! 1312:
! 1313: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
! 1314: x86_alu_membase_reg(b->jit_ptr,X86_OR,
! 1315: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1316: X86_EBX);
1.1 root 1317: return(0);
1318: }
1319:
1320: /* CRNOR - Condition Register NOR */
1321: DECLARE_INSN(CRNOR)
1322: {
1323: int bd = bits(insn,21,25);
1324: int bb = bits(insn,16,20);
1325: int ba = bits(insn,11,15);
1326:
1327: /* test $ba bit */
1.1.1.2 ! root 1328: x86_test_membase_imm(b->jit_ptr,
! 1329: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
! 1330: (1 << ppc32_get_cr_bit(ba)));
1.1 root 1331: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1332:
1333: /* test $bb bit */
1.1.1.2 ! root 1334: x86_test_membase_imm(b->jit_ptr,
! 1335: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
! 1336: (1 << ppc32_get_cr_bit(bb)));
1.1 root 1337: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1338:
1339: /* result of NOR between $ba and $bb */
1340: x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
1341: x86_not_reg(b->jit_ptr,X86_EBX);
1342: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1343:
1344: /* set/clear $bd bit depending on the result */
1.1.1.2 ! root 1345: x86_alu_membase_imm(b->jit_ptr,X86_AND,
! 1346: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1347: ~(1 << ppc32_get_cr_bit(bd)));
! 1348:
! 1349: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
! 1350: x86_alu_membase_reg(b->jit_ptr,X86_OR,
! 1351: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1352: X86_EBX);
1.1 root 1353: return(0);
1354: }
1355:
1356: /* CROR - Condition Register OR */
1357: DECLARE_INSN(CROR)
1358: {
1359: int bd = bits(insn,21,25);
1360: int bb = bits(insn,16,20);
1361: int ba = bits(insn,11,15);
1362:
1363: /* test $ba bit */
1.1.1.2 ! root 1364: x86_test_membase_imm(b->jit_ptr,
! 1365: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
! 1366: (1 << ppc32_get_cr_bit(ba)));
1.1 root 1367: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1368:
1369: /* test $bb bit */
1.1.1.2 ! root 1370: x86_test_membase_imm(b->jit_ptr,
! 1371: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
! 1372: (1 << ppc32_get_cr_bit(bb)));
1.1 root 1373: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1374:
1375: /* result of OR between $ba and $bb */
1376: x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
1377: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1378:
1379: /* set/clear $bd bit depending on the result */
1.1.1.2 ! root 1380: x86_alu_membase_imm(b->jit_ptr,X86_AND,
! 1381: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1382: ~(1 << ppc32_get_cr_bit(bd)));
! 1383:
! 1384: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
! 1385: x86_alu_membase_reg(b->jit_ptr,X86_OR,
! 1386: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1387: X86_EBX);
1.1 root 1388: return(0);
1389: }
1390:
1391: /* CRORC - Condition Register OR with Complement */
1392: DECLARE_INSN(CRORC)
1393: {
1394: int bd = bits(insn,21,25);
1395: int bb = bits(insn,16,20);
1396: int ba = bits(insn,11,15);
1397:
1398: /* test $ba bit */
1.1.1.2 ! root 1399: x86_test_membase_imm(b->jit_ptr,
! 1400: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
! 1401: (1 << ppc32_get_cr_bit(ba)));
1.1 root 1402: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1403:
1404: /* test $bb bit */
1.1.1.2 ! root 1405: x86_test_membase_imm(b->jit_ptr,
! 1406: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
! 1407: (1 << ppc32_get_cr_bit(bb)));
1.1 root 1408: x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE);
1409:
1410: /* result of ORC between $ba and $bb */
1411: x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
1412: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1413:
1414: /* set/clear $bd bit depending on the result */
1.1.1.2 ! root 1415: x86_alu_membase_imm(b->jit_ptr,X86_AND,
! 1416: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1417: ~(1 << ppc32_get_cr_bit(bd)));
! 1418:
! 1419: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
! 1420: x86_alu_membase_reg(b->jit_ptr,X86_OR,
! 1421: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1422: X86_EBX);
1.1 root 1423: return(0);
1424: }
1425:
1426: /* CRXOR - Condition Register XOR */
1427: DECLARE_INSN(CRXOR)
1428: {
1429: int bd = bits(insn,21,25);
1430: int bb = bits(insn,16,20);
1431: int ba = bits(insn,11,15);
1432:
1433: /* test $ba bit */
1.1.1.2 ! root 1434: x86_test_membase_imm(b->jit_ptr,
! 1435: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
! 1436: (1 << ppc32_get_cr_bit(ba)));
1.1 root 1437: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE);
1438:
1439: /* test $bb bit */
1.1.1.2 ! root 1440: x86_test_membase_imm(b->jit_ptr,
! 1441: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
! 1442: (1 << ppc32_get_cr_bit(bb)));
1.1 root 1443: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE);
1444:
1445: /* result of XOR between $ba and $bb */
1446: x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EAX);
1447: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01);
1448:
1449: /* set/clear $bd bit depending on the result */
1.1.1.2 ! root 1450: x86_alu_membase_imm(b->jit_ptr,X86_AND,
! 1451: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1452: ~(1 << ppc32_get_cr_bit(bd)));
! 1453:
! 1454: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd));
! 1455: x86_alu_membase_reg(b->jit_ptr,X86_OR,
! 1456: X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
! 1457: X86_EBX);
1.1 root 1458: return(0);
1459: }
1460:
1461: /* DIVWU - Divide Word Unsigned */
1462: DECLARE_INSN(DIVWU)
1463: {
1464: int rd = bits(insn,21,25);
1465: int ra = bits(insn,16,20);
1466: int rb = bits(insn,11,15);
1467:
1468: ppc32_load_gpr(b,X86_EAX,ra);
1469: ppc32_load_gpr(b,X86_EBX,rb);
1470: ppc32_load_imm(b,X86_EDX,0);
1471:
1472: x86_div_reg(b->jit_ptr,X86_EBX,0);
1473: ppc32_store_gpr(b,rd,X86_EAX);
1474:
1475: if (insn & 1) {
1476: x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
1477: ppc32_update_cr0(b);
1478: }
1479:
1480: return(0);
1481: }
1482:
1483: /* EQV */
1484: DECLARE_INSN(EQV)
1485: {
1486: int rs = bits(insn,21,25);
1487: int ra = bits(insn,16,20);
1488: int rb = bits(insn,11,15);
1489:
1490: /* $ra = ~($rs ^ $rb) */
1491: ppc32_load_gpr(b,X86_EBX,rs);
1492: ppc32_alu_gpr(b,X86_XOR,X86_EBX,rb);
1493: x86_not_reg(b->jit_ptr,X86_EBX);
1494: ppc32_store_gpr(b,ra,X86_EBX);
1495:
1496: if (insn & 1) {
1497: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1498: ppc32_update_cr0(b);
1499: }
1500:
1501: return(0);
1502: }
1503:
1504: /* EXTSB - Extend Sign Byte */
1505: DECLARE_INSN(EXTSB)
1506: {
1507: int rs = bits(insn,21,25);
1508: int ra = bits(insn,16,20);
1509:
1510: ppc32_load_gpr(b,X86_EBX,rs);
1511: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,24);
1512: x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,24);
1513: ppc32_store_gpr(b,ra,X86_EBX);
1514:
1515: if (insn & 1) {
1516: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1517: ppc32_update_cr0(b);
1518: }
1519:
1520: return(0);
1521: }
1522:
1523: /* EXTSH - Extend Sign Word */
1524: DECLARE_INSN(EXTSH)
1525: {
1526: int rs = bits(insn,21,25);
1527: int ra = bits(insn,16,20);
1528:
1529: ppc32_load_gpr(b,X86_EBX,rs);
1530: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,16);
1531: x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,16);
1532: ppc32_store_gpr(b,ra,X86_EBX);
1533:
1534: if (insn & 1) {
1535: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1536: ppc32_update_cr0(b);
1537: }
1538:
1539: return(0);
1540: }
1541:
1542: /* LBZ - Load Byte and Zero */
1543: DECLARE_INSN(LBZ)
1544: {
1545: int rs = bits(insn,21,25);
1546: int ra = bits(insn,16,20);
1547: m_uint16_t offset = bits(insn,0,15);
1548:
1549: //ppc32_emit_memop(b,PPC_MEMOP_LBZ,ra,offset,rs,0);
1550: ppc32_emit_memop_fast(b,0,PPC_MEMOP_LBZ,ra,offset,rs,ppc32_memop_fast_lbz);
1551: return(0);
1552: }
1553:
1554: /* LBZU - Load Byte and Zero with Update */
1555: DECLARE_INSN(LBZU)
1556: {
1557: int rs = bits(insn,21,25);
1558: int ra = bits(insn,16,20);
1559: m_uint16_t offset = bits(insn,0,15);
1560:
1561: ppc32_emit_memop(b,PPC_MEMOP_LBZ,ra,offset,rs,1);
1562: return(0);
1563: }
1564:
1565: /* LBZUX - Load Byte and Zero with Update Indexed */
1566: DECLARE_INSN(LBZUX)
1567: {
1568: int rs = bits(insn,21,25);
1569: int ra = bits(insn,16,20);
1570: int rb = bits(insn,11,15);
1571:
1572: ppc32_emit_memop_idx(b,PPC_MEMOP_LBZ,ra,rb,rs,1);
1573: return(0);
1574: }
1575:
1576: /* LBZX - Load Byte and Zero Indexed */
1577: DECLARE_INSN(LBZX)
1578: {
1579: int rs = bits(insn,21,25);
1580: int ra = bits(insn,16,20);
1581: int rb = bits(insn,11,15);
1582:
1583: ppc32_emit_memop_idx(b,PPC_MEMOP_LBZ,ra,rb,rs,0);
1584: return(0);
1585: }
1586:
1587: /* LHA - Load Half-Word Algebraic */
1588: DECLARE_INSN(LHA)
1589: {
1590: int rs = bits(insn,21,25);
1591: int ra = bits(insn,16,20);
1592: m_uint16_t offset = bits(insn,0,15);
1593:
1594: ppc32_emit_memop(b,PPC_MEMOP_LHA,ra,offset,rs,0);
1595: return(0);
1596: }
1597:
1598: /* LHAU - Load Half-Word Algebraic with Update */
1599: DECLARE_INSN(LHAU)
1600: {
1601: int rs = bits(insn,21,25);
1602: int ra = bits(insn,16,20);
1603: m_uint16_t offset = bits(insn,0,15);
1604:
1605: ppc32_emit_memop(b,PPC_MEMOP_LHA,ra,offset,rs,1);
1606: return(0);
1607: }
1608:
1609: /* LHAUX - Load Half-Word Algebraic with Update Indexed */
1610: DECLARE_INSN(LHAUX)
1611: {
1612: int rs = bits(insn,21,25);
1613: int ra = bits(insn,16,20);
1614: int rb = bits(insn,11,15);
1615:
1616: ppc32_emit_memop_idx(b,PPC_MEMOP_LHA,ra,rb,rs,1);
1617: return(0);
1618: }
1619:
1620: /* LHAX - Load Half-Word Algebraic Indexed */
1621: DECLARE_INSN(LHAX)
1622: {
1623: int rs = bits(insn,21,25);
1624: int ra = bits(insn,16,20);
1625: int rb = bits(insn,11,15);
1626:
1627: ppc32_emit_memop_idx(b,PPC_MEMOP_LHA,ra,rb,rs,0);
1628: return(0);
1629: }
1630:
1631: /* LHZ - Load Half-Word and Zero */
1632: DECLARE_INSN(LHZ)
1633: {
1634: int rs = bits(insn,21,25);
1635: int ra = bits(insn,16,20);
1636: m_uint16_t offset = bits(insn,0,15);
1637:
1638: ppc32_emit_memop(b,PPC_MEMOP_LHZ,ra,offset,rs,0);
1639: return(0);
1640: }
1641:
1642: /* LHZU - Load Half-Word and Zero with Update */
1643: DECLARE_INSN(LHZU)
1644: {
1645: int rs = bits(insn,21,25);
1646: int ra = bits(insn,16,20);
1647: m_uint16_t offset = bits(insn,0,15);
1648:
1649: ppc32_emit_memop(b,PPC_MEMOP_LHZ,ra,offset,rs,1);
1650: return(0);
1651: }
1652:
1653: /* LHZUX - Load Half-Word and Zero with Update Indexed */
1654: DECLARE_INSN(LHZUX)
1655: {
1656: int rs = bits(insn,21,25);
1657: int ra = bits(insn,16,20);
1658: int rb = bits(insn,11,15);
1659:
1660: ppc32_emit_memop_idx(b,PPC_MEMOP_LHZ,ra,rb,rs,1);
1661: return(0);
1662: }
1663:
1664: /* LHZX - Load Half-Word and Zero Indexed */
1665: DECLARE_INSN(LHZX)
1666: {
1667: int rs = bits(insn,21,25);
1668: int ra = bits(insn,16,20);
1669: int rb = bits(insn,11,15);
1670:
1671: ppc32_emit_memop_idx(b,PPC_MEMOP_LHZ,ra,rb,rs,0);
1672: return(0);
1673: }
1674:
1675: /* LWZ - Load Word and Zero */
1676: DECLARE_INSN(LWZ)
1677: {
1678: int rs = bits(insn,21,25);
1679: int ra = bits(insn,16,20);
1680: m_uint16_t offset = bits(insn,0,15);
1681:
1682: //ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,0);
1683: ppc32_emit_memop_fast(b,0,PPC_MEMOP_LWZ,ra,offset,rs,ppc32_memop_fast_lwz);
1684: return(0);
1685: }
1686:
1687: /* LWZU - Load Word and Zero with Update */
1688: DECLARE_INSN(LWZU)
1689: {
1690: int rs = bits(insn,21,25);
1691: int ra = bits(insn,16,20);
1692: m_uint16_t offset = bits(insn,0,15);
1693:
1694: ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,1);
1695: return(0);
1696: }
1697:
1698: /* LWZUX - Load Word and Zero with Update Indexed */
1699: DECLARE_INSN(LWZUX)
1700: {
1701: int rs = bits(insn,21,25);
1702: int ra = bits(insn,16,20);
1703: int rb = bits(insn,11,15);
1704:
1705: ppc32_emit_memop_idx(b,PPC_MEMOP_LWZ,ra,rb,rs,1);
1706: return(0);
1707: }
1708:
1709: /* LWZX - Load Word and Zero Indexed */
1710: DECLARE_INSN(LWZX)
1711: {
1712: int rs = bits(insn,21,25);
1713: int ra = bits(insn,16,20);
1714: int rb = bits(insn,11,15);
1715:
1716: ppc32_emit_memop_idx(b,PPC_MEMOP_LWZ,ra,rb,rs,0);
1717: return(0);
1718: }
1719:
1720: /* MCRF - Move Condition Register Field */
1721: DECLARE_INSN(MCRF)
1722: {
1723: int rd = bits(insn,23,25);
1724: int rs = bits(insn,18,20);
1725:
1.1.1.2 ! root 1726: /* Load "rs" field in %edx */
! 1727: x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,PPC32_CR_FIELD_OFFSET(rs),4);
! 1728:
! 1729: /* Store it in "rd" field */
! 1730: x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(rd),X86_EDX,4);
1.1 root 1731: return(0);
1732: }
1733:
1734: /* MFCR - Move from Condition Register */
1735: DECLARE_INSN(MFCR)
1736: {
1737: int rd = bits(insn,21,25);
1.1.1.2 ! root 1738: int i;
! 1739:
! 1740: x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EAX,X86_EAX);
! 1741:
! 1742: for(i=0;i<8;i++) {
! 1743: /* load field in %edx */
! 1744: x86_mov_reg_membase(b->jit_ptr,X86_EDX,
! 1745: X86_EDI,PPC32_CR_FIELD_OFFSET(i),4);
! 1746: x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,4);
! 1747: x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_EDX);
! 1748: }
1.1 root 1749:
1750: ppc32_store_gpr(b,rd,X86_EAX);
1751: return(0);
1752: }
1753:
1754: /* MFMSR - Move from Machine State Register */
1755: DECLARE_INSN(MFMSR)
1756: {
1757: int rd = bits(insn,21,25);
1758:
1759: x86_mov_reg_membase(b->jit_ptr,X86_EAX,X86_EDI,OFFSET(cpu_ppc_t,msr),4);
1760: ppc32_store_gpr(b,rd,X86_EAX);
1761: return(0);
1762: }
1763:
1764: /* MFSR - Move From Segment Register */
1765: DECLARE_INSN(MFSR)
1766: {
1767: int rd = bits(insn,21,25);
1768: int sr = bits(insn,16,19);
1769:
1770: x86_mov_reg_membase(b->jit_ptr,X86_EAX,
1771: X86_EDI,(OFFSET(cpu_ppc_t,sr) + (sr << 2)),4);
1772: ppc32_store_gpr(b,rd,X86_EAX);
1773: return(0);
1774: }
1775:
1776: /* MTCRF - Move to Condition Register Fields */
1777: DECLARE_INSN(MTCRF)
1778: {
1779: int rs = bits(insn,21,25);
1780: int crm = bits(insn,12,19);
1781: int i;
1782:
1.1.1.2 ! root 1783: ppc32_load_gpr(b,X86_EDX,rs);
! 1784:
1.1 root 1785: for(i=0;i<8;i++)
1.1.1.2 ! root 1786: if (crm & (1 << (7 - i))) {
! 1787: x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDX,4);
1.1 root 1788:
1.1.1.2 ! root 1789: if (i != 7)
! 1790: x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,28 - (i << 2));
1.1 root 1791:
1.1.1.2 ! root 1792: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x0F);
! 1793: x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(i),
! 1794: X86_EAX,4);
! 1795: }
1.1 root 1796:
1797: return(0);
1798: }
1799:
1800: /* MULHW - Multiply High Word */
1801: DECLARE_INSN(MULHW)
1802: {
1803: int rd = bits(insn,21,25);
1804: int ra = bits(insn,16,20);
1805: int rb = bits(insn,11,15);
1806:
1807: ppc32_load_gpr(b,X86_EAX,ra);
1808: ppc32_load_gpr(b,X86_EBX,rb);
1809: x86_mul_reg(b->jit_ptr,X86_EBX,1);
1810: ppc32_store_gpr(b,rd,X86_EDX);
1811:
1812: if (insn & 1) {
1813: x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
1814: ppc32_update_cr0(b);
1815: }
1816:
1817: return(0);
1818: }
1819:
1820: /* MULHWU - Multiply High Word Unsigned */
1821: DECLARE_INSN(MULHWU)
1822: {
1823: int rd = bits(insn,21,25);
1824: int ra = bits(insn,16,20);
1825: int rb = bits(insn,11,15);
1826:
1827: ppc32_load_gpr(b,X86_EAX,ra);
1828: ppc32_load_gpr(b,X86_EBX,rb);
1829: x86_mul_reg(b->jit_ptr,X86_EBX,0);
1830: ppc32_store_gpr(b,rd,X86_EDX);
1831:
1832: if (insn & 1) {
1833: x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX);
1834: ppc32_update_cr0(b);
1835: }
1836:
1837: return(0);
1838: }
1839:
1840: /* MULLI - Multiply Low Immediate */
1841: DECLARE_INSN(MULLI)
1842: {
1843: int rd = bits(insn,21,25);
1844: int ra = bits(insn,16,20);
1845: m_uint32_t imm = bits(insn,0,15);
1846:
1847: ppc32_load_gpr(b,X86_EAX,ra);
1848: ppc32_load_imm(b,X86_EBX,sign_extend_32(imm,16));
1849:
1850: x86_mul_reg(b->jit_ptr,X86_EBX,1);
1851: ppc32_store_gpr(b,rd,X86_EAX);
1852: return(0);
1853: }
1854:
1855: /* MULLW - Multiply Low Word */
1856: DECLARE_INSN(MULLW)
1857: {
1858: int rd = bits(insn,21,25);
1859: int ra = bits(insn,16,20);
1860: int rb = bits(insn,11,15);
1861:
1862: ppc32_load_gpr(b,X86_EAX,ra);
1863: ppc32_load_gpr(b,X86_EBX,rb);
1864: x86_mul_reg(b->jit_ptr,X86_EBX,1);
1865: ppc32_store_gpr(b,rd,X86_EAX);
1866:
1867: if (insn & 1) {
1868: x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX);
1869: ppc32_update_cr0(b);
1870: }
1871:
1872: return(0);
1873: }
1874:
1875: /* NAND */
1876: DECLARE_INSN(NAND)
1877: {
1878: int rs = bits(insn,21,25);
1879: int ra = bits(insn,16,20);
1880: int rb = bits(insn,11,15);
1881:
1882: /* $ra = ~($rs & $rb) */
1883: ppc32_load_gpr(b,X86_EBX,rs);
1884: ppc32_alu_gpr(b,X86_AND,X86_EBX,rb);
1885: x86_not_reg(b->jit_ptr,X86_EBX);
1886: ppc32_store_gpr(b,ra,X86_EBX);
1887:
1888: if (insn & 1) {
1889: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1890: ppc32_update_cr0(b);
1891: }
1892:
1893: return(0);
1894: }
1895:
1896: /* NEG */
1897: DECLARE_INSN(NEG)
1898: {
1899: int rd = bits(insn,21,25);
1900: int ra = bits(insn,16,20);
1901:
1902: ppc32_load_gpr(b,X86_EBX,ra);
1903: x86_neg_reg(b->jit_ptr,X86_EBX);
1904: ppc32_store_gpr(b,rd,X86_EBX);
1905:
1906: if (insn & 1) {
1907: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1908: ppc32_update_cr0(b);
1909: }
1910:
1911: return(0);
1912: }
1913:
1914: /* NOR */
1915: DECLARE_INSN(NOR)
1916: {
1917: int rs = bits(insn,21,25);
1918: int ra = bits(insn,16,20);
1919: int rb = bits(insn,11,15);
1920:
1921: /* $ra = ~($rs | $rb) */
1922: ppc32_load_gpr(b,X86_EBX,rs);
1923: ppc32_alu_gpr(b,X86_OR,X86_EBX,rb);
1924: x86_not_reg(b->jit_ptr,X86_EBX);
1925: ppc32_store_gpr(b,ra,X86_EBX);
1926:
1927: if (insn & 1) {
1928: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
1929: ppc32_update_cr0(b);
1930: }
1931:
1932: return(0);
1933: }
1934:
1935: /* OR */
1936: DECLARE_INSN(OR)
1937: {
1938: int rs = bits(insn,21,25);
1939: int ra = bits(insn,16,20);
1940: int rb = bits(insn,11,15);
1941:
1942: ppc32_load_gpr(b,X86_ECX,rs);
1943:
1944: if (rs != rb)
1945: ppc32_alu_gpr(b,X86_OR,X86_ECX,rb);
1946:
1947: ppc32_store_gpr(b,ra,X86_ECX);
1948:
1949: if (insn & 1) {
1950: if (rs == rb)
1951: x86_test_reg_reg(b->jit_ptr,X86_ECX,X86_ECX);
1952: ppc32_update_cr0(b);
1953: }
1954:
1955: return(0);
1956: }
1957:
1958: /* OR with Complement */
1959: DECLARE_INSN(ORC)
1960: {
1961: int rs = bits(insn,21,25);
1962: int ra = bits(insn,16,20);
1963: int rb = bits(insn,11,15);
1964:
1965: /* $ra = $rs | ~$rb */
1966: ppc32_load_gpr(b,X86_EBX,rb);
1967: x86_not_reg(b->jit_ptr,X86_EBX);
1968: ppc32_alu_gpr(b,X86_OR,X86_EBX,rs);
1969: ppc32_store_gpr(b,ra,X86_EBX);
1970:
1971: if (insn & 1)
1972: ppc32_update_cr0(b);
1973:
1974: return(0);
1975: }
1976:
1977: /* OR Immediate */
1978: DECLARE_INSN(ORI)
1979: {
1980: int rs = bits(insn,21,25);
1981: int ra = bits(insn,16,20);
1982: m_uint16_t imm = bits(insn,0,15);
1983:
1984: /* $ra = $rs | imm */
1985: ppc32_load_imm(b,X86_EBX,imm);
1986: ppc32_alu_gpr(b,X86_OR,X86_EBX,rs);
1987: ppc32_store_gpr(b,ra,X86_EBX);
1988: return(0);
1989: }
1990:
1991: /* OR Immediate Shifted */
1992: DECLARE_INSN(ORIS)
1993: {
1994: int rs = bits(insn,21,25);
1995: int ra = bits(insn,16,20);
1996: m_uint32_t imm = bits(insn,0,15);
1997:
1998: /* $ra = $rs | (imm << 16) */
1999: ppc32_load_imm(b,X86_EBX,imm << 16);
2000: ppc32_alu_gpr(b,X86_OR,X86_EBX,rs);
2001: ppc32_store_gpr(b,ra,X86_EBX);
2002: return(0);
2003: }
2004:
2005: /* RLWIMI - Rotate Left Word Immediate then Mask Insert */
2006: DECLARE_INSN(RLWIMI)
2007: {
2008: int rs = bits(insn,21,25);
2009: int ra = bits(insn,16,20);
2010: int sh = bits(insn,11,15);
2011: int mb = bits(insn,6,10);
2012: int me = bits(insn,1,5);
2013: register m_uint32_t mask;
2014:
2015: mask = ppc32_rotate_mask(mb,me);
2016:
2017: /* Apply inverse mask to %eax "ra" */
2018: ppc32_load_gpr(b,X86_EAX,ra);
2019: if (mask != 0)
2020: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,~mask);
2021:
2022: /* Rotate %ebx ("rs") of "sh" bits and apply the mask */
2023: ppc32_load_gpr(b,X86_EBX,rs);
2024:
2025: if (sh != 0)
2026: x86_shift_reg_imm(b->jit_ptr,X86_ROL,X86_EBX,sh);
2027:
2028: if (mask != 0xFFFFFFFF)
2029: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,mask);
2030:
2031: /* Store the result */
2032: x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EBX,X86_EAX);
2033: ppc32_store_gpr(b,ra,X86_EBX);
2034:
2035: if (insn & 1)
2036: ppc32_update_cr0(b);
2037:
2038: return(0);
2039: }
2040:
2041: /* RLWINM - Rotate Left Word Immediate AND with Mask */
2042: DECLARE_INSN(RLWINM)
2043: {
2044: int rs = bits(insn,21,25);
2045: int ra = bits(insn,16,20);
2046: int sh = bits(insn,11,15);
2047: int mb = bits(insn,6,10);
2048: int me = bits(insn,1,5);
2049: register m_uint32_t mask;
2050:
2051: mask = ppc32_rotate_mask(mb,me);
2052:
2053: /* Rotate %ebx ("rs") of "sh" bits and apply the mask */
2054: ppc32_load_gpr(b,X86_EBX,rs);
2055:
2056: if (sh != 0)
2057: x86_shift_reg_imm(b->jit_ptr,X86_ROL,X86_EBX,sh);
2058:
2059: if (mask != 0xFFFFFFFF)
2060: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,mask);
2061:
2062: ppc32_store_gpr(b,ra,X86_EBX);
2063:
2064: if (insn & 1) {
2065: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
2066: ppc32_update_cr0(b);
2067: }
2068:
2069: return(0);
2070: }
2071:
2072: /* RLWNM - Rotate Left Word then Mask Insert */
2073: DECLARE_INSN(RLWNM)
2074: {
2075: int rs = bits(insn,21,25);
2076: int ra = bits(insn,16,20);
2077: int rb = bits(insn,11,15);
2078: int mb = bits(insn,6,10);
2079: int me = bits(insn,1,5);
2080: register m_uint32_t mask;
2081:
2082: mask = ppc32_rotate_mask(mb,me);
2083:
2084: /* Load the shift register ("sh") */
2085: ppc32_load_gpr(b,X86_ECX,rb);
2086:
2087: /* Rotate %ebx ("rs") and apply the mask */
2088: ppc32_load_gpr(b,X86_EBX,rs);
2089: x86_shift_reg(b->jit_ptr,X86_ROL,X86_EBX);
2090:
2091: if (mask != 0xFFFFFFFF)
2092: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,mask);
2093:
2094: ppc32_store_gpr(b,ra,X86_EBX);
2095:
2096: if (insn & 1) {
2097: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
2098: ppc32_update_cr0(b);
2099: }
2100:
2101: return(0);
2102: }
2103:
2104: /* Shift Left Word */
2105: DECLARE_INSN(SLW)
2106: {
2107: int rs = bits(insn,21,25);
2108: int ra = bits(insn,16,20);
2109: int rb = bits(insn,11,15);
2110: u_char *test1;
2111:
2112: /* If count >= 32, then null result */
2113: ppc32_load_gpr(b,X86_ECX,rb);
2114: x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EBX);
2115:
2116: x86_test_reg_imm(b->jit_ptr,X86_ECX,0x20);
2117: test1 = b->jit_ptr;
2118: x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
2119:
2120: ppc32_load_gpr(b,X86_EBX,rs);
2121: x86_shift_reg(b->jit_ptr,X86_SHL,X86_EBX);
2122:
2123: /* Store the result */
2124: x86_patch(test1,b->jit_ptr);
2125: ppc32_store_gpr(b,ra,X86_EBX);
2126:
2127: if (insn & 1) {
2128: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
2129: ppc32_update_cr0(b);
2130: }
2131:
2132: return(0);
2133: }
2134:
2135: /* SRAWI - Shift Right Algebraic Word Immediate */
2136: DECLARE_INSN(SRAWI)
2137: {
2138: int rs = bits(insn,21,25);
2139: int ra = bits(insn,16,20);
2140: int sh = bits(insn,11,15);
2141: register m_uint32_t mask;
2142:
2143: mask = ~(0xFFFFFFFFU << sh);
2144:
2145: /* $ra = (int32)$rs >> sh */
2146: ppc32_load_gpr(b,X86_EBX,rs);
2147: x86_mov_reg_reg(b->jit_ptr,X86_ESI,X86_EBX,4);
2148: x86_shift_reg_imm(b->jit_ptr,X86_SAR,X86_EBX,sh);
2149: ppc32_store_gpr(b,ra,X86_EBX);
2150:
2151: /* test the sign-bit of gpr[rs] */
2152: x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
2153: x86_set_reg(b->jit_ptr,X86_CC_LT,X86_EAX,TRUE);
2154:
2155: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,mask);
2156: x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_ECX,TRUE);
2157:
2158: x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_ECX,X86_EAX);
2159: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,0x1);
2160: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_ECX,4);
2161:
2162: if (insn & 1) {
2163: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
2164: ppc32_update_cr0(b);
2165: }
2166:
2167: return(0);
2168: }
2169:
2170: /* Shift Right Word */
2171: DECLARE_INSN(SRW)
2172: {
2173: int rs = bits(insn,21,25);
2174: int ra = bits(insn,16,20);
2175: int rb = bits(insn,11,15);
2176: u_char *test1;
2177:
2178: /* If count >= 32, then null result */
2179: ppc32_load_gpr(b,X86_ECX,rb);
2180: x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EBX,X86_EBX);
2181:
2182: x86_test_reg_imm(b->jit_ptr,X86_ECX,0x20);
2183: test1 = b->jit_ptr;
2184: x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1);
2185:
2186: ppc32_load_gpr(b,X86_EBX,rs);
2187: x86_shift_reg(b->jit_ptr,X86_SHR,X86_EBX);
2188:
2189: /* Store the result */
2190: x86_patch(test1,b->jit_ptr);
2191: ppc32_store_gpr(b,ra,X86_EBX);
2192:
2193: if (insn & 1) {
2194: x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX);
2195: ppc32_update_cr0(b);
2196: }
2197:
2198: return(0);
2199: }
2200:
2201: /* STB - Store Byte */
2202: DECLARE_INSN(STB)
2203: {
2204: int rs = bits(insn,21,25);
2205: int ra = bits(insn,16,20);
2206: m_uint16_t offset = bits(insn,0,15);
2207:
2208: //ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,0);
2209: ppc32_emit_memop_fast(b,1,PPC_MEMOP_STB,ra,offset,rs,ppc32_memop_fast_stb);
2210: return(0);
2211: }
2212:
2213: /* STBU - Store Byte with Update */
2214: DECLARE_INSN(STBU)
2215: {
2216: int rs = bits(insn,21,25);
2217: int ra = bits(insn,16,20);
2218: m_uint16_t offset = bits(insn,0,15);
2219:
2220: ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,1);
2221: return(0);
2222: }
2223:
2224: /* STBUX - Store Byte with Update Indexed */
2225: DECLARE_INSN(STBUX)
2226: {
2227: int rs = bits(insn,21,25);
2228: int ra = bits(insn,16,20);
2229: int rb = bits(insn,11,15);
2230:
2231: ppc32_emit_memop_idx(b,PPC_MEMOP_STB,ra,rb,rs,1);
2232: return(0);
2233: }
2234:
2235: /* STBUX - Store Byte Indexed */
2236: DECLARE_INSN(STBX)
2237: {
2238: int rs = bits(insn,21,25);
2239: int ra = bits(insn,16,20);
2240: int rb = bits(insn,11,15);
2241:
2242: ppc32_emit_memop_idx(b,PPC_MEMOP_STB,ra,rb,rs,0);
2243: return(0);
2244: }
2245:
2246: /* STH - Store Half-Word */
2247: DECLARE_INSN(STH)
2248: {
2249: int rs = bits(insn,21,25);
2250: int ra = bits(insn,16,20);
2251: m_uint16_t offset = bits(insn,0,15);
2252:
2253: ppc32_emit_memop(b,PPC_MEMOP_STH,ra,offset,rs,0);
2254: return(0);
2255: }
2256:
2257: /* STHU - Store Half-Word with Update */
2258: DECLARE_INSN(STHU)
2259: {
2260: int rs = bits(insn,21,25);
2261: int ra = bits(insn,16,20);
2262: m_uint16_t offset = bits(insn,0,15);
2263:
2264: ppc32_emit_memop(b,PPC_MEMOP_STH,ra,offset,rs,1);
2265: return(0);
2266: }
2267:
2268: /* STHUX - Store Half-Word with Update Indexed */
2269: DECLARE_INSN(STHUX)
2270: {
2271: int rs = bits(insn,21,25);
2272: int ra = bits(insn,16,20);
2273: int rb = bits(insn,11,15);
2274:
2275: ppc32_emit_memop_idx(b,PPC_MEMOP_STH,ra,rb,rs,1);
2276: return(0);
2277: }
2278:
2279: /* STHUX - Store Half-Word Indexed */
2280: DECLARE_INSN(STHX)
2281: {
2282: int rs = bits(insn,21,25);
2283: int ra = bits(insn,16,20);
2284: int rb = bits(insn,11,15);
2285:
2286: ppc32_emit_memop_idx(b,PPC_MEMOP_STH,ra,rb,rs,0);
2287: return(0);
2288: }
2289:
2290: /* STW - Store Word */
2291: DECLARE_INSN(STW)
2292: {
2293: int rs = bits(insn,21,25);
2294: int ra = bits(insn,16,20);
2295: m_uint16_t offset = bits(insn,0,15);
2296:
2297: //ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,0);
2298: ppc32_emit_memop_fast(b,1,PPC_MEMOP_STW,ra,offset,rs,ppc32_memop_fast_stw);
2299: return(0);
2300: }
2301:
2302: /* STWU - Store Word with Update */
2303: DECLARE_INSN(STWU)
2304: {
2305: int rs = bits(insn,21,25);
2306: int ra = bits(insn,16,20);
2307: m_uint16_t offset = bits(insn,0,15);
2308:
2309: ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,1);
2310: return(0);
2311: }
2312:
2313: /* STWUX - Store Word with Update Indexed */
2314: DECLARE_INSN(STWUX)
2315: {
2316: int rs = bits(insn,21,25);
2317: int ra = bits(insn,16,20);
2318: int rb = bits(insn,11,15);
2319:
2320: ppc32_emit_memop_idx(b,PPC_MEMOP_STW,ra,rb,rs,1);
2321: return(0);
2322: }
2323:
2324: /* STWUX - Store Word Indexed */
2325: DECLARE_INSN(STWX)
2326: {
2327: int rs = bits(insn,21,25);
2328: int ra = bits(insn,16,20);
2329: int rb = bits(insn,11,15);
2330:
2331: ppc32_emit_memop_idx(b,PPC_MEMOP_STW,ra,rb,rs,0);
2332: return(0);
2333: }
2334:
2335: /* SUBF - Subtract From */
2336: DECLARE_INSN(SUBF)
2337: {
2338: int rd = bits(insn,21,25);
2339: int ra = bits(insn,16,20);
2340: int rb = bits(insn,11,15);
2341:
2342: /* $rd = $rb - $rb */
2343: ppc32_load_gpr(b,X86_EBX,rb);
2344: ppc32_alu_gpr(b,X86_SUB,X86_EBX,ra);
2345: ppc32_store_gpr(b,rd,X86_EBX);
2346:
2347: if (insn & 1)
2348: ppc32_update_cr0(b);
2349:
2350: return(0);
2351: }
2352:
2353: /* SUBFC - Subtract From Carrying */
2354: DECLARE_INSN(SUBFC)
2355: {
2356: int rd = bits(insn,21,25);
2357: int ra = bits(insn,16,20);
2358: int rb = bits(insn,11,15);
2359:
2360: /* ~$ra + 1 */
2361: ppc32_load_gpr(b,X86_ESI,ra);
2362: x86_not_reg(b->jit_ptr,X86_ESI);
2363: x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESI,1);
2364: x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
2365:
2366: /* add $rb */
2367: ppc32_alu_gpr(b,X86_ADD,X86_ESI,rb);
2368: x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
2369:
2370: ppc32_store_gpr(b,rd,X86_ESI);
2371:
2372: /* store the carry flag */
2373: x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
2374: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
2375:
2376: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
2377:
2378: /* update cr0 */
2379: if (insn & 1) {
2380: x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
2381: ppc32_update_cr0(b);
2382: }
2383:
2384: return(0);
2385: }
2386:
2387: /* SUBFE - Subtract From Extended */
2388: DECLARE_INSN(SUBFE)
2389: {
2390: int rd = bits(insn,21,25);
2391: int ra = bits(insn,16,20);
2392: int rb = bits(insn,11,15);
2393:
2394: /* ~$ra + carry */
2395: ppc32_load_gpr(b,X86_ESI,ra);
2396: x86_not_reg(b->jit_ptr,X86_ESI);
2397: x86_alu_reg_membase(b->jit_ptr,X86_ADD,X86_ESI,
2398: X86_EDI,OFFSET(cpu_ppc_t,xer_ca));
2399: x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
2400:
2401: /* add $rb */
2402: ppc32_alu_gpr(b,X86_ADD,X86_ESI,rb);
2403: x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
2404:
2405: ppc32_store_gpr(b,rd,X86_ESI);
2406:
2407: /* store the carry flag */
2408: x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
2409: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
2410: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
2411:
2412: /* update cr0 */
2413: if (insn & 1) {
2414: x86_test_reg_reg(b->jit_ptr,X86_ESI,X86_ESI);
2415: ppc32_update_cr0(b);
2416: }
2417:
2418: return(0);
2419: }
2420:
2421: /* SUBFIC - Subtract From Immediate Carrying */
2422: DECLARE_INSN(SUBFIC)
2423: {
2424: int rd = bits(insn,21,25);
2425: int ra = bits(insn,16,20);
2426: m_uint16_t imm = bits(insn,0,15);
2427: m_uint32_t tmp = sign_extend_32(imm,16);
2428:
2429: /* ~$ra + 1 */
2430: ppc32_load_gpr(b,X86_ESI,ra);
2431: x86_not_reg(b->jit_ptr,X86_ESI);
2432: x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESI,1);
2433: x86_set_reg(b->jit_ptr,X86_CC_C,X86_EAX,FALSE);
2434:
2435: /* add sign-extended $immediate */
2436: x86_alu_reg_imm(b->jit_ptr,X86_ADD,X86_ESI,tmp);
2437: x86_set_reg(b->jit_ptr,X86_CC_C,X86_ECX,FALSE);
2438:
2439: ppc32_store_gpr(b,rd,X86_ESI);
2440:
2441: /* store the carry flag */
2442: x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX);
2443: x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x1);
2444:
2445: x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,xer_ca),X86_EAX,4);
2446: return(0);
2447: }
2448:
2449: /* SYNC - Synchronize */
2450: DECLARE_INSN(SYNC)
2451: {
2452: return(0);
2453: }
2454:
2455: /* XOR */
2456: DECLARE_INSN(XOR)
2457: {
2458: int rs = bits(insn,21,25);
2459: int ra = bits(insn,16,20);
2460: int rb = bits(insn,11,15);
2461:
2462: ppc32_load_gpr(b,X86_EBX,rs);
2463: ppc32_alu_gpr(b,X86_XOR,X86_EBX,rb);
2464: ppc32_store_gpr(b,ra,X86_EBX);
2465:
2466: if (insn & 1)
2467: ppc32_update_cr0(b);
2468:
2469: return(0);
2470: }
2471:
2472: /* XORI - XOR Immediate */
2473: DECLARE_INSN(XORI)
2474: {
2475: int rs = bits(insn,21,25);
2476: int ra = bits(insn,16,20);
2477: m_uint32_t imm = bits(insn,0,15);
2478:
2479: ppc32_load_imm(b,X86_EBX,imm);
2480: ppc32_alu_gpr(b,X86_XOR,X86_EBX,rs);
2481: ppc32_store_gpr(b,ra,X86_EBX);
2482: return(0);
2483: }
2484:
2485: /* XORIS - XOR Immediate Shifted */
2486: DECLARE_INSN(XORIS)
2487: {
2488: int rs = bits(insn,21,25);
2489: int ra = bits(insn,16,20);
2490: m_uint32_t imm = bits(insn,0,15);
2491:
2492: ppc32_load_imm(b,X86_EBX,imm << 16);
2493: ppc32_alu_gpr(b,X86_XOR,X86_EBX,rs);
2494: ppc32_store_gpr(b,ra,X86_EBX);
2495: return(0);
2496: }
2497:
2498: /* PPC instruction array */
2499: struct ppc32_insn_tag ppc32_insn_tags[] = {
2500: { ppc32_emit_BLR , 0xfffffffe , 0x4e800020 },
2501: { ppc32_emit_BCTR , 0xfffffffe , 0x4e800420 },
2502: { ppc32_emit_MFLR , 0xfc1fffff , 0x7c0802a6 },
2503: { ppc32_emit_MTLR , 0xfc1fffff , 0x7c0803a6 },
2504: { ppc32_emit_MFCTR , 0xfc1fffff , 0x7c0902a6 },
2505: { ppc32_emit_MTCTR , 0xfc1fffff , 0x7c0903a6 },
2506: { ppc32_emit_MFTBL , 0xfc1ff7ff , 0x7c0c42e6 },
2507: { ppc32_emit_MFTBU , 0xfc1ff7ff , 0x7c0d42e6 },
2508: { ppc32_emit_ADD , 0xfc0007fe , 0x7c000214 },
2509: { ppc32_emit_ADDC , 0xfc0007fe , 0x7c000014 },
2510: { ppc32_emit_ADDE , 0xfc0007fe , 0x7c000114 },
2511: { ppc32_emit_ADDI , 0xfc000000 , 0x38000000 },
2512: { ppc32_emit_ADDIC , 0xfc000000 , 0x30000000 },
2513: { ppc32_emit_ADDIC_dot , 0xfc000000 , 0x34000000 },
2514: { ppc32_emit_ADDIS , 0xfc000000 , 0x3c000000 },
2515: { ppc32_emit_AND , 0xfc0007fe , 0x7c000038 },
2516: { ppc32_emit_ANDC , 0xfc0007fe , 0x7c000078 },
2517: { ppc32_emit_ANDI , 0xfc000000 , 0x70000000 },
2518: { ppc32_emit_ANDIS , 0xfc000000 , 0x74000000 },
2519: { ppc32_emit_B , 0xfc000003 , 0x48000000 },
2520: { ppc32_emit_BA , 0xfc000003 , 0x48000002 },
2521: { ppc32_emit_BL , 0xfc000003 , 0x48000001 },
2522: { ppc32_emit_BLA , 0xfc000003 , 0x48000003 },
2523: { ppc32_emit_BCC , 0xfe800000 , 0x40800000 },
2524: { ppc32_emit_BC , 0xfc000000 , 0x40000000 },
2525: { ppc32_emit_BCLR , 0xfc00fffe , 0x4c000020 },
2526: { ppc32_emit_CMP , 0xfc6007ff , 0x7c000000 },
2527: { ppc32_emit_CMPI , 0xfc600000 , 0x2c000000 },
2528: { ppc32_emit_CMPL , 0xfc6007ff , 0x7c000040 },
2529: { ppc32_emit_CMPLI , 0xfc600000 , 0x28000000 },
2530: { ppc32_emit_CRAND , 0xfc0007ff , 0x4c000202 },
2531: { ppc32_emit_CRANDC , 0xfc0007ff , 0x4c000102 },
2532: { ppc32_emit_CREQV , 0xfc0007ff , 0x4c000242 },
2533: { ppc32_emit_CRNAND , 0xfc0007ff , 0x4c0001c2 },
2534: { ppc32_emit_CRNOR , 0xfc0007ff , 0x4c000042 },
2535: { ppc32_emit_CROR , 0xfc0007ff , 0x4c000382 },
2536: { ppc32_emit_CRORC , 0xfc0007ff , 0x4c000342 },
2537: { ppc32_emit_CRXOR , 0xfc0007ff , 0x4c000182 },
2538: { ppc32_emit_DIVWU , 0xfc0007fe , 0x7c000396 },
2539: { ppc32_emit_EQV , 0xfc0007fe , 0x7c000238 },
2540: { ppc32_emit_EXTSB , 0xfc00fffe , 0x7c000774 },
2541: { ppc32_emit_EXTSH , 0xfc00fffe , 0x7c000734 },
2542: { ppc32_emit_LBZ , 0xfc000000 , 0x88000000 },
2543: { ppc32_emit_LBZU , 0xfc000000 , 0x8c000000 },
2544: { ppc32_emit_LBZUX , 0xfc0007ff , 0x7c0000ee },
2545: { ppc32_emit_LBZX , 0xfc0007ff , 0x7c0000ae },
2546: { ppc32_emit_LHA , 0xfc000000 , 0xa8000000 },
2547: { ppc32_emit_LHAU , 0xfc000000 , 0xac000000 },
2548: { ppc32_emit_LHAUX , 0xfc0007ff , 0x7c0002ee },
2549: { ppc32_emit_LHAX , 0xfc0007ff , 0x7c0002ae },
2550: { ppc32_emit_LHZ , 0xfc000000 , 0xa0000000 },
2551: { ppc32_emit_LHZU , 0xfc000000 , 0xa4000000 },
2552: { ppc32_emit_LHZUX , 0xfc0007ff , 0x7c00026e },
2553: { ppc32_emit_LHZX , 0xfc0007ff , 0x7c00022e },
2554: { ppc32_emit_LWZ , 0xfc000000 , 0x80000000 },
2555: { ppc32_emit_LWZU , 0xfc000000 , 0x84000000 },
2556: { ppc32_emit_LWZUX , 0xfc0007ff , 0x7c00006e },
2557: { ppc32_emit_LWZX , 0xfc0007ff , 0x7c00002e },
2558: { ppc32_emit_MCRF , 0xfc63ffff , 0x4c000000 },
2559: { ppc32_emit_MFCR , 0xfc1fffff , 0x7c000026 },
2560: { ppc32_emit_MFMSR , 0xfc1fffff , 0x7c0000a6 },
2561: { ppc32_emit_MFSR , 0xfc10ffff , 0x7c0004a6 },
2562: { ppc32_emit_MTCRF , 0xfc100fff , 0x7c000120 },
2563: { ppc32_emit_MULHW , 0xfc0007fe , 0x7c000096 },
2564: { ppc32_emit_MULHWU , 0xfc0007fe , 0x7c000016 },
2565: { ppc32_emit_MULLI , 0xfc000000 , 0x1c000000 },
2566: { ppc32_emit_MULLW , 0xfc0007fe , 0x7c0001d6 },
2567: { ppc32_emit_NAND , 0xfc0007fe , 0x7c0003b8 },
2568: { ppc32_emit_NEG , 0xfc00fffe , 0x7c0000d0 },
2569: { ppc32_emit_NOR , 0xfc0007fe , 0x7c0000f8 },
2570: { ppc32_emit_OR , 0xfc0007fe , 0x7c000378 },
2571: { ppc32_emit_ORC , 0xfc0007fe , 0x7c000338 },
2572: { ppc32_emit_ORI , 0xfc000000 , 0x60000000 },
2573: { ppc32_emit_ORIS , 0xfc000000 , 0x64000000 },
2574: { ppc32_emit_RLWIMI , 0xfc000000 , 0x50000000 },
2575: { ppc32_emit_RLWINM , 0xfc000000 , 0x54000000 },
2576: { ppc32_emit_RLWNM , 0xfc000000 , 0x5c000000 },
2577: { ppc32_emit_SLW , 0xfc0007fe , 0x7c000030 },
2578: { ppc32_emit_SRAWI , 0xfc0007fe , 0x7c000670 },
2579: { ppc32_emit_SRW , 0xfc0007fe , 0x7c000430 },
2580: { ppc32_emit_STB , 0xfc000000 , 0x98000000 },
2581: { ppc32_emit_STBU , 0xfc000000 , 0x9c000000 },
2582: { ppc32_emit_STBUX , 0xfc0007ff , 0x7c0001ee },
2583: { ppc32_emit_STBX , 0xfc0007ff , 0x7c0001ae },
2584: { ppc32_emit_STH , 0xfc000000 , 0xb0000000 },
2585: { ppc32_emit_STHU , 0xfc000000 , 0xb4000000 },
2586: { ppc32_emit_STHUX , 0xfc0007ff , 0x7c00036e },
2587: { ppc32_emit_STHX , 0xfc0007ff , 0x7c00032e },
2588: { ppc32_emit_STW , 0xfc000000 , 0x90000000 },
2589: { ppc32_emit_STWU , 0xfc000000 , 0x94000000 },
2590: { ppc32_emit_STWUX , 0xfc0007ff , 0x7c00016e },
2591: { ppc32_emit_STWX , 0xfc0007ff , 0x7c00012e },
2592: { ppc32_emit_SUBF , 0xfc0007fe , 0x7c000050 },
2593: { ppc32_emit_SUBFC , 0xfc0007fe , 0x7c000010 },
2594: { ppc32_emit_SUBFE , 0xfc0007fe , 0x7c000110 },
2595: { ppc32_emit_SUBFIC , 0xfc000000 , 0x20000000 },
2596: { ppc32_emit_SYNC , 0xffffffff , 0x7c0004ac },
2597: { ppc32_emit_XOR , 0xfc0007fe , 0x7c000278 },
2598: { ppc32_emit_XORI , 0xfc000000 , 0x68000000 },
2599: { ppc32_emit_XORIS , 0xfc000000 , 0x6c000000 },
2600: { ppc32_emit_unknown , 0x00000000 , 0x00000000 },
1.1.1.2 ! root 2601: { NULL , 0x00000000 , 0x00000000 },
1.1 root 2602: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.