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