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_nop }; 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;
240 cpu->
pc = (uint32_t)((
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[0]);
243 quick_pc_to_pointers_arm(
cpu);
257 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic->arg[0];
260 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
264 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
268 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
272 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
276 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
280 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
284 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
288 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
293 (
struct arm_instr_call *)
ic->arg[0] :
294 (
struct arm_instr_call *)
ic->arg[1];
297 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
302 (
struct arm_instr_call *)
ic->arg[0] :
303 (
struct arm_instr_call *)
ic->arg[1];
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 *)
319 struct arm_instr_call *) = {
320 arm_instr_b_samepage__eq, arm_instr_b_samepage__ne,
321 arm_instr_b_samepage__cs, arm_instr_b_samepage__cc,
322 arm_instr_b_samepage__mi, arm_instr_b_samepage__pl,
323 arm_instr_b_samepage__vs, arm_instr_b_samepage__vc,
324 arm_instr_b_samepage__hi, arm_instr_b_samepage__ls,
325 arm_instr_b_samepage__ge, arm_instr_b_samepage__lt,
326 arm_instr_b_samepage__gt, arm_instr_b_samepage__le,
348 fatal(
"[ ARM pc misaligned? 0x%08x ]\n", (
int)
cpu->
pc);
351 cpu->
cd.
arm.next_ic = ¬hing_call;
356 quick_pc_to_pointers_arm(
cpu);
379 fatal(
"[ ARM pc misaligned? 0x%08x ]\n", (
int)
cpu->
pc);
382 cpu->
cd.
arm.next_ic = ¬hing_call;
389 quick_pc_to_pointers_arm(
cpu);
401 uint32_t pc = ((uint32_t)
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[1];
405 cpu->
pc = pc + (int32_t)
ic->arg[0];
408 quick_pc_to_pointers_arm(
cpu);
420 uint32_t lr = ((uint32_t)
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[2];
434 fatal(
"[ ARM pc misaligned? 0x%08x ]\n", (
int)
cpu->
pc);
437 cpu->
cd.
arm.next_ic = ¬hing_call;
442 quick_pc_to_pointers_arm(
cpu);
454 uint32_t pc = ((uint32_t)
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[1];
458 cpu->
pc = pc + (int32_t)
ic->arg[0];
463 quick_pc_to_pointers_arm(
cpu);
476 ((uint32_t)
cpu->
pc & 0xfffff000) + (int32_t)
ic->arg[2];
477 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic->arg[0];
489 uint32_t low_pc, lr = (
cpu->
pc & 0xfffff000) +
ic->arg[2];
493 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic->arg[0];
496 low_pc = ((size_t)
cpu->
cd.
arm.next_ic - (
size_t)
497 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
516 uint32_t rm =
reg(
ic->arg[0]);
517 int i = 32, n = 0, j;
519 if (rm & 0xff000000) {
520 for (j=0; j<8; j++) {
557 if (result & 0x80000000)
559 reg(
ic->arg[0]) = result;
572 uint32_t iw =
ic->arg[0];
574 rd = (iw >> 16) & 15; rn = (iw >> 12) & 15,
575 rs = (iw >> 8) & 15; rm = iw & 15;
583 uint32_t iw =
ic->arg[0];
585 rd = (iw >> 16) & 15; rn = (iw >> 12) & 15,
586 rs = (iw >> 8) & 15; rm = iw & 15;
606 uint32_t iw; uint64_t tmp;
int u_bit, a_bit;
608 u_bit = iw & 0x00400000; a_bit = iw & 0x00200000;
611 tmp = (int64_t)(int32_t)tmp
612 * (int64_t)(int32_t)
cpu->
cd.
arm.
r[(iw >> 8) & 15];
614 tmp *= (uint64_t)
cpu->
cd.
arm.
r[(iw >> 8) & 15];
616 uint64_t x = ((uint64_t)
cpu->
cd.
arm.
r[(iw >> 16) & 15] << 32)
619 cpu->
cd.
arm.
r[(iw >> 16) & 15] = (x >> 32);
622 cpu->
cd.
arm.
r[(iw >> 16) & 15] = (tmp >> 32);
638 reg(
ic->arg[2]) = (int32_t)(int16_t)
reg(
ic->arg[0]) *
639 (int32_t)(int16_t)
reg(
ic->arg[1]);
644 reg(
ic->arg[2]) = (int32_t)(int16_t)(
reg(
ic->arg[0]) >> 16) *
645 (int32_t)(int16_t)
reg(
ic->arg[1]);
650 reg(
ic->arg[2]) = (int32_t)(int16_t)
reg(
ic->arg[0]) *
651 (int32_t)(int16_t)(
reg(
ic->arg[1]) >> 16);
656 reg(
ic->arg[2]) = (int32_t)(int16_t)(
reg(
ic->arg[0]) >> 16) *
657 (int32_t)(int16_t)(
reg(
ic->arg[1]) >> 16);
683 reg(
ic->arg[1]) = ((uint32_t)
cpu->
pc&0xfffff000) + (int32_t)
ic->arg[0];
696 uint32_t old_pc, mask_within_page;
711 if ((old_pc & ~mask_within_page) == (
cpu->
pc & ~mask_within_page)) {
716 quick_pc_to_pointers_arm(
cpu);
723 quick_pc_to_pointers_arm(
cpu);
740 uint32_t mask =
ic->arg[1];
749 uint32_t new_value =
ic->arg[0];
754 if (switch_register_banks)
762 if (switch_register_banks)
774 uint32_t mask =
ic->arg[1];
775 uint32_t new_value =
ic->arg[0];
797 default:
fatal(
"msr_spsr: unimplemented mode %i\n",
801 uint32_t old_pc, low_pc = ((size_t)
ic - (
size_t)
802 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
806 printf(
"msr_spsr: old pc = 0x%08" PRIx32
"\n", old_pc);
849 default:
fatal(
"mrs_spsr: unimplemented mode %i\n",
864 uint32_t low_pc = ((size_t)
ic - (
size_t)
865 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
872 uint32_t low_pc = ((size_t)
ic - (
size_t)
873 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
891 quick_pc_to_pointers_arm(
cpu);
902 cpu->
cd.
arm.next_ic = ¬hing_call;
912 cpu->
pc &= 0xfffff000;
925 cpu->
pc &= 0xfffff000;
938 cpu->
pc &= 0xfffff000;
958 uint32_t low_pc = ((size_t)
ic - (
size_t)
959 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
965 fatal(
"swp: load failed\n");
968 data = d[0] + (d[1] << 8) + (d[2] << 16) + (d[3] << 24);
969 data2 =
reg(
ic->arg[1]);
970 d[0] = data2; d[1] = data2 >> 8; d[2] = data2 >> 16; d[3] = data2 >> 24;
973 fatal(
"swp: store failed\n");
985 uint32_t low_pc = ((size_t)
ic - (
size_t)
986 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
992 fatal(
"swp: load failed\n");
996 d[0] =
reg(
ic->arg[1]);
999 fatal(
"swp: store failed\n");
1008 struct arm_instr_call *);
1009 X(store_w1_word_u1_p0_imm);
1010 X(store_w0_byte_u1_p0_imm);
1011 X(store_w0_word_u1_p0_imm);
1012 X(store_w0_word_u1_p1_imm);
1013 X(load_w0_word_u1_p0_imm);
1014 X(load_w0_word_u1_p1_imm);
1015 X(load_w1_word_u1_p0_imm);
1016 X(load_w0_byte_u1_p1_imm);
1017 X(load_w0_byte_u1_p1_reg);
1018 X(load_w1_byte_u1_p1_imm);
1021 struct arm_instr_call *);
1024 struct arm_instr_call *);
1027 struct arm_instr_call *);
1029 extern uint32_t (*
arm_r[8192])(
struct cpu *,
struct arm_instr_call *);
1032 extern void (*
arm_dpi_instr[2 * 2 * 2 * 16 * 16])(
struct cpu *,
1033 struct arm_instr_call *);
1035 struct arm_instr_call *);
1057 unsigned char data[4];
1058 uint32_t *np = (uint32_t *)ic->arg[0];
1059 uint32_t
addr = *np, low_pc;
1060 unsigned char *
page;
1061 uint32_t iw = ic->arg[1];
1062 int p_bit = iw & 0x01000000;
1063 int u_bit = iw & 0x00800000;
1064 int s_bit = iw & 0x00400000;
1065 int w_bit = iw & 0x00200000;
1066 int i, return_flag = 0;
1067 uint32_t new_values[16];
1069 #ifdef GATHER_BDT_STATISTICS
1071 update_bdt_statistics(iw);
1075 low_pc = ((size_t)ic - (
size_t)
1076 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1083 fatal(
"[ bdt_load: s-bit: in usermode? ]\n");
1092 for (i=(u_bit? 0 : 15); i>=0 && i<=15; i+=(u_bit? 1 : -1)) {
1095 if (!((iw >> i) & 1)) {
1102 addr +=
sizeof(uint32_t);
1104 addr -=
sizeof(uint32_t);
1109 uint32_t *p32 = (uint32_t *)
page;
1110 value = p32[(
addr & 0xfff) >> 2];
1113 #ifdef HOST_LITTLE_ENDIAN 1118 value = ((value & 0xff) << 24) |
1119 ((value & 0xff00) << 8) |
1120 ((value & 0xff0000) >> 8) |
1121 ((value & 0xff000000) >> 24);
1130 (data[1] << 8) + (data[2] << 16)
1134 (data[2] << 8) + (data[1] << 16)
1139 new_values[i] = value;
1143 addr +=
sizeof(uint32_t);
1145 addr -=
sizeof(uint32_t);
1149 for (i=(u_bit? 0 : 15); i>=0 && i<=15; i+=(u_bit? 1 : -1)) {
1150 if (!((iw >> i) & 1)) {
1156 cpu->
cd.
arm.
r[i] = new_values[i];
1161 cpu->
cd.
arm.
r[i] = new_values[i];
1164 if (i >= 8 && i <= 14)
1168 cpu->
cd.
arm.
r[i] = new_values[i];
1174 if (i >= 13 && i <= 14)
1178 cpu->
cd.
arm.
r[i] = new_values[i];
1189 int switch_register_banks;
1202 default:
fatal(
"bdt_load: unimplemented mode %i\n",
1210 if (switch_register_banks)
1216 if (switch_register_banks)
1230 quick_pc_to_pointers_arm(cpu);
1244 unsigned char data[4];
1245 uint32_t *np = (uint32_t *)ic->arg[0];
1246 uint32_t low_pc, value,
addr = *np;
1247 uint32_t iw = ic->arg[1];
1248 unsigned char *
page;
1249 int p_bit = iw & 0x01000000;
1250 int u_bit = iw & 0x00800000;
1251 int s_bit = iw & 0x00400000;
1252 int w_bit = iw & 0x00200000;
1255 #ifdef GATHER_BDT_STATISTICS
1257 update_bdt_statistics(iw);
1261 low_pc = ((size_t)ic - (
size_t)
1262 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1266 for (i=(u_bit? 0 : 15); i>=0 && i<=15; i+=(u_bit? 1 : -1)) {
1267 if (!((iw >> i) & 1)) {
1272 value = cpu->
cd.
arm.
r[i];
1277 if (i >= 8 && i <= 14)
1284 if (i >= 13 && i <= 14)
1295 value = cpu->
pc + 12;
1299 addr +=
sizeof(uint32_t);
1301 addr -=
sizeof(uint32_t);
1306 uint32_t *p32 = (uint32_t *)
page;
1309 #ifdef HOST_LITTLE_ENDIAN 1314 value = ((value & 0xff) << 24) |
1315 ((value & 0xff00) << 8) |
1316 ((value & 0xff0000) >> 8) |
1317 ((value & 0xff000000) >> 24);
1318 p32[(
addr & 0xfff) >> 2] = value;
1322 data[1] = value >> 8;
1323 data[2] = value >> 16;
1324 data[3] = value >> 24;
1326 data[0] = value >> 24;
1327 data[1] = value >> 16;
1328 data[2] = value >> 8;
1340 addr +=
sizeof(uint32_t);
1342 addr -=
sizeof(uint32_t);
1354 extern void (**
multi_opcode_f[256])(
struct cpu *,
struct arm_instr_call *);
1355 X(multi_0x08b15018);
1356 X(multi_0x08ac000c__ge);
1357 X(multi_0x08a05018);
1375 unsigned char *
page;
1387 cpu->
cd.
arm.next_ic = &ic[17];
1392 if ((addr & 0xfff) + 128 > 0x1000)
1401 page = cpu->
cd.
arm.host_store[addr >> 12];
1407 memset(page + (addr & 0xfff), 0, 128);
1418 cpu->
cd.
arm.next_ic = &ic[18];
1436 unsigned char *page_0, *page_1;
1437 uint32_t addr_r0, addr_r1;
1440 addr_r0 = cpu->
cd.
arm.
r[0];
1441 addr_r1 = cpu->
cd.
arm.
r[1];
1446 if ((addr_r0 & 0xfff) + 32 > 0x1000 ||
1447 (addr_r1 & 0xfff) + 32 > 0x1000) {
1448 instr(multi_0x08b15018)(cpu,
ic);
1452 page_0 = cpu->
cd.
arm.host_store[addr_r0 >> 12];
1453 page_1 = cpu->
cd.
arm.host_store[addr_r1 >> 12];
1456 if (page_0 == NULL || page_1 == NULL) {
1457 instr(multi_0x08b15018)(cpu,
ic);
1461 memcpy(page_0 + (addr_r0 & 0xfff),
1462 page_1 + (addr_r1 & 0xfff), 32);
1463 cpu->
cd.
arm.
r[0] = addr_r0 + 32;
1464 cpu->
cd.
arm.
r[1] = addr_r1 + 32;
1468 instr(subs)(cpu, ic + 4);
1477 cpu->
cd.
arm.next_ic = &ic[6];
1494 uint32_t r1 = cpu->
cd.
arm.
r[1];
1498 cpu->
cd.
arm.next_ic = &ic[4];
1516 cpu->
cd.
arm.next_ic = &ic[5];
1533 instr(load_w0_byte_u1_p1_imm)(cpu,
ic);
1537 t = page[cpu->
cd.
arm.
r[1] & 0xfff];
1539 page = cpu->
cd.
arm.host_load[t >> 12];
1542 instr(load_w0_byte_u1_p1_imm)(cpu,
ic);
1546 cpu->
cd.
arm.
r[3] = page[t & 0xfff];
1554 cpu->
cd.
arm.next_ic = &ic[3];
1571 uint32_t rY =
reg(ic[0].arg[0]);
1572 uint32_t rZ =
reg(ic[3].arg[0]);
1576 p = (uint32_t *) cpu->
cd.
arm.host_load[rY >> 12];
1578 instr(load_w0_word_u1_p1_imm)(cpu,
ic);
1582 rX = p[(rY & 0xfff) >> 2];
1588 instr(load_w0_word_u1_p1_imm)(cpu,
ic);
1596 uint32_t low_pc = ((size_t)ic - (
size_t)
1597 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1610 cpu->
cd.
arm.next_ic = ¬hing_call;
1614 cpu->
cd.
arm.next_ic = &ic[5];
1627 unsigned int n_loops = 0;
1628 uint32_t rY, rX =
reg(ic[0].arg[0]);
1633 p = cpu->
cd.
arm.host_load[rX >> 12];
1636 instr(load_w1_byte_u1_p1_imm)(cpu,
ic);
1640 rY =
reg(ic[0].arg[2]) = p[rX & 0xfff];
1641 reg(ic[0].arg[0]) = rX;
1651 cpu->
cd.
arm.next_ic = &ic[3];
1664 uint32_t tmp =
reg(ic[0].arg[0]);
1666 cpu->
cd.
arm.next_ic = &ic[3];
1667 reg(ic[0].arg[0]) =
reg(ic[1].arg[0]);
1668 reg(ic[1].arg[0]) = tmp;
1684 uint32_t r0 = cpu->
cd.
arm.
r[0], ofs = (r0 & 0xffc), index = r0 >> 12;
1685 unsigned char *p = cpu->
cd.
arm.host_load[index];
1686 uint32_t *p32 = (uint32_t *) p, *q32;
1689 if (ofs > 0x1000 - 6*4 || !ok || p == NULL) {
1690 instr(load_w1_word_u1_p0_imm)(cpu,
ic);
1695 q32[0] = p32[ofs+2];
1696 q32[1] = p32[ofs+3];
1697 q32[2] = p32[ofs+4];
1698 q32[3] = p32[ofs+5];
1699 q32[4] = p32[ofs+0];
1700 q32[5] = p32[ofs+1];
1701 cpu->
cd.
arm.
r[0] = r0 + 24;
1703 cpu->
cd.
arm.next_ic = &ic[6];
1719 uint32_t r1 = cpu->
cd.
arm.
r[1], ofs = (r1 & 0xffc), index = r1 >> 12;
1720 unsigned char *p = cpu->
cd.
arm.host_store[index];
1721 uint32_t *p32 = (uint32_t *) p, *q32;
1724 if (ofs > 0x1000 - 6*4 || !ok || p == NULL) {
1725 instr(store_w1_word_u1_p0_imm)(cpu,
ic);
1731 p32[ofs+1] = q32[3];
1732 p32[ofs+2] = q32[4];
1733 p32[ofs+3] = q32[5];
1734 p32[ofs+4] = q32[0];
1735 p32[ofs+5] = q32[1];
1736 cpu->
cd.
arm.
r[1] = r1 + 24;
1738 cpu->
cd.
arm.next_ic = &ic[6];
1745 X(cmps0_beq_samepage)
1747 uint32_t a =
reg(ic->arg[0]);
1756 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1758 cpu->
cd.
arm.next_ic = &ic[2];
1765 X(cmps_beq_samepage)
1767 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1770 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1771 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1775 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1777 cpu->
cd.
arm.next_ic = &ic[2];
1789 uint32_t a =
reg(ic->arg[0]);
1793 cpu->
pc = (uint32_t)(((uint32_t)cpu->
pc & 0xfffff000)
1794 + (int32_t)ic[1].arg[0]);
1795 quick_pc_to_pointers_arm(cpu);
1799 cpu->
cd.
arm.next_ic = &ic[2];
1804 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1807 if ((int32_t)a < 0 && (int32_t)c >= 0)
1811 cpu->
pc = (uint32_t)(((uint32_t)cpu->
pc & 0xfffff000)
1812 + (int32_t)ic[1].arg[0]);
1813 quick_pc_to_pointers_arm(cpu);
1815 cpu->
cd.
arm.next_ic = &ic[2];
1822 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1825 if ((int32_t)a >= 0 && (int32_t)c < 0)
1829 cpu->
pc = (uint32_t)(((uint32_t)cpu->
pc & 0xfffff000)
1830 + (int32_t)ic[1].arg[0]);
1831 quick_pc_to_pointers_arm(cpu);
1833 cpu->
cd.
arm.next_ic = &ic[2];
1843 X(cmps0_bne_samepage)
1845 uint32_t a =
reg(ic->arg[0]);
1854 cpu->
cd.
arm.next_ic = &ic[2];
1856 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1863 X(cmps_bne_samepage)
1865 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1868 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1869 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1873 cpu->
cd.
arm.next_ic = &ic[2];
1877 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1885 X(cmps_bcc_samepage)
1887 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1894 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1895 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1898 cpu->
cd.
arm.next_ic = &ic[2];
1900 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1907 X(cmps_reg_bcc_samepage)
1909 uint32_t a =
reg(ic->arg[0]), b =
reg(ic->arg[1]), c = a - b;
1916 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1917 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1920 cpu->
cd.
arm.next_ic = &ic[2];
1922 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1929 X(cmps_bhi_samepage)
1931 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1938 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1939 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1942 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1944 cpu->
cd.
arm.next_ic = &ic[2];
1951 X(cmps_reg_bhi_samepage)
1953 uint32_t a =
reg(ic->arg[0]), b =
reg(ic->arg[1]), c = a - b;
1960 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1961 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1964 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1966 cpu->
cd.
arm.next_ic = &ic[2];
1973 X(cmps_bgt_samepage)
1975 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
1982 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
1983 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
1985 if ((int32_t)a > (int32_t)b)
1986 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
1988 cpu->
cd.
arm.next_ic = &ic[2];
1995 X(cmps_ble_samepage)
1997 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a - b;
2004 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2005 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2007 if ((int32_t)a <= (int32_t)b)
2008 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *) ic[1].arg[0];
2010 cpu->
cd.
arm.next_ic = &ic[2];
2017 X(teqs_beq_samepage)
2019 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a ^ b;
2024 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2029 cpu->
cd.
arm.next_ic = &ic[2];
2038 X(tsts_lo_beq_samepage)
2040 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a & b;
2046 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2049 cpu->
cd.
arm.next_ic = &ic[2];
2056 X(teqs_bne_samepage)
2058 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a ^ b;
2068 cpu->
cd.
arm.next_ic = &ic[2];
2070 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2079 X(tsts_lo_bne_samepage)
2081 uint32_t a =
reg(ic->arg[0]), b = ic->arg[1], c = a & b;
2087 cpu->
cd.
arm.next_ic = &ic[2];
2089 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2104 quick_pc_to_pointers_arm(cpu);
2121 struct arm_instr_call *
ic,
int low_addr)
2123 #ifdef HOST_LITTLE_ENDIAN 2129 for (i=-16; i<=-1; i++)
2130 if (ic[i].f !=
instr(multi_0x08ac000c__ge))
2132 if (ic[-17].f ==
instr(subs) &&
2133 ic[-17].arg[0]==ic[-17].arg[2] && ic[-17].arg[1] == 128 &&
2134 ic[ 0].f ==
instr(b_samepage__gt) &&
2135 ic[ 0].arg[0] == (size_t)&ic[-17]) {
2152 #ifdef HOST_LITTLE_ENDIAN 2157 if (ic[-5].f==
instr(multi_0x08b15018) &&
2158 ic[-4].f==
instr(multi_0x08a05018) &&
2159 ic[-3].f==
instr(multi_0x08b15018) &&
2160 ic[-2].f==
instr(multi_0x08a05018) &&
2161 ic[-1].f ==
instr(subs) &&
2162 ic[-1].arg[0]==ic[-1].arg[2] && ic[-1].arg[1] == 0x20 &&
2163 ic[ 0].f ==
instr(b_samepage__ge) &&
2164 ic[ 0].arg[0] == (size_t)&ic[-5]) {
2178 struct arm_instr_call *
ic,
int low_addr)
2184 if (ic[-3].f==
instr(load_w0_word_u1_p0_imm) &&
2185 ic[-2].f ==
instr(subs) &&
2186 ic[-2].arg[0]==ic[-2].arg[2] && ic[-2].arg[1] == 0x20 &&
2187 ic[-1].f ==
instr(b_samepage__ne) &&
2188 ic[-1].arg[0] == (size_t)&ic[-3]) {
2201 struct arm_instr_call *
ic,
int low_addr)
2207 if (ic[-4].f ==
instr(mcr_mrc) && ic[-4].arg[0] == 0xee070f3a &&
2208 ic[-3].f ==
instr(mcr_mrc) && ic[-3].arg[0] == 0xee070f36 &&
2209 ic[-2].f ==
instr(add) &&
2210 ic[-2].arg[0]==ic[-2].arg[2] && ic[-2].arg[1] == 0x20 &&
2211 ic[-1].f ==
instr(subs) &&
2212 ic[-1].arg[0]==ic[-1].arg[2] && ic[-1].arg[1] == 0x20) {
2223 struct arm_instr_call *
ic,
int low_addr)
2231 if (ic[-2].f ==
instr(load_w0_byte_u1_p1_imm) &&
2232 ic[-2].arg[0] == (size_t)(&cpu->
cd.
arm.
r[1]) &&
2233 ic[-2].arg[1] == 0 &&
2234 ic[-2].arg[2] == (size_t)(&cpu->
cd.
arm.
r[3]) &&
2235 ic[-1].f ==
instr(load_w0_byte_u1_p1_reg) &&
2236 ic[-1].arg[0] == (size_t)(&cpu->
cd.
arm.
r[2]) &&
2237 ic[-1].arg[1] == (size_t)arm_r_r3_t0_c0 &&
2238 ic[-1].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[3])) {
2248 struct arm_instr_call *
ic,
int low_addr)
2256 if (ic[-2].f ==
instr(load_w1_byte_u1_p1_imm) &&
2257 ic[-2].arg[1] == 1 &&
2258 ic[-2].arg[2] == (size_t)(&cpu->
cd.
arm.
r[3]) &&
2260 ic[-1].arg[0] == (size_t)(&cpu->
cd.
arm.
r[3]) &&
2261 ic[-1].arg[1] == 0) {
2271 struct arm_instr_call *
ic,
int low_addr)
2280 a = ic[-2].arg[0]; b = ic[-1].arg[0];
2282 if (ic[-2].f ==
instr(eor_regshort) &&
2283 ic[-1].f ==
instr(eor_regshort) &&
2284 ic[-2].arg[0] == a && ic[-2].arg[1] == b && ic[-2].arg[2] == b &&
2285 ic[-1].arg[0] == b && ic[-1].arg[1] == a && ic[-1].arg[2] == a &&
2286 ic[ 0].arg[0] == a && ic[ 0].arg[1] == b && ic[ 0].arg[2] == b) {
2296 struct arm_instr_call *
ic,
int low_addr)
2298 #ifdef HOST_LITTLE_ENDIAN 2305 for (i=-5; i<0; i++) {
2306 if (ic[i].f !=
instr(load_w1_word_u1_p0_imm) ||
2307 ic[i].arg[0] != (size_t)(&cpu->
cd.
arm.
r[0]) ||
2312 if (ic[-5].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[10]) &&
2313 ic[-4].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[11]) &&
2314 ic[-3].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[6]) &&
2315 ic[-2].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[7]) &&
2316 ic[-1].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[8])) {
2327 struct arm_instr_call *
ic,
int low_addr)
2329 #ifdef HOST_LITTLE_ENDIAN 2336 for (i=-5; i<0; i++) {
2337 if (ic[i].f !=
instr(store_w1_word_u1_p0_imm) ||
2338 ic[i].arg[0] != (size_t)(&cpu->
cd.
arm.
r[1]) ||
2343 if (ic[-5].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[8]) &&
2344 ic[-4].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[9]) &&
2345 ic[-3].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[10]) &&
2346 ic[-2].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[11]) &&
2347 ic[-1].arg[2] == (
size_t)(&cpu->
cd.
arm.
r[6])) {
2358 struct arm_instr_call *
ic,
int low_addr)
2364 if (ic[0].f ==
instr(b__eq)) {
2366 if (ic[-1].arg[1] == 0)
2367 ic[-1].f =
instr(cmps_0_beq);
2368 else if (ic[-1].arg[1] & 0x80000000)
2369 ic[-1].f =
instr(cmps_neg_beq);
2371 ic[-1].f =
instr(cmps_pos_beq);
2375 if (ic[0].f ==
instr(b_samepage__eq)) {
2377 if (ic[-1].arg[1] == 0)
2378 ic[-1].f =
instr(cmps0_beq_samepage);
2380 ic[-1].f =
instr(cmps_beq_samepage);
2382 if (ic[-1].f ==
instr(tsts) &&
2383 !(ic[-1].arg[1] & 0x80000000)) {
2384 ic[-1].f =
instr(tsts_lo_beq_samepage);
2387 ic[-4].f ==
instr(load_w0_word_u1_p1_imm) &&
2388 ic[-4].arg[0] != ic[-4].arg[2] &&
2389 ic[-4].arg[1] == 0 &&
2390 ic[-4].arg[2] == ic[-3].arg[0] &&
2392 ic[-3].f ==
instr(teqs_bne_samepage) &&
2393 ic[-3].arg[1] == 0 &&
2394 ic[-2].f ==
instr(b_samepage__ne) &&
2395 ic[-1].f ==
instr(teqs) &&
2396 ic[-1].arg[0] != ic[-4].arg[0] &&
2397 ic[-1].arg[1] == 0) {
2398 ic[-4].f =
instr(netbsd_idle);
2400 if (ic[-1].f ==
instr(teqs)) {
2401 ic[-1].f =
instr(teqs_beq_samepage);
2405 if (ic[0].f ==
instr(b_samepage__ne)) {
2407 if (ic[-1].arg[1] == 0)
2408 ic[-1].f =
instr(cmps0_bne_samepage);
2410 ic[-1].f =
instr(cmps_bne_samepage);
2412 if (ic[-1].f ==
instr(tsts) &&
2413 !(ic[-1].arg[1] & 0x80000000)) {
2414 ic[-1].f =
instr(tsts_lo_bne_samepage);
2416 if (ic[-1].f ==
instr(teqs)) {
2417 ic[-1].f =
instr(teqs_bne_samepage);
2421 if (ic[0].f ==
instr(b_samepage__cc)) {
2423 ic[-1].f =
instr(cmps_bcc_samepage);
2425 if (ic[-1].f ==
instr(cmps_regshort)) {
2426 ic[-1].f =
instr(cmps_reg_bcc_samepage);
2430 if (ic[0].f ==
instr(b_samepage__hi)) {
2432 ic[-1].f =
instr(cmps_bhi_samepage);
2434 if (ic[-1].f ==
instr(cmps_regshort)) {
2435 ic[-1].f =
instr(cmps_reg_bhi_samepage);
2439 if (ic[0].f ==
instr(b_samepage__gt)) {
2441 ic[-1].f =
instr(cmps_bgt_samepage);
2445 if (ic[0].f ==
instr(b_samepage__le)) {
2447 ic[-1].f =
instr(cmps_ble_samepage);
2457 static void arm_switch_clear(
struct arm_instr_call *ic,
int rd,
2471 case 10: ic->f =
cond_instr(clear_r10);
break;
2472 case 11: ic->f =
cond_instr(clear_r11);
break;
2473 case 12: ic->f =
cond_instr(clear_r12);
break;
2474 case 13: ic->f =
cond_instr(clear_r13);
break;
2475 case 14: ic->f =
cond_instr(clear_r14);
break;
2480 static void arm_switch_mov1(
struct arm_instr_call *ic,
int rd,
2494 case 10: ic->f =
cond_instr(mov1_r10);
break;
2495 case 11: ic->f =
cond_instr(mov1_r11);
break;
2496 case 12: ic->f =
cond_instr(mov1_r12);
break;
2497 case 13: ic->f =
cond_instr(mov1_r13);
break;
2498 case 14: ic->f =
cond_instr(mov1_r14);
break;
2503 static void arm_switch_add1(
struct arm_instr_call *ic,
int rd,
2517 case 10: ic->f =
cond_instr(add1_r10);
break;
2518 case 11: ic->f =
cond_instr(add1_r11);
break;
2519 case 12: ic->f =
cond_instr(add1_r12);
break;
2520 case 13: ic->f =
cond_instr(add1_r13);
break;
2521 case 14: ic->f =
cond_instr(add1_r14);
break;
2539 uint32_t
addr, low_pc, iword, imm = 0;
2540 unsigned char *
page;
2541 unsigned char ib[4];
2542 int condition_code, main_opcode, secondary_opcode, s_bit, rn, rd, r8;
2543 int p_bit, u_bit, w_bit, l_bit, regform, rm, any_pc_reg;
2544 void (*samepage_function)(
struct cpu *,
struct arm_instr_call *);
2547 low_pc = ((size_t)ic - (
size_t)cpu->
cd.
arm.cur_ic_page)
2548 /
sizeof(
struct arm_instr_call);
2556 page = cpu->
cd.
arm.host_load[addr >> 12];
2560 memcpy(ib, page + (addr & 0xfff),
sizeof(ib));
2565 fatal(
"to_be_translated(): " 2566 "read failed: TODO\n");
2572 iword = ib[0] + (ib[1]<<8) + (ib[2]<<16) + (ib[3]<<24);
2574 iword = ib[3] + (ib[2]<<8) + (ib[1]<<16) + (ib[0]<<24);
2577 #define DYNTRANS_TO_BE_TRANSLATED_HEAD 2579 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD 2584 condition_code = iword >> 28;
2585 main_opcode = (iword >> 24) & 15;
2586 secondary_opcode = (iword >> 21) & 15;
2587 u_bit = iword & 0x00800000;
2588 w_bit = iword & 0x00200000;
2589 s_bit = l_bit = iword & 0x00100000;
2590 rn = (iword >> 16) & 15;
2591 rd = (iword >> 12) & 15;
2592 r8 = (iword >> 8) & 15;
2597 if (condition_code == 0xf) {
2615 switch (main_opcode) {
2622 if ((iword & 0x0fc000f0) == 0x00000090) {
2627 if (iword & 0x00200000) {
2639 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2640 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2641 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[r8]);
2645 if ((iword & 0x0f8000f0) == 0x00800090) {
2649 fatal(
"TODO: sbit mull\n");
2656 if ((iword & 0x0f900ff0) == 0x01000050) {
2658 fatal(
"TODO: q{,d}{add,sub}\n");
2661 if ((iword & 0x0ff000d0) == 0x01200010) {
2672 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2675 if ((iword & 0x0fb00ff0) == 0x1000090) {
2676 if (iword & 0x00400000)
2680 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2681 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2682 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2685 if ((iword & 0x0fff0ff0) == 0x016f0f10) {
2687 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2688 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2691 if ((iword & 0x0ff00090) == 0x01000080) {
2695 if ((iword & 0x0ff00090) == 0x01400080) {
2699 if ((iword & 0x0ff000b0) == 0x01200080) {
2703 if ((iword & 0x0ff0f090) == 0x01600080) {
2705 switch (iword & 0x60) {
2706 case 0x00: ic->f =
cond_instr(smulbb);
break;
2707 case 0x20: ic->f =
cond_instr(smultb);
break;
2708 case 0x40: ic->f =
cond_instr(smulbt);
break;
2711 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2712 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[r8]);
2713 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2716 if ((iword & 0x0ff0f0b0) == 0x012000a0) {
2720 if ((iword & 0x0fb0fff0) == 0x0120f000 ||
2721 (iword & 0x0fb0f000) == 0x0320f000) {
2724 if (iword & 0x02000000) {
2725 if (iword & 0x00400000)
2735 if (iword & 0x00400000)
2742 imm = (imm >> 2) | ((imm & 3) << 30);
2744 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2747 if (iword & (1<<16)) arg1 |= 0x000000ff;
2748 if (iword & (1<<17)) arg1 |= 0x0000ff00;
2749 if (iword & (1<<18)) arg1 |= 0x00ff0000;
2750 if (iword & (1<<19)) arg1 |= 0xff000000;
2753 fatal(
"msr no fields\n");
2760 if ((iword & 0x0fbf0fff) == 0x010f0000) {
2767 if (iword & 0x00400000)
2771 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2774 if ((iword & 0x0e000090) == 0x00000090) {
2775 regform = !(iword & 0x00400000);
2776 imm = ((iword >> 4) & 0xf0) | (iword & 0xf);
2777 p_bit = main_opcode & 1;
2778 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2779 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2782 condition_code + (l_bit? 16 : 0)
2783 + (iword & 0x40? 32 : 0)
2785 + (iword & 0x20? 128 : 0)
2786 + (u_bit? 256 : 0) + (p_bit? 512 : 0)
2787 + (regform? 1024 : 0)];
2789 ic->arg[0] = (size_t)
2791 if (!l_bit && rd ==
ARM_PC)
2792 ic->arg[2] = (size_t)
2796 condition_code + (l_bit? 16 : 0)
2797 + (iword & 0x40? 32 : 0)
2799 + (iword & 0x20? 128 : 0)
2800 + (u_bit? 256 : 0) + (p_bit? 512 : 0)
2801 + (regform? 1024 : 0)];
2803 ic->arg[1] = (size_t)(
void *)
arm_r[iword & 0xf];
2809 if (iword & 0x80 && !(main_opcode & 2) && iword & 0x10) {
2811 fatal(
"reg form blah blah\n");
2816 if ((iword & 0x0ff000f0) == 0x01200070) {
2818 ic->arg[0] = addr & 0xfff;
2823 if ((iword & 0x0fffffff) == 0x01a0f00e) {
2832 if ((iword & 0x0fff0ff0) == 0x01a00000 && rd !=
ARM_PC) {
2835 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2838 ic->arg[0] = (addr & 0xfff) + 8;
2840 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2845 if ((iword & 0x0fff0fff) == 0x03a00000 && rd !=
ARM_PC) {
2846 arm_switch_clear(ic, rd, condition_code);
2851 if ((iword & 0x0fff0fff) == 0x03a00001 && rd !=
ARM_PC) {
2852 arm_switch_mov1(ic, rd, condition_code);
2857 if ((iword & 0x0ff00fff) == 0x02800001 && rd !=
ARM_PC 2859 arm_switch_add1(ic, rd, condition_code);
2866 if ((main_opcode & 2) == 0)
2879 if ((secondary_opcode >= 2 && secondary_opcode <= 7)
2880 || secondary_opcode==0xa || secondary_opcode==0xb)
2882 ic->arg[1] = (size_t)(
void *)
arm_r[(iword & 0xfff) + q];
2889 imm = (imm >> 2) | ((imm & 3) << 30);
2891 if (steps != 0 && imm < 256) {
2893 fatal(
"TODO: see cpu_arm_instr_dpi; non-zero steps but still under 256 is not implemented yet\n");
2901 if (secondary_opcode == 0xf && !regform) {
2902 secondary_opcode = 0xd;
2903 ic->arg[1] = ~ic->arg[1];
2906 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2907 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2912 if (!any_pc_reg && regform && (iword & 0xfff) <
ARM_PC) {
2913 ic->arg[1] = (size_t)(&cpu->
cd.
arm.
r[rm]);
2915 16 * secondary_opcode + (s_bit? 256 : 0)];
2918 16 * secondary_opcode + (s_bit? 256 : 0) +
2919 (any_pc_reg? 512 : 0) + (regform? 1024 : 0)];
2921 if (ic->f ==
instr(eor_regshort))
2923 if (iword == 0xe113000c)
2931 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
2932 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2935 & 0x3f0) + condition_code];
2938 if (!l_bit && rd ==
ARM_PC)
2942 0x3f0) + condition_code];
2944 imm = iword & 0xfff;
2945 if (main_opcode < 6)
2948 ic->arg[1] = (size_t)(
void *)
arm_r[iword & 0xfff];
2949 if ((iword & 0x0e000010) == 0x06000010) {
2952 ic->arg[0] = addr & 0xfff;
2955 if (rn ==
ARM_PC && rd !=
ARM_PC && main_opcode < 6 && l_bit) {
2956 unsigned char *p =
page;
2957 int ofs = (addr & 0xfff) + 8, max = 0xffc;
2958 int b_bit = iword & 0x00400000;
2962 ofs += (iword & 0xfff);
2964 ofs -= (iword & 0xfff);
2967 if (ofs >= 0 && ofs <= max && p != NULL) {
2968 unsigned char cbuf[4];
2969 int len = b_bit? 1 : 4;
2970 uint32_t x, a = (addr & 0xfffff000) | ofs;
2973 ic->arg[2] = (size_t)(&cpu->
cd.
arm.
r[rd]);
2975 memcpy(cbuf, p + (a & 0xfff), len);
2981 x = cbuf[0] + (cbuf[1]<<8) +
2982 (cbuf[2]<<16) + (cbuf[3]<<24);
2984 x = cbuf[3] + (cbuf[2]<<8) +
2985 (cbuf[1]<<16) + (cbuf[0]<<24);
2991 if (iword == 0xe4b09004)
2993 if (iword == 0xe4a17004)
2999 ic->arg[0] = (size_t)(&cpu->
cd.
arm.
r[rn]);
3000 ic->arg[1] = (size_t)iword;
3006 #if defined(HOST_LITTLE_ENDIAN) && !defined(GATHER_BDT_STATISTICS) 3018 int i = 0, j = iword;
3019 j = ((j & 0x00800000) >> 16) | ((j & 0x00100000) >> 14)
3020 | ((j & 0x00040000) >> 13) | ((j & 0x00010000) >> 12)
3021 | ((j & 0x00000100) >> 5) | ((j & 0x00000040) >> 4)
3022 | ((j & 0x00000010) >> 3) | ((j & 0x00000004) >> 2);
3023 while (multi_opcode[j][i] != 0) {
3024 if ((iword & 0x0fffffff) ==
3025 multi_opcode[j][i]) {
3027 [i*16 + condition_code];
3036 fatal(
"TODO: bdt with PC as base\n");
3043 if (main_opcode == 0x0a) {
3048 if (condition_code == 0xe &&
3052 if (iword == 0xcaffffed)
3053 cpu->
cd.
arm.combination_check =
3055 if (iword == 0xaafffff9)
3056 cpu->
cd.
arm.combination_check =
3071 ic->arg[1] = addr & 0xffc;
3072 ic->arg[2] = (addr & 0xffc) + 4;
3074 ic->arg[0] = (iword & 0x00ffffff) << 2;
3076 if (ic->arg[0] & 0x02000000)
3077 ic->arg[0] |= 0xfc000000;
3081 ic->arg[0] = (int32_t)(ic->arg[0] + 8);
3090 uint32_t mask_within_page =
3094 uint32_t old_pc =
addr;
3095 uint32_t new_pc = old_pc + (int32_t)ic->arg[0];
3096 if ((old_pc & ~mask_within_page) ==
3097 (new_pc & ~mask_within_page)) {
3098 ic->f = samepage_function;
3099 ic->arg[0] = (size_t) (
3100 cpu->
cd.
arm.cur_ic_page +
3101 ((new_pc & mask_within_page) >>
3103 ic->arg[1] = (size_t) (
3104 cpu->
cd.
arm.cur_ic_page +
3105 (((addr & mask_within_page) + 4) >>
3107 }
else if (main_opcode == 0x0a) {
3109 ic->arg[0] += ic->arg[1];
3113 if (main_opcode == 0xa && (condition_code <= 1
3114 || condition_code == 3 || condition_code == 8
3115 || condition_code == 12 || condition_code == 13))
3118 if (iword == 0x1afffffc)
3122 if (iword == 0x8afffffa)
3123 cpu->
cd.
arm.combination_check =
3133 if ((iword & 0x0fe00fff) == 0x0c400000) {
3136 fatal(
"TODO: mar/mra DSP instructions!\n");
3141 if ((iword & 0x0fe00000) == 0x0c400000) {
3143 fatal(
"MCRR/MRRC: TODO\n");
3155 ic->arg[0] = addr & 0xfff;
3158 fatal(
"LDC/STC: TODO\n");
3164 if ((iword & 0x0ff00ff0) == 0x0e200010) {
3168 fatal(
"TODO: mia* DSP instructions!\n");
3180 if (iword == 0xee070f9a)
3181 cpu->
cd.
arm.combination_check =
3189 ic->arg[0] = addr & 0xfff;
3190 if (iword == 0xef8c64eb) {
3192 ic->f =
instr(reboot);
3193 }
else if (iword == 0xef8c64be) {
3195 ic->f =
instr(openfirmware);
3204 #define DYNTRANS_TO_BE_TRANSLATED_TAIL 3206 #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 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_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
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)
else instr() bdt_load(cpu, ic)