Commit 6de4e7fd authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/bkoppelmann/tags/pull-tricore-20141021' into staging



TriCore ABS, ABSB, B, BIT, BO instructions added

# gpg: Signature made Tue 21 Oct 2014 17:47:32 BST using RSA key ID 6B69CA14
# gpg: Good signature from "Bastian Koppelmann <kbastian@mail.uni-paderborn.de>"

* remotes/bkoppelmann/tags/pull-tricore-20141021:
  target-tricore: Add instructions of BO opcode format
  target-tricore: Add instructions of BIT opcode format
  target-tricore: Add instructions of B opcode format
  target-tricore: Add instructions of ABS, ABSB opcode format
  target-tricore: Cleanup and Bugfixes

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 60b6381f 3a16ecb0
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -23,3 +23,10 @@ DEF_HELPER_2(call, void, env, i32)
DEF_HELPER_1(ret, void, env)
DEF_HELPER_2(bisr, void, env, i32)
DEF_HELPER_1(rfe, void, env)
DEF_HELPER_2(ldlcx, void, env, i32)
DEF_HELPER_2(lducx, void, env, i32)
DEF_HELPER_2(stlcx, void, env, i32)
DEF_HELPER_2(stucx, void, env, i32)
/* Address mode helper */
DEF_HELPER_1(br_update, i32, i32)
DEF_HELPER_2(circ_update, i32, i32, i32)
+102 −26
Original line number Diff line number Diff line
@@ -20,6 +20,42 @@
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"

/* Addressing mode helper */

static uint16_t reverse16(uint16_t val)
{
    uint8_t high = (uint8_t)(val >> 8);
    uint8_t low  = (uint8_t)(val & 0xff);

    uint16_t rh, rl;

    rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
    rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);

    return (rh << 8) | rl;
}

uint32_t helper_br_update(uint32_t reg)
{
    uint32_t index = reg & 0xffff;
    uint32_t incr  = reg >> 16;
    uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
    return reg - index + new_index;
}

uint32_t helper_circ_update(uint32_t reg, uint32_t off)
{
    uint32_t index = reg & 0xffff;
    uint32_t length = reg >> 16;
    int32_t new_index = index + off;
    if (new_index < 0) {
        new_index += length;
    } else {
        new_index %= length;
    }
    return reg - index + new_index;
}

#define SSOV(env, ret, arg, len) do {               \
    int64_t max_pos = INT##len ##_MAX;              \
    int64_t max_neg = INT##len ##_MIN;              \
@@ -114,10 +150,8 @@ static bool cdc_zero(target_ulong *psw)
    return count == 0;
}

static void save_context_upper(CPUTriCoreState *env, int ea,
                               target_ulong *new_FCX)
static void save_context_upper(CPUTriCoreState *env, int ea)
{
    *new_FCX = cpu_ldl_data(env, ea);
    cpu_stl_data(env, ea, env->PCXI);
    cpu_stl_data(env, ea+4, env->PSW);
    cpu_stl_data(env, ea+8, env->gpr_a[10]);
@@ -134,15 +168,12 @@ static void save_context_upper(CPUTriCoreState *env, int ea,
    cpu_stl_data(env, ea+52, env->gpr_d[13]);
    cpu_stl_data(env, ea+56, env->gpr_d[14]);
    cpu_stl_data(env, ea+60, env->gpr_d[15]);

}

static void save_context_lower(CPUTriCoreState *env, int ea,
                               target_ulong *new_FCX)
static void save_context_lower(CPUTriCoreState *env, int ea)
{
    *new_FCX = cpu_ldl_data(env, ea);
    cpu_stl_data(env, ea, env->PCXI);
    cpu_stl_data(env, ea+4, env->PSW);
    cpu_stl_data(env, ea+4, env->gpr_a[11]);
    cpu_stl_data(env, ea+8, env->gpr_a[2]);
    cpu_stl_data(env, ea+12, env->gpr_a[3]);
    cpu_stl_data(env, ea+16, env->gpr_d[0]);
@@ -178,7 +209,27 @@ static void restore_context_upper(CPUTriCoreState *env, int ea,
    env->gpr_d[13] = cpu_ldl_data(env, ea+52);
    env->gpr_d[14] = cpu_ldl_data(env, ea+56);
    env->gpr_d[15] = cpu_ldl_data(env, ea+60);
    cpu_stl_data(env, ea, env->FCX);
}

static void restore_context_lower(CPUTriCoreState *env, int ea,
                                  target_ulong *ra, target_ulong *pcxi)
{
    *pcxi = cpu_ldl_data(env, ea);
    *ra = cpu_ldl_data(env, ea+4);
    env->gpr_a[2] = cpu_ldl_data(env, ea+8);
    env->gpr_a[3] = cpu_ldl_data(env, ea+12);
    env->gpr_d[0] = cpu_ldl_data(env, ea+16);
    env->gpr_d[1] = cpu_ldl_data(env, ea+20);
    env->gpr_d[2] = cpu_ldl_data(env, ea+24);
    env->gpr_d[3] = cpu_ldl_data(env, ea+28);
    env->gpr_a[4] = cpu_ldl_data(env, ea+32);
    env->gpr_a[5] = cpu_ldl_data(env, ea+36);
    env->gpr_a[6] = cpu_ldl_data(env, ea+40);
    env->gpr_a[7] = cpu_ldl_data(env, ea+44);
    env->gpr_d[4] = cpu_ldl_data(env, ea+48);
    env->gpr_d[5] = cpu_ldl_data(env, ea+52);
    env->gpr_d[6] = cpu_ldl_data(env, ea+56);
    env->gpr_d[7] = cpu_ldl_data(env, ea+60);
}

void helper_call(CPUTriCoreState *env, uint32_t next_pc)
@@ -206,11 +257,12 @@ void helper_call(CPUTriCoreState *env, uint32_t next_pc)
    /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
    ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
         ((env->FCX & MASK_FCX_FCXO) << 6);
    /* new_FCX = M(EA, word);
       M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
    /* new_FCX = M(EA, word); */
    new_FCX = cpu_ldl_data(env, ea);
    /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
                           A[12], A[13], A[14], A[15], D[12], D[13], D[14],
                           D[15]}; */
    save_context_upper(env, ea, &new_FCX);
    save_context_upper(env, ea);

    /* PCXI.PCPN = ICR.CCPN; */
    env->PCXI = (env->PCXI & 0xffffff) +
@@ -263,9 +315,10 @@ void helper_ret(CPUTriCoreState *env)
    ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
         ((env->PCXI & MASK_PCXI_PCXO) << 6);
    /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
        A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
        M(EA, word) = FCX; */
        A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
    restore_context_upper(env, ea, &new_PCXI, &new_PSW);
    /* M(EA, word) = FCX; */
    cpu_stl_data(env, ea, env->FCX);
    /* FCX[19: 0] = PCXI[19: 0]; */
    env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
    /* PCXI = new_PCXI; */
@@ -293,7 +346,12 @@ void helper_bisr(CPUTriCoreState *env, uint32_t const9)
    tmp_FCX = env->FCX;
    ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);

    save_context_lower(env, ea, &new_FCX);
    /* new_FCX = M(EA, word); */
    new_FCX = cpu_ldl_data(env, ea);
    /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
                           , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
    save_context_lower(env, ea);


    /* PCXI.PCPN = ICR.CCPN */
    env->PCXI = (env->PCXI & 0xffffff) +
