Revision | fec7daab3d63b7b2ca61581fffc40142b22b2bd5 (tree) |
---|---|
Time | 2015-10-07 18:24:04 |
Author | Chen Gang <gang.chen.5i5j@gmai...> |
Commiter | Richard Henderson |
target-tilegx: Support iret instruction and related special registers
EX_CONTEXT_0_0 is used for jumping address, and EX_CONTEXT_0_1 is for
INTERRUPT_CRITICAL_SECTION, which should only be 0 or 1 in user mode, or
it will cause target SIGILL (and the patch doesn't support system mode).
Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
@@ -53,6 +53,8 @@ enum { | ||
53 | 53 | TILEGX_SPR_CMPEXCH = 0, |
54 | 54 | TILEGX_SPR_CRITICAL_SEC = 1, |
55 | 55 | TILEGX_SPR_SIM_CONTROL = 2, |
56 | + TILEGX_SPR_EX_CONTEXT_0_0 = 3, | |
57 | + TILEGX_SPR_EX_CONTEXT_0_1 = 4, | |
56 | 58 | TILEGX_SPR_COUNT |
57 | 59 | }; |
58 | 60 |
@@ -22,6 +22,7 @@ | ||
22 | 22 | #include "qemu-common.h" |
23 | 23 | #include "exec/helper-proto.h" |
24 | 24 | #include <zlib.h> /* For crc32 */ |
25 | +#include "syscall_defs.h" | |
25 | 26 | |
26 | 27 | void helper_exception(CPUTLGState *env, uint32_t excp) |
27 | 28 | { |
@@ -31,6 +32,27 @@ void helper_exception(CPUTLGState *env, uint32_t excp) | ||
31 | 32 | cpu_loop_exit(cs); |
32 | 33 | } |
33 | 34 | |
35 | +void helper_ext01_ics(CPUTLGState *env) | |
36 | +{ | |
37 | + uint64_t val = env->spregs[TILEGX_SPR_EX_CONTEXT_0_1]; | |
38 | + | |
39 | + switch (val) { | |
40 | + case 0: | |
41 | + case 1: | |
42 | + env->spregs[TILEGX_SPR_CRITICAL_SEC] = val; | |
43 | + break; | |
44 | + default: | |
45 | +#if defined(CONFIG_USER_ONLY) | |
46 | + env->signo = TARGET_SIGILL; | |
47 | + env->sigcode = TARGET_ILL_ILLOPC; | |
48 | + helper_exception(env, TILEGX_EXCP_SIGNAL); | |
49 | +#else | |
50 | + helper_exception(env, TILEGX_EXCP_OPCODE_UNIMPLEMENTED); | |
51 | +#endif | |
52 | + break; | |
53 | + } | |
54 | +} | |
55 | + | |
34 | 56 | uint64_t helper_cntlz(uint64_t arg) |
35 | 57 | { |
36 | 58 | return clz64(arg); |
@@ -1,4 +1,5 @@ | ||
1 | 1 | DEF_HELPER_2(exception, noreturn, env, i32) |
2 | +DEF_HELPER_1(ext01_ics, void, env) | |
2 | 3 | DEF_HELPER_FLAGS_1(cntlz, TCG_CALL_NO_RWG_SE, i64, i64) |
3 | 4 | DEF_HELPER_FLAGS_1(cnttz, TCG_CALL_NO_RWG_SE, i64, i64) |
4 | 5 | DEF_HELPER_FLAGS_1(pcnt, TCG_CALL_NO_RWG_SE, i64, i64) |
@@ -529,6 +529,15 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext, | ||
529 | 529 | /* ??? This should yield, especially in system mode. */ |
530 | 530 | mnemonic = "nap"; |
531 | 531 | goto done0; |
532 | + case OE_RR_X1(IRET): | |
533 | + gen_helper_ext01_ics(cpu_env); | |
534 | + dc->jmp.cond = TCG_COND_ALWAYS; | |
535 | + dc->jmp.dest = tcg_temp_new(); | |
536 | + tcg_gen_ld_tl(dc->jmp.dest, cpu_env, | |
537 | + offsetof(CPUTLGState, spregs[TILEGX_SPR_EX_CONTEXT_0_0])); | |
538 | + tcg_gen_andi_tl(dc->jmp.dest, dc->jmp.dest, ~7); | |
539 | + mnemonic = "iret"; | |
540 | + goto done0; | |
532 | 541 | case OE_RR_X1(SWINT0): |
533 | 542 | case OE_RR_X1(SWINT2): |
534 | 543 | case OE_RR_X1(SWINT3): |
@@ -606,7 +615,6 @@ static TileExcp gen_rr_opcode(DisasContext *dc, unsigned opext, | ||
606 | 615 | break; |
607 | 616 | case OE_RR_X0(FSINGLE_PACK1): |
608 | 617 | case OE_RR_Y0(FSINGLE_PACK1): |
609 | - case OE_RR_X1(IRET): | |
610 | 618 | return TILEGX_EXCP_OPCODE_UNIMPLEMENTED; |
611 | 619 | case OE_RR_X1(LD1S): |
612 | 620 | memop = MO_SB; |
@@ -1947,6 +1955,10 @@ static const TileSPR *find_spr(unsigned spr) | ||
1947 | 1955 | offsetof(CPUTLGState, spregs[TILEGX_SPR_CRITICAL_SEC]), 0, 0) |
1948 | 1956 | D(SIM_CONTROL, |
1949 | 1957 | offsetof(CPUTLGState, spregs[TILEGX_SPR_SIM_CONTROL]), 0, 0) |
1958 | + D(EX_CONTEXT_0_0, | |
1959 | + offsetof(CPUTLGState, spregs[TILEGX_SPR_EX_CONTEXT_0_0]), 0, 0) | |
1960 | + D(EX_CONTEXT_0_1, | |
1961 | + offsetof(CPUTLGState, spregs[TILEGX_SPR_EX_CONTEXT_0_1]), 0, 0) | |
1950 | 1962 | } |
1951 | 1963 | |
1952 | 1964 | #undef D |