|
|
1.1 root 1: /*
2: * Cisco router simulation platform.
3: * Copyright (c) 2005,2006 Christophe Fillot ([email protected])
4: */
5:
6: #include <stdio.h>
7: #include <stdlib.h>
8: #include <unistd.h>
9: #include <string.h>
10: #include <sys/types.h>
11: #include <sys/stat.h>
12: #include <sys/mman.h>
13: #include <fcntl.h>
14:
15: #include "cpu.h"
1.1.1.3 root 16: #include "jit_op.h"
1.1 root 17: #include "ppc32_jit.h"
18: #include "ppc32_amd64_trans.h"
19: #include "memory.h"
20:
21: /* Macros for CPU structure access */
22: #define REG_OFFSET(reg) (OFFSET(cpu_ppc_t,gpr[(reg)]))
23: #define MEMOP_OFFSET(op) (OFFSET(cpu_ppc_t,mem_op_fn[(op)]))
24:
25: #define DECLARE_INSN(name) \
26: static int ppc32_emit_##name(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, \
27: ppc_insn_t insn)
28:
1.1.1.2 root 29: /* EFLAGS to Condition Register (CR) field - signed */
1.1.1.5 root 30: static m_uint32_t eflags_to_cr_signed[64] = {
31: 0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 0x08, 0x02,
32: 0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 0x08, 0x02,
33: 0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 0x08, 0x02,
34: 0x04, 0x02, 0x08, 0x02, 0x04, 0x02, 0x08, 0x02,
35: 0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 0x04, 0x02,
36: 0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 0x04, 0x02,
37: 0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 0x04, 0x02,
38: 0x08, 0x02, 0x04, 0x02, 0x08, 0x02, 0x04, 0x02,
1.1.1.2 root 39: };
40:
41: /* EFLAGS to Condition Register (CR) field - unsigned */
42: static m_uint32_t eflags_to_cr_unsigned[256] = {
1.1.1.5 root 43: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
44: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
45: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
46: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
47: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
48: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
49: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
50: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
51: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
52: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
53: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
54: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
55: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
56: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
57: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
58: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
59: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
60: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
61: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
62: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
63: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
64: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
65: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
66: 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08,
67: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
68: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
69: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
70: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
71: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
72: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
73: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
74: 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08,
1.1.1.2 root 75: };
76:
1.1 root 77: /* Load a 32 bit immediate value */
1.1.1.3 root 78: static inline void ppc32_load_imm(u_char **ptr,u_int reg,m_uint32_t val)
1.1 root 79: {
80: if (val)
1.1.1.3 root 81: amd64_mov_reg_imm_size(*ptr,reg,val,4);
1.1 root 82: else
1.1.1.3 root 83: amd64_alu_reg_reg_size(*ptr,X86_XOR,reg,reg,4);
1.1 root 84: }
85:
86: /* Set the Instruction Address (IA) register */
1.1.1.3 root 87: void ppc32_set_ia(u_char **ptr,m_uint32_t new_ia)
1.1 root 88: {
1.1.1.3 root 89: amd64_mov_membase_imm(*ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia),new_ia,4);
1.1 root 90: }
91:
92: /* Set the Link Register (LR) */
1.1.1.3 root 93: static void ppc32_set_lr(jit_op_t *iop,m_uint32_t new_lr)
1.1 root 94: {
1.1.1.3 root 95: amd64_mov_membase_imm(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,lr),new_lr,4);
1.1 root 96: }
97:
1.1.1.2 root 98: /*
99: * Try to branch directly to the specified JIT block without returning to
100: * main loop.
101: */
1.1.1.3 root 102: static void ppc32_try_direct_far_jump(cpu_ppc_t *cpu,jit_op_t *iop,
1.1.1.2 root 103: m_uint32_t new_ia)
104: {
105: m_uint32_t new_page,ia_hash,ia_offset;
1.1.1.6 ! root 106: u_char *test1,*test2,*test3,*test4;
1.1.1.2 root 107:
1.1.1.3 root 108: /* Indicate that we throw %rbx, %rdx */
109: ppc32_op_emit_alter_host_reg(cpu,AMD64_RBX);
110: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
111: ppc32_op_emit_alter_host_reg(cpu,AMD64_RSI);
112:
1.1.1.2 root 113: new_page = new_ia & PPC32_MIN_PAGE_MASK;
114: ia_offset = (new_ia & PPC32_MIN_PAGE_IMASK) >> 2;
1.1.1.6 ! root 115: ia_hash = ppc32_jit_get_virt_hash(new_ia);
1.1.1.2 root 116:
117: /* Get JIT block info in %rdx */
1.1.1.3 root 118: amd64_mov_reg_membase(iop->ob_ptr,AMD64_RBX,
1.1.1.6 ! root 119: AMD64_R15,OFFSET(cpu_ppc_t,tcb_virt_hash),8);
1.1.1.3 root 120: amd64_mov_reg_membase(iop->ob_ptr,AMD64_RDX,
1.1.1.2 root 121: AMD64_RBX,ia_hash*sizeof(void *),8);
122:
123: /* no JIT block found ? */
1.1.1.3 root 124: amd64_test_reg_reg(iop->ob_ptr,AMD64_RDX,AMD64_RDX);
125: test1 = iop->ob_ptr;
126: amd64_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
1.1.1.2 root 127:
128: /* Check block IA */
1.1.1.3 root 129: ppc32_load_imm(&iop->ob_ptr,AMD64_RSI,new_page);
130: amd64_alu_reg_membase_size(iop->ob_ptr,X86_CMP,AMD64_RAX,AMD64_RDX,
1.1.1.2 root 131: OFFSET(ppc32_jit_tcb_t,start_ia),4);
1.1.1.3 root 132: test2 = iop->ob_ptr;
133: amd64_branch8(iop->ob_ptr, X86_CC_NE, 0, 1);
1.1.1.2 root 134:
135: /* Jump to the code */
1.1.1.3 root 136: amd64_mov_reg_membase(iop->ob_ptr,AMD64_RSI,
1.1.1.2 root 137: AMD64_RDX,OFFSET(ppc32_jit_tcb_t,jit_insn_ptr),8);
1.1.1.6 ! root 138:
! 139: amd64_test_reg_reg(iop->ob_ptr,AMD64_RSI,AMD64_RSI);
! 140: test3 = iop->ob_ptr;
! 141: amd64_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
! 142:
1.1.1.3 root 143: amd64_mov_reg_membase(iop->ob_ptr,AMD64_RBX,
1.1.1.2 root 144: AMD64_RSI,ia_offset * sizeof(void *),8);
145:
1.1.1.3 root 146: amd64_test_reg_reg(iop->ob_ptr,AMD64_RBX,AMD64_RBX);
1.1.1.6 ! root 147: test4 = iop->ob_ptr;
1.1.1.3 root 148: amd64_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
149: amd64_jump_reg(iop->ob_ptr,AMD64_RBX);
1.1.1.2 root 150:
151: /* Returns to caller... */
1.1.1.3 root 152: amd64_patch(test1,iop->ob_ptr);
153: amd64_patch(test2,iop->ob_ptr);
154: amd64_patch(test3,iop->ob_ptr);
1.1.1.6 ! root 155: amd64_patch(test4,iop->ob_ptr);
1.1.1.2 root 156:
1.1.1.3 root 157: ppc32_set_ia(&iop->ob_ptr,new_ia);
158: ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
1.1.1.2 root 159: }
160:
1.1 root 161: /* Set Jump */
1.1.1.3 root 162: static void ppc32_set_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,jit_op_t *iop,
1.1 root 163: m_uint32_t new_ia,int local_jump)
164: {
165: int return_to_caller = FALSE;
166: u_char *jump_ptr;
167:
168: #if 0
169: if (cpu->sym_trace && !local_jump)
170: return_to_caller = TRUE;
171: #endif
172:
173: if (!return_to_caller && ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr)) {
1.1.1.3 root 174: ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia);
175: amd64_jump32(iop->ob_ptr,0);
1.1.1.2 root 176: } else {
177: if (cpu->exec_blk_direct_jump) {
178: /* Block lookup optimization */
1.1.1.3 root 179: ppc32_try_direct_far_jump(cpu,iop,new_ia);
1.1.1.2 root 180: } else {
1.1.1.3 root 181: ppc32_set_ia(&iop->ob_ptr,new_ia);
182: ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
1.1.1.2 root 183: }
1.1 root 184: }
185: }
186:
1.1.1.3 root 187: /* Jump to the next page */
188: void ppc32_set_page_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b)
189: {
190: jit_op_t *iop,*op_list = NULL;
191:
192: cpu->gen->jit_op_current = &op_list;
193:
194: iop = ppc32_op_emit_insn_output(cpu,4,"set_page_jump");
195: ppc32_set_jump(cpu,b,iop,b->start_ia + PPC32_MIN_PAGE_SIZE,FALSE);
196: ppc32_op_insn_output(b,iop);
197:
198: jit_op_free_list(cpu->gen,op_list);
199: cpu->gen->jit_op_current = NULL;
200: }
201:
1.1 root 202: /* Load a GPR into the specified host register */
1.1.1.3 root 203: static forced_inline void ppc32_load_gpr(u_char **ptr,u_int host_reg,
1.1 root 204: u_int ppc_reg)
205: {
1.1.1.3 root 206: amd64_mov_reg_membase(*ptr,host_reg,AMD64_R15,REG_OFFSET(ppc_reg),4);
1.1 root 207: }
208:
209: /* Store contents for a host register into a GPR register */
1.1.1.3 root 210: static forced_inline void ppc32_store_gpr(u_char **ptr,u_int ppc_reg,
1.1 root 211: u_int host_reg)
212: {
1.1.1.3 root 213: amd64_mov_membase_reg(*ptr,AMD64_R15,REG_OFFSET(ppc_reg),host_reg,4);
1.1 root 214: }
215:
216: /* Apply an ALU operation on a GPR register and a host register */
1.1.1.3 root 217: static forced_inline void ppc32_alu_gpr(u_char **ptr,u_int op,
1.1 root 218: u_int host_reg,u_int ppc_reg)
219: {
1.1.1.3 root 220: amd64_alu_reg_membase_size(*ptr,op,host_reg,
1.1 root 221: AMD64_R15,REG_OFFSET(ppc_reg),4);
222: }
223:
224: /*
225: * Update CR from %eflags
1.1.1.2 root 226: * %rax, %rdx, %rsi are modified.
1.1 root 227: */
228: static void ppc32_update_cr(ppc32_jit_tcb_t *b,int field,int is_signed)
229: {
1.1.1.2 root 230: /* Get status bits from EFLAGS */
231: amd64_pushfd_size(b->jit_ptr,8);
232: amd64_pop_reg(b->jit_ptr,AMD64_RAX);
1.1 root 233:
1.1.1.5 root 234: if (!is_signed) {
235: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,0xFF);
1.1.1.2 root 236: amd64_mov_reg_imm_size(b->jit_ptr,AMD64_RDX,eflags_to_cr_unsigned,8);
1.1.1.5 root 237: } else {
238: amd64_shift_reg_imm(b->jit_ptr,X86_SHR,AMD64_RAX,6);
239: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RAX,0x3F);
240: amd64_mov_reg_imm_size(b->jit_ptr,AMD64_RDX,eflags_to_cr_signed,8);
241: }
1.1 root 242:
1.1.1.2 root 243: amd64_mov_reg_memindex(b->jit_ptr,AMD64_RAX,AMD64_RDX,0,AMD64_RAX,2,4);
1.1 root 244:
1.1.1.2 root 245: #if 0
1.1 root 246: /* Check XER Summary of Overflow and report it */
247: amd64_mov_reg_membase(b->jit_ptr,AMD64_RCX,
248: AMD64_R15,OFFSET(cpu_ppc_t,xer),4);
249: amd64_alu_reg_imm(b->jit_ptr,X86_AND,AMD64_RCX,PPC32_XER_SO);
250: amd64_shift_reg_imm(b->jit_ptr,X86_SHR,AMD64_RCX,(field << 2) + 3);
251: amd64_alu_reg_reg(b->jit_ptr,X86_OR,AMD64_RDX,AMD64_RCX);
1.1.1.2 root 252: #endif
1.1 root 253:
1.1.1.2 root 254: /* Store modified CR field */
255: amd64_mov_membase_reg(b->jit_ptr,AMD64_R15,PPC32_CR_FIELD_OFFSET(field),
256: AMD64_RAX,4);
1.1 root 257: }
258:
259: /*
260: * Update CR0 from %eflags
261: * %eax, %ecx, %edx, %esi are modified.
262: */
263: static void ppc32_update_cr0(ppc32_jit_tcb_t *b)
264: {
265: ppc32_update_cr(b,0,TRUE);
266: }
267:
1.1.1.3 root 268: /* Indicate registers modified by ppc32_update_cr() functions */
269: void ppc32_update_cr_set_altered_hreg(cpu_ppc_t *cpu)
270: {
271: ppc32_op_emit_alter_host_reg(cpu,AMD64_RAX);
272: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
273: }
274:
1.1 root 275: /* Basic C call */
1.1.1.3 root 276: static forced_inline void ppc32_emit_basic_c_call(u_char **ptr,void *f)
1.1 root 277: {
1.1.1.3 root 278: amd64_mov_reg_imm(*ptr,AMD64_RBX,f);
279: amd64_call_reg(*ptr,AMD64_RBX);
1.1 root 280: }
281:
282: /* Emit a simple call to a C function without any parameter */
1.1.1.3 root 283: static void ppc32_emit_c_call(ppc32_jit_tcb_t *b,jit_op_t *iop,void *f)
1.1 root 284: {
1.1.1.3 root 285: ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
286: ppc32_emit_basic_c_call(&iop->ob_ptr,f);
287: }
288:
289: /* ======================================================================== */
290:
291: /* Initialize register mapping */
292: void ppc32_jit_init_hreg_mapping(cpu_ppc_t *cpu)
293: {
294: int avail_hregs[] = { AMD64_RSI, AMD64_RAX, AMD64_RCX, AMD64_RDX,
295: AMD64_R13, AMD64_R14, AMD64_RDI, -1 };
296: struct hreg_map *map;
297: int i,hreg;
298:
299: cpu->hreg_map_list = cpu->hreg_lru = NULL;
300:
301: /* Add the available registers to the map list */
302: for(i=0;avail_hregs[i]!=-1;i++) {
303: hreg = avail_hregs[i];
304: map = &cpu->hreg_map[hreg];
305:
306: /* Initialize mapping. At the beginning, no PPC reg is mapped */
307: map->flags = 0;
308: map->hreg = hreg;
309: map->vreg = -1;
310: ppc32_jit_insert_hreg_mru(cpu,map);
311: }
312:
313: /* Clear PPC registers mapping */
314: for(i=0;i<PPC32_GPR_NR;i++)
315: cpu->ppc_reg_map[i] = -1;
316: }
317:
318: /* Allocate a specific temp register */
319: static int ppc32_jit_get_tmp_hreg(cpu_ppc_t *cpu)
320: {
321: return(AMD64_RBX);
322: }
323:
324: /* ======================================================================== */
325: /* JIT operations (specific to target CPU). */
326: /* ======================================================================== */
327:
328: /* INSN_OUTPUT */
329: void ppc32_op_insn_output(ppc32_jit_tcb_t *b,jit_op_t *op)
330: {
331: op->ob_final = b->jit_ptr;
332: memcpy(b->jit_ptr,op->ob_data,op->ob_ptr - op->ob_data);
333: b->jit_ptr += op->ob_ptr - op->ob_data;
334: }
335:
336: /* LOAD_GPR: p[0] = %host_reg, p[1] = %ppc_reg */
337: void ppc32_op_load_gpr(ppc32_jit_tcb_t *b,jit_op_t *op)
338: {
339: if (op->param[0] != JIT_OP_INV_REG)
340: ppc32_load_gpr(&b->jit_ptr,op->param[0],op->param[1]);
341: }
342:
343: /* STORE_GPR: p[0] = %host_reg, p[1] = %ppc_reg */
344: void ppc32_op_store_gpr(ppc32_jit_tcb_t *b,jit_op_t *op)
345: {
346: if (op->param[0] != JIT_OP_INV_REG)
347: ppc32_store_gpr(&b->jit_ptr,op->param[1],op->param[0]);
348: }
349:
350: /* UPDATE_FLAGS: p[0] = cr_field, p[1] = is_signed */
351: void ppc32_op_update_flags(ppc32_jit_tcb_t *b,jit_op_t *op)
352: {
353: if (op->param[0] != JIT_OP_INV_REG)
354: ppc32_update_cr(b,op->param[0],op->param[1]);
1.1 root 355: }
356:
1.1.1.3 root 357: /* MOVE_HOST_REG: p[0] = %host_dst_reg, p[1] = %host_src_reg */
358: void ppc32_op_move_host_reg(ppc32_jit_tcb_t *b,jit_op_t *op)
359: {
360: if ((op->param[0] != JIT_OP_INV_REG) && (op->param[1] != JIT_OP_INV_REG))
361: amd64_mov_reg_reg(b->jit_ptr,op->param[0],op->param[1],4);
362: }
363:
364: /* SET_HOST_REG_IMM32: p[0] = %host_reg, p[1] = imm32 */
365: void ppc32_op_set_host_reg_imm32(ppc32_jit_tcb_t *b,jit_op_t *op)
366: {
367: if (op->param[0] != JIT_OP_INV_REG)
368: ppc32_load_imm(&b->jit_ptr,op->param[0],op->param[1]);
369: }
370:
371: /* ======================================================================== */
372:
1.1 root 373: /* Memory operation */
1.1.1.3 root 374: static void ppc32_emit_memop(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
375: int op,int base,int offset,int target,int update)
1.1 root 376: {
377: m_uint32_t val = sign_extend(offset,16);
1.1.1.3 root 378: jit_op_t *iop;
379:
380: /*
381: * Since an exception can be triggered, clear JIT state. This allows
382: * to use branch target tag (we can directly branch on this instruction).
383: */
384: ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);
385: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
386:
387: iop = ppc32_op_emit_insn_output(cpu,5,"memop");
1.1 root 388:
389: /* Save PC for exception handling */
1.1.1.3 root 390: ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
1.1 root 391:
392: /* RSI = sign-extended offset */
1.1.1.3 root 393: ppc32_load_imm(&iop->ob_ptr,AMD64_RSI,val);
1.1 root 394:
395: /* RSI = GPR[base] + sign-extended offset */
396: if (update || (base != 0))
1.1.1.3 root 397: ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,AMD64_RSI,base);
1.1 root 398:
399: if (update)
1.1.1.3 root 400: amd64_mov_reg_reg(iop->ob_ptr,AMD64_R14,AMD64_RSI,4);
1.1 root 401:
402: /* RDX = target register */
1.1.1.3 root 403: amd64_mov_reg_imm(iop->ob_ptr,AMD64_RDX,target);
1.1 root 404:
405: /* RDI = CPU instance pointer */
1.1.1.3 root 406: amd64_mov_reg_reg(iop->ob_ptr,AMD64_RDI,AMD64_R15,8);
1.1 root 407:
408: /* Call memory function */
1.1.1.6 ! root 409: amd64_alu_reg_imm(iop->ob_ptr,X86_SUB,AMD64_RSP,8);
1.1.1.3 root 410: amd64_call_membase(iop->ob_ptr,AMD64_R15,MEMOP_OFFSET(op));
1.1.1.6 ! root 411: amd64_alu_reg_imm(iop->ob_ptr,X86_ADD,AMD64_RSP,8);
1.1 root 412:
413: if (update)
1.1.1.3 root 414: ppc32_store_gpr(&iop->ob_ptr,base,AMD64_R14);
1.1 root 415: }
416:
417: /* Memory operation (indexed) */
1.1.1.3 root 418: static void ppc32_emit_memop_idx(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
419: int op,int ra,int rb,int target,int update)
1.1 root 420: {
1.1.1.3 root 421: jit_op_t *iop;
422:
423: /*
424: * Since an exception can be triggered, clear JIT state. This allows
425: * to use branch target tag (we can directly branch on this instruction).
426: */
427: ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);
428: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
429:
430: iop = ppc32_op_emit_insn_output(cpu,5,"memop_idx");
1.1 root 431:
432: /* Save PC for exception handling */
1.1.1.3 root 433: ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
1.1 root 434:
435: /* RSI = $rb */
1.1.1.3 root 436: ppc32_load_gpr(&iop->ob_ptr,AMD64_RSI,rb);
1.1 root 437:
438: /* RSI = GPR[base] + sign-extended offset */
439: if (update || (ra != 0))
1.1.1.3 root 440: ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,AMD64_RSI,ra);
1.1 root 441:
442: if (update)
1.1.1.3 root 443: amd64_mov_reg_reg(iop->ob_ptr,AMD64_R14,AMD64_RSI,4);
1.1 root 444:
445: /* RDX = target register */
1.1.1.3 root 446: amd64_mov_reg_imm(iop->ob_ptr,AMD64_RDX,target);
1.1 root 447:
448: /* RDI = CPU instance pointer */
1.1.1.3 root 449: amd64_mov_reg_reg(iop->ob_ptr,AMD64_RDI,AMD64_R15,8);
1.1 root 450:
451: /* Call memory function */
1.1.1.6 ! root 452: amd64_alu_reg_imm(iop->ob_ptr,X86_SUB,AMD64_RSP,8);
1.1.1.3 root 453: amd64_call_membase(iop->ob_ptr,AMD64_R15,MEMOP_OFFSET(op));
1.1.1.6 ! root 454: amd64_alu_reg_imm(iop->ob_ptr,X86_ADD,AMD64_RSP,8);
1.1 root 455:
456: if (update)
1.1.1.3 root 457: ppc32_store_gpr(&iop->ob_ptr,ra,AMD64_R14);
1.1 root 458: }
459:
1.1.1.3 root 460: typedef void (*memop_fast_access)(jit_op_t *iop,int target);
1.1 root 461:
462: /* Fast LBZ */
1.1.1.3 root 463: static void ppc32_memop_fast_lbz(jit_op_t *iop,int target)
1.1 root 464: {
1.1.1.3 root 465: amd64_clear_reg(iop->ob_ptr,AMD64_RCX);
466: amd64_mov_reg_memindex(iop->ob_ptr,AMD64_RCX,AMD64_RBX,0,AMD64_RSI,0,1);
467: ppc32_store_gpr(&iop->ob_ptr,target,AMD64_RCX);
1.1 root 468: }
469:
470: /* Fast STB */
1.1.1.3 root 471: static void ppc32_memop_fast_stb(jit_op_t *iop,int target)
1.1 root 472: {
1.1.1.3 root 473: ppc32_load_gpr(&iop->ob_ptr,AMD64_RDX,target);
474: amd64_mov_memindex_reg(iop->ob_ptr,AMD64_RBX,0,AMD64_RSI,0,AMD64_RDX,1);
1.1 root 475: }
476:
477: /* Fast LWZ */
1.1.1.3 root 478: static void ppc32_memop_fast_lwz(jit_op_t *iop,int target)
1.1 root 479: {
1.1.1.3 root 480: amd64_mov_reg_memindex(iop->ob_ptr,AMD64_RAX,AMD64_RBX,0,AMD64_RSI,0,4);
481: amd64_bswap32(iop->ob_ptr,AMD64_RAX);
482: ppc32_store_gpr(&iop->ob_ptr,target,AMD64_RAX);
1.1 root 483: }
484:
485: /* Fast STW */
1.1.1.3 root 486: static void ppc32_memop_fast_stw(jit_op_t *iop,int target)
1.1 root 487: {
1.1.1.3 root 488: ppc32_load_gpr(&iop->ob_ptr,AMD64_RDX,target);
489: amd64_bswap32(iop->ob_ptr,AMD64_RDX);
490: amd64_mov_memindex_reg(iop->ob_ptr,AMD64_RBX,0,AMD64_RSI,0,AMD64_RDX,4);
1.1 root 491: }
492:
493: /* Fast memory operation */
1.1.1.3 root 494: static void ppc32_emit_memop_fast(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
495: int write_op,int opcode,
496: int base,int offset,int target,
1.1 root 497: memop_fast_access op_handler)
498: {
499: m_uint32_t val = sign_extend(offset,16);
1.1.1.4 root 500: u_char *test1,*test2,*p_exit;
1.1.1.3 root 501: jit_op_t *iop;
502:
503: /*
504: * Since an exception can be triggered, clear JIT state. This allows
505: * to use branch target tag (we can directly branch on this instruction).
506: */
507: ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_TARGET);
508: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
509:
510: iop = ppc32_op_emit_insn_output(cpu,5,"memop_fast");
1.1 root 511:
512: test2 = NULL;
513:
1.1.1.6 ! root 514: /* XXX */
! 515: amd64_inc_membase(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,mts_lookups));
! 516:
1.1 root 517: /* RSI = GPR[base] + sign-extended offset */
1.1.1.3 root 518: ppc32_load_imm(&iop->ob_ptr,AMD64_RSI,val);
1.1 root 519: if (base != 0)
1.1.1.3 root 520: ppc32_alu_gpr(&iop->ob_ptr,X86_ADD,AMD64_RSI,base);
1.1 root 521:
522: /* RBX = mts32_entry index */
1.1.1.3 root 523: amd64_mov_reg_reg_size(iop->ob_ptr,X86_EBX,X86_ESI,4);
1.1.1.6 ! root 524: amd64_mov_reg_reg_size(iop->ob_ptr,X86_EAX,X86_ESI,4);
! 525:
! 526: amd64_shift_reg_imm_size(iop->ob_ptr,X86_SHR,X86_EBX,MTS32_HASH_SHIFT1,4);
! 527: amd64_shift_reg_imm_size(iop->ob_ptr,X86_SHR,X86_EAX,MTS32_HASH_SHIFT2,4);
! 528: amd64_alu_reg_reg(iop->ob_ptr,X86_XOR,AMD64_RBX,AMD64_RAX);
! 529:
1.1.1.3 root 530: amd64_alu_reg_imm_size(iop->ob_ptr,X86_AND,X86_EBX,MTS32_HASH_MASK,4);
1.1 root 531:
532: /* RCX = mts32 entry */
1.1.1.3 root 533: amd64_mov_reg_membase(iop->ob_ptr,AMD64_RCX,
1.1 root 534: AMD64_R15,
535: OFFSET(cpu_ppc_t,mts_cache[PPC32_MTS_DCACHE]),8);
1.1.1.3 root 536: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,AMD64_RBX,5); /* TO FIX */
537: amd64_alu_reg_reg(iop->ob_ptr,X86_ADD,AMD64_RCX,AMD64_RBX);
1.1 root 538:
539: /* Compare virtual page address (EAX = vpage) */
1.1.1.3 root 540: amd64_mov_reg_reg(iop->ob_ptr,X86_EAX,X86_ESI,4);
541: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,X86_EAX,PPC32_MIN_PAGE_MASK);
1.1 root 542:
1.1.1.3 root 543: amd64_alu_reg_membase_size(iop->ob_ptr,X86_CMP,X86_EAX,AMD64_RCX,
1.1 root 544: OFFSET(mts32_entry_t,gvpa),4);
1.1.1.3 root 545: test1 = iop->ob_ptr;
546: amd64_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
1.1 root 547:
548: /* Test if we are writing to a COW page */
549: if (write_op) {
1.1.1.3 root 550: amd64_test_membase_imm_size(iop->ob_ptr,
1.1 root 551: AMD64_RCX,OFFSET(mts32_entry_t,flags),
1.1.1.2 root 552: MTS_FLAG_COW|MTS_FLAG_EXEC,4);
1.1.1.3 root 553: test2 = iop->ob_ptr;
554: amd64_branch8(iop->ob_ptr, X86_CC_NZ, 0, 1);
1.1 root 555: }
556:
557: /* ESI = offset in page, RBX = Host Page Address */
1.1.1.3 root 558: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,X86_ESI,PPC32_MIN_PAGE_IMASK);
559: amd64_mov_reg_membase(iop->ob_ptr,AMD64_RBX,
1.1 root 560: AMD64_RCX,OFFSET(mts32_entry_t,hpa),8);
561:
562: /* Memory access */
1.1.1.3 root 563: op_handler(iop,target);
1.1 root 564:
1.1.1.3 root 565: p_exit = iop->ob_ptr;
566: amd64_jump8(iop->ob_ptr,0);
1.1 root 567:
568: /* === Slow lookup === */
1.1.1.3 root 569: amd64_patch(test1,iop->ob_ptr);
1.1 root 570: if (test2)
1.1.1.3 root 571: amd64_patch(test2,iop->ob_ptr);
1.1 root 572:
573: /* Save IA for exception handling */
1.1.1.3 root 574: ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
1.1 root 575:
576: /* RDX = target register */
1.1.1.3 root 577: amd64_mov_reg_imm(iop->ob_ptr,AMD64_RDX,target);
1.1 root 578:
579: /* RDI = CPU instance */
1.1.1.3 root 580: amd64_mov_reg_reg(iop->ob_ptr,AMD64_RDI,AMD64_R15,8);
1.1 root 581:
582: /* Call memory access function */
1.1.1.6 ! root 583: amd64_alu_reg_imm(iop->ob_ptr,X86_SUB,AMD64_RSP,8);
1.1.1.3 root 584: amd64_call_membase(iop->ob_ptr,AMD64_R15,MEMOP_OFFSET(opcode));
1.1.1.6 ! root 585: amd64_alu_reg_imm(iop->ob_ptr,X86_ADD,AMD64_RSP,8);
1.1 root 586:
1.1.1.3 root 587: amd64_patch(p_exit,iop->ob_ptr);
1.1.1.2 root 588: }
589:
1.1 root 590: /* Emit unhandled instruction code */
591: static int ppc32_emit_unknown(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b,
592: ppc_insn_t opcode)
593: {
594: u_char *test1;
1.1.1.3 root 595: jit_op_t *iop;
1.1 root 596:
1.1.1.3 root 597: iop = ppc32_op_emit_insn_output(cpu,3,"unknown");
598:
599: /* Update IA */
600: ppc32_set_ia(&iop->ob_ptr,b->start_ia+(b->ppc_trans_pos << 2));
1.1 root 601:
602: /* Fallback to non-JIT mode */
1.1.1.3 root 603: amd64_mov_reg_reg(iop->ob_ptr,AMD64_RDI,AMD64_R15,8);
604: amd64_mov_reg_imm(iop->ob_ptr,AMD64_RSI,opcode);
605:
1.1.1.6 ! root 606: amd64_alu_reg_imm(iop->ob_ptr,X86_SUB,AMD64_RSP,8);
1.1.1.3 root 607: ppc32_emit_c_call(b,iop,ppc32_exec_single_insn_ext);
1.1.1.6 ! root 608: amd64_alu_reg_imm(iop->ob_ptr,X86_ADD,AMD64_RSP,8);
! 609:
1.1.1.3 root 610: amd64_test_reg_reg_size(iop->ob_ptr,AMD64_RAX,AMD64_RAX,4);
611: test1 = iop->ob_ptr;
612: amd64_branch8(iop->ob_ptr, X86_CC_Z, 0, 1);
613: ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
1.1 root 614:
1.1.1.3 root 615: amd64_patch(test1,iop->ob_ptr);
1.1 root 616:
1.1.1.3 root 617: /* Signal this as an EOB to reset JIT state */
618: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1.1 root 619: return(0);
620: }
621:
1.1.1.3 root 622: /* Virtual Breakpoint */
623: void ppc32_emit_breakpoint(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b)
624: {
625: jit_op_t *iop;
626:
627: iop = ppc32_op_emit_insn_output(cpu,2,"breakpoint");
628:
629: amd64_mov_reg_reg(iop->ob_ptr,AMD64_RDI,AMD64_R15,8);
1.1.1.6 ! root 630:
! 631: amd64_alu_reg_imm(iop->ob_ptr,X86_SUB,AMD64_RSP,8);
1.1.1.3 root 632: ppc32_emit_c_call(b,iop,ppc32_run_breakpoint);
1.1.1.6 ! root 633: amd64_alu_reg_imm(iop->ob_ptr,X86_ADD,AMD64_RSP,8);
1.1.1.3 root 634:
635: /* Signal this as an EOB to to reset JIT state */
636: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
637: }
638:
1.1 root 639: /* Increment the number of executed instructions (performance debugging) */
1.1.1.4 root 640: void ppc32_inc_perf_counter(cpu_ppc_t *cpu)
641: {
642: jit_op_t *iop;
643:
644: iop = ppc32_op_emit_insn_output(cpu,1,"perf_cnt");
645: amd64_inc_membase_size(iop->ob_ptr,
646: AMD64_R15,OFFSET(cpu_ppc_t,perf_counter),4);
1.1 root 647: }
648:
649: /* ======================================================================== */
650:
651: /* BLR - Branch to Link Register */
652: DECLARE_INSN(BLR)
653: {
1.1.1.3 root 654: jit_op_t *iop;
655: int hreg;
656:
657: ppc32_jit_start_hreg_seq(cpu,"blr");
658: hreg = ppc32_jit_alloc_hreg(cpu,-1);
659: ppc32_op_emit_alter_host_reg(cpu,hreg);
660:
661: iop = ppc32_op_emit_insn_output(cpu,2,"blr");
662:
663: amd64_mov_reg_membase(iop->ob_ptr,hreg,AMD64_R15,OFFSET(cpu_ppc_t,lr),4);
664: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia),hreg,4);
1.1 root 665:
666: /* set the return address */
667: if (insn & 1)
1.1.1.3 root 668: ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1.1 root 669:
1.1.1.3 root 670: ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
671: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
672: ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
673:
674: ppc32_jit_close_hreg_seq(cpu);
1.1 root 675: return(0);
676: }
677:
678: /* BCTR - Branch to Count Register */
679: DECLARE_INSN(BCTR)
680: {
1.1.1.3 root 681: jit_op_t *iop;
682: int hreg;
683:
684: ppc32_jit_start_hreg_seq(cpu,"bctr");
685: hreg = ppc32_jit_alloc_hreg(cpu,-1);
686: ppc32_op_emit_alter_host_reg(cpu,hreg);
687:
688: iop = ppc32_op_emit_insn_output(cpu,2,"bctr");
689:
690: amd64_mov_reg_membase(iop->ob_ptr,hreg,AMD64_R15,OFFSET(cpu_ppc_t,ctr),4);
691: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia),hreg,4);
1.1 root 692:
693: /* set the return address */
694: if (insn & 1)
1.1.1.4 root 695: ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1.1.1.3 root 696:
697: ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
698: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
699: ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1 root 700:
1.1.1.3 root 701: ppc32_jit_close_hreg_seq(cpu);
1.1 root 702: return(0);
703: }
704:
705: /* MFLR - Move From Link Register */
706: DECLARE_INSN(MFLR)
707: {
708: int rd = bits(insn,21,25);
1.1.1.3 root 709: int hreg_rd;
710: jit_op_t *iop;
711:
712: ppc32_jit_start_hreg_seq(cpu,"mflr");
713: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
714: iop = ppc32_op_emit_insn_output(cpu,1,"mflr");
715:
716: amd64_mov_reg_membase(iop->ob_ptr,hreg_rd,AMD64_R15,OFFSET(cpu_ppc_t,lr),4);
717: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
718:
719: ppc32_jit_close_hreg_seq(cpu);
1.1 root 720: return(0);
721: }
722:
723: /* MTLR - Move To Link Register */
724: DECLARE_INSN(MTLR)
725: {
726: int rs = bits(insn,21,25);
1.1.1.3 root 727: int hreg_rs;
728: jit_op_t *iop;
729:
730: ppc32_jit_start_hreg_seq(cpu,"mtlr");
731: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
732: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1.1 root 733:
1.1.1.3 root 734: iop = ppc32_op_emit_insn_output(cpu,1,"mtlr");
735: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,lr),hreg_rs,4);
1.1 root 736: return(0);
737: }
738:
739: /* MFCTR - Move From Counter Register */
740: DECLARE_INSN(MFCTR)
741: {
742: int rd = bits(insn,21,25);
1.1.1.3 root 743: int hreg_rd;
744: jit_op_t *iop;
1.1 root 745:
1.1.1.3 root 746: ppc32_jit_start_hreg_seq(cpu,"mfctr");
747: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
748:
749: iop = ppc32_op_emit_insn_output(cpu,1,"mfctr");
750:
751: amd64_mov_reg_membase(iop->ob_ptr,hreg_rd,
1.1 root 752: AMD64_R15,OFFSET(cpu_ppc_t,ctr),4);
1.1.1.3 root 753: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
754:
755: ppc32_jit_close_hreg_seq(cpu);
1.1 root 756: return(0);
757: }
758:
759: /* MTCTR - Move To Counter Register */
760: DECLARE_INSN(MTCTR)
761: {
762: int rs = bits(insn,21,25);
1.1.1.3 root 763: int hreg_rs;
764: jit_op_t *iop;
1.1 root 765:
1.1.1.3 root 766: ppc32_jit_start_hreg_seq(cpu,"mtctr");
767: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
768: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
769:
770: iop = ppc32_op_emit_insn_output(cpu,1,"mtctr");
771:
772: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ctr),
773: hreg_rs,4);
774:
775: ppc32_jit_close_hreg_seq(cpu);
1.1 root 776: return(0);
777: }
778:
779: /* MFTBU - Move from Time Base (Up) */
780: DECLARE_INSN(MFTBU)
781: {
782: int rd = bits(insn,21,25);
1.1.1.3 root 783: int hreg_rd;
784: jit_op_t *iop;
785:
786: ppc32_jit_start_hreg_seq(cpu,"mftbu");
787: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1 root 788:
1.1.1.3 root 789: iop = ppc32_op_emit_insn_output(cpu,1,"mftbu");
790:
791: amd64_mov_reg_membase(iop->ob_ptr,hreg_rd,
1.1 root 792: AMD64_R15,OFFSET(cpu_ppc_t,tb)+4,4);
1.1.1.3 root 793: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
794:
795: ppc32_jit_close_hreg_seq(cpu);
1.1 root 796: return(0);
797: }
798:
799: #define PPC32_TB_INCREMENT 50
800:
801: /* MFTBL - Move from Time Base (Lo) */
802: DECLARE_INSN(MFTBL)
803: {
804: int rd = bits(insn,21,25);
1.1.1.3 root 805: int hreg_rd;
806: jit_op_t *iop;
807:
808: ppc32_jit_start_hreg_seq(cpu,"mftbl");
809: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
810:
811: iop = ppc32_op_emit_insn_output(cpu,3,"mftbl");
1.1 root 812:
1.1.1.3 root 813: amd64_mov_reg_membase(iop->ob_ptr,hreg_rd,
1.1 root 814: AMD64_R15,OFFSET(cpu_ppc_t,tb),8);
1.1.1.3 root 815: amd64_alu_reg_imm(iop->ob_ptr,X86_ADD,hreg_rd,PPC32_TB_INCREMENT);
816: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,tb),
817: hreg_rd,8);
1.1 root 818:
1.1.1.3 root 819: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
820:
821: ppc32_jit_close_hreg_seq(cpu);
1.1 root 822: return(0);
823: }
824:
825: /* ADD */
826: DECLARE_INSN(ADD)
827: {
828: int rd = bits(insn,21,25);
829: int ra = bits(insn,16,20);
830: int rb = bits(insn,11,15);
1.1.1.3 root 831: int hreg_rd,hreg_ra,hreg_rb;
832: jit_op_t *iop;
1.1 root 833:
834: /* $rd = $ra + $rb */
1.1.1.3 root 835: ppc32_jit_start_hreg_seq(cpu,"add");
836: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
837: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
838: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
839:
840: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
841: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
842:
843: iop = ppc32_op_emit_insn_output(cpu,2,"add");
844:
845: if (rd == ra)
846: amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb,4);
847: else if (rd == rb)
848: amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_ra,4);
849: else {
850: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
851: amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb,4);
852: }
853:
854: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1 root 855:
856: if (insn & 1)
1.1.1.3 root 857: ppc32_op_emit_update_flags(cpu,0,TRUE);
858:
859: ppc32_jit_close_hreg_seq(cpu);
1.1 root 860: return(0);
861: }
862:
863: /* ADDC */
864: DECLARE_INSN(ADDC)
865: {
866: int rd = bits(insn,21,25);
867: int ra = bits(insn,16,20);
868: int rb = bits(insn,11,15);
1.1.1.3 root 869: int hreg_rd,hreg_ra,hreg_rb,hreg_t0;
870: jit_op_t *iop;
1.1 root 871:
872: /* $rd = $ra + $rb */
1.1.1.3 root 873: ppc32_jit_start_hreg_seq(cpu,"addc");
874: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
875: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
876: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1.1 root 877:
878: /* store the carry flag */
1.1.1.3 root 879: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
880:
881: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
882: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
883:
884: iop = ppc32_op_emit_insn_output(cpu,2,"addc");
885:
886: if (rd == ra)
887: amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb,4);
888: else if (rd == rb)
889: amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_ra,4);
890: else {
891: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
892: amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_rd,hreg_rb,4);
893: }
894:
895: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
896:
897: /* store the carry flag */
898: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t0,FALSE);
899: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x1);
900: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
901: hreg_t0,4);
1.1 root 902:
903: if (insn & 1) {
1.1.1.3 root 904: amd64_test_reg_reg_size(iop->ob_ptr,hreg_rd,hreg_rd,4);
905: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 906: }
1.1.1.3 root 907:
908: ppc32_jit_close_hreg_seq(cpu);
1.1 root 909: return(0);
910: }
911:
912: /* ADDE - Add Extended */
913: DECLARE_INSN(ADDE)
914: {
915: int rd = bits(insn,21,25);
916: int ra = bits(insn,16,20);
917: int rb = bits(insn,11,15);
1.1.1.3 root 918: int hreg_ra,hreg_rb,hreg_rd,hreg_t0,hreg_t1;
919: jit_op_t *iop;
1.1 root 920:
1.1.1.3 root 921: ppc32_jit_start_hreg_seq(cpu,"adde");
922: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
923: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
924: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1 root 925:
1.1.1.3 root 926: hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
927: hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
1.1 root 928:
1.1.1.3 root 929: ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
930: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
931: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1.1 root 932:
1.1.1.3 root 933: iop = ppc32_op_emit_insn_output(cpu,3,"adde");
1.1 root 934:
1.1.1.3 root 935: /* $t0 = $ra + carry */
936: amd64_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
937: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
938:
939: amd64_alu_reg_membase_size(iop->ob_ptr,X86_ADD,hreg_t0,
940: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),4);
941: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
942: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
943: hreg_t1,4);
944:
945: /* $t0 += $rb */
946: amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_t0,hreg_rb,4);
947: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
948: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
949: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
950: hreg_t1,4);
1.1 root 951:
952: /* update cr0 */
1.1.1.3 root 953: if (insn & 1)
954: amd64_test_reg_reg_size(iop->ob_ptr,hreg_t0,hreg_t0,4);
1.1 root 955:
1.1.1.3 root 956: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
957: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
958:
959: if (insn & 1)
960: ppc32_op_emit_update_flags(cpu,0,TRUE);
961:
962: ppc32_jit_close_hreg_seq(cpu);
1.1 root 963: return(0);
964: }
965:
966: /* ADDI - ADD Immediate */
967: DECLARE_INSN(ADDI)
968: {
969: int rd = bits(insn,21,25);
970: int ra = bits(insn,16,20);
971: int imm = bits(insn,0,15);
972: m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3 root 973: int hreg_rd,hreg_ra;
974: jit_op_t *iop;
975:
976: /* $rd = $ra + imm */
977: ppc32_jit_start_hreg_seq(cpu,"addi");
978: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1 root 979:
1.1.1.3 root 980: if (ra != 0) {
981: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
982: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1.1 root 983:
1.1.1.3 root 984: iop = ppc32_op_emit_insn_output(cpu,2,"addi");
1.1 root 985:
1.1.1.3 root 986: if (rd != ra)
987: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
988:
989: amd64_alu_reg_imm_size(iop->ob_ptr,X86_ADD,hreg_rd,tmp,4);
990: } else {
991: iop = ppc32_op_emit_insn_output(cpu,1,"addi");
992: ppc32_load_imm(&iop->ob_ptr,hreg_rd,tmp);
993: }
994:
995: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
996:
997: ppc32_jit_close_hreg_seq(cpu);
1.1 root 998: return(0);
999: }
1000:
1001: /* ADDIC - ADD Immediate with Carry */
1002: DECLARE_INSN(ADDIC)
1003: {
1004: int rd = bits(insn,21,25);
1005: int ra = bits(insn,16,20);
1006: int imm = bits(insn,0,15);
1007: m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3 root 1008: int hreg_rd,hreg_ra;
1009: jit_op_t *iop;
1010:
1011: /* $rd = $ra + imm */
1012: ppc32_jit_start_hreg_seq(cpu,"addic");
1013: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1014: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1015:
1016: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1017:
1018: iop = ppc32_op_emit_insn_output(cpu,1,"addic");
1019:
1020: if (rd != ra)
1021: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1.1 root 1022:
1.1.1.3 root 1023: amd64_alu_reg_imm_size(iop->ob_ptr,X86_ADD,hreg_rd,tmp,4);
1024: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1025:
1026: amd64_set_membase(iop->ob_ptr,X86_CC_C,
1027: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),FALSE);
1028:
1029: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1030: return(0);
1031: }
1032:
1033: /* ADDIC. */
1034: DECLARE_INSN(ADDIC_dot)
1035: {
1036: int rd = bits(insn,21,25);
1037: int ra = bits(insn,16,20);
1038: int imm = bits(insn,0,15);
1039: m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3 root 1040: int hreg_rd,hreg_ra;
1041: jit_op_t *iop;
1042:
1043: /* $rd = $ra + imm */
1044: ppc32_jit_start_hreg_seq(cpu,"addic.");
1045: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1046: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1047:
1048: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1049:
1050: iop = ppc32_op_emit_insn_output(cpu,1,"addic.");
1051:
1052: if (rd != ra)
1053: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1054:
1055: amd64_alu_reg_imm_size(iop->ob_ptr,X86_ADD,hreg_rd,tmp,4);
1056: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1057:
1058: amd64_set_membase(iop->ob_ptr,X86_CC_C,
1059: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),FALSE);
1.1 root 1060:
1.1.1.3 root 1061: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 1062:
1.1.1.3 root 1063: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1064: return(0);
1065: }
1066:
1067: /* ADDIS - ADD Immediate Shifted */
1068: DECLARE_INSN(ADDIS)
1069: {
1070: int rd = bits(insn,21,25);
1071: int ra = bits(insn,16,20);
1072: m_uint32_t imm = bits(insn,0,15);
1.1.1.3 root 1073: m_uint32_t tmp = imm << 16;
1074: int hreg_rd,hreg_ra;
1075: jit_op_t *iop;
1076:
1077: /* $rd = $ra + (imm << 16) */
1078: ppc32_jit_start_hreg_seq(cpu,"addis");
1079: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1080:
1081: if (ra != 0) {
1082: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1083: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1084:
1085: iop = ppc32_op_emit_insn_output(cpu,1,"addis");
1086:
1087: if (rd != ra)
1088: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1089:
1090: amd64_alu_reg_imm_size(iop->ob_ptr,X86_ADD,hreg_rd,tmp,4);
1091: } else {
1092: iop = ppc32_op_emit_insn_output(cpu,1,"addis");
1093: amd64_mov_reg_imm(iop->ob_ptr,hreg_rd,tmp);
1094: }
1095:
1096: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1097:
1098: ppc32_jit_close_hreg_seq(cpu);
1099: return(0);
1100: }
1101:
1102: /* ADDZE */
1103: DECLARE_INSN(ADDZE)
1104: {
1105: int rd = bits(insn,21,25);
1106: int ra = bits(insn,16,20);
1107: int hreg_rd,hreg_ra,hreg_t0;
1108: jit_op_t *iop;
1109:
1110: /* $rd = $ra + xer_ca + set_carry */
1111: ppc32_jit_start_hreg_seq(cpu,"addze");
1112: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1113: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1114: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1115:
1116: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1.1 root 1117:
1.1.1.3 root 1118: iop = ppc32_op_emit_insn_output(cpu,2,"addze");
1.1 root 1119:
1.1.1.3 root 1120: amd64_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,hreg_t0);
1.1 root 1121:
1.1.1.3 root 1122: if (rd != ra)
1123: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
1124:
1125: amd64_alu_reg_membase_size(iop->ob_ptr,X86_ADD,hreg_rd,
1126: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),4);
1127:
1128: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t0,FALSE);
1129: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
1130: hreg_t0,4);
1131:
1132: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1133:
1134: if (insn & 1)
1135: ppc32_op_emit_update_flags(cpu,0,TRUE);
1136:
1137: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1138: return(0);
1139: }
1140:
1141: /* AND */
1142: DECLARE_INSN(AND)
1143: {
1144: int rs = bits(insn,21,25);
1145: int ra = bits(insn,16,20);
1146: int rb = bits(insn,11,15);
1.1.1.3 root 1147: int hreg_rs,hreg_ra,hreg_rb;
1148: jit_op_t *iop;
1149:
1150: /* $ra = $rs & $rb */
1151: ppc32_jit_start_hreg_seq(cpu,"and");
1152: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
1153: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1154: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1155:
1156: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1157: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1158:
1159: iop = ppc32_op_emit_insn_output(cpu,1,"and");
1160:
1161: if (ra == rs)
1162: amd64_alu_reg_reg_size(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb,4);
1163: else if (ra == rb)
1164: amd64_alu_reg_reg_size(iop->ob_ptr,X86_AND,hreg_ra,hreg_rs,4);
1165: else {
1166: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1167: amd64_alu_reg_reg_size(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb,4);
1168: }
1.1 root 1169:
1.1.1.3 root 1170: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1 root 1171:
1172: if (insn & 1)
1.1.1.3 root 1173: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 1174:
1.1.1.3 root 1175: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1176: return(0);
1177: }
1178:
1179: /* ANDC */
1180: DECLARE_INSN(ANDC)
1181: {
1182: int rs = bits(insn,21,25);
1183: int ra = bits(insn,16,20);
1184: int rb = bits(insn,11,15);
1.1.1.3 root 1185: int hreg_rs,hreg_ra,hreg_rb,hreg_t0;
1186: jit_op_t *iop;
1.1 root 1187:
1188: /* $ra = $rs & ~$rb */
1.1.1.3 root 1189: ppc32_jit_start_hreg_seq(cpu,"andc");
1190: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
1191: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1192: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1193:
1194: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1195: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1196:
1197: iop = ppc32_op_emit_insn_output(cpu,1,"andc");
1198:
1199: /* $t0 = ~$rb */
1200: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1201: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rb,4);
1202: amd64_not_reg(iop->ob_ptr,hreg_t0);
1203:
1204: /* $ra = $rs & $t0 */
1205: if (ra == rs)
1206: amd64_alu_reg_reg_size(iop->ob_ptr,X86_AND,hreg_ra,hreg_t0,4);
1207: else {
1208: amd64_alu_reg_reg_size(iop->ob_ptr,X86_AND,hreg_t0,hreg_rs,4);
1209: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
1210: }
1211:
1212: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1 root 1213:
1214: if (insn & 1)
1.1.1.3 root 1215: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 1216:
1.1.1.3 root 1217: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1218: return(0);
1219: }
1220:
1221: /* AND Immediate */
1222: DECLARE_INSN(ANDI)
1223: {
1224: int rs = bits(insn,21,25);
1225: int ra = bits(insn,16,20);
1226: m_uint16_t imm = bits(insn,0,15);
1.1.1.3 root 1227: m_uint32_t tmp = imm;
1228: int hreg_rs,hreg_ra;
1229: jit_op_t *iop;
1.1 root 1230:
1231: /* $ra = $rs & imm */
1.1.1.3 root 1232: ppc32_jit_start_hreg_seq(cpu,"andi");
1233: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
1234: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1235:
1236: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1237:
1238: iop = ppc32_op_emit_insn_output(cpu,2,"andi");
1239:
1240: if (ra != rs)
1241: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1.1 root 1242:
1.1.1.3 root 1243: amd64_alu_reg_imm_size(iop->ob_ptr,X86_AND,hreg_ra,tmp,4);
1244: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1245:
1246: ppc32_op_emit_update_flags(cpu,0,TRUE);
1247:
1248: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1249: return(0);
1250: }
1251:
1252: /* AND Immediate Shifted */
1253: DECLARE_INSN(ANDIS)
1254: {
1255: int rs = bits(insn,21,25);
1256: int ra = bits(insn,16,20);
1257: m_uint32_t imm = bits(insn,0,15);
1.1.1.3 root 1258: m_uint32_t tmp = imm << 16;
1259: int hreg_rs,hreg_ra;
1260: jit_op_t *iop;
1.1 root 1261:
1262: /* $ra = $rs & imm */
1.1.1.3 root 1263: ppc32_jit_start_hreg_seq(cpu,"andis");
1264: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
1265: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1266:
1267: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1268:
1269: iop = ppc32_op_emit_insn_output(cpu,2,"andis");
1.1 root 1270:
1.1.1.3 root 1271: if (ra != rs)
1272: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1273:
1274: amd64_alu_reg_imm_size(iop->ob_ptr,X86_AND,hreg_ra,tmp,4);
1275: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1276:
1277: ppc32_op_emit_update_flags(cpu,0,TRUE);
1278:
1279: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1280: return(0);
1281: }
1282:
1283: /* B - Branch */
1284: DECLARE_INSN(B)
1285: {
1286: m_uint32_t offset = bits(insn,2,25);
1.1.1.3 root 1287: m_uint32_t new_ia;
1288: jit_op_t *iop;
1289:
1290: iop = ppc32_op_emit_insn_output(cpu,4,"b");
1.1 root 1291:
1292: /* compute the new ia */
1.1.1.3 root 1293: new_ia = b->start_ia + (b->ppc_trans_pos << 2);
1.1 root 1294: new_ia += sign_extend(offset << 2,26);
1.1.1.3 root 1295: ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1296:
1297: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1298: ppc32_op_emit_branch_target(cpu,b,new_ia);
1299: ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1 root 1300: return(0);
1301: }
1302:
1303: /* BA - Branch Absolute */
1304: DECLARE_INSN(BA)
1305: {
1306: m_uint32_t offset = bits(insn,2,25);
1.1.1.3 root 1307: m_uint32_t new_ia;
1308: jit_op_t *iop;
1309:
1310: iop = ppc32_op_emit_insn_output(cpu,4,"ba");
1.1 root 1311:
1312: /* compute the new ia */
1313: new_ia = sign_extend(offset << 2,26);
1.1.1.3 root 1314: ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1315:
1316: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1317: ppc32_op_emit_branch_target(cpu,b,new_ia);
1318: ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1 root 1319: return(0);
1320: }
1321:
1322: /* BL - Branch and Link */
1323: DECLARE_INSN(BL)
1324: {
1325: m_uint32_t offset = bits(insn,2,25);
1.1.1.3 root 1326: m_uint32_t new_ia;
1327: jit_op_t *iop;
1328:
1329: iop = ppc32_op_emit_insn_output(cpu,4,"bl");
1.1 root 1330:
1331: /* compute the new ia */
1.1.1.3 root 1332: new_ia = b->start_ia + (b->ppc_trans_pos << 2);
1.1 root 1333: new_ia += sign_extend(offset << 2,26);
1334:
1335: /* set the return address */
1.1.1.3 root 1336: ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1337: ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1.1 root 1338:
1.1.1.3 root 1339: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1340: ppc32_op_emit_branch_target(cpu,b,new_ia);
1341: ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1 root 1342: return(0);
1343: }
1344:
1345: /* BLA - Branch and Link Absolute */
1346: DECLARE_INSN(BLA)
1347: {
1348: m_uint32_t offset = bits(insn,2,25);
1.1.1.3 root 1349: m_uint32_t new_ia;
1350: jit_op_t *iop;
1351:
1352: iop = ppc32_op_emit_insn_output(cpu,4,"bla");
1.1 root 1353:
1354: /* compute the new ia */
1355: new_ia = sign_extend(offset << 2,26);
1356:
1357: /* set the return address */
1.1.1.3 root 1358: ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1359: ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1.1 root 1360:
1.1.1.3 root 1361: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1362: ppc32_op_emit_branch_target(cpu,b,new_ia);
1363: ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1) << 2));
1.1 root 1364: return(0);
1365: }
1366:
1367: /* BC - Branch Conditional (Condition Check only) */
1368: DECLARE_INSN(BCC)
1369: {
1370: int bo = bits(insn,21,25);
1371: int bi = bits(insn,16,20);
1372: int bd = bits(insn,2,15);
1.1.1.3 root 1373: jit_op_t *iop;
1.1.1.2 root 1374: u_int cr_field,cr_bit;
1.1 root 1375: m_uint32_t new_ia;
1376: u_char *jump_ptr;
1377: int local_jump;
1378: int cond;
1379:
1.1.1.3 root 1380: ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP);
1381:
1382: iop = ppc32_op_emit_insn_output(cpu,5,"bcc");
1383:
1.1 root 1384: /* Get the wanted value for the condition bit */
1385: cond = (bo >> 3) & 0x1;
1386:
1387: /* Set the return address */
1.1.1.3 root 1388: if (insn & 1) {
1389: ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1390: ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2));
1391: }
1.1 root 1392:
1393: /* Compute the new ia */
1394: new_ia = sign_extend_32(bd << 2,16);
1395: if (!(insn & 0x02))
1.1.1.3 root 1396: new_ia += b->start_ia + (b->ppc_trans_pos << 2);
1.1 root 1397:
1398: /* Test the condition bit */
1.1.1.2 root 1399: cr_field = ppc32_get_cr_field(bi);
1400: cr_bit = ppc32_get_cr_bit(bi);
1401:
1.1.1.3 root 1402: ppc32_op_emit_require_flags(cpu,cr_field);
1403:
1404: amd64_test_membase_imm_size(iop->ob_ptr,
1.1.1.2 root 1405: AMD64_R15,PPC32_CR_FIELD_OFFSET(cr_field),
1406: (1 << cr_bit),4);
1.1 root 1407:
1408: local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
1409:
1410: /*
1411: * Optimize the jump, depending if the destination is in the same
1412: * page or not.
1413: */
1414: if (local_jump) {
1.1.1.3 root 1415: ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia);
1416: amd64_branch32(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,0,FALSE);
1.1 root 1417: } else {
1.1.1.3 root 1418: jump_ptr = iop->ob_ptr;
1419: amd64_branch32(iop->ob_ptr,(cond) ? X86_CC_Z : X86_CC_NZ,0,FALSE);
1420: ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1421: amd64_patch(jump_ptr,iop->ob_ptr);
1.1 root 1422: }
1423:
1.1.1.3 root 1424: ppc32_op_emit_branch_target(cpu,b,new_ia);
1.1 root 1425: return(0);
1426: }
1427:
1428: /* BC - Branch Conditional */
1429: DECLARE_INSN(BC)
1.1.1.3 root 1430: {
1.1 root 1431: int bo = bits(insn,21,25);
1432: int bi = bits(insn,16,20);
1433: int bd = bits(insn,2,15);
1.1.1.3 root 1434: int hreg_t0,hreg_t1;
1435: jit_op_t *iop;
1.1.1.2 root 1436: u_int cr_field,cr_bit;
1.1 root 1437: m_uint32_t new_ia;
1438: u_char *jump_ptr;
1439: int local_jump;
1440: int cond,ctr;
1441:
1.1.1.3 root 1442: ppc32_op_emit_basic_opcode(cpu,JIT_OP_BRANCH_JUMP);
1443:
1444: iop = ppc32_op_emit_insn_output(cpu,5,"bc");
1445:
1446: ppc32_jit_start_hreg_seq(cpu,"bc");
1447: hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
1448: hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
1449:
1450: ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
1451:
1.1 root 1452: /* Get the wanted value for the condition bit and CTR value */
1453: cond = (bo >> 3) & 0x1;
1454: ctr = (bo >> 1) & 0x1;
1455:
1456: /* Set the return address */
1.1.1.3 root 1457: if (insn & 1) {
1458: ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1459: ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2));
1460: }
1.1 root 1461:
1462: /* Compute the new ia */
1463: new_ia = sign_extend_32(bd << 2,16);
1464: if (!(insn & 0x02))
1.1.1.3 root 1465: new_ia += b->start_ia + (b->ppc_trans_pos << 2);
1.1 root 1466:
1.1.1.3 root 1467: amd64_mov_reg_imm(iop->ob_ptr,hreg_t0,1);
1.1 root 1468:
1469: /* Decrement the count register */
1470: if (!(bo & 0x04)) {
1.1.1.3 root 1471: amd64_dec_membase_size(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ctr),4);
1472: amd64_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE);
1473: amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1.1 root 1474: }
1475:
1476: /* Test the condition bit */
1477: if (!((bo >> 4) & 0x01)) {
1.1.1.2 root 1478: cr_field = ppc32_get_cr_field(bi);
1479: cr_bit = ppc32_get_cr_bit(bi);
1480:
1.1.1.3 root 1481: ppc32_op_emit_require_flags(cpu,cr_field);
1482:
1483: amd64_test_membase_imm_size(iop->ob_ptr,
1.1.1.2 root 1484: AMD64_R15,PPC32_CR_FIELD_OFFSET(cr_field),
1485: (1 << cr_bit),4);
1486:
1.1.1.3 root 1487: amd64_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE);
1488: amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1.1 root 1489: }
1490:
1.1.1.3 root 1491: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1 root 1492:
1493: local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr);
1494:
1495: /*
1496: * Optimize the jump, depending if the destination is in the same
1497: * page or not.
1498: */
1499: if (local_jump) {
1.1.1.3 root 1500: ppc32_jit_tcb_record_patch(b,iop,iop->ob_ptr,new_ia);
1501: amd64_branch32(iop->ob_ptr,X86_CC_NZ,0,FALSE);
1.1 root 1502: } else {
1.1.1.3 root 1503: jump_ptr = iop->ob_ptr;
1504: amd64_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE);
1505: ppc32_set_jump(cpu,b,iop,new_ia,TRUE);
1506: amd64_patch(jump_ptr,iop->ob_ptr);
1.1 root 1507: }
1508:
1.1.1.3 root 1509: ppc32_op_emit_branch_target(cpu,b,new_ia);
1510:
1511: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1512: return(0);
1513: }
1514:
1515: /* BCLR - Branch Conditional to Link register */
1516: DECLARE_INSN(BCLR)
1517: {
1518: int bo = bits(insn,21,25);
1519: int bi = bits(insn,16,20);
1520: int bd = bits(insn,2,15);
1.1.1.3 root 1521: int hreg_t0,hreg_t1;
1522: jit_op_t *iop;
1.1.1.2 root 1523: u_int cr_field,cr_bit;
1.1 root 1524: m_uint32_t new_ia;
1525: u_char *jump_ptr;
1526: int cond,ctr;
1527:
1.1.1.3 root 1528: ppc32_jit_start_hreg_seq(cpu,"bclr");
1529: hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
1530: hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
1531:
1532: ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
1533:
1534: iop = ppc32_op_emit_insn_output(cpu,5,"bclr");
1535:
1.1 root 1536: /* Get the wanted value for the condition bit and CTR value */
1537: cond = (bo >> 3) & 0x1;
1538: ctr = (bo >> 1) & 0x1;
1539:
1540: /* Compute the new ia */
1541: new_ia = sign_extend_32(bd << 2,16);
1542: if (!(insn & 0x02))
1.1.1.3 root 1543: new_ia += b->start_ia + (b->ppc_trans_pos << 2);
1.1 root 1544:
1.1.1.3 root 1545: amd64_mov_reg_imm(iop->ob_ptr,hreg_t0,1);
1.1 root 1546:
1547: /* Decrement the count register */
1548: if (!(bo & 0x04)) {
1.1.1.3 root 1549: amd64_dec_membase_size(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ctr),4);
1550: amd64_set_reg(iop->ob_ptr,(ctr) ? X86_CC_Z : X86_CC_NZ,hreg_t1,FALSE);
1551: amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1.1 root 1552: }
1553:
1554: /* Test the condition bit */
1555: if (!((bo >> 4) & 0x01)) {
1.1.1.2 root 1556: cr_field = ppc32_get_cr_field(bi);
1557: cr_bit = ppc32_get_cr_bit(bi);
1558:
1.1.1.3 root 1559: ppc32_op_emit_require_flags(cpu,cr_field);
1560:
1561: amd64_test_membase_imm_size(iop->ob_ptr,
1.1.1.2 root 1562: AMD64_R15,PPC32_CR_FIELD_OFFSET(cr_field),
1563: (1 << cr_bit),4);
1564:
1.1.1.3 root 1565: amd64_set_reg(iop->ob_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,hreg_t1,FALSE);
1566: amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,hreg_t1);
1.1 root 1567: }
1568:
1569: /* Set the return address */
1.1.1.3 root 1570: amd64_mov_reg_membase(iop->ob_ptr,hreg_t1,AMD64_R15,OFFSET(cpu_ppc_t,lr),4);
1.1 root 1571:
1.1.1.3 root 1572: if (insn & 1) {
1573: ppc32_set_lr(iop,b->start_ia + ((b->ppc_trans_pos+1) << 2));
1574: ppc32_op_emit_branch_target(cpu,b,b->start_ia+((b->ppc_trans_pos+1)<<2));
1575: }
1.1 root 1576:
1577: /* Branching */
1.1.1.3 root 1578: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1579:
1580: jump_ptr = iop->ob_ptr;
1581: amd64_branch32(iop->ob_ptr,X86_CC_Z,0,FALSE);
1.1 root 1582:
1.1.1.3 root 1583: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t1,0xFFFFFFFC);
1584: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,ia),hreg_t1,4);
1585: ppc32_jit_tcb_push_epilog(&iop->ob_ptr);
1.1 root 1586:
1.1.1.3 root 1587: amd64_patch(jump_ptr,iop->ob_ptr);
1.1 root 1588:
1.1.1.3 root 1589: ppc32_op_emit_basic_opcode(cpu,JIT_OP_EOB);
1590:
1591: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1592: return(0);
1593: }
1594:
1595: /* CMP - Compare */
1596: DECLARE_INSN(CMP)
1597: {
1598: int rd = bits(insn,23,25);
1599: int ra = bits(insn,16,20);
1600: int rb = bits(insn,11,15);
1.1.1.3 root 1601: int hreg_ra,hreg_rb;
1602: jit_op_t *iop;
1603:
1604: ppc32_jit_start_hreg_seq(cpu,"cmp");
1605: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1606: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1.1 root 1607:
1.1.1.3 root 1608: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1609: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1610:
1611: iop = ppc32_op_emit_insn_output(cpu,1,"cmp");
1612:
1613: amd64_alu_reg_reg_size(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb,4);
1614: ppc32_op_emit_update_flags(cpu,rd,TRUE);
1615:
1616: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1617: return(0);
1618: }
1619:
1620: /* CMPI - Compare Immediate */
1621: DECLARE_INSN(CMPI)
1622: {
1623: int rd = bits(insn,23,25);
1624: int ra = bits(insn,16,20);
1625: m_uint16_t imm = bits(insn,0,15);
1626: m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3 root 1627: int hreg_ra;
1628: jit_op_t *iop;
1629:
1630: ppc32_jit_start_hreg_seq(cpu,"cmpi");
1631: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1632: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1.1 root 1633:
1.1.1.3 root 1634: iop = ppc32_op_emit_insn_output(cpu,1,"cmpi");
1.1 root 1635:
1.1.1.3 root 1636: amd64_alu_reg_imm_size(iop->ob_ptr,X86_CMP,hreg_ra,tmp,4);
1637: ppc32_op_emit_update_flags(cpu,rd,TRUE);
1638:
1639: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1640: return(0);
1641: }
1642:
1643: /* CMPL - Compare Logical */
1644: DECLARE_INSN(CMPL)
1645: {
1646: int rd = bits(insn,23,25);
1647: int ra = bits(insn,16,20);
1648: int rb = bits(insn,11,15);
1.1.1.3 root 1649: int hreg_ra,hreg_rb;
1650: jit_op_t *iop;
1651:
1652: ppc32_jit_start_hreg_seq(cpu,"cmpl");
1653: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1654: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1655:
1656: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1657: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1658:
1659: iop = ppc32_op_emit_insn_output(cpu,1,"cmpl");
1.1 root 1660:
1.1.1.3 root 1661: amd64_alu_reg_reg_size(iop->ob_ptr,X86_CMP,hreg_ra,hreg_rb,4);
1662: ppc32_op_emit_update_flags(cpu,rd,FALSE);
1663:
1664: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1665: return(0);
1666: }
1667:
1668: /* CMPLI - Compare Immediate */
1669: DECLARE_INSN(CMPLI)
1670: {
1671: int rd = bits(insn,23,25);
1672: int ra = bits(insn,16,20);
1.1.1.3 root 1673: m_uint32_t imm = bits(insn,0,15);
1674: int hreg_ra;
1675: jit_op_t *iop;
1676:
1677: ppc32_jit_start_hreg_seq(cpu,"cmpli");
1678: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1679: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1.1 root 1680:
1.1.1.3 root 1681: iop = ppc32_op_emit_insn_output(cpu,1,"cmpli");
1.1 root 1682:
1.1.1.3 root 1683: amd64_alu_reg_imm_size(iop->ob_ptr,X86_CMP,hreg_ra,imm,4);
1684: ppc32_op_emit_update_flags(cpu,rd,FALSE);
1685:
1686: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1687: return(0);
1688: }
1689:
1690: /* CRAND - Condition Register AND */
1691: DECLARE_INSN(CRAND)
1692: {
1693: int bd = bits(insn,21,25);
1694: int bb = bits(insn,16,20);
1695: int ba = bits(insn,11,15);
1.1.1.3 root 1696: int hreg_t0;
1697: jit_op_t *iop;
1698:
1699: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
1700:
1701: ppc32_jit_start_hreg_seq(cpu,"crand");
1702: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1703: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
1704:
1705: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1706: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1707: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1708:
1709: iop = ppc32_op_emit_insn_output(cpu,3,"crand");
1.1 root 1710:
1711: /* test $ba bit */
1.1.1.3 root 1712: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1713: AMD64_R15,
1714: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1715: (1 << ppc32_get_cr_bit(ba)));
1.1.1.3 root 1716: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,AMD64_RDX,FALSE);
1.1 root 1717:
1718: /* test $bb bit */
1.1.1.3 root 1719: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1720: AMD64_R15,
1721: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
1722: (1 << ppc32_get_cr_bit(bb)));
1.1.1.3 root 1723: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1 root 1724:
1725: /* result of AND between $ba and $bb */
1.1.1.3 root 1726: amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,AMD64_RDX);
1727: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1 root 1728:
1729: /* set/clear $bd bit depending on the result */
1.1.1.3 root 1730: amd64_alu_membase_imm_size(iop->ob_ptr,X86_AND,
1.1.1.2 root 1731: AMD64_R15,
1732: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1733: ~(1 << ppc32_get_cr_bit(bd)),4);
1734:
1.1.1.3 root 1735: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
1736: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
1.1.1.2 root 1737: AMD64_R15,
1738: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3 root 1739: hreg_t0,4);
1740:
1741: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1742: return(0);
1743: }
1744:
1745: /* CRANDC - Condition Register AND with Complement */
1746: DECLARE_INSN(CRANDC)
1747: {
1748: int bd = bits(insn,21,25);
1749: int bb = bits(insn,16,20);
1750: int ba = bits(insn,11,15);
1.1.1.3 root 1751: int hreg_t0;
1752: jit_op_t *iop;
1753:
1754: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
1755:
1756: ppc32_jit_start_hreg_seq(cpu,"crandc");
1757: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1758: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
1759:
1760: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1761: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1762: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1763:
1764: iop = ppc32_op_emit_insn_output(cpu,3,"crandc");
1.1 root 1765:
1766: /* test $ba bit */
1.1.1.3 root 1767: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1768: AMD64_R15,
1769: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1770: (1 << ppc32_get_cr_bit(ba)));
1.1.1.3 root 1771: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,AMD64_RDX,FALSE);
1.1 root 1772:
1773: /* test $bb bit */
1.1.1.3 root 1774: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1775: AMD64_R15,
1776: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
1777: (1 << ppc32_get_cr_bit(bb)));
1.1.1.3 root 1778: amd64_set_reg(iop->ob_ptr,X86_CC_Z,hreg_t0,FALSE);
1.1 root 1779:
1780: /* result of AND between $ba and $bb */
1.1.1.3 root 1781: amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,AMD64_RDX);
1782: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1 root 1783:
1784: /* set/clear $bd bit depending on the result */
1.1.1.3 root 1785: amd64_alu_membase_imm_size(iop->ob_ptr,X86_AND,
1.1.1.2 root 1786: AMD64_R15,
1787: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1788: ~(1 << ppc32_get_cr_bit(bd)),4);
1789:
1.1.1.3 root 1790: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
1791: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
1.1.1.2 root 1792: AMD64_R15,
1793: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3 root 1794: hreg_t0,4);
1795:
1796: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1797: return(0);
1798: }
1799:
1800: /* CREQV - Condition Register EQV */
1801: DECLARE_INSN(CREQV)
1802: {
1803: int bd = bits(insn,21,25);
1804: int bb = bits(insn,16,20);
1805: int ba = bits(insn,11,15);
1.1.1.3 root 1806: int hreg_t0;
1807: jit_op_t *iop;
1808:
1809: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
1810:
1811: ppc32_jit_start_hreg_seq(cpu,"creqv");
1812: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1813: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
1814:
1815: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1816: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1817: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1818:
1819: iop = ppc32_op_emit_insn_output(cpu,3,"creqv");
1.1 root 1820:
1821: /* test $ba bit */
1.1.1.3 root 1822: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1823: AMD64_R15,
1824: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1825: (1 << ppc32_get_cr_bit(ba)));
1.1.1.3 root 1826: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,AMD64_RDX,FALSE);
1.1 root 1827:
1828: /* test $bb bit */
1.1.1.3 root 1829: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1830: AMD64_R15,
1831: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
1832: (1 << ppc32_get_cr_bit(bb)));
1.1.1.3 root 1833: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1 root 1834:
1835: /* result of XOR between $ba and $bb */
1.1.1.3 root 1836: amd64_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,AMD64_RDX);
1837: amd64_not_reg(iop->ob_ptr,hreg_t0);
1838: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1 root 1839:
1840: /* set/clear $bd bit depending on the result */
1.1.1.3 root 1841: amd64_alu_membase_imm_size(iop->ob_ptr,X86_AND,
1.1.1.2 root 1842: AMD64_R15,
1843: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1844: ~(1 << ppc32_get_cr_bit(bd)),4);
1845:
1.1.1.3 root 1846: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
1847: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
1.1.1.2 root 1848: AMD64_R15,
1849: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3 root 1850: hreg_t0,4);
1851:
1852: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1853: return(0);
1854: }
1855:
1856: /* CRNAND - Condition Register NAND */
1857: DECLARE_INSN(CRNAND)
1858: {
1859: int bd = bits(insn,21,25);
1860: int bb = bits(insn,16,20);
1861: int ba = bits(insn,11,15);
1.1.1.3 root 1862: int hreg_t0;
1863: jit_op_t *iop;
1864:
1865: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
1866:
1867: ppc32_jit_start_hreg_seq(cpu,"crnand");
1868: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1869: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
1870:
1871: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1872: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1873: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1874:
1875: iop = ppc32_op_emit_insn_output(cpu,3,"crnand");
1.1 root 1876:
1877: /* test $ba bit */
1.1.1.3 root 1878: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1879: AMD64_R15,
1880: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1881: (1 << ppc32_get_cr_bit(ba)));
1.1.1.3 root 1882: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,AMD64_RDX,FALSE);
1.1 root 1883:
1884: /* test $bb bit */
1.1.1.3 root 1885: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1886: AMD64_R15,
1887: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
1888: (1 << ppc32_get_cr_bit(bb)));
1.1.1.3 root 1889: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1 root 1890:
1891: /* result of NAND between $ba and $bb */
1.1.1.3 root 1892: amd64_alu_reg_reg(iop->ob_ptr,X86_AND,hreg_t0,AMD64_RDX);
1893: amd64_not_reg(iop->ob_ptr,hreg_t0);
1894: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1 root 1895:
1896: /* set/clear $bd bit depending on the result */
1.1.1.3 root 1897: amd64_alu_membase_imm_size(iop->ob_ptr,X86_AND,
1.1.1.2 root 1898: AMD64_R15,
1899: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1900: ~(1 << ppc32_get_cr_bit(bd)),4);
1901:
1.1.1.3 root 1902: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
1903: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
1.1.1.2 root 1904: AMD64_R15,
1905: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3 root 1906: hreg_t0,4);
1907:
1908: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1909: return(0);
1910: }
1911:
1912: /* CRNOR - Condition Register NOR */
1913: DECLARE_INSN(CRNOR)
1914: {
1915: int bd = bits(insn,21,25);
1916: int bb = bits(insn,16,20);
1917: int ba = bits(insn,11,15);
1.1.1.3 root 1918: int hreg_t0;
1919: jit_op_t *iop;
1920:
1921: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
1922:
1923: ppc32_jit_start_hreg_seq(cpu,"crnor");
1924: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1925: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
1926:
1927: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1928: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1929: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1930:
1931: iop = ppc32_op_emit_insn_output(cpu,3,"crnor");
1.1 root 1932:
1933: /* test $ba bit */
1.1.1.3 root 1934: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1935: AMD64_R15,
1936: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1937: (1 << ppc32_get_cr_bit(ba)));
1.1.1.3 root 1938: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,AMD64_RDX,FALSE);
1.1 root 1939:
1940: /* test $bb bit */
1.1.1.3 root 1941: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1942: AMD64_R15,
1943: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
1944: (1 << ppc32_get_cr_bit(bb)));
1.1.1.3 root 1945: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1 root 1946:
1947: /* result of NOR between $ba and $bb */
1.1.1.3 root 1948: amd64_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,AMD64_RDX);
1949: amd64_not_reg(iop->ob_ptr,hreg_t0);
1950: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1 root 1951:
1952: /* set/clear $bd bit depending on the result */
1.1.1.3 root 1953: amd64_alu_membase_imm_size(iop->ob_ptr,X86_AND,
1.1.1.2 root 1954: AMD64_R15,
1955: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1956: ~(1 << ppc32_get_cr_bit(bd)),4);
1957:
1.1.1.3 root 1958: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
1959: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
1.1.1.2 root 1960: AMD64_R15,
1961: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3 root 1962: hreg_t0,4);
1963:
1964: ppc32_jit_close_hreg_seq(cpu);
1.1 root 1965: return(0);
1966: }
1967:
1968: /* CROR - Condition Register OR */
1969: DECLARE_INSN(CROR)
1970: {
1971: int bd = bits(insn,21,25);
1972: int bb = bits(insn,16,20);
1973: int ba = bits(insn,11,15);
1.1.1.3 root 1974: int hreg_t0;
1975: jit_op_t *iop;
1976:
1977: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
1978:
1979: ppc32_jit_start_hreg_seq(cpu,"cror");
1980: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
1981: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
1982:
1983: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
1984: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
1985: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
1986:
1987: iop = ppc32_op_emit_insn_output(cpu,3,"cror");
1.1 root 1988:
1989: /* test $ba bit */
1.1.1.3 root 1990: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1991: AMD64_R15,
1992: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
1993: (1 << ppc32_get_cr_bit(ba)));
1.1.1.3 root 1994: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,AMD64_RDX,FALSE);
1.1 root 1995:
1996: /* test $bb bit */
1.1.1.3 root 1997: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 1998: AMD64_R15,
1999: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
2000: (1 << ppc32_get_cr_bit(bb)));
1.1.1.3 root 2001: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1 root 2002:
2003: /* result of NOR between $ba and $bb */
1.1.1.3 root 2004: amd64_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,AMD64_RDX);
2005: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1 root 2006:
2007: /* set/clear $bd bit depending on the result */
1.1.1.3 root 2008: amd64_alu_membase_imm_size(iop->ob_ptr,X86_AND,
1.1.1.2 root 2009: AMD64_R15,
2010: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2011: ~(1 << ppc32_get_cr_bit(bd)),4);
2012:
1.1.1.3 root 2013: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
2014: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
1.1.1.2 root 2015: AMD64_R15,
2016: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3 root 2017: hreg_t0,4);
2018:
2019: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2020: return(0);
2021: }
2022:
2023: /* CRORC - Condition Register OR with Complement */
2024: DECLARE_INSN(CRORC)
2025: {
2026: int bd = bits(insn,21,25);
2027: int bb = bits(insn,16,20);
2028: int ba = bits(insn,11,15);
1.1.1.3 root 2029: int hreg_t0;
2030: jit_op_t *iop;
2031:
2032: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
2033:
2034: ppc32_jit_start_hreg_seq(cpu,"crorc");
2035: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2036: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
2037:
2038: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
2039: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
2040: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
2041:
2042: iop = ppc32_op_emit_insn_output(cpu,3,"crorc");
1.1 root 2043:
2044: /* test $ba bit */
1.1.1.3 root 2045: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 2046: AMD64_R15,
2047: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
2048: (1 << ppc32_get_cr_bit(ba)));
1.1.1.3 root 2049: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,AMD64_RDX,FALSE);
1.1 root 2050:
2051: /* test $bb bit */
1.1.1.3 root 2052: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 2053: AMD64_R15,
2054: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
2055: (1 << ppc32_get_cr_bit(bb)));
1.1.1.3 root 2056: amd64_set_reg(iop->ob_ptr,X86_CC_Z,hreg_t0,FALSE);
1.1 root 2057:
2058: /* result of ORC between $ba and $bb */
1.1.1.3 root 2059: amd64_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_t0,AMD64_RDX);
2060: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1 root 2061:
2062: /* set/clear $bd bit depending on the result */
1.1.1.3 root 2063: amd64_alu_membase_imm_size(iop->ob_ptr,X86_AND,
1.1.1.2 root 2064: AMD64_R15,
2065: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2066: ~(1 << ppc32_get_cr_bit(bd)),4);
2067:
1.1.1.3 root 2068: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
2069: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
1.1.1.2 root 2070: AMD64_R15,
2071: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3 root 2072: hreg_t0,4);
2073:
2074: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2075: return(0);
2076: }
2077:
2078: /* CRXOR - Condition Register XOR */
2079: DECLARE_INSN(CRXOR)
2080: {
2081: int bd = bits(insn,21,25);
2082: int bb = bits(insn,16,20);
2083: int ba = bits(insn,11,15);
1.1.1.3 root 2084: int hreg_t0;
2085: jit_op_t *iop;
2086:
2087: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
2088:
2089: ppc32_jit_start_hreg_seq(cpu,"crxor");
2090: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2091: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
2092:
2093: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(ba));
2094: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bb));
2095: ppc32_op_emit_require_flags(cpu,ppc32_get_cr_field(bd));
2096:
2097: iop = ppc32_op_emit_insn_output(cpu,3,"crxor");
1.1 root 2098:
2099: /* test $ba bit */
1.1.1.3 root 2100: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 2101: AMD64_R15,
2102: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)),
2103: (1 << ppc32_get_cr_bit(ba)));
1.1.1.3 root 2104: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,AMD64_RDX,FALSE);
1.1 root 2105:
2106: /* test $bb bit */
1.1.1.3 root 2107: amd64_test_membase_imm(iop->ob_ptr,
1.1.1.2 root 2108: AMD64_R15,
2109: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)),
2110: (1 << ppc32_get_cr_bit(bb)));
1.1.1.3 root 2111: amd64_set_reg(iop->ob_ptr,X86_CC_NZ,hreg_t0,FALSE);
1.1 root 2112:
2113: /* result of XOR between $ba and $bb */
1.1.1.3 root 2114: amd64_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t0,AMD64_RDX);
2115: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x01);
1.1 root 2116:
2117: /* set/clear $bd bit depending on the result */
1.1.1.3 root 2118: amd64_alu_membase_imm_size(iop->ob_ptr,X86_AND,
1.1.1.2 root 2119: AMD64_R15,
2120: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
2121: ~(1 << ppc32_get_cr_bit(bd)),4);
2122:
1.1.1.3 root 2123: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_t0,ppc32_get_cr_bit(bd));
2124: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
1.1.1.2 root 2125: AMD64_R15,
2126: PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)),
1.1.1.3 root 2127: hreg_t0,4);
2128:
2129: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2130: return(0);
2131: }
2132:
2133: /* DIVWU - Divide Word Unsigned */
2134: DECLARE_INSN(DIVWU)
2135: {
2136: int rd = bits(insn,21,25);
2137: int ra = bits(insn,16,20);
2138: int rb = bits(insn,11,15);
1.1.1.3 root 2139: int hreg_rb;
2140: jit_op_t *iop;
1.1 root 2141:
1.1.1.3 root 2142: ppc32_jit_start_hreg_seq(cpu,"divwu");
2143: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RAX);
2144: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
2145: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2146:
2147: /* $rd = $ra / $rb */
2148: ppc32_op_emit_load_gpr(cpu,AMD64_RAX,ra);
2149: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
1.1 root 2150:
1.1.1.3 root 2151: iop = ppc32_op_emit_insn_output(cpu,2,"divwu");
2152: ppc32_load_imm(&iop->ob_ptr,AMD64_RDX,0);
1.1 root 2153:
1.1.1.3 root 2154: amd64_div_reg_size(iop->ob_ptr,hreg_rb,0,4);
2155:
2156: if (insn & 1)
2157: amd64_test_reg_reg_size(iop->ob_ptr,AMD64_RAX,AMD64_RAX,4);
2158:
2159: ppc32_op_emit_store_gpr(cpu,rd,AMD64_RAX);
2160:
2161: if (insn & 1)
2162: ppc32_op_emit_update_flags(cpu,0,TRUE);
2163:
2164: /* edx:eax are directly modified: throw them */
2165: ppc32_op_emit_alter_host_reg(cpu,AMD64_RAX);
2166: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
2167:
2168: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2169: return(0);
2170: }
2171:
2172: /* EQV */
2173: DECLARE_INSN(EQV)
2174: {
2175: int rs = bits(insn,21,25);
2176: int ra = bits(insn,16,20);
2177: int rb = bits(insn,11,15);
1.1.1.3 root 2178: int hreg_rs,hreg_ra,hreg_rb;
2179: jit_op_t *iop;
1.1 root 2180:
2181: /* $ra = ~($rs ^ $rb) */
1.1.1.3 root 2182: ppc32_jit_start_hreg_seq(cpu,"eqv");
2183: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2184: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2185: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2186:
2187: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2188: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2189:
2190: iop = ppc32_op_emit_insn_output(cpu,1,"eqv");
2191:
2192: if (ra == rs)
2193: amd64_alu_reg_reg_size(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb,4);
2194: else if (ra == rb)
2195: amd64_alu_reg_reg_size(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rs,4);
2196: else {
2197: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2198: amd64_alu_reg_reg_size(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb,4);
1.1 root 2199: }
2200:
1.1.1.3 root 2201: amd64_not_reg(iop->ob_ptr,hreg_ra);
2202:
2203: if (insn & 1)
2204: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
2205:
2206: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2207:
2208: if (insn & 1)
2209: ppc32_op_emit_update_flags(cpu,0,TRUE);
2210:
2211: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2212: return(0);
2213: }
2214:
2215: /* EXTSB - Extend Sign Byte */
2216: DECLARE_INSN(EXTSB)
2217: {
2218: int rs = bits(insn,21,25);
2219: int ra = bits(insn,16,20);
1.1.1.3 root 2220: int hreg_rs,hreg_ra;
2221: jit_op_t *iop;
1.1 root 2222:
1.1.1.3 root 2223: /* $ra = extsb($rs) */
2224: ppc32_jit_start_hreg_seq(cpu,"extsb");
2225: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2226: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1 root 2227:
1.1.1.3 root 2228: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2229:
2230: iop = ppc32_op_emit_insn_output(cpu,2,"extsb");
2231:
2232: if (rs != ra)
2233: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2234:
2235: amd64_shift_reg_imm_size(iop->ob_ptr,X86_SHL,hreg_ra,24,4);
2236: amd64_shift_reg_imm_size(iop->ob_ptr,X86_SAR,hreg_ra,24,4);
1.1 root 2237:
1.1.1.3 root 2238: if (insn & 1)
2239: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
2240:
2241: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2242:
2243: if (insn & 1)
2244: ppc32_op_emit_update_flags(cpu,0,TRUE);
2245:
2246: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2247: return(0);
2248: }
2249:
2250: /* EXTSH - Extend Sign Word */
2251: DECLARE_INSN(EXTSH)
2252: {
2253: int rs = bits(insn,21,25);
2254: int ra = bits(insn,16,20);
1.1.1.3 root 2255: int hreg_rs,hreg_ra;
2256: jit_op_t *iop;
1.1 root 2257:
1.1.1.3 root 2258: /* $ra = extsh($rs) */
2259: ppc32_jit_start_hreg_seq(cpu,"extsh");
2260: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2261: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1 root 2262:
1.1.1.3 root 2263: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2264:
2265: iop = ppc32_op_emit_insn_output(cpu,2,"extsh");
2266:
2267: if (rs != ra)
2268: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2269:
2270: amd64_shift_reg_imm_size(iop->ob_ptr,X86_SHL,hreg_ra,16,4);
2271: amd64_shift_reg_imm_size(iop->ob_ptr,X86_SAR,hreg_ra,16,4);
2272:
2273: if (insn & 1)
2274: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
2275:
2276: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2277:
2278: if (insn & 1)
2279: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 2280:
1.1.1.3 root 2281: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2282: return(0);
2283: }
2284:
2285: /* LBZ - Load Byte and Zero */
2286: DECLARE_INSN(LBZ)
2287: {
2288: int rs = bits(insn,21,25);
2289: int ra = bits(insn,16,20);
2290: m_uint16_t offset = bits(insn,0,15);
2291:
2292: //ppc32_emit_memop(b,PPC_MEMOP_LBZ,ra,offset,rs,0);
1.1.1.3 root 2293: ppc32_emit_memop_fast(cpu,b,0,PPC_MEMOP_LBZ,ra,offset,rs,
2294: ppc32_memop_fast_lbz);
1.1 root 2295: return(0);
2296: }
2297:
2298: /* LBZU - Load Byte and Zero with Update */
2299: DECLARE_INSN(LBZU)
2300: {
2301: int rs = bits(insn,21,25);
2302: int ra = bits(insn,16,20);
2303: m_uint16_t offset = bits(insn,0,15);
2304:
1.1.1.3 root 2305: ppc32_emit_memop(cpu,b,PPC_MEMOP_LBZ,ra,offset,rs,1);
1.1 root 2306: return(0);
2307: }
2308:
2309: /* LBZUX - Load Byte and Zero with Update Indexed */
2310: DECLARE_INSN(LBZUX)
2311: {
2312: int rs = bits(insn,21,25);
2313: int ra = bits(insn,16,20);
2314: int rb = bits(insn,11,15);
2315:
1.1.1.3 root 2316: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LBZ,ra,rb,rs,1);
1.1 root 2317: return(0);
2318: }
2319:
2320: /* LBZX - Load Byte and Zero Indexed */
2321: DECLARE_INSN(LBZX)
2322: {
2323: int rs = bits(insn,21,25);
2324: int ra = bits(insn,16,20);
2325: int rb = bits(insn,11,15);
2326:
1.1.1.3 root 2327: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LBZ,ra,rb,rs,0);
1.1 root 2328: return(0);
2329: }
2330:
2331: /* LHA - Load Half-Word Algebraic */
2332: DECLARE_INSN(LHA)
2333: {
2334: int rs = bits(insn,21,25);
2335: int ra = bits(insn,16,20);
2336: m_uint16_t offset = bits(insn,0,15);
2337:
1.1.1.3 root 2338: ppc32_emit_memop(cpu,b,PPC_MEMOP_LHA,ra,offset,rs,0);
1.1 root 2339: return(0);
2340: }
2341:
2342: /* LHAU - Load Half-Word Algebraic with Update */
2343: DECLARE_INSN(LHAU)
2344: {
2345: int rs = bits(insn,21,25);
2346: int ra = bits(insn,16,20);
2347: m_uint16_t offset = bits(insn,0,15);
2348:
1.1.1.3 root 2349: ppc32_emit_memop(cpu,b,PPC_MEMOP_LHA,ra,offset,rs,1);
1.1 root 2350: return(0);
2351: }
2352:
2353: /* LHAUX - Load Half-Word Algebraic with Update Indexed */
2354: DECLARE_INSN(LHAUX)
2355: {
2356: int rs = bits(insn,21,25);
2357: int ra = bits(insn,16,20);
2358: int rb = bits(insn,11,15);
2359:
1.1.1.3 root 2360: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHA,ra,rb,rs,1);
1.1 root 2361: return(0);
2362: }
2363:
2364: /* LHAX - Load Half-Word Algebraic Indexed */
2365: DECLARE_INSN(LHAX)
2366: {
2367: int rs = bits(insn,21,25);
2368: int ra = bits(insn,16,20);
2369: int rb = bits(insn,11,15);
2370:
1.1.1.3 root 2371: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHA,ra,rb,rs,0);
1.1 root 2372: return(0);
2373: }
2374:
2375: /* LHZ - Load Half-Word and Zero */
2376: DECLARE_INSN(LHZ)
2377: {
2378: int rs = bits(insn,21,25);
2379: int ra = bits(insn,16,20);
2380: m_uint16_t offset = bits(insn,0,15);
2381:
1.1.1.3 root 2382: ppc32_emit_memop(cpu,b,PPC_MEMOP_LHZ,ra,offset,rs,0);
1.1 root 2383: return(0);
2384: }
2385:
2386: /* LHZU - Load Half-Word and Zero with Update */
2387: DECLARE_INSN(LHZU)
2388: {
2389: int rs = bits(insn,21,25);
2390: int ra = bits(insn,16,20);
2391: m_uint16_t offset = bits(insn,0,15);
2392:
1.1.1.3 root 2393: ppc32_emit_memop(cpu,b,PPC_MEMOP_LHZ,ra,offset,rs,1);
1.1 root 2394: return(0);
2395: }
2396:
2397: /* LHZUX - Load Half-Word and Zero with Update Indexed */
2398: DECLARE_INSN(LHZUX)
2399: {
2400: int rs = bits(insn,21,25);
2401: int ra = bits(insn,16,20);
2402: int rb = bits(insn,11,15);
2403:
1.1.1.3 root 2404: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHZ,ra,rb,rs,1);
1.1 root 2405: return(0);
2406: }
2407:
2408: /* LHZX - Load Half-Word and Zero Indexed */
2409: DECLARE_INSN(LHZX)
2410: {
2411: int rs = bits(insn,21,25);
2412: int ra = bits(insn,16,20);
2413: int rb = bits(insn,11,15);
2414:
1.1.1.3 root 2415: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LHZ,ra,rb,rs,0);
1.1 root 2416: return(0);
2417: }
2418:
2419: /* LWZ - Load Word and Zero */
2420: DECLARE_INSN(LWZ)
2421: {
2422: int rs = bits(insn,21,25);
2423: int ra = bits(insn,16,20);
2424: m_uint16_t offset = bits(insn,0,15);
2425:
2426: //ppc32_emit_memop(b,PPC_MEMOP_LWZ,ra,offset,rs,0);
1.1.1.3 root 2427: ppc32_emit_memop_fast(cpu,b,0,PPC_MEMOP_LWZ,ra,offset,rs,
2428: ppc32_memop_fast_lwz);
1.1 root 2429: return(0);
2430: }
2431:
2432: /* LWZU - Load Word and Zero with Update */
2433: DECLARE_INSN(LWZU)
2434: {
2435: int rs = bits(insn,21,25);
2436: int ra = bits(insn,16,20);
2437: m_uint16_t offset = bits(insn,0,15);
2438:
1.1.1.3 root 2439: ppc32_emit_memop(cpu,b,PPC_MEMOP_LWZ,ra,offset,rs,1);
1.1 root 2440: return(0);
2441: }
2442:
2443: /* LWZUX - Load Word and Zero with Update Indexed */
2444: DECLARE_INSN(LWZUX)
2445: {
2446: int rs = bits(insn,21,25);
2447: int ra = bits(insn,16,20);
2448: int rb = bits(insn,11,15);
2449:
1.1.1.3 root 2450: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LWZ,ra,rb,rs,1);
1.1 root 2451: return(0);
2452: }
2453:
2454: /* LWZX - Load Word and Zero Indexed */
2455: DECLARE_INSN(LWZX)
2456: {
2457: int rs = bits(insn,21,25);
2458: int ra = bits(insn,16,20);
2459: int rb = bits(insn,11,15);
2460:
1.1.1.3 root 2461: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_LWZ,ra,rb,rs,0);
1.1 root 2462: return(0);
2463: }
2464:
2465: /* MCRF - Move Condition Register Field */
2466: DECLARE_INSN(MCRF)
2467: {
2468: int rd = bits(insn,23,25);
2469: int rs = bits(insn,18,20);
1.1.1.3 root 2470: int hreg_t0;
2471: jit_op_t *iop;
1.1 root 2472:
1.1.1.3 root 2473: ppc32_jit_start_hreg_seq(cpu,"mcrf");
2474: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2475: ppc32_op_emit_require_flags(cpu,rs);
2476:
2477: iop = ppc32_op_emit_insn_output(cpu,1,"mcrf");
2478:
2479: /* Load "rs" field in %edx */
2480: amd64_mov_reg_membase(iop->ob_ptr,hreg_t0,
1.1.1.2 root 2481: AMD64_R15,PPC32_CR_FIELD_OFFSET(rs),4);
2482:
2483: /* Store it in "rd" field */
1.1.1.3 root 2484: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,PPC32_CR_FIELD_OFFSET(rd),
2485: hreg_t0,4);
2486:
2487: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2488: return(0);
2489: }
2490:
2491: /* MFCR - Move from Condition Register */
2492: DECLARE_INSN(MFCR)
2493: {
2494: int rd = bits(insn,21,25);
1.1.1.3 root 2495: int hreg_rd,hreg_t0;
2496: jit_op_t *iop;
1.1.1.2 root 2497: int i;
1.1.1.3 root 2498:
2499: ppc32_jit_start_hreg_seq(cpu,"mfcr");
2500: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
2501: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2502: ppc32_op_emit_require_flags(cpu,JIT_OP_PPC_ALL_FLAGS);
2503:
2504: iop = ppc32_op_emit_insn_output(cpu,3,"mfcr");
2505:
2506: amd64_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_rd,hreg_rd);
1.1.1.2 root 2507:
2508: for(i=0;i<8;i++) {
1.1.1.3 root 2509: /* load field in %edx */
2510: amd64_mov_reg_membase(iop->ob_ptr,hreg_t0,
1.1.1.2 root 2511: AMD64_R15,PPC32_CR_FIELD_OFFSET(i),4);
1.1.1.3 root 2512: amd64_shift_reg_imm(iop->ob_ptr,X86_SHL,hreg_rd,4);
2513: amd64_alu_reg_reg(iop->ob_ptr,X86_OR,hreg_rd,hreg_t0);
1.1.1.2 root 2514: }
1.1 root 2515:
1.1.1.3 root 2516: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
2517:
2518: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2519: return(0);
2520: }
2521:
2522: /* MFMSR - Move from Machine State Register */
2523: DECLARE_INSN(MFMSR)
2524: {
2525: int rd = bits(insn,21,25);
1.1.1.3 root 2526: int hreg_rd;
2527: jit_op_t *iop;
2528:
2529: ppc32_jit_start_hreg_seq(cpu,"mfmsr");
2530: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1 root 2531:
1.1.1.3 root 2532: iop = ppc32_op_emit_insn_output(cpu,1,"mfmsr");
2533: amd64_mov_reg_membase(iop->ob_ptr,hreg_rd,
1.1 root 2534: AMD64_R15,OFFSET(cpu_ppc_t,msr),4);
1.1.1.3 root 2535: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
2536:
2537: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2538: return(0);
2539: }
2540:
2541: /* MFSR - Move From Segment Register */
2542: DECLARE_INSN(MFSR)
2543: {
2544: int rd = bits(insn,21,25);
2545: int sr = bits(insn,16,19);
1.1.1.3 root 2546: int hreg_rd;
2547: jit_op_t *iop;
2548:
2549: ppc32_jit_start_hreg_seq(cpu,"mfsr");
2550: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1 root 2551:
1.1.1.3 root 2552: iop = ppc32_op_emit_insn_output(cpu,1,"mfsr");
2553:
2554: amd64_mov_reg_membase(iop->ob_ptr,hreg_rd,
1.1 root 2555: AMD64_R15,(OFFSET(cpu_ppc_t,sr) + (sr << 2)),4);
1.1.1.3 root 2556: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
2557:
2558: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2559: return(0);
2560: }
2561:
2562: /* MTCRF - Move to Condition Register Fields */
2563: DECLARE_INSN(MTCRF)
2564: {
2565: int rs = bits(insn,21,25);
2566: int crm = bits(insn,12,19);
1.1.1.3 root 2567: int hreg_rs,hreg_t0;
2568: jit_op_t *iop;
1.1 root 2569: int i;
2570:
1.1.1.3 root 2571: ppc32_jit_start_hreg_seq(cpu,"mtcrf");
2572: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2573: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2574:
2575: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2576:
1.1.1.4 root 2577: iop = ppc32_op_emit_insn_output(cpu,4,"mtcrf");
1.1.1.2 root 2578:
1.1 root 2579: for(i=0;i<8;i++)
1.1.1.2 root 2580: if (crm & (1 << (7 - i))) {
1.1.1.3 root 2581: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
1.1 root 2582:
1.1.1.2 root 2583: if (i != 7)
1.1.1.3 root 2584: amd64_shift_reg_imm(iop->ob_ptr,X86_SHR,hreg_t0,28 - (i << 2));
1.1 root 2585:
1.1.1.3 root 2586: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x0F);
2587: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,PPC32_CR_FIELD_OFFSET(i),
2588: hreg_t0,4);
1.1.1.2 root 2589: }
1.1 root 2590:
1.1.1.3 root 2591: ppc32_op_emit_basic_opcode(cpu,JIT_OP_TRASH_FLAGS);
2592:
2593: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2594: return(0);
2595: }
2596:
2597: /* MULHW - Multiply High Word */
2598: DECLARE_INSN(MULHW)
2599: {
2600: int rd = bits(insn,21,25);
2601: int ra = bits(insn,16,20);
2602: int rb = bits(insn,11,15);
1.1.1.3 root 2603: int hreg_rb;
2604: jit_op_t *iop;
1.1 root 2605:
1.1.1.3 root 2606: ppc32_jit_start_hreg_seq(cpu,"mulhw");
2607: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RAX);
2608: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
2609: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2610:
2611: ppc32_op_emit_load_gpr(cpu,AMD64_RAX,ra);
2612: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2613:
2614: /* rd = hi(ra * rb) */
2615: iop = ppc32_op_emit_insn_output(cpu,2,"mulhw");
2616: amd64_mul_reg_size(iop->ob_ptr,hreg_rb,1,4);
1.1 root 2617:
1.1.1.3 root 2618: if (insn & 1)
2619: amd64_test_reg_reg_size(iop->ob_ptr,AMD64_RDX,AMD64_RDX,4);
2620:
2621: ppc32_op_emit_store_gpr(cpu,rd,AMD64_RDX);
1.1 root 2622:
1.1.1.3 root 2623: if (insn & 1)
2624: ppc32_op_emit_update_flags(cpu,0,TRUE);
2625:
2626: /* edx:eax are directly modified: throw them */
2627: ppc32_op_emit_alter_host_reg(cpu,AMD64_RAX);
2628: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
2629:
2630: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2631: return(0);
2632: }
2633:
2634: /* MULHWU - Multiply High Word Unsigned */
2635: DECLARE_INSN(MULHWU)
2636: {
2637: int rd = bits(insn,21,25);
2638: int ra = bits(insn,16,20);
2639: int rb = bits(insn,11,15);
1.1.1.3 root 2640: int hreg_rb;
2641: jit_op_t *iop;
1.1 root 2642:
1.1.1.3 root 2643: ppc32_jit_start_hreg_seq(cpu,"mulhwu");
2644: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RAX);
2645: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
2646: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2647:
2648: ppc32_op_emit_load_gpr(cpu,AMD64_RAX,ra);
2649: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2650:
2651: /* rd = hi(ra * rb) */
2652: iop = ppc32_op_emit_insn_output(cpu,2,"mulhwu");
2653: amd64_mul_reg_size(iop->ob_ptr,hreg_rb,0,4);
1.1 root 2654:
1.1.1.3 root 2655: if (insn & 1)
2656: amd64_test_reg_reg_size(iop->ob_ptr,AMD64_RDX,AMD64_RDX,4);
1.1 root 2657:
1.1.1.3 root 2658: ppc32_op_emit_store_gpr(cpu,rd,AMD64_RDX);
2659:
2660: if (insn & 1)
2661: ppc32_op_emit_update_flags(cpu,0,TRUE);
2662:
2663: /* edx:eax are directly modified: throw them */
2664: ppc32_op_emit_alter_host_reg(cpu,AMD64_RAX);
2665: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
2666:
2667: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2668: return(0);
2669: }
2670:
2671: /* MULLI - Multiply Low Immediate */
2672: DECLARE_INSN(MULLI)
2673: {
2674: int rd = bits(insn,21,25);
2675: int ra = bits(insn,16,20);
2676: m_uint32_t imm = bits(insn,0,15);
1.1.1.3 root 2677: int hreg_t0;
2678: jit_op_t *iop;
2679:
2680: ppc32_jit_start_hreg_seq(cpu,"mulli");
2681: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RAX);
2682: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
2683: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2684:
2685: ppc32_op_emit_load_gpr(cpu,AMD64_RAX,ra);
1.1 root 2686:
1.1.1.3 root 2687: /* rd = lo(ra * imm) */
2688: iop = ppc32_op_emit_insn_output(cpu,2,"mulli");
1.1 root 2689:
1.1.1.3 root 2690: ppc32_load_imm(&iop->ob_ptr,hreg_t0,sign_extend_32(imm,16));
2691: amd64_mul_reg_size(iop->ob_ptr,hreg_t0,1,4);
2692: ppc32_op_emit_store_gpr(cpu,rd,AMD64_RAX);
2693:
2694: /* edx:eax are directly modified: throw them */
2695: ppc32_op_emit_alter_host_reg(cpu,AMD64_RAX);
2696: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
2697:
2698: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2699: return(0);
2700: }
2701:
2702: /* MULLW - Multiply Low Word */
2703: DECLARE_INSN(MULLW)
2704: {
2705: int rd = bits(insn,21,25);
2706: int ra = bits(insn,16,20);
2707: int rb = bits(insn,11,15);
1.1.1.3 root 2708: int hreg_rb;
2709: jit_op_t *iop;
1.1 root 2710:
1.1.1.3 root 2711: ppc32_jit_start_hreg_seq(cpu,"mullw");
2712: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RAX);
2713: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RDX);
2714: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2715:
2716: ppc32_op_emit_load_gpr(cpu,AMD64_RAX,ra);
2717: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2718:
2719: /* rd = lo(ra * rb) */
2720: iop = ppc32_op_emit_insn_output(cpu,2,"mullw");
2721: amd64_mul_reg_size(iop->ob_ptr,hreg_rb,1,4);
1.1 root 2722:
1.1.1.3 root 2723: if (insn & 1)
2724: amd64_test_reg_reg_size(iop->ob_ptr,AMD64_RAX,AMD64_RAX,4);
2725:
2726: ppc32_op_emit_store_gpr(cpu,rd,AMD64_RAX);
2727:
2728: if (insn & 1)
2729: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 2730:
1.1.1.3 root 2731: /* edx:eax are directly modified: throw them */
2732: ppc32_op_emit_alter_host_reg(cpu,AMD64_RAX);
2733: ppc32_op_emit_alter_host_reg(cpu,AMD64_RDX);
2734:
2735: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2736: return(0);
2737: }
2738:
2739: /* NAND */
2740: DECLARE_INSN(NAND)
2741: {
2742: int rs = bits(insn,21,25);
2743: int ra = bits(insn,16,20);
2744: int rb = bits(insn,11,15);
1.1.1.3 root 2745: int hreg_rs,hreg_ra,hreg_rb;
2746: jit_op_t *iop;
1.1 root 2747:
2748: /* $ra = ~($rs & $rb) */
1.1.1.3 root 2749: ppc32_jit_start_hreg_seq(cpu,"nand");
2750: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2751: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2752: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2753:
2754: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2755: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2756:
2757: iop = ppc32_op_emit_insn_output(cpu,2,"nand");
2758:
2759: if (ra == rs)
2760: amd64_alu_reg_reg_size(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb,4);
2761: else if (ra == rb)
2762: amd64_alu_reg_reg_size(iop->ob_ptr,X86_AND,hreg_ra,hreg_rs,4);
2763: else {
2764: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2765: amd64_alu_reg_reg_size(iop->ob_ptr,X86_AND,hreg_ra,hreg_rb,4);
1.1 root 2766: }
2767:
1.1.1.3 root 2768: amd64_not_reg(iop->ob_ptr,hreg_ra);
2769:
2770: if (insn & 1)
2771: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
2772:
2773: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2774:
2775: if (insn & 1)
2776: ppc32_op_emit_update_flags(cpu,0,TRUE);
2777:
2778: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2779: return(0);
2780: }
2781:
2782: /* NEG */
2783: DECLARE_INSN(NEG)
2784: {
2785: int rd = bits(insn,21,25);
2786: int ra = bits(insn,16,20);
1.1.1.3 root 2787: int hreg_rd,hreg_ra;
2788: jit_op_t *iop;
1.1 root 2789:
1.1.1.3 root 2790: /* $rd = neg($ra) */
2791: ppc32_jit_start_hreg_seq(cpu,"neg");
2792: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2793: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1 root 2794:
1.1.1.3 root 2795: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
2796:
2797: iop = ppc32_op_emit_insn_output(cpu,1,"neg");
2798:
2799: if (rd != ra)
2800: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_ra,4);
2801:
2802: amd64_neg_reg(iop->ob_ptr,hreg_rd);
2803:
2804: if (insn & 1)
2805: amd64_test_reg_reg_size(iop->ob_ptr,hreg_rd,hreg_rd,4);
2806:
2807: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
2808:
2809: if (insn & 1)
2810: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 2811:
1.1.1.3 root 2812: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2813: return(0);
2814: }
2815:
2816: /* NOR */
2817: DECLARE_INSN(NOR)
2818: {
2819: int rs = bits(insn,21,25);
2820: int ra = bits(insn,16,20);
2821: int rb = bits(insn,11,15);
1.1.1.3 root 2822: int hreg_rs,hreg_ra,hreg_rb;
2823: jit_op_t *iop;
1.1 root 2824:
2825: /* $ra = ~($rs | $rb) */
1.1.1.3 root 2826: ppc32_jit_start_hreg_seq(cpu,"nor");
2827: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2828: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2829: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2830:
2831: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2832: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2833:
2834: iop = ppc32_op_emit_insn_output(cpu,2,"nor");
2835:
2836: if (ra == rs)
2837: amd64_alu_reg_reg_size(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb,4);
2838: else if (ra == rb)
2839: amd64_alu_reg_reg_size(iop->ob_ptr,X86_OR,hreg_ra,hreg_rs,4);
2840: else {
2841: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2842: amd64_alu_reg_reg_size(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb,4);
1.1 root 2843: }
2844:
1.1.1.3 root 2845: amd64_not_reg(iop->ob_ptr,hreg_ra);
2846:
2847: if (insn & 1)
2848: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
2849:
2850: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2851:
2852: if (insn & 1)
2853: ppc32_op_emit_update_flags(cpu,0,TRUE);
2854:
2855: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2856: return(0);
2857: }
2858:
2859: /* OR */
2860: DECLARE_INSN(OR)
2861: {
2862: int rs = bits(insn,21,25);
2863: int ra = bits(insn,16,20);
2864: int rb = bits(insn,11,15);
1.1.1.3 root 2865: int hreg_rs,hreg_ra,hreg_rb;
2866: jit_op_t *iop;
1.1 root 2867:
1.1.1.3 root 2868: /* $ra = $rs | $rb */
2869: ppc32_jit_start_hreg_seq(cpu,"or");
2870: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2871: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2872: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
1.1 root 2873:
1.1.1.3 root 2874: /* special optimization for move/nop operation */
2875: if (rs == rb) {
2876: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2877: iop = ppc32_op_emit_insn_output(cpu,2,"or");
1.1 root 2878:
1.1.1.3 root 2879: if (ra != rs)
2880: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1.1 root 2881:
1.1.1.3 root 2882: if (insn & 1)
2883: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
2884:
2885: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2886:
2887: if (insn & 1)
2888: ppc32_op_emit_update_flags(cpu,0,TRUE);
2889:
2890: ppc32_jit_close_hreg_seq(cpu);
2891: return(0);
1.1 root 2892: }
2893:
1.1.1.3 root 2894: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2895: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2896:
2897: iop = ppc32_op_emit_insn_output(cpu,2,"or");
2898:
2899: if (ra == rs) {
2900: amd64_alu_reg_reg_size(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb,4);
2901: } else if (ra == rb)
2902: amd64_alu_reg_reg_size(iop->ob_ptr,X86_OR,hreg_ra,hreg_rs,4);
2903: else {
2904: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2905: amd64_alu_reg_reg_size(iop->ob_ptr,X86_OR,hreg_ra,hreg_rb,4);
2906: }
2907:
2908: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2909:
2910: if (insn & 1)
2911: ppc32_op_emit_update_flags(cpu,0,TRUE);
2912:
2913: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2914: return(0);
2915: }
2916:
2917: /* OR with Complement */
2918: DECLARE_INSN(ORC)
2919: {
2920: int rs = bits(insn,21,25);
2921: int ra = bits(insn,16,20);
2922: int rb = bits(insn,11,15);
1.1.1.3 root 2923: int hreg_rs,hreg_ra,hreg_rb,hreg_t0;
2924: jit_op_t *iop;
2925:
2926: /* $ra = $rs & ~$rb */
2927: ppc32_jit_start_hreg_seq(cpu,"orc");
2928: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2929: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2930: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
2931:
2932: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2933: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
2934:
2935: iop = ppc32_op_emit_insn_output(cpu,1,"orc");
2936:
2937: /* $t0 = ~$rb */
2938: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
2939: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rb,4);
2940: amd64_not_reg(iop->ob_ptr,hreg_t0);
2941:
2942: /* $ra = $rs | $t0 */
2943: if (ra == rs)
2944: amd64_alu_reg_reg_size(iop->ob_ptr,X86_OR,hreg_ra,hreg_t0,4);
2945: else {
2946: amd64_alu_reg_reg_size(iop->ob_ptr,X86_OR,hreg_t0,hreg_rs,4);
2947: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
2948: }
1.1 root 2949:
1.1.1.3 root 2950: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1 root 2951:
2952: if (insn & 1)
1.1.1.3 root 2953: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 2954:
1.1.1.3 root 2955: ppc32_jit_close_hreg_seq(cpu);
1.1 root 2956: return(0);
2957: }
2958:
2959: /* OR Immediate */
2960: DECLARE_INSN(ORI)
2961: {
2962: int rs = bits(insn,21,25);
2963: int ra = bits(insn,16,20);
2964: m_uint16_t imm = bits(insn,0,15);
1.1.1.3 root 2965: m_uint32_t tmp = imm;
2966: int hreg_rs,hreg_ra;
2967: jit_op_t *iop;
1.1 root 2968:
2969: /* $ra = $rs | imm */
1.1.1.3 root 2970: ppc32_jit_start_hreg_seq(cpu,"ori");
2971: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
2972: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
2973:
2974: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
2975:
2976: iop = ppc32_op_emit_insn_output(cpu,1,"ori");
2977:
2978: if (ra != rs)
2979: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
2980:
2981: amd64_alu_reg_imm_size(iop->ob_ptr,X86_OR,hreg_ra,tmp,4);
2982: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
2983:
2984: ppc32_jit_close_hreg_seq(cpu);
2985: return(0);
1.1 root 2986: }
2987:
2988: /* OR Immediate Shifted */
2989: DECLARE_INSN(ORIS)
2990: {
2991: int rs = bits(insn,21,25);
2992: int ra = bits(insn,16,20);
1.1.1.3 root 2993: m_uint16_t imm = bits(insn,0,15);
2994: m_uint32_t tmp = imm << 16;
2995: int hreg_rs,hreg_ra;
2996: jit_op_t *iop;
1.1 root 2997:
1.1.1.3 root 2998: /* $ra = $rs | imm */
2999: ppc32_jit_start_hreg_seq(cpu,"oris");
3000: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3001: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3002:
3003: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3004:
3005: iop = ppc32_op_emit_insn_output(cpu,1,"oris");
3006:
3007: if (ra != rs)
3008: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3009:
3010: amd64_alu_reg_imm_size(iop->ob_ptr,X86_OR,hreg_ra,tmp,4);
3011: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3012:
3013: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3014: return(0);
3015: }
3016:
3017: /* RLWIMI - Rotate Left Word Immediate then Mask Insert */
3018: DECLARE_INSN(RLWIMI)
3019: {
3020: int rs = bits(insn,21,25);
3021: int ra = bits(insn,16,20);
3022: int sh = bits(insn,11,15);
3023: int mb = bits(insn,6,10);
3024: int me = bits(insn,1,5);
3025: register m_uint32_t mask;
1.1.1.3 root 3026: int hreg_rs,hreg_ra,hreg_t0;
3027: jit_op_t *iop;
3028:
3029: ppc32_jit_start_hreg_seq(cpu,"rlwimi");
3030: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3031: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3032: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3033:
3034: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3035: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3036:
1.1 root 3037: mask = ppc32_rotate_mask(mb,me);
3038:
1.1.1.3 root 3039: iop = ppc32_op_emit_insn_output(cpu,2,"rlwimi");
3040:
3041: /* Apply inverse mask to $ra */
1.1 root 3042: if (mask != 0)
1.1.1.3 root 3043: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,~mask);
1.1 root 3044:
1.1.1.3 root 3045: /* Rotate $rs of "sh" bits and apply the mask */
3046: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
1.1 root 3047:
3048: if (sh != 0)
1.1.1.3 root 3049: amd64_shift_reg_imm_size(iop->ob_ptr,X86_ROL,hreg_t0,sh,4);
1.1 root 3050:
3051: if (mask != 0xFFFFFFFF)
1.1.1.3 root 3052: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,mask);
1.1 root 3053:
3054: /* Store the result */
1.1.1.3 root 3055: amd64_alu_reg_reg_size(iop->ob_ptr,X86_OR,hreg_ra,hreg_t0,4);
3056: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1 root 3057:
3058: if (insn & 1)
1.1.1.3 root 3059: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 3060:
1.1.1.3 root 3061: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3062: return(0);
3063: }
3064:
3065: /* RLWINM - Rotate Left Word Immediate AND with Mask */
3066: DECLARE_INSN(RLWINM)
3067: {
3068: int rs = bits(insn,21,25);
3069: int ra = bits(insn,16,20);
3070: int sh = bits(insn,11,15);
3071: int mb = bits(insn,6,10);
3072: int me = bits(insn,1,5);
3073: register m_uint32_t mask;
1.1.1.3 root 3074: int hreg_rs,hreg_ra;
3075: jit_op_t *iop;
3076:
3077: ppc32_jit_start_hreg_seq(cpu,"rlwinm");
3078: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3079: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3080:
3081: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1.1 root 3082:
1.1.1.3 root 3083: iop = ppc32_op_emit_insn_output(cpu,2,"rlwinm");
3084:
3085: /* Rotate $rs of "sh" bits and apply the mask */
1.1 root 3086: mask = ppc32_rotate_mask(mb,me);
3087:
1.1.1.3 root 3088: if (rs != ra)
3089: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1.1 root 3090:
3091: if (sh != 0)
1.1.1.3 root 3092: amd64_shift_reg_imm_size(iop->ob_ptr,X86_ROL,hreg_ra,sh,4);
1.1 root 3093:
3094: if (mask != 0xFFFFFFFF)
1.1.1.3 root 3095: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_ra,mask);
1.1 root 3096:
1.1.1.3 root 3097: if (insn & 1)
3098: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
1.1 root 3099:
1.1.1.3 root 3100: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3101:
3102: if (insn & 1)
3103: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 3104:
1.1.1.3 root 3105: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3106: return(0);
3107: }
3108:
3109: /* RLWNM - Rotate Left Word then Mask Insert */
3110: DECLARE_INSN(RLWNM)
3111: {
3112: int rs = bits(insn,21,25);
3113: int ra = bits(insn,16,20);
3114: int rb = bits(insn,11,15);
3115: int mb = bits(insn,6,10);
3116: int me = bits(insn,1,5);
3117: register m_uint32_t mask;
1.1.1.3 root 3118: int hreg_rs,hreg_ra,hreg_t0;
3119: jit_op_t *iop;
1.1 root 3120:
1.1.1.3 root 3121: /* ecx is directly modified: throw it */
3122: ppc32_op_emit_alter_host_reg(cpu,AMD64_RCX);
3123:
3124: ppc32_jit_start_hreg_seq(cpu,"rlwnm");
3125: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RCX);
3126:
3127: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3128: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3129: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3130:
3131: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3132: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3133: ppc32_op_emit_load_gpr(cpu,AMD64_RCX,rb);
3134:
3135: iop = ppc32_op_emit_insn_output(cpu,2,"rlwnm");
1.1 root 3136:
3137: /* Load the shift register ("sh") */
1.1.1.3 root 3138: mask = ppc32_rotate_mask(mb,me);
3139:
3140: /* Rotate $rs and apply the mask */
3141: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
1.1 root 3142:
1.1.1.3 root 3143: amd64_shift_reg_size(iop->ob_ptr,X86_ROL,hreg_t0,4);
1.1 root 3144:
3145: if (mask != 0xFFFFFFFF)
1.1.1.3 root 3146: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,mask);
1.1 root 3147:
1.1.1.3 root 3148: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_t0,4);
1.1 root 3149:
1.1.1.3 root 3150: if (insn & 1)
3151: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
3152:
3153: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3154:
3155: if (insn & 1)
3156: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 3157:
1.1.1.3 root 3158: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3159: return(0);
3160: }
3161:
3162: /* Shift Left Word */
3163: DECLARE_INSN(SLW)
3164: {
3165: int rs = bits(insn,21,25);
3166: int ra = bits(insn,16,20);
3167: int rb = bits(insn,11,15);
1.1.1.3 root 3168: int hreg_rs,hreg_ra;
3169: jit_op_t *iop;
1.1 root 3170:
1.1.1.3 root 3171: /* ecx is directly modified: throw it */
3172: ppc32_op_emit_alter_host_reg(cpu,AMD64_RCX);
1.1 root 3173:
1.1.1.3 root 3174: ppc32_jit_start_hreg_seq(cpu,"slw");
3175: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RCX);
3176: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3177: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1 root 3178:
1.1.1.3 root 3179: /* $ra = $rs << $rb. If count >= 32, then null result */
3180: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3181: ppc32_op_emit_load_gpr(cpu,AMD64_RCX,rb);
1.1 root 3182:
1.1.1.3 root 3183: iop = ppc32_op_emit_insn_output(cpu,3,"slw");
3184:
3185: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,AMD64_RCX,0x3f);
1.1 root 3186:
1.1.1.3 root 3187: if (ra != rs)
3188: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3189:
3190: amd64_shift_reg(iop->ob_ptr,X86_SHL,hreg_ra);
3191:
3192: /* store the result */
3193: if (insn & 1)
3194: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
3195:
3196: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3197:
3198: if (insn & 1)
3199: ppc32_op_emit_update_flags(cpu,0,TRUE);
3200:
3201: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3202: return(0);
3203: }
3204:
3205: /* SRAWI - Shift Right Algebraic Word Immediate */
3206: DECLARE_INSN(SRAWI)
3207: {
3208: int rs = bits(insn,21,25);
3209: int ra = bits(insn,16,20);
3210: int sh = bits(insn,11,15);
3211: register m_uint32_t mask;
1.1.1.3 root 3212: int hreg_rs,hreg_ra,hreg_t0;
3213: jit_op_t *iop;
1.1 root 3214:
1.1.1.3 root 3215: ppc32_jit_start_hreg_seq(cpu,"srawi");
3216: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3217: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3218: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1 root 3219:
3220: /* $ra = (int32)$rs >> sh */
1.1.1.3 root 3221: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
1.1 root 3222:
1.1.1.3 root 3223: iop = ppc32_op_emit_insn_output(cpu,3,"srawi");
3224: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rs,4);
3225:
3226: if (ra != rs)
3227: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3228: amd64_shift_reg_imm_size(iop->ob_ptr,X86_SAR,hreg_ra,sh,4);
3229:
3230: /* set XER_CA depending on the result */
3231: mask = ~(0xFFFFFFFFU << sh) | 0x80000000;
3232:
3233: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,mask);
3234: amd64_alu_reg_imm_size(iop->ob_ptr,X86_CMP,hreg_t0,0x80000000,4);
3235: amd64_set_reg(iop->ob_ptr,X86_CC_A,hreg_t0,FALSE);
3236: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,hreg_t0,0x1);
3237: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
3238: hreg_t0,4);
1.1 root 3239:
1.1.1.3 root 3240: if (insn & 1)
3241: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
3242:
3243: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3244:
3245: if (insn & 1)
3246: ppc32_op_emit_update_flags(cpu,0,TRUE);
3247:
3248: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3249: return(0);
3250: }
3251:
3252: /* Shift Right Word */
3253: DECLARE_INSN(SRW)
3254: {
3255: int rs = bits(insn,21,25);
3256: int ra = bits(insn,16,20);
3257: int rb = bits(insn,11,15);
1.1.1.3 root 3258: int hreg_rs,hreg_ra;
3259: jit_op_t *iop;
1.1 root 3260:
1.1.1.3 root 3261: /* ecx is directly modified: throw it */
3262: ppc32_op_emit_alter_host_reg(cpu,AMD64_RCX);
1.1 root 3263:
1.1.1.3 root 3264: ppc32_jit_start_hreg_seq(cpu,"srw");
3265: ppc32_jit_alloc_hreg_forced(cpu,AMD64_RCX);
3266: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3267: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
1.1 root 3268:
1.1.1.3 root 3269: /* $ra = $rs >> $rb. If count >= 32, then null result */
3270: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3271: ppc32_op_emit_load_gpr(cpu,AMD64_RCX,rb);
1.1 root 3272:
1.1.1.3 root 3273: iop = ppc32_op_emit_insn_output(cpu,3,"srw");
3274:
3275: amd64_alu_reg_imm(iop->ob_ptr,X86_AND,AMD64_RCX,0x3f);
3276:
3277: if (ra != rs)
3278: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3279:
3280: amd64_shift_reg(iop->ob_ptr,X86_SHR,hreg_ra);
3281:
3282: /* store the result */
3283: if (insn & 1)
3284: amd64_test_reg_reg_size(iop->ob_ptr,hreg_ra,hreg_ra,4);
3285:
3286: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3287:
3288: if (insn & 1)
3289: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 3290:
1.1.1.3 root 3291: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3292: return(0);
3293: }
3294:
3295: /* STB - Store Byte */
3296: DECLARE_INSN(STB)
3297: {
3298: int rs = bits(insn,21,25);
3299: int ra = bits(insn,16,20);
3300: m_uint16_t offset = bits(insn,0,15);
3301:
3302: //ppc32_emit_memop(b,PPC_MEMOP_STB,ra,offset,rs,0);
1.1.1.3 root 3303: ppc32_emit_memop_fast(cpu,b,1,PPC_MEMOP_STB,ra,offset,rs,
3304: ppc32_memop_fast_stb);
1.1 root 3305: return(0);
3306: }
3307:
3308: /* STBU - Store Byte with Update */
3309: DECLARE_INSN(STBU)
3310: {
3311: int rs = bits(insn,21,25);
3312: int ra = bits(insn,16,20);
3313: m_uint16_t offset = bits(insn,0,15);
3314:
1.1.1.3 root 3315: ppc32_emit_memop(cpu,b,PPC_MEMOP_STB,ra,offset,rs,1);
1.1 root 3316: return(0);
3317: }
3318:
3319: /* STBUX - Store Byte with Update Indexed */
3320: DECLARE_INSN(STBUX)
3321: {
3322: int rs = bits(insn,21,25);
3323: int ra = bits(insn,16,20);
3324: int rb = bits(insn,11,15);
3325:
1.1.1.3 root 3326: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STB,ra,rb,rs,1);
1.1 root 3327: return(0);
3328: }
3329:
3330: /* STBUX - Store Byte Indexed */
3331: DECLARE_INSN(STBX)
3332: {
3333: int rs = bits(insn,21,25);
3334: int ra = bits(insn,16,20);
3335: int rb = bits(insn,11,15);
3336:
1.1.1.3 root 3337: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STB,ra,rb,rs,0);
1.1 root 3338: return(0);
3339: }
3340:
3341: /* STH - Store Half-Word */
3342: DECLARE_INSN(STH)
3343: {
3344: int rs = bits(insn,21,25);
3345: int ra = bits(insn,16,20);
3346: m_uint16_t offset = bits(insn,0,15);
3347:
1.1.1.3 root 3348: ppc32_emit_memop(cpu,b,PPC_MEMOP_STH,ra,offset,rs,0);
1.1 root 3349: return(0);
3350: }
3351:
3352: /* STHU - Store Half-Word with Update */
3353: DECLARE_INSN(STHU)
3354: {
3355: int rs = bits(insn,21,25);
3356: int ra = bits(insn,16,20);
3357: m_uint16_t offset = bits(insn,0,15);
3358:
1.1.1.3 root 3359: ppc32_emit_memop(cpu,b,PPC_MEMOP_STH,ra,offset,rs,1);
1.1 root 3360: return(0);
3361: }
3362:
3363: /* STHUX - Store Half-Word with Update Indexed */
3364: DECLARE_INSN(STHUX)
3365: {
3366: int rs = bits(insn,21,25);
3367: int ra = bits(insn,16,20);
3368: int rb = bits(insn,11,15);
3369:
1.1.1.3 root 3370: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STH,ra,rb,rs,1);
1.1 root 3371: return(0);
3372: }
3373:
3374: /* STHUX - Store Half-Word Indexed */
3375: DECLARE_INSN(STHX)
3376: {
3377: int rs = bits(insn,21,25);
3378: int ra = bits(insn,16,20);
3379: int rb = bits(insn,11,15);
3380:
1.1.1.3 root 3381: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STH,ra,rb,rs,0);
1.1 root 3382: return(0);
3383: }
3384:
3385: /* STW - Store Word */
3386: DECLARE_INSN(STW)
3387: {
3388: int rs = bits(insn,21,25);
3389: int ra = bits(insn,16,20);
3390: m_uint16_t offset = bits(insn,0,15);
3391:
3392: //ppc32_emit_memop(b,PPC_MEMOP_STW,ra,offset,rs,0);
1.1.1.3 root 3393: ppc32_emit_memop_fast(cpu,b,1,PPC_MEMOP_STW,ra,offset,rs,
3394: ppc32_memop_fast_stw);
1.1 root 3395: return(0);
3396: }
3397:
3398: /* STWU - Store Word with Update */
3399: DECLARE_INSN(STWU)
3400: {
3401: int rs = bits(insn,21,25);
3402: int ra = bits(insn,16,20);
3403: m_uint16_t offset = bits(insn,0,15);
3404:
1.1.1.3 root 3405: ppc32_emit_memop(cpu,b,PPC_MEMOP_STW,ra,offset,rs,1);
1.1 root 3406: return(0);
3407: }
3408:
3409: /* STWUX - Store Word with Update Indexed */
3410: DECLARE_INSN(STWUX)
3411: {
3412: int rs = bits(insn,21,25);
3413: int ra = bits(insn,16,20);
3414: int rb = bits(insn,11,15);
3415:
1.1.1.3 root 3416: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STW,ra,rb,rs,1);
1.1 root 3417: return(0);
3418: }
3419:
3420: /* STWUX - Store Word Indexed */
3421: DECLARE_INSN(STWX)
3422: {
3423: int rs = bits(insn,21,25);
3424: int ra = bits(insn,16,20);
3425: int rb = bits(insn,11,15);
3426:
1.1.1.3 root 3427: ppc32_emit_memop_idx(cpu,b,PPC_MEMOP_STW,ra,rb,rs,0);
1.1 root 3428: return(0);
3429: }
3430:
3431: /* SUBF - Subtract From */
3432: DECLARE_INSN(SUBF)
3433: {
3434: int rd = bits(insn,21,25);
3435: int ra = bits(insn,16,20);
3436: int rb = bits(insn,11,15);
1.1.1.3 root 3437: int hreg_rd,hreg_ra,hreg_rb,hreg_t0;
3438: jit_op_t *iop;
3439:
3440: /* $rd = $rb - $ra */
3441: ppc32_jit_start_hreg_seq(cpu,"subf");
3442: hreg_t0 = ppc32_jit_get_tmp_hreg(cpu);
3443:
3444: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
3445: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3446: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
3447:
3448: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3449: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
3450:
3451: iop = ppc32_op_emit_insn_output(cpu,2,"subf");
3452:
3453: if (rd == rb)
3454: amd64_alu_reg_reg_size(iop->ob_ptr,X86_SUB,hreg_rd,hreg_ra,4);
3455: else if (rd == ra) {
3456: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_rb,4);
3457: amd64_alu_reg_reg_size(iop->ob_ptr,X86_SUB,hreg_t0,hreg_ra,4);
3458: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
3459: } else {
3460: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_rb,4);
3461: amd64_alu_reg_reg_size(iop->ob_ptr,X86_SUB,hreg_rd,hreg_ra,4);
3462: }
1.1 root 3463:
1.1.1.3 root 3464: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1 root 3465:
3466: if (insn & 1)
1.1.1.3 root 3467: ppc32_op_emit_update_flags(cpu,0,TRUE);
3468:
3469: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3470: return(0);
3471: }
3472:
3473: /* SUBFC - Subtract From Carrying */
3474: DECLARE_INSN(SUBFC)
3475: {
3476: int rd = bits(insn,21,25);
3477: int ra = bits(insn,16,20);
3478: int rb = bits(insn,11,15);
1.1.1.3 root 3479: int hreg_ra,hreg_rb,hreg_rd,hreg_t0,hreg_t1;
3480: jit_op_t *iop;
1.1 root 3481:
1.1.1.3 root 3482: /* $rd = ~$ra + 1 + $rb */
3483: ppc32_jit_start_hreg_seq(cpu,"subfc");
3484: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3485: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
3486: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
3487:
3488: hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
3489: hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
3490:
3491: ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
3492: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3493: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
3494:
3495: iop = ppc32_op_emit_insn_output(cpu,3,"subfc");
3496:
3497: amd64_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
3498:
3499: /* $t0 = ~$ra + 1 */
3500: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
3501: amd64_not_reg(iop->ob_ptr,hreg_t0);
3502: amd64_alu_reg_imm_size(iop->ob_ptr,X86_ADD,hreg_t0,1,4);
3503: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3504: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
3505: hreg_t1,4);
3506:
3507: /* $t0 += $rb */
3508: amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_t0,hreg_rb,4);
3509: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3510: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
3511: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
3512: hreg_t1,4);
1.1 root 3513:
1.1.1.3 root 3514: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
1.1 root 3515:
1.1.1.3 root 3516: if (insn & 1)
3517: amd64_test_reg_reg_size(iop->ob_ptr,hreg_rd,hreg_rd,4);
1.1 root 3518:
1.1.1.3 root 3519: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1 root 3520:
3521: /* update cr0 */
1.1.1.3 root 3522: if (insn & 1)
1.1 root 3523: ppc32_update_cr0(b);
3524:
1.1.1.3 root 3525: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3526: return(0);
3527: }
3528:
3529: /* SUBFE - Subtract From Extended */
3530: DECLARE_INSN(SUBFE)
3531: {
3532: int rd = bits(insn,21,25);
3533: int ra = bits(insn,16,20);
3534: int rb = bits(insn,11,15);
1.1.1.3 root 3535: int hreg_ra,hreg_rb,hreg_rd,hreg_t0,hreg_t1;
3536: jit_op_t *iop;
1.1 root 3537:
1.1.1.3 root 3538: /* $rd = ~$ra + $carry (xer_ca) + $rb */
3539: ppc32_jit_start_hreg_seq(cpu,"subfe");
3540: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3541: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
3542: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
3543:
3544: hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
3545: hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
3546:
3547: ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
3548: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
3549: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
3550:
3551: iop = ppc32_op_emit_insn_output(cpu,3,"subfe");
3552:
3553: amd64_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
3554:
3555: /* $t0 = ~$ra + $carry */
3556: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
3557: amd64_not_reg(iop->ob_ptr,hreg_t0);
3558: amd64_alu_reg_membase_size(iop->ob_ptr,X86_ADD,hreg_t0,
1.1 root 3559: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),4);
3560:
1.1.1.3 root 3561: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3562: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
3563: hreg_t1,4);
3564:
3565: /* $t0 += $rb */
3566: amd64_alu_reg_reg_size(iop->ob_ptr,X86_ADD,hreg_t0,hreg_rb,4);
3567: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3568: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
3569: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
3570: hreg_t1,4);
1.1 root 3571:
1.1.1.3 root 3572: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
1.1 root 3573:
1.1.1.3 root 3574: if (insn & 1)
3575: amd64_test_reg_reg_size(iop->ob_ptr,hreg_rd,hreg_rd,4);
3576:
3577: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
1.1 root 3578:
3579: /* update cr0 */
1.1.1.3 root 3580: if (insn & 1)
1.1 root 3581: ppc32_update_cr0(b);
3582:
1.1.1.3 root 3583: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3584: return(0);
3585: }
3586:
3587: /* SUBFIC - Subtract From Immediate Carrying */
3588: DECLARE_INSN(SUBFIC)
3589: {
3590: int rd = bits(insn,21,25);
3591: int ra = bits(insn,16,20);
3592: m_uint16_t imm = bits(insn,0,15);
3593: m_uint32_t tmp = sign_extend_32(imm,16);
1.1.1.3 root 3594: int hreg_ra,hreg_rd,hreg_t0,hreg_t1;
3595: jit_op_t *iop;
1.1 root 3596:
1.1.1.3 root 3597: /* $rd = ~$ra + 1 + sign_extend(imm,16) */
3598: ppc32_jit_start_hreg_seq(cpu,"subfic");
3599: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3600: hreg_rd = ppc32_jit_alloc_hreg(cpu,rd);
1.1 root 3601:
1.1.1.3 root 3602: hreg_t0 = ppc32_jit_alloc_hreg(cpu,-1);
3603: hreg_t1 = ppc32_jit_get_tmp_hreg(cpu);
1.1 root 3604:
1.1.1.3 root 3605: ppc32_op_emit_alter_host_reg(cpu,hreg_t0);
3606: ppc32_op_emit_load_gpr(cpu,hreg_ra,ra);
1.1 root 3607:
1.1.1.3 root 3608: iop = ppc32_op_emit_insn_output(cpu,3,"subfic");
3609:
3610: amd64_alu_reg_reg(iop->ob_ptr,X86_XOR,hreg_t1,hreg_t1);
3611:
3612: /* $t0 = ~$ra + 1 */
3613: amd64_mov_reg_reg(iop->ob_ptr,hreg_t0,hreg_ra,4);
3614: amd64_not_reg(iop->ob_ptr,hreg_t0);
3615: amd64_alu_reg_imm_size(iop->ob_ptr,X86_ADD,hreg_t0,1,4);
3616:
3617: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3618: amd64_mov_membase_reg(iop->ob_ptr,AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
3619: hreg_t1,4);
3620:
3621: /* $t0 += sign_extend(imm,16) */
3622: amd64_alu_reg_imm_size(iop->ob_ptr,X86_ADD,hreg_t0,tmp,4);
3623: amd64_set_reg(iop->ob_ptr,X86_CC_C,hreg_t1,FALSE);
3624: amd64_alu_membase_reg_size(iop->ob_ptr,X86_OR,
3625: AMD64_R15,OFFSET(cpu_ppc_t,xer_ca),
3626: hreg_t1,4);
3627:
3628: amd64_mov_reg_reg(iop->ob_ptr,hreg_rd,hreg_t0,4);
3629: ppc32_op_emit_store_gpr(cpu,rd,hreg_rd);
3630:
3631: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3632: return(0);
3633: }
3634:
3635: /* SYNC - Synchronize */
3636: DECLARE_INSN(SYNC)
3637: {
3638: return(0);
3639: }
3640:
3641: /* XOR */
3642: DECLARE_INSN(XOR)
3643: {
3644: int rs = bits(insn,21,25);
3645: int ra = bits(insn,16,20);
3646: int rb = bits(insn,11,15);
1.1.1.3 root 3647: int hreg_rs,hreg_ra,hreg_rb;
3648: jit_op_t *iop;
3649:
3650: /* $ra = $rs ^ $rb */
3651: ppc32_jit_start_hreg_seq(cpu,"xor");
3652: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3653: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3654: hreg_rb = ppc32_jit_alloc_hreg(cpu,rb);
3655:
3656: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3657: ppc32_op_emit_load_gpr(cpu,hreg_rb,rb);
3658:
3659: iop = ppc32_op_emit_insn_output(cpu,1,"xor");
3660:
3661: if (ra == rs)
3662: amd64_alu_reg_reg_size(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb,4);
3663: else if (ra == rb)
3664: amd64_alu_reg_reg_size(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rs,4);
3665: else {
3666: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3667: amd64_alu_reg_reg_size(iop->ob_ptr,X86_XOR,hreg_ra,hreg_rb,4);
3668: }
1.1 root 3669:
1.1.1.3 root 3670: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1 root 3671:
3672: if (insn & 1)
1.1.1.3 root 3673: ppc32_op_emit_update_flags(cpu,0,TRUE);
1.1 root 3674:
1.1.1.3 root 3675: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3676: return(0);
3677: }
3678:
3679: /* XORI - XOR Immediate */
3680: DECLARE_INSN(XORI)
3681: {
3682: int rs = bits(insn,21,25);
3683: int ra = bits(insn,16,20);
3684: m_uint32_t imm = bits(insn,0,15);
1.1.1.3 root 3685: int hreg_rs,hreg_ra;
3686: jit_op_t *iop;
3687:
3688: /* $ra = $rs ^ imm */
3689: ppc32_jit_start_hreg_seq(cpu,"xori");
3690: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3691: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3692:
3693: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3694:
3695: iop = ppc32_op_emit_insn_output(cpu,1,"xori");
3696:
3697: if (ra != rs)
3698: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
1.1 root 3699:
1.1.1.3 root 3700: amd64_alu_reg_imm(iop->ob_ptr,X86_XOR,hreg_ra,imm);
3701: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
3702:
3703: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3704: return(0);
3705: }
3706:
3707: /* XORIS - XOR Immediate Shifted */
3708: DECLARE_INSN(XORIS)
3709: {
3710: int rs = bits(insn,21,25);
3711: int ra = bits(insn,16,20);
1.1.1.3 root 3712: m_uint16_t imm = bits(insn,0,15);
3713: m_uint32_t tmp = imm << 16;
3714: int hreg_rs,hreg_ra;
3715: jit_op_t *iop;
3716:
3717: /* $ra = $rs ^ (imm << 16) */
3718: ppc32_jit_start_hreg_seq(cpu,"xoris");
3719: hreg_rs = ppc32_jit_alloc_hreg(cpu,rs);
3720: hreg_ra = ppc32_jit_alloc_hreg(cpu,ra);
3721:
3722: ppc32_op_emit_load_gpr(cpu,hreg_rs,rs);
3723:
3724: iop = ppc32_op_emit_insn_output(cpu,1,"xoris");
3725:
3726: if (ra != rs)
3727: amd64_mov_reg_reg(iop->ob_ptr,hreg_ra,hreg_rs,4);
3728:
3729: amd64_alu_reg_imm(iop->ob_ptr,X86_XOR,hreg_ra,tmp);
3730: ppc32_op_emit_store_gpr(cpu,ra,hreg_ra);
1.1 root 3731:
1.1.1.3 root 3732: ppc32_jit_close_hreg_seq(cpu);
1.1 root 3733: return(0);
3734: }
3735:
3736: /* PPC instruction array */
3737: struct ppc32_insn_tag ppc32_insn_tags[] = {
3738: { ppc32_emit_BLR , 0xfffffffe , 0x4e800020 },
3739: { ppc32_emit_BCTR , 0xfffffffe , 0x4e800420 },
3740: { ppc32_emit_MFLR , 0xfc1fffff , 0x7c0802a6 },
3741: { ppc32_emit_MTLR , 0xfc1fffff , 0x7c0803a6 },
3742: { ppc32_emit_MFCTR , 0xfc1fffff , 0x7c0902a6 },
3743: { ppc32_emit_MTCTR , 0xfc1fffff , 0x7c0903a6 },
3744: { ppc32_emit_MFTBL , 0xfc1ff7ff , 0x7c0c42e6 },
3745: { ppc32_emit_MFTBU , 0xfc1ff7ff , 0x7c0d42e6 },
3746: { ppc32_emit_ADD , 0xfc0007fe , 0x7c000214 },
3747: { ppc32_emit_ADDC , 0xfc0007fe , 0x7c000014 },
3748: { ppc32_emit_ADDE , 0xfc0007fe , 0x7c000114 },
3749: { ppc32_emit_ADDI , 0xfc000000 , 0x38000000 },
3750: { ppc32_emit_ADDIC , 0xfc000000 , 0x30000000 },
3751: { ppc32_emit_ADDIC_dot , 0xfc000000 , 0x34000000 },
3752: { ppc32_emit_ADDIS , 0xfc000000 , 0x3c000000 },
1.1.1.3 root 3753: { ppc32_emit_ADDZE , 0xfc00fffe , 0x7c000194 },
1.1 root 3754: { ppc32_emit_AND , 0xfc0007fe , 0x7c000038 },
3755: { ppc32_emit_ANDC , 0xfc0007fe , 0x7c000078 },
3756: { ppc32_emit_ANDI , 0xfc000000 , 0x70000000 },
3757: { ppc32_emit_ANDIS , 0xfc000000 , 0x74000000 },
3758: { ppc32_emit_B , 0xfc000003 , 0x48000000 },
3759: { ppc32_emit_BA , 0xfc000003 , 0x48000002 },
3760: { ppc32_emit_BL , 0xfc000003 , 0x48000001 },
3761: { ppc32_emit_BLA , 0xfc000003 , 0x48000003 },
3762: { ppc32_emit_BCC , 0xfe800000 , 0x40800000 },
3763: { ppc32_emit_BC , 0xfc000000 , 0x40000000 },
3764: { ppc32_emit_BCLR , 0xfc00fffe , 0x4c000020 },
3765: { ppc32_emit_CMP , 0xfc6007ff , 0x7c000000 },
3766: { ppc32_emit_CMPI , 0xfc600000 , 0x2c000000 },
3767: { ppc32_emit_CMPL , 0xfc6007ff , 0x7c000040 },
3768: { ppc32_emit_CMPLI , 0xfc600000 , 0x28000000 },
3769: { ppc32_emit_CRAND , 0xfc0007ff , 0x4c000202 },
3770: { ppc32_emit_CRANDC , 0xfc0007ff , 0x4c000102 },
3771: { ppc32_emit_CREQV , 0xfc0007ff , 0x4c000242 },
3772: { ppc32_emit_CRNAND , 0xfc0007ff , 0x4c0001c2 },
3773: { ppc32_emit_CRNOR , 0xfc0007ff , 0x4c000042 },
3774: { ppc32_emit_CROR , 0xfc0007ff , 0x4c000382 },
3775: { ppc32_emit_CRORC , 0xfc0007ff , 0x4c000342 },
3776: { ppc32_emit_CRXOR , 0xfc0007ff , 0x4c000182 },
3777: { ppc32_emit_DIVWU , 0xfc0007fe , 0x7c000396 },
3778: { ppc32_emit_EQV , 0xfc0007fe , 0x7c000238 },
3779: { ppc32_emit_EXTSB , 0xfc00fffe , 0x7c000774 },
3780: { ppc32_emit_EXTSH , 0xfc00fffe , 0x7c000734 },
3781: { ppc32_emit_LBZ , 0xfc000000 , 0x88000000 },
3782: { ppc32_emit_LBZU , 0xfc000000 , 0x8c000000 },
3783: { ppc32_emit_LBZUX , 0xfc0007ff , 0x7c0000ee },
3784: { ppc32_emit_LBZX , 0xfc0007ff , 0x7c0000ae },
3785: { ppc32_emit_LHA , 0xfc000000 , 0xa8000000 },
3786: { ppc32_emit_LHAU , 0xfc000000 , 0xac000000 },
3787: { ppc32_emit_LHAUX , 0xfc0007ff , 0x7c0002ee },
3788: { ppc32_emit_LHAX , 0xfc0007ff , 0x7c0002ae },
3789: { ppc32_emit_LHZ , 0xfc000000 , 0xa0000000 },
3790: { ppc32_emit_LHZU , 0xfc000000 , 0xa4000000 },
3791: { ppc32_emit_LHZUX , 0xfc0007ff , 0x7c00026e },
3792: { ppc32_emit_LHZX , 0xfc0007ff , 0x7c00022e },
3793: { ppc32_emit_LWZ , 0xfc000000 , 0x80000000 },
3794: { ppc32_emit_LWZU , 0xfc000000 , 0x84000000 },
3795: { ppc32_emit_LWZUX , 0xfc0007ff , 0x7c00006e },
3796: { ppc32_emit_LWZX , 0xfc0007ff , 0x7c00002e },
3797: { ppc32_emit_MCRF , 0xfc63ffff , 0x4c000000 },
3798: { ppc32_emit_MFCR , 0xfc1fffff , 0x7c000026 },
3799: { ppc32_emit_MFMSR , 0xfc1fffff , 0x7c0000a6 },
3800: { ppc32_emit_MFSR , 0xfc10ffff , 0x7c0004a6 },
3801: { ppc32_emit_MTCRF , 0xfc100fff , 0x7c000120 },
3802: { ppc32_emit_MULHW , 0xfc0007fe , 0x7c000096 },
3803: { ppc32_emit_MULHWU , 0xfc0007fe , 0x7c000016 },
3804: { ppc32_emit_MULLI , 0xfc000000 , 0x1c000000 },
3805: { ppc32_emit_MULLW , 0xfc0007fe , 0x7c0001d6 },
3806: { ppc32_emit_NAND , 0xfc0007fe , 0x7c0003b8 },
3807: { ppc32_emit_NEG , 0xfc00fffe , 0x7c0000d0 },
3808: { ppc32_emit_NOR , 0xfc0007fe , 0x7c0000f8 },
3809: { ppc32_emit_OR , 0xfc0007fe , 0x7c000378 },
3810: { ppc32_emit_ORC , 0xfc0007fe , 0x7c000338 },
3811: { ppc32_emit_ORI , 0xfc000000 , 0x60000000 },
3812: { ppc32_emit_ORIS , 0xfc000000 , 0x64000000 },
3813: { ppc32_emit_RLWIMI , 0xfc000000 , 0x50000000 },
3814: { ppc32_emit_RLWINM , 0xfc000000 , 0x54000000 },
3815: { ppc32_emit_RLWNM , 0xfc000000 , 0x5c000000 },
3816: { ppc32_emit_SLW , 0xfc0007fe , 0x7c000030 },
3817: { ppc32_emit_SRAWI , 0xfc0007fe , 0x7c000670 },
3818: { ppc32_emit_SRW , 0xfc0007fe , 0x7c000430 },
3819: { ppc32_emit_STB , 0xfc000000 , 0x98000000 },
3820: { ppc32_emit_STBU , 0xfc000000 , 0x9c000000 },
3821: { ppc32_emit_STBUX , 0xfc0007ff , 0x7c0001ee },
3822: { ppc32_emit_STBX , 0xfc0007ff , 0x7c0001ae },
3823: { ppc32_emit_STH , 0xfc000000 , 0xb0000000 },
3824: { ppc32_emit_STHU , 0xfc000000 , 0xb4000000 },
3825: { ppc32_emit_STHUX , 0xfc0007ff , 0x7c00036e },
3826: { ppc32_emit_STHX , 0xfc0007ff , 0x7c00032e },
3827: { ppc32_emit_STW , 0xfc000000 , 0x90000000 },
3828: { ppc32_emit_STWU , 0xfc000000 , 0x94000000 },
3829: { ppc32_emit_STWUX , 0xfc0007ff , 0x7c00016e },
3830: { ppc32_emit_STWX , 0xfc0007ff , 0x7c00012e },
3831: { ppc32_emit_SUBF , 0xfc0007fe , 0x7c000050 },
3832: { ppc32_emit_SUBFC , 0xfc0007fe , 0x7c000010 },
3833: { ppc32_emit_SUBFE , 0xfc0007fe , 0x7c000110 },
3834: { ppc32_emit_SUBFIC , 0xfc000000 , 0x20000000 },
3835: { ppc32_emit_SYNC , 0xffffffff , 0x7c0004ac },
3836: { ppc32_emit_XOR , 0xfc0007fe , 0x7c000278 },
3837: { ppc32_emit_XORI , 0xfc000000 , 0x68000000 },
3838: { ppc32_emit_XORIS , 0xfc000000 , 0x6c000000 },
3839: { ppc32_emit_unknown , 0x00000000 , 0x00000000 },
1.1.1.2 root 3840: { NULL , 0x00000000 , 0x00000000 },
1.1 root 3841: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.