/[dynamips]/upstream/dynamips-0.2.7-RC1/ppc32_x86_trans.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.7-RC1/ppc32_x86_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 63543 byte(s)
dynamips-0.2.7-RC1

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
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 };

  ViewVC Help
Powered by ViewVC 1.1.26