44 #ifdef GATHER_BDT_STATISTICS 60 static void update_bdt_statistics(uint32_t iw)
62 static FILE *
f = NULL;
63 static long long *counts;
64 static char *counts_used;
65 static long long n = 0;
68 size_t s = (1 << 24) *
sizeof(
long long);
69 f = fopen(
"bdt_statistics.txt",
"w");
71 fprintf(stderr,
"update_bdt_statistics(): :-(\n");
79 iw = ((iw & 0x01800000) >> 1) | (iw & 0x003fffff);
81 counts_used[iw & 0xffff] = 1;
85 if ((n % 500000) == 0) {
88 fatal(
"[ update_bdt_statistics(): n = %lli ]\n", (
long long) n);
89 fseek(f, 0, SEEK_SET);
90 for (i=0; i<0x1000000; i++)
91 if (counts_used[i & 0xffff] && counts[i] != 0) {
93 uint32_t opcode = ((i & 0x00c00000) << 1)
94 | (i & 0x003fffff) | 0x08000000;
95 for (j=0; j<counts[i]; j++)
96 fprintf(f,
"0x%08x\n", opcode);
128 uint8_t
condition_hi[16] = { 0,0,1,1, 0,0,0,0, 0,0,1,1, 0,0,0,0 };
129 uint8_t
condition_ge[16] = { 1,0,1,0, 1,0,1,0, 0,1,0,1, 0,1,0,1 };
130 uint8_t
condition_gt[16] = { 1,0,1,0, 0,0,0,0, 0,1,0,1, 0,0,0,0 };
132 #define Y(n) void arm_instr_ ## n ## __eq(struct cpu *cpu, \ 133 struct arm_instr_call *ic) \ 134 { if (cpu->cd.arm.flags & ARM_F_Z) \ 135 arm_instr_ ## n (cpu, ic); } \ 136 void arm_instr_ ## n ## __ne(struct cpu *cpu, \ 137 struct arm_instr_call *ic) \ 138 { if (!(cpu->cd.arm.flags & ARM_F_Z)) \ 139 arm_instr_ ## n (cpu, ic); } \ 140 void arm_instr_ ## n ## __cs(struct cpu *cpu, \ 141 struct arm_instr_call *ic) \ 142 { if (cpu->cd.arm.flags & ARM_F_C) \ 143 arm_instr_ ## n (cpu, ic); } \ 144 void arm_instr_ ## n ## __cc(struct cpu *cpu, \ 145 struct arm_instr_call *ic) \ 146 { if (!(cpu->cd.arm.flags & ARM_F_C)) \ 147 arm_instr_ ## n (cpu, ic); } \ 148 void arm_instr_ ## n ## __mi(struct cpu *cpu, \ 149 struct arm_instr_call *ic) \ 150 { if (cpu->cd.arm.flags & ARM_F_N) \ 151 arm_instr_ ## n (cpu, ic); } \ 152 void arm_instr_ ## n ## __pl(struct cpu *cpu, \ 153 struct arm_instr_call *ic) \ 154 { if (!(cpu->cd.arm.flags & ARM_F_N)) \ 155 arm_instr_ ## n (cpu, ic); } \ 156 void arm_instr_ ## n ## __vs(struct cpu *cpu, \ 157 struct arm_instr_call *ic) \ 158 { if (cpu->cd.arm.flags & ARM_F_V) \ 159 arm_instr_ ## n (cpu, ic); } \ 160 void arm_instr_ ## n ## __vc(struct cpu *cpu, \ 161 struct arm_instr_call *ic) \ 162 { if (!(cpu->cd.arm.flags & ARM_F_V)) \ 163 arm_instr_ ## n (cpu, ic); } \ 164 void arm_instr_ ## n ## __hi(struct cpu *cpu, \ 165 struct arm_instr_call *ic) \ 166 { if (condition_hi[cpu->cd.arm.flags]) \ 167 arm_instr_ ## n (cpu, ic); } \ 168 void arm_instr_ ## n ## __ls(struct cpu *cpu, \ 169 struct arm_instr_call *ic) \ 170 { if (!condition_hi[cpu->cd.arm.flags]) \ 171 arm_instr_ ## n (cpu, ic); } \ 172 void arm_instr_ ## n ## __ge(struct cpu *cpu, \ 173 struct arm_instr_call *ic) \ 174 { if (condition_ge[cpu->cd.arm.flags]) \ 175 arm_instr_ ## n (cpu, ic); } \ 176 void arm_instr_ ## n ## __lt(struct cpu *cpu, \ 177 struct arm_instr_call *ic) \ 178 { if (!condition_ge[cpu->cd.arm.flags]) \ 179 arm_instr_ ## n (cpu, ic); } \ 180 void arm_instr_ ## n ## __gt(struct cpu *cpu, \ 181 struct arm_instr_call *ic) \ 182 { if (condition_gt[cpu->cd.arm.flags]) \ 183 arm_instr_ ## n (cpu, ic); } \ 184 void arm_instr_ ## n ## __le(struct cpu *cpu, \ 185 struct arm_instr_call *ic) \ 186 { if (!condition_gt[cpu->cd.arm.flags]) \ 187 arm_instr_ ## n (cpu, ic); } \ 188 void (*arm_cond_instr_ ## n [16])(struct cpu *, \ 189 struct arm_instr_call *) = { \ 190 arm_instr_ ## n ## __eq, arm_instr_ ## n ## __ne, \ 191 arm_instr_ ## n ## __cs, arm_instr_ ## n ## __cc, \ 192 arm_instr_ ## n ## __mi, arm_instr_ ## n ## __pl, \ 193 arm_instr_ ## n ## __vs, arm_instr_ ## n ## __vc, \ 194 arm_instr_ ## n ## __hi, arm_instr_ ## n ## __ls, \ 195 arm_instr_ ## n ## __ge, arm_instr_ ## n ## __lt, \ 196 arm_instr_ ## n ## __gt, arm_instr_ ## n ## __le, \ 197 arm_instr_ ## n , arm_instr_never }; 199 #define cond_instr(n) ( arm_cond_instr_ ## n [condition_code] ) 210 low_pc = ((size_t)
ic - (
size_t)
211 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
216 fatal(
"FATAL ERROR: An internal error occured in the ARM" 217 " dyntrans code. Please contact the author with detailed" 218 " repro steps on how to trigger this bug. pc = 0x%08" PRIx32
"\n",
221 cpu->
cd.
arm.next_ic = ¬hing_call;
231 low_pc = ((size_t)
ic - (
size_t)
232 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
237 fatal(
"[ ARM: unimplemented 0xf instruction at pc = 0x%08" PRIx32
" ]\n", (uint32_t)
cpu->
pc);
239 cpu->
cd.
arm.next_ic = ¬hing_call;
258 cpu->
pc = (uint32_t)((
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[0]);
261 quick_pc_to_pointers_arm(
cpu);
275 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic->arg[0];
278 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
282 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
286 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
290 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
294 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
298 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
302 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
306 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
311 (
struct arm_instr_call *)
ic->arg[0] :
312 (
struct arm_instr_call *)
ic->arg[1];
315 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
320 (
struct arm_instr_call *)
ic->arg[0] :
321 (
struct arm_instr_call *)
ic->arg[1];
324 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
329 (
struct arm_instr_call *)
ic->arg[0] :
330 (
struct arm_instr_call *)
ic->arg[1];
333 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
337 struct arm_instr_call *) = {
338 arm_instr_b_samepage__eq, arm_instr_b_samepage__ne,
339 arm_instr_b_samepage__cs, arm_instr_b_samepage__cc,
340 arm_instr_b_samepage__mi, arm_instr_b_samepage__pl,
341 arm_instr_b_samepage__vs, arm_instr_b_samepage__vc,
342 arm_instr_b_samepage__hi, arm_instr_b_samepage__ls,
343 arm_instr_b_samepage__ge, arm_instr_b_samepage__lt,
344 arm_instr_b_samepage__gt, arm_instr_b_samepage__le,
363 cpu->
cd.
arm.next_ic = ¬hing_call;
366 fatal(
"[ ARM pc misaligned? 0x%08x ]\n", (
int)
cpu->
pc);
369 cpu->
cd.
arm.next_ic = ¬hing_call;
374 quick_pc_to_pointers_arm(
cpu);
394 cpu->
cd.
arm.next_ic = ¬hing_call;
397 fatal(
"[ ARM pc misaligned? 0x%08x ]\n", (
int)
cpu->
pc);
400 cpu->
cd.
arm.next_ic = ¬hing_call;
407 quick_pc_to_pointers_arm(
cpu);
420 uint32_t pc = ((uint32_t)
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[1];
424 cpu->
pc = pc + (int32_t)
ic->arg[0];
427 quick_pc_to_pointers_arm(
cpu);
440 uint32_t pc = ((uint32_t)
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[1];
445 cpu->
pc = pc + (int32_t)
ic->arg[0];
450 fatal(
"[ blx_imm internal error. Should have switched to THUMB! 0x%08x ]\n", (
int)
cpu->
pc);
453 cpu->
cd.
arm.next_ic = ¬hing_call;
458 cpu->
cd.
arm.next_ic = ¬hing_call;
461 fatal(
"[ ARM pc misaligned? 0x%08x ]\n", (
int)
cpu->
pc);
464 cpu->
cd.
arm.next_ic = ¬hing_call;
472 quick_pc_to_pointers_arm(
cpu);
484 uint32_t lr = ((uint32_t)
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[2];
495 cpu->
cd.
arm.next_ic = ¬hing_call;
498 fatal(
"[ ARM pc misaligned? 0x%08x ]\n", (
int)
cpu->
pc);
501 cpu->
cd.
arm.next_ic = ¬hing_call;
506 quick_pc_to_pointers_arm(
cpu);
518 uint32_t pc = ((uint32_t)
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[1];
522 cpu->
pc = pc + (int32_t)
ic->arg[0];
527 quick_pc_to_pointers_arm(
cpu);
540 ((uint32_t)
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[2];
541 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic->arg[0];
553 uint32_t low_pc, lr = (
cpu->
pc & 0xfffff000) +
ic->arg[2];
557 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic->arg[0];
560 low_pc = ((size_t)
cpu->
cd.
arm.next_ic - (
size_t)
561 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
580 uint32_t rm =
reg(
ic->arg[0]);
581 int i = 32, n = 0, j;
583 if (rm & 0xff000000) {
584 for (j=0; j<8; j++) {
621 if (result & 0x80000000)
623 reg(
ic->arg[0]) = result;
636 uint32_t iw =
ic->arg[0];
638 rd = (iw >> 16) & 15; rn = (iw >> 12) & 15,
639 rs = (iw >> 8) & 15; rm = iw & 15;
647 uint32_t iw =
ic->arg[0];
649 rd = (iw >> 16) & 15; rn = (iw >> 12) & 15,
650 rs = (iw >> 8) & 15; rm = iw & 15;
670 uint32_t iw; uint64_t tmp;
int u_bit, a_bit;
672 u_bit = iw & 0x00400000; a_bit = iw & 0x00200000;
675 tmp = (int64_t)(int32_t)tmp
676 * (int64_t)(int32_t)
cpu->
cd.
arm.
r[(iw >> 8) & 15];
678 tmp *= (uint64_t)
cpu->
cd.
arm.
r[(iw >> 8) & 15];
680 uint64_t x = ((uint64_t)
cpu->
cd.
arm.
r[(iw >> 16) & 15] << 32)
683 cpu->
cd.
arm.
r[(iw >> 16) & 15] = (x >> 32);
686 cpu->
cd.
arm.
r[(iw >> 16) & 15] = (tmp >> 32);
702 reg(
ic->arg[2]) = (int32_t)(int16_t)
reg(
ic->arg[0]) *
703 (int32_t)(int16_t)
reg(
ic->arg[1]);
708 reg(
ic->arg[2]) = (int32_t)(int16_t)(
reg(
ic->arg[0]) >> 16) *
709 (int32_t)(int16_t)
reg(
ic->arg[1]);
714 reg(
ic->arg[2]) = (int32_t)(int16_t)
reg(
ic->arg[0]) *
715 (int32_t)(int16_t)(
reg(
ic->arg[1]) >> 16);
720 reg(
ic->arg[2]) = (int32_t)(int16_t)(
reg(
ic->arg[0]) >> 16) *
721 (int32_t)(int16_t)(
reg(
ic->arg[1]) >> 16);
747 reg(
ic->arg[1]) = ((uint32_t)
cpu->
pc&0xfffff000) + (int32_t)
ic->arg[0];
760 uint32_t old_pc, mask_within_page;
775 if ((old_pc & ~mask_within_page) == (
cpu->
pc & ~mask_within_page)) {
780 quick_pc_to_pointers_arm(
cpu);
787 quick_pc_to_pointers_arm(
cpu);
804 uint32_t mask =
ic->arg[1];
813 uint32_t new_value =
ic->arg[0];
818 if (switch_register_banks)
826 if (switch_register_banks)
838 uint32_t mask =
ic->arg[1];
839 uint32_t new_value =
ic->arg[0];
861 default:
fatal(
"msr_spsr: unimplemented mode %i\n",
865 uint32_t old_pc, low_pc = ((size_t)
ic - (
size_t)
866 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
870 printf(
"msr_spsr: old pc = 0x%08" PRIx32
"\n", old_pc);
913 default:
fatal(
"mrs_spsr: unimplemented mode %i\n",
928 uint32_t low_pc = ((size_t)
ic - (
size_t)
929 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
936 uint32_t low_pc = ((size_t)
ic - (
size_t)
937 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
955 quick_pc_to_pointers_arm(
cpu);
966 cpu->
cd.
arm.next_ic = ¬hing_call;
976 cpu->
pc &= 0xfffff000;
989 cpu->
pc &= 0xfffff000;
1002 cpu->
pc &= 0xfffff000;
1022 uint32_t low_pc = ((size_t)
ic - (
size_t)
1023 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1029 fatal(
"swp: load failed\n");
1032 data = d[0] + (d[1] << 8) + (d[2] << 16) + (d[3] << 24);
1033 data2 =
reg(
ic->arg[1]);
1034 d[0] = data2; d[1] = data2 >> 8; d[2] = data2 >> 16; d[3] = data2 >> 24;
1037 fatal(
"swp: store failed\n");
1049 uint32_t low_pc = ((size_t)
ic - (
size_t)
1050 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1056 fatal(
"swp: load failed\n");
1060 d[0] =
reg(
ic->arg[1]);
1063 fatal(
"swp: store failed\n");
1072 struct arm_instr_call *);
1073 X(store_w1_word_u1_p0_imm);
1074 X(store_w0_byte_u1_p0_imm);
1075 X(store_w0_word_u1_p0_imm);
1076 X(store_w0_word_u1_p1_imm);
1077 X(load_w0_word_u1_p0_imm);
1078 X(load_w0_word_u1_p1_imm);
1079 X(load_w1_word_u1_p0_imm);
1080 X(load_w0_byte_u1_p1_imm);
1081 X(load_w0_byte_u1_p1_reg);
1082 X(load_w1_byte_u1_p1_imm);
1085 struct arm_instr_call *);
1088 struct arm_instr_call *);
1091 struct arm_instr_call *);
1093 extern uint32_t (*
arm_r[8192])(
struct cpu *,
struct arm_instr_call *);
1096 extern void (*
arm_dpi_instr[2 * 2 * 2 * 16 * 16])(
struct cpu *,
1097 struct arm_instr_call *);
1099 struct arm_instr_call *);
1116 void arm_pop(
struct cpu* cpu, uint32_t* np,
int p_bit,
int u_bit,
int s_bit,
int w_bit, uint32_t iw)
1118 uint32_t
addr = *np;
1119 unsigned char data[4];
1120 unsigned char *
page;
1121 int i, return_flag = 0;
1122 uint32_t new_values[16];
1127 fatal(
"[ bdt_load: s-bit: in usermode? ]\n");
1136 for (i=(u_bit? 0 : 15); i>=0 && i<=15; i+=(u_bit? 1 : -1)) {
1139 if (!((iw >> i) & 1)) {
1146 addr +=
sizeof(uint32_t);
1148 addr -=
sizeof(uint32_t);
1151 page = cpu->
cd.
arm.host_load[addr >> 12];
1153 uint32_t *p32 = (uint32_t *) page;
1154 value = p32[(addr & 0xfff) >> 2];
1157 #ifdef HOST_LITTLE_ENDIAN 1162 value = ((value & 0xff) << 24) |
1163 ((value & 0xff00) << 8) |
1164 ((value & 0xff0000) >> 8) |
1165 ((value & 0xff000000) >> 24);
1174 (data[1] << 8) + (data[2] << 16)
1178 (data[2] << 8) + (data[1] << 16)
1183 new_values[i] = value;
1187 addr +=
sizeof(uint32_t);
1189 addr -=
sizeof(uint32_t);
1193 for (i=(u_bit? 0 : 15); i>=0 && i<=15; i+=(u_bit? 1 : -1)) {
1194 if (!((iw >> i) & 1)) {
1200 cpu->
cd.
arm.
r[i] = new_values[i];
1205 cpu->
cd.
arm.
r[i] = new_values[i];
1208 if (i >= 8 && i <= 14)
1212 cpu->
cd.
arm.
r[i] = new_values[i];
1218 if (i >= 13 && i <= 14)
1222 cpu->
cd.
arm.
r[i] = new_values[i];
1233 int switch_register_banks;
1246 default:
fatal(
"bdt_load: unimplemented mode %i\n",
1254 if (switch_register_banks)
1260 if (switch_register_banks)
1274 quick_pc_to_pointers_arm(cpu);
1282 void arm_push(
struct cpu* cpu, uint32_t* np,
int p_bit,
int u_bit,
int s_bit,
int w_bit, uint16_t regs)
1285 uint32_t value,
addr = *np;
1286 unsigned char data[4];
1287 unsigned char *
page;
1289 for (i=(u_bit? 0 : 15); i>=0 && i<=15; i+=(u_bit? 1 : -1)) {
1290 if (!((regs >> i) & 1)) {
1295 value = cpu->
cd.
arm.
r[i];
1300 if (i >= 8 && i <= 14)
1307 if (i >= 13 && i <= 14)
1318 value = cpu->
pc + 12;
1322 addr +=
sizeof(uint32_t);
1324 addr -=
sizeof(uint32_t);
1327 page = cpu->
cd.
arm.host_store[addr >> 12];
1329 uint32_t *p32 = (uint32_t *) page;
1332 #ifdef HOST_LITTLE_ENDIAN 1337 value = ((value & 0xff) << 24) |
1338 ((value & 0xff00) << 8) |
1339 ((value & 0xff0000) >> 8) |
1340 ((value & 0xff000000) >> 24);
1341 p32[(addr & 0xfff) >> 2] = value;
1345 data[1] = value >> 8;
1346 data[2] = value >> 16;
1347 data[3] = value >> 24;
1349 data[0] = value >> 24;
1350 data[1] = value >> 16;
1351 data[2] = value >> 8;
1363 addr +=
sizeof(uint32_t);
1365 addr -=
sizeof(uint32_t);
1382 uint32_t *np = (uint32_t *)ic->arg[0];
1384 uint32_t iw = ic->arg[1];
1385 int p_bit = iw & 0x01000000;
1386 int u_bit = iw & 0x00800000;
1387 int s_bit = iw & 0x00400000;
1388 int w_bit = iw & 0x00200000;
1390 #ifdef GATHER_BDT_STATISTICS
1392 update_bdt_statistics(iw);
1396 low_pc = ((size_t)ic - (
size_t)
1397 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1401 arm_pop(cpu, np, p_bit, u_bit, s_bit, w_bit, (uint16_t)iw);
1414 uint32_t *np = (uint32_t *)ic->arg[0];
1416 uint32_t iw = ic->arg[1];
1417 int p_bit = iw & 0x01000000;
1418 int u_bit = iw & 0x00800000;
1419 int s_bit = iw & 0x00400000;
1420 int w_bit = iw & 0x00200000;
1422 #ifdef GATHER_BDT_STATISTICS
1424 update_bdt_statistics(iw);
1428 low_pc = ((size_t)ic - (
size_t)
1429 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1433 arm_push(cpu, np, p_bit, u_bit, s_bit, w_bit, (uint16_t)iw);
1440 extern void (**
multi_opcode_f[256])(
struct cpu *,
struct arm_instr_call *);
1441 X(multi_0x08b15018);
1442 X(multi_0x08ac000c__ge);
1443 X(multi_0x08a05018);
1461 unsigned char *
page;
1473 cpu->
cd.
arm.next_ic = &ic[17];
1478 if ((addr & 0xfff) + 128 > 0x1000)
1487 page = cpu->
cd.
arm.host_store[addr >> 12];
1493 memset(page + (addr & 0xfff), 0, 128);
1504 cpu->
cd.
arm.next_ic = &ic[18];
1522 unsigned char *page_0, *page_1;
1523 uint32_t addr_r0, addr_r1;
1526 addr_r0 = cpu->
cd.
arm.
r[0];
1527 addr_r1 = cpu->
cd.
arm.
r[1];
1532 if ((addr_r0 & 0xfff) + 32 > 0x1000 ||
1533 (addr_r1 & 0xfff) + 32 > 0x1000) {
1534 instr(multi_0x08b15018)(cpu,
ic);
1538 page_0 = cpu->
cd.
arm.host_store[addr_r0 >> 12];
1539 page_1 = cpu->
cd.
arm.host_store[addr_r1 >> 12];
1542 if (page_0 == NULL || page_1 == NULL) {
1543 instr(multi_0x08b15018)(cpu,
ic);
1547 memcpy(page_0 + (addr_r0 & 0xfff),
1548 page_1 + (addr_r1 & 0xfff), 32);
1549 cpu->
cd.
arm.
r[0] = addr_r0 + 32;
1550 cpu->
cd.
arm.
r[1] = addr_r1 + 32;
1554 instr(subs)(cpu, ic + 4);
1563 cpu->
cd.
arm.next_ic = &ic[6];
1580 uint32_t r1 = cpu->
cd.
arm.
r[1];
1584 cpu->
cd.
arm.next_ic = &ic[4];
1602 cpu->
cd.
arm.next_ic = &ic[5];
1619 instr(load_w0_byte_u1_p1_imm)(cpu,
ic);
1623 t = page[cpu->
cd.
arm.
r[1] & 0xfff];
1625 page = cpu->
cd.
arm.host_load[t >> 12];
1628 instr(load_w0_byte_u1_p1_imm)(cpu,
ic);
1632 cpu->
cd.
arm.
r[3] = page[t & 0xfff];
1640 cpu->
cd.
arm.next_ic = &ic[3];
1657 uint32_t rY =
reg(ic[0].arg[0]);
1658 uint32_t rZ =
reg(ic[3].arg[0]);
1662 p = (uint32_t *) cpu->
cd.
arm.host_load[rY >> 12];
1664 instr(load_w0_word_u1_p1_imm)(cpu,
ic);
1668 rX = p[(rY & 0xfff) >> 2];
1674 instr(load_w0_word_u1_p1_imm)(cpu,
ic);
1682 uint32_t low_pc = ((size_t)ic - (
size_t)
1683 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1696 cpu->
cd.
arm.next_ic = ¬hing_call;
1700 cpu->
cd.
arm.next_ic = &ic[5];
1713 unsigned int n_loops = 0;
1714 uint32_t rY, rX =
reg(ic[0].arg[0]);
1719 p = cpu->
cd.
arm.host_load[rX >> 12];
1722 instr(load_w1_byte_u1_p1_imm)(cpu,
ic);
1726 rY =
reg(ic[0].arg[2]) = p[rX & 0xfff];
1727 reg(ic[0].arg[0]) = rX;
1737 cpu->
cd.
arm.next_ic = &ic[3];
1750 uint32_t tmp =
reg(ic[0].arg[0]);
1752 cpu->
cd.
arm.next_ic = &ic[3];
1753 reg(ic[0].arg[0]) =
reg(ic[1].arg[0]);
1754 reg(ic[1].arg[0]) = tmp;
1770 uint32_t r0 = cpu->
cd.
arm.
r[0], ofs = (r0 & 0xffc), index = r0 >> 12;
1771 unsigned char *p = cpu->
cd.
arm.host_load[index];
1772 uint32_t *p32 = (uint32_t *) p, *q32;
1775 if (ofs > 0x1000 - 6*4 || !ok || p == NULL) {
1776 instr(load_w1_word_u1_p0_imm)(cpu,
ic);
1781 q32[0] = p32[ofs+2];
1782 q32[1] = p32[ofs+3];
1783 q32[2] = p32[ofs+4];
1784 q32[3] = p32[ofs+5];
1785 q32[4] = p32[ofs+0];
1786 q32[5] = p32[ofs+1];
1787 cpu->
cd.
arm.
r[0] = r0 + 24;
1789 cpu->
cd.
arm.next_ic = &ic[6];
1805 uint32_t r1 = cpu->
cd.
arm.
r[1], ofs = (r1 & 0xffc), index = r1 >> 12;
1806 unsigned char *p = cpu->
cd.
arm.host_store[index];
1807 uint32_t *p32 = (uint32_t *) p, *q32;
1810 if (ofs > 0x1000 - 6*4 || !ok || p == NULL) {
1811 instr(store_w1_word_u1_p0_imm)(cpu,
ic);
1817 p32[ofs+1] = q32[3];
1818 p32[ofs+2] = q32[4];
1819 p32[ofs+3] = q32[5];
1820 p32[ofs+4] = q32[0];
1821 p32[ofs+5] = q32[1];
1822 cpu->
cd.
arm.
r[1] = r1 + 24;
1824 cpu->
cd.
arm.next_ic = &ic[6];
1831 X(cmps0_beq_samepage)
1833 uint32_t a =
reg(ic->arg[0]);
1842 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1844 cpu->
cd.
arm.next_ic = &ic[2];
1851 X(cmps_beq_samepage)
1853 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1856 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1857 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1861 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1863 cpu->
cd.
arm.next_ic = &ic[2];
1875 uint32_t a =
reg(ic->arg[0]);
1879 cpu->
pc = (uint32_t)(((uint32_t)cpu->
pc & 0xfffff000)
1880 + (int32_t)ic[1].arg[0]);
1881 quick_pc_to_pointers_arm(cpu);
1885 cpu->
cd.
arm.next_ic = &ic[2];
1890 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1893 if ((int32_t)a < 0 && (int32_t)c >= 0)
1897 cpu->
pc = (uint32_t)(((uint32_t)cpu->
pc & 0xfffff000)
1898 + (int32_t)ic[1].arg[0]);
1899 quick_pc_to_pointers_arm(cpu);
1901 cpu->
cd.
arm.next_ic = &ic[2];
1908 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1911 if ((int32_t)a >= 0 && (int32_t)c < 0)
1915 cpu->
pc = (uint32_t)(((uint32_t)cpu->
pc & 0xfffff000)
1916 + (int32_t)ic[1].arg[0]);
1917 quick_pc_to_pointers_arm(cpu);
1919 cpu->
cd.
arm.next_ic = &ic[2];
1929 X(cmps0_bne_samepage)
1931 uint32_t a =
reg(ic->arg[0]);
1940 cpu->
cd.
arm.next_ic = &ic[2];
1942 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1949 X(cmps_bne_samepage)
1951 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1954 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1955 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1959 cpu->
cd.
arm.next_ic = &ic[2];
1963 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1971 X(cmps_bcc_samepage)
1973 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1980 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1981 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1984 cpu->
cd.
arm.next_ic = &ic[2];
1986 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1993 X(cmps_reg_bcc_samepage)
1995 uint32_t a =
reg(ic->arg[0]), b =
reg(ic->arg[1]), c = a - b;
2002 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2003 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2006 cpu->
cd.
arm.next_ic = &ic[2];
2008 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
2015 X(cmps_bhi_samepage)
2017 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
2024 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2025 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2028 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
2030 cpu->
cd.
arm.next_ic = &ic[2];
2037 X(cmps_reg_bhi_samepage)
2039 uint32_t a =
reg(ic->arg[0]), b =
reg(ic->arg[1]), c = a - b;
2046 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2047 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2050 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
2052 cpu->
cd.
arm.next_ic = &ic[2];
2059 X(cmps_bgt_samepage)
2061 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
2068 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2069 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2071 if ((int32_t)a > (int32_t)b)
2072 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
2074 cpu->
cd.
arm.next_ic = &ic[2];
2081 X(cmps_ble_samepage)
2083 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
2090 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2091 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2093 if ((int32_t)a <= (int32_t)b)
2094 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
2096 cpu->
cd.
arm.next_ic = &ic[2];
2103 X(teqs_beq_samepage)
2105 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a ^ b;
2110 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2115 cpu->
cd.
arm.next_ic = &ic[2];
2124 X(tsts_lo_beq_samepage)
2126 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a & b;
2132 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2135 cpu->
cd.
arm.next_ic = &ic[2];
2142 X(teqs_bne_samepage)
2144 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a ^ b;
2154 cpu->
cd.
arm.next_ic = &ic[2];
2156 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2165 X(tsts_lo_bne_samepage)
2167 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a & b;
2173 cpu->
cd.
arm.next_ic = &ic[2];
2175 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2190 quick_pc_to_pointers_arm(cpu);
2207 struct arm_instr_call *
ic,
int low_addr)
2209 #ifdef HOST_LITTLE_ENDIAN 2215 for (i=-16; i<=-1; i++)
2216 if (ic[i].f !=
instr(multi_0x08ac000c__ge))
2218 if (ic[-17].f ==
instr(subs) &&
2219 ic[-17].arg[0]==ic[-17].arg[2] && ic[-17].arg[1] == 128 &&
2220 ic[ 0].f ==
instr(b_samepage__gt) &&
2221 ic[ 0].arg[0] == (size_t)&ic[-17]) {
2238 #ifdef HOST_LITTLE_ENDIAN 2243 if (ic[-5].f==
instr(multi_0x08b15018) &&
2244 ic[-4].f==
instr(multi_0x08a05018) &&
2245 ic[-3].f==
instr(multi_0x08b15018) &&
2246 ic[-2].f==
instr(multi_0x08a05018) &&
2247 ic[-1].f ==
instr(subs) &&
2248 ic[-1].arg[0]==ic[-1].arg[2] && ic[-1].arg[1] == 0x20 &&
2249 ic[ 0].f ==
instr(b_samepage__ge) &&
2250 ic[ 0].arg[0] == (size_t)&ic[-5]) {
2264 struct arm_instr_call *
ic,
int low_addr)
2270 if (ic[-3].f==
instr(load_w0_word_u1_p0_imm) &&
2271 ic[-2].f ==
instr(subs) &&
2272 ic[-2].arg[0]==ic[-2].arg[2] && ic[-2].arg[1] == 0x20 &&
2273 ic[-1].f ==
instr(b_samepage__ne) &&
2274 ic[-1].arg[0] == (size_t)&ic[-3]) {
2287 struct arm_instr_call *
ic,
int low_addr)
2293 if (ic[-4].f ==
instr(mcr_mrc) && ic[-4].arg[0] == 0xee070f3a &&
2294 ic[-3].f ==
instr(mcr_mrc) && ic[-3].arg[0] == 0xee070f36 &&
2295 ic[-2].f ==
instr(add) &&
2296 ic[-2].arg[0]==ic[-2].arg[2] && ic[-2].arg[1] == 0x20 &&
2297 ic[-1].f ==
instr(subs) &&
2298 ic[-1].arg[0]==ic[-1].arg[2] && ic[-1].arg[1] == 0x20) {
2309 struct arm_instr_call *
ic,
int low_addr)
2317 if (ic[-2].f ==
instr(load_w0_byte_u1_p1_imm) &&
2318 ic[-2].arg[0] == (size_t)(&cpu->
cd.
arm.
r[1]) &&
2319 ic[-2].arg[1] == 0 &&
2320 ic[-2].arg[2] == (size_t)(&cpu->
cd.
arm.
r[3]) &&
2321 ic[-1].f ==
instr(load_w0_byte_u1_p1_reg) &&
2322 ic[-1].arg[0] == (size_t)(&cpu->
cd.
arm.
r[2]) &&
2323 ic[-1].arg[1] == (size_t)arm_r_r3_t0_c0 &&
2324 ic[-1].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[3])) {
2334 struct arm_instr_call *
ic,
int low_addr)
2342 if (ic[-2].f ==
instr(load_w1_byte_u1_p1_imm) &&
2343 ic[-2].arg[1] == 1 &&
2344 ic[-2].arg[2] == (size_t)(&cpu->
cd.
arm.
r[3]) &&
2346 ic[-1].arg[0] == (size_t)(&cpu->
cd.
arm.
r[3]) &&
2347 ic[-1].arg[1] == 0) {
2357 struct arm_instr_call *
ic,
int low_addr)
2366 a = ic[-2].arg[0]; b = ic[-1].arg[0];
2368 if (ic[-2].f ==
instr(eor_regshort) &&
2369 ic[-1].f ==
instr(eor_regshort) &&
2370 ic[-2].arg[0] == a && ic[-2].arg[1] == b && ic[-2].arg[2] == b &&
2371 ic[-1].arg[0] == b && ic[-1].arg[1] == a && ic[-1].arg[2] == a &&
2372 ic[ 0].arg[0] == a && ic[ 0].arg[1] == b && ic[ 0].arg[2] == b) {
2382 struct arm_instr_call *
ic,
int low_addr)
2384 #ifdef HOST_LITTLE_ENDIAN 2391 for (i=-5; i<0; i++) {
2392 if (ic[i].f !=
instr(load_w1_word_u1_p0_imm) ||
2393 ic[i].arg[0] != (size_t)(&cpu->
cd.
arm.
r[0]) ||
2398 if (ic[-5].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[10]) &&
2399 ic[-4].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[11]) &&
2400 ic[-3].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[6]) &&
2401 ic[-2].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[7]) &&
2402 ic[-1].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[8])) {
2413 struct arm_instr_call *
ic,
int low_addr)
2415 #ifdef HOST_LITTLE_ENDIAN 2422 for (i=-5; i<0; i++) {
2423 if (ic[i].f !=
instr(store_w1_word_u1_p0_imm) ||
2424 ic[i].arg[0] != (size_t)(&cpu->
cd.
arm.
r[1]) ||
2429 if (ic[-5].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[8]) &&
2430 ic[-4].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[9]) &&
2431 ic[-3].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[10]) &&
2432 ic[-2].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[11]) &&
2433 ic[-1].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[6])) {
2444 struct arm_instr_call *
ic,
int low_addr)
2450 if (ic[0].f ==
instr(b__eq)) {
2452 if (ic[-1].arg[1] == 0)
2453 ic[-1].f =
instr(cmps_0_beq);
2454 else if (ic[-1].arg[1] & 0x80000000)
2455 ic[-1].f =
instr(cmps_neg_beq);
2457 ic[-1].f =
instr(cmps_pos_beq);
2461 if (ic[0].f ==
instr(b_samepage__eq)) {
2463 if (ic[-1].arg[1] == 0)
2464 ic[-1].f =
instr(cmps0_beq_samepage);
2466 ic[-1].f =
instr(cmps_beq_samepage);
2468 if (ic[-1].f ==
instr(tsts) &&
2469 !(ic[-1].arg[1] & 0x80000000)) {
2470 ic[-1].f =
instr(tsts_lo_beq_samepage);
2473 ic[-4].f ==
instr(load_w0_word_u1_p1_imm) &&
2474 ic[-4].arg[0] != ic[-4].arg[2] &&
2475 ic[-4].arg[1] == 0 &&
2476 ic[-4].arg[2] == ic[-3].arg[0] &&
2478 ic[-3].f ==
instr(teqs_bne_samepage) &&
2479 ic[-3].arg[1] == 0 &&
2480 ic[-2].f ==
instr(b_samepage__ne) &&
2481 ic[-1].f ==
instr(teqs) &&
2482 ic[-1].arg[0] != ic[-4].arg[0] &&
2483 ic[-1].arg[1] == 0) {
2484 ic[-4].f =
instr(netbsd_idle);
2486 if (ic[-1].f ==
instr(teqs)) {
2487 ic[-1].f =
instr(teqs_beq_samepage);
2491 if (ic[0].f ==
instr(b_samepage__ne)) {
2493 if (ic[-1].arg[1] == 0)
2494 ic[-1].f =
instr(cmps0_bne_samepage);
2496 ic[-1].f =
instr(cmps_bne_samepage);
2498 if (ic[-1].f ==
instr(tsts) &&
2499 !(ic[-1].arg[1] & 0x80000000)) {
2500 ic[-1].f =
instr(tsts_lo_bne_samepage);
2502 if (ic[-1].f ==
instr(teqs)) {
2503 ic[-1].f =
instr(teqs_bne_samepage);
2507 if (ic[0].f ==
instr(b_samepage__cc)) {
2509 ic[-1].f =
instr(cmps_bcc_samepage);
2511 if (ic[-1].f ==
instr(cmps_regshort)) {
2512 ic[-1].f =
instr(cmps_reg_bcc_samepage);
2516 if (ic[0].f ==
instr(b_samepage__hi)) {
2518 ic[-1].f =
instr(cmps_bhi_samepage);
2520 if (ic[-1].f ==
instr(cmps_regshort)) {
2521 ic[-1].f =
instr(cmps_reg_bhi_samepage);
2525 if (ic[0].f ==
instr(b_samepage__gt)) {
2527 ic[-1].f =
instr(cmps_bgt_samepage);
2531 if (ic[0].f ==
instr(b_samepage__le)) {
2533 ic[-1].f =
instr(cmps_ble_samepage);
2543 static void arm_switch_clear(
struct arm_instr_call *ic,
int rd,
2557 case 10: ic->f =
cond_instr(clear_r10);
break;
2558 case 11: ic->f =
cond_instr(clear_r11);
break;
2559 case 12: ic->f =
cond_instr(clear_r12);
break;
2560 case 13: ic->f =
cond_instr(clear_r13);
break;
2561 case 14: ic->f =
cond_instr(clear_r14);
break;
2566 static void arm_switch_mov1(
struct arm_instr_call *ic,
int rd,
2580 case 10: ic->f =
cond_instr(mov1_r10);
break;
2581 case 11: ic->f =
cond_instr(mov1_r11);
break;
2582 case 12: ic->f =
cond_instr(mov1_r12);
break;
2583 case 13: ic->f =
cond_instr(mov1_r13);
break;
2584 case 14: ic->f =
cond_instr(mov1_r14);
break;
2589 static void arm_switch_add1(
struct arm_instr_call *ic,
int rd,
2603 case 10: ic->f =
cond_instr(add1_r10);
break;
2604 case 11: ic->f =
cond_instr(add1_r11);
break;
2605 case 12: ic->f =
cond_instr(add1_r12);
break;
2606 case 13: ic->f =
cond_instr(add1_r13);
break;
2607 case 14: ic->f =
cond_instr(add1_r14);
break;
2625 uint32_t
addr, low_pc, iword, imm = 0;
2626 unsigned char *
page;
2627 unsigned char ib[4];
2628 int condition_code, main_opcode, secondary_opcode, s_bit, rn, rd, r8;
2629 int p_bit, u_bit, w_bit, l_bit, regform, rm, any_pc_reg;
2630 void (*samepage_function)(
struct cpu *,
struct arm_instr_call *);
2633 low_pc = ((size_t)ic - (
size_t)cpu->
cd.
arm.cur_ic_page)
2634 /
sizeof(
struct arm_instr_call);
2642 page = cpu->
cd.
arm.host_load[addr >> 12];
2646 memcpy(ib, page + (addr & 0xfff),
sizeof(ib));
2651 fatal(
"to_be_translated(): " 2652 "read failed: TODO\n");
2658 iword = ib[0] + (ib[1]<<8) + (ib[2]<<16) + (ib[3]<<24);
2660 iword = ib[3] + (ib[2]<<8) + (ib[1]<<16) + (ib[0]<<24);
2663 #define DYNTRANS_TO_BE_TRANSLATED_HEAD 2665 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD 2670 condition_code = iword >> 28;
2671 main_opcode = (iword >> 24) & 15;
2672 secondary_opcode = (iword >> 21) & 15;
2673 u_bit = iword & 0x00800000;
2674 w_bit = iword & 0x00200000;
2675 s_bit = l_bit = iword & 0x00100000;
2676 rn = (iword >> 16) & 15;
2677 rd = (iword >> 12) & 15;
2678 r8 = (iword >> 8) & 15;
2687 if ((iword >> 28) == 0xf) {
2689 if ((iword & 0xfc70f000) == 0xf450f000) {
2695 switch (main_opcode) {
2698 ic->f =
instr(blx_imm);
2701 ic->arg[1] = addr & 0xffc;
2704 ic->arg[0] = (iword & 0x00ffffff) << 2;
2706 if (ic->arg[0] & 0x02000000)
2707 ic->arg[0] |= 0xfc000000;
2708 if (main_opcode == 0xb)
2710 ic->arg[0] = (int32_t)(ic->arg[0] + 8 + 1);
2718 switch (main_opcode) {
2725 if ((iword & 0x0fc000f0) == 0x00000090) {
2730 if (iword & 0x00200000) {
2742 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2743 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2744 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[r8]);
2748 if ((iword & 0x0f8000f0) == 0x00800090) {
2752 fatal(
"TODO: sbit mull\n");
2759 if ((iword & 0x0f900ff0) == 0x01000050) {
2761 fatal(
"TODO: q{,d}{add,sub}\n");
2764 if ((iword & 0x0ff000d0) == 0x01200010) {
2775 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2776 ic->arg[2] = (addr & 0xffc) + 4;
2779 if ((iword & 0x0fb00ff0) == 0x1000090) {
2780 if (iword & 0x00400000)
2784 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2785 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2786 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2789 if ((iword & 0x0fff0ff0) == 0x016f0f10) {
2791 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2792 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2795 if ((iword & 0x0ff00090) == 0x01000080) {
2799 if ((iword & 0x0ff00090) == 0x01400080) {
2803 if ((iword & 0x0ff000b0) == 0x01200080) {
2807 if ((iword & 0x0ff0f090) == 0x01600080) {
2809 switch (iword & 0x60) {
2810 case 0x00: ic->f =
cond_instr(smulbb);
break;
2811 case 0x20: ic->f =
cond_instr(smultb);
break;
2812 case 0x40: ic->f =
cond_instr(smulbt);
break;
2815 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2816 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[r8]);
2817 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2820 if ((iword & 0x0ff0f0b0) == 0x012000a0) {
2824 if ((iword & 0x0fb0fff0) == 0x0120f000 ||
2825 (iword & 0x0fb0f000) == 0x0320f000) {
2828 if (iword & 0x02000000) {
2829 if (iword & 0x00400000)
2839 if (iword & 0x00400000)
2846 imm = (imm >> 2) | ((imm & 3) << 30);
2848 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2851 if (iword & (1<<16)) arg1 |= 0x000000ff;
2852 if (iword & (1<<17)) arg1 |= 0x0000ff00;
2853 if (iword & (1<<18)) arg1 |= 0x00ff0000;
2854 if (iword & (1<<19)) arg1 |= 0xff000000;
2857 fatal(
"msr no fields\n");
2864 if ((iword & 0x0fbf0fff) == 0x010f0000) {
2871 if (iword & 0x00400000)
2875 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2878 if ((iword & 0x0e000090) == 0x00000090) {
2879 regform = !(iword & 0x00400000);
2880 imm = ((iword >> 4) & 0xf0) | (iword & 0xf);
2881 p_bit = main_opcode & 1;
2882 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2883 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2886 condition_code + (l_bit? 16 : 0)
2887 + (iword & 0x40? 32 : 0)
2889 + (iword & 0x20? 128 : 0)
2890 + (u_bit? 256 : 0) + (p_bit? 512 : 0)
2891 + (regform? 1024 : 0)];
2893 ic->arg[0] = (size_t)
2895 if (!l_bit && rd ==
ARM_PC)
2896 ic->arg[2] = (size_t)
2900 condition_code + (l_bit? 16 : 0)
2901 + (iword & 0x40? 32 : 0)
2903 + (iword & 0x20? 128 : 0)
2904 + (u_bit? 256 : 0) + (p_bit? 512 : 0)
2905 + (regform? 1024 : 0)];
2907 ic->arg[1] = (size_t)(
void *)
arm_r[iword & 0xf];
2913 if (iword & 0x80 && !(main_opcode & 2) && iword & 0x10) {
2915 fatal(
"reg form blah blah\n");
2920 if ((iword & 0x0ff000f0) == 0x01200070) {
2922 ic->arg[0] = addr & 0xfff;
2927 if ((iword & 0x0fffffff) == 0x01a0f00e) {
2936 if ((iword & 0x0fff0ff0) == 0x01a00000 && rd !=
ARM_PC) {
2939 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2942 ic->arg[0] = (addr & 0xfff) + 8;
2944 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2949 if ((iword & 0x0fff0fff) == 0x03a00000 && rd !=
ARM_PC) {
2950 arm_switch_clear(ic, rd, condition_code);
2955 if ((iword & 0x0fff0fff) == 0x03a00001 && rd !=
ARM_PC) {
2956 arm_switch_mov1(ic, rd, condition_code);
2961 if ((iword & 0x0ff00fff) == 0x02800001 && rd !=
ARM_PC 2963 arm_switch_add1(ic, rd, condition_code);
2970 if ((main_opcode & 2) == 0)
2983 if ((secondary_opcode >= 2 && secondary_opcode <= 7)
2984 || secondary_opcode==0xa || secondary_opcode==0xb)
2986 ic->arg[1] = (size_t)(
void *)
arm_r[(iword & 0xfff) + q];
2993 imm = (imm >> 2) | ((imm & 3) << 30);
2995 if (steps != 0 && (imm != 0 && imm < 256)) {
2997 fatal(
"TODO: see cpu_arm_instr_dpi; non-zero steps but still under 256 is not implemented yet\n");
3005 if (secondary_opcode == 0xf && !regform) {
3006 secondary_opcode = 0xd;
3007 ic->arg[1] = ~ic->arg[1];
3010 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
3011 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rd]);
3016 if (!any_pc_reg && regform && (iword & 0xfff) <
ARM_PC) {
3017 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rm]);
3019 16 * secondary_opcode + (s_bit? 256 : 0)];
3022 16 * secondary_opcode + (s_bit? 256 : 0) +
3023 (any_pc_reg? 512 : 0) + (regform? 1024 : 0)];
3025 if (ic->f ==
instr(eor_regshort))
3027 if (iword == 0xe113000c)
3035 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
3036 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rd]);
3039 & 0x3f0) + condition_code];
3042 if (!l_bit && rd ==
ARM_PC)
3046 0x3f0) + condition_code];
3048 imm = iword & 0xfff;
3049 if (main_opcode < 6)
3052 ic->arg[1] = (size_t)(
void *)
arm_r[iword & 0xfff];
3053 if ((iword & 0x0e000010) == 0x06000010) {
3056 ic->arg[0] = addr & 0xfff;
3059 if (rn ==
ARM_PC && rd !=
ARM_PC && main_opcode < 6 && l_bit) {
3060 unsigned char *p =
page;
3061 int ofs = (addr & 0xfff) + 8, max = 0xffc;
3062 int b_bit = iword & 0x00400000;
3066 ofs += (iword & 0xfff);
3068 ofs -= (iword & 0xfff);
3071 if (ofs >= 0 && ofs <= max && p != NULL) {
3072 unsigned char cbuf[4];
3073 int len = b_bit? 1 : 4;
3074 uint32_t x, a = (addr & 0xfffff000) | ofs;
3077 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rd]);
3079 memcpy(cbuf, p + (a & 0xfff), len);
3085 x = cbuf[0] + (cbuf[1]<<8) +
3086 (cbuf[2]<<16) + (cbuf[3]<<24);
3088 x = cbuf[3] + (cbuf[2]<<8) +
3089 (cbuf[1]<<16) + (cbuf[0]<<24);
3095 if (iword == 0xe4b09004)
3097 if (iword == 0xe4a17004)
3103 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
3104 ic->arg[1] = (size_t)iword;
3110 #if defined(HOST_LITTLE_ENDIAN) && !defined(GATHER_BDT_STATISTICS) 3122 int i = 0, j = iword;
3123 j = ((j & 0x00800000) >> 16) | ((j & 0x00100000) >> 14)
3124 | ((j & 0x00040000) >> 13) | ((j & 0x00010000) >> 12)
3125 | ((j & 0x00000100) >> 5) | ((j & 0x00000040) >> 4)
3126 | ((j & 0x00000010) >> 3) | ((j & 0x00000004) >> 2);
3127 while (multi_opcode[j][i] != 0) {
3128 if ((iword & 0x0fffffff) ==
3129 multi_opcode[j][i]) {
3131 [i*16 + condition_code];
3140 fatal(
"TODO: bdt with PC as base\n");
3147 if (main_opcode == 0x0a) {
3152 if (condition_code == 0xe &&
3156 if (iword == 0xcaffffed)
3157 cpu->
cd.
arm.combination_check =
3159 if (iword == 0xaafffff9)
3160 cpu->
cd.
arm.combination_check =
3175 ic->arg[1] = addr & 0xffc;
3176 ic->arg[2] = (addr & 0xffc) + 4;
3178 ic->arg[0] = (iword & 0x00ffffff) << 2;
3180 if (ic->arg[0] & 0x02000000)
3181 ic->arg[0] |= 0xfc000000;
3185 ic->arg[0] = (int32_t)(ic->arg[0] + 8);
3194 uint32_t mask_within_page =
3198 uint32_t old_pc =
addr;
3199 uint32_t new_pc = old_pc + (int32_t)ic->arg[0];
3200 if ((old_pc & ~mask_within_page) ==
3201 (new_pc & ~mask_within_page)) {
3202 ic->f = samepage_function;
3203 ic->arg[0] = (size_t) (
3204 cpu->
cd.
arm.cur_ic_page +
3205 ((new_pc & mask_within_page) >>
3207 ic->arg[1] = (size_t) (
3208 cpu->
cd.
arm.cur_ic_page +
3209 (((addr & mask_within_page) + 4) >>
3211 }
else if (main_opcode == 0x0a) {
3213 ic->arg[0] += ic->arg[1];
3217 if (main_opcode == 0xa && (condition_code <= 1
3218 || condition_code == 3 || condition_code == 8
3219 || condition_code == 12 || condition_code == 13))
3222 if (iword == 0x1afffffc)
3226 if (iword == 0x8afffffa)
3227 cpu->
cd.
arm.combination_check =
3237 if ((iword & 0x0fe00fff) == 0x0c400000) {
3240 fatal(
"TODO: mar/mra DSP instructions!\n");
3245 if ((iword & 0x0fe00000) == 0x0c400000) {
3247 fatal(
"MCRR/MRRC: TODO\n");
3259 ic->arg[0] = addr & 0xfff;
3262 fatal(
"LDC/STC: TODO\n");
3268 if ((iword & 0x0ff00ff0) == 0x0e200010) {
3272 fatal(
"TODO: mia* DSP instructions!\n");
3284 if (iword == 0xee070f9a)
3285 cpu->
cd.
arm.combination_check =
3293 ic->arg[0] = addr & 0xfff;
3294 if (iword == 0xef8c64eb) {
3296 ic->f =
instr(reboot);
3297 }
else if (iword == 0xef8c64be) {
3299 ic->f =
instr(openfirmware);
3308 #define DYNTRANS_TO_BE_TRANSLATED_TAIL 3310 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
void * zeroed_alloc(size_t s)
void(* arm_load_store_instr_pc[1024])(struct cpu *, struct arm_instr_call *)
void fatal(const char *fmt,...)
void COMBINE() netbsd_memset(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
void arm_save_register_bank(struct cpu *cpu)
void COMBINE() netbsd_memcpy(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
uint32_t arm_r_r3_t0_c0(struct cpu *cpu, struct arm_instr_call *ic)
void COMBINE() netbsd_copyout(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
void(* arm_load_store_instr_3_pc[2048])(struct cpu *, struct arm_instr_call *)
void COMBINE() nop(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
struct arm_instr_call * ic
void arm_push(struct cpu *cpu, uint32_t *np, int p_bit, int u_bit, int s_bit, int w_bit, uint16_t regs)
void f(int s, int func, int only_name)
void arm_load_register_bank(struct cpu *cpu)
void COMBINE() netbsd_copyin(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
uint32_t default_r8_r14[7]
void(* arm_dpi_instr_regshort[2 *16 *16])(struct cpu *, struct arm_instr_call *)
void COMBINE() netbsd_cacheclean2(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
uint32_t is_userpage[N_VPH32_ENTRIES/32]
#define EMUL_LITTLE_ENDIAN
int translation_readahead
#define ARM_IC_ENTRIES_PER_PAGE
void arm_pop(struct cpu *cpu, uint32_t *np, int p_bit, int u_bit, int s_bit, int w_bit, uint32_t iw)
void arm_exception(struct cpu *cpu, int exception_nr)
void COMBINE() beq_etc(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
#define ARM_INSTR_ALIGNMENT_SHIFT
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
#define ARM_EXCEPTION_SWI
uint32_t(* arm_r[8192])(struct cpu *, struct arm_instr_call *)
void(** multi_opcode_f[256])(struct cpu *, struct arm_instr_call *)
void COMBINE() netbsd_scanc(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
int of_emul(struct cpu *cpu)
else instr() bdt_store(cpu, ic)
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
void COMBINE() xchg(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
#define ARM_EXCEPTION_PREF_ABT
void cpu_functioncall_trace_return(struct cpu *cpu)
void(* arm_cond_instr_b_samepage[16])(struct cpu *, struct arm_instr_call *)
void arm_instr_nop(struct cpu *, struct arm_instr_call *)
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
#define CACHE_INSTRUCTION
uint32_t * multi_opcode[256]
void(* arm_dpi_instr[2 *2 *2 *16 *16])(struct cpu *, struct arm_instr_call *)
addr & if(addr >=0x24 &&page !=NULL)
#define N_SAFE_DYNTRANS_LIMIT
void(* arm_load_store_instr_3[2048])(struct cpu *, struct arm_instr_call *)
void arm_mcr_mrc(struct cpu *cpu, uint32_t iword)
void(* arm_load_store_instr[1024])(struct cpu *, struct arm_instr_call *)
void COMBINE() netbsd_cacheclean(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
void arm_cdp(struct cpu *cpu, uint32_t iword)
#define ARM_EXCEPTION_UND
else instr() bdt_load(cpu, ic)