Statistics
| Branch: | Revision:

root / target-sparc / helper.c @ c09015dd

History | View | Annotate | Download (3.2 kB)

1
/*
2
 *  Misc Sparc helpers
3
 *
4
 *  Copyright (c) 2003-2005 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 */
19

    
20
#include "cpu.h"
21
#include "host-utils.h"
22
#include "helper.h"
23
#include "sysemu.h"
24

    
25
void helper_raise_exception(CPUState *env, int tt)
26
{
27
    env->exception_index = tt;
28
    cpu_loop_exit(env);
29
}
30

    
31
void helper_debug(CPUState *env)
32
{
33
    env->exception_index = EXCP_DEBUG;
34
    cpu_loop_exit(env);
35
}
36

    
37
#ifdef TARGET_SPARC64
38
target_ulong helper_popc(target_ulong val)
39
{
40
    return ctpop64(val);
41
}
42

    
43
void helper_tick_set_count(void *opaque, uint64_t count)
44
{
45
#if !defined(CONFIG_USER_ONLY)
46
    cpu_tick_set_count(opaque, count);
47
#endif
48
}
49

    
50
uint64_t helper_tick_get_count(void *opaque)
51
{
52
#if !defined(CONFIG_USER_ONLY)
53
    return cpu_tick_get_count(opaque);
54
#else
55
    return 0;
56
#endif
57
}
58

    
59
void helper_tick_set_limit(void *opaque, uint64_t limit)
60
{
61
#if !defined(CONFIG_USER_ONLY)
62
    cpu_tick_set_limit(opaque, limit);
63
#endif
64
}
65
#endif
66

    
67
static target_ulong helper_udiv_common(CPUState *env, target_ulong a,
68
                                       target_ulong b, int cc)
69
{
70
    int overflow = 0;
71
    uint64_t x0;
72
    uint32_t x1;
73

    
74
    x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
75
    x1 = (b & 0xffffffff);
76

    
77
    if (x1 == 0) {
78
        helper_raise_exception(env, TT_DIV_ZERO);
79
    }
80

    
81
    x0 = x0 / x1;
82
    if (x0 > 0xffffffff) {
83
        x0 = 0xffffffff;
84
        overflow = 1;
85
    }
86

    
87
    if (cc) {
88
        env->cc_dst = x0;
89
        env->cc_src2 = overflow;
90
        env->cc_op = CC_OP_DIV;
91
    }
92
    return x0;
93
}
94

    
95
target_ulong helper_udiv(CPUState *env, target_ulong a, target_ulong b)
96
{
97
    return helper_udiv_common(env, a, b, 0);
98
}
99

    
100
target_ulong helper_udiv_cc(CPUState *env, target_ulong a, target_ulong b)
101
{
102
    return helper_udiv_common(env, a, b, 1);
103
}
104

    
105
static target_ulong helper_sdiv_common(CPUState *env, target_ulong a,
106
                                       target_ulong b, int cc)
107
{
108
    int overflow = 0;
109
    int64_t x0;
110
    int32_t x1;
111

    
112
    x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
113
    x1 = (b & 0xffffffff);
114

    
115
    if (x1 == 0) {
116
        helper_raise_exception(env, TT_DIV_ZERO);
117
    }
118

    
119
    x0 = x0 / x1;
120
    if ((int32_t) x0 != x0) {
121
        x0 = x0 < 0 ? 0x80000000 : 0x7fffffff;
122
        overflow = 1;
123
    }
124

    
125
    if (cc) {
126
        env->cc_dst = x0;
127
        env->cc_src2 = overflow;
128
        env->cc_op = CC_OP_DIV;
129
    }
130
    return x0;
131
}
132

    
133
target_ulong helper_sdiv(CPUState *env, target_ulong a, target_ulong b)
134
{
135
    return helper_sdiv_common(env, a, b, 0);
136
}
137

    
138
target_ulong helper_sdiv_cc(CPUState *env, target_ulong a, target_ulong b)
139
{
140
    return helper_sdiv_common(env, a, b, 1);
141
}