@@ -343,9 +401,10 @@ void helper_rfe(CPUTriCoreState *env)
    ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
         ((env->PCXI & MASK_PCXI_PCXO) << 6);
    /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
      A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word);
      M(EA, word) = FCX;*/
      A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
    restore_context_upper(env, ea, &new_PCXI, &new_PSW);
    /* M(EA, word) = FCX;*/
    cpu_stl_data(env, ea, env->FCX);
    /* FCX[19: 0] = PCXI[19: 0]; */
    env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
    /* PCXI = new_PCXI; */
@@ -354,6 +413,30 @@ void helper_rfe(CPUTriCoreState *env)
    psw_write(env, new_PSW);
}

void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
{
    uint32_t dummy;
    /* insn doesn't load PCXI and RA */
    restore_context_lower(env, ea, &dummy, &dummy);
}

void helper_lducx(CPUTriCoreState *env, uint32_t ea)
{
    uint32_t dummy;
    /* insn doesn't load PCXI and PSW */
    restore_context_upper(env, ea, &dummy, &dummy);
}

void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
{
    save_context_lower(env, ea);
}

void helper_stucx(CPUTriCoreState *env, uint32_t ea)
{
    save_context_upper(env, ea);
}

static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
                                                        uint32_t exception,
                                                        int error_code,
@@ -371,13 +454,6 @@ static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
    cpu_loop_exit(cs);
}

static inline void QEMU_NORETURN do_raise_exception(CPUTriCoreState *env,
                                                    uint32_t exception,
                                                    uintptr_t pc)
{
    do_raise_exception_err(env, exception, 0, pc);
}

void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
              uintptr_t retaddr)
{
+1305 −0

File changed.

Preview size limit exceeded, changes collapsed.

+3 −1
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@
#define MASK_OP_ABSB_OFF18(op) MASK_OP_ABS_OFF18(op)
#define MASK_OP_ABSB_OP2(op)   MASK_BITS_SHIFT(op, 26, 27)
#define MASK_OP_ABSB_B(op)     MASK_BITS_SHIFT(op, 11, 11)
#define MASK_OP_ABSB_BPOS(op)  MASK_BITS_SHIFT(op, 7, 10)
#define MASK_OP_ABSB_BPOS(op)  MASK_BITS_SHIFT(op, 8, 10)

/* B Format   */
#define MASK_OP_B_DISP24(op)   (MASK_BITS_SHIFT(op, 16, 31) + \
@@ -105,6 +105,8 @@
/* BO Format */
#define MASK_OP_BO_OFF10(op)   (MASK_BITS_SHIFT(op, 16, 21) + \
                               (MASK_BITS_SHIFT(op, 28, 31) << 6))
#define MASK_OP_BO_OFF10_SEXT(op)   (MASK_BITS_SHIFT_SEXT(op, 16, 21) + \
                                    (MASK_BITS_SHIFT_SEXT(op, 28, 31) << 6))
#define MASK_OP_BO_OP2(op)     MASK_BITS_SHIFT(op, 22, 27)
#define MASK_OP_BO_S2(op)      MASK_BITS_SHIFT(op, 12, 15)
#define MASK_OP_BO_S1D(op)     MASK_BITS_SHIFT(op, 8, 11)