From 2ab153e3228b1d65910bb69f7852be6a4bfc6262 Mon Sep 17 00:00:00 2001 From: Denis Drakhnya Date: Tue, 8 Dec 2020 09:11:56 +0200 Subject: [PATCH] target: e2k: Add staa{b,h} instrs. --- target/e2k/cpu.c | 1 + target/e2k/cpu.h | 14 +- target/e2k/helper.h | 6 - target/e2k/helper_aau.c | 58 ------ target/e2k/translate.c | 32 +++- target/e2k/translate.h | 9 + target/e2k/translate/alc.c | 368 +++++++++++++++++++++++++++---------- 7 files changed, 323 insertions(+), 165 deletions(-) diff --git a/target/e2k/cpu.c b/target/e2k/cpu.c index fa42db79c3..93fb9e7fd1 100644 --- a/target/e2k/cpu.c +++ b/target/e2k/cpu.c @@ -52,6 +52,7 @@ static void e2k_cpu_reset(DeviceState *dev) env->bn.base = 8; env->bn.size = 8; env->bn.cur = 0; + env->aau.incrs[0] = 1; /* always one */ // FIXME: testing env->idr = 0x3a207; // mimic 8c diff --git a/target/e2k/cpu.h b/target/e2k/cpu.h index 66378c6818..f1f78e8b12 100644 --- a/target/e2k/cpu.h +++ b/target/e2k/cpu.h @@ -324,13 +324,13 @@ typedef enum { typedef struct { union { struct { - uint64_t base : 48; - uint64_t unused1 : 6; - uint64_t tag : 3; - uint64_t mb : 1; - uint64_t ed : 1; - uint64_t rw : 2; - uint64_t unused2 : 3; + uint64_t base : 48; /* 48:0 */ + uint64_t unused1 : 6; /* 53:48 */ + uint64_t tag : 3; /* 56:54 */ + uint64_t mb : 1; /* 57 */ + uint64_t ed : 1; /* 58 */ + uint64_t rw : 2; /* 60:59 */ + uint64_t unused2 : 3; /* 63:60 */ }; uint64_t lo; }; diff --git a/target/e2k/helper.h b/target/e2k/helper.h index da6627184b..e3f673338b 100644 --- a/target/e2k/helper.h +++ b/target/e2k/helper.h @@ -18,9 +18,3 @@ DEF_HELPER_2(probe_read_access, int, env, tl) DEF_HELPER_2(probe_write_access, int, env, tl) DEF_HELPER_3(packed_shuffle_i64, i64, i64, i64, i64) DEF_HELPER_2(pcmpeqb, i64, i64, i64) -DEF_HELPER_4(set_aad_i64, void, env, i64, int, int) -DEF_HELPER_4(set_aad_i32, void, env, i32, int, int) -DEF_HELPER_3(set_aasti_i64, void, env, i64, int) -DEF_HELPER_3(set_aasti_i32, void, env, i32, int) -DEF_HELPER_7(staa_i64, void, env, i64, i32, int, int, int, int) -DEF_HELPER_7(staa_i32, void, env, i32, i32, int, int, int, int) diff --git a/target/e2k/helper_aau.c b/target/e2k/helper_aau.c index 3b56ad2fda..9b4416e2cb 100644 --- a/target/e2k/helper_aau.c +++ b/target/e2k/helper_aau.c @@ -4,61 +4,3 @@ #include "exec/exec-all.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" - -void HELPER(set_aad_i64)(CPUE2KState *env, uint64_t src4, int incr, int d) -{ - assert(d < 32); - - // FIXME: What register default values should be? - env->aau.ds[d].lo = 0; - env->aau.ds[d].hi = 0; - - env->aau.ds[d].base = extract64(src4, 0, 48); - env->aau.ds[d].rw = 3; - env->aau.incrs[incr] = 1; -} - -void HELPER(set_aad_i32)(CPUE2KState *env, uint32_t src4, int incr, int d) -{ - assert(d < 32); - - // FIXME: What register default values should be? - env->aau.ds[d].lo = 0; - env->aau.ds[d].hi = 0; - - env->aau.ds[d].base = src4; - env->aau.ds[d].rw = 3; - env->aau.incrs[incr] = 1; -} - -void HELPER(set_aasti_i64)(CPUE2KState *env, uint64_t src4, int ind) -{ - assert(ind < 16); - env->aau.stis[ind] = src4; -} - -void HELPER(set_aasti_i32)(CPUE2KState *env, uint32_t src4, int ind) -{ - assert(ind < 16); - env->aau.stis[ind] = src4; -} - -void HELPER(staa_i64)(CPUE2KState *env, uint64_t src4, uint32_t lit, int am, - int incr, int ind, int d) -{ - abi_ulong ptr = env->aau.ds[d].base + env->aau.stis[ind] + lit; - cpu_stq_le_data_ra(env, ptr, src4, GETPC()); - if (am) { - env->aau.stis[ind] += env->aau.incrs[incr] * 8; - } -} - -void HELPER(staa_i32)(CPUE2KState *env, uint32_t src4, uint32_t lit, int am, - int incr, int ind, int d) -{ - abi_ulong ptr = env->aau.ds[d].base + env->aau.stis[ind] + lit; - cpu_stl_le_data_ra(env, ptr, src4, GETPC()); - if (am) { - env->aau.stis[ind] += env->aau.incrs[incr] * 4; - } -} diff --git a/target/e2k/translate.c b/target/e2k/translate.c index a26a4287a5..c54315abf6 100644 --- a/target/e2k/translate.c +++ b/target/e2k/translate.c @@ -497,6 +497,9 @@ void e2k_tcg_initialize(void) { { &e2k_cs.psize, offsetof(CPUE2KState, bp.size), "psize" }, { &e2k_cs.pcur, offsetof(CPUE2KState, bp.cur), "pcur" }, { &e2k_cs.is_bp, offsetof(CPUE2KState, is_bp), "is_bp" }, + { &e2k_cs.aasti_tags, offsetof(CPUE2KState, aau.sti_tags), "aasti_tags" }, + { &e2k_cs.aaind_tags, offsetof(CPUE2KState, aau.ind_tags), "aaind_tags" }, + { &e2k_cs.aaincr_tags, offsetof(CPUE2KState, aau.incr_tags), "aaincr_tags" }, }; static const struct { TCGv_i64 *ptr; int off; const char *name; } r64[] = { @@ -545,7 +548,34 @@ void e2k_tcg_initialize(void) { for (i = 0; i < 3; i++) { snprintf(buf, ARRAY_SIZE(buf), "%%ctpr%d", i + 1); - e2k_cs.ctprs[i] = tcg_global_mem_new(cpu_env, + e2k_cs.ctprs[i] = tcg_global_mem_new_i64(cpu_env, offsetof(CPUE2KState, ctprs[i]), buf); } + + for (i = 0; i < 16; i++) { + snprintf(buf, ARRAY_SIZE(buf), "%%aasti%d", i); + e2k_cs.aasti[i] = tcg_global_mem_new_i32(cpu_env, + offsetof(CPUE2KState, aau.stis[i]), buf); + } + + for (i = 0; i < 16; i++) { + snprintf(buf, ARRAY_SIZE(buf), "%%aaind%d", i); + e2k_cs.aaind[i] = tcg_global_mem_new_i32(cpu_env, + offsetof(CPUE2KState, aau.inds[i]), buf); + } + + for (i = 0; i < 7; i++) { + snprintf(buf, ARRAY_SIZE(buf), "%%aaincr%d", i); + e2k_cs.aaincr[i] = tcg_global_mem_new_i32(cpu_env, + offsetof(CPUE2KState, aau.incrs[i]), buf); + } + + for (i = 0; i < 32; i++) { + snprintf(buf, ARRAY_SIZE(buf), "%%aad%d_lo", i); + e2k_cs.aad_lo[i] = tcg_global_mem_new_i64(cpu_env, + offsetof(CPUE2KState, aau.ds[i].lo), buf); + snprintf(buf, ARRAY_SIZE(buf), "%%aad%d_hi", i); + e2k_cs.aad_hi[i] = tcg_global_mem_new_i64(cpu_env, + offsetof(CPUE2KState, aau.ds[i].hi), buf); + } } diff --git a/target/e2k/translate.h b/target/e2k/translate.h index 7261839ef3..3836fe1c7c 100644 --- a/target/e2k/translate.h +++ b/target/e2k/translate.h @@ -74,6 +74,15 @@ typedef struct CPUE2KStateTCG { TCGv_i64 pregs; TCGv_i32 psize; /* holds psz */ TCGv_i32 pcur; /* holds pcur */ + /* AAU */ + TCGv_i32 aasti[16]; + TCGv_i32 aasti_tags; + TCGv_i32 aaind[16]; + TCGv_i32 aaind_tags; + TCGv_i32 aaincr[8]; + TCGv_i32 aaincr_tags; + TCGv_i64 aad_lo[32]; + TCGv_i64 aad_hi[32]; } CPUE2KStateTCG; extern struct CPUE2KStateTCG e2k_cs; diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index e5b5603c15..446efa14bb 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -33,13 +33,18 @@ typedef struct { struct { uint32_t dst_preg: 5; uint32_t opc_cmp: 3; - uint32_t lts: 2; - uint32_t inc: 1; - uint32_t ind_type: 1; - uint32_t incr: 3; - uint32_t index: 4; - uint32_t desc: 5; + uint32_t unused2: 24; + }; + /* staa/ldaa/aaurw/aaurr */ + struct { uint32_t unused3: 8; + uint32_t aalit: 2; + uint32_t aaopc: 2; + uint32_t aaincr: 3; + /* aaind/aasti/aaincr for aaurw/aaurr */ + uint32_t aaind: 4; + uint32_t aad: 5; + uint32_t unused4: 8; }; }; union { @@ -50,7 +55,7 @@ typedef struct { }; struct { uint16_t opce3: 8; - uint16_t unused4: 8; + uint16_t unused5: 8; }; }; TCGv_i32 mrgc; @@ -511,6 +516,38 @@ static uint16_t find_cond(DisasContext *ctx, int chan) return 0; } +static uint16_t find_am_cond(DisasContext *ctx, int chan) +{ + unsigned int i, j; + + for (i = 0; i < ctx->bundle.cds_present[i]; i++) { + uint16_t *cds = (uint16_t *) &ctx->bundle.cds[i]; + + for (j = 0; j < 2; j++) { + int opc = extract16(cds[j], 13, 3); + int req = chan <= 2 ? 1 : 3; + + if (opc == req) { + return cds[j]; + } + } + } + + return 0; +} + +static inline void gen_am_cond_i32(DisasContext *ctx, TCGv_i32 ret, int chan, + uint16_t rlp) +{ + TCGv_i32 t0 = tcg_temp_new_i32(); + + e2k_gen_cond_i32(ctx, t0, extract16(rlp, 0, 7)); + // FIXME: It isn't clear if am can be the only one cond in RLP. + tcg_gen_xori_i32(ret, t0, GET_BIT(rlp, 7 + chan % 3)); + + tcg_temp_free_i32(t0); +} + static inline void gen_mrgc_i64(DisasContext *ctx, int chan, TCGv_i64 ret) { uint16_t rlp = find_mrgc(ctx, chan); @@ -1339,107 +1376,250 @@ static void gen_st_i32(DisasContext *ctx, int chan, MemOp memop) tcg_temp_free_i64(t0); } -static void gen_staa_i64(DisasContext *ctx, int chan) +static void gen_aad_tag(TCGv_i64 ret, TCGv_i32 tag) { - uint32_t als = ctx->bundle.als[chan]; - uint8_t mas = ctx->mas[chan]; - bool sm = extract32(als, 31, 1); - int lit = extract32(als, 8, 2); - int am = extract32(als, 10, 1); - int incr = extract32(als, 12, 3); - int ind = extract32(als, 15, 4); - int d = extract32(als, 19, 5); - Src64 s4 = get_src4_i64(ctx, chan); - TCGv_i32 t0 = tcg_const_i32(am); - TCGv_i32 t1 = tcg_const_i32(incr); - TCGv_i32 t2 = tcg_const_i32(ind); - TCGv_i32 t3 = tcg_const_i32(d); - TCGv_i32 t4; + TCGv_i32 t0 = tcg_temp_new_i32(); + TCGv_i64 t1 = tcg_temp_new_i64(); - if (lit) { - if (!ctx->bundle.lts_present[lit - 1]) { - e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPN); - return; - } - t4 = tcg_const_i32(ctx->bundle.lts[lit - 1]); - } else { - t4 = tcg_const_i32(0); - } + tcg_gen_setcondi_i32(TCG_COND_NE, t0, tag, 0); + tcg_gen_extu_i32_i64(t1, t0); + tcg_gen_shli_i64(ret, t1, 54); - if (sm) { - qemu_log_mask(LOG_UNIMP, "staad: sm is not implemented\n"); - abort(); - } - - if (mas == 0) { - gen_helper_staa_i64(cpu_env, s4.value, t4, t0, t1, t2, t3); - } else if (mas == 0x3f) { - if (!am) { - gen_helper_set_aad_i64(cpu_env, s4.value, t1, t3); - } else { - gen_helper_set_aasti_i64(cpu_env, s4.value, t2); - } - } else { - qemu_log_mask(LOG_UNIMP, "staad: not implemented mas\n"); - abort(); - } - - tcg_temp_free_i32(t4); - tcg_temp_free_i32(t3); - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t1); + tcg_temp_free_i64(t1); tcg_temp_free_i32(t0); } -static void gen_staa_i32(DisasContext *ctx, int chan) -{ - uint32_t als = ctx->bundle.als[chan]; - uint8_t mas = ctx->mas[chan]; - bool sm = extract32(als, 31, 1); - int lit = extract32(als, 8, 2); - int am = extract32(als, 10, 1); - int incr = extract32(als, 12, 3); - int ind = extract32(als, 15, 4); - int d = extract32(als, 19, 5); - Src32 s4 = get_src4_i32(ctx, chan); - TCGv_i32 t0 = tcg_const_i32(am); - TCGv_i32 t1 = tcg_const_i32(incr); - TCGv_i32 t2 = tcg_const_i32(ind); - TCGv_i32 t3 = tcg_const_i32(d); - TCGv_i32 t4; - if (lit) { - if (!ctx->bundle.lts_present[lit - 1]) { +static void gen_aaurw_aad_i64(Instr *instr, TCGv_i64 arg1, TCGv_i32 tag) +{ + TCGv_i64 lo = e2k_cs.aad_lo[instr->aad]; + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + + tcg_gen_andi_i64(t0, arg1, 3UL << 57); + tcg_gen_andi_i64(lo, lo, !(0x1fUL << 54)); + tcg_gen_or_i64(lo, lo, t0); + tcg_gen_deposit_i64(lo, lo, arg1, 0, 48); + tcg_gen_ori_i64(lo, lo, 3UL << 59); + gen_aad_tag(t1, tag); + tcg_gen_or_i64(lo, lo, t1); + + tcg_temp_free_i64(t1); + tcg_temp_free_i64(t0); +} + +static void gen_aaurw_aad_i32(Instr *instr, TCGv_i32 arg1, TCGv_i32 tag) +{ + TCGv_i64 lo = e2k_cs.aad_lo[instr->aad]; + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + TCGv_i64 t2 = tcg_temp_new_i64(); + + tcg_gen_extu_i32_i64(t0, arg1); + tcg_gen_deposit_i64(lo, lo, t0, 0, 48); + tcg_gen_ori_i64(lo, lo, 3UL << 59); + tcg_gen_andi_i64(lo, lo, !(0x7UL << 54)); + gen_aad_tag(t1, tag); + tcg_gen_or_i64(lo, lo, t1); + + tcg_temp_free_i64(t2); + tcg_temp_free_i64(t1); + tcg_temp_free_i64(t0); +} + +static void gen_aaurw_rest_i32(Instr* instr, TCGv_i32 arg1, TCGv_i32 tag) +{ + int idx = instr->aaind; + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_setcondi_i32(TCG_COND_NE, t0, tag, 0); + switch(instr->aaopc) { + case 1: /* aaurwd src4, aasti */ + tcg_gen_mov_i32(e2k_cs.aasti[idx], arg1); + tcg_gen_deposit_i32(e2k_cs.aasti_tags, e2k_cs.aasti_tags, t0, idx, 1); + break; + case 2: { /* aaurwd src4, aaind */ + if (idx == 0) { + tcg_gen_movi_i32(e2k_cs.aaind[idx], 0); + } else { + tcg_gen_mov_i32(e2k_cs.aaind[idx], arg1); + tcg_gen_deposit_i32(e2k_cs.aaind_tags, e2k_cs.aaind_tags, t0, + idx, 1); + } + break; + } + case 3: /* aaurwd src4, aaincr */ + idx &= 7; + if (idx > 0) { + tcg_gen_mov_i32(e2k_cs.aaincr[idx], arg1); + tcg_gen_deposit_i32(e2k_cs.aaincr_tags, e2k_cs.aaincr_tags, t0, + idx, 1); + } + break; + default: + g_assert_not_reached(); + break; + } + tcg_temp_free_i32(t0); +} + +static void gen_aasti_incr(DisasContext *ctx, Instr *instr, int size) +{ + uint16_t rlp = find_am_cond(ctx, instr->chan); + TCGLabel *l0 = gen_new_label(); + TCGv_i32 t0 = tcg_temp_new_i32(); + + if (rlp != 0) { + TCGv_i32 t1 = tcg_temp_new_i32(); + + gen_am_cond_i32(ctx, t1, instr->chan, rlp); + tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l0); + tcg_temp_free_i32(t1); + } + + tcg_gen_muli_i32(t0, e2k_cs.aaincr[instr->aaincr], size); + tcg_gen_add_i32(e2k_cs.aasti[instr->aaind], e2k_cs.aasti[instr->aaind], t0); + gen_set_label(l0); + + tcg_temp_free_i32(t0); +} + +static void gen_aad_ptr(DisasContext *ctx, TCGv ret, Instr *instr) +{ + uint32_t lit = 0; + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); + + if (instr->aalit) { + int lts = instr->aalit - 1; + if (ctx->bundle.lts_present[lts]) { + lit = ctx->bundle.lts[lts]; + } else { e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPN); return; } - t4 = tcg_const_i32(ctx->bundle.lts[lit - 1]); + } + + tcg_gen_extract_i64(t0, e2k_cs.aad_lo[instr->aad], 0, 48); + tcg_gen_trunc_i64_tl(t1, t0); + tcg_gen_ext_i32_tl(t2, e2k_cs.aasti[instr->aaind]); + if (lit != 0) { + TCGv t3 = tcg_temp_new(); + tcg_gen_add_tl(t3, t1, t2); + tcg_gen_addi_tl(ret, t3, lit); + tcg_temp_free(t3); } else { - t4 = tcg_const_i32(0); + tcg_gen_add_tl(ret, t1, t2); } + tcg_temp_free(t2); + tcg_temp_free(t1); + tcg_temp_free_i64(t0); +} - if (sm) { - qemu_log_mask(LOG_UNIMP, "staaw: sm is not implemented\n"); - abort(); - } +static void gen_staa_i64(DisasContext *ctx, Instr *instr) +{ + uint8_t mas = ctx->mas[instr->chan]; + Src64 s4 = get_src4_i64(ctx, instr->chan); - if (mas == 0) { - gen_helper_staa_i32(cpu_env, s4.value, t4, t0, t1, t2, t3); - } else if (mas == 0x3f) { - if (!am) { - gen_helper_set_aad_i32(cpu_env, s4.value, t1, t3); + gen_tag_check(ctx, instr->sm, s4.tag); + if (mas == 0x3f) { + /* aaurwd */ + if (instr->aaopc == 0) { + gen_aaurw_aad_i64(instr, s4.value, s4.tag); } else { - gen_helper_set_aasti_i32(cpu_env, s4.value, t2); + TCGv_i32 t0 = tcg_temp_new_i32(); + tcg_gen_extrl_i64_i32(t0, s4.value); + gen_aaurw_rest_i32(instr, t0, s4.tag); + tcg_temp_free_i32(t0); } } else { - qemu_log_mask(LOG_UNIMP, "staaw: not implemented mas\n"); - abort(); - } + /* staad */ + TCGLabel *l0 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(); - tcg_temp_free_i32(t4); - tcg_temp_free_i32(t3); - tcg_temp_free_i32(t2); - tcg_temp_free_i32(t1); - tcg_temp_free_i32(t0); + if (mas != 0) { + qemu_log_mask(LOG_UNIMP, + "0x%lx: staad mas=%#x is not implemented\n", ctx->pc, mas); + } + + gen_aad_ptr(ctx, t0, instr); + + if (instr->sm) { + TCGv_i32 t1 = tcg_temp_new_i32(); + gen_helper_probe_write_access(t1, cpu_env, t0); + tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l0); + } + + tcg_gen_qemu_st_i64(s4.value, t0, 0, MO_Q); + gen_set_label(l0); + tcg_temp_free(t0); + + if (instr->aaopc & 1) { + gen_aasti_incr(ctx, instr, 8); + } + } +} + +static void gen_staa_i32(DisasContext *ctx, Instr *instr, MemOp memop) +{ + uint8_t mas = ctx->mas[instr->chan]; + Src32 s4 = get_src4_i32(ctx, instr->chan); + + gen_tag_check(ctx, instr->sm, s4.tag); + if (mas == 0x3f) { + /* aaurw */ + /* CPU do nothing if size less than 32 bits */ + if ((memop & MO_SIZE) == MO_32) { + if (instr->aaopc == 0) { + gen_aaurw_aad_i32(instr, s4.value, s4.tag); + } else { + gen_aaurw_rest_i32(instr, s4.value, s4.tag); + } + } + } else { + /* staaw */ + int len; + TCGLabel *l0 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(); + + if (mas != 0) { + char c; + switch(memop & MO_SIZE) { + case MO_8: c = 'b'; break; + case MO_16: c = 'h'; break; + case MO_32: c = 'w'; break; + default: + g_assert_not_reached(); + break; + } + qemu_log_mask(LOG_UNIMP, + "0x%lx: staa%c mas=%#x is not implemented\n", ctx->pc, c, mas); + } + + gen_aad_ptr(ctx, t0, instr); + + if (instr->sm) { + TCGv_i32 t1 = tcg_temp_new_i32(); + gen_helper_probe_write_access(t1, cpu_env, t0); + tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l0); + } + + tcg_gen_qemu_st_i32(s4.value, t0, 0, memop); + gen_set_label(l0); + tcg_temp_free(t0); + + switch(memop & MO_SIZE) { + case MO_8: len = 1; break; + case MO_16: len = 2; break; + case MO_32: len = 4; break; + default: + g_assert_not_reached(); + break; + } + + if (instr->aaopc & 1) { + gen_aasti_incr(ctx, instr, len); + } + } } static void gen_alopf1_i64(DisasContext *ctx, int chan, @@ -1854,8 +2034,10 @@ static void execute_ext_01_25(DisasContext *ctx, Instr *instr) case 0x09: gen_gettag_i64(ctx, chan); break; /* gettagd */ case 0x0a: gen_puttag_i32(ctx, chan); break; /* puttags */ case 0x0b: gen_puttag_i64(ctx, chan); break; /* puttagd */ - case 0x1e: gen_staa_i32(ctx, chan); break; /* staaw */ - case 0x1f: gen_staa_i64(ctx, chan); break; /* staad */ + case 0x1c: gen_staa_i32(ctx, instr, MO_8); break; /* staab */ + case 0x1d: gen_staa_i32(ctx, instr, MO_16); break; /* staah */ + case 0x1e: gen_staa_i32(ctx, instr, MO_32); break; /* staaw */ + case 0x1f: gen_staa_i64(ctx, instr); break; /* staad */ default: e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC); break;