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. This could be due to an unimplemented instruction"
218 " encoding. 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 =
ic->arg[0];
671 int rd = (iw >> 16) & 15;
672 int rn = (iw >> 0) & 15;
673 int rm = (iw >> 8) & 15;
674 int ra = (iw >> 12) & 15;
690 uint32_t iw; uint64_t tmp;
int u_bit, a_bit;
692 u_bit = iw & 0x00400000; a_bit = iw & 0x00200000;
695 tmp = (int64_t)(int32_t)tmp
696 * (int64_t)(int32_t)
cpu->
cd.
arm.
r[(iw >> 8) & 15];
698 tmp *= (uint64_t)
cpu->
cd.
arm.
r[(iw >> 8) & 15];
700 uint64_t x = ((uint64_t)
cpu->
cd.
arm.
r[(iw >> 16) & 15] << 32)
703 cpu->
cd.
arm.
r[(iw >> 16) & 15] = (x >> 32);
706 cpu->
cd.
arm.
r[(iw >> 16) & 15] = (tmp >> 32);
722 reg(
ic->arg[2]) = (int32_t)(int16_t)
reg(
ic->arg[0]) *
723 (int32_t)(int16_t)
reg(
ic->arg[1]);
728 reg(
ic->arg[2]) = (int32_t)(int16_t)(
reg(
ic->arg[0]) >> 16) *
729 (int32_t)(int16_t)
reg(
ic->arg[1]);
734 reg(
ic->arg[2]) = (int32_t)(int16_t)
reg(
ic->arg[0]) *
735 (int32_t)(int16_t)(
reg(
ic->arg[1]) >> 16);
740 reg(
ic->arg[2]) = (int32_t)(int16_t)(
reg(
ic->arg[0]) >> 16) *
741 (int32_t)(int16_t)(
reg(
ic->arg[1]) >> 16);
767 reg(
ic->arg[1]) = ((uint32_t)
cpu->
pc&0xfffff000) + (int32_t)
ic->arg[0];
780 uint32_t old_pc, mask_within_page;
795 if ((old_pc & ~mask_within_page) == (
cpu->
pc & ~mask_within_page)) {
800 quick_pc_to_pointers_arm(
cpu);
807 quick_pc_to_pointers_arm(
cpu);
824 uint32_t mask =
ic->arg[1];
833 uint32_t new_value =
ic->arg[0];
838 if (switch_register_banks)
846 if (switch_register_banks)
858 uint32_t mask =
ic->arg[1];
859 uint32_t new_value =
ic->arg[0];
881 default:
fatal(
"msr_spsr: unimplemented mode %i\n",
885 uint32_t old_pc, low_pc = ((size_t)
ic - (
size_t)
886 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
890 printf(
"msr_spsr: old pc = 0x%08" PRIx32
"\n", old_pc);
933 default:
fatal(
"mrs_spsr: unimplemented mode %i\n",
948 uint32_t low_pc = ((size_t)
ic - (
size_t)
949 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
956 uint32_t low_pc = ((size_t)
ic - (
size_t)
957 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
975 quick_pc_to_pointers_arm(
cpu);
986 cpu->
cd.
arm.next_ic = ¬hing_call;
996 cpu->
pc &= 0xfffff000;
1009 cpu->
pc &= 0xfffff000;
1022 cpu->
pc &= 0xfffff000;
1037 reg(
ic->arg[2]) &= 0xffff;
1038 reg(
ic->arg[2]) |=
ic->arg[1];
1064 uint32_t v =
reg(
ic->arg[1]);
1066 reg(
ic->arg[0]) = (v >> 24) | ((v & 0x00ff0000) >> 8)
1067 | ((v & 0x0000ff00) << 8) | ((v & 0xff) << 24);
1081 uint32_t x =
reg(
ic->arg[1]);
1082 reg(
ic->arg[0]) = (uint8_t)(x >>
ic->arg[2]);
1098 uint32_t x =
reg(
ic->arg[1]);
1100 switch (
ic->arg[2]) {
1102 case 8: x >>= 8;
break;
1103 case 16: x >>= 16;
break;
1104 case 24: x = (x >> 24) | ((x & 255) << 8);
break;
1107 int16_t rotated = x;
1108 reg(
ic->arg[0]) = (int32_t)rotated;
1124 uint32_t x =
reg(
ic->arg[1]);
1126 switch (
ic->arg[2]) {
1128 case 8: x >>= 8;
break;
1129 case 16: x >>= 16;
break;
1130 case 24: x = (x >> 24) | ((x & 255) << 8);
break;
1133 uint16_t rotated = x;
1134 reg(
ic->arg[0]) = (uint32_t)rotated;
1176 uint32_t x =
reg(
ic->arg[1]);
1178 int lsb = (uint8_t)
ic->arg[2];
1179 int width =
ic->arg[2] >> 16;
1181 uint32_t mask = (1 << width) - 1;
1186 reg(
ic->arg[0]) = x;
1200 uint32_t x =
reg(
ic->arg[1]);
1202 int lsb = (uint8_t)
ic->arg[2];
1203 int width =
ic->arg[2] >> 16;
1205 uint32_t mask = (1 << width) - 1;
1209 uint32_t topBitMask = 1 << (width-1);
1210 if (x & topBitMask && width < 32)
1213 reg(
ic->arg[0]) = x;
1227 uint32_t x =
reg(
ic->arg[1]);
1229 int lsb = (uint8_t)
ic->arg[2];
1230 int msb =
ic->arg[2] >> 16;
1231 int width = msb - lsb + 1;
1235 uint32_t mask = (1 << width) - 1;
1239 reg(
ic->arg[0]) &= ~mask;
1240 reg(
ic->arg[0]) |= (x & mask);
1258 uint32_t low_pc = ((size_t)
ic - (
size_t)
1259 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1265 fatal(
"swp: load failed\n");
1268 data = d[0] + (d[1] << 8) + (d[2] << 16) + (d[3] << 24);
1269 data2 =
reg(
ic->arg[1]);
1270 d[0] = data2; d[1] = data2 >> 8; d[2] = data2 >> 16; d[3] = data2 >> 24;
1273 fatal(
"swp: store failed\n");
1285 uint32_t low_pc = ((size_t)
ic - (
size_t)
1286 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1292 fatal(
"swp: load failed\n");
1296 d[0] =
reg(
ic->arg[1]);
1299 fatal(
"swp: store failed\n");
1308 struct arm_instr_call *);
1309 X(store_w1_word_u1_p0_imm);
1310 X(store_w0_byte_u1_p0_imm);
1311 X(store_w0_word_u1_p0_imm);
1312 X(store_w0_word_u1_p1_imm);
1313 X(load_w0_word_u1_p0_imm);
1314 X(load_w0_word_u1_p1_imm);
1315 X(load_w1_word_u1_p0_imm);
1316 X(load_w0_byte_u1_p1_imm);
1317 X(load_w0_byte_u1_p1_reg);
1318 X(load_w1_byte_u1_p1_imm);
1321 struct arm_instr_call *);
1324 struct arm_instr_call *);
1327 struct arm_instr_call *);
1329 extern uint32_t (*
arm_r[8192])(
struct cpu *,
struct arm_instr_call *);
1333 struct arm_instr_call *);
1335 struct arm_instr_call *);
1352 void arm_pop(
struct cpu*
cpu, uint32_t* np,
int p_bit,
int u_bit,
int s_bit,
int w_bit, uint32_t iw)
1354 uint32_t
addr = *np;
1355 unsigned char data[4];
1356 unsigned char *
page;
1357 int i, return_flag = 0;
1358 uint32_t new_values[16];
1363 fatal(
"[ bdt_load: s-bit: in usermode? ]\n");
1372 for (i=(u_bit? 0 : 15); i>=0 && i<=15; i+=(u_bit? 1 : -1)) {
1375 if (!((iw >> i) & 1)) {
1382 addr +=
sizeof(uint32_t);
1384 addr -=
sizeof(uint32_t);
1389 uint32_t *p32 = (uint32_t *)
page;
1390 value = p32[(
addr & 0xfff) >> 2];
1393 #ifdef HOST_LITTLE_ENDIAN
1398 value = ((value & 0xff) << 24) |
1399 ((value & 0xff00) << 8) |
1400 ((value & 0xff0000) >> 8) |
1401 ((value & 0xff000000) >> 24);
1419 new_values[i] = value;
1423 addr +=
sizeof(uint32_t);
1425 addr -=
sizeof(uint32_t);
1429 for (i=(u_bit? 0 : 15); i>=0 && i<=15; i+=(u_bit? 1 : -1)) {
1430 if (!((iw >> i) & 1)) {
1444 if (i >= 8 && i <= 14)
1454 if (i >= 13 && i <= 14)
1469 int switch_register_banks;
1482 default:
fatal(
"bdt_load: unimplemented mode %i\n",
1490 if (switch_register_banks)
1496 if (switch_register_banks)
1510 quick_pc_to_pointers_arm(
cpu);
1518 void arm_push(
struct cpu*
cpu, uint32_t* np,
int p_bit,
int u_bit,
int s_bit,
int w_bit, uint16_t regs)
1521 uint32_t value,
addr = *np;
1522 unsigned char data[4];
1523 unsigned char *
page;
1525 for (i=(u_bit? 0 : 15); i>=0 && i<=15; i+=(u_bit? 1 : -1)) {
1526 if (!((regs >> i) & 1)) {
1536 if (i >= 8 && i <= 14)
1543 if (i >= 13 && i <= 14)
1554 value =
cpu->
pc + 12;
1558 addr +=
sizeof(uint32_t);
1560 addr -=
sizeof(uint32_t);
1565 uint32_t *p32 = (uint32_t *)
page;
1568 #ifdef HOST_LITTLE_ENDIAN
1573 value = ((value & 0xff) << 24) |
1574 ((value & 0xff00) << 8) |
1575 ((value & 0xff0000) >> 8) |
1576 ((value & 0xff000000) >> 24);
1577 p32[(
addr & 0xfff) >> 2] = value;
1581 data[1] = value >> 8;
1582 data[2] = value >> 16;
1583 data[3] = value >> 24;
1585 data[0] = value >> 24;
1586 data[1] = value >> 16;
1587 data[2] = value >> 8;
1599 addr +=
sizeof(uint32_t);
1601 addr -=
sizeof(uint32_t);
1618 uint32_t *np = (uint32_t *)
ic->arg[0];
1620 uint32_t iw =
ic->arg[1];
1621 int p_bit = iw & 0x01000000;
1622 int u_bit = iw & 0x00800000;
1623 int s_bit = iw & 0x00400000;
1624 int w_bit = iw & 0x00200000;
1626 #ifdef GATHER_BDT_STATISTICS
1628 update_bdt_statistics(iw);
1632 low_pc = ((size_t)
ic - (
size_t)
1633 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1637 arm_pop(
cpu, np, p_bit, u_bit, s_bit, w_bit, (uint16_t)iw);
1650 uint32_t *np = (uint32_t *)
ic->arg[0];
1652 uint32_t iw =
ic->arg[1];
1653 int p_bit = iw & 0x01000000;
1654 int u_bit = iw & 0x00800000;
1655 int s_bit = iw & 0x00400000;
1656 int w_bit = iw & 0x00200000;
1658 #ifdef GATHER_BDT_STATISTICS
1660 update_bdt_statistics(iw);
1664 low_pc = ((size_t)
ic - (
size_t)
1665 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1669 arm_push(
cpu, np, p_bit, u_bit, s_bit, w_bit, (uint16_t)iw);
1688 uint32_t
addr =
reg(
ic->arg[1]) + (int32_t)
ic->arg[2];
1690 uint8_t word[
sizeof(uint32_t)];
1693 low_pc = ((size_t)
ic - (
size_t)
1694 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1698 if (
addr & (
sizeof(word)-1)) {
1699 fatal(
"TODO: ldrex unaligned access: exception\n");
1714 reg(
ic->arg[0]) = word[0] + (word[1] << 8)
1715 + (word[2] << 16) + (word[3] << 24);
1717 reg(
ic->arg[0]) = word[3] + (word[2] << 8)
1718 + (word[1] << 16) + (word[0] << 24);
1731 uint64_t r =
reg(
ic->arg[2]);
1733 uint8_t word[
sizeof(uint32_t)];
1736 low_pc = ((size_t)
ic - (
size_t)
1737 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
1741 if (
addr & (
sizeof(word)-1)) {
1742 fatal(
"TODO: strex unaligned access: exception\n");
1747 word[0]=r; word[1]=r>>8; word[2]=r>>16; word[3]=r>>24;
1749 word[3]=r; word[2]=r>>8; word[1]=r>>16; word[0]=r>>24;
1756 reg(
ic->arg[0]) = 1;
1776 uint64_t mask = 2047;
1785 reg(
ic->arg[0]) = 0;
1794 X(multi_0x08b15018);
1795 X(multi_0x08ac000c__ge);
1796 X(multi_0x08a05018);
1814 unsigned char *
page;
1831 if ((
addr & 0xfff) + 128 > 0x1000)
1846 memset(
page + (
addr & 0xfff), 0, 128);
1875 unsigned char *page_0, *page_1;
1876 uint32_t addr_r0, addr_r1;
1885 if ((addr_r0 & 0xfff) + 32 > 0x1000 ||
1886 (addr_r1 & 0xfff) + 32 > 0x1000) {
1891 page_0 =
cpu->
cd.
arm.host_store[addr_r0 >> 12];
1892 page_1 =
cpu->
cd.
arm.host_store[addr_r1 >> 12];
1895 if (page_0 == NULL || page_1 == NULL) {
1900 memcpy(page_0 + (addr_r0 & 0xfff),
1901 page_1 + (addr_r1 & 0xfff), 32);
2010 uint32_t rY =
reg(
ic[0].arg[0]);
2011 uint32_t rZ =
reg(
ic[3].arg[0]);
2015 p = (uint32_t *)
cpu->
cd.
arm.host_load[rY >> 12];
2021 rX = p[(rY & 0xfff) >> 2];
2035 uint32_t low_pc = ((size_t)
ic - (
size_t)
2036 cpu->
cd.
arm.cur_ic_page) /
sizeof(
struct arm_instr_call);
2049 cpu->
cd.
arm.next_ic = ¬hing_call;
2066 unsigned int n_loops = 0;
2067 uint32_t rY, rX =
reg(
ic[0].arg[0]);
2072 p =
cpu->
cd.
arm.host_load[rX >> 12];
2079 rY =
reg(
ic[0].arg[2]) = p[rX & 0xfff];
2080 reg(
ic[0].arg[0]) = rX;
2103 uint32_t tmp =
reg(
ic[0].arg[0]);
2107 reg(
ic[1].arg[0]) = tmp;
2123 uint32_t r0 =
cpu->
cd.
arm.
r[0], ofs = (r0 & 0xffc), index = r0 >> 12;
2124 unsigned char *p =
cpu->
cd.
arm.host_load[index];
2125 uint32_t *p32 = (uint32_t *) p, *q32;
2128 if (ofs > 0x1000 - 6*4 || !ok || p == NULL) {
2134 q32[0] = p32[ofs+2];
2135 q32[1] = p32[ofs+3];
2136 q32[2] = p32[ofs+4];
2137 q32[3] = p32[ofs+5];
2138 q32[4] = p32[ofs+0];
2139 q32[5] = p32[ofs+1];
2158 uint32_t r1 =
cpu->
cd.
arm.
r[1], ofs = (r1 & 0xffc), index = r1 >> 12;
2159 unsigned char *p =
cpu->
cd.
arm.host_store[index];
2160 uint32_t *p32 = (uint32_t *) p, *q32;
2163 if (ofs > 0x1000 - 6*4 || !ok || p == NULL) {
2170 p32[ofs+1] = q32[3];
2171 p32[ofs+2] = q32[4];
2172 p32[ofs+3] = q32[5];
2173 p32[ofs+4] = q32[0];
2174 p32[ofs+5] = q32[1];
2184 X(cmps0_beq_samepage)
2186 uint32_t a =
reg(
ic->arg[0]);
2195 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2204 X(cmps_beq_samepage)
2206 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a - b;
2209 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2210 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2214 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2228 uint32_t a =
reg(
ic->arg[0]);
2232 cpu->
pc = (uint32_t)(((uint32_t)
cpu->
pc & 0xfffff000)
2233 + (int32_t)
ic[1].arg[0]);
2234 quick_pc_to_pointers_arm(
cpu);
2243 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a - b;
2246 if ((int32_t)a < 0 && (int32_t)c >= 0)
2250 cpu->
pc = (uint32_t)(((uint32_t)
cpu->
pc & 0xfffff000)
2251 + (int32_t)
ic[1].arg[0]);
2252 quick_pc_to_pointers_arm(
cpu);
2261 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a - b;
2264 if ((int32_t)a >= 0 && (int32_t)c < 0)
2268 cpu->
pc = (uint32_t)(((uint32_t)
cpu->
pc & 0xfffff000)
2269 + (int32_t)
ic[1].arg[0]);
2270 quick_pc_to_pointers_arm(
cpu);
2282 X(cmps0_bne_samepage)
2284 uint32_t a =
reg(
ic->arg[0]);
2295 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2302 X(cmps_bne_samepage)
2304 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a - b;
2307 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2308 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2316 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2324 X(cmps_bcc_samepage)
2326 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a - b;
2333 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2334 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2339 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2346 X(cmps_reg_bcc_samepage)
2348 uint32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]), c = a - b;
2355 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2356 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2361 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2368 X(cmps_bhi_samepage)
2370 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a - b;
2377 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2378 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2381 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2390 X(cmps_reg_bhi_samepage)
2392 uint32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]), c = a - b;
2399 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2400 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2403 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2412 X(cmps_bgt_samepage)
2414 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a - b;
2421 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2422 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2424 if ((int32_t)a > (int32_t)b)
2425 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2434 X(cmps_ble_samepage)
2436 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a - b;
2443 if (((int32_t)a >= 0 && (int32_t)b < 0 && (int32_t)c < 0) ||
2444 ((int32_t)a < 0 && (int32_t)b >= 0 && (int32_t)c >= 0))
2446 if ((int32_t)a <= (int32_t)b)
2447 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
ic[1].arg[0];
2456 X(teqs_beq_samepage)
2458 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a ^ b;
2463 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2477 X(tsts_lo_beq_samepage)
2479 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a & b;
2485 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2495 X(teqs_bne_samepage)
2497 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a ^ b;
2509 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2518 X(tsts_lo_bne_samepage)
2520 uint32_t a =
reg(
ic->arg[0]), b =
ic->arg[1], c = a & b;
2528 cpu->
cd.
arm.next_ic = (
struct arm_instr_call *)
2543 quick_pc_to_pointers_arm(
cpu);
2560 struct arm_instr_call *
ic,
int low_addr)
2562 #ifdef HOST_LITTLE_ENDIAN
2568 for (i=-16; i<=-1; i++)
2569 if (
ic[i].
f !=
instr(multi_0x08ac000c__ge))
2572 ic[-17].arg[0]==
ic[-17].arg[2] &&
ic[-17].arg[1] == 128 &&
2573 ic[ 0].f ==
instr(b_samepage__gt) &&
2574 ic[ 0].arg[0] == (size_t)&
ic[-17]) {
2591 #ifdef HOST_LITTLE_ENDIAN
2596 if (
ic[-5].
f==
instr(multi_0x08b15018) &&
2597 ic[-4].f==
instr(multi_0x08a05018) &&
2598 ic[-3].f==
instr(multi_0x08b15018) &&
2599 ic[-2].f==
instr(multi_0x08a05018) &&
2601 ic[-1].arg[0]==
ic[-1].arg[2] &&
ic[-1].arg[1] == 0x20 &&
2602 ic[ 0].f ==
instr(b_samepage__ge) &&
2603 ic[ 0].arg[0] == (size_t)&
ic[-5]) {
2617 struct arm_instr_call *
ic,
int low_addr)
2623 if (
ic[-3].
f==
instr(load_w0_word_u1_p0_imm) &&
2625 ic[-2].arg[0]==
ic[-2].arg[2] &&
ic[-2].arg[1] == 0x20 &&
2626 ic[-1].f ==
instr(b_samepage__ne) &&
2627 ic[-1].arg[0] == (size_t)&
ic[-3]) {
2640 struct arm_instr_call *
ic,
int low_addr)
2646 if (
ic[-4].
f ==
instr(mcr_mrc) &&
ic[-4].arg[0] == 0xee070f3a &&
2647 ic[-3].f ==
instr(mcr_mrc) &&
ic[-3].arg[0] == 0xee070f36 &&
2649 ic[-2].arg[0]==
ic[-2].arg[2] &&
ic[-2].arg[1] == 0x20 &&
2651 ic[-1].arg[0]==
ic[-1].arg[2] &&
ic[-1].arg[1] == 0x20) {
2662 struct arm_instr_call *
ic,
int low_addr)
2670 if (
ic[-2].
f ==
instr(load_w0_byte_u1_p1_imm) &&
2672 ic[-2].arg[1] == 0 &&
2674 ic[-1].f ==
instr(load_w0_byte_u1_p1_reg) &&
2687 struct arm_instr_call *
ic,
int low_addr)
2695 if (
ic[-2].
f ==
instr(load_w1_byte_u1_p1_imm) &&
2696 ic[-2].arg[1] == 1 &&
2700 ic[-1].arg[1] == 0) {
2710 struct arm_instr_call *
ic,
int low_addr)
2719 a =
ic[-2].arg[0]; b =
ic[-1].arg[0];
2721 if (
ic[-2].
f ==
instr(eor_regshort) &&
2722 ic[-1].f ==
instr(eor_regshort) &&
2723 ic[-2].arg[0] == a &&
ic[-2].arg[1] == b &&
ic[-2].arg[2] == b &&
2724 ic[-1].arg[0] == b &&
ic[-1].arg[1] == a &&
ic[-1].arg[2] == a &&
2725 ic[ 0].arg[0] == a &&
ic[ 0].arg[1] == b &&
ic[ 0].arg[2] == b) {
2735 struct arm_instr_call *
ic,
int low_addr)
2737 #ifdef HOST_LITTLE_ENDIAN
2744 for (i=-5; i<0; i++) {
2745 if (
ic[i].
f !=
instr(load_w1_word_u1_p0_imm) ||
2751 if (
ic[-5].arg[2] == (
size_t)(&
cpu->
cd.
arm.
r[10]) &&
2766 struct arm_instr_call *
ic,
int low_addr)
2768 #ifdef HOST_LITTLE_ENDIAN
2775 for (i=-5; i<0; i++) {
2776 if (
ic[i].
f !=
instr(store_w1_word_u1_p0_imm) ||
2782 if (
ic[-5].arg[2] == (
size_t)(&
cpu->
cd.
arm.
r[8]) &&
2797 struct arm_instr_call *
ic,
int low_addr)
2805 if (
ic[-1].arg[1] == 0)
2807 else if (
ic[-1].arg[1] & 0x80000000)
2808 ic[-1].f =
instr(cmps_neg_beq);
2810 ic[-1].f =
instr(cmps_pos_beq);
2814 if (
ic[0].
f ==
instr(b_samepage__eq)) {
2816 if (
ic[-1].arg[1] == 0)
2817 ic[-1].f =
instr(cmps0_beq_samepage);
2819 ic[-1].f =
instr(cmps_beq_samepage);
2822 !(
ic[-1].arg[1] & 0x80000000)) {
2823 ic[-1].f =
instr(tsts_lo_beq_samepage);
2826 ic[-4].
f ==
instr(load_w0_word_u1_p1_imm) &&
2827 ic[-4].arg[0] !=
ic[-4].arg[2] &&
2828 ic[-4].arg[1] == 0 &&
2829 ic[-4].arg[2] ==
ic[-3].arg[0] &&
2831 ic[-3].
f ==
instr(teqs_bne_samepage) &&
2832 ic[-3].arg[1] == 0 &&
2833 ic[-2].
f ==
instr(b_samepage__ne) &&
2835 ic[-1].arg[0] !=
ic[-4].arg[0] &&
2836 ic[-1].arg[1] == 0) {
2837 ic[-4].f =
instr(netbsd_idle);
2840 ic[-1].f =
instr(teqs_beq_samepage);
2844 if (
ic[0].
f ==
instr(b_samepage__ne)) {
2846 if (
ic[-1].arg[1] == 0)
2847 ic[-1].f =
instr(cmps0_bne_samepage);
2849 ic[-1].f =
instr(cmps_bne_samepage);
2852 !(
ic[-1].arg[1] & 0x80000000)) {
2853 ic[-1].f =
instr(tsts_lo_bne_samepage);
2856 ic[-1].f =
instr(teqs_bne_samepage);
2860 if (
ic[0].
f ==
instr(b_samepage__cc)) {
2862 ic[-1].f =
instr(cmps_bcc_samepage);
2864 if (
ic[-1].
f ==
instr(cmps_regshort)) {
2865 ic[-1].f =
instr(cmps_reg_bcc_samepage);
2869 if (
ic[0].
f ==
instr(b_samepage__hi)) {
2871 ic[-1].f =
instr(cmps_bhi_samepage);
2873 if (
ic[-1].
f ==
instr(cmps_regshort)) {
2874 ic[-1].f =
instr(cmps_reg_bhi_samepage);
2878 if (
ic[0].
f ==
instr(b_samepage__gt)) {
2880 ic[-1].f =
instr(cmps_bgt_samepage);
2884 if (
ic[0].
f ==
instr(b_samepage__le)) {
2886 ic[-1].f =
instr(cmps_ble_samepage);
2896 static void arm_switch_clear(
struct arm_instr_call *
ic,
int rd,
2919 static void arm_switch_mov1(
struct arm_instr_call *
ic,
int rd,
2942 static void arm_switch_add1(
struct arm_instr_call *
ic,
int rd,
2978 uint32_t
addr, low_pc, iword, imm = 0;
2979 unsigned char *
page;
2980 unsigned char ib[4];
2981 int condition_code, main_opcode, secondary_opcode, s_bit, rn, rd, r8;
2982 int p_bit, u_bit, w_bit, l_bit, regform, rm, any_pc_reg;
2983 void (*samepage_function)(
struct cpu *,
struct arm_instr_call *);
2986 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
arm.cur_ic_page)
2987 /
sizeof(
struct arm_instr_call);
2999 memcpy(ib,
page + (
addr & 0xfff),
sizeof(ib));
3004 fatal(
"to_be_translated(): "
3005 "read failed: TODO\n");
3011 iword = ib[0] + (ib[1]<<8) + (ib[2]<<16) + (ib[3]<<24);
3013 iword = ib[3] + (ib[2]<<8) + (ib[1]<<16) + (ib[0]<<24);
3016 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
3018 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
3023 condition_code = iword >> 28;
3024 main_opcode = (iword >> 24) & 15;
3025 secondary_opcode = (iword >> 21) & 15;
3026 u_bit = iword & 0x00800000;
3027 w_bit = iword & 0x00200000;
3028 s_bit = l_bit = iword & 0x00100000;
3029 rn = (iword >> 16) & 15;
3030 rd = (iword >> 12) & 15;
3031 r8 = (iword >> 8) & 15;
3040 if ((iword >> 28) == 0xf) {
3042 if ((iword & 0xfc70f000) == 0xf450f000) {
3048 if (iword == 0xf10c0040) {
3054 if (iword == 0xf10c0080) {
3060 if (iword == 0xf57ff04f) {
3066 if (iword == 0xf57ff05f) {
3072 if (iword == 0xf57ff06f) {
3078 switch (main_opcode) {
3084 ic->arg[1] =
addr & 0xffc;
3087 ic->arg[0] = (iword & 0x00ffffff) << 2;
3089 if (
ic->arg[0] & 0x02000000)
3090 ic->arg[0] |= 0xfc000000;
3091 if (main_opcode == 0xb)
3093 ic->arg[0] = (int32_t)(
ic->arg[0] + 8 + 1);
3101 switch (main_opcode) {
3108 if ((iword & 0x0ff00fff) == 0x01900f9f) {
3115 fatal(
"ldrex with pc register: TODO\n");
3123 if ((iword & 0x0ff00ff0) == 0x01800f90) {
3129 rd == rm || rd == rn) {
3131 fatal(
"strex with bad register: TODO\n");
3139 if ((iword & 0x0ff000f0) == 0x00600090) {
3145 if ((iword & 0x0fc000f0) == 0x00000090) {
3150 if (iword & 0x00200000) {
3168 if ((iword & 0x0f8000f0) == 0x00800090) {
3172 fatal(
"TODO: sbit mull\n");
3179 if ((iword & 0x0f900ff0) == 0x01000050) {
3181 fatal(
"TODO: q{,d}{add,sub}\n");
3184 if ((iword & 0x0ff000d0) == 0x01200010) {
3196 ic->arg[2] = (
addr & 0xffc) + 4;
3199 if ((iword & 0x0fb00ff0) == 0x1000090) {
3200 if (iword & 0x00400000)
3209 if ((iword & 0x0fff0ff0) == 0x016f0f10) {
3215 if ((iword & 0x0ff00090) == 0x01000080) {
3219 if ((iword & 0x0ff00090) == 0x01400080) {
3223 if ((iword & 0x0ff000b0) == 0x01200080) {
3227 if ((iword & 0x0ff0f090) == 0x01600080) {
3229 switch (iword & 0x60) {
3240 if ((iword & 0x0ff0f0b0) == 0x012000a0) {
3244 if ((iword & 0x0fb0fff0) == 0x0120f000 ||
3245 (iword & 0x0fb0f000) == 0x0320f000) {
3248 if (iword & 0x02000000) {
3249 if (iword & 0x00400000)
3259 if (iword & 0x00400000)
3266 imm = (imm >> 2) | ((imm & 3) << 30);
3271 if (iword & (1<<16)) arg1 |= 0x000000ff;
3272 if (iword & (1<<17)) arg1 |= 0x0000ff00;
3273 if (iword & (1<<18)) arg1 |= 0x00ff0000;
3274 if (iword & (1<<19)) arg1 |= 0xff000000;
3281 if ((iword & 0x0fbf0fff) == 0x010f0000) {
3288 if (iword & 0x00400000)
3295 if ((iword & 0x0e000090) == 0x00000090) {
3296 regform = !(iword & 0x00400000);
3297 imm = ((iword >> 4) & 0xf0) | (iword & 0xf);
3298 p_bit = main_opcode & 1;
3303 condition_code + (l_bit? 16 : 0)
3304 + (iword & 0x40? 32 : 0)
3306 + (iword & 0x20? 128 : 0)
3307 + (u_bit? 256 : 0) + (p_bit? 512 : 0)
3308 + (regform? 1024 : 0)];
3310 ic->arg[0] = (size_t)
3312 if (!l_bit && rd ==
ARM_PC)
3313 ic->arg[2] = (size_t)
3317 condition_code + (l_bit? 16 : 0)
3318 + (iword & 0x40? 32 : 0)
3320 + (iword & 0x20? 128 : 0)
3321 + (u_bit? 256 : 0) + (p_bit? 512 : 0)
3322 + (regform? 1024 : 0)];
3324 ic->arg[1] = (size_t)(
void *)
arm_r[iword & 0xf];
3330 if (iword & 0x80 && !(main_opcode & 2) && iword & 0x10) {
3332 fatal(
"reg form blah blah\n");
3337 if ((iword & 0x0ff000f0) == 0x01200070) {
3339 ic->arg[0] =
addr & 0xfff;
3344 if ((iword & 0x0fffffff) == 0x01a0f00e) {
3353 if ((iword & 0x0fff0ff0) == 0x01a00000 && rd !=
ARM_PC) {
3359 ic->arg[0] = (
addr & 0xfff) + 8;
3366 if ((iword & 0x0fff0fff) == 0x03a00000 && rd !=
ARM_PC) {
3367 arm_switch_clear(
ic, rd, condition_code);
3372 if ((iword & 0x0fff0fff) == 0x03a00001 && rd !=
ARM_PC) {
3373 arm_switch_mov1(
ic, rd, condition_code);
3378 if ((iword & 0x0ff00fff) == 0x02800001 && rd !=
ARM_PC
3380 arm_switch_add1(
ic, rd, condition_code);
3384 if ((iword & 0x0ff00000) == 0x03000000) {
3386 ic->arg[1] = (((iword & 0xf0000) >> 4) | (iword & 0xfff));
3391 fatal(
"movw with rd = pc?\n");
3395 }
else if ((iword & 0x0ff00000) == 0x03400000) {
3397 ic->arg[1] = (((iword & 0xf0000) >> 4) | (iword & 0xfff)) << 16;
3402 fatal(
"movt with rd = pc?\n");
3411 if ((main_opcode & 2) == 0)
3424 if ((secondary_opcode >= 2 && secondary_opcode <= 7)
3425 || secondary_opcode==0xa || secondary_opcode==0xb)
3427 ic->arg[1] = (size_t)(
void *)
arm_r[(iword & 0xfff) + q];
3434 imm = (imm >> 2) | ((imm & 3) << 30);
3436 if (steps != 0 && (imm != 0 && imm < 256)) {
3438 fatal(
"TODO: see cpu_arm_instr_dpi; non-zero steps but still under 256 is not implemented yet\n");
3446 if (secondary_opcode == 0xf && !regform) {
3447 secondary_opcode = 0xd;
3448 ic->arg[1] = ~
ic->arg[1];
3457 if (!any_pc_reg && regform && (iword & 0xfff) <
ARM_PC) {
3460 16 * secondary_opcode + (s_bit? 256 : 0)];
3463 16 * secondary_opcode + (s_bit? 256 : 0) +
3464 (any_pc_reg? 512 : 0) + (regform? 1024 : 0)];
3466 if (
ic->f ==
instr(eor_regshort))
3468 if (iword == 0xe113000c)
3477 if (main_opcode >= 6 && iword & 0x10) {
3478 if ((iword & 0x0fff0ff0) == 0x06bf0f30) {
3482 }
else if ((iword & 0x0fff03f0) == 0x06bf0070) {
3486 ic->arg[2] = ((iword & 0xc00) >> 10) << 3;
3487 }
else if ((iword & 0x0fff03f0) == 0x06ef0070) {
3491 ic->arg[2] = ((iword & 0xc00) >> 10) << 3;
3492 }
else if ((iword & 0x0ff003f0) == 0x06e00070) {
3497 if (iword & 0xc00) {
3499 fatal(
"unimplemented uxtab with rotate != 0\n");
3502 }
else if ((iword & 0x0fff03f0) == 0x06ff0070) {
3506 ic->arg[2] = ((iword & 0xc00) >> 10) << 3;
3507 }
else if ((iword & 0x0ff003f0) == 0x06f00070) {
3512 if (iword & 0xc00) {
3514 fatal(
"unimplemented uxtah with rotate != 0\n");
3517 }
else if ((iword & 0x0fe00070) == 0x07c00010) {
3521 int lsb = (iword >> 7) & 31;
3522 int msb = (iword >> 16) & 31;
3523 ic->arg[2] = (msb << 16) + lsb;
3524 }
else if ((iword & 0x0fe00070) == 0x07e00050) {
3528 int lsb = (iword >> 7) & 31;
3529 int width = 1 + ((iword >> 16) & 31);
3530 ic->arg[2] = (width << 16) + lsb;
3531 }
else if ((iword & 0x0fe00070) == 0x07a00050) {
3535 int lsb = (iword >> 7) & 31;
3536 int width = 1 + ((iword >> 16) & 31);
3537 ic->arg[2] = (width << 16) + lsb;
3540 fatal(
"unimplemented special non-loadstore encoding!\n");
3550 & 0x3f0) + condition_code];
3553 if (!l_bit && rd ==
ARM_PC)
3557 0x3f0) + condition_code];
3559 imm = iword & 0xfff;
3560 if (main_opcode < 6)
3563 ic->arg[1] = (size_t)(
void *)
arm_r[iword & 0xfff];
3564 if ((iword & 0x0e000010) == 0x06000010) {
3567 ic->arg[0] =
addr & 0xfff;
3570 if (rn ==
ARM_PC && rd !=
ARM_PC && main_opcode < 6 && l_bit) {
3571 unsigned char *p =
page;
3572 int ofs = (
addr & 0xfff) + 8, max = 0xffc;
3573 int b_bit = iword & 0x00400000;
3577 ofs += (iword & 0xfff);
3579 ofs -= (iword & 0xfff);
3582 if (ofs >= 0 && ofs <= max && p != NULL) {
3583 unsigned char cbuf[4];
3584 int len = b_bit? 1 : 4;
3585 uint32_t x, a = (
addr & 0xfffff000) | ofs;
3590 memcpy(cbuf, p + (a & 0xfff), len);
3596 x = cbuf[0] + (cbuf[1]<<8) +
3597 (cbuf[2]<<16) + (cbuf[3]<<24);
3599 x = cbuf[3] + (cbuf[2]<<8) +
3600 (cbuf[1]<<16) + (cbuf[0]<<24);
3606 if (iword == 0xe4b09004)
3608 if (iword == 0xe4a17004)
3615 ic->arg[1] = (size_t)iword;
3621 #if defined(HOST_LITTLE_ENDIAN) && !defined(GATHER_BDT_STATISTICS)
3633 int i = 0, j = iword;
3634 j = ((j & 0x00800000) >> 16) | ((j & 0x00100000) >> 14)
3635 | ((j & 0x00040000) >> 13) | ((j & 0x00010000) >> 12)
3636 | ((j & 0x00000100) >> 5) | ((j & 0x00000040) >> 4)
3637 | ((j & 0x00000010) >> 3) | ((j & 0x00000004) >> 2);
3639 if ((iword & 0x0fffffff) ==
3642 [i*16 + condition_code];
3651 fatal(
"TODO: bdt with PC as base\n");
3658 if (main_opcode == 0x0a) {
3663 if (condition_code == 0xe &&
3667 if (iword == 0xcaffffed)
3670 if (iword == 0xaafffff9)
3686 ic->arg[1] =
addr & 0xffc;
3687 ic->arg[2] = (
addr & 0xffc) + 4;
3689 ic->arg[0] = (iword & 0x00ffffff) << 2;
3691 if (
ic->arg[0] & 0x02000000)
3692 ic->arg[0] |= 0xfc000000;
3696 ic->arg[0] = (int32_t)(
ic->arg[0] + 8);
3705 uint32_t mask_within_page =
3709 uint32_t old_pc =
addr;
3710 uint32_t new_pc = old_pc + (int32_t)
ic->arg[0];
3711 if ((old_pc & ~mask_within_page) ==
3712 (new_pc & ~mask_within_page)) {
3713 ic->f = samepage_function;
3714 ic->arg[0] = (size_t) (
3716 ((new_pc & mask_within_page) >>
3718 ic->arg[1] = (size_t) (
3720 (((
addr & mask_within_page) + 4) >>
3722 }
else if (main_opcode == 0x0a) {
3724 ic->arg[0] +=
ic->arg[1];
3728 if (main_opcode == 0xa && (condition_code <= 1
3729 || condition_code == 3 || condition_code == 8
3730 || condition_code == 12 || condition_code == 13))
3733 if (iword == 0x1afffffc)
3737 if (iword == 0x8afffffa)
3748 if ((iword & 0x0fe00fff) == 0x0c400000) {
3751 fatal(
"TODO: mar/mra DSP instructions!\n");
3756 if ((iword & 0x0fe00000) == 0x0c400000) {
3758 fatal(
"MCRR/MRRC: TODO\n");
3770 ic->arg[0] =
addr & 0xfff;
3773 fatal(
"LDC/STC: TODO\n");
3779 if ((iword & 0x0ff00ff0) == 0x0e200010) {
3783 fatal(
"TODO: mia* DSP instructions!\n");
3795 if (iword == 0xee070f9a)
3804 ic->arg[0] =
addr & 0xfff;
3805 if (iword == 0xef8c64eb) {
3808 }
else if (iword == 0xef8c64be) {
3819 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
3821 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL