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) */ |
238 |
m_uint32_t res; |
m_uint32_t res; |
239 |
|
|
240 |
if (val & 0x80000000) |
if (val & 0x80000000) |
241 |
res = PPC32_CR0_LT; |
res = 1 << PPC32_CR_LT_BIT; |
242 |
else { |
else { |
243 |
if (val > 0) |
if (val > 0) |
244 |
res = PPC32_CR0_GT; |
res = 1 << PPC32_CR_GT_BIT; |
245 |
else |
else |
246 |
res = PPC32_CR0_EQ; |
res = 1 << PPC32_CR_EQ_BIT; |
247 |
} |
} |
248 |
|
|
249 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
250 |
res |= PPC32_CR0_SO; |
res |= 1 << PPC32_CR_SO_BIT; |
251 |
|
|
252 |
cpu->cr &= ~(PPC32_CR0_LT|PPC32_CR0_GT|PPC32_CR0_EQ|PPC32_CR0_SO); |
cpu->cr_fields[0] = res; |
|
cpu->cr |= res; |
|
253 |
} |
} |
254 |
|
|
255 |
/* |
/* |
312 |
{ |
{ |
313 |
u_int ctr_ok = TRUE; |
u_int ctr_ok = TRUE; |
314 |
u_int cond_ok; |
u_int cond_ok; |
315 |
|
u_int cr_bit; |
316 |
|
|
317 |
if (!(bo & 0x04)) { |
if (!(bo & 0x04)) { |
318 |
cpu->ctr--; |
cpu->ctr--; |
319 |
ctr_ok = (cpu->ctr != 0) ^ ((bo >> 1) & 0x1); |
ctr_ok = (cpu->ctr != 0) ^ ((bo >> 1) & 0x1); |
320 |
} |
} |
321 |
|
|
322 |
cond_ok = (bo >> 4) | (((cpu->cr >> (31 - bi)) ^ (~bo >> 3)) & 0x1); |
cr_bit = ppc32_read_cr_bit(cpu,bi); |
323 |
|
cond_ok = (bo >> 4) | ((cr_bit ^ (~bo >> 3)) & 0x1); |
324 |
|
|
325 |
return(ctr_ok & cond_ok); |
return(ctr_ok & cond_ok); |
326 |
} |
} |
1007 |
|
|
1008 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
1009 |
res |= 0x01; |
res |= 0x01; |
1010 |
|
|
1011 |
cpu->cr &= ~(0xF0000000 >> (rd << 2)); |
cpu->cr_fields[rd] = res; |
|
cpu->cr |= res << (28 - (rd << 2)); |
|
1012 |
return(0); |
return(0); |
1013 |
} |
} |
1014 |
|
|
1036 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
1037 |
res |= 0x01; |
res |= 0x01; |
1038 |
|
|
1039 |
cpu->cr &= ~(0xF0000000 >> (rd << 2)); |
cpu->cr_fields[rd] = res; |
|
cpu->cr |= res << (28 - (rd << 2)); |
|
1040 |
return(0); |
return(0); |
1041 |
} |
} |
1042 |
|
|
1063 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
1064 |
res |= 0x01; |
res |= 0x01; |
1065 |
|
|
1066 |
cpu->cr &= ~(0xF0000000 >> (rd << 2)); |
cpu->cr_fields[rd] = res; |
|
cpu->cr |= res << (28 - (rd << 2)); |
|
1067 |
return(0); |
return(0); |
1068 |
} |
} |
1069 |
|
|
1089 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
1090 |
res |= 0x01; |
res |= 0x01; |
1091 |
|
|
1092 |
cpu->cr &= ~(0xF0000000 >> (rd << 2)); |
cpu->cr_fields[rd] = res; |
|
cpu->cr |= res << (28 - (rd << 2)); |
|
1093 |
return(0); |
return(0); |
1094 |
} |
} |
1095 |
|
|
1123 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1124 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1125 |
|
|
1126 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1127 |
tmp &= cpu->cr >> (31 - bb); |
tmp &= ppc32_read_cr_bit(cpu,bb); |
1128 |
|
|
1129 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1130 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1131 |
else |
else |
1132 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1133 |
|
|
1134 |
return(0); |
return(0); |
1135 |
} |
} |
1142 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1143 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1144 |
|
|
1145 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1146 |
tmp ^= cpu->cr >> (31 - bb); |
tmp ^= ppc32_read_cr_bit(cpu,bb); |
1147 |
|
|
1148 |
if (!(tmp & 0x1)) |
if (!(tmp & 0x1)) |
1149 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1150 |
else |
else |
1151 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1152 |
|
|
1153 |
return(0); |
return(0); |
1154 |
} |
} |
1161 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1162 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1163 |
|
|
1164 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1165 |
tmp &= ~(cpu->cr >> (31 - bb)); |
tmp &= ~ppc32_read_cr_bit(cpu,bb); |
1166 |
|
|
1167 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1168 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1169 |
else |
else |
1170 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1171 |
|
|
1172 |
return(0); |
return(0); |
1173 |
} |
} |
1180 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1181 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1182 |
|
|
1183 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1184 |
tmp &= cpu->cr >> (31 - bb); |
tmp &= ppc32_read_cr_bit(cpu,bb); |
1185 |
|
|
1186 |
if (!(tmp & 0x1)) |
if (!(tmp & 0x1)) |
1187 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1188 |
else |
else |
1189 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1190 |
|
|
1191 |
return(0); |
return(0); |
1192 |
} |
} |
1199 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1200 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1201 |
|
|
1202 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1203 |
tmp |= cpu->cr >> (31 - bb); |
tmp |= ppc32_read_cr_bit(cpu,bb); |
1204 |
|
|
1205 |
if (!(tmp & 0x1)) |
if (!(tmp & 0x1)) |
1206 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1207 |
else |
else |
1208 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1209 |
|
|
1210 |
return(0); |
return(0); |
1211 |
} |
} |
1218 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1219 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1220 |
|
|
1221 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1222 |
tmp |= cpu->cr >> (31 - bb); |
tmp |= ppc32_read_cr_bit(cpu,bb); |
1223 |
|
|
1224 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1225 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1226 |
else |
else |
1227 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1228 |
|
|
1229 |
return(0); |
return(0); |
1230 |
} |
} |
1237 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1238 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1239 |
|
|
1240 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1241 |
tmp |= ~(cpu->cr >> (31 - bb)); |
tmp |= ~ppc32_read_cr_bit(cpu,bb); |
1242 |
|
|
1243 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1244 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1245 |
else |
else |
1246 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1247 |
|
|
1248 |
return(0); |
return(0); |
1249 |
} |
} |
1256 |
int ba = bits(insn,11,15); |
int ba = bits(insn,11,15); |
1257 |
m_uint32_t tmp; |
m_uint32_t tmp; |
1258 |
|
|
1259 |
tmp = cpu->cr >> (31 - ba); |
tmp = ppc32_read_cr_bit(cpu,ba); |
1260 |
tmp ^= cpu->cr >> (31 - bb); |
tmp ^= ppc32_read_cr_bit(cpu,bb); |
1261 |
|
|
1262 |
if (tmp & 0x1) |
if (tmp & 0x1) |
1263 |
cpu->cr |= 1 << (31 - bd); |
ppc32_set_cr_bit(cpu,bd); |
1264 |
else |
else |
1265 |
cpu->cr &= ~(1 << (31 - bd)); |
ppc32_clear_cr_bit(cpu,bd); |
1266 |
|
|
1267 |
return(0); |
return(0); |
1268 |
} |
} |
1938 |
{ |
{ |
1939 |
int rd = bits(insn,23,25); |
int rd = bits(insn,23,25); |
1940 |
int rs = bits(insn,18,20); |
int rs = bits(insn,18,20); |
|
m_uint32_t tmp,dmask; |
|
1941 |
|
|
1942 |
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)); |
|
1943 |
return(0); |
return(0); |
1944 |
} |
} |
1945 |
|
|
1948 |
{ |
{ |
1949 |
int rd = bits(insn,21,25); |
int rd = bits(insn,21,25); |
1950 |
|
|
1951 |
cpu->gpr[rd] = cpu->cr; |
cpu->gpr[rd] = ppc32_get_cr(cpu); |
1952 |
return(0); |
return(0); |
1953 |
} |
} |
1954 |
|
|
2090 |
{ |
{ |
2091 |
int rs = bits(insn,21,25); |
int rs = bits(insn,21,25); |
2092 |
int crm = bits(insn,12,19); |
int crm = bits(insn,12,19); |
|
m_uint32_t mask = 0; |
|
2093 |
int i; |
int i; |
2094 |
|
|
2095 |
for(i=0;i<8;i++) |
for(i=0;i<8;i++) |
2096 |
if (crm & (1 << i)) |
if (crm & (1 << (7 - i))) |
2097 |
mask |= 0xF << (i << 2); |
cpu->cr_fields[i] = (cpu->gpr[rs] >> (28 - (i << 2))) & 0x0F; |
2098 |
|
|
|
cpu->cr = (cpu->gpr[rs] & mask) | (cpu->cr & ~mask); |
|
2099 |
return(0); |
return(0); |
2100 |
} |
} |
2101 |
|
|
3046 |
res = ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,rs); |
res = ppc32_exec_memop(cpu,PPC_MEMOP_STW,vaddr,rs); |
3047 |
if (res != 0) return(res); |
if (res != 0) return(res); |
3048 |
|
|
3049 |
cpu->cr &= ~0xF0000000; |
cpu->cr_fields[0] = 1 << PPC32_CR_EQ_BIT; |
|
cpu->cr |= PPC32_CR0_EQ; |
|
3050 |
|
|
3051 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
3052 |
cpu->cr |= PPC32_CR0_SO; |
cpu->cr_fields[0] |= 1 << PPC32_CR_SO_BIT; |
3053 |
|
|
3054 |
cpu->reserve = 0; |
cpu->reserve = 0; |
3055 |
} else { |
} else { |
3056 |
cpu->cr &= ~0xF0000000; |
cpu->cr_fields[0] = 0; |
3057 |
|
|
3058 |
if (cpu->xer & PPC32_XER_SO) |
if (cpu->xer & PPC32_XER_SO) |
3059 |
cpu->cr |= PPC32_CR0_SO; |
cpu->cr_fields[0] |= 1 << PPC32_CR_SO_BIT; |
3060 |
} |
} |
3061 |
|
|
3062 |
return(0); |
return(0); |
3834 |
{ "tlbre" , ppc32_exec_TLBRE , 0xfc0007ff , 0x7c000764, 0 }, |
{ "tlbre" , ppc32_exec_TLBRE , 0xfc0007ff , 0x7c000764, 0 }, |
3835 |
{ "tlbwe" , ppc32_exec_TLBWE , 0xfc0007ff , 0x7c0007a4, 0 }, |
{ "tlbwe" , ppc32_exec_TLBWE , 0xfc0007ff , 0x7c0007a4, 0 }, |
3836 |
|
|
3837 |
{ NULL , NULL , 0x00000000 , 0x00000000, 0 }, |
/* Unknown opcode fallback */ |
3838 |
|
{ "unknown" , ppc32_exec_unknown , 0x00000000 , 0x00000000, 0 }, |
3839 |
|
|
3840 |
|
{ NULL , NULL, 0, 0, 0 }, |
3841 |
}; |
}; |