Commit 0c9fa168 authored by Richard Henderson's avatar Richard Henderson
Browse files

target/s390x: Split do_cdsg, do_lpq, do_stpq

parent 5e95612e
Loading
Loading
Loading
Loading
+58 −64
Original line number Diff line number Diff line
@@ -1380,26 +1380,15 @@ uint32_t HELPER(trXX)(CPUS390XState *env, uint32_t r1, uint32_t r2,
    return cc;
}

static void do_cdsg(CPUS390XState *env, uint64_t addr,
                    uint32_t r1, uint32_t r3, bool parallel)
void HELPER(cdsg)(CPUS390XState *env, uint64_t addr,
                  uint32_t r1, uint32_t r3)
{
    uintptr_t ra = GETPC();
    Int128 cmpv = int128_make128(env->regs[r1 + 1], env->regs[r1]);
    Int128 newv = int128_make128(env->regs[r3 + 1], env->regs[r3]);
    Int128 oldv;
    bool fail;

    if (parallel) {
#if !HAVE_CMPXCHG128
        cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
#else
        int mem_idx = cpu_mmu_index(env, false);
        TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
        oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
        fail = !int128_eq(oldv, cmpv);
#endif
    } else {
    uint64_t oldh, oldl;
    bool fail;

    check_alignment(env, addr, 16, ra);

@@ -1414,23 +1403,35 @@ static void do_cdsg(CPUS390XState *env, uint64_t addr,

    cpu_stq_data_ra(env, addr + 0, int128_gethi(newv), ra);
    cpu_stq_data_ra(env, addr + 8, int128_getlo(newv), ra);
    }

    env->cc_op = fail;
    env->regs[r1] = int128_gethi(oldv);
    env->regs[r1 + 1] = int128_getlo(oldv);
}

void HELPER(cdsg)(CPUS390XState *env, uint64_t addr,
void HELPER(cdsg_parallel)(CPUS390XState *env, uint64_t addr,
                           uint32_t r1, uint32_t r3)
{
    do_cdsg(env, addr, r1, r3, false);
    uintptr_t ra = GETPC();
    Int128 cmpv = int128_make128(env->regs[r1 + 1], env->regs[r1]);
    Int128 newv = int128_make128(env->regs[r3 + 1], env->regs[r3]);
    int mem_idx;
    TCGMemOpIdx oi;
    Int128 oldv;
    bool fail;

    if (!HAVE_CMPXCHG128) {
        cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
    }

void HELPER(cdsg_parallel)(CPUS390XState *env, uint64_t addr,
                           uint32_t r1, uint32_t r3)
{
    do_cdsg(env, addr, r1, r3, true);
    mem_idx = cpu_mmu_index(env, false);
    oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
    oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
    fail = !int128_eq(oldv, cmpv);

    env->cc_op = fail;
    env->regs[r1] = int128_gethi(oldv);
    env->regs[r1 + 1] = int128_getlo(oldv);
}

static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
@@ -2097,16 +2098,25 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
#endif

/* load pair from quadword */
static uint64_t do_lpq(CPUS390XState *env, uint64_t addr, bool parallel)
uint64_t HELPER(lpq)(CPUS390XState *env, uint64_t addr)
{
    uintptr_t ra = GETPC();
    uint64_t hi, lo;

    if (!parallel) {
    check_alignment(env, addr, 16, ra);
    hi = cpu_ldq_data_ra(env, addr + 0, ra);
    lo = cpu_ldq_data_ra(env, addr + 8, ra);
    } else if (HAVE_ATOMIC128) {

    env->retxl = lo;
    return hi;
}

uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr)
{
    uintptr_t ra = GETPC();
    uint64_t hi, lo;

    if (HAVE_ATOMIC128) {
        int mem_idx = cpu_mmu_index(env, false);
        TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
        Int128 v = helper_atomic_ldo_be_mmu(env, addr, oi, ra);
@@ -2120,27 +2130,23 @@ static uint64_t do_lpq(CPUS390XState *env, uint64_t addr, bool parallel)
    return hi;
}

uint64_t HELPER(lpq)(CPUS390XState *env, uint64_t addr)
{
    return do_lpq(env, addr, false);
}

uint64_t HELPER(lpq_parallel)(CPUS390XState *env, uint64_t addr)
{
    return do_lpq(env, addr, true);
}

/* store pair to quadword */
static void do_stpq(CPUS390XState *env, uint64_t addr,
                    uint64_t low, uint64_t high, bool parallel)
void HELPER(stpq)(CPUS390XState *env, uint64_t addr,
                  uint64_t low, uint64_t high)
{
    uintptr_t ra = GETPC();

    if (!parallel) {
    check_alignment(env, addr, 16, ra);
    cpu_stq_data_ra(env, addr + 0, high, ra);
    cpu_stq_data_ra(env, addr + 8, low, ra);
    } else if (HAVE_ATOMIC128) {
}

void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
                           uint64_t low, uint64_t high)
{
    uintptr_t ra = GETPC();

    if (HAVE_ATOMIC128) {
        int mem_idx = cpu_mmu_index(env, false);
        TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);
        Int128 v = int128_make128(low, high);
@@ -2150,18 +2156,6 @@ static void do_stpq(CPUS390XState *env, uint64_t addr,
    }
}

void HELPER(stpq)(CPUS390XState *env, uint64_t addr,
                  uint64_t low, uint64_t high)
{
    do_stpq(env, addr, low, high, false);
}

void HELPER(stpq_parallel)(CPUS390XState *env, uint64_t addr,
                           uint64_t low, uint64_t high)
{
    do_stpq(env, addr, low, high, true);
}

/* Execute instruction.  This instruction executes an insn modified with
   the contents of r1.  It does not change the executed instruction in memory;
   it does not change the program counter.