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