Revision b4e2bd35

b/target-s390x/cpu.h
931 931

  
932 932
/* misc_helper.c */
933 933
void program_interrupt(CPUS390XState *env, uint32_t code, int ilen);
934
void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
935
                                     uintptr_t retaddr);
934 936

  
935 937
#endif
b/target-s390x/int_helper.c
38 38
}
39 39

  
40 40
/* 64/32 -> 32 signed division */
41
int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b)
41
int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
42 42
{
43
    env->retxl = a % (int32_t)b;
44
    return a / (int32_t)b;
43
    int32_t ret, b = b64;
44
    int64_t q;
45

  
46
    if (b == 0) {
47
        runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
48
    }
49

  
50
    ret = q = a / b;
51
    env->retxl = a % b;
52

  
53
    /* Catch non-representable quotient.  */
54
    if (ret != q) {
55
        runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
56
    }
57

  
58
    return ret;
45 59
}
46 60

  
47 61
/* 64/32 -> 32 unsigned division */
48
uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b)
62
uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
49 63
{
50
    env->retxl = a % (uint32_t)b;
51
    return a / (uint32_t)b;
64
    uint32_t ret, b = b64;
65
    uint64_t q;
66

  
67
    if (b == 0) {
68
        runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
69
    }
70

  
71
    ret = q = a / b;
72
    env->retxl = a % b;
73

  
74
    /* Catch non-representable quotient.  */
75
    if (ret != q) {
76
        runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
77
    }
78

  
79
    return ret;
52 80
}
53 81

  
54 82
/* 64/64 -> 64 signed division */
55 83
int64_t HELPER(divs64)(CPUS390XState *env, int64_t a, int64_t b)
56 84
{
85
    /* Catch divide by zero, and non-representable quotient (MIN / -1).  */
86
    if (b == 0 || (b == -1 && a == (1ll << 63))) {
87
        runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
88
    }
57 89
    env->retxl = a % b;
58 90
    return a / b;
59 91
}
......
63 95
                        uint64_t b)
64 96
{
65 97
    uint64_t ret;
98
    /* Signal divide by zero.  */
99
    if (b == 0) {
100
        runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
101
    }
66 102
    if (ah == 0) {
67 103
        /* 64 -> 64/64 case */
68 104
        env->retxl = al % b;
......
75 111
        __uint128_t q = a / b;
76 112
        env->retxl = a % b;
77 113
        ret = q;
114
        if (ret != q) {
115
            runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
116
        }
78 117
#else
79 118
        /* 32-bit hosts would need special wrapper functionality - just abort if
80 119
           we encounter such a case; it's very unlikely anyways. */
b/target-s390x/misc_helper.c
41 41
#define HELPER_LOG(x...)
42 42
#endif
43 43

  
44
/* Raise an exception dynamically from a helper function.  */
45
void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
46
                                     uintptr_t retaddr)
47
{
48
    int t;
49

  
50
    env->exception_index = EXCP_PGM;
51
    env->int_pgm_code = excp;
52

  
53
    /* Use the (ultimate) callers address to find the insn that trapped.  */
54
    cpu_restore_state(env, retaddr);
55

  
56
    /* Advance past the insn.  */
57
    t = cpu_ldub_code(env, env->psw.addr);
58
    env->int_pgm_ilen = t = get_ilen(t);
59
    env->psw.addr += 2 * t;
60

  
61
    cpu_loop_exit(env);
62
}
63

  
44 64
/* Raise an exception statically from a TB.  */
45 65
void HELPER(exception)(CPUS390XState *env, uint32_t excp)
46 66
{

Also available in: Unified diff