Revision af7bf89b target-sparc/translate.c
b/target-sparc/translate.c | ||
---|---|---|
423 | 423 |
|
424 | 424 |
static inline void save_state(DisasContext * dc) |
425 | 425 |
{ |
426 |
gen_op_jmp_im((uint32_t)dc->pc);
|
|
426 |
gen_op_jmp_im(dc->pc); |
|
427 | 427 |
save_npc(dc); |
428 | 428 |
} |
429 | 429 |
|
430 | 430 |
static void gen_cond(int cond) |
431 | 431 |
{ |
432 | 432 |
switch (cond) { |
433 |
case 0x0: |
|
434 |
gen_op_movl_T2_0(); |
|
435 |
break; |
|
436 | 433 |
case 0x1: |
437 | 434 |
gen_op_eval_be(); |
438 | 435 |
break; |
... | ... | |
454 | 451 |
case 0x7: |
455 | 452 |
gen_op_eval_bvs(); |
456 | 453 |
break; |
457 |
case 0x8: |
|
458 |
gen_op_movl_T2_1(); |
|
459 |
break; |
|
460 | 454 |
case 0x9: |
461 | 455 |
gen_op_eval_bne(); |
462 | 456 |
break; |
... | ... | |
485 | 479 |
static void gen_fcond(int cond) |
486 | 480 |
{ |
487 | 481 |
switch (cond) { |
488 |
case 0x0: |
|
489 |
gen_op_movl_T2_0(); |
|
490 |
break; |
|
491 | 482 |
case 0x1: |
492 | 483 |
gen_op_eval_fbne(); |
493 | 484 |
break; |
... | ... | |
509 | 500 |
case 0x7: |
510 | 501 |
gen_op_eval_fbu(); |
511 | 502 |
break; |
512 |
case 0x8: |
|
513 |
gen_op_movl_T2_1(); |
|
514 |
break; |
|
515 | 503 |
case 0x9: |
516 | 504 |
gen_op_eval_fbe(); |
517 | 505 |
break; |
... | ... | |
537 | 525 |
} |
538 | 526 |
} |
539 | 527 |
|
540 |
static void do_branch(DisasContext * dc, uint32_t target, uint32_t insn)
|
|
528 |
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn)
|
|
541 | 529 |
{ |
542 | 530 |
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); |
543 |
target += (uint32_t) dc->pc; |
|
531 |
target_ulong target = dc->pc + offset; |
|
532 |
|
|
544 | 533 |
if (cond == 0x0) { |
545 | 534 |
/* unconditional not taken */ |
546 | 535 |
if (a) { |
... | ... | |
574 | 563 |
} |
575 | 564 |
} |
576 | 565 |
|
577 |
static void do_fbranch(DisasContext * dc, uint32_t target, uint32_t insn)
|
|
566 |
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn)
|
|
578 | 567 |
{ |
579 | 568 |
unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); |
580 |
target += (uint32_t) dc->pc; |
|
569 |
target_ulong target = dc->pc + offset; |
|
570 |
|
|
581 | 571 |
if (cond == 0x0) { |
582 | 572 |
/* unconditional not taken */ |
583 | 573 |
if (a) { |
... | ... | |
611 | 601 |
} |
612 | 602 |
} |
613 | 603 |
|
614 |
#if 0 |
|
615 |
static void gen_debug(DisasContext *s, uint32_t pc) |
|
616 |
{ |
|
617 |
gen_op_jmp_im(pc); |
|
618 |
gen_op_debug(); |
|
619 |
s->is_br = 1; |
|
620 |
} |
|
621 |
#endif |
|
622 |
|
|
623 | 604 |
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1) |
624 | 605 |
|
625 | 606 |
static int sign_extend(int x, int len) |
... | ... | |
640 | 621 |
case 0: /* branches/sethi */ |
641 | 622 |
{ |
642 | 623 |
unsigned int xop = GET_FIELD(insn, 7, 9); |
643 |
int target; |
|
624 |
int32_t target;
|
|
644 | 625 |
target = GET_FIELD(insn, 10, 31); |
645 | 626 |
switch (xop) { |
646 |
case 0x0: |
|
647 |
case 0x1: /* UNIMPL */ |
|
648 |
case 0x5: /*CBN+x */ |
|
627 |
case 0x0: /* UNIMPL */ |
|
628 |
case 0x1: /* V9 BPcc */ |
|
629 |
case 0x3: /* V9 BPr */ |
|
630 |
case 0x5: /* V9 FBPcc */ |
|
649 | 631 |
default: |
650 | 632 |
goto illegal_insn; |
651 | 633 |
case 0x2: /* BN+x */ |
... | ... | |
679 | 661 |
} |
680 | 662 |
break; |
681 | 663 |
} |
664 |
break; |
|
682 | 665 |
case 1: |
683 | 666 |
/*CALL*/ { |
684 |
unsigned int target = GET_FIELDs(insn, 2, 31) << 2;
|
|
667 |
target_long target = GET_FIELDs(insn, 2, 31) << 2;
|
|
685 | 668 |
|
686 |
gen_op_movl_T0_im((long) (dc->pc));
|
|
669 |
gen_op_movl_T0_im(dc->pc);
|
|
687 | 670 |
gen_movl_T0_reg(15); |
688 |
target = dc->pc + target;
|
|
671 |
target += dc->pc;
|
|
689 | 672 |
dc->pc = dc->npc; |
690 | 673 |
dc->npc = target; |
691 | 674 |
} |
... | ... | |
719 | 702 |
#endif |
720 | 703 |
} |
721 | 704 |
save_state(dc); |
705 |
/* V9 icc/xcc */ |
|
722 | 706 |
cond = GET_FIELD(insn, 3, 6); |
723 | 707 |
if (cond == 0x8) { |
724 | 708 |
gen_op_trap_T0(); |
725 | 709 |
dc->is_br = 1; |
726 | 710 |
goto jmp_insn; |
727 |
} else { |
|
711 |
} else if (cond != 0) {
|
|
728 | 712 |
gen_cond(cond); |
729 | 713 |
gen_op_trapcc_T0(); |
730 | 714 |
} |
... | ... | |
735 | 719 |
gen_op_rdy(); |
736 | 720 |
gen_movl_T0_reg(rd); |
737 | 721 |
break; |
738 |
case 15: /* stbar */ |
|
722 |
case 15: /* stbar / V9 membar */
|
|
739 | 723 |
break; /* no effect? */ |
740 | 724 |
default: |
725 |
case 0x2: /* V9 rdccr */ |
|
726 |
case 0x3: /* V9 rdasi */ |
|
727 |
case 0x4: /* V9 rdtick */ |
|
728 |
case 0x5: /* V9 rdpc */ |
|
729 |
case 0x6: /* V9 rdfprs */ |
|
741 | 730 |
goto illegal_insn; |
742 | 731 |
} |
743 | 732 |
#if !defined(CONFIG_USER_ONLY) |
... | ... | |
901 | 890 |
case 0xd3: /* fqtoi */ |
902 | 891 |
goto nfpu_insn; |
903 | 892 |
default: |
893 |
case 0x2: /* V9 fmovd */ |
|
894 |
case 0x6: /* V9 fnegd */ |
|
895 |
case 0xa: /* V9 fabsd */ |
|
896 |
case 0x81: /* V9 fstox */ |
|
897 |
case 0x82: /* V9 fdtox */ |
|
898 |
case 0x84: /* V9 fxtos */ |
|
899 |
case 0x88: /* V9 fxtod */ |
|
900 |
|
|
901 |
case 0x3: /* V9 fmovq */ |
|
902 |
case 0x7: /* V9 fnegq */ |
|
903 |
case 0xb: /* V9 fabsq */ |
|
904 |
case 0x83: /* V9 fqtox */ |
|
905 |
case 0x8c: /* V9 fxtoq */ |
|
904 | 906 |
goto illegal_insn; |
905 | 907 |
} |
906 | 908 |
} else if (xop == 0x35) { /* FPU Operations */ |
... | ... | |
910 | 912 |
rs1 = GET_FIELD(insn, 13, 17); |
911 | 913 |
rs2 = GET_FIELD(insn, 27, 31); |
912 | 914 |
xop = GET_FIELD(insn, 18, 26); |
915 |
/* V9 fmovscc: x5, cond = x >> 1 */ |
|
916 |
/* V9 fmovdcc: x6, cond = x >> 1 */ |
|
917 |
|
|
918 |
/* V9 fmovqcc: x7, cond = x >> 1 */ |
|
913 | 919 |
switch (xop) { |
914 | 920 |
case 0x51: |
915 | 921 |
gen_op_load_fpr_FT0(rs1); |
... | ... | |
1028 | 1034 |
gen_op_logic_T0_cc(); |
1029 | 1035 |
break; |
1030 | 1036 |
case 0x8: |
1031 |
gen_op_addx_T1_T0(); |
|
1032 | 1037 |
if (xop & 0x10) |
1033 |
gen_op_set_flags(); |
|
1038 |
gen_op_addx_T1_T0_cc(); |
|
1039 |
else |
|
1040 |
gen_op_addx_T1_T0(); |
|
1034 | 1041 |
break; |
1035 | 1042 |
case 0xa: |
1036 | 1043 |
gen_op_umul_T1_T0(); |
... | ... | |
1043 | 1050 |
gen_op_logic_T0_cc(); |
1044 | 1051 |
break; |
1045 | 1052 |
case 0xc: |
1046 |
gen_op_subx_T1_T0(); |
|
1047 | 1053 |
if (xop & 0x10) |
1048 |
gen_op_set_flags(); |
|
1054 |
gen_op_subx_T1_T0_cc(); |
|
1055 |
else |
|
1056 |
gen_op_subx_T1_T0(); |
|
1049 | 1057 |
break; |
1050 | 1058 |
case 0xe: |
1051 | 1059 |
gen_op_udiv_T1_T0(); |
... | ... | |
1058 | 1066 |
gen_op_div_cc(); |
1059 | 1067 |
break; |
1060 | 1068 |
default: |
1069 |
case 0x9: /* V9 mulx */ |
|
1070 |
case 0xd: /* V9 udivx */ |
|
1061 | 1071 |
goto illegal_insn; |
1062 | 1072 |
} |
1063 | 1073 |
gen_movl_T0_reg(rd); |
... | ... | |
1072 | 1082 |
gen_op_mulscc_T1_T0(); |
1073 | 1083 |
gen_movl_T0_reg(rd); |
1074 | 1084 |
break; |
1075 |
case 0x25: /* SLL */
|
|
1085 |
case 0x25: /* sll, V9 sllx */
|
|
1076 | 1086 |
gen_op_sll(); |
1077 | 1087 |
gen_movl_T0_reg(rd); |
1078 | 1088 |
break; |
1079 |
case 0x26: |
|
1089 |
case 0x26: /* srl, V9 srlx */
|
|
1080 | 1090 |
gen_op_srl(); |
1081 | 1091 |
gen_movl_T0_reg(rd); |
1082 | 1092 |
break; |
1083 |
case 0x27: |
|
1093 |
case 0x27: /* sra, V9 srax */
|
|
1084 | 1094 |
gen_op_sra(); |
1085 | 1095 |
gen_movl_T0_reg(rd); |
1086 | 1096 |
break; |
... | ... | |
1092 | 1102 |
gen_op_wry(); |
1093 | 1103 |
break; |
1094 | 1104 |
default: |
1105 |
case 0x2: /* V9 wrccr */ |
|
1106 |
case 0x3: /* V9 wrasi */ |
|
1107 |
case 0x6: /* V9 wrfprs */ |
|
1108 |
case 0xf: /* V9 sir */ |
|
1095 | 1109 |
goto illegal_insn; |
1096 | 1110 |
} |
1097 | 1111 |
} |
1098 | 1112 |
break; |
1099 | 1113 |
#if !defined(CONFIG_USER_ONLY) |
1100 |
case 0x31: |
|
1114 |
case 0x31: /* wrpsr, V9 saved, restored */
|
|
1101 | 1115 |
{ |
1102 | 1116 |
if (!supervisor(dc)) |
1103 | 1117 |
goto priv_insn; |
... | ... | |
1105 | 1119 |
gen_op_wrpsr(); |
1106 | 1120 |
} |
1107 | 1121 |
break; |
1108 |
case 0x32: |
|
1122 |
case 0x32: /* wrwim, V9 wrpr */
|
|
1109 | 1123 |
{ |
1110 | 1124 |
if (!supervisor(dc)) |
1111 | 1125 |
goto priv_insn; |
... | ... | |
1123 | 1137 |
break; |
1124 | 1138 |
#endif |
1125 | 1139 |
default: |
1140 |
case 0x2a: /* V9 rdpr */ |
|
1141 |
case 0x2b: /* V9 flushw */ |
|
1142 |
case 0x2c: /* V9 movcc */ |
|
1143 |
case 0x2d: /* V9 sdivx */ |
|
1144 |
case 0x2e: /* V9 popc */ |
|
1145 |
case 0x2f: /* V9 movr */ |
|
1126 | 1146 |
goto illegal_insn; |
1127 | 1147 |
} |
1128 | 1148 |
} |
... | ... | |
1155 | 1175 |
{ |
1156 | 1176 |
gen_op_movl_npc_T0(); |
1157 | 1177 |
if (rd != 0) { |
1158 |
gen_op_movl_T0_im((long) (dc->pc));
|
|
1178 |
gen_op_movl_T0_im(dc->pc);
|
|
1159 | 1179 |
gen_movl_T0_reg(rd); |
1160 | 1180 |
} |
1161 | 1181 |
dc->pc = dc->npc; |
... | ... | |
1163 | 1183 |
} |
1164 | 1184 |
goto jmp_insn; |
1165 | 1185 |
#if !defined(CONFIG_USER_ONLY) |
1166 |
case 0x39: /* rett */ |
|
1186 |
case 0x39: /* rett, V9 return */
|
|
1167 | 1187 |
{ |
1168 | 1188 |
if (!supervisor(dc)) |
1169 | 1189 |
goto priv_insn; |
... | ... | |
1186 | 1206 |
gen_movl_T0_reg(rd); |
1187 | 1207 |
break; |
1188 | 1208 |
default: |
1209 |
case 0x3e: /* V9 done/retry */ |
|
1189 | 1210 |
goto illegal_insn; |
1190 | 1211 |
} |
1191 | 1212 |
} |
1192 | 1213 |
break; |
1193 | 1214 |
} |
1215 |
break; |
|
1194 | 1216 |
case 3: /* load/store instructions */ |
1195 | 1217 |
{ |
1196 | 1218 |
unsigned int xop = GET_FIELD(insn, 7, 12); |
... | ... | |
1297 | 1319 |
(void) &gen_op_lddfa; |
1298 | 1320 |
#endif |
1299 | 1321 |
default: |
1322 |
case 0x08: /* V9 ldsw */ |
|
1323 |
case 0x0b: /* V9 ldx */ |
|
1324 |
case 0x18: /* V9 ldswa */ |
|
1325 |
case 0x1b: /* V9 ldxa */ |
|
1326 |
case 0x2d: /* V9 prefetch */ |
|
1327 |
case 0x30: /* V9 ldfa */ |
|
1328 |
case 0x33: /* V9 lddfa */ |
|
1329 |
case 0x3d: /* V9 prefetcha */ |
|
1330 |
|
|
1331 |
case 0x32: /* V9 ldqfa */ |
|
1300 | 1332 |
goto illegal_insn; |
1301 | 1333 |
} |
1302 | 1334 |
gen_movl_T1_reg(rd); |
... | ... | |
1313 | 1345 |
gen_op_ldfsr(); |
1314 | 1346 |
gen_op_store_FT0_fpr(rd); |
1315 | 1347 |
break; |
1348 |
case 0x22: /* load quad fpreg */ |
|
1349 |
goto nfpu_insn; |
|
1316 | 1350 |
case 0x23: /* load double fpreg */ |
1317 | 1351 |
gen_op_ldst(lddf); |
1318 | 1352 |
gen_op_store_DT0_fpr(rd); |
... | ... | |
1362 | 1396 |
break; |
1363 | 1397 |
#endif |
1364 | 1398 |
default: |
1399 |
case 0x0e: /* V9 stx */ |
|
1400 |
case 0x1e: /* V9 stxa */ |
|
1365 | 1401 |
goto illegal_insn; |
1366 | 1402 |
} |
1367 | 1403 |
} else if (xop > 0x23 && xop < 0x28) { |
... | ... | |
1373 | 1409 |
gen_op_load_fpr_FT0(rd); |
1374 | 1410 |
gen_op_ldst(stf); |
1375 | 1411 |
break; |
1376 |
case 0x25: |
|
1412 |
case 0x25: /* stfsr, V9 stxfsr */
|
|
1377 | 1413 |
gen_op_load_fpr_FT0(rd); |
1378 | 1414 |
gen_op_stfsr(); |
1379 | 1415 |
break; |
1416 |
case 0x26: /* stdfq */ |
|
1417 |
goto nfpu_insn; |
|
1380 | 1418 |
case 0x27: |
1381 | 1419 |
gen_op_load_fpr_DT0(rd); |
1382 | 1420 |
gen_op_ldst(stdf); |
1383 | 1421 |
break; |
1384 |
case 0x26: /* stdfq */ |
|
1385 | 1422 |
default: |
1423 |
case 0x34: /* V9 stfa */ |
|
1424 |
case 0x37: /* V9 stdfa */ |
|
1425 |
case 0x3c: /* V9 casa */ |
|
1426 |
case 0x3e: /* V9 casxa */ |
|
1427 |
|
|
1428 |
case 0x36: /* V9 stqfa */ |
|
1386 | 1429 |
goto illegal_insn; |
1387 | 1430 |
} |
1388 | 1431 |
} else if (xop > 0x33 && xop < 0x38) { |
... | ... | |
1392 | 1435 |
else |
1393 | 1436 |
goto illegal_insn; |
1394 | 1437 |
} |
1438 |
break; |
|
1395 | 1439 |
} |
1396 | 1440 |
/* default case for non jump instructions */ |
1397 | 1441 |
if (dc->npc == DYNAMIC_PC) { |
... | ... | |
1589 | 1633 |
{ |
1590 | 1634 |
int i, x; |
1591 | 1635 |
|
1592 |
cpu_fprintf(f, "pc: 0x%08x npc: 0x%08x\n", (int) env->pc, (int) env->npc);
|
|
1636 |
cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
|
|
1593 | 1637 |
cpu_fprintf(f, "General Registers:\n"); |
1594 | 1638 |
for (i = 0; i < 4; i++) |
1595 |
cpu_fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
|
|
1639 |
cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
|
|
1596 | 1640 |
cpu_fprintf(f, "\n"); |
1597 | 1641 |
for (; i < 8; i++) |
1598 |
cpu_fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
|
|
1642 |
cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
|
|
1599 | 1643 |
cpu_fprintf(f, "\nCurrent Register Window:\n"); |
1600 | 1644 |
for (x = 0; x < 3; x++) { |
1601 | 1645 |
for (i = 0; i < 4; i++) |
1602 |
cpu_fprintf(f, "%%%c%d: 0x%08x\t",
|
|
1646 |
cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
|
|
1603 | 1647 |
(x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i, |
1604 | 1648 |
env->regwptr[i + x * 8]); |
1605 | 1649 |
cpu_fprintf(f, "\n"); |
1606 | 1650 |
for (; i < 8; i++) |
1607 |
cpu_fprintf(f, "%%%c%d: 0x%08x\t",
|
|
1651 |
cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
|
|
1608 | 1652 |
(x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i, |
1609 | 1653 |
env->regwptr[i + x * 8]); |
1610 | 1654 |
cpu_fprintf(f, "\n"); |
... | ... | |
1626 | 1670 |
} |
1627 | 1671 |
|
1628 | 1672 |
#if defined(CONFIG_USER_ONLY) |
1629 |
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
|
1673 |
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
|
1630 | 1674 |
{ |
1631 | 1675 |
return addr; |
1632 | 1676 |
} |
1633 | 1677 |
|
1634 | 1678 |
#else |
1635 |
extern int get_physical_address (CPUState *env, uint32_t *physical, int *prot,
|
|
1636 |
int *access_index, uint32_t address, int rw,
|
|
1679 |
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
|
|
1680 |
int *access_index, target_ulong address, int rw,
|
|
1637 | 1681 |
int is_user); |
1638 | 1682 |
|
1639 |
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
|
1683 |
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
|
1640 | 1684 |
{ |
1641 |
uint32_t phys_addr;
|
|
1685 |
target_phys_addr_t phys_addr;
|
|
1642 | 1686 |
int prot, access_index; |
1643 | 1687 |
|
1644 | 1688 |
if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0) |
Also available in: Unified diff