Commit 00967f4e authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/agraf/tags/signed-s390-for-upstream' into staging



Patch queue for s390 - 2015-06-05

This time there are a lot of s390x TCG emulation bug fixes - almost all
of them from Aurelien, who returned from nirvana :).

# gpg: Signature made Fri Jun  5 00:39:27 2015 BST using RSA key ID 03FEDC60
# gpg: Good signature from "Alexander Graf <agraf@suse.de>"
# gpg:                 aka "Alexander Graf <alex@csgraf.de>"

* remotes/agraf/tags/signed-s390-for-upstream: (34 commits)
  target-s390x: Only access allocated storage keys
  target-s390x: fix MVC instruction when areas overlap
  target-s390x: use softmmu functions for mvcp/mvcs
  target-s390x: support non current ASC in s390_cpu_handle_mmu_fault
  target-s390x: add a cpu_mmu_idx_to_asc function
  target-s390x: implement high-word facility
  target-s390x: implement load-and-trap facility
  target-s390x: implement miscellaneous-instruction-extensions facility
  target-s390x: implement LPDFR and LNDFR instructions
  target-s390x: implement TRANSLATE EXTENDED instruction
  target-s390x: implement TRANSLATE AND TEST instruction
  target-s390x: implement LOAD FP INTEGER instructions
  target-s390x: move SET DFP ROUNDING MODE to the correct facility
  target-s390x: move STORE CLOCK FAST to the correct facility
  target-s390x: change CHRL and CGHRL format to RIL-b
  target-s390x: fix CLGIT instruction
  target-s390x: fix exception for invalid operation code
  target-s390x: implement LAY and LAEY instructions
  target-s390x: move a few instructions to the correct facility
  target-s390x: detect tininess before rounding for FP operations
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents d6688ba1 9814fed0
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ const float16 float16_default_nan = const_float16(0xFE00);
#if defined(TARGET_SPARC)
const float32 float32_default_nan = const_float32(0x7FFFFFFF);
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
      defined(TARGET_XTENSA)
      defined(TARGET_XTENSA) || defined(TARGET_S390X)
const float32 float32_default_nan = const_float32(0x7FC00000);
#elif SNAN_BIT_IS_ONE
const float32 float32_default_nan = const_float32(0x7FBFFFFF);
@@ -126,7 +126,8 @@ const float32 float32_default_nan = const_float32(0xFFC00000);
*----------------------------------------------------------------------------*/
#if defined(TARGET_SPARC)
const float64 float64_default_nan = const_float64(LIT64( 0x7FFFFFFFFFFFFFFF ));
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
      defined(TARGET_S390X)
const float64 float64_default_nan = const_float64(LIT64( 0x7FF8000000000000 ));
#elif SNAN_BIT_IS_ONE
const float64 float64_default_nan = const_float64(LIT64(0x7FF7FFFFFFFFFFFF));
@@ -155,6 +156,9 @@ const floatx80 floatx80_default_nan
#if SNAN_BIT_IS_ONE
#define float128_default_nan_high LIT64(0x7FFF7FFFFFFFFFFF)
#define float128_default_nan_low  LIT64(0xFFFFFFFFFFFFFFFF)
#elif defined(TARGET_S390X)
#define float128_default_nan_high LIT64( 0x7FFF800000000000 )
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
#else
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
+2 −2
Original line number Diff line number Diff line
@@ -195,7 +195,7 @@ static uint32_t cc_calc_abs_64(int64_t dst)
    if ((uint64_t)dst == 0x8000000000000000ULL) {
        return 3;
    } else if (dst) {
        return 1;
        return 2;
    } else {
        return 0;
    }
@@ -296,7 +296,7 @@ static uint32_t cc_calc_abs_32(int32_t dst)
    if ((uint32_t)dst == 0x80000000UL) {
        return 3;
    } else if (dst) {
        return 1;
        return 2;
    } else {
        return 0;
    }
