25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_mips_instr.c,v 1.133 2007/06/13 02:08:03 debug Exp $ |
* $Id: cpu_mips_instr.c,v 1.143 2007/06/28 13:36:46 debug Exp $ |
29 |
* |
* |
30 |
* MIPS instructions. |
* MIPS instructions. |
31 |
* |
* |
1577 |
X(movn) { if (reg(ic->arg[1])) reg(ic->arg[2]) = reg(ic->arg[0]); } |
X(movn) { if (reg(ic->arg[1])) reg(ic->arg[2]) = reg(ic->arg[0]); } |
1578 |
X(movz) { if (!reg(ic->arg[1])) reg(ic->arg[2]) = reg(ic->arg[0]); } |
X(movz) { if (!reg(ic->arg[1])) reg(ic->arg[2]) = reg(ic->arg[0]); } |
1579 |
|
|
1580 |
|
X(ror) |
1581 |
|
{ |
1582 |
|
uint32_t result = reg(ic->arg[0]); |
1583 |
|
int sa = ic->arg[1]; |
1584 |
|
|
1585 |
|
result = (result >> sa) | (result << (32-sa)); |
1586 |
|
|
1587 |
|
reg(ic->arg[2]) = (int32_t) result; |
1588 |
|
} |
1589 |
|
|
1590 |
|
|
1591 |
/* |
/* |
1592 |
* p*: 128-bit C790/TX79/R5900 stuff |
* p*: 128-bit C790/TX79/R5900 stuff |
2221 |
|
|
2222 |
if (cpu->machine->ncpus == 1) { |
if (cpu->machine->ncpus == 1) { |
2223 |
static int x = 0; |
static int x = 0; |
2224 |
if ((++x) == 600) { |
|
2225 |
usleep(10); |
if ((++x) == 300) { |
2226 |
|
usleep(20); |
2227 |
x = 0; |
x = 0; |
2228 |
} |
} |
2229 |
|
|
2230 |
cpu->n_translated_instrs += N_SAFE_DYNTRANS_LIMIT / 6; |
cpu->n_translated_instrs += N_SAFE_DYNTRANS_LIMIT / 6; |
2231 |
} |
} |
2232 |
} |
} |
2378 |
|
|
2379 |
/* If rmw is 0, then the store failed. (This cache-line was written |
/* If rmw is 0, then the store failed. (This cache-line was written |
2380 |
to by someone else.) */ |
to by someone else.) */ |
2381 |
if (cpu->cd.mips.rmw == 0 || cpu->cd.mips.rmw_addr != addr |
if (cpu->cd.mips.rmw == 0 || (MODE_int_t)cpu->cd.mips.rmw_addr != addr |
2382 |
|| cpu->cd.mips.rmw_len != sizeof(word)) { |
|| cpu->cd.mips.rmw_len != sizeof(word)) { |
2383 |
reg(ic->arg[0]) = 0; |
reg(ic->arg[0]) = 0; |
2384 |
cpu->cd.mips.rmw = 0; |
cpu->cd.mips.rmw = 0; |
2438 |
|
|
2439 |
/* If rmw is 0, then the store failed. (This cache-line was written |
/* If rmw is 0, then the store failed. (This cache-line was written |
2440 |
to by someone else.) */ |
to by someone else.) */ |
2441 |
if (cpu->cd.mips.rmw == 0 || cpu->cd.mips.rmw_addr != addr |
if (cpu->cd.mips.rmw == 0 || (MODE_int_t)cpu->cd.mips.rmw_addr != addr |
2442 |
|| cpu->cd.mips.rmw_len != sizeof(word)) { |
|| cpu->cd.mips.rmw_len != sizeof(word)) { |
2443 |
reg(ic->arg[0]) = 0; |
reg(ic->arg[0]) = 0; |
2444 |
cpu->cd.mips.rmw = 0; |
cpu->cd.mips.rmw = 0; |
2676 |
reg(ic[1].arg[2]) = (int32_t)(reg(ic[1].arg[0]) + reg(ic[1].arg[1])); |
reg(ic[1].arg[2]) = (int32_t)(reg(ic[1].arg[0]) + reg(ic[1].arg[1])); |
2677 |
reg(ic[2].arg[2]) = (int32_t)(reg(ic[2].arg[0]) + reg(ic[2].arg[1])); |
reg(ic[2].arg[2]) = (int32_t)(reg(ic[2].arg[0]) + reg(ic[2].arg[1])); |
2678 |
cpu->n_translated_instrs += 2; |
cpu->n_translated_instrs += 2; |
2679 |
cpu->cd.mips.next_ic += 2; |
cpu->cd.mips.next_ic = ic + 3; |
2680 |
} |
} |
2681 |
|
|
2682 |
|
|
2708 |
cpu->n_translated_instrs += (ry - rx + 4) / 4 * 3 + 4; |
cpu->n_translated_instrs += (ry - rx + 4) / 4 * 3 + 4; |
2709 |
|
|
2710 |
/* Run the last mtc0 instruction: */ |
/* Run the last mtc0 instruction: */ |
2711 |
cpu->cd.mips.next_ic = (struct mips_instr_call *) &ic[8]; |
cpu->cd.mips.next_ic = ic + 8; |
2712 |
} |
} |
2713 |
|
|
2714 |
|
|
2826 |
|
|
2827 |
/* Done with the loop? Or continue on the next rx page? */ |
/* Done with the loop? Or continue on the next rx page? */ |
2828 |
if (rv == 0) |
if (rv == 0) |
2829 |
cpu->cd.mips.next_ic = (struct mips_instr_call *) &ic[4]; |
cpu->cd.mips.next_ic = ic + 4; |
2830 |
else |
else |
2831 |
cpu->cd.mips.next_ic = (struct mips_instr_call *) &ic[0]; |
cpu->cd.mips.next_ic = ic; |
2832 |
} |
} |
2833 |
#endif |
#endif |
2834 |
|
|
2855 |
if (rs != rt) |
if (rs != rt) |
2856 |
cpu->cd.mips.next_ic = (struct mips_instr_call *) ic[1].arg[2]; |
cpu->cd.mips.next_ic = (struct mips_instr_call *) ic[1].arg[2]; |
2857 |
else |
else |
2858 |
cpu->cd.mips.next_ic += 2; |
cpu->cd.mips.next_ic = ic + 3; |
2859 |
} |
} |
2860 |
|
|
2861 |
|
|
2875 |
reg(ic[2].arg[2]) = (int32_t)(reg(ic[2].arg[0])<<(int32_t)ic[2].arg[1]); |
reg(ic[2].arg[2]) = (int32_t)(reg(ic[2].arg[0])<<(int32_t)ic[2].arg[1]); |
2876 |
|
|
2877 |
cpu->n_translated_instrs += 2; |
cpu->n_translated_instrs += 2; |
2878 |
cpu->cd.mips.next_ic += 2; |
cpu->cd.mips.next_ic = ic + 3; |
2879 |
} |
} |
2880 |
|
|
2881 |
|
|
2894 |
reg(ic[1].arg[2]) = (int32_t)(reg(ic[1].arg[0])<<(int32_t)ic[1].arg[1]); |
reg(ic[1].arg[2]) = (int32_t)(reg(ic[1].arg[0])<<(int32_t)ic[1].arg[1]); |
2895 |
|
|
2896 |
cpu->n_translated_instrs ++; |
cpu->n_translated_instrs ++; |
2897 |
cpu->cd.mips.next_ic ++; |
cpu->cd.mips.next_ic = ic + 2; |
2898 |
} |
} |
2899 |
|
|
2900 |
|
|
2913 |
reg(ic[1].arg[1]) = reg(ic[1].arg[0]) | (uint32_t)ic[1].arg[2]; |
reg(ic[1].arg[1]) = reg(ic[1].arg[0]) | (uint32_t)ic[1].arg[2]; |
2914 |
|
|
2915 |
cpu->n_translated_instrs ++; |
cpu->n_translated_instrs ++; |
2916 |
cpu->cd.mips.next_ic ++; |
cpu->cd.mips.next_ic = ic + 2; |
2917 |
} |
} |
2918 |
|
|
2919 |
|
|
2933 |
((int32_t)reg(ic[1].arg[0]) + (int32_t)ic[1].arg[2]); |
((int32_t)reg(ic[1].arg[0]) + (int32_t)ic[1].arg[2]); |
2934 |
|
|
2935 |
cpu->n_translated_instrs ++; |
cpu->n_translated_instrs ++; |
2936 |
cpu->cd.mips.next_ic ++; |
cpu->cd.mips.next_ic = ic + 2; |
2937 |
} |
} |
2938 |
|
|
2939 |
|
|
3569 |
case SPECIAL_DSRA32:ic->f = instr(dsra); x64=1; |
case SPECIAL_DSRA32:ic->f = instr(dsra); x64=1; |
3570 |
sa += 32; break; |
sa += 32; break; |
3571 |
} |
} |
3572 |
|
|
3573 |
ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt]; |
ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rt]; |
3574 |
if (sa >= 0) |
if (sa >= 0) |
3575 |
ic->arg[1] = sa; |
ic->arg[1] = sa; |
3576 |
else |
else |
3577 |
ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs]; |
ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rs]; |
3578 |
ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd]; |
ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd]; |
|
if (rd == MIPS_GPR_ZERO) |
|
|
ic->f = instr(nop); |
|
|
if (ic->f == instr(sll)) |
|
|
cpu->cd.mips.combination_check = COMBINE(sll); |
|
|
if (ic->f == instr(nop)) |
|
|
cpu->cd.mips.combination_check = COMBINE(nop); |
|
3579 |
|
|
3580 |
/* Special checks for MIPS32/64 revision 2 opcodes, |
/* Special checks for MIPS32/64 revision 2 opcodes, |
3581 |
such as rotation instructions: */ |
such as rotation instructions: */ |
3582 |
if (sa >= 0 && rs != 0x00) { |
if (sa >= 0 && rs != 0x00) { |
3583 |
|
if (cpu->cd.mips.cpu_type.isa_level < 32 || |
3584 |
|
cpu->cd.mips.cpu_type.isa_revision < 2) { |
3585 |
|
static int warning_rotate = 0; |
3586 |
|
if (!warning_rotate && |
3587 |
|
!cpu->translation_readahead) { |
3588 |
|
fatal("[ WARNING! MIPS32/64 " |
3589 |
|
"revision 2 rotate opcode" |
3590 |
|
" used, but the %s process" |
3591 |
|
"or does not implement " |
3592 |
|
"such instructions. Only " |
3593 |
|
"printing this " |
3594 |
|
"warning once. ]\n", |
3595 |
|
cpu->cd.mips.cpu_type.name); |
3596 |
|
warning_rotate = 1; |
3597 |
|
} |
3598 |
|
ic->f = instr(reserved); |
3599 |
|
break; |
3600 |
|
} |
3601 |
switch (rs) { |
switch (rs) { |
3602 |
/* TODO: [d]ror, etc. */ |
case 0x01: |
3603 |
|
switch (s6) { |
3604 |
|
case SPECIAL_SRL: /* ror */ |
3605 |
|
ic->f = instr(ror); |
3606 |
|
break; |
3607 |
|
default:goto bad; |
3608 |
|
} |
3609 |
|
break; |
3610 |
default:goto bad; |
default:goto bad; |
3611 |
} |
} |
3612 |
} |
} |
3616 |
default:goto bad; |
default:goto bad; |
3617 |
} |
} |
3618 |
} |
} |
3619 |
|
|
3620 |
|
if (rd == MIPS_GPR_ZERO) |
3621 |
|
ic->f = instr(nop); |
3622 |
|
if (ic->f == instr(sll)) |
3623 |
|
cpu->cd.mips.combination_check = COMBINE(sll); |
3624 |
|
if (ic->f == instr(nop)) |
3625 |
|
cpu->cd.mips.combination_check = COMBINE(nop); |
3626 |
break; |
break; |
3627 |
|
|
3628 |
case SPECIAL_ADD: |
case SPECIAL_ADD: |
3695 |
case SPECIAL_MOVN: ic->f = instr(movn); break; |
case SPECIAL_MOVN: ic->f = instr(movn); break; |
3696 |
case SPECIAL_MOVZ: ic->f = instr(movz); break; |
case SPECIAL_MOVZ: ic->f = instr(movz); break; |
3697 |
} |
} |
3698 |
|
|
3699 |
ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs]; |
ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs]; |
3700 |
ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt]; |
ic->arg[1] = (size_t)&cpu->cd.mips.gpr[rt]; |
3701 |
ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd]; |
ic->arg[2] = (size_t)&cpu->cd.mips.gpr[rd]; |
3702 |
|
|
3703 |
switch (s6) { |
switch (s6) { |
3704 |
case SPECIAL_MFHI: |
case SPECIAL_MFHI: |
3705 |
ic->arg[0] = (size_t)&cpu->cd.mips.hi; |
ic->arg[0] = (size_t)&cpu->cd.mips.hi; |