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