51 |
for(i=0,count=0;ppc32_exec_tags[i].exec;i++) |
for(i=0,count=0;ppc32_exec_tags[i].exec;i++) |
52 |
count++; |
count++; |
53 |
|
|
54 |
ilt = ilt_create(count+1, |
ilt = ilt_create("ppc32e",count, |
55 |
(ilt_get_insn_cbk_t)ppc32_exec_get_insn, |
(ilt_get_insn_cbk_t)ppc32_exec_get_insn, |
56 |
(ilt_check_cbk_t)ppc32_exec_chk_lo, |
(ilt_check_cbk_t)ppc32_exec_chk_lo, |
57 |
(ilt_check_cbk_t)ppc32_exec_chk_hi); |
(ilt_check_cbk_t)ppc32_exec_chk_hi); |
103 |
return(0); |
return(0); |
104 |
} |
} |
105 |
|
|
106 |
|
/* Unknown opcode */ |
107 |
|
static fastcall int ppc32_exec_unknown(cpu_ppc_t *cpu,ppc_insn_t insn) |
108 |
|
{ |
109 |
|
printf("PPC32: unknown opcode 0x%8.8x at ia = 0x%x\n",insn,cpu->ia); |
110 |
|
ppc32_dump_regs(cpu->gen); |
111 |
|
return(0); |
112 |
|
} |
113 |
|
|
114 |
/* Execute a single instruction */ |
/* Execute a single instruction */ |
115 |
static forced_inline int |
static forced_inline int |
116 |
ppc32_exec_single_instruction(cpu_ppc_t *cpu,ppc_insn_t instruction) |
ppc32_exec_single_instruction(cpu_ppc_t *cpu,ppc_insn_t instruction) |
128 |
tag = ppc32_exec_get_insn(index); |
tag = ppc32_exec_get_insn(index); |
129 |
exec = tag->exec; |
exec = tag->exec; |
130 |
|
|
|
if (likely(exec != NULL)) { |
|
131 |
#if NJM_STATS_ENABLE |
#if NJM_STATS_ENABLE |
132 |
cpu->insn_exec_count++; |
cpu->insn_exec_count++; |
133 |
ppc32_exec_tags[index].count++; |
ppc32_exec_tags[index].count++; |
134 |
#endif |
#endif |
135 |
return(exec(cpu,instruction)); |
return(exec(cpu,instruction)); |
|
} |
|
|
|
|
|
printf("PPC32: unknown opcode 0x%8.8x at ia = 0x%x\n", |
|
|
instruction,cpu->ia); |
|
|
ppc32_dump_regs(cpu->gen); |
|
|
return(0); |
|
136 |
} |
} |
137 |
|
|
138 |
/* Execute a single instruction (external) */ |
/* Execute a single instruction (external) */ |
145 |
return(res); |
return(res); |
146 |
} |
} |
147 |
|
|
148 |
|
/* Execute a page */ |
149 |
|
fastcall int ppc32_exec_page(cpu_ppc_t *cpu) |
150 |
|
{ |
151 |
|
m_uint32_t exec_page,offset; |
152 |
|
ppc_insn_t insn; |
153 |
|
int res; |
154 |
|
|
155 |
|
exec_page = cpu->ia & ~PPC32_MIN_PAGE_IMASK; |
156 |
|
cpu->njm_exec_page = exec_page; |
157 |
|
cpu->njm_exec_ptr = cpu->mem_op_lookup(cpu,exec_page,PPC32_MTS_ICACHE); |
158 |
|
|
159 |
|
do { |
160 |
|
offset = (cpu->ia & PPC32_MIN_PAGE_IMASK) >> 2; |
161 |
|
insn = vmtoh32(cpu->njm_exec_ptr[offset]); |
162 |
|
|
163 |
|
res = ppc32_exec_single_instruction(cpu,insn); |
164 |
|
if (likely(!res)) cpu->ia += sizeof(ppc_insn_t); |
165 |
|
}while((cpu->ia & ~PPC32_MIN_PAGE_IMASK) == exec_page); |
166 |
|
|
167 |
|
return(0); |
168 |
|
} |
169 |
|
|
170 |
/* Run PowerPC code in step-by-step mode */ |
/* Run PowerPC code in step-by-step mode */ |
171 |
void *ppc32_exec_run_cpu(cpu_gen_t *gen) |
void *ppc32_exec_run_cpu(cpu_gen_t *gen) |
172 |
{ |
{ |
260 |
m_uint32_t res; |
m_uint32_t res; |
261 |
|
|
262 |
if (val & 0x80000000) |
if (val & 0x80000000) |
263 |
res = PPC32_CR0_LT; |
res = 1 << PPC32_CR_LT_BIT; |
264 |
else { |
else { |
265 |
if (val > 0) |
if (val > 0) |
266 |
res = PPC32_CR0_GT; |
res = 1 << PPC32_CR_GT_BIT; |
267 |
else |
else |
268 |
res = PPC32_CR0_EQ; |
res = 1 << PPC32_CR_EQ_BIT; |
269 |
} |
} |
270 |
|
|
271 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
272 |
res |= PPC32_CR0_SO; |
res |= 1 << PPC32_CR_SO_BIT; |
273 |
|
|
274 |
cpu->cr &= ~(PPC32_CR0_LT|PPC32_CR0_GT|PPC32_CR0_EQ|PPC32_CR0_SO); |
cpu->cr_fields[0] = res; |
|
cpu->cr |= res; |
|
275 |
} |
} |
276 |
|
|
277 |
/* |
/* |
334 |
{ |
{ |
335 |
u_int ctr_ok = TRUE; |
u_int ctr_ok = TRUE; |
336 |
u_int cond_ok; |
u_int cond_ok; |
337 |
|
u_int cr_bit; |
338 |
|
|
339 |
if (!(bo & 0x04)) { |
if (!(bo & 0x04)) { |
340 |
cpu->ctr--; |
cpu->ctr--; |
341 |
ctr_ok = (cpu->ctr != 0) ^ ((bo >> 1) & 0x1); |
ctr_ok = (cpu->ctr != 0) ^ ((bo >> 1) & 0x1); |
342 |
} |
} |
343 |
|
|
344 |
cond_ok = (bo >> 4) | (((cpu->cr >> (31 - bi)) ^ (~bo >> 3)) & 0x1); |
cr_bit = ppc32_read_cr_bit(cpu,bi); |
345 |
|
cond_ok = (bo >> 4) | ((cr_bit ^ (~bo >> 3)) & 0x1); |
346 |
|
|
347 |
return(ctr_ok & cond_ok); |
return(ctr_ok & cond_ok); |
348 |
} |
} |
1029 |
|
|
1030 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
1031 |
res |= 0x01; |
res |= 0x01; |
1032 |
|
|
1033 |
cpu->cr &= ~(0xF0000000 >> (rd << 2)); |
cpu->cr_fields[rd] = res; |
|
cpu->cr |= res << (28 - (rd << 2)); |
|
1034 |
return(0); |
return(0); |
1035 |
} |
} |
1036 |
|
|
1058 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
1059 |
res |= 0x01; |
res |= 0x01; |
1060 |
|
|
1061 |
cpu->cr &= ~(0xF0000000 >> (rd << 2)); |
cpu->cr_fields[rd] = res; |
|
cpu->cr |= res << (28 - (rd << 2)); |
|
1062 |
return(0); |
return(0); |
1063 |
} |
} |
1064 |
|
|
1085 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
1086 |
res |= 0x01; |
res |= 0x01; |
1087 |
|
|
1088 |
cpu->cr &= ~(0xF0000000 >> (rd << 2)); |
cpu->cr_fields[rd] = res; |
|
cpu->cr |= res << (28 - (rd << 2)); |
|
1089 |
return(0); |
return(0); |
1090 |
} |
} |
1091 |
|
|
1111 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
1112 |
res |= 0x01; |
res |= 0x01; |
1113 |
|
|
1114 |
cpu->cr &= ~(0xF0000000 >> (rd << 2)); |
cpu->cr_fields[rd] = res; |
|
cpu->cr |= res << (28 - (rd << 2)); |
|
1115 |
return(0); |
return(0); |
1116 |
} |
} |
1117 |
|
|
1145 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1146 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1147 |
|
|
1148 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1149 |
tmp &= cpu->cr >> (31 - bb); |
tmp &= ppc32_read_cr_bit(cpu,bb); |
1150 |
|
|
1151 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1152 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1153 |
else |
else |
1154 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1155 |
|
|
1156 |
return(0); |
return(0); |
1157 |
} |
} |
1164 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1165 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1166 |
|
|
1167 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1168 |
tmp ^= cpu->cr >> (31 - bb); |
tmp ^= ppc32_read_cr_bit(cpu,bb); |
1169 |
|
|
1170 |
if (!(tmp & 0x1)) |
if (!(tmp & 0x1)) |
1171 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1172 |
else |
else |
1173 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1174 |
|
|
1175 |
return(0); |
return(0); |
1176 |
} |
} |
1183 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1184 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1185 |
|
|
1186 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1187 |
tmp &= ~(cpu->cr >> (31 - bb)); |
tmp &= ~ppc32_read_cr_bit(cpu,bb); |
1188 |
|
|
1189 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1190 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1191 |
else |
else |
1192 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1193 |
|
|
1194 |
return(0); |
return(0); |
1195 |
} |
} |
1202 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1203 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1204 |
|
|
1205 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1206 |
tmp &= cpu->cr >> (31 - bb); |
tmp &= ppc32_read_cr_bit(cpu,bb); |
1207 |
|
|
1208 |
if (!(tmp & 0x1)) |
if (!(tmp & 0x1)) |
1209 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1210 |
else |
else |
1211 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1212 |
|
|
1213 |
return(0); |
return(0); |
1214 |
} |
} |
1221 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1222 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1223 |
|
|
1224 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1225 |
tmp |= cpu->cr >> (31 - bb); |
tmp |= ppc32_read_cr_bit(cpu,bb); |
1226 |
|
|
1227 |
if (!(tmp & 0x1)) |
if (!(tmp & 0x1)) |
1228 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1229 |
else |
else |
1230 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1231 |
|
|
1232 |
return(0); |
return(0); |
1233 |
} |
} |
1240 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1241 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1242 |
|
|
1243 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1244 |
tmp |= cpu->cr >> (31 - bb); |
tmp |= ppc32_read_cr_bit(cpu,bb); |
1245 |
|
|
1246 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1247 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1248 |
else |
else |
1249 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1250 |
|
|
1251 |
return(0); |
return(0); |
1252 |
} |
} |
1259 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1260 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1261 |
|
|
1262 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1263 |
tmp |= ~(cpu->cr >> (31 - bb)); |
tmp |= ~ppc32_read_cr_bit(cpu,bb); |
1264 |
|
|
1265 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1266 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1267 |
else |
else |
1268 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1269 |
|
|
1270 |
return(0); |
return(0); |
1271 |
} |
} |
1278 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1279 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1280 |
|
|
1281 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1282 |
tmp ^= cpu->cr >> (31 - bb); |
tmp ^= ppc32_read_cr_bit(cpu,bb); |
1283 |
|
|
1284 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1285 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1286 |
else |
else |
1287 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1288 |
|
|
1289 |
return(0); |
return(0); |
1290 |
} |
} |
1960 |
{ |
{ |
1961 |
int rd = bits(insn,23,25); |
int rd = bits(insn,23,25); |
1962 |
int rs = bits(insn,18,20); |
int rs = bits(insn,18,20); |
|
m_uint32_t tmp,dmask; |
|
1963 |
|
|
1964 |
tmp = (cpu->cr >> (28 - (rs << 2))) & 0xF; |
cpu->cr_fields[rd] = cpu->cr_fields[rs]; |
|
|
|
|
/* clear the destination bits */ |
|
|
dmask = (0xF0000000 >> (rd << 2)); |
|
|
cpu->cr &= ~dmask; |
|
|
|
|
|
/* set the new field value */ |
|
|
cpu->cr |= tmp << (28 - (rd << 2)); |
|
1965 |
return(0); |
return(0); |
1966 |
} |
} |
1967 |
|
|
1970 |
{ |
{ |
1971 |
int rd = bits(insn,21,25); |
int rd = bits(insn,21,25); |
1972 |
|
|
1973 |
cpu->gpr[rd] = cpu->cr; |
cpu->gpr[rd] = ppc32_get_cr(cpu); |
1974 |
return(0); |
return(0); |
1975 |
} |
} |
1976 |
|
|
2112 |
{ |
{ |
2113 |
int rs = bits(insn,21,25); |
int rs = bits(insn,21,25); |
2114 |
int crm = bits(insn,12,19); |
int crm = bits(insn,12,19); |
|
m_uint32_t mask = 0; |
|
2115 |
int i; |
int i; |
2116 |
|
|
2117 |
for(i=0;i<8;i++) |
for(i=0;i<8;i++) |
2118 |
if (crm & (1 << i)) |
if (crm & (1 << (7 - i))) |
2119 |
mask |= 0xF << (i << 2); |
cpu->cr_fields[i] = (cpu->gpr[rs] >> (28 - (i << 2))) & 0x0F; |
2120 |
|
|
|
cpu->cr = (cpu->gpr[rs] & mask) | (cpu->cr & ~mask); |
|
2121 |
return(0); |
return(0); |
2122 |
} |
} |
2123 |
|
|
3068 |
res = ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,rs); |
res = ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,rs); |
3069 |
if (res != 0) return(res); |
if (res != 0) return(res); |
3070 |
|
|
3071 |
cpu->cr &= ~0xF0000000; |
cpu->cr_fields[0] = 1 << PPC32_CR_EQ_BIT; |
|
cpu->cr |= PPC32_CR0_EQ; |
|
3072 |
|
|
3073 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
3074 |
cpu->cr |= PPC32_CR0_SO; |
cpu->cr_fields[0] |= 1 << PPC32_CR_SO_BIT; |
3075 |
|
|
3076 |
cpu->reserve = 0; |
cpu->reserve = 0; |
3077 |
} else { |
} else { |
3078 |
cpu->cr &= ~0xF0000000; |
cpu->cr_fields[0] = 0; |
3079 |
|
|
3080 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
3081 |
cpu->cr |= PPC32_CR0_SO; |
cpu->cr_fields[0] |= 1 << PPC32_CR_SO_BIT; |
3082 |
} |
} |
3083 |
|
|
3084 |
return(0); |
return(0); |
3856 |
{ "tlbre" , ppc32_exec_TLBRE , 0xfc0007ff , 0x7c000764, 0 }, |
{ "tlbre" , ppc32_exec_TLBRE , 0xfc0007ff , 0x7c000764, 0 }, |
3857 |
{ "tlbwe" , ppc32_exec_TLBWE , 0xfc0007ff , 0x7c0007a4, 0 }, |
{ "tlbwe" , ppc32_exec_TLBWE , 0xfc0007ff , 0x7c0007a4, 0 }, |
3858 |
|
|
3859 |
{ NULL , NULL , 0x00000000 , 0x00000000, 0 }, |
/* Unknown opcode fallback */ |
3860 |
|
{ "unknown" , ppc32_exec_unknown , 0x00000000 , 0x00000000, 0 }, |
3861 |
|
|
3862 |
|
{ NULL , NULL, 0, 0, 0 }, |
3863 |
}; |
}; |