17 |
#include "ppc32_x86_trans.h" |
#include "ppc32_x86_trans.h" |
18 |
#include "memory.h" |
#include "memory.h" |
19 |
|
|
20 |
|
/* ======================================================================= */ |
21 |
|
|
22 |
/* Macros for CPU structure access */ |
/* Macros for CPU structure access */ |
23 |
#define REG_OFFSET(reg) (OFFSET(cpu_ppc_t,gpr[(reg)])) |
#define REG_OFFSET(reg) (OFFSET(cpu_ppc_t,gpr[(reg)])) |
24 |
#define MEMOP_OFFSET(op) (OFFSET(cpu_ppc_t,mem_op_fn[(op)])) |
#define MEMOP_OFFSET(op) (OFFSET(cpu_ppc_t,mem_op_fn[(op)])) |
27 |
static int ppc32_emit_##name(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, \ |
static int ppc32_emit_##name(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, \ |
28 |
ppc_insn_t insn) |
ppc_insn_t insn) |
29 |
|
|
30 |
|
/* EFLAGS to Condition Register (CR) field - signed */ |
31 |
|
static m_uint32_t eflags_to_cr_signed[256] = { |
32 |
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, |
33 |
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, |
34 |
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, |
35 |
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, |
36 |
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, |
37 |
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, |
38 |
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, |
39 |
|
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, |
40 |
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, |
41 |
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, |
42 |
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, |
43 |
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, |
44 |
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, |
45 |
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, |
46 |
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, |
47 |
|
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, |
48 |
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, |
49 |
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, |
50 |
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, |
51 |
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, |
52 |
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, |
53 |
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, |
54 |
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, |
55 |
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, |
56 |
|
0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, |
57 |
|
0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, |
58 |
|
0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, |
59 |
|
0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, |
60 |
|
0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, |
61 |
|
0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, |
62 |
|
0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, |
63 |
|
0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, |
64 |
|
}; |
65 |
|
|
66 |
|
/* EFLAGS to Condition Register (CR) field - unsigned */ |
67 |
|
static m_uint32_t eflags_to_cr_unsigned[256] = { |
68 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
69 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
70 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
71 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
72 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
73 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
74 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
75 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
76 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
77 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
78 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
79 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
80 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
81 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
82 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
83 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
84 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
85 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
86 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
87 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
88 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
89 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
90 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
91 |
|
0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, |
92 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
93 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
94 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
95 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
96 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
97 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
98 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
99 |
|
0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0x0a, |
100 |
|
}; |
101 |
|
|
102 |
/* Dump regs */ |
/* Dump regs */ |
103 |
static void ppc32_emit_dump_regs(ppc32_jit_tcb_t *b); |
static void ppc32_emit_dump_regs(ppc32_jit_tcb_t *b); |
104 |
|
|
123 |
x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),new_lr,4); |
x86_mov_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,lr),new_lr,4); |
124 |
} |
} |
125 |
|
|
126 |
|
/* |
127 |
|
* Try to branch directly to the specified JIT block without returning to |
128 |
|
* main loop. |
129 |
|
*/ |
130 |
|
static void ppc32_try_direct_far_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, |
131 |
|
m_uint32_t new_ia) |
132 |
|
{ |
133 |
|
m_uint32_t new_page,ia_hash,ia_offset; |
134 |
|
u_char *test1,*test2,*test3; |
135 |
|
|
136 |
|
new_page = new_ia & PPC32_MIN_PAGE_MASK; |
137 |
|
ia_offset = (new_ia & PPC32_MIN_PAGE_IMASK) >> 2; |
138 |
|
ia_hash = ppc32_jit_get_ia_hash(new_ia); |
139 |
|
|
140 |
|
/* Get JIT block info in %edx */ |
141 |
|
x86_mov_reg_membase(b->jit_ptr,X86_EBX, |
142 |
|
X86_EDI,OFFSET(cpu_ppc_t,exec_blk_map),4); |
143 |
|
x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EBX,ia_hash*sizeof(void *),4); |
144 |
|
|
145 |
|
/* no JIT block found ? */ |
146 |
|
x86_test_reg_reg(b->jit_ptr,X86_EDX,X86_EDX); |
147 |
|
test1 = b->jit_ptr; |
148 |
|
x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1); |
149 |
|
|
150 |
|
/* Check block IA */ |
151 |
|
x86_mov_reg_imm(b->jit_ptr,X86_EAX,new_page); |
152 |
|
x86_alu_reg_membase(b->jit_ptr,X86_CMP,X86_EAX,X86_EDX, |
153 |
|
OFFSET(ppc32_jit_tcb_t,start_ia)); |
154 |
|
test2 = b->jit_ptr; |
155 |
|
x86_branch8(b->jit_ptr, X86_CC_NE, 0, 1); |
156 |
|
|
157 |
|
/* Jump to the code */ |
158 |
|
x86_mov_reg_membase(b->jit_ptr,X86_ESI, |
159 |
|
X86_EDX,OFFSET(ppc32_jit_tcb_t,jit_insn_ptr),4); |
160 |
|
x86_mov_reg_membase(b->jit_ptr,X86_EBX, |
161 |
|
X86_ESI,ia_offset * sizeof(void *),4); |
162 |
|
|
163 |
|
x86_test_reg_reg(b->jit_ptr,X86_EBX,X86_EBX); |
164 |
|
test3 = b->jit_ptr; |
165 |
|
x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1); |
166 |
|
x86_jump_reg(b->jit_ptr,X86_EBX); |
167 |
|
|
168 |
|
/* Returns to caller... */ |
169 |
|
x86_patch(test1,b->jit_ptr); |
170 |
|
x86_patch(test2,b->jit_ptr); |
171 |
|
x86_patch(test3,b->jit_ptr); |
172 |
|
|
173 |
|
ppc32_set_ia(b,new_ia); |
174 |
|
ppc32_jit_tcb_push_epilog(b); |
175 |
|
} |
176 |
|
|
177 |
/* Set Jump */ |
/* Set Jump */ |
178 |
static void ppc32_set_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, |
static void ppc32_set_jump(cpu_ppc_t *cpu,ppc32_jit_tcb_t *b, |
179 |
m_uint32_t new_ia,int local_jump) |
m_uint32_t new_ia,int local_jump) |
194 |
x86_jump32(b->jit_ptr,0); |
x86_jump32(b->jit_ptr,0); |
195 |
} |
} |
196 |
} else { |
} else { |
197 |
/* save PC */ |
if (cpu->exec_blk_direct_jump) { |
198 |
ppc32_set_ia(b,new_ia); |
/* Block lookup optimization */ |
199 |
|
ppc32_try_direct_far_jump(cpu,b,new_ia); |
200 |
/* address is in another block, for now, returns to caller */ |
} else { |
201 |
ppc32_jit_tcb_push_epilog(b); |
ppc32_set_ia(b,new_ia); |
202 |
|
ppc32_jit_tcb_push_epilog(b); |
203 |
|
} |
204 |
} |
} |
205 |
} |
} |
206 |
|
|
|
/* Load the Condition Register (CR) into the specified host register */ |
|
|
static forced_inline void ppc32_load_cr(ppc32_jit_tcb_t *b,u_int host_reg) |
|
|
{ |
|
|
x86_mov_reg_membase(b->jit_ptr,host_reg,X86_EDI,OFFSET(cpu_ppc_t,cr),4); |
|
|
} |
|
|
|
|
|
/* Store the Condition Register (CR) from the specified host register */ |
|
|
static forced_inline void ppc32_store_cr(ppc32_jit_tcb_t *b,u_int host_reg) |
|
|
{ |
|
|
x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr),host_reg,4); |
|
|
} |
|
|
|
|
207 |
/* Load a GPR into the specified host register */ |
/* Load a GPR into the specified host register */ |
208 |
static forced_inline void ppc32_load_gpr(ppc32_jit_tcb_t *b,u_int host_reg, |
static forced_inline void ppc32_load_gpr(ppc32_jit_tcb_t *b,u_int host_reg, |
209 |
u_int ppc_reg) |
u_int ppc_reg) |
227 |
|
|
228 |
/* |
/* |
229 |
* Update CR from %eflags |
* Update CR from %eflags |
230 |
* %eax, %ecx, %edx, %esi are modified. |
* %eax, %edx, %esi are modified. |
231 |
*/ |
*/ |
|
#define PPC32_CR_LT_BIT 3 |
|
|
#define PPC32_CR_GT_BIT 2 |
|
|
#define PPC32_CR_EQ_BIT 1 |
|
|
#define PPC32_CR_SO_BIT 0 |
|
|
|
|
232 |
static void ppc32_update_cr(ppc32_jit_tcb_t *b,int field,int is_signed) |
static void ppc32_update_cr(ppc32_jit_tcb_t *b,int field,int is_signed) |
233 |
{ |
{ |
234 |
m_uint32_t cr_mask; |
/* Get status bits from EFLAGS */ |
235 |
u_int cfb; |
x86_mov_reg_imm(b->jit_ptr,X86_EAX,0); |
236 |
|
x86_lahf(b->jit_ptr); |
237 |
cr_mask = 0xF0000000 >> (field << 2); |
x86_xchg_ah_al(b->jit_ptr); |
|
cfb = 28 - (field << 2); |
|
|
|
|
|
x86_set_reg(b->jit_ptr,X86_CC_LT,X86_EAX,is_signed); |
|
|
x86_set_reg(b->jit_ptr,X86_CC_GT,X86_ECX,is_signed); |
|
|
x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EDX,is_signed); |
|
|
|
|
|
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,(cfb + PPC32_CR_LT_BIT)); |
|
|
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_ECX,(cfb + PPC32_CR_GT_BIT)); |
|
|
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EDX,(cfb + PPC32_CR_EQ_BIT)); |
|
238 |
|
|
239 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ECX); |
if (is_signed) |
240 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_EDX); |
x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_signed); |
241 |
|
else |
242 |
|
x86_mov_reg_imm(b->jit_ptr,X86_EDX,eflags_to_cr_unsigned); |
243 |
|
|
244 |
/* Load Condition Register */ |
x86_mov_reg_memindex(b->jit_ptr,X86_EAX,X86_EDX,0,X86_EAX,2,4); |
|
x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,OFFSET(cpu_ppc_t,cr),4); |
|
|
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EDX,~cr_mask); |
|
|
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,cr_mask); |
|
|
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EDX,X86_EAX); |
|
245 |
|
|
246 |
/* Check XER Summary of Overflow and report it */ |
/* Check XER Summary of Overflow and report it */ |
247 |
x86_mov_reg_membase(b->jit_ptr,X86_ECX,X86_EDI,OFFSET(cpu_ppc_t,xer),4); |
x86_mov_reg_membase(b->jit_ptr,X86_ESI,X86_EDI,OFFSET(cpu_ppc_t,xer),4); |
248 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ECX,PPC32_XER_SO); |
//x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,PPC32_XER_SO); |
249 |
x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_ECX,(field << 2) + 3); |
//x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_ESI,PPC32_XER_SO_BIT); |
250 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EDX,X86_ECX); |
//x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_ESI); |
251 |
|
|
252 |
/* Store modified CR */ |
/* Store modified CR field */ |
253 |
x86_mov_membase_reg(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr),X86_EDX,4); |
x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(field), |
254 |
|
X86_EAX,4); |
255 |
} |
} |
256 |
|
|
257 |
/* |
/* |
430 |
/* Test if we are writing to a COW page */ |
/* Test if we are writing to a COW page */ |
431 |
if (write_op) { |
if (write_op) { |
432 |
x86_test_membase_imm(b->jit_ptr,X86_EDX,OFFSET(mts32_entry_t,flags), |
x86_test_membase_imm(b->jit_ptr,X86_EDX,OFFSET(mts32_entry_t,flags), |
433 |
MTS_FLAG_COW); |
MTS_FLAG_COW|MTS_FLAG_EXEC); |
434 |
test2 = b->jit_ptr; |
test2 = b->jit_ptr; |
435 |
x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1); |
x86_branch8(b->jit_ptr, X86_CC_NZ, 0, 1); |
436 |
} |
} |
542 |
X86_EDI,OFFSET(cpu_ppc_t,perf_counter)+4,0); |
X86_EDI,OFFSET(cpu_ppc_t,perf_counter)+4,0); |
543 |
} |
} |
544 |
|
|
545 |
|
/* Check if there are pending IRQ */ |
546 |
|
void ppc32_check_pending_irq(ppc32_jit_tcb_t *b) |
547 |
|
{ |
548 |
|
u_char *test1; |
549 |
|
|
550 |
|
/* Check the pending IRQ flag */ |
551 |
|
x86_mov_reg_membase(b->jit_ptr,X86_EAX, |
552 |
|
X86_EDI,OFFSET(cpu_ppc_t,irq_check),4); |
553 |
|
x86_test_reg_reg(b->jit_ptr,X86_EAX,X86_EAX); |
554 |
|
test1 = b->jit_ptr; |
555 |
|
x86_branch8(b->jit_ptr, X86_CC_Z, 0, 1); |
556 |
|
|
557 |
|
/* Save PC */ |
558 |
|
ppc32_set_ia(b,b->start_ia+((b->ppc_trans_pos-1)<<2)); |
559 |
|
ppc32_jit_tcb_push_epilog(b); |
560 |
|
|
561 |
|
x86_patch(test1,b->jit_ptr); |
562 |
|
} |
563 |
|
|
564 |
/* ======================================================================== */ |
/* ======================================================================== */ |
565 |
|
|
566 |
/* BLR - Branch to Link Register */ |
/* BLR - Branch to Link Register */ |
935 |
int bo = bits(insn,21,25); |
int bo = bits(insn,21,25); |
936 |
int bi = bits(insn,16,20); |
int bi = bits(insn,16,20); |
937 |
int bd = bits(insn,2,15); |
int bd = bits(insn,2,15); |
938 |
|
u_int cr_field,cr_bit; |
939 |
m_uint32_t new_ia; |
m_uint32_t new_ia; |
940 |
u_char *jump_ptr; |
u_char *jump_ptr; |
941 |
int local_jump; |
int local_jump; |
954 |
new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2); |
new_ia += b->start_ia + ((b->ppc_trans_pos-1) << 2); |
955 |
|
|
956 |
/* Test the condition bit */ |
/* Test the condition bit */ |
957 |
x86_test_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr), |
cr_field = ppc32_get_cr_field(bi); |
958 |
(1 << (31 - bi))); |
cr_bit = ppc32_get_cr_bit(bi); |
959 |
|
|
960 |
|
x86_test_membase_imm(b->jit_ptr, |
961 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field), |
962 |
|
(1 << cr_bit)); |
963 |
|
|
964 |
local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr); |
local_jump = ppc32_jit_tcb_local_addr(b,new_ia,&jump_ptr); |
965 |
|
|
990 |
int bo = bits(insn,21,25); |
int bo = bits(insn,21,25); |
991 |
int bi = bits(insn,16,20); |
int bi = bits(insn,16,20); |
992 |
int bd = bits(insn,2,15); |
int bd = bits(insn,2,15); |
993 |
|
u_int cr_field,cr_bit; |
994 |
m_uint32_t new_ia; |
m_uint32_t new_ia; |
995 |
u_char *jump_ptr; |
u_char *jump_ptr; |
996 |
int local_jump; |
int local_jump; |
1020 |
|
|
1021 |
/* Test the condition bit */ |
/* Test the condition bit */ |
1022 |
if (!((bo >> 4) & 0x01)) { |
if (!((bo >> 4) & 0x01)) { |
1023 |
x86_test_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr), |
cr_field = ppc32_get_cr_field(bi); |
1024 |
(1 << (31 - bi))); |
cr_bit = ppc32_get_cr_bit(bi); |
1025 |
|
|
1026 |
|
x86_test_membase_imm(b->jit_ptr, |
1027 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field), |
1028 |
|
(1 << cr_bit)); |
1029 |
|
|
1030 |
x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE); |
x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE); |
1031 |
x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX); |
x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX); |
1032 |
} |
} |
1062 |
int bo = bits(insn,21,25); |
int bo = bits(insn,21,25); |
1063 |
int bi = bits(insn,16,20); |
int bi = bits(insn,16,20); |
1064 |
int bd = bits(insn,2,15); |
int bd = bits(insn,2,15); |
1065 |
|
u_int cr_field,cr_bit; |
1066 |
m_uint32_t new_ia; |
m_uint32_t new_ia; |
1067 |
u_char *jump_ptr; |
u_char *jump_ptr; |
1068 |
int cond,ctr; |
int cond,ctr; |
1087 |
|
|
1088 |
/* Test the condition bit */ |
/* Test the condition bit */ |
1089 |
if (!((bo >> 4) & 0x01)) { |
if (!((bo >> 4) & 0x01)) { |
1090 |
x86_test_membase_imm(b->jit_ptr,X86_EDI,OFFSET(cpu_ppc_t,cr), |
cr_field = ppc32_get_cr_field(bi); |
1091 |
(1 << (31 - bi))); |
cr_bit = ppc32_get_cr_bit(bi); |
1092 |
|
|
1093 |
|
x86_test_membase_imm(b->jit_ptr, |
1094 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(cr_field), |
1095 |
|
(1 << cr_bit)); |
1096 |
|
|
1097 |
x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE); |
x86_set_reg(b->jit_ptr,(cond) ? X86_CC_NZ : X86_CC_Z,X86_ECX,FALSE); |
1098 |
x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX); |
x86_alu_reg_reg(b->jit_ptr,X86_AND,X86_EAX,X86_ECX); |
1099 |
} |
} |
1182 |
int bb = bits(insn,16,20); |
int bb = bits(insn,16,20); |
1183 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1184 |
|
|
|
ppc32_load_cr(b,X86_ESI); |
|
|
|
|
1185 |
/* test $ba bit */ |
/* test $ba bit */ |
1186 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba))); |
x86_test_membase_imm(b->jit_ptr, |
1187 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)), |
1188 |
|
(1 << ppc32_get_cr_bit(ba))); |
1189 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
1190 |
|
|
1191 |
/* test $bb bit */ |
/* test $bb bit */ |
1192 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb))); |
x86_test_membase_imm(b->jit_ptr, |
1193 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)), |
1194 |
|
(1 << ppc32_get_cr_bit(bb))); |
1195 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
1196 |
|
|
1197 |
/* result of AND between $ba and $bb */ |
/* result of AND between $ba and $bb */ |
1199 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
1200 |
|
|
1201 |
/* set/clear $bd bit depending on the result */ |
/* set/clear $bd bit depending on the result */ |
1202 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd))); |
x86_alu_membase_imm(b->jit_ptr,X86_AND, |
1203 |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd)); |
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1204 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX); |
~(1 << ppc32_get_cr_bit(bd))); |
1205 |
|
|
1206 |
ppc32_store_cr(b,X86_ESI); |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd)); |
1207 |
|
x86_alu_membase_reg(b->jit_ptr,X86_OR, |
1208 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1209 |
|
X86_EBX); |
1210 |
return(0); |
return(0); |
1211 |
} |
} |
1212 |
|
|
1217 |
int bb = bits(insn,16,20); |
int bb = bits(insn,16,20); |
1218 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1219 |
|
|
|
ppc32_load_cr(b,X86_ESI); |
|
|
|
|
1220 |
/* test $ba bit */ |
/* test $ba bit */ |
1221 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba))); |
x86_test_membase_imm(b->jit_ptr, |
1222 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)), |
1223 |
|
(1 << ppc32_get_cr_bit(ba))); |
1224 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
1225 |
|
|
1226 |
/* test $bb bit */ |
/* test $bb bit */ |
1227 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb))); |
x86_test_membase_imm(b->jit_ptr, |
1228 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)), |
1229 |
|
(1 << ppc32_get_cr_bit(bb))); |
1230 |
x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE); |
1231 |
|
|
1232 |
/* result of AND between $ba and $bb */ |
/* result of AND between $ba and $bb */ |
1234 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
1235 |
|
|
1236 |
/* set/clear $bd bit depending on the result */ |
/* set/clear $bd bit depending on the result */ |
1237 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd))); |
x86_alu_membase_imm(b->jit_ptr,X86_AND, |
1238 |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd)); |
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1239 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX); |
~(1 << ppc32_get_cr_bit(bd))); |
1240 |
|
|
1241 |
ppc32_store_cr(b,X86_ESI); |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd)); |
1242 |
|
x86_alu_membase_reg(b->jit_ptr,X86_OR, |
1243 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1244 |
|
X86_EBX); |
1245 |
return(0); |
return(0); |
1246 |
} |
} |
1247 |
|
|
1252 |
int bb = bits(insn,16,20); |
int bb = bits(insn,16,20); |
1253 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1254 |
|
|
|
ppc32_load_cr(b,X86_ESI); |
|
|
|
|
1255 |
/* test $ba bit */ |
/* test $ba bit */ |
1256 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba))); |
x86_test_membase_imm(b->jit_ptr, |
1257 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)), |
1258 |
|
(1 << ppc32_get_cr_bit(ba))); |
1259 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
1260 |
|
|
1261 |
/* test $bb bit */ |
/* test $bb bit */ |
1262 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb))); |
x86_test_membase_imm(b->jit_ptr, |
1263 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)), |
1264 |
|
(1 << ppc32_get_cr_bit(bb))); |
1265 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
1266 |
|
|
1267 |
/* result of XOR between $ba and $bb */ |
/* result of XOR between $ba and $bb */ |
1270 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
1271 |
|
|
1272 |
/* set/clear $bd bit depending on the result */ |
/* set/clear $bd bit depending on the result */ |
1273 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd))); |
x86_alu_membase_imm(b->jit_ptr,X86_AND, |
1274 |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd)); |
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1275 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX); |
~(1 << ppc32_get_cr_bit(bd))); |
1276 |
|
|
1277 |
ppc32_store_cr(b,X86_ESI); |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd)); |
1278 |
|
x86_alu_membase_reg(b->jit_ptr,X86_OR, |
1279 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1280 |
|
X86_EBX); |
1281 |
return(0); |
return(0); |
1282 |
} |
} |
1283 |
|
|
1288 |
int bb = bits(insn,16,20); |
int bb = bits(insn,16,20); |
1289 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1290 |
|
|
|
ppc32_load_cr(b,X86_ESI); |
|
|
|
|
1291 |
/* test $ba bit */ |
/* test $ba bit */ |
1292 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba))); |
x86_test_membase_imm(b->jit_ptr, |
1293 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)), |
1294 |
|
(1 << ppc32_get_cr_bit(ba))); |
1295 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
1296 |
|
|
1297 |
/* test $bb bit */ |
/* test $bb bit */ |
1298 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb))); |
x86_test_membase_imm(b->jit_ptr, |
1299 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)), |
1300 |
|
(1 << ppc32_get_cr_bit(bb))); |
1301 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
1302 |
|
|
1303 |
/* result of NAND between $ba and $bb */ |
/* result of NAND between $ba and $bb */ |
1306 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
1307 |
|
|
1308 |
/* set/clear $bd bit depending on the result */ |
/* set/clear $bd bit depending on the result */ |
1309 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd))); |
x86_alu_membase_imm(b->jit_ptr,X86_AND, |
1310 |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd)); |
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1311 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX); |
~(1 << ppc32_get_cr_bit(bd))); |
1312 |
|
|
1313 |
ppc32_store_cr(b,X86_ESI); |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd)); |
1314 |
|
x86_alu_membase_reg(b->jit_ptr,X86_OR, |
1315 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1316 |
|
X86_EBX); |
1317 |
return(0); |
return(0); |
1318 |
} |
} |
1319 |
|
|
1324 |
int bb = bits(insn,16,20); |
int bb = bits(insn,16,20); |
1325 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1326 |
|
|
|
ppc32_load_cr(b,X86_ESI); |
|
|
|
|
1327 |
/* test $ba bit */ |
/* test $ba bit */ |
1328 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba))); |
x86_test_membase_imm(b->jit_ptr, |
1329 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)), |
1330 |
|
(1 << ppc32_get_cr_bit(ba))); |
1331 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
1332 |
|
|
1333 |
/* test $bb bit */ |
/* test $bb bit */ |
1334 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb))); |
x86_test_membase_imm(b->jit_ptr, |
1335 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)), |
1336 |
|
(1 << ppc32_get_cr_bit(bb))); |
1337 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
1338 |
|
|
1339 |
/* result of NOR between $ba and $bb */ |
/* result of NOR between $ba and $bb */ |
1342 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
1343 |
|
|
1344 |
/* set/clear $bd bit depending on the result */ |
/* set/clear $bd bit depending on the result */ |
1345 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd))); |
x86_alu_membase_imm(b->jit_ptr,X86_AND, |
1346 |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd)); |
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1347 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX); |
~(1 << ppc32_get_cr_bit(bd))); |
1348 |
|
|
1349 |
ppc32_store_cr(b,X86_ESI); |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd)); |
1350 |
|
x86_alu_membase_reg(b->jit_ptr,X86_OR, |
1351 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1352 |
|
X86_EBX); |
1353 |
return(0); |
return(0); |
1354 |
} |
} |
1355 |
|
|
1360 |
int bb = bits(insn,16,20); |
int bb = bits(insn,16,20); |
1361 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1362 |
|
|
|
ppc32_load_cr(b,X86_ESI); |
|
|
|
|
1363 |
/* test $ba bit */ |
/* test $ba bit */ |
1364 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba))); |
x86_test_membase_imm(b->jit_ptr, |
1365 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)), |
1366 |
|
(1 << ppc32_get_cr_bit(ba))); |
1367 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
1368 |
|
|
1369 |
/* test $bb bit */ |
/* test $bb bit */ |
1370 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb))); |
x86_test_membase_imm(b->jit_ptr, |
1371 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)), |
1372 |
|
(1 << ppc32_get_cr_bit(bb))); |
1373 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
1374 |
|
|
1375 |
/* result of OR between $ba and $bb */ |
/* result of OR between $ba and $bb */ |
1377 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
1378 |
|
|
1379 |
/* set/clear $bd bit depending on the result */ |
/* set/clear $bd bit depending on the result */ |
1380 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd))); |
x86_alu_membase_imm(b->jit_ptr,X86_AND, |
1381 |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd)); |
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1382 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX); |
~(1 << ppc32_get_cr_bit(bd))); |
1383 |
|
|
1384 |
ppc32_store_cr(b,X86_ESI); |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd)); |
1385 |
|
x86_alu_membase_reg(b->jit_ptr,X86_OR, |
1386 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1387 |
|
X86_EBX); |
1388 |
return(0); |
return(0); |
1389 |
} |
} |
1390 |
|
|
1395 |
int bb = bits(insn,16,20); |
int bb = bits(insn,16,20); |
1396 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1397 |
|
|
|
ppc32_load_cr(b,X86_ESI); |
|
|
|
|
1398 |
/* test $ba bit */ |
/* test $ba bit */ |
1399 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba))); |
x86_test_membase_imm(b->jit_ptr, |
1400 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)), |
1401 |
|
(1 << ppc32_get_cr_bit(ba))); |
1402 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
1403 |
|
|
1404 |
/* test $bb bit */ |
/* test $bb bit */ |
1405 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb))); |
x86_test_membase_imm(b->jit_ptr, |
1406 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)), |
1407 |
|
(1 << ppc32_get_cr_bit(bb))); |
1408 |
x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_Z,X86_EBX,FALSE); |
1409 |
|
|
1410 |
/* result of ORC between $ba and $bb */ |
/* result of ORC between $ba and $bb */ |
1412 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
1413 |
|
|
1414 |
/* set/clear $bd bit depending on the result */ |
/* set/clear $bd bit depending on the result */ |
1415 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd))); |
x86_alu_membase_imm(b->jit_ptr,X86_AND, |
1416 |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd)); |
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1417 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX); |
~(1 << ppc32_get_cr_bit(bd))); |
1418 |
|
|
1419 |
ppc32_store_cr(b,X86_ESI); |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd)); |
1420 |
|
x86_alu_membase_reg(b->jit_ptr,X86_OR, |
1421 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1422 |
|
X86_EBX); |
1423 |
return(0); |
return(0); |
1424 |
} |
} |
1425 |
|
|
1430 |
int bb = bits(insn,16,20); |
int bb = bits(insn,16,20); |
1431 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1432 |
|
|
|
ppc32_load_cr(b,X86_ESI); |
|
|
|
|
1433 |
/* test $ba bit */ |
/* test $ba bit */ |
1434 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - ba))); |
x86_test_membase_imm(b->jit_ptr, |
1435 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(ba)), |
1436 |
|
(1 << ppc32_get_cr_bit(ba))); |
1437 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EAX,FALSE); |
1438 |
|
|
1439 |
/* test $bb bit */ |
/* test $bb bit */ |
1440 |
x86_test_reg_imm(b->jit_ptr,X86_ESI,(1 << (31 - bb))); |
x86_test_membase_imm(b->jit_ptr, |
1441 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bb)), |
1442 |
|
(1 << ppc32_get_cr_bit(bb))); |
1443 |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
x86_set_reg(b->jit_ptr,X86_CC_NZ,X86_EBX,FALSE); |
1444 |
|
|
1445 |
/* result of XOR between $ba and $bb */ |
/* result of XOR between $ba and $bb */ |
1447 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x01); |
1448 |
|
|
1449 |
/* set/clear $bd bit depending on the result */ |
/* set/clear $bd bit depending on the result */ |
1450 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_ESI,~(1 << (31 - bd))); |
x86_alu_membase_imm(b->jit_ptr,X86_AND, |
1451 |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(31 - bd)); |
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1452 |
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_ESI,X86_EBX); |
~(1 << ppc32_get_cr_bit(bd))); |
1453 |
|
|
1454 |
ppc32_store_cr(b,X86_ESI); |
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,ppc32_get_cr_bit(bd)); |
1455 |
|
x86_alu_membase_reg(b->jit_ptr,X86_OR, |
1456 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(ppc32_get_cr_field(bd)), |
1457 |
|
X86_EBX); |
1458 |
return(0); |
return(0); |
1459 |
} |
} |
1460 |
|
|
1722 |
{ |
{ |
1723 |
int rd = bits(insn,23,25); |
int rd = bits(insn,23,25); |
1724 |
int rs = bits(insn,18,20); |
int rs = bits(insn,18,20); |
|
m_uint32_t dmask; |
|
1725 |
|
|
1726 |
/* %eax = %ebx = CR */ |
/* Load "rs" field in %edx */ |
1727 |
ppc32_load_cr(b,X86_EAX); |
x86_mov_reg_membase(b->jit_ptr,X86_EDX,X86_EDI,PPC32_CR_FIELD_OFFSET(rs),4); |
1728 |
x86_mov_reg_reg(b->jit_ptr,X86_EBX,X86_EAX,4); |
|
1729 |
|
/* Store it in "rd" field */ |
1730 |
x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EBX,(28 - (rs << 2))); |
x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(rd),X86_EDX,4); |
|
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EBX,0x0F); |
|
|
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EBX,(28 - (rd << 2))); |
|
|
|
|
|
/* clear the destination bits */ |
|
|
dmask = (0xF0000000 >> (rd << 2)); |
|
|
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,~dmask); |
|
|
|
|
|
/* set the new field value */ |
|
|
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_EBX); |
|
|
ppc32_store_cr(b,X86_EAX); |
|
1731 |
return(0); |
return(0); |
1732 |
} |
} |
1733 |
|
|
1735 |
DECLARE_INSN(MFCR) |
DECLARE_INSN(MFCR) |
1736 |
{ |
{ |
1737 |
int rd = bits(insn,21,25); |
int rd = bits(insn,21,25); |
1738 |
|
int i; |
1739 |
|
|
1740 |
|
x86_alu_reg_reg(b->jit_ptr,X86_XOR,X86_EAX,X86_EAX); |
1741 |
|
|
1742 |
|
for(i=0;i<8;i++) { |
1743 |
|
/* load field in %edx */ |
1744 |
|
x86_mov_reg_membase(b->jit_ptr,X86_EDX, |
1745 |
|
X86_EDI,PPC32_CR_FIELD_OFFSET(i),4); |
1746 |
|
x86_shift_reg_imm(b->jit_ptr,X86_SHL,X86_EAX,4); |
1747 |
|
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EAX,X86_EDX); |
1748 |
|
} |
1749 |
|
|
|
ppc32_load_cr(b,X86_EAX); |
|
1750 |
ppc32_store_gpr(b,rd,X86_EAX); |
ppc32_store_gpr(b,rd,X86_EAX); |
1751 |
return(0); |
return(0); |
1752 |
} |
} |
1778 |
{ |
{ |
1779 |
int rs = bits(insn,21,25); |
int rs = bits(insn,21,25); |
1780 |
int crm = bits(insn,12,19); |
int crm = bits(insn,12,19); |
|
m_uint32_t mask = 0; |
|
1781 |
int i; |
int i; |
1782 |
|
|
1783 |
|
ppc32_load_gpr(b,X86_EDX,rs); |
1784 |
|
|
1785 |
for(i=0;i<8;i++) |
for(i=0;i<8;i++) |
1786 |
if (crm & (1 << i)) |
if (crm & (1 << (7 - i))) { |
1787 |
mask |= 0xF << (i << 2); |
x86_mov_reg_reg(b->jit_ptr,X86_EAX,X86_EDX,4); |
1788 |
|
|
1789 |
ppc32_load_cr(b,X86_EAX); |
if (i != 7) |
1790 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,~mask); |
x86_shift_reg_imm(b->jit_ptr,X86_SHR,X86_EAX,28 - (i << 2)); |
1791 |
|
|
1792 |
ppc32_load_gpr(b,X86_EDX,rs); |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EAX,0x0F); |
1793 |
x86_alu_reg_imm(b->jit_ptr,X86_AND,X86_EDX,mask); |
x86_mov_membase_reg(b->jit_ptr,X86_EDI,PPC32_CR_FIELD_OFFSET(i), |
1794 |
|
X86_EAX,4); |
1795 |
|
} |
1796 |
|
|
|
x86_alu_reg_reg(b->jit_ptr,X86_OR,X86_EDX,X86_EAX); |
|
|
ppc32_store_cr(b,X86_EDX); |
|
1797 |
return(0); |
return(0); |
1798 |
} |
} |
1799 |
|
|
2598 |
{ ppc32_emit_XORI , 0xfc000000 , 0x68000000 }, |
{ ppc32_emit_XORI , 0xfc000000 , 0x68000000 }, |
2599 |
{ ppc32_emit_XORIS , 0xfc000000 , 0x6c000000 }, |
{ ppc32_emit_XORIS , 0xfc000000 , 0x6c000000 }, |
2600 |
{ ppc32_emit_unknown , 0x00000000 , 0x00000000 }, |
{ ppc32_emit_unknown , 0x00000000 , 0x00000000 }, |
2601 |
|
{ NULL , 0x00000000 , 0x00000000 }, |
2602 |
}; |
}; |