+8 −0
Original line number Diff line number Diff line
@@ -118,6 +118,10 @@ static void s390_cpu_initial_reset(CPUState *s)

    env->pfault_token = -1UL;

    /* tininess for underflow is detected before rounding */
    set_float_detect_tininess(float_tininess_before_rounding,
                              &env->fpu_status);

    /* Reset state inside the kernel that we cannot access yet from QEMU. */
    if (kvm_enabled()) {
        kvm_s390_reset_vcpu(cpu);
@@ -143,6 +147,10 @@ static void s390_cpu_full_reset(CPUState *s)

    env->pfault_token = -1UL;

    /* tininess for underflow is detected before rounding */
    set_float_detect_tininess(float_tininess_before_rounding,
                              &env->fpu_status);

    /* Reset state inside the kernel that we cannot access yet from QEMU. */
    if (kvm_enabled()) {
        kvm_s390_reset_vcpu(cpu);
+35 −4
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@
#define MMU_MODE1_SUFFIX _secondary
#define MMU_MODE2_SUFFIX _home

#define MMU_USER_IDX 1
#define MMU_USER_IDX 0

#define MAX_EXT_QUEUE 16
#define MAX_IO_QUEUE 16
@@ -302,13 +302,39 @@ static inline CPU_DoubleU *get_freg(CPUS390XState *cs, int nr)
#define CR0_LOWPROT             0x0000000010000000ULL
#define CR0_EDAT                0x0000000000800000ULL

/* MMU */
#define MMU_PRIMARY_IDX         0
#define MMU_SECONDARY_IDX       1
#define MMU_HOME_IDX            2

static inline int cpu_mmu_index (CPUS390XState *env)
{
    if (env->psw.mask & PSW_MASK_PSTATE) {
        return 1;
    switch (env->psw.mask & PSW_MASK_ASC) {
    case PSW_ASC_PRIMARY:
        return MMU_PRIMARY_IDX;
    case PSW_ASC_SECONDARY:
        return MMU_SECONDARY_IDX;
    case PSW_ASC_HOME:
        return MMU_HOME_IDX;
    case PSW_ASC_ACCREG:
        /* Fallthrough: access register mode is not yet supported */
    default:
        abort();
    }
}

    return 0;
static inline uint64_t cpu_mmu_idx_to_asc(int mmu_idx)
{
    switch (mmu_idx) {
    case MMU_PRIMARY_IDX:
        return PSW_ASC_PRIMARY;
    case MMU_SECONDARY_IDX:
        return PSW_ASC_SECONDARY;
    case MMU_HOME_IDX:
        return PSW_ASC_HOME;
    default:
        abort();
    }
}

static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
@@ -995,6 +1021,11 @@ static inline uint64_t time2tod(uint64_t ns) {
    return (ns << 9) / 125;
}

/* Converts s390's clock format to ns */
static inline uint64_t tod2time(uint64_t t) {
    return (t * 125) >> 9;
}

static inline void cpu_inject_ext(S390CPU *cpu, uint32_t code, uint32_t param,
                                  uint64_t param64)
{
+37 −6
Original line number Diff line number Diff line
@@ -265,7 +265,7 @@ uint64_t HELPER(ldeb)(CPUS390XState *env, uint64_t f2)
{
    float64 ret = float32_to_float64(f2, &env->fpu_status);
    handle_exceptions(env, GETPC());
    return ret;
    return float64_maybe_silence_nan(ret);
}

/* convert 128-bit float to 64-bit float */
@@ -273,7 +273,7 @@ uint64_t HELPER(ldxb)(CPUS390XState *env, uint64_t ah, uint64_t al)
{
    float64 ret = float128_to_float64(make_float128(ah, al), &env->fpu_status);
    handle_exceptions(env, GETPC());
    return ret;
    return float64_maybe_silence_nan(ret);
}

/* convert 64-bit float to 128-bit float */
@@ -281,7 +281,7 @@ uint64_t HELPER(lxdb)(CPUS390XState *env, uint64_t f2)
{
    float128 ret = float64_to_float128(f2, &env->fpu_status);
    handle_exceptions(env, GETPC());
    return RET128(ret);
    return RET128(float128_maybe_silence_nan(ret));
}

/* convert 32-bit float to 128-bit float */
@@ -289,7 +289,7 @@ uint64_t HELPER(lxeb)(CPUS390XState *env, uint64_t f2)
{
    float128 ret = float32_to_float128(f2, &env->fpu_status);
    handle_exceptions(env, GETPC());
    return RET128(ret);
    return RET128(float128_maybe_silence_nan(ret));
}

/* convert 64-bit float to 32-bit float */
@@ -297,7 +297,7 @@ uint64_t HELPER(ledb)(CPUS390XState *env, uint64_t f2)
{
    float32 ret = float64_to_float32(f2, &env->fpu_status);
    handle_exceptions(env, GETPC());
    return ret;
    return float32_maybe_silence_nan(ret);
}

/* convert 128-bit float to 32-bit float */
@@ -305,7 +305,7 @@ uint64_t HELPER(lexb)(CPUS390XState *env, uint64_t ah, uint64_t al)
{
    float32 ret = float128_to_float32(make_float128(ah, al), &env->fpu_status);
    handle_exceptions(env, GETPC());
    return ret;
    return float32_maybe_silence_nan(ret);
}

/* 32-bit FP compare */
@@ -552,6 +552,37 @@ uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m3)
    return ret;
}

/* round to integer 32-bit */
uint64_t HELPER(fieb)(CPUS390XState *env, uint64_t f2, uint32_t m3)
{
    int hold = swap_round_mode(env, m3);
    float32 ret = float32_round_to_int(f2, &env->fpu_status);
    set_float_rounding_mode(hold, &env->fpu_status);
    handle_exceptions(env, GETPC());
    return ret;
}

/* round to integer 64-bit */
uint64_t HELPER(fidb)(CPUS390XState *env, uint64_t f2, uint32_t m3)
{
    int hold = swap_round_mode(env, m3);
    float64 ret = float64_round_to_int(f2, &env->fpu_status);
    set_float_rounding_mode(hold, &env->fpu_status);
    handle_exceptions(env, GETPC());
    return ret;
}

/* round to integer 128-bit */
uint64_t HELPER(fixb)(CPUS390XState *env, uint64_t ah, uint64_t al, uint32_t m3)
{
    int hold = swap_round_mode(env, m3);
    float128 ret = float128_round_to_int(make_float128(ah, al),
                                         &env->fpu_status);
    set_float_rounding_mode(hold, &env->fpu_status);
    handle_exceptions(env, GETPC());
    return RET128(ret);
}

/* 32-bit FP multiply and add */
uint64_t HELPER(maeb)(CPUS390XState *env, uint64_t f1,
                      uint64_t f2, uint64_t f3)
Loading