@@ -21,4 +21,6 @@
DEF_HELPER_1(debug, void, env)
DEF_HELPER_2(norm, i32, env, i32)
DEF_HELPER_2(normw, i32, env, i32)
+DEF_HELPER_2(lr, tl, env, i32)
+DEF_HELPER_2(sr, void, i32, i32)
@@ -89,3 +89,325 @@ target_ulong helper_normw(CPUARCState *env, uint32_t src1)
}
}
+void helper_sr(uint32_t val, uint32_t aux)
+{
+ switch (aux) {
+ case AUX_ID_STATUS: {
+ } break;
+
+ case AUX_ID_SEMAPHORE: {
+ } break;
+
+ case AUX_ID_LP_START: {
+ } break;
+
+ case AUX_ID_LP_END: {
+ } break;
+
+ case AUX_ID_IDENTITY: {
+ } break;
+
+ case AUX_ID_DEBUG: {
+ } break;
+
+ case AUX_ID_PC: {
+ } break;
+
+ case AUX_ID_STATUS32: {
+ } break;
+
+ case AUX_ID_STATUS32_L1: {
+ } break;
+
+ case AUX_ID_STATUS32_L2: {
+ } break;
+
+ case AUX_ID_MULHI: {
+ } break;
+
+ case AUX_ID_INT_VECTOR_BASE: {
+ } break;
+
+ case AUX_ID_INT_MACMODE: {
+ } break;
+
+ case AUX_ID_IRQ_LV12: {
+ } break;
+
+ case AUX_ID_IRQ_LEV: {
+ } break;
+
+ case AUX_ID_IRQ_HINT: {
+ } break;
+
+ case AUX_ID_ERET: {
+ } break;
+
+ case AUX_ID_ERBTA: {
+ } break;
+
+ case AUX_ID_ERSTATUS: {
+ } break;
+
+ case AUX_ID_ECR: {
+ } break;
+
+ case AUX_ID_EFA: {
+ } break;
+
+ case AUX_ID_ICAUSE1: {
+ } break;
+
+ case AUX_ID_ICAUSE2: {
+ } break;
+
+ case AUX_ID_IENABLE: {
+ } break;
+
+ case AUX_ID_ITRIGGER: {
+ } break;
+
+ case AUX_ID_BTA: {
+ } break;
+
+ case AUX_ID_BTA_L1: {
+ } break;
+
+ case AUX_ID_BTA_L2: {
+ } break;
+
+ case AUX_ID_IRQ_PULSE_CANSEL: {
+ } break;
+
+ case AUX_ID_IRQ_PENDING: {
+ } break;
+
+ default: {
+ cpu_outl(aux, val);
+ }
+ }
+ cpu_outl(aux, val);
+}
+
+static target_ulong get_status(CPUARCState *env)
+{
+ target_ulong res = 0x00000000;
+
+ res |= (env->stat.Zf) ? BIT(31) : 0;
+ res |= (env->stat.Nf) ? BIT(30) : 0;
+ res |= (env->stat.Cf) ? BIT(29) : 0;
+ res |= (env->stat.Vf) ? BIT(28) : 0;
+ res |= (env->stat.E2f) ? BIT(27) : 0;
+ res |= (env->stat.E1f) ? BIT(26) : 0;
+
+ if (env->stopped) {
+ res |= BIT(25);
+ }
+
+ res |= (env->r[63] >> 2) & 0x03ffffff;
+
+ return res;
+}
+
+static target_ulong get_status32(CPUARCState *env)
+{
+ target_ulong res = 0x00000000;
+
+ res |= (env->stat.Lf) ? BIT(12) : 0;
+ res |= (env->stat.Zf) ? BIT(11) : 0;
+ res |= (env->stat.Nf) ? BIT(10) : 0;
+ res |= (env->stat.Cf) ? BIT(9) : 0;
+ res |= (env->stat.Vf) ? BIT(8) : 0;
+ res |= (env->stat.Uf) ? BIT(7) : 0;
+ res |= (env->stat.DEf) ? BIT(6) : 0;
+ res |= (env->stat.AEf) ? BIT(5) : 0;
+ res |= (env->stat.A2f) ? BIT(4) : 0;
+ res |= (env->stat.A1f) ? BIT(3) : 0;
+ res |= (env->stat.E2f) ? BIT(2) : 0;
+ res |= (env->stat.E1f) ? BIT(1) : 0;
+
+ if (env->stopped) {
+ res |= BIT(0);
+ }
+
+ return res;
+}
+
+static target_ulong get_status32_l1(CPUARCState *env)
+{
+ target_ulong res = 0x00000000;
+
+ res |= (env->stat_l1.Lf) ? BIT(12) : 0;
+ res |= (env->stat_l1.Zf) ? BIT(11) : 0;
+ res |= (env->stat_l1.Nf) ? BIT(10) : 0;
+ res |= (env->stat_l1.Cf) ? BIT(9) : 0;
+ res |= (env->stat_l1.Vf) ? BIT(8) : 0;
+ res |= (env->stat_l1.Uf) ? BIT(7) : 0;
+ res |= (env->stat_l1.DEf) ? BIT(6) : 0;
+ res |= (env->stat_l1.AEf) ? BIT(5) : 0;
+ res |= (env->stat_l1.A2f) ? BIT(4) : 0;
+ res |= (env->stat_l1.A1f) ? BIT(3) : 0;
+ res |= (env->stat_l1.E2f) ? BIT(2) : 0;
+ res |= (env->stat_l1.E1f) ? BIT(1) : 0;
+
+ return res;
+}
+
+static target_ulong get_status32_l2(CPUARCState *env)
+{
+ target_ulong res = 0x00000000;
+
+ res |= (env->stat_l2.Lf) ? BIT(12) : 0;
+ res |= (env->stat_l2.Zf) ? BIT(11) : 0;
+ res |= (env->stat_l2.Nf) ? BIT(10) : 0;
+ res |= (env->stat_l2.Cf) ? BIT(9) : 0;
+ res |= (env->stat_l2.Vf) ? BIT(8) : 0;
+ res |= (env->stat_l2.Uf) ? BIT(7) : 0;
+ res |= (env->stat_l2.DEf) ? BIT(6) : 0;
+ res |= (env->stat_l2.AEf) ? BIT(5) : 0;
+ res |= (env->stat_l2.A2f) ? BIT(4) : 0;
+ res |= (env->stat_l2.A1f) ? BIT(3) : 0;
+ res |= (env->stat_l2.E2f) ? BIT(2) : 0;
+ res |= (env->stat_l2.E1f) ? BIT(1) : 0;
+
+ return res;
+}
+
+static target_ulong get_debug(CPUARCState *env)
+{
+ target_ulong res = 0x00000000;
+
+ res |= (env->debug.LD) ? BIT(31) : 0;
+ res |= (env->debug.SH) ? BIT(30) : 0;
+ res |= (env->debug.BH) ? BIT(29) : 0;
+ res |= (env->debug.UB) ? BIT(28) : 0;
+ res |= (env->debug.ZZ) ? BIT(27) : 0;
+ res |= (env->debug.RA) ? BIT(22) : 0;
+ res |= (env->debug.IS) ? BIT(11) : 0;
+ res |= (env->debug.FH) ? BIT(1) : 0;
+ res |= (env->debug.SS) ? BIT(0) : 0;
+
+ return res;
+}
+
+target_ulong helper_lr(CPUARCState *env, uint32_t aux)
+{
+ target_ulong result = 0;
+
+ switch (aux) {
+ case AUX_ID_STATUS: {
+ result = get_status(env);
+ } break;
+
+ /*
+ NOTE: SEMAPHORE should be handled by a device
+ */
+
+ case AUX_ID_LP_START: {
+ result = env->lps;
+ } break;
+
+ case AUX_ID_LP_END: {
+ result = env->lpe;
+ } break;
+
+ case AUX_ID_IDENTITY: {
+ } break;
+
+ case AUX_ID_DEBUG: {
+ result = get_debug(env);
+ } break;
+
+ case AUX_ID_PC: {
+ result = env->pc & 0xfffffffe;
+ } break;
+
+ case AUX_ID_STATUS32: {
+ result = get_status32(env);
+ } break;
+
+ case AUX_ID_STATUS32_L1: {
+ result = get_status32_l1(env);
+ } break;
+
+ case AUX_ID_STATUS32_L2: {
+ result = get_status32_l2(env);
+ } break;
+
+ case AUX_ID_MULHI: {
+ result = CPU_MHI(env);
+ } break;
+
+ case AUX_ID_INT_VECTOR_BASE: {
+ result = env->intvec;
+ } break;
+
+ case AUX_ID_INT_MACMODE: {
+ } break;
+
+ case AUX_ID_IRQ_LV12: {
+ } break;
+
+ case AUX_ID_IRQ_LEV: {
+ } break;
+
+ case AUX_ID_IRQ_HINT: {
+ } break;
+
+ case AUX_ID_ERET: {
+ result = env->eret;
+ } break;
+
+ case AUX_ID_ERBTA: {
+ result = env->erbta;
+ } break;
+
+ case AUX_ID_ERSTATUS: {
+ } break;
+
+ case AUX_ID_ECR: {
+ result = env->ecr;
+ } break;
+
+ case AUX_ID_EFA: {
+ result = env->efa;
+ } break;
+
+ case AUX_ID_ICAUSE1: {
+ } break;
+
+ case AUX_ID_ICAUSE2: {
+ } break;
+
+ case AUX_ID_IENABLE: {
+ } break;
+
+ case AUX_ID_ITRIGGER: {
+ } break;
+
+ case AUX_ID_BTA: {
+ result = env->bta;
+ } break;
+
+ case AUX_ID_BTA_L1: {
+ result = env->bta_l1;
+ } break;
+
+ case AUX_ID_BTA_L2: {
+ result = env->bta_l2;
+ } break;
+
+ case AUX_ID_IRQ_PULSE_CANSEL: {
+ } break;
+
+ case AUX_ID_IRQ_PENDING: {
+ } break;
+
+ default: {
+ result = cpu_inl(aux);
+ }
+ }
+
+ return result;
+}
+
@@ -2069,3 +2069,29 @@ gen_set_label(label_done);
return BS_BRANCH_DS;
}
+/*
+ LR
+*/
+int arc_gen_LR(DisasCtxt *ctx, TCGv dest, TCGv src1)
+{
+ TCGv cpc = tcg_const_local_i32((ctx->cpc + 3) & 0xfffffffc);
+ TCGv npc = tcg_const_local_i32((ctx->npc + 3) & 0xfffffffc);
+
+ gen_helper_lr(dest, cpu_env, src1);
+
+ tcg_temp_free_i32(cpc);
+ tcg_temp_free_i32(npc);
+
+ return BS_NONE;
+}
+
+/*
+ SR
+*/
+int arc_gen_SR(DisasCtxt *ctx, TCGv src1, TCGv src2)
+{
+ gen_helper_sr(src1, src2);
+
+ return BS_NONE;
+}
+
@@ -141,3 +141,6 @@ int arc_gen_BL(DisasCtxt *c, TCGv Rd, ARC_COND cond);
int arc_gen_J(DisasCtxt *c, TCGv src1, ARC_COND cond);
int arc_gen_JL(DisasCtxt *c, TCGv src1, ARC_COND cond);
+int arc_gen_LR(DisasCtxt *c, TCGv dest, TCGv src1);
+int arc_gen_SR(DisasCtxt *c, TCGv src1, TCGv src2);
+
Signed-off-by: Michael Rolnik <mrolnik@gmail.com> --- target-arc/helper.h | 2 + target-arc/op_helper.c | 322 ++++++++++++++++++++++++++++++++++++++++++++ target-arc/translate-inst.c | 26 ++++ target-arc/translate-inst.h | 3 + 4 files changed, 353 insertions(+)