/[dynamips]/upstream/dynamips-0.2.7-RC2/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-RC2/ppc32_x86_trans.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Sat Oct 6 16:24:54 2007 UTC (12 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 71864 byte(s)
dynamips-0.2.7-RC2

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

  ViewVC Help
Powered by ViewVC 1.1.26