Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 543fc7b2

History | View | Annotate | Download (101.9 kB)

1 e8af50a3 bellard
#include "exec.h"
2 eed152bb blueswir1
#include "host-utils.h"
3 1a2fb1c0 blueswir1
#include "helper.h"
4 0828b448 blueswir1
#if !defined(CONFIG_USER_ONLY)
5 0828b448 blueswir1
#include "softmmu_exec.h"
6 0828b448 blueswir1
#endif /* !defined(CONFIG_USER_ONLY) */
7 e8af50a3 bellard
8 e80cfcfc bellard
//#define DEBUG_MMU
9 952a328f blueswir1
//#define DEBUG_MXCC
10 94554550 blueswir1
//#define DEBUG_UNALIGNED
11 6c36d3fa blueswir1
//#define DEBUG_UNASSIGNED
12 8543e2cf blueswir1
//#define DEBUG_ASI
13 d81fd722 blueswir1
//#define DEBUG_PCALL
14 e80cfcfc bellard
15 952a328f blueswir1
#ifdef DEBUG_MMU
16 001faf32 Blue Swirl
#define DPRINTF_MMU(fmt, ...)                                   \
17 001faf32 Blue Swirl
    do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
18 952a328f blueswir1
#else
19 001faf32 Blue Swirl
#define DPRINTF_MMU(fmt, ...) do {} while (0)
20 952a328f blueswir1
#endif
21 952a328f blueswir1
22 952a328f blueswir1
#ifdef DEBUG_MXCC
23 001faf32 Blue Swirl
#define DPRINTF_MXCC(fmt, ...)                                  \
24 001faf32 Blue Swirl
    do { printf("MXCC: " fmt , ## __VA_ARGS__); } while (0)
25 952a328f blueswir1
#else
26 001faf32 Blue Swirl
#define DPRINTF_MXCC(fmt, ...) do {} while (0)
27 952a328f blueswir1
#endif
28 952a328f blueswir1
29 8543e2cf blueswir1
#ifdef DEBUG_ASI
30 001faf32 Blue Swirl
#define DPRINTF_ASI(fmt, ...)                                   \
31 001faf32 Blue Swirl
    do { printf("ASI: " fmt , ## __VA_ARGS__); } while (0)
32 8543e2cf blueswir1
#endif
33 8543e2cf blueswir1
34 2cade6a3 blueswir1
#ifdef TARGET_SPARC64
35 2cade6a3 blueswir1
#ifndef TARGET_ABI32
36 2cade6a3 blueswir1
#define AM_CHECK(env1) ((env1)->pstate & PS_AM)
37 c2bc0e38 blueswir1
#else
38 2cade6a3 blueswir1
#define AM_CHECK(env1) (1)
39 2cade6a3 blueswir1
#endif
40 c2bc0e38 blueswir1
#endif
41 c2bc0e38 blueswir1
42 9c22a623 Blue Swirl
#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
43 697a77e6 Igor Kovalenko
// Calculates TSB pointer value for fault page size 8k or 64k
44 697a77e6 Igor Kovalenko
static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register,
45 697a77e6 Igor Kovalenko
                                       uint64_t tag_access_register,
46 697a77e6 Igor Kovalenko
                                       int page_size)
47 697a77e6 Igor Kovalenko
{
48 697a77e6 Igor Kovalenko
    uint64_t tsb_base = tsb_register & ~0x1fffULL;
49 6e8e7d4c Igor Kovalenko
    int tsb_split = (tsb_register & 0x1000ULL) ? 1 : 0;
50 6e8e7d4c Igor Kovalenko
    int tsb_size  = tsb_register & 0xf;
51 697a77e6 Igor Kovalenko
52 697a77e6 Igor Kovalenko
    // discard lower 13 bits which hold tag access context
53 697a77e6 Igor Kovalenko
    uint64_t tag_access_va = tag_access_register & ~0x1fffULL;
54 697a77e6 Igor Kovalenko
55 697a77e6 Igor Kovalenko
    // now reorder bits
56 697a77e6 Igor Kovalenko
    uint64_t tsb_base_mask = ~0x1fffULL;
57 697a77e6 Igor Kovalenko
    uint64_t va = tag_access_va;
58 697a77e6 Igor Kovalenko
59 697a77e6 Igor Kovalenko
    // move va bits to correct position
60 697a77e6 Igor Kovalenko
    if (page_size == 8*1024) {
61 697a77e6 Igor Kovalenko
        va >>= 9;
62 697a77e6 Igor Kovalenko
    } else if (page_size == 64*1024) {
63 697a77e6 Igor Kovalenko
        va >>= 12;
64 697a77e6 Igor Kovalenko
    }
65 697a77e6 Igor Kovalenko
66 697a77e6 Igor Kovalenko
    if (tsb_size) {
67 697a77e6 Igor Kovalenko
        tsb_base_mask <<= tsb_size;
68 697a77e6 Igor Kovalenko
    }
69 697a77e6 Igor Kovalenko
70 697a77e6 Igor Kovalenko
    // calculate tsb_base mask and adjust va if split is in use
71 697a77e6 Igor Kovalenko
    if (tsb_split) {
72 697a77e6 Igor Kovalenko
        if (page_size == 8*1024) {
73 697a77e6 Igor Kovalenko
            va &= ~(1ULL << (13 + tsb_size));
74 697a77e6 Igor Kovalenko
        } else if (page_size == 64*1024) {
75 697a77e6 Igor Kovalenko
            va |= (1ULL << (13 + tsb_size));
76 697a77e6 Igor Kovalenko
        }
77 697a77e6 Igor Kovalenko
        tsb_base_mask <<= 1;
78 697a77e6 Igor Kovalenko
    }
79 697a77e6 Igor Kovalenko
80 697a77e6 Igor Kovalenko
    return ((tsb_base & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL;
81 697a77e6 Igor Kovalenko
}
82 697a77e6 Igor Kovalenko
83 697a77e6 Igor Kovalenko
// Calculates tag target register value by reordering bits
84 697a77e6 Igor Kovalenko
// in tag access register
85 697a77e6 Igor Kovalenko
static uint64_t ultrasparc_tag_target(uint64_t tag_access_register)
86 697a77e6 Igor Kovalenko
{
87 697a77e6 Igor Kovalenko
    return ((tag_access_register & 0x1fff) << 48) | (tag_access_register >> 22);
88 697a77e6 Igor Kovalenko
}
89 697a77e6 Igor Kovalenko
90 f707726e Igor Kovalenko
static void replace_tlb_entry(SparcTLBEntry *tlb,
91 f707726e Igor Kovalenko
                              uint64_t tlb_tag, uint64_t tlb_tte,
92 f707726e Igor Kovalenko
                              CPUState *env1)
93 6e8e7d4c Igor Kovalenko
{
94 6e8e7d4c Igor Kovalenko
    target_ulong mask, size, va, offset;
95 6e8e7d4c Igor Kovalenko
96 6e8e7d4c Igor Kovalenko
    // flush page range if translation is valid
97 f707726e Igor Kovalenko
    if (TTE_IS_VALID(tlb->tte)) {
98 6e8e7d4c Igor Kovalenko
99 6e8e7d4c Igor Kovalenko
        mask = 0xffffffffffffe000ULL;
100 6e8e7d4c Igor Kovalenko
        mask <<= 3 * ((tlb->tte >> 61) & 3);
101 6e8e7d4c Igor Kovalenko
        size = ~mask + 1;
102 6e8e7d4c Igor Kovalenko
103 6e8e7d4c Igor Kovalenko
        va = tlb->tag & mask;
104 6e8e7d4c Igor Kovalenko
105 6e8e7d4c Igor Kovalenko
        for (offset = 0; offset < size; offset += TARGET_PAGE_SIZE) {
106 6e8e7d4c Igor Kovalenko
            tlb_flush_page(env1, va + offset);
107 6e8e7d4c Igor Kovalenko
        }
108 6e8e7d4c Igor Kovalenko
    }
109 6e8e7d4c Igor Kovalenko
110 6e8e7d4c Igor Kovalenko
    tlb->tag = tlb_tag;
111 6e8e7d4c Igor Kovalenko
    tlb->tte = tlb_tte;
112 6e8e7d4c Igor Kovalenko
}
113 6e8e7d4c Igor Kovalenko
114 6e8e7d4c Igor Kovalenko
static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr,
115 f707726e Igor Kovalenko
                      const char* strmmu, CPUState *env1)
116 6e8e7d4c Igor Kovalenko
{
117 6e8e7d4c Igor Kovalenko
    unsigned int i;
118 6e8e7d4c Igor Kovalenko
    target_ulong mask;
119 6e8e7d4c Igor Kovalenko
120 6e8e7d4c Igor Kovalenko
    for (i = 0; i < 64; i++) {
121 f707726e Igor Kovalenko
        if (TTE_IS_VALID(tlb[i].tte)) {
122 6e8e7d4c Igor Kovalenko
123 6e8e7d4c Igor Kovalenko
            mask = 0xffffffffffffe000ULL;
124 6e8e7d4c Igor Kovalenko
            mask <<= 3 * ((tlb[i].tte >> 61) & 3);
125 6e8e7d4c Igor Kovalenko
126 6e8e7d4c Igor Kovalenko
            if ((demap_addr & mask) == (tlb[i].tag & mask)) {
127 f707726e Igor Kovalenko
                replace_tlb_entry(&tlb[i], 0, 0, env1);
128 6e8e7d4c Igor Kovalenko
#ifdef DEBUG_MMU
129 f707726e Igor Kovalenko
                DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i);
130 f707726e Igor Kovalenko
                dump_mmu(env1);
131 6e8e7d4c Igor Kovalenko
#endif
132 6e8e7d4c Igor Kovalenko
            }
133 6e8e7d4c Igor Kovalenko
            //return;
134 6e8e7d4c Igor Kovalenko
        }
135 6e8e7d4c Igor Kovalenko
    }
136 6e8e7d4c Igor Kovalenko
137 6e8e7d4c Igor Kovalenko
}
138 6e8e7d4c Igor Kovalenko
139 f707726e Igor Kovalenko
static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
140 f707726e Igor Kovalenko
                                 uint64_t tlb_tag, uint64_t tlb_tte,
141 f707726e Igor Kovalenko
                                 const char* strmmu, CPUState *env1)
142 f707726e Igor Kovalenko
{
143 f707726e Igor Kovalenko
    unsigned int i, replace_used;
144 f707726e Igor Kovalenko
145 f707726e Igor Kovalenko
    // Try replacing invalid entry
146 f707726e Igor Kovalenko
    for (i = 0; i < 64; i++) {
147 f707726e Igor Kovalenko
        if (!TTE_IS_VALID(tlb[i].tte)) {
148 f707726e Igor Kovalenko
            replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
149 f707726e Igor Kovalenko
#ifdef DEBUG_MMU
150 f707726e Igor Kovalenko
            DPRINTF_MMU("%s lru replaced invalid entry [%i]\n", strmmu, i);
151 f707726e Igor Kovalenko
            dump_mmu(env1);
152 f707726e Igor Kovalenko
#endif
153 f707726e Igor Kovalenko
            return;
154 f707726e Igor Kovalenko
        }
155 f707726e Igor Kovalenko
    }
156 f707726e Igor Kovalenko
157 f707726e Igor Kovalenko
    // All entries are valid, try replacing unlocked entry
158 f707726e Igor Kovalenko
159 f707726e Igor Kovalenko
    for (replace_used = 0; replace_used < 2; ++replace_used) {
160 f707726e Igor Kovalenko
161 f707726e Igor Kovalenko
        // Used entries are not replaced on first pass
162 f707726e Igor Kovalenko
163 f707726e Igor Kovalenko
        for (i = 0; i < 64; i++) {
164 f707726e Igor Kovalenko
            if (!TTE_IS_LOCKED(tlb[i].tte) && !TTE_IS_USED(tlb[i].tte)) {
165 f707726e Igor Kovalenko
166 f707726e Igor Kovalenko
                replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
167 f707726e Igor Kovalenko
#ifdef DEBUG_MMU
168 f707726e Igor Kovalenko
                DPRINTF_MMU("%s lru replaced unlocked %s entry [%i]\n",
169 f707726e Igor Kovalenko
                            strmmu, (replace_used?"used":"unused"), i);
170 f707726e Igor Kovalenko
                dump_mmu(env1);
171 f707726e Igor Kovalenko
#endif
172 f707726e Igor Kovalenko
                return;
173 f707726e Igor Kovalenko
            }
174 f707726e Igor Kovalenko
        }
175 f707726e Igor Kovalenko
176 f707726e Igor Kovalenko
        // Now reset used bit and search for unused entries again
177 f707726e Igor Kovalenko
178 f707726e Igor Kovalenko
        for (i = 0; i < 64; i++) {
179 f707726e Igor Kovalenko
            TTE_SET_UNUSED(tlb[i].tte);
180 f707726e Igor Kovalenko
        }
181 f707726e Igor Kovalenko
    }
182 f707726e Igor Kovalenko
183 f707726e Igor Kovalenko
#ifdef DEBUG_MMU
184 f707726e Igor Kovalenko
    DPRINTF_MMU("%s lru replacement failed: no entries available\n", strmmu);
185 f707726e Igor Kovalenko
#endif
186 f707726e Igor Kovalenko
    // error state?
187 f707726e Igor Kovalenko
}
188 f707726e Igor Kovalenko
189 697a77e6 Igor Kovalenko
#endif
190 697a77e6 Igor Kovalenko
191 2cade6a3 blueswir1
static inline void address_mask(CPUState *env1, target_ulong *addr)
192 2cade6a3 blueswir1
{
193 2cade6a3 blueswir1
#ifdef TARGET_SPARC64
194 2cade6a3 blueswir1
    if (AM_CHECK(env1))
195 2cade6a3 blueswir1
        *addr &= 0xffffffffULL;
196 2cade6a3 blueswir1
#endif
197 2cade6a3 blueswir1
}
198 2cade6a3 blueswir1
199 f4a5a5ba blueswir1
static void raise_exception(int tt)
200 9d893301 bellard
{
201 9d893301 bellard
    env->exception_index = tt;
202 9d893301 bellard
    cpu_loop_exit();
203 3b46e624 ths
}
204 9d893301 bellard
205 a7812ae4 pbrook
void HELPER(raise_exception)(int tt)
206 a7812ae4 pbrook
{
207 a7812ae4 pbrook
    raise_exception(tt);
208 a7812ae4 pbrook
}
209 a7812ae4 pbrook
210 91736d37 blueswir1
static inline void set_cwp(int new_cwp)
211 91736d37 blueswir1
{
212 91736d37 blueswir1
    cpu_set_cwp(env, new_cwp);
213 91736d37 blueswir1
}
214 91736d37 blueswir1
215 2b29924f blueswir1
void helper_check_align(target_ulong addr, uint32_t align)
216 2b29924f blueswir1
{
217 c2bc0e38 blueswir1
    if (addr & align) {
218 c2bc0e38 blueswir1
#ifdef DEBUG_UNALIGNED
219 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
220 c2bc0e38 blueswir1
           "\n", addr, env->pc);
221 c2bc0e38 blueswir1
#endif
222 2b29924f blueswir1
        raise_exception(TT_UNALIGNED);
223 c2bc0e38 blueswir1
    }
224 2b29924f blueswir1
}
225 2b29924f blueswir1
226 44e7757c blueswir1
#define F_HELPER(name, p) void helper_f##name##p(void)
227 44e7757c blueswir1
228 44e7757c blueswir1
#define F_BINOP(name)                                           \
229 714547bb blueswir1
    float32 helper_f ## name ## s (float32 src1, float32 src2)  \
230 44e7757c blueswir1
    {                                                           \
231 714547bb blueswir1
        return float32_ ## name (src1, src2, &env->fp_status);  \
232 44e7757c blueswir1
    }                                                           \
233 44e7757c blueswir1
    F_HELPER(name, d)                                           \
234 44e7757c blueswir1
    {                                                           \
235 44e7757c blueswir1
        DT0 = float64_ ## name (DT0, DT1, &env->fp_status);     \
236 4e14008f blueswir1
    }                                                           \
237 4e14008f blueswir1
    F_HELPER(name, q)                                           \
238 4e14008f blueswir1
    {                                                           \
239 4e14008f blueswir1
        QT0 = float128_ ## name (QT0, QT1, &env->fp_status);    \
240 44e7757c blueswir1
    }
241 44e7757c blueswir1
242 44e7757c blueswir1
F_BINOP(add);
243 44e7757c blueswir1
F_BINOP(sub);
244 44e7757c blueswir1
F_BINOP(mul);
245 44e7757c blueswir1
F_BINOP(div);
246 44e7757c blueswir1
#undef F_BINOP
247 44e7757c blueswir1
248 d84763bc blueswir1
void helper_fsmuld(float32 src1, float32 src2)
249 1a2fb1c0 blueswir1
{
250 d84763bc blueswir1
    DT0 = float64_mul(float32_to_float64(src1, &env->fp_status),
251 d84763bc blueswir1
                      float32_to_float64(src2, &env->fp_status),
252 44e7757c blueswir1
                      &env->fp_status);
253 44e7757c blueswir1
}
254 1a2fb1c0 blueswir1
255 4e14008f blueswir1
void helper_fdmulq(void)
256 4e14008f blueswir1
{
257 4e14008f blueswir1
    QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status),
258 4e14008f blueswir1
                       float64_to_float128(DT1, &env->fp_status),
259 4e14008f blueswir1
                       &env->fp_status);
260 4e14008f blueswir1
}
261 4e14008f blueswir1
262 714547bb blueswir1
float32 helper_fnegs(float32 src)
263 44e7757c blueswir1
{
264 714547bb blueswir1
    return float32_chs(src);
265 417454b0 blueswir1
}
266 417454b0 blueswir1
267 44e7757c blueswir1
#ifdef TARGET_SPARC64
268 44e7757c blueswir1
F_HELPER(neg, d)
269 7e8c2b6c blueswir1
{
270 44e7757c blueswir1
    DT0 = float64_chs(DT1);
271 7e8c2b6c blueswir1
}
272 4e14008f blueswir1
273 4e14008f blueswir1
F_HELPER(neg, q)
274 4e14008f blueswir1
{
275 4e14008f blueswir1
    QT0 = float128_chs(QT1);
276 4e14008f blueswir1
}
277 4e14008f blueswir1
#endif
278 44e7757c blueswir1
279 44e7757c blueswir1
/* Integer to float conversion.  */
280 714547bb blueswir1
float32 helper_fitos(int32_t src)
281 a0c4cb4a bellard
{
282 714547bb blueswir1
    return int32_to_float32(src, &env->fp_status);
283 a0c4cb4a bellard
}
284 a0c4cb4a bellard
285 d84763bc blueswir1
void helper_fitod(int32_t src)
286 a0c4cb4a bellard
{
287 d84763bc blueswir1
    DT0 = int32_to_float64(src, &env->fp_status);
288 a0c4cb4a bellard
}
289 9c2b428e blueswir1
290 c5d04e99 blueswir1
void helper_fitoq(int32_t src)
291 4e14008f blueswir1
{
292 c5d04e99 blueswir1
    QT0 = int32_to_float128(src, &env->fp_status);
293 4e14008f blueswir1
}
294 4e14008f blueswir1
295 1e64e78d blueswir1
#ifdef TARGET_SPARC64
296 d84763bc blueswir1
float32 helper_fxtos(void)
297 1e64e78d blueswir1
{
298 d84763bc blueswir1
    return int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
299 1e64e78d blueswir1
}
300 1e64e78d blueswir1
301 44e7757c blueswir1
F_HELPER(xto, d)
302 1e64e78d blueswir1
{
303 1e64e78d blueswir1
    DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
304 1e64e78d blueswir1
}
305 64a88d5d blueswir1
306 4e14008f blueswir1
F_HELPER(xto, q)
307 4e14008f blueswir1
{
308 4e14008f blueswir1
    QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
309 4e14008f blueswir1
}
310 4e14008f blueswir1
#endif
311 44e7757c blueswir1
#undef F_HELPER
312 44e7757c blueswir1
313 44e7757c blueswir1
/* floating point conversion */
314 d84763bc blueswir1
float32 helper_fdtos(void)
315 44e7757c blueswir1
{
316 d84763bc blueswir1
    return float64_to_float32(DT1, &env->fp_status);
317 44e7757c blueswir1
}
318 44e7757c blueswir1
319 d84763bc blueswir1
void helper_fstod(float32 src)
320 44e7757c blueswir1
{
321 d84763bc blueswir1
    DT0 = float32_to_float64(src, &env->fp_status);
322 44e7757c blueswir1
}
323 9c2b428e blueswir1
324 c5d04e99 blueswir1
float32 helper_fqtos(void)
325 4e14008f blueswir1
{
326 c5d04e99 blueswir1
    return float128_to_float32(QT1, &env->fp_status);
327 4e14008f blueswir1
}
328 4e14008f blueswir1
329 c5d04e99 blueswir1
void helper_fstoq(float32 src)
330 4e14008f blueswir1
{
331 c5d04e99 blueswir1
    QT0 = float32_to_float128(src, &env->fp_status);
332 4e14008f blueswir1
}
333 4e14008f blueswir1
334 4e14008f blueswir1
void helper_fqtod(void)
335 4e14008f blueswir1
{
336 4e14008f blueswir1
    DT0 = float128_to_float64(QT1, &env->fp_status);
337 4e14008f blueswir1
}
338 4e14008f blueswir1
339 4e14008f blueswir1
void helper_fdtoq(void)
340 4e14008f blueswir1
{
341 4e14008f blueswir1
    QT0 = float64_to_float128(DT1, &env->fp_status);
342 4e14008f blueswir1
}
343 4e14008f blueswir1
344 44e7757c blueswir1
/* Float to integer conversion.  */
345 714547bb blueswir1
int32_t helper_fstoi(float32 src)
346 44e7757c blueswir1
{
347 714547bb blueswir1
    return float32_to_int32_round_to_zero(src, &env->fp_status);
348 44e7757c blueswir1
}
349 44e7757c blueswir1
350 d84763bc blueswir1
int32_t helper_fdtoi(void)
351 44e7757c blueswir1
{
352 d84763bc blueswir1
    return float64_to_int32_round_to_zero(DT1, &env->fp_status);
353 44e7757c blueswir1
}
354 44e7757c blueswir1
355 c5d04e99 blueswir1
int32_t helper_fqtoi(void)
356 4e14008f blueswir1
{
357 c5d04e99 blueswir1
    return float128_to_int32_round_to_zero(QT1, &env->fp_status);
358 4e14008f blueswir1
}
359 4e14008f blueswir1
360 44e7757c blueswir1
#ifdef TARGET_SPARC64
361 d84763bc blueswir1
void helper_fstox(float32 src)
362 44e7757c blueswir1
{
363 d84763bc blueswir1
    *((int64_t *)&DT0) = float32_to_int64_round_to_zero(src, &env->fp_status);
364 44e7757c blueswir1
}
365 44e7757c blueswir1
366 44e7757c blueswir1
void helper_fdtox(void)
367 44e7757c blueswir1
{
368 44e7757c blueswir1
    *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
369 44e7757c blueswir1
}
370 44e7757c blueswir1
371 4e14008f blueswir1
void helper_fqtox(void)
372 4e14008f blueswir1
{
373 4e14008f blueswir1
    *((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status);
374 4e14008f blueswir1
}
375 4e14008f blueswir1
376 44e7757c blueswir1
void helper_faligndata(void)
377 44e7757c blueswir1
{
378 44e7757c blueswir1
    uint64_t tmp;
379 44e7757c blueswir1
380 44e7757c blueswir1
    tmp = (*((uint64_t *)&DT0)) << ((env->gsr & 7) * 8);
381 06057e6f blueswir1
    /* on many architectures a shift of 64 does nothing */
382 06057e6f blueswir1
    if ((env->gsr & 7) != 0) {
383 06057e6f blueswir1
        tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
384 06057e6f blueswir1
    }
385 44e7757c blueswir1
    *((uint64_t *)&DT0) = tmp;
386 44e7757c blueswir1
}
387 44e7757c blueswir1
388 e2542fe2 Juan Quintela
#ifdef HOST_WORDS_BIGENDIAN
389 44e7757c blueswir1
#define VIS_B64(n) b[7 - (n)]
390 44e7757c blueswir1
#define VIS_W64(n) w[3 - (n)]
391 44e7757c blueswir1
#define VIS_SW64(n) sw[3 - (n)]
392 44e7757c blueswir1
#define VIS_L64(n) l[1 - (n)]
393 44e7757c blueswir1
#define VIS_B32(n) b[3 - (n)]
394 44e7757c blueswir1
#define VIS_W32(n) w[1 - (n)]
395 44e7757c blueswir1
#else
396 44e7757c blueswir1
#define VIS_B64(n) b[n]
397 44e7757c blueswir1
#define VIS_W64(n) w[n]
398 44e7757c blueswir1
#define VIS_SW64(n) sw[n]
399 44e7757c blueswir1
#define VIS_L64(n) l[n]
400 44e7757c blueswir1
#define VIS_B32(n) b[n]
401 44e7757c blueswir1
#define VIS_W32(n) w[n]
402 44e7757c blueswir1
#endif
403 44e7757c blueswir1
404 44e7757c blueswir1
typedef union {
405 44e7757c blueswir1
    uint8_t b[8];
406 44e7757c blueswir1
    uint16_t w[4];
407 44e7757c blueswir1
    int16_t sw[4];
408 44e7757c blueswir1
    uint32_t l[2];
409 44e7757c blueswir1
    float64 d;
410 44e7757c blueswir1
} vis64;
411 44e7757c blueswir1
412 44e7757c blueswir1
typedef union {
413 44e7757c blueswir1
    uint8_t b[4];
414 44e7757c blueswir1
    uint16_t w[2];
415 44e7757c blueswir1
    uint32_t l;
416 44e7757c blueswir1
    float32 f;
417 44e7757c blueswir1
} vis32;
418 44e7757c blueswir1
419 44e7757c blueswir1
void helper_fpmerge(void)
420 44e7757c blueswir1
{
421 44e7757c blueswir1
    vis64 s, d;
422 44e7757c blueswir1
423 44e7757c blueswir1
    s.d = DT0;
424 44e7757c blueswir1
    d.d = DT1;
425 44e7757c blueswir1
426 44e7757c blueswir1
    // Reverse calculation order to handle overlap
427 44e7757c blueswir1
    d.VIS_B64(7) = s.VIS_B64(3);
428 44e7757c blueswir1
    d.VIS_B64(6) = d.VIS_B64(3);
429 44e7757c blueswir1
    d.VIS_B64(5) = s.VIS_B64(2);
430 44e7757c blueswir1
    d.VIS_B64(4) = d.VIS_B64(2);
431 44e7757c blueswir1
    d.VIS_B64(3) = s.VIS_B64(1);
432 44e7757c blueswir1
    d.VIS_B64(2) = d.VIS_B64(1);
433 44e7757c blueswir1
    d.VIS_B64(1) = s.VIS_B64(0);
434 44e7757c blueswir1
    //d.VIS_B64(0) = d.VIS_B64(0);
435 44e7757c blueswir1
436 44e7757c blueswir1
    DT0 = d.d;
437 44e7757c blueswir1
}
438 44e7757c blueswir1
439 44e7757c blueswir1
void helper_fmul8x16(void)
440 44e7757c blueswir1
{
441 44e7757c blueswir1
    vis64 s, d;
442 44e7757c blueswir1
    uint32_t tmp;
443 44e7757c blueswir1
444 44e7757c blueswir1
    s.d = DT0;
445 44e7757c blueswir1
    d.d = DT1;
446 44e7757c blueswir1
447 44e7757c blueswir1
#define PMUL(r)                                                 \
448 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r);       \
449 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                    \
450 44e7757c blueswir1
        tmp += 0x100;                                           \
451 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
452 44e7757c blueswir1
453 44e7757c blueswir1
    PMUL(0);
454 44e7757c blueswir1
    PMUL(1);
455 44e7757c blueswir1
    PMUL(2);
456 44e7757c blueswir1
    PMUL(3);
457 44e7757c blueswir1
#undef PMUL
458 44e7757c blueswir1
459 44e7757c blueswir1
    DT0 = d.d;
460 44e7757c blueswir1
}
461 44e7757c blueswir1
462 44e7757c blueswir1
void helper_fmul8x16al(void)
463 44e7757c blueswir1
{
464 44e7757c blueswir1
    vis64 s, d;
465 44e7757c blueswir1
    uint32_t tmp;
466 44e7757c blueswir1
467 44e7757c blueswir1
    s.d = DT0;
468 44e7757c blueswir1
    d.d = DT1;
469 44e7757c blueswir1
470 44e7757c blueswir1
#define PMUL(r)                                                 \
471 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r);       \
472 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                    \
473 44e7757c blueswir1
        tmp += 0x100;                                           \
474 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
475 44e7757c blueswir1
476 44e7757c blueswir1
    PMUL(0);
477 44e7757c blueswir1
    PMUL(1);
478 44e7757c blueswir1
    PMUL(2);
479 44e7757c blueswir1
    PMUL(3);
480 44e7757c blueswir1
#undef PMUL
481 44e7757c blueswir1
482 44e7757c blueswir1
    DT0 = d.d;
483 44e7757c blueswir1
}
484 44e7757c blueswir1
485 44e7757c blueswir1
void helper_fmul8x16au(void)
486 44e7757c blueswir1
{
487 44e7757c blueswir1
    vis64 s, d;
488 44e7757c blueswir1
    uint32_t tmp;
489 44e7757c blueswir1
490 44e7757c blueswir1
    s.d = DT0;
491 44e7757c blueswir1
    d.d = DT1;
492 44e7757c blueswir1
493 44e7757c blueswir1
#define PMUL(r)                                                 \
494 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r);       \
495 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                    \
496 44e7757c blueswir1
        tmp += 0x100;                                           \
497 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
498 44e7757c blueswir1
499 44e7757c blueswir1
    PMUL(0);
500 44e7757c blueswir1
    PMUL(1);
501 44e7757c blueswir1
    PMUL(2);
502 44e7757c blueswir1
    PMUL(3);
503 44e7757c blueswir1
#undef PMUL
504 44e7757c blueswir1
505 44e7757c blueswir1
    DT0 = d.d;
506 44e7757c blueswir1
}
507 44e7757c blueswir1
508 44e7757c blueswir1
void helper_fmul8sux16(void)
509 44e7757c blueswir1
{
510 44e7757c blueswir1
    vis64 s, d;
511 44e7757c blueswir1
    uint32_t tmp;
512 44e7757c blueswir1
513 44e7757c blueswir1
    s.d = DT0;
514 44e7757c blueswir1
    d.d = DT1;
515 44e7757c blueswir1
516 44e7757c blueswir1
#define PMUL(r)                                                         \
517 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
518 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                            \
519 44e7757c blueswir1
        tmp += 0x100;                                                   \
520 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
521 44e7757c blueswir1
522 44e7757c blueswir1
    PMUL(0);
523 44e7757c blueswir1
    PMUL(1);
524 44e7757c blueswir1
    PMUL(2);
525 44e7757c blueswir1
    PMUL(3);
526 44e7757c blueswir1
#undef PMUL
527 44e7757c blueswir1
528 44e7757c blueswir1
    DT0 = d.d;
529 44e7757c blueswir1
}
530 44e7757c blueswir1
531 44e7757c blueswir1
void helper_fmul8ulx16(void)
532 44e7757c blueswir1
{
533 44e7757c blueswir1
    vis64 s, d;
534 44e7757c blueswir1
    uint32_t tmp;
535 44e7757c blueswir1
536 44e7757c blueswir1
    s.d = DT0;
537 44e7757c blueswir1
    d.d = DT1;
538 44e7757c blueswir1
539 44e7757c blueswir1
#define PMUL(r)                                                         \
540 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
541 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                            \
542 44e7757c blueswir1
        tmp += 0x100;                                                   \
543 44e7757c blueswir1
    d.VIS_W64(r) = tmp >> 8;
544 44e7757c blueswir1
545 44e7757c blueswir1
    PMUL(0);
546 44e7757c blueswir1
    PMUL(1);
547 44e7757c blueswir1
    PMUL(2);
548 44e7757c blueswir1
    PMUL(3);
549 44e7757c blueswir1
#undef PMUL
550 44e7757c blueswir1
551 44e7757c blueswir1
    DT0 = d.d;
552 44e7757c blueswir1
}
553 44e7757c blueswir1
554 44e7757c blueswir1
void helper_fmuld8sux16(void)
555 44e7757c blueswir1
{
556 44e7757c blueswir1
    vis64 s, d;
557 44e7757c blueswir1
    uint32_t tmp;
558 44e7757c blueswir1
559 44e7757c blueswir1
    s.d = DT0;
560 44e7757c blueswir1
    d.d = DT1;
561 44e7757c blueswir1
562 44e7757c blueswir1
#define PMUL(r)                                                         \
563 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8);       \
564 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                            \
565 44e7757c blueswir1
        tmp += 0x100;                                                   \
566 44e7757c blueswir1
    d.VIS_L64(r) = tmp;
567 44e7757c blueswir1
568 44e7757c blueswir1
    // Reverse calculation order to handle overlap
569 44e7757c blueswir1
    PMUL(1);
570 44e7757c blueswir1
    PMUL(0);
571 44e7757c blueswir1
#undef PMUL
572 44e7757c blueswir1
573 44e7757c blueswir1
    DT0 = d.d;
574 44e7757c blueswir1
}
575 44e7757c blueswir1
576 44e7757c blueswir1
void helper_fmuld8ulx16(void)
577 44e7757c blueswir1
{
578 44e7757c blueswir1
    vis64 s, d;
579 44e7757c blueswir1
    uint32_t tmp;
580 44e7757c blueswir1
581 44e7757c blueswir1
    s.d = DT0;
582 44e7757c blueswir1
    d.d = DT1;
583 44e7757c blueswir1
584 44e7757c blueswir1
#define PMUL(r)                                                         \
585 44e7757c blueswir1
    tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2));        \
586 44e7757c blueswir1
    if ((tmp & 0xff) > 0x7f)                                            \
587 44e7757c blueswir1
        tmp += 0x100;                                                   \
588 44e7757c blueswir1
    d.VIS_L64(r) = tmp;
589 44e7757c blueswir1
590 44e7757c blueswir1
    // Reverse calculation order to handle overlap
591 44e7757c blueswir1
    PMUL(1);
592 44e7757c blueswir1
    PMUL(0);
593 44e7757c blueswir1
#undef PMUL
594 44e7757c blueswir1
595 44e7757c blueswir1
    DT0 = d.d;
596 44e7757c blueswir1
}
597 44e7757c blueswir1
598 44e7757c blueswir1
void helper_fexpand(void)
599 44e7757c blueswir1
{
600 44e7757c blueswir1
    vis32 s;
601 44e7757c blueswir1
    vis64 d;
602 44e7757c blueswir1
603 44e7757c blueswir1
    s.l = (uint32_t)(*(uint64_t *)&DT0 & 0xffffffff);
604 44e7757c blueswir1
    d.d = DT1;
605 c55bda30 blueswir1
    d.VIS_W64(0) = s.VIS_B32(0) << 4;
606 c55bda30 blueswir1
    d.VIS_W64(1) = s.VIS_B32(1) << 4;
607 c55bda30 blueswir1
    d.VIS_W64(2) = s.VIS_B32(2) << 4;
608 c55bda30 blueswir1
    d.VIS_W64(3) = s.VIS_B32(3) << 4;
609 44e7757c blueswir1
610 44e7757c blueswir1
    DT0 = d.d;
611 44e7757c blueswir1
}
612 44e7757c blueswir1
613 44e7757c blueswir1
#define VIS_HELPER(name, F)                             \
614 44e7757c blueswir1
    void name##16(void)                                 \
615 44e7757c blueswir1
    {                                                   \
616 44e7757c blueswir1
        vis64 s, d;                                     \
617 44e7757c blueswir1
                                                        \
618 44e7757c blueswir1
        s.d = DT0;                                      \
619 44e7757c blueswir1
        d.d = DT1;                                      \
620 44e7757c blueswir1
                                                        \
621 44e7757c blueswir1
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0));   \
622 44e7757c blueswir1
        d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1));   \
623 44e7757c blueswir1
        d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2));   \
624 44e7757c blueswir1
        d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3));   \
625 44e7757c blueswir1
                                                        \
626 44e7757c blueswir1
        DT0 = d.d;                                      \
627 44e7757c blueswir1
    }                                                   \
628 44e7757c blueswir1
                                                        \
629 1d01299d blueswir1
    uint32_t name##16s(uint32_t src1, uint32_t src2)    \
630 44e7757c blueswir1
    {                                                   \
631 44e7757c blueswir1
        vis32 s, d;                                     \
632 44e7757c blueswir1
                                                        \
633 1d01299d blueswir1
        s.l = src1;                                     \
634 1d01299d blueswir1
        d.l = src2;                                     \
635 44e7757c blueswir1
                                                        \
636 44e7757c blueswir1
        d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0));   \
637 44e7757c blueswir1
        d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1));   \
638 44e7757c blueswir1
                                                        \
639 1d01299d blueswir1
        return d.l;                                     \
640 44e7757c blueswir1
    }                                                   \
641 44e7757c blueswir1
                                                        \
642 44e7757c blueswir1
    void name##32(void)                                 \
643 44e7757c blueswir1
    {                                                   \
644 44e7757c blueswir1
        vis64 s, d;                                     \
645 44e7757c blueswir1
                                                        \
646 44e7757c blueswir1
        s.d = DT0;                                      \
647 44e7757c blueswir1
        d.d = DT1;                                      \
648 44e7757c blueswir1
                                                        \
649 44e7757c blueswir1
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0));   \
650 44e7757c blueswir1
        d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1));   \
651 44e7757c blueswir1
                                                        \
652 44e7757c blueswir1
        DT0 = d.d;                                      \
653 44e7757c blueswir1
    }                                                   \
654 44e7757c blueswir1
                                                        \
655 1d01299d blueswir1
    uint32_t name##32s(uint32_t src1, uint32_t src2)    \
656 44e7757c blueswir1
    {                                                   \
657 44e7757c blueswir1
        vis32 s, d;                                     \
658 44e7757c blueswir1
                                                        \
659 1d01299d blueswir1
        s.l = src1;                                     \
660 1d01299d blueswir1
        d.l = src2;                                     \
661 44e7757c blueswir1
                                                        \
662 44e7757c blueswir1
        d.l = F(d.l, s.l);                              \
663 44e7757c blueswir1
                                                        \
664 1d01299d blueswir1
        return d.l;                                     \
665 44e7757c blueswir1
    }
666 44e7757c blueswir1
667 44e7757c blueswir1
#define FADD(a, b) ((a) + (b))
668 44e7757c blueswir1
#define FSUB(a, b) ((a) - (b))
669 44e7757c blueswir1
VIS_HELPER(helper_fpadd, FADD)
670 44e7757c blueswir1
VIS_HELPER(helper_fpsub, FSUB)
671 44e7757c blueswir1
672 44e7757c blueswir1
#define VIS_CMPHELPER(name, F)                                        \
673 44e7757c blueswir1
    void name##16(void)                                           \
674 44e7757c blueswir1
    {                                                             \
675 44e7757c blueswir1
        vis64 s, d;                                               \
676 44e7757c blueswir1
                                                                  \
677 44e7757c blueswir1
        s.d = DT0;                                                \
678 44e7757c blueswir1
        d.d = DT1;                                                \
679 44e7757c blueswir1
                                                                  \
680 44e7757c blueswir1
        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0;       \
681 44e7757c blueswir1
        d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0;      \
682 44e7757c blueswir1
        d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0;      \
683 44e7757c blueswir1
        d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0;      \
684 44e7757c blueswir1
                                                                  \
685 44e7757c blueswir1
        DT0 = d.d;                                                \
686 44e7757c blueswir1
    }                                                             \
687 44e7757c blueswir1
                                                                  \
688 44e7757c blueswir1
    void name##32(void)                                           \
689 44e7757c blueswir1
    {                                                             \
690 44e7757c blueswir1
        vis64 s, d;                                               \
691 44e7757c blueswir1
                                                                  \
692 44e7757c blueswir1
        s.d = DT0;                                                \
693 44e7757c blueswir1
        d.d = DT1;                                                \
694 44e7757c blueswir1
                                                                  \
695 44e7757c blueswir1
        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0;       \
696 44e7757c blueswir1
        d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0;      \
697 44e7757c blueswir1
                                                                  \
698 44e7757c blueswir1
        DT0 = d.d;                                                \
699 44e7757c blueswir1
    }
700 44e7757c blueswir1
701 44e7757c blueswir1
#define FCMPGT(a, b) ((a) > (b))
702 44e7757c blueswir1
#define FCMPEQ(a, b) ((a) == (b))
703 44e7757c blueswir1
#define FCMPLE(a, b) ((a) <= (b))
704 44e7757c blueswir1
#define FCMPNE(a, b) ((a) != (b))
705 44e7757c blueswir1
706 44e7757c blueswir1
VIS_CMPHELPER(helper_fcmpgt, FCMPGT)
707 44e7757c blueswir1
VIS_CMPHELPER(helper_fcmpeq, FCMPEQ)
708 44e7757c blueswir1
VIS_CMPHELPER(helper_fcmple, FCMPLE)
709 44e7757c blueswir1
VIS_CMPHELPER(helper_fcmpne, FCMPNE)
710 44e7757c blueswir1
#endif
711 44e7757c blueswir1
712 44e7757c blueswir1
void helper_check_ieee_exceptions(void)
713 44e7757c blueswir1
{
714 44e7757c blueswir1
    target_ulong status;
715 44e7757c blueswir1
716 44e7757c blueswir1
    status = get_float_exception_flags(&env->fp_status);
717 44e7757c blueswir1
    if (status) {
718 44e7757c blueswir1
        /* Copy IEEE 754 flags into FSR */
719 44e7757c blueswir1
        if (status & float_flag_invalid)
720 44e7757c blueswir1
            env->fsr |= FSR_NVC;
721 44e7757c blueswir1
        if (status & float_flag_overflow)
722 44e7757c blueswir1
            env->fsr |= FSR_OFC;
723 44e7757c blueswir1
        if (status & float_flag_underflow)
724 44e7757c blueswir1
            env->fsr |= FSR_UFC;
725 44e7757c blueswir1
        if (status & float_flag_divbyzero)
726 44e7757c blueswir1
            env->fsr |= FSR_DZC;
727 44e7757c blueswir1
        if (status & float_flag_inexact)
728 44e7757c blueswir1
            env->fsr |= FSR_NXC;
729 44e7757c blueswir1
730 44e7757c blueswir1
        if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) {
731 44e7757c blueswir1
            /* Unmasked exception, generate a trap */
732 44e7757c blueswir1
            env->fsr |= FSR_FTT_IEEE_EXCP;
733 44e7757c blueswir1
            raise_exception(TT_FP_EXCP);
734 44e7757c blueswir1
        } else {
735 44e7757c blueswir1
            /* Accumulate exceptions */
736 44e7757c blueswir1
            env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
737 44e7757c blueswir1
        }
738 44e7757c blueswir1
    }
739 44e7757c blueswir1
}
740 44e7757c blueswir1
741 44e7757c blueswir1
void helper_clear_float_exceptions(void)
742 44e7757c blueswir1
{
743 44e7757c blueswir1
    set_float_exception_flags(0, &env->fp_status);
744 44e7757c blueswir1
}
745 44e7757c blueswir1
746 714547bb blueswir1
float32 helper_fabss(float32 src)
747 e8af50a3 bellard
{
748 714547bb blueswir1
    return float32_abs(src);
749 e8af50a3 bellard
}
750 e8af50a3 bellard
751 3475187d bellard
#ifdef TARGET_SPARC64
752 7e8c2b6c blueswir1
void helper_fabsd(void)
753 3475187d bellard
{
754 3475187d bellard
    DT0 = float64_abs(DT1);
755 3475187d bellard
}
756 4e14008f blueswir1
757 4e14008f blueswir1
void helper_fabsq(void)
758 4e14008f blueswir1
{
759 4e14008f blueswir1
    QT0 = float128_abs(QT1);
760 4e14008f blueswir1
}
761 4e14008f blueswir1
#endif
762 3475187d bellard
763 714547bb blueswir1
float32 helper_fsqrts(float32 src)
764 e8af50a3 bellard
{
765 714547bb blueswir1
    return float32_sqrt(src, &env->fp_status);
766 e8af50a3 bellard
}
767 e8af50a3 bellard
768 7e8c2b6c blueswir1
void helper_fsqrtd(void)
769 e8af50a3 bellard
{
770 7a0e1f41 bellard
    DT0 = float64_sqrt(DT1, &env->fp_status);
771 e8af50a3 bellard
}
772 e8af50a3 bellard
773 4e14008f blueswir1
void helper_fsqrtq(void)
774 4e14008f blueswir1
{
775 4e14008f blueswir1
    QT0 = float128_sqrt(QT1, &env->fp_status);
776 4e14008f blueswir1
}
777 4e14008f blueswir1
778 417454b0 blueswir1
#define GEN_FCMP(name, size, reg1, reg2, FS, TRAP)                      \
779 7e8c2b6c blueswir1
    void glue(helper_, name) (void)                                     \
780 65ce8c2f bellard
    {                                                                   \
781 1a2fb1c0 blueswir1
        target_ulong new_fsr;                                           \
782 1a2fb1c0 blueswir1
                                                                        \
783 65ce8c2f bellard
        env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                     \
784 65ce8c2f bellard
        switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) {   \
785 65ce8c2f bellard
        case float_relation_unordered:                                  \
786 1a2fb1c0 blueswir1
            new_fsr = (FSR_FCC1 | FSR_FCC0) << FS;                      \
787 417454b0 blueswir1
            if ((env->fsr & FSR_NVM) || TRAP) {                         \
788 1a2fb1c0 blueswir1
                env->fsr |= new_fsr;                                    \
789 417454b0 blueswir1
                env->fsr |= FSR_NVC;                                    \
790 417454b0 blueswir1
                env->fsr |= FSR_FTT_IEEE_EXCP;                          \
791 65ce8c2f bellard
                raise_exception(TT_FP_EXCP);                            \
792 65ce8c2f bellard
            } else {                                                    \
793 65ce8c2f bellard
                env->fsr |= FSR_NVA;                                    \
794 65ce8c2f bellard
            }                                                           \
795 65ce8c2f bellard
            break;                                                      \
796 65ce8c2f bellard
        case float_relation_less:                                       \
797 1a2fb1c0 blueswir1
            new_fsr = FSR_FCC0 << FS;                                   \
798 65ce8c2f bellard
            break;                                                      \
799 65ce8c2f bellard
        case float_relation_greater:                                    \
800 1a2fb1c0 blueswir1
            new_fsr = FSR_FCC1 << FS;                                   \
801 65ce8c2f bellard
            break;                                                      \
802 65ce8c2f bellard
        default:                                                        \
803 1a2fb1c0 blueswir1
            new_fsr = 0;                                                \
804 65ce8c2f bellard
            break;                                                      \
805 65ce8c2f bellard
        }                                                               \
806 1a2fb1c0 blueswir1
        env->fsr |= new_fsr;                                            \
807 e8af50a3 bellard
    }
808 714547bb blueswir1
#define GEN_FCMPS(name, size, FS, TRAP)                                 \
809 714547bb blueswir1
    void glue(helper_, name)(float32 src1, float32 src2)                \
810 714547bb blueswir1
    {                                                                   \
811 714547bb blueswir1
        target_ulong new_fsr;                                           \
812 714547bb blueswir1
                                                                        \
813 714547bb blueswir1
        env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                     \
814 714547bb blueswir1
        switch (glue(size, _compare) (src1, src2, &env->fp_status)) {   \
815 714547bb blueswir1
        case float_relation_unordered:                                  \
816 714547bb blueswir1
            new_fsr = (FSR_FCC1 | FSR_FCC0) << FS;                      \
817 714547bb blueswir1
            if ((env->fsr & FSR_NVM) || TRAP) {                         \
818 714547bb blueswir1
                env->fsr |= new_fsr;                                    \
819 714547bb blueswir1
                env->fsr |= FSR_NVC;                                    \
820 714547bb blueswir1
                env->fsr |= FSR_FTT_IEEE_EXCP;                          \
821 714547bb blueswir1
                raise_exception(TT_FP_EXCP);                            \
822 714547bb blueswir1
            } else {                                                    \
823 714547bb blueswir1
                env->fsr |= FSR_NVA;                                    \
824 714547bb blueswir1
            }                                                           \
825 714547bb blueswir1
            break;                                                      \
826 714547bb blueswir1
        case float_relation_less:                                       \
827 714547bb blueswir1
            new_fsr = FSR_FCC0 << FS;                                   \
828 714547bb blueswir1
            break;                                                      \
829 714547bb blueswir1
        case float_relation_greater:                                    \
830 714547bb blueswir1
            new_fsr = FSR_FCC1 << FS;                                   \
831 714547bb blueswir1
            break;                                                      \
832 714547bb blueswir1
        default:                                                        \
833 714547bb blueswir1
            new_fsr = 0;                                                \
834 714547bb blueswir1
            break;                                                      \
835 714547bb blueswir1
        }                                                               \
836 714547bb blueswir1
        env->fsr |= new_fsr;                                            \
837 714547bb blueswir1
    }
838 e8af50a3 bellard
839 714547bb blueswir1
GEN_FCMPS(fcmps, float32, 0, 0);
840 417454b0 blueswir1
GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0);
841 417454b0 blueswir1
842 714547bb blueswir1
GEN_FCMPS(fcmpes, float32, 0, 1);
843 417454b0 blueswir1
GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1);
844 3475187d bellard
845 4e14008f blueswir1
GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0);
846 4e14008f blueswir1
GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1);
847 4e14008f blueswir1
848 8393617c Blue Swirl
static uint32_t compute_all_flags(void)
849 8393617c Blue Swirl
{
850 8393617c Blue Swirl
    return env->psr & PSR_ICC;
851 8393617c Blue Swirl
}
852 8393617c Blue Swirl
853 8393617c Blue Swirl
static uint32_t compute_C_flags(void)
854 8393617c Blue Swirl
{
855 8393617c Blue Swirl
    return env->psr & PSR_CARRY;
856 8393617c Blue Swirl
}
857 8393617c Blue Swirl
858 bdf9f35d Blue Swirl
static inline uint32_t get_NZ_icc(target_ulong dst)
859 bdf9f35d Blue Swirl
{
860 bdf9f35d Blue Swirl
    uint32_t ret = 0;
861 bdf9f35d Blue Swirl
862 bdf9f35d Blue Swirl
    if (!(dst & 0xffffffffULL))
863 bdf9f35d Blue Swirl
        ret |= PSR_ZERO;
864 bdf9f35d Blue Swirl
    if ((int32_t) (dst & 0xffffffffULL) < 0)
865 bdf9f35d Blue Swirl
        ret |= PSR_NEG;
866 bdf9f35d Blue Swirl
    return ret;
867 bdf9f35d Blue Swirl
}
868 bdf9f35d Blue Swirl
869 8393617c Blue Swirl
#ifdef TARGET_SPARC64
870 8393617c Blue Swirl
static uint32_t compute_all_flags_xcc(void)
871 8393617c Blue Swirl
{
872 8393617c Blue Swirl
    return env->xcc & PSR_ICC;
873 8393617c Blue Swirl
}
874 8393617c Blue Swirl
875 8393617c Blue Swirl
static uint32_t compute_C_flags_xcc(void)
876 8393617c Blue Swirl
{
877 8393617c Blue Swirl
    return env->xcc & PSR_CARRY;
878 8393617c Blue Swirl
}
879 8393617c Blue Swirl
880 bdf9f35d Blue Swirl
static inline uint32_t get_NZ_xcc(target_ulong dst)
881 bdf9f35d Blue Swirl
{
882 bdf9f35d Blue Swirl
    uint32_t ret = 0;
883 bdf9f35d Blue Swirl
884 bdf9f35d Blue Swirl
    if (!dst)
885 bdf9f35d Blue Swirl
        ret |= PSR_ZERO;
886 bdf9f35d Blue Swirl
    if ((int64_t)dst < 0)
887 bdf9f35d Blue Swirl
        ret |= PSR_NEG;
888 bdf9f35d Blue Swirl
    return ret;
889 bdf9f35d Blue Swirl
}
890 bdf9f35d Blue Swirl
#endif
891 bdf9f35d Blue Swirl
892 6c78ea32 Blue Swirl
static inline uint32_t get_V_div_icc(target_ulong src2)
893 6c78ea32 Blue Swirl
{
894 6c78ea32 Blue Swirl
    uint32_t ret = 0;
895 6c78ea32 Blue Swirl
896 6c78ea32 Blue Swirl
    if (src2 != 0)
897 6c78ea32 Blue Swirl
        ret |= PSR_OVF;
898 6c78ea32 Blue Swirl
    return ret;
899 6c78ea32 Blue Swirl
}
900 6c78ea32 Blue Swirl
901 6c78ea32 Blue Swirl
static uint32_t compute_all_div(void)
902 6c78ea32 Blue Swirl
{
903 6c78ea32 Blue Swirl
    uint32_t ret;
904 6c78ea32 Blue Swirl
905 6c78ea32 Blue Swirl
    ret = get_NZ_icc(CC_DST);
906 6c78ea32 Blue Swirl
    ret |= get_V_div_icc(CC_SRC2);
907 6c78ea32 Blue Swirl
    return ret;
908 6c78ea32 Blue Swirl
}
909 6c78ea32 Blue Swirl
910 6c78ea32 Blue Swirl
static uint32_t compute_C_div(void)
911 6c78ea32 Blue Swirl
{
912 6c78ea32 Blue Swirl
    return 0;
913 6c78ea32 Blue Swirl
}
914 6c78ea32 Blue Swirl
915 3e6ba503 Artyom Tarasenko
/* carry = (src1[31] & src2[31]) | ( ~dst[31] & (src1[31] | src2[31])) */
916 3e6ba503 Artyom Tarasenko
static inline uint32_t get_C_add_icc(target_ulong dst, target_ulong src1,
917 3e6ba503 Artyom Tarasenko
                                     target_ulong src2)
918 bdf9f35d Blue Swirl
{
919 bdf9f35d Blue Swirl
    uint32_t ret = 0;
920 bdf9f35d Blue Swirl
921 3e6ba503 Artyom Tarasenko
    if (((src1 & (1ULL << 31)) & (src2 & (1ULL << 31)))
922 3e6ba503 Artyom Tarasenko
        | ((~(dst & (1ULL << 31)))
923 3e6ba503 Artyom Tarasenko
           & ((src1 & (1ULL << 31)) | (src2 & (1ULL << 31)))))
924 bdf9f35d Blue Swirl
        ret |= PSR_CARRY;
925 bdf9f35d Blue Swirl
    return ret;
926 bdf9f35d Blue Swirl
}
927 bdf9f35d Blue Swirl
928 bdf9f35d Blue Swirl
static inline uint32_t get_V_add_icc(target_ulong dst, target_ulong src1,
929 bdf9f35d Blue Swirl
                                         target_ulong src2)
930 bdf9f35d Blue Swirl
{
931 bdf9f35d Blue Swirl
    uint32_t ret = 0;
932 bdf9f35d Blue Swirl
933 bdf9f35d Blue Swirl
    if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1ULL << 31))
934 bdf9f35d Blue Swirl
        ret |= PSR_OVF;
935 bdf9f35d Blue Swirl
    return ret;
936 bdf9f35d Blue Swirl
}
937 bdf9f35d Blue Swirl
938 bdf9f35d Blue Swirl
#ifdef TARGET_SPARC64
939 bdf9f35d Blue Swirl
static inline uint32_t get_C_add_xcc(target_ulong dst, target_ulong src1)
940 bdf9f35d Blue Swirl
{
941 bdf9f35d Blue Swirl
    uint32_t ret = 0;
942 bdf9f35d Blue Swirl
943 bdf9f35d Blue Swirl
    if (dst < src1)
944 bdf9f35d Blue Swirl
        ret |= PSR_CARRY;
945 bdf9f35d Blue Swirl
    return ret;
946 bdf9f35d Blue Swirl
}
947 bdf9f35d Blue Swirl
948 bdf9f35d Blue Swirl
static inline uint32_t get_V_add_xcc(target_ulong dst, target_ulong src1,
949 bdf9f35d Blue Swirl
                                         target_ulong src2)
950 bdf9f35d Blue Swirl
{
951 bdf9f35d Blue Swirl
    uint32_t ret = 0;
952 bdf9f35d Blue Swirl
953 bdf9f35d Blue Swirl
    if (((src1 ^ src2 ^ -1) & (src1 ^ dst)) & (1ULL << 63))
954 bdf9f35d Blue Swirl
        ret |= PSR_OVF;
955 bdf9f35d Blue Swirl
    return ret;
956 bdf9f35d Blue Swirl
}
957 bdf9f35d Blue Swirl
958 bdf9f35d Blue Swirl
static uint32_t compute_all_add_xcc(void)
959 bdf9f35d Blue Swirl
{
960 bdf9f35d Blue Swirl
    uint32_t ret;
961 bdf9f35d Blue Swirl
962 bdf9f35d Blue Swirl
    ret = get_NZ_xcc(CC_DST);
963 bdf9f35d Blue Swirl
    ret |= get_C_add_xcc(CC_DST, CC_SRC);
964 bdf9f35d Blue Swirl
    ret |= get_V_add_xcc(CC_DST, CC_SRC, CC_SRC2);
965 bdf9f35d Blue Swirl
    return ret;
966 bdf9f35d Blue Swirl
}
967 bdf9f35d Blue Swirl
968 bdf9f35d Blue Swirl
static uint32_t compute_C_add_xcc(void)
969 bdf9f35d Blue Swirl
{
970 bdf9f35d Blue Swirl
    return get_C_add_xcc(CC_DST, CC_SRC);
971 bdf9f35d Blue Swirl
}
972 8393617c Blue Swirl
#endif
973 8393617c Blue Swirl
974 3e6ba503 Artyom Tarasenko
static uint32_t compute_all_add(void)
975 789c91ef Blue Swirl
{
976 789c91ef Blue Swirl
    uint32_t ret;
977 789c91ef Blue Swirl
978 789c91ef Blue Swirl
    ret = get_NZ_icc(CC_DST);
979 3e6ba503 Artyom Tarasenko
    ret |= get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
980 789c91ef Blue Swirl
    ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2);
981 789c91ef Blue Swirl
    return ret;
982 789c91ef Blue Swirl
}
983 789c91ef Blue Swirl
984 3e6ba503 Artyom Tarasenko
static uint32_t compute_C_add(void)
985 789c91ef Blue Swirl
{
986 3e6ba503 Artyom Tarasenko
    return get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
987 789c91ef Blue Swirl
}
988 789c91ef Blue Swirl
989 789c91ef Blue Swirl
#ifdef TARGET_SPARC64
990 789c91ef Blue Swirl
static uint32_t compute_all_addx_xcc(void)
991 789c91ef Blue Swirl
{
992 789c91ef Blue Swirl
    uint32_t ret;
993 789c91ef Blue Swirl
994 789c91ef Blue Swirl
    ret = get_NZ_xcc(CC_DST);
995 789c91ef Blue Swirl
    ret |= get_C_add_xcc(CC_DST - CC_SRC2, CC_SRC);
996 789c91ef Blue Swirl
    ret |= get_C_add_xcc(CC_DST, CC_SRC);
997 789c91ef Blue Swirl
    ret |= get_V_add_xcc(CC_DST, CC_SRC, CC_SRC2);
998 789c91ef Blue Swirl
    return ret;
999 789c91ef Blue Swirl
}
1000 789c91ef Blue Swirl
1001 789c91ef Blue Swirl
static uint32_t compute_C_addx_xcc(void)
1002 789c91ef Blue Swirl
{
1003 789c91ef Blue Swirl
    uint32_t ret;
1004 789c91ef Blue Swirl
1005 789c91ef Blue Swirl
    ret = get_C_add_xcc(CC_DST - CC_SRC2, CC_SRC);
1006 789c91ef Blue Swirl
    ret |= get_C_add_xcc(CC_DST, CC_SRC);
1007 789c91ef Blue Swirl
    return ret;
1008 789c91ef Blue Swirl
}
1009 789c91ef Blue Swirl
#endif
1010 789c91ef Blue Swirl
1011 3b2d1e92 Blue Swirl
static inline uint32_t get_V_tag_icc(target_ulong src1, target_ulong src2)
1012 3b2d1e92 Blue Swirl
{
1013 3b2d1e92 Blue Swirl
    uint32_t ret = 0;
1014 3b2d1e92 Blue Swirl
1015 3b2d1e92 Blue Swirl
    if ((src1 | src2) & 0x3)
1016 3b2d1e92 Blue Swirl
        ret |= PSR_OVF;
1017 3b2d1e92 Blue Swirl
    return ret;
1018 3b2d1e92 Blue Swirl
}
1019 3b2d1e92 Blue Swirl
1020 3b2d1e92 Blue Swirl
static uint32_t compute_all_tadd(void)
1021 3b2d1e92 Blue Swirl
{
1022 3b2d1e92 Blue Swirl
    uint32_t ret;
1023 3b2d1e92 Blue Swirl
1024 3b2d1e92 Blue Swirl
    ret = get_NZ_icc(CC_DST);
1025 3e6ba503 Artyom Tarasenko
    ret |= get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
1026 3b2d1e92 Blue Swirl
    ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2);
1027 3b2d1e92 Blue Swirl
    ret |= get_V_tag_icc(CC_SRC, CC_SRC2);
1028 3b2d1e92 Blue Swirl
    return ret;
1029 3b2d1e92 Blue Swirl
}
1030 3b2d1e92 Blue Swirl
1031 3b2d1e92 Blue Swirl
static uint32_t compute_C_tadd(void)
1032 3b2d1e92 Blue Swirl
{
1033 3e6ba503 Artyom Tarasenko
    return get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
1034 3b2d1e92 Blue Swirl
}
1035 3b2d1e92 Blue Swirl
1036 3b2d1e92 Blue Swirl
static uint32_t compute_all_taddtv(void)
1037 3b2d1e92 Blue Swirl
{
1038 3b2d1e92 Blue Swirl
    uint32_t ret;
1039 3b2d1e92 Blue Swirl
1040 3b2d1e92 Blue Swirl
    ret = get_NZ_icc(CC_DST);
1041 3e6ba503 Artyom Tarasenko
    ret |= get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
1042 3b2d1e92 Blue Swirl
    return ret;
1043 3b2d1e92 Blue Swirl
}
1044 3b2d1e92 Blue Swirl
1045 3b2d1e92 Blue Swirl
static uint32_t compute_C_taddtv(void)
1046 3b2d1e92 Blue Swirl
{
1047 3e6ba503 Artyom Tarasenko
    return get_C_add_icc(CC_DST, CC_SRC, CC_SRC2);
1048 3b2d1e92 Blue Swirl
}
1049 3b2d1e92 Blue Swirl
1050 3e6ba503 Artyom Tarasenko
/* carry = (~src1[31] & src2[31]) | ( dst[31]  & (~src1[31] | src2[31])) */
1051 3e6ba503 Artyom Tarasenko
static inline uint32_t get_C_sub_icc(target_ulong dst, target_ulong src1,
1052 3e6ba503 Artyom Tarasenko
                                     target_ulong src2)
1053 d4b0d468 Blue Swirl
{
1054 d4b0d468 Blue Swirl
    uint32_t ret = 0;
1055 d4b0d468 Blue Swirl
1056 3e6ba503 Artyom Tarasenko
    if (((~(src1 & (1ULL << 31))) & (src2 & (1ULL << 31)))
1057 3e6ba503 Artyom Tarasenko
        | ((dst & (1ULL << 31)) & (( ~(src1 & (1ULL << 31)))
1058 3e6ba503 Artyom Tarasenko
                                   | (src2 & (1ULL << 31)))))
1059 d4b0d468 Blue Swirl
        ret |= PSR_CARRY;
1060 d4b0d468 Blue Swirl
    return ret;
1061 d4b0d468 Blue Swirl
}
1062 d4b0d468 Blue Swirl
1063 d4b0d468 Blue Swirl
static inline uint32_t get_V_sub_icc(target_ulong dst, target_ulong src1,
1064 d4b0d468 Blue Swirl
                                     target_ulong src2)
1065 d4b0d468 Blue Swirl
{
1066 d4b0d468 Blue Swirl
    uint32_t ret = 0;
1067 d4b0d468 Blue Swirl
1068 d4b0d468 Blue Swirl
    if (((src1 ^ src2) & (src1 ^ dst)) & (1ULL << 31))
1069 d4b0d468 Blue Swirl
        ret |= PSR_OVF;
1070 d4b0d468 Blue Swirl
    return ret;
1071 d4b0d468 Blue Swirl
}
1072 d4b0d468 Blue Swirl
1073 d4b0d468 Blue Swirl
1074 d4b0d468 Blue Swirl
#ifdef TARGET_SPARC64
1075 d4b0d468 Blue Swirl
static inline uint32_t get_C_sub_xcc(target_ulong src1, target_ulong src2)
1076 d4b0d468 Blue Swirl
{
1077 d4b0d468 Blue Swirl
    uint32_t ret = 0;
1078 d4b0d468 Blue Swirl
1079 d4b0d468 Blue Swirl
    if (src1 < src2)
1080 d4b0d468 Blue Swirl
        ret |= PSR_CARRY;
1081 d4b0d468 Blue Swirl
    return ret;
1082 d4b0d468 Blue Swirl
}
1083 d4b0d468 Blue Swirl
1084 d4b0d468 Blue Swirl
static inline uint32_t get_V_sub_xcc(target_ulong dst, target_ulong src1,
1085 d4b0d468 Blue Swirl
                                     target_ulong src2)
1086 d4b0d468 Blue Swirl
{
1087 d4b0d468 Blue Swirl
    uint32_t ret = 0;
1088 d4b0d468 Blue Swirl
1089 d4b0d468 Blue Swirl
    if (((src1 ^ src2) & (src1 ^ dst)) & (1ULL << 63))
1090 d4b0d468 Blue Swirl
        ret |= PSR_OVF;
1091 d4b0d468 Blue Swirl
    return ret;
1092 d4b0d468 Blue Swirl
}
1093 d4b0d468 Blue Swirl
1094 d4b0d468 Blue Swirl
static uint32_t compute_all_sub_xcc(void)
1095 d4b0d468 Blue Swirl
{
1096 d4b0d468 Blue Swirl
    uint32_t ret;
1097 d4b0d468 Blue Swirl
1098 d4b0d468 Blue Swirl
    ret = get_NZ_xcc(CC_DST);
1099 d4b0d468 Blue Swirl
    ret |= get_C_sub_xcc(CC_SRC, CC_SRC2);
1100 d4b0d468 Blue Swirl
    ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2);
1101 d4b0d468 Blue Swirl
    return ret;
1102 d4b0d468 Blue Swirl
}
1103 d4b0d468 Blue Swirl
1104 d4b0d468 Blue Swirl
static uint32_t compute_C_sub_xcc(void)
1105 d4b0d468 Blue Swirl
{
1106 d4b0d468 Blue Swirl
    return get_C_sub_xcc(CC_SRC, CC_SRC2);
1107 d4b0d468 Blue Swirl
}
1108 d4b0d468 Blue Swirl
#endif
1109 d4b0d468 Blue Swirl
1110 3e6ba503 Artyom Tarasenko
static uint32_t compute_all_sub(void)
1111 2ca1d92b Blue Swirl
{
1112 2ca1d92b Blue Swirl
    uint32_t ret;
1113 2ca1d92b Blue Swirl
1114 2ca1d92b Blue Swirl
    ret = get_NZ_icc(CC_DST);
1115 3e6ba503 Artyom Tarasenko
    ret |= get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
1116 2ca1d92b Blue Swirl
    ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
1117 2ca1d92b Blue Swirl
    return ret;
1118 2ca1d92b Blue Swirl
}
1119 2ca1d92b Blue Swirl
1120 3e6ba503 Artyom Tarasenko
static uint32_t compute_C_sub(void)
1121 2ca1d92b Blue Swirl
{
1122 3e6ba503 Artyom Tarasenko
    return get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
1123 2ca1d92b Blue Swirl
}
1124 2ca1d92b Blue Swirl
1125 2ca1d92b Blue Swirl
#ifdef TARGET_SPARC64
1126 2ca1d92b Blue Swirl
static uint32_t compute_all_subx_xcc(void)
1127 2ca1d92b Blue Swirl
{
1128 2ca1d92b Blue Swirl
    uint32_t ret;
1129 2ca1d92b Blue Swirl
1130 2ca1d92b Blue Swirl
    ret = get_NZ_xcc(CC_DST);
1131 2ca1d92b Blue Swirl
    ret |= get_C_sub_xcc(CC_DST - CC_SRC2, CC_SRC);
1132 2ca1d92b Blue Swirl
    ret |= get_C_sub_xcc(CC_DST, CC_SRC2);
1133 2ca1d92b Blue Swirl
    ret |= get_V_sub_xcc(CC_DST, CC_SRC, CC_SRC2);
1134 2ca1d92b Blue Swirl
    return ret;
1135 2ca1d92b Blue Swirl
}
1136 2ca1d92b Blue Swirl
1137 2ca1d92b Blue Swirl
static uint32_t compute_C_subx_xcc(void)
1138 2ca1d92b Blue Swirl
{
1139 2ca1d92b Blue Swirl
    uint32_t ret;
1140 2ca1d92b Blue Swirl
1141 2ca1d92b Blue Swirl
    ret = get_C_sub_xcc(CC_DST - CC_SRC2, CC_SRC);
1142 2ca1d92b Blue Swirl
    ret |= get_C_sub_xcc(CC_DST, CC_SRC2);
1143 2ca1d92b Blue Swirl
    return ret;
1144 2ca1d92b Blue Swirl
}
1145 2ca1d92b Blue Swirl
#endif
1146 2ca1d92b Blue Swirl
1147 3b2d1e92 Blue Swirl
static uint32_t compute_all_tsub(void)
1148 3b2d1e92 Blue Swirl
{
1149 3b2d1e92 Blue Swirl
    uint32_t ret;
1150 3b2d1e92 Blue Swirl
1151 3b2d1e92 Blue Swirl
    ret = get_NZ_icc(CC_DST);
1152 3e6ba503 Artyom Tarasenko
    ret |= get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
1153 3b2d1e92 Blue Swirl
    ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2);
1154 3b2d1e92 Blue Swirl
    ret |= get_V_tag_icc(CC_SRC, CC_SRC2);
1155 3b2d1e92 Blue Swirl
    return ret;
1156 3b2d1e92 Blue Swirl
}
1157 3b2d1e92 Blue Swirl
1158 3b2d1e92 Blue Swirl
static uint32_t compute_C_tsub(void)
1159 3b2d1e92 Blue Swirl
{
1160 3e6ba503 Artyom Tarasenko
    return get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
1161 3b2d1e92 Blue Swirl
}
1162 3b2d1e92 Blue Swirl
1163 3b2d1e92 Blue Swirl
static uint32_t compute_all_tsubtv(void)
1164 3b2d1e92 Blue Swirl
{
1165 3b2d1e92 Blue Swirl
    uint32_t ret;
1166 3b2d1e92 Blue Swirl
1167 3b2d1e92 Blue Swirl
    ret = get_NZ_icc(CC_DST);
1168 3e6ba503 Artyom Tarasenko
    ret |= get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
1169 3b2d1e92 Blue Swirl
    return ret;
1170 3b2d1e92 Blue Swirl
}
1171 3b2d1e92 Blue Swirl
1172 3b2d1e92 Blue Swirl
static uint32_t compute_C_tsubtv(void)
1173 3b2d1e92 Blue Swirl
{
1174 3e6ba503 Artyom Tarasenko
    return get_C_sub_icc(CC_DST, CC_SRC, CC_SRC2);
1175 3b2d1e92 Blue Swirl
}
1176 3b2d1e92 Blue Swirl
1177 38482a77 Blue Swirl
static uint32_t compute_all_logic(void)
1178 38482a77 Blue Swirl
{
1179 38482a77 Blue Swirl
    return get_NZ_icc(CC_DST);
1180 38482a77 Blue Swirl
}
1181 38482a77 Blue Swirl
1182 38482a77 Blue Swirl
static uint32_t compute_C_logic(void)
1183 38482a77 Blue Swirl
{
1184 38482a77 Blue Swirl
    return 0;
1185 38482a77 Blue Swirl
}
1186 38482a77 Blue Swirl
1187 38482a77 Blue Swirl
#ifdef TARGET_SPARC64
1188 38482a77 Blue Swirl
static uint32_t compute_all_logic_xcc(void)
1189 38482a77 Blue Swirl
{
1190 38482a77 Blue Swirl
    return get_NZ_xcc(CC_DST);
1191 38482a77 Blue Swirl
}
1192 38482a77 Blue Swirl
#endif
1193 38482a77 Blue Swirl
1194 8393617c Blue Swirl
typedef struct CCTable {
1195 8393617c Blue Swirl
    uint32_t (*compute_all)(void); /* return all the flags */
1196 8393617c Blue Swirl
    uint32_t (*compute_c)(void);  /* return the C flag */
1197 8393617c Blue Swirl
} CCTable;
1198 8393617c Blue Swirl
1199 8393617c Blue Swirl
static const CCTable icc_table[CC_OP_NB] = {
1200 8393617c Blue Swirl
    /* CC_OP_DYNAMIC should never happen */
1201 8393617c Blue Swirl
    [CC_OP_FLAGS] = { compute_all_flags, compute_C_flags },
1202 6c78ea32 Blue Swirl
    [CC_OP_DIV] = { compute_all_div, compute_C_div },
1203 bdf9f35d Blue Swirl
    [CC_OP_ADD] = { compute_all_add, compute_C_add },
1204 3e6ba503 Artyom Tarasenko
    [CC_OP_ADDX] = { compute_all_add, compute_C_add },
1205 3b2d1e92 Blue Swirl
    [CC_OP_TADD] = { compute_all_tadd, compute_C_tadd },
1206 3b2d1e92 Blue Swirl
    [CC_OP_TADDTV] = { compute_all_taddtv, compute_C_taddtv },
1207 d4b0d468 Blue Swirl
    [CC_OP_SUB] = { compute_all_sub, compute_C_sub },
1208 3e6ba503 Artyom Tarasenko
    [CC_OP_SUBX] = { compute_all_sub, compute_C_sub },
1209 3b2d1e92 Blue Swirl
    [CC_OP_TSUB] = { compute_all_tsub, compute_C_tsub },
1210 3b2d1e92 Blue Swirl
    [CC_OP_TSUBTV] = { compute_all_tsubtv, compute_C_tsubtv },
1211 38482a77 Blue Swirl
    [CC_OP_LOGIC] = { compute_all_logic, compute_C_logic },
1212 8393617c Blue Swirl
};
1213 8393617c Blue Swirl
1214 8393617c Blue Swirl
#ifdef TARGET_SPARC64
1215 8393617c Blue Swirl
static const CCTable xcc_table[CC_OP_NB] = {
1216 8393617c Blue Swirl
    /* CC_OP_DYNAMIC should never happen */
1217 8393617c Blue Swirl
    [CC_OP_FLAGS] = { compute_all_flags_xcc, compute_C_flags_xcc },
1218 6c78ea32 Blue Swirl
    [CC_OP_DIV] = { compute_all_logic_xcc, compute_C_logic },
1219 bdf9f35d Blue Swirl
    [CC_OP_ADD] = { compute_all_add_xcc, compute_C_add_xcc },
1220 789c91ef Blue Swirl
    [CC_OP_ADDX] = { compute_all_addx_xcc, compute_C_addx_xcc },
1221 3b2d1e92 Blue Swirl
    [CC_OP_TADD] = { compute_all_add_xcc, compute_C_add_xcc },
1222 3b2d1e92 Blue Swirl
    [CC_OP_TADDTV] = { compute_all_add_xcc, compute_C_add_xcc },
1223 d4b0d468 Blue Swirl
    [CC_OP_SUB] = { compute_all_sub_xcc, compute_C_sub_xcc },
1224 2ca1d92b Blue Swirl
    [CC_OP_SUBX] = { compute_all_subx_xcc, compute_C_subx_xcc },
1225 3b2d1e92 Blue Swirl
    [CC_OP_TSUB] = { compute_all_sub_xcc, compute_C_sub_xcc },
1226 3b2d1e92 Blue Swirl
    [CC_OP_TSUBTV] = { compute_all_sub_xcc, compute_C_sub_xcc },
1227 38482a77 Blue Swirl
    [CC_OP_LOGIC] = { compute_all_logic_xcc, compute_C_logic },
1228 8393617c Blue Swirl
};
1229 8393617c Blue Swirl
#endif
1230 8393617c Blue Swirl
1231 8393617c Blue Swirl
void helper_compute_psr(void)
1232 8393617c Blue Swirl
{
1233 8393617c Blue Swirl
    uint32_t new_psr;
1234 8393617c Blue Swirl
1235 8393617c Blue Swirl
    new_psr = icc_table[CC_OP].compute_all();
1236 8393617c Blue Swirl
    env->psr = new_psr;
1237 8393617c Blue Swirl
#ifdef TARGET_SPARC64
1238 8393617c Blue Swirl
    new_psr = xcc_table[CC_OP].compute_all();
1239 8393617c Blue Swirl
    env->xcc = new_psr;
1240 8393617c Blue Swirl
#endif
1241 8393617c Blue Swirl
    CC_OP = CC_OP_FLAGS;
1242 8393617c Blue Swirl
}
1243 8393617c Blue Swirl
1244 8393617c Blue Swirl
uint32_t helper_compute_C_icc(void)
1245 8393617c Blue Swirl
{
1246 8393617c Blue Swirl
    uint32_t ret;
1247 8393617c Blue Swirl
1248 8393617c Blue Swirl
    ret = icc_table[CC_OP].compute_c() >> PSR_CARRY_SHIFT;
1249 8393617c Blue Swirl
    return ret;
1250 8393617c Blue Swirl
}
1251 8393617c Blue Swirl
1252 3475187d bellard
#ifdef TARGET_SPARC64
1253 714547bb blueswir1
GEN_FCMPS(fcmps_fcc1, float32, 22, 0);
1254 417454b0 blueswir1
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
1255 64a88d5d blueswir1
GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
1256 417454b0 blueswir1
1257 714547bb blueswir1
GEN_FCMPS(fcmps_fcc2, float32, 24, 0);
1258 417454b0 blueswir1
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
1259 64a88d5d blueswir1
GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
1260 417454b0 blueswir1
1261 714547bb blueswir1
GEN_FCMPS(fcmps_fcc3, float32, 26, 0);
1262 417454b0 blueswir1
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
1263 64a88d5d blueswir1
GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
1264 417454b0 blueswir1
1265 714547bb blueswir1
GEN_FCMPS(fcmpes_fcc1, float32, 22, 1);
1266 417454b0 blueswir1
GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
1267 64a88d5d blueswir1
GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
1268 3475187d bellard
1269 714547bb blueswir1
GEN_FCMPS(fcmpes_fcc2, float32, 24, 1);
1270 417454b0 blueswir1
GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
1271 64a88d5d blueswir1
GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
1272 3475187d bellard
1273 714547bb blueswir1
GEN_FCMPS(fcmpes_fcc3, float32, 26, 1);
1274 417454b0 blueswir1
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
1275 4e14008f blueswir1
GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
1276 4e14008f blueswir1
#endif
1277 714547bb blueswir1
#undef GEN_FCMPS
1278 3475187d bellard
1279 77f193da blueswir1
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \
1280 77f193da blueswir1
    defined(DEBUG_MXCC)
1281 952a328f blueswir1
static void dump_mxcc(CPUState *env)
1282 952a328f blueswir1
{
1283 0bf9e31a Blue Swirl
    printf("mxccdata: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
1284 0bf9e31a Blue Swirl
           "\n",
1285 77f193da blueswir1
           env->mxccdata[0], env->mxccdata[1],
1286 77f193da blueswir1
           env->mxccdata[2], env->mxccdata[3]);
1287 0bf9e31a Blue Swirl
    printf("mxccregs: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
1288 0bf9e31a Blue Swirl
           "\n"
1289 0bf9e31a Blue Swirl
           "          %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
1290 0bf9e31a Blue Swirl
           "\n",
1291 77f193da blueswir1
           env->mxccregs[0], env->mxccregs[1],
1292 77f193da blueswir1
           env->mxccregs[2], env->mxccregs[3],
1293 77f193da blueswir1
           env->mxccregs[4], env->mxccregs[5],
1294 77f193da blueswir1
           env->mxccregs[6], env->mxccregs[7]);
1295 952a328f blueswir1
}
1296 952a328f blueswir1
#endif
1297 952a328f blueswir1
1298 1a2fb1c0 blueswir1
#if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)) \
1299 1a2fb1c0 blueswir1
    && defined(DEBUG_ASI)
1300 1a2fb1c0 blueswir1
static void dump_asi(const char *txt, target_ulong addr, int asi, int size,
1301 1a2fb1c0 blueswir1
                     uint64_t r1)
1302 8543e2cf blueswir1
{
1303 8543e2cf blueswir1
    switch (size)
1304 8543e2cf blueswir1
    {
1305 8543e2cf blueswir1
    case 1:
1306 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %02" PRIx64 "\n", txt,
1307 1a2fb1c0 blueswir1
                    addr, asi, r1 & 0xff);
1308 8543e2cf blueswir1
        break;
1309 8543e2cf blueswir1
    case 2:
1310 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %04" PRIx64 "\n", txt,
1311 1a2fb1c0 blueswir1
                    addr, asi, r1 & 0xffff);
1312 8543e2cf blueswir1
        break;
1313 8543e2cf blueswir1
    case 4:
1314 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %08" PRIx64 "\n", txt,
1315 1a2fb1c0 blueswir1
                    addr, asi, r1 & 0xffffffff);
1316 8543e2cf blueswir1
        break;
1317 8543e2cf blueswir1
    case 8:
1318 1a2fb1c0 blueswir1
        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %016" PRIx64 "\n", txt,
1319 1a2fb1c0 blueswir1
                    addr, asi, r1);
1320 8543e2cf blueswir1
        break;
1321 8543e2cf blueswir1
    }
1322 8543e2cf blueswir1
}
1323 8543e2cf blueswir1
#endif
1324 8543e2cf blueswir1
1325 1a2fb1c0 blueswir1
#ifndef TARGET_SPARC64
1326 1a2fb1c0 blueswir1
#ifndef CONFIG_USER_ONLY
1327 1a2fb1c0 blueswir1
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1328 e8af50a3 bellard
{
1329 1a2fb1c0 blueswir1
    uint64_t ret = 0;
1330 8543e2cf blueswir1
#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
1331 1a2fb1c0 blueswir1
    uint32_t last_addr = addr;
1332 952a328f blueswir1
#endif
1333 e80cfcfc bellard
1334 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1335 e80cfcfc bellard
    switch (asi) {
1336 6c36d3fa blueswir1
    case 2: /* SuperSparc MXCC registers */
1337 1a2fb1c0 blueswir1
        switch (addr) {
1338 952a328f blueswir1
        case 0x01c00a00: /* MXCC control register */
1339 1a2fb1c0 blueswir1
            if (size == 8)
1340 1a2fb1c0 blueswir1
                ret = env->mxccregs[3];
1341 1a2fb1c0 blueswir1
            else
1342 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1343 77f193da blueswir1
                             size);
1344 952a328f blueswir1
            break;
1345 952a328f blueswir1
        case 0x01c00a04: /* MXCC control register */
1346 952a328f blueswir1
            if (size == 4)
1347 952a328f blueswir1
                ret = env->mxccregs[3];
1348 952a328f blueswir1
            else
1349 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1350 77f193da blueswir1
                             size);
1351 952a328f blueswir1
            break;
1352 295db113 blueswir1
        case 0x01c00c00: /* Module reset register */
1353 295db113 blueswir1
            if (size == 8) {
1354 1a2fb1c0 blueswir1
                ret = env->mxccregs[5];
1355 295db113 blueswir1
                // should we do something here?
1356 295db113 blueswir1
            } else
1357 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1358 77f193da blueswir1
                             size);
1359 295db113 blueswir1
            break;
1360 952a328f blueswir1
        case 0x01c00f00: /* MBus port address register */
1361 1a2fb1c0 blueswir1
            if (size == 8)
1362 1a2fb1c0 blueswir1
                ret = env->mxccregs[7];
1363 1a2fb1c0 blueswir1
            else
1364 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1365 77f193da blueswir1
                             size);
1366 952a328f blueswir1
            break;
1367 952a328f blueswir1
        default:
1368 77f193da blueswir1
            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
1369 77f193da blueswir1
                         size);
1370 952a328f blueswir1
            break;
1371 952a328f blueswir1
        }
1372 77f193da blueswir1
        DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
1373 9827e450 blueswir1
                     "addr = %08x -> ret = %" PRIx64 ","
1374 1a2fb1c0 blueswir1
                     "addr = %08x\n", asi, size, sign, last_addr, ret, addr);
1375 952a328f blueswir1
#ifdef DEBUG_MXCC
1376 952a328f blueswir1
        dump_mxcc(env);
1377 952a328f blueswir1
#endif
1378 6c36d3fa blueswir1
        break;
1379 e8af50a3 bellard
    case 3: /* MMU probe */
1380 0f8a249a blueswir1
        {
1381 0f8a249a blueswir1
            int mmulev;
1382 0f8a249a blueswir1
1383 1a2fb1c0 blueswir1
            mmulev = (addr >> 8) & 15;
1384 0f8a249a blueswir1
            if (mmulev > 4)
1385 0f8a249a blueswir1
                ret = 0;
1386 1a2fb1c0 blueswir1
            else
1387 1a2fb1c0 blueswir1
                ret = mmu_probe(env, addr, mmulev);
1388 1a2fb1c0 blueswir1
            DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64 "\n",
1389 1a2fb1c0 blueswir1
                        addr, mmulev, ret);
1390 0f8a249a blueswir1
        }
1391 0f8a249a blueswir1
        break;
1392 e8af50a3 bellard
    case 4: /* read MMU regs */
1393 0f8a249a blueswir1
        {
1394 1a2fb1c0 blueswir1
            int reg = (addr >> 8) & 0x1f;
1395 3b46e624 ths
1396 0f8a249a blueswir1
            ret = env->mmuregs[reg];
1397 0f8a249a blueswir1
            if (reg == 3) /* Fault status cleared on read */
1398 3dd9a152 blueswir1
                env->mmuregs[3] = 0;
1399 3dd9a152 blueswir1
            else if (reg == 0x13) /* Fault status read */
1400 3dd9a152 blueswir1
                ret = env->mmuregs[3];
1401 3dd9a152 blueswir1
            else if (reg == 0x14) /* Fault address read */
1402 3dd9a152 blueswir1
                ret = env->mmuregs[4];
1403 1a2fb1c0 blueswir1
            DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
1404 0f8a249a blueswir1
        }
1405 0f8a249a blueswir1
        break;
1406 045380be blueswir1
    case 5: // Turbosparc ITLB Diagnostic
1407 045380be blueswir1
    case 6: // Turbosparc DTLB Diagnostic
1408 045380be blueswir1
    case 7: // Turbosparc IOTLB Diagnostic
1409 045380be blueswir1
        break;
1410 6c36d3fa blueswir1
    case 9: /* Supervisor code access */
1411 6c36d3fa blueswir1
        switch(size) {
1412 6c36d3fa blueswir1
        case 1:
1413 1a2fb1c0 blueswir1
            ret = ldub_code(addr);
1414 6c36d3fa blueswir1
            break;
1415 6c36d3fa blueswir1
        case 2:
1416 a4e7dd52 blueswir1
            ret = lduw_code(addr);
1417 6c36d3fa blueswir1
            break;
1418 6c36d3fa blueswir1
        default:
1419 6c36d3fa blueswir1
        case 4:
1420 a4e7dd52 blueswir1
            ret = ldl_code(addr);
1421 6c36d3fa blueswir1
            break;
1422 6c36d3fa blueswir1
        case 8:
1423 a4e7dd52 blueswir1
            ret = ldq_code(addr);
1424 6c36d3fa blueswir1
            break;
1425 6c36d3fa blueswir1
        }
1426 6c36d3fa blueswir1
        break;
1427 81ad8ba2 blueswir1
    case 0xa: /* User data access */
1428 81ad8ba2 blueswir1
        switch(size) {
1429 81ad8ba2 blueswir1
        case 1:
1430 1a2fb1c0 blueswir1
            ret = ldub_user(addr);
1431 81ad8ba2 blueswir1
            break;
1432 81ad8ba2 blueswir1
        case 2:
1433 a4e7dd52 blueswir1
            ret = lduw_user(addr);
1434 81ad8ba2 blueswir1
            break;
1435 81ad8ba2 blueswir1
        default:
1436 81ad8ba2 blueswir1
        case 4:
1437 a4e7dd52 blueswir1
            ret = ldl_user(addr);
1438 81ad8ba2 blueswir1
            break;
1439 81ad8ba2 blueswir1
        case 8:
1440 a4e7dd52 blueswir1
            ret = ldq_user(addr);
1441 81ad8ba2 blueswir1
            break;
1442 81ad8ba2 blueswir1
        }
1443 81ad8ba2 blueswir1
        break;
1444 81ad8ba2 blueswir1
    case 0xb: /* Supervisor data access */
1445 81ad8ba2 blueswir1
        switch(size) {
1446 81ad8ba2 blueswir1
        case 1:
1447 1a2fb1c0 blueswir1
            ret = ldub_kernel(addr);
1448 81ad8ba2 blueswir1
            break;
1449 81ad8ba2 blueswir1
        case 2:
1450 a4e7dd52 blueswir1
            ret = lduw_kernel(addr);
1451 81ad8ba2 blueswir1
            break;
1452 81ad8ba2 blueswir1
        default:
1453 81ad8ba2 blueswir1
        case 4:
1454 a4e7dd52 blueswir1
            ret = ldl_kernel(addr);
1455 81ad8ba2 blueswir1
            break;
1456 81ad8ba2 blueswir1
        case 8:
1457 a4e7dd52 blueswir1
            ret = ldq_kernel(addr);
1458 81ad8ba2 blueswir1
            break;
1459 81ad8ba2 blueswir1
        }
1460 81ad8ba2 blueswir1
        break;
1461 6c36d3fa blueswir1
    case 0xc: /* I-cache tag */
1462 6c36d3fa blueswir1
    case 0xd: /* I-cache data */
1463 6c36d3fa blueswir1
    case 0xe: /* D-cache tag */
1464 6c36d3fa blueswir1
    case 0xf: /* D-cache data */
1465 6c36d3fa blueswir1
        break;
1466 6c36d3fa blueswir1
    case 0x20: /* MMU passthrough */
1467 02aab46a bellard
        switch(size) {
1468 02aab46a bellard
        case 1:
1469 1a2fb1c0 blueswir1
            ret = ldub_phys(addr);
1470 02aab46a bellard
            break;
1471 02aab46a bellard
        case 2:
1472 a4e7dd52 blueswir1
            ret = lduw_phys(addr);
1473 02aab46a bellard
            break;
1474 02aab46a bellard
        default:
1475 02aab46a bellard
        case 4:
1476 a4e7dd52 blueswir1
            ret = ldl_phys(addr);
1477 02aab46a bellard
            break;
1478 9e61bde5 bellard
        case 8:
1479 a4e7dd52 blueswir1
            ret = ldq_phys(addr);
1480 0f8a249a blueswir1
            break;
1481 02aab46a bellard
        }
1482 0f8a249a blueswir1
        break;
1483 7d85892b blueswir1
    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1484 5dcb6b91 blueswir1
        switch(size) {
1485 5dcb6b91 blueswir1
        case 1:
1486 c227f099 Anthony Liguori
            ret = ldub_phys((target_phys_addr_t)addr
1487 c227f099 Anthony Liguori
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
1488 5dcb6b91 blueswir1
            break;
1489 5dcb6b91 blueswir1
        case 2:
1490 c227f099 Anthony Liguori
            ret = lduw_phys((target_phys_addr_t)addr
1491 c227f099 Anthony Liguori
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
1492 5dcb6b91 blueswir1
            break;
1493 5dcb6b91 blueswir1
        default:
1494 5dcb6b91 blueswir1
        case 4:
1495 c227f099 Anthony Liguori
            ret = ldl_phys((target_phys_addr_t)addr
1496 c227f099 Anthony Liguori
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
1497 5dcb6b91 blueswir1
            break;
1498 5dcb6b91 blueswir1
        case 8:
1499 c227f099 Anthony Liguori
            ret = ldq_phys((target_phys_addr_t)addr
1500 c227f099 Anthony Liguori
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
1501 0f8a249a blueswir1
            break;
1502 5dcb6b91 blueswir1
        }
1503 0f8a249a blueswir1
        break;
1504 045380be blueswir1
    case 0x30: // Turbosparc secondary cache diagnostic
1505 045380be blueswir1
    case 0x31: // Turbosparc RAM snoop
1506 045380be blueswir1
    case 0x32: // Turbosparc page table descriptor diagnostic
1507 666c87aa blueswir1
    case 0x39: /* data cache diagnostic register */
1508 666c87aa blueswir1
        ret = 0;
1509 666c87aa blueswir1
        break;
1510 4017190e blueswir1
    case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
1511 4017190e blueswir1
        {
1512 4017190e blueswir1
            int reg = (addr >> 8) & 3;
1513 4017190e blueswir1
1514 4017190e blueswir1
            switch(reg) {
1515 4017190e blueswir1
            case 0: /* Breakpoint Value (Addr) */
1516 4017190e blueswir1
                ret = env->mmubpregs[reg];
1517 4017190e blueswir1
                break;
1518 4017190e blueswir1
            case 1: /* Breakpoint Mask */
1519 4017190e blueswir1
                ret = env->mmubpregs[reg];
1520 4017190e blueswir1
                break;
1521 4017190e blueswir1
            case 2: /* Breakpoint Control */
1522 4017190e blueswir1
                ret = env->mmubpregs[reg];
1523 4017190e blueswir1
                break;
1524 4017190e blueswir1
            case 3: /* Breakpoint Status */
1525 4017190e blueswir1
                ret = env->mmubpregs[reg];
1526 4017190e blueswir1
                env->mmubpregs[reg] = 0ULL;
1527 4017190e blueswir1
                break;
1528 4017190e blueswir1
            }
1529 0bf9e31a Blue Swirl
            DPRINTF_MMU("read breakpoint reg[%d] 0x%016" PRIx64 "\n", reg,
1530 0bf9e31a Blue Swirl
                        ret);
1531 4017190e blueswir1
        }
1532 4017190e blueswir1
        break;
1533 045380be blueswir1
    case 8: /* User code access, XXX */
1534 e8af50a3 bellard
    default:
1535 e18231a3 blueswir1
        do_unassigned_access(addr, 0, 0, asi, size);
1536 0f8a249a blueswir1
        ret = 0;
1537 0f8a249a blueswir1
        break;
1538 e8af50a3 bellard
    }
1539 81ad8ba2 blueswir1
    if (sign) {
1540 81ad8ba2 blueswir1
        switch(size) {
1541 81ad8ba2 blueswir1
        case 1:
1542 1a2fb1c0 blueswir1
            ret = (int8_t) ret;
1543 e32664fb blueswir1
            break;
1544 81ad8ba2 blueswir1
        case 2:
1545 1a2fb1c0 blueswir1
            ret = (int16_t) ret;
1546 1a2fb1c0 blueswir1
            break;
1547 1a2fb1c0 blueswir1
        case 4:
1548 1a2fb1c0 blueswir1
            ret = (int32_t) ret;
1549 e32664fb blueswir1
            break;
1550 81ad8ba2 blueswir1
        default:
1551 81ad8ba2 blueswir1
            break;
1552 81ad8ba2 blueswir1
        }
1553 81ad8ba2 blueswir1
    }
1554 8543e2cf blueswir1
#ifdef DEBUG_ASI
1555 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
1556 8543e2cf blueswir1
#endif
1557 1a2fb1c0 blueswir1
    return ret;
1558 e8af50a3 bellard
}
1559 e8af50a3 bellard
1560 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
1561 e8af50a3 bellard
{
1562 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1563 e8af50a3 bellard
    switch(asi) {
1564 6c36d3fa blueswir1
    case 2: /* SuperSparc MXCC registers */
1565 1a2fb1c0 blueswir1
        switch (addr) {
1566 952a328f blueswir1
        case 0x01c00000: /* MXCC stream data register 0 */
1567 952a328f blueswir1
            if (size == 8)
1568 1a2fb1c0 blueswir1
                env->mxccdata[0] = val;
1569 952a328f blueswir1
            else
1570 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1571 77f193da blueswir1
                             size);
1572 952a328f blueswir1
            break;
1573 952a328f blueswir1
        case 0x01c00008: /* MXCC stream data register 1 */
1574 952a328f blueswir1
            if (size == 8)
1575 1a2fb1c0 blueswir1
                env->mxccdata[1] = val;
1576 952a328f blueswir1
            else
1577 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1578 77f193da blueswir1
                             size);
1579 952a328f blueswir1
            break;
1580 952a328f blueswir1
        case 0x01c00010: /* MXCC stream data register 2 */
1581 952a328f blueswir1
            if (size == 8)
1582 1a2fb1c0 blueswir1
                env->mxccdata[2] = val;
1583 952a328f blueswir1
            else
1584 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1585 77f193da blueswir1
                             size);
1586 952a328f blueswir1
            break;
1587 952a328f blueswir1
        case 0x01c00018: /* MXCC stream data register 3 */
1588 952a328f blueswir1
            if (size == 8)
1589 1a2fb1c0 blueswir1
                env->mxccdata[3] = val;
1590 952a328f blueswir1
            else
1591 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1592 77f193da blueswir1
                             size);
1593 952a328f blueswir1
            break;
1594 952a328f blueswir1
        case 0x01c00100: /* MXCC stream source */
1595 952a328f blueswir1
            if (size == 8)
1596 1a2fb1c0 blueswir1
                env->mxccregs[0] = val;
1597 952a328f blueswir1
            else
1598 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1599 77f193da blueswir1
                             size);
1600 77f193da blueswir1
            env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1601 77f193da blueswir1
                                        0);
1602 77f193da blueswir1
            env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1603 77f193da blueswir1
                                        8);
1604 77f193da blueswir1
            env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1605 77f193da blueswir1
                                        16);
1606 77f193da blueswir1
            env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +
1607 77f193da blueswir1
                                        24);
1608 952a328f blueswir1
            break;
1609 952a328f blueswir1
        case 0x01c00200: /* MXCC stream destination */
1610 952a328f blueswir1
            if (size == 8)
1611 1a2fb1c0 blueswir1
                env->mxccregs[1] = val;
1612 952a328f blueswir1
            else
1613 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1614 77f193da blueswir1
                             size);
1615 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  0,
1616 77f193da blueswir1
                     env->mxccdata[0]);
1617 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  8,
1618 77f193da blueswir1
                     env->mxccdata[1]);
1619 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16,
1620 77f193da blueswir1
                     env->mxccdata[2]);
1621 77f193da blueswir1
            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24,
1622 77f193da blueswir1
                     env->mxccdata[3]);
1623 952a328f blueswir1
            break;
1624 952a328f blueswir1
        case 0x01c00a00: /* MXCC control register */
1625 952a328f blueswir1
            if (size == 8)
1626 1a2fb1c0 blueswir1
                env->mxccregs[3] = val;
1627 952a328f blueswir1
            else
1628 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1629 77f193da blueswir1
                             size);
1630 952a328f blueswir1
            break;
1631 952a328f blueswir1
        case 0x01c00a04: /* MXCC control register */
1632 952a328f blueswir1
            if (size == 4)
1633 9f4576f0 blueswir1
                env->mxccregs[3] = (env->mxccregs[3] & 0xffffffff00000000ULL)
1634 77f193da blueswir1
                    | val;
1635 952a328f blueswir1
            else
1636 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1637 77f193da blueswir1
                             size);
1638 952a328f blueswir1
            break;
1639 952a328f blueswir1
        case 0x01c00e00: /* MXCC error register  */
1640 bbf7d96b blueswir1
            // writing a 1 bit clears the error
1641 952a328f blueswir1
            if (size == 8)
1642 1a2fb1c0 blueswir1
                env->mxccregs[6] &= ~val;
1643 952a328f blueswir1
            else
1644 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1645 77f193da blueswir1
                             size);
1646 952a328f blueswir1
            break;
1647 952a328f blueswir1
        case 0x01c00f00: /* MBus port address register */
1648 952a328f blueswir1
            if (size == 8)
1649 1a2fb1c0 blueswir1
                env->mxccregs[7] = val;
1650 952a328f blueswir1
            else
1651 77f193da blueswir1
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr,
1652 77f193da blueswir1
                             size);
1653 952a328f blueswir1
            break;
1654 952a328f blueswir1
        default:
1655 77f193da blueswir1
            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr,
1656 77f193da blueswir1
                         size);
1657 952a328f blueswir1
            break;
1658 952a328f blueswir1
        }
1659 9827e450 blueswir1
        DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n",
1660 9827e450 blueswir1
                     asi, size, addr, val);
1661 952a328f blueswir1
#ifdef DEBUG_MXCC
1662 952a328f blueswir1
        dump_mxcc(env);
1663 952a328f blueswir1
#endif
1664 6c36d3fa blueswir1
        break;
1665 e8af50a3 bellard
    case 3: /* MMU flush */
1666 0f8a249a blueswir1
        {
1667 0f8a249a blueswir1
            int mmulev;
1668 e80cfcfc bellard
1669 1a2fb1c0 blueswir1
            mmulev = (addr >> 8) & 15;
1670 952a328f blueswir1
            DPRINTF_MMU("mmu flush level %d\n", mmulev);
1671 0f8a249a blueswir1
            switch (mmulev) {
1672 0f8a249a blueswir1
            case 0: // flush page
1673 1a2fb1c0 blueswir1
                tlb_flush_page(env, addr & 0xfffff000);
1674 0f8a249a blueswir1
                break;
1675 0f8a249a blueswir1
            case 1: // flush segment (256k)
1676 0f8a249a blueswir1
            case 2: // flush region (16M)
1677 0f8a249a blueswir1
            case 3: // flush context (4G)
1678 0f8a249a blueswir1
            case 4: // flush entire
1679 0f8a249a blueswir1
                tlb_flush(env, 1);
1680 0f8a249a blueswir1
                break;
1681 0f8a249a blueswir1
            default:
1682 0f8a249a blueswir1
                break;
1683 0f8a249a blueswir1
            }
1684 55754d9e bellard
#ifdef DEBUG_MMU
1685 0f8a249a blueswir1
            dump_mmu(env);
1686 55754d9e bellard
#endif
1687 0f8a249a blueswir1
        }
1688 8543e2cf blueswir1
        break;
1689 e8af50a3 bellard
    case 4: /* write MMU regs */
1690 0f8a249a blueswir1
        {
1691 1a2fb1c0 blueswir1
            int reg = (addr >> 8) & 0x1f;
1692 0f8a249a blueswir1
            uint32_t oldreg;
1693 3b46e624 ths
1694 0f8a249a blueswir1
            oldreg = env->mmuregs[reg];
1695 55754d9e bellard
            switch(reg) {
1696 3deaeab7 blueswir1
            case 0: // Control Register
1697 3dd9a152 blueswir1
                env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
1698 1a2fb1c0 blueswir1
                                    (val & 0x00ffffff);
1699 0f8a249a blueswir1
                // Mappings generated during no-fault mode or MMU
1700 0f8a249a blueswir1
                // disabled mode are invalid in normal mode
1701 5578ceab blueswir1
                if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) !=
1702 5578ceab blueswir1
                    (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm)))
1703 55754d9e bellard
                    tlb_flush(env, 1);
1704 55754d9e bellard
                break;
1705 3deaeab7 blueswir1
            case 1: // Context Table Pointer Register
1706 5578ceab blueswir1
                env->mmuregs[reg] = val & env->def->mmu_ctpr_mask;
1707 3deaeab7 blueswir1
                break;
1708 3deaeab7 blueswir1
            case 2: // Context Register
1709 5578ceab blueswir1
                env->mmuregs[reg] = val & env->def->mmu_cxr_mask;
1710 55754d9e bellard
                if (oldreg != env->mmuregs[reg]) {
1711 55754d9e bellard
                    /* we flush when the MMU context changes because
1712 55754d9e bellard
                       QEMU has no MMU context support */
1713 55754d9e bellard
                    tlb_flush(env, 1);
1714 55754d9e bellard
                }
1715 55754d9e bellard
                break;
1716 3deaeab7 blueswir1
            case 3: // Synchronous Fault Status Register with Clear
1717 3deaeab7 blueswir1
            case 4: // Synchronous Fault Address Register
1718 3deaeab7 blueswir1
                break;
1719 3deaeab7 blueswir1
            case 0x10: // TLB Replacement Control Register
1720 5578ceab blueswir1
                env->mmuregs[reg] = val & env->def->mmu_trcr_mask;
1721 55754d9e bellard
                break;
1722 3deaeab7 blueswir1
            case 0x13: // Synchronous Fault Status Register with Read and Clear
1723 5578ceab blueswir1
                env->mmuregs[3] = val & env->def->mmu_sfsr_mask;
1724 3dd9a152 blueswir1
                break;
1725 3deaeab7 blueswir1
            case 0x14: // Synchronous Fault Address Register
1726 1a2fb1c0 blueswir1
                env->mmuregs[4] = val;
1727 3dd9a152 blueswir1
                break;
1728 55754d9e bellard
            default:
1729 1a2fb1c0 blueswir1
                env->mmuregs[reg] = val;
1730 55754d9e bellard
                break;
1731 55754d9e bellard
            }
1732 55754d9e bellard
            if (oldreg != env->mmuregs[reg]) {
1733 77f193da blueswir1
                DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
1734 77f193da blueswir1
                            reg, oldreg, env->mmuregs[reg]);
1735 55754d9e bellard
            }
1736 952a328f blueswir1
#ifdef DEBUG_MMU
1737 0f8a249a blueswir1
            dump_mmu(env);
1738 55754d9e bellard
#endif
1739 0f8a249a blueswir1
        }
1740 8543e2cf blueswir1
        break;
1741 045380be blueswir1
    case 5: // Turbosparc ITLB Diagnostic
1742 045380be blueswir1
    case 6: // Turbosparc DTLB Diagnostic
1743 045380be blueswir1
    case 7: // Turbosparc IOTLB Diagnostic
1744 045380be blueswir1
        break;
1745 81ad8ba2 blueswir1
    case 0xa: /* User data access */
1746 81ad8ba2 blueswir1
        switch(size) {
1747 81ad8ba2 blueswir1
        case 1:
1748 1a2fb1c0 blueswir1
            stb_user(addr, val);
1749 81ad8ba2 blueswir1
            break;
1750 81ad8ba2 blueswir1
        case 2:
1751 a4e7dd52 blueswir1
            stw_user(addr, val);
1752 81ad8ba2 blueswir1
            break;
1753 81ad8ba2 blueswir1
        default:
1754 81ad8ba2 blueswir1
        case 4:
1755 a4e7dd52 blueswir1
            stl_user(addr, val);
1756 81ad8ba2 blueswir1
            break;
1757 81ad8ba2 blueswir1
        case 8:
1758 a4e7dd52 blueswir1
            stq_user(addr, val);
1759 81ad8ba2 blueswir1
            break;
1760 81ad8ba2 blueswir1
        }
1761 81ad8ba2 blueswir1
        break;
1762 81ad8ba2 blueswir1
    case 0xb: /* Supervisor data access */
1763 81ad8ba2 blueswir1
        switch(size) {
1764 81ad8ba2 blueswir1
        case 1:
1765 1a2fb1c0 blueswir1
            stb_kernel(addr, val);
1766 81ad8ba2 blueswir1
            break;
1767 81ad8ba2 blueswir1
        case 2:
1768 a4e7dd52 blueswir1
            stw_kernel(addr, val);
1769 81ad8ba2 blueswir1
            break;
1770 81ad8ba2 blueswir1
        default:
1771 81ad8ba2 blueswir1
        case 4:
1772 a4e7dd52 blueswir1
            stl_kernel(addr, val);
1773 81ad8ba2 blueswir1
            break;
1774 81ad8ba2 blueswir1
        case 8:
1775 a4e7dd52 blueswir1
            stq_kernel(addr, val);
1776 81ad8ba2 blueswir1
            break;
1777 81ad8ba2 blueswir1
        }
1778 81ad8ba2 blueswir1
        break;
1779 6c36d3fa blueswir1
    case 0xc: /* I-cache tag */
1780 6c36d3fa blueswir1
    case 0xd: /* I-cache data */
1781 6c36d3fa blueswir1
    case 0xe: /* D-cache tag */
1782 6c36d3fa blueswir1
    case 0xf: /* D-cache data */
1783 6c36d3fa blueswir1
    case 0x10: /* I/D-cache flush page */
1784 6c36d3fa blueswir1
    case 0x11: /* I/D-cache flush segment */
1785 6c36d3fa blueswir1
    case 0x12: /* I/D-cache flush region */
1786 6c36d3fa blueswir1
    case 0x13: /* I/D-cache flush context */
1787 6c36d3fa blueswir1
    case 0x14: /* I/D-cache flush user */
1788 6c36d3fa blueswir1
        break;
1789 e80cfcfc bellard
    case 0x17: /* Block copy, sta access */
1790 0f8a249a blueswir1
        {
1791 1a2fb1c0 blueswir1
            // val = src
1792 1a2fb1c0 blueswir1
            // addr = dst
1793 0f8a249a blueswir1
            // copy 32 bytes
1794 6c36d3fa blueswir1
            unsigned int i;
1795 1a2fb1c0 blueswir1
            uint32_t src = val & ~3, dst = addr & ~3, temp;
1796 3b46e624 ths
1797 6c36d3fa blueswir1
            for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
1798 6c36d3fa blueswir1
                temp = ldl_kernel(src);
1799 6c36d3fa blueswir1
                stl_kernel(dst, temp);
1800 6c36d3fa blueswir1
            }
1801 0f8a249a blueswir1
        }
1802 8543e2cf blueswir1
        break;
1803 e80cfcfc bellard
    case 0x1f: /* Block fill, stda access */
1804 0f8a249a blueswir1
        {
1805 1a2fb1c0 blueswir1
            // addr = dst
1806 1a2fb1c0 blueswir1
            // fill 32 bytes with val
1807 6c36d3fa blueswir1
            unsigned int i;
1808 1a2fb1c0 blueswir1
            uint32_t dst = addr & 7;
1809 6c36d3fa blueswir1
1810 6c36d3fa blueswir1
            for (i = 0; i < 32; i += 8, dst += 8)
1811 6c36d3fa blueswir1
                stq_kernel(dst, val);
1812 0f8a249a blueswir1
        }
1813 8543e2cf blueswir1
        break;
1814 6c36d3fa blueswir1
    case 0x20: /* MMU passthrough */
1815 0f8a249a blueswir1
        {
1816 02aab46a bellard
            switch(size) {
1817 02aab46a bellard
            case 1:
1818 1a2fb1c0 blueswir1
                stb_phys(addr, val);
1819 02aab46a bellard
                break;
1820 02aab46a bellard
            case 2:
1821 a4e7dd52 blueswir1
                stw_phys(addr, val);
1822 02aab46a bellard
                break;
1823 02aab46a bellard
            case 4:
1824 02aab46a bellard
            default:
1825 a4e7dd52 blueswir1
                stl_phys(addr, val);
1826 02aab46a bellard
                break;
1827 9e61bde5 bellard
            case 8:
1828 a4e7dd52 blueswir1
                stq_phys(addr, val);
1829 9e61bde5 bellard
                break;
1830 02aab46a bellard
            }
1831 0f8a249a blueswir1
        }
1832 8543e2cf blueswir1
        break;
1833 045380be blueswir1
    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1834 0f8a249a blueswir1
        {
1835 5dcb6b91 blueswir1
            switch(size) {
1836 5dcb6b91 blueswir1
            case 1:
1837 c227f099 Anthony Liguori
                stb_phys((target_phys_addr_t)addr
1838 c227f099 Anthony Liguori
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1839 5dcb6b91 blueswir1
                break;
1840 5dcb6b91 blueswir1
            case 2:
1841 c227f099 Anthony Liguori
                stw_phys((target_phys_addr_t)addr
1842 c227f099 Anthony Liguori
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1843 5dcb6b91 blueswir1
                break;
1844 5dcb6b91 blueswir1
            case 4:
1845 5dcb6b91 blueswir1
            default:
1846 c227f099 Anthony Liguori
                stl_phys((target_phys_addr_t)addr
1847 c227f099 Anthony Liguori
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1848 5dcb6b91 blueswir1
                break;
1849 5dcb6b91 blueswir1
            case 8:
1850 c227f099 Anthony Liguori
                stq_phys((target_phys_addr_t)addr
1851 c227f099 Anthony Liguori
                         | ((target_phys_addr_t)(asi & 0xf) << 32), val);
1852 5dcb6b91 blueswir1
                break;
1853 5dcb6b91 blueswir1
            }
1854 0f8a249a blueswir1
        }
1855 8543e2cf blueswir1
        break;
1856 045380be blueswir1
    case 0x30: // store buffer tags or Turbosparc secondary cache diagnostic
1857 045380be blueswir1
    case 0x31: // store buffer data, Ross RT620 I-cache flush or
1858 045380be blueswir1
               // Turbosparc snoop RAM
1859 77f193da blueswir1
    case 0x32: // store buffer control or Turbosparc page table
1860 77f193da blueswir1
               // descriptor diagnostic
1861 6c36d3fa blueswir1
    case 0x36: /* I-cache flash clear */
1862 6c36d3fa blueswir1
    case 0x37: /* D-cache flash clear */
1863 666c87aa blueswir1
    case 0x4c: /* breakpoint action */
1864 6c36d3fa blueswir1
        break;
1865 4017190e blueswir1
    case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
1866 4017190e blueswir1
        {
1867 4017190e blueswir1
            int reg = (addr >> 8) & 3;
1868 4017190e blueswir1
1869 4017190e blueswir1
            switch(reg) {
1870 4017190e blueswir1
            case 0: /* Breakpoint Value (Addr) */
1871 4017190e blueswir1
                env->mmubpregs[reg] = (val & 0xfffffffffULL);
1872 4017190e blueswir1
                break;
1873 4017190e blueswir1
            case 1: /* Breakpoint Mask */
1874 4017190e blueswir1
                env->mmubpregs[reg] = (val & 0xfffffffffULL);
1875 4017190e blueswir1
                break;
1876 4017190e blueswir1
            case 2: /* Breakpoint Control */
1877 4017190e blueswir1
                env->mmubpregs[reg] = (val & 0x7fULL);
1878 4017190e blueswir1
                break;
1879 4017190e blueswir1
            case 3: /* Breakpoint Status */
1880 4017190e blueswir1
                env->mmubpregs[reg] = (val & 0xfULL);
1881 4017190e blueswir1
                break;
1882 4017190e blueswir1
            }
1883 0bf9e31a Blue Swirl
            DPRINTF_MMU("write breakpoint reg[%d] 0x%016x\n", reg,
1884 4017190e blueswir1
                        env->mmuregs[reg]);
1885 4017190e blueswir1
        }
1886 4017190e blueswir1
        break;
1887 045380be blueswir1
    case 8: /* User code access, XXX */
1888 6c36d3fa blueswir1
    case 9: /* Supervisor code access, XXX */
1889 e8af50a3 bellard
    default:
1890 e18231a3 blueswir1
        do_unassigned_access(addr, 1, 0, asi, size);
1891 8543e2cf blueswir1
        break;
1892 e8af50a3 bellard
    }
1893 8543e2cf blueswir1
#ifdef DEBUG_ASI
1894 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
1895 8543e2cf blueswir1
#endif
1896 e8af50a3 bellard
}
1897 e8af50a3 bellard
1898 81ad8ba2 blueswir1
#endif /* CONFIG_USER_ONLY */
1899 81ad8ba2 blueswir1
#else /* TARGET_SPARC64 */
1900 81ad8ba2 blueswir1
1901 81ad8ba2 blueswir1
#ifdef CONFIG_USER_ONLY
1902 1a2fb1c0 blueswir1
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
1903 81ad8ba2 blueswir1
{
1904 81ad8ba2 blueswir1
    uint64_t ret = 0;
1905 1a2fb1c0 blueswir1
#if defined(DEBUG_ASI)
1906 1a2fb1c0 blueswir1
    target_ulong last_addr = addr;
1907 1a2fb1c0 blueswir1
#endif
1908 81ad8ba2 blueswir1
1909 81ad8ba2 blueswir1
    if (asi < 0x80)
1910 81ad8ba2 blueswir1
        raise_exception(TT_PRIV_ACT);
1911 81ad8ba2 blueswir1
1912 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
1913 2cade6a3 blueswir1
    address_mask(env, &addr);
1914 c2bc0e38 blueswir1
1915 81ad8ba2 blueswir1
    switch (asi) {
1916 81ad8ba2 blueswir1
    case 0x82: // Primary no-fault
1917 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1918 e83ce550 blueswir1
        if (page_check_range(addr, size, PAGE_READ) == -1) {
1919 e83ce550 blueswir1
#ifdef DEBUG_ASI
1920 e83ce550 blueswir1
            dump_asi("read ", last_addr, asi, size, ret);
1921 e83ce550 blueswir1
#endif
1922 e83ce550 blueswir1
            return 0;
1923 e83ce550 blueswir1
        }
1924 e83ce550 blueswir1
        // Fall through
1925 e83ce550 blueswir1
    case 0x80: // Primary
1926 e83ce550 blueswir1
    case 0x88: // Primary LE
1927 81ad8ba2 blueswir1
        {
1928 81ad8ba2 blueswir1
            switch(size) {
1929 81ad8ba2 blueswir1
            case 1:
1930 1a2fb1c0 blueswir1
                ret = ldub_raw(addr);
1931 81ad8ba2 blueswir1
                break;
1932 81ad8ba2 blueswir1
            case 2:
1933 a4e7dd52 blueswir1
                ret = lduw_raw(addr);
1934 81ad8ba2 blueswir1
                break;
1935 81ad8ba2 blueswir1
            case 4:
1936 a4e7dd52 blueswir1
                ret = ldl_raw(addr);
1937 81ad8ba2 blueswir1
                break;
1938 81ad8ba2 blueswir1
            default:
1939 81ad8ba2 blueswir1
            case 8:
1940 a4e7dd52 blueswir1
                ret = ldq_raw(addr);
1941 81ad8ba2 blueswir1
                break;
1942 81ad8ba2 blueswir1
            }
1943 81ad8ba2 blueswir1
        }
1944 81ad8ba2 blueswir1
        break;
1945 81ad8ba2 blueswir1
    case 0x83: // Secondary no-fault
1946 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
1947 e83ce550 blueswir1
        if (page_check_range(addr, size, PAGE_READ) == -1) {
1948 e83ce550 blueswir1
#ifdef DEBUG_ASI
1949 e83ce550 blueswir1
            dump_asi("read ", last_addr, asi, size, ret);
1950 e83ce550 blueswir1
#endif
1951 e83ce550 blueswir1
            return 0;
1952 e83ce550 blueswir1
        }
1953 e83ce550 blueswir1
        // Fall through
1954 e83ce550 blueswir1
    case 0x81: // Secondary
1955 e83ce550 blueswir1
    case 0x89: // Secondary LE
1956 81ad8ba2 blueswir1
        // XXX
1957 81ad8ba2 blueswir1
        break;
1958 81ad8ba2 blueswir1
    default:
1959 81ad8ba2 blueswir1
        break;
1960 81ad8ba2 blueswir1
    }
1961 81ad8ba2 blueswir1
1962 81ad8ba2 blueswir1
    /* Convert from little endian */
1963 81ad8ba2 blueswir1
    switch (asi) {
1964 81ad8ba2 blueswir1
    case 0x88: // Primary LE
1965 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
1966 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
1967 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
1968 81ad8ba2 blueswir1
        switch(size) {
1969 81ad8ba2 blueswir1
        case 2:
1970 81ad8ba2 blueswir1
            ret = bswap16(ret);
1971 e32664fb blueswir1
            break;
1972 81ad8ba2 blueswir1
        case 4:
1973 81ad8ba2 blueswir1
            ret = bswap32(ret);
1974 e32664fb blueswir1
            break;
1975 81ad8ba2 blueswir1
        case 8:
1976 81ad8ba2 blueswir1
            ret = bswap64(ret);
1977 e32664fb blueswir1
            break;
1978 81ad8ba2 blueswir1
        default:
1979 81ad8ba2 blueswir1
            break;
1980 81ad8ba2 blueswir1
        }
1981 81ad8ba2 blueswir1
    default:
1982 81ad8ba2 blueswir1
        break;
1983 81ad8ba2 blueswir1
    }
1984 81ad8ba2 blueswir1
1985 81ad8ba2 blueswir1
    /* Convert to signed number */
1986 81ad8ba2 blueswir1
    if (sign) {
1987 81ad8ba2 blueswir1
        switch(size) {
1988 81ad8ba2 blueswir1
        case 1:
1989 81ad8ba2 blueswir1
            ret = (int8_t) ret;
1990 e32664fb blueswir1
            break;
1991 81ad8ba2 blueswir1
        case 2:
1992 81ad8ba2 blueswir1
            ret = (int16_t) ret;
1993 e32664fb blueswir1
            break;
1994 81ad8ba2 blueswir1
        case 4:
1995 81ad8ba2 blueswir1
            ret = (int32_t) ret;
1996 e32664fb blueswir1
            break;
1997 81ad8ba2 blueswir1
        default:
1998 81ad8ba2 blueswir1
            break;
1999 81ad8ba2 blueswir1
        }
2000 81ad8ba2 blueswir1
    }
2001 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
2002 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
2003 1a2fb1c0 blueswir1
#endif
2004 1a2fb1c0 blueswir1
    return ret;
2005 81ad8ba2 blueswir1
}
2006 81ad8ba2 blueswir1
2007 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
2008 81ad8ba2 blueswir1
{
2009 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
2010 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
2011 1a2fb1c0 blueswir1
#endif
2012 81ad8ba2 blueswir1
    if (asi < 0x80)
2013 81ad8ba2 blueswir1
        raise_exception(TT_PRIV_ACT);
2014 81ad8ba2 blueswir1
2015 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
2016 2cade6a3 blueswir1
    address_mask(env, &addr);
2017 c2bc0e38 blueswir1
2018 81ad8ba2 blueswir1
    /* Convert to little endian */
2019 81ad8ba2 blueswir1
    switch (asi) {
2020 81ad8ba2 blueswir1
    case 0x88: // Primary LE
2021 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
2022 81ad8ba2 blueswir1
        switch(size) {
2023 81ad8ba2 blueswir1
        case 2:
2024 5b0f0bec Igor Kovalenko
            val = bswap16(val);
2025 e32664fb blueswir1
            break;
2026 81ad8ba2 blueswir1
        case 4:
2027 5b0f0bec Igor Kovalenko
            val = bswap32(val);
2028 e32664fb blueswir1
            break;
2029 81ad8ba2 blueswir1
        case 8:
2030 5b0f0bec Igor Kovalenko
            val = bswap64(val);
2031 e32664fb blueswir1
            break;
2032 81ad8ba2 blueswir1
        default:
2033 81ad8ba2 blueswir1
            break;
2034 81ad8ba2 blueswir1
        }
2035 81ad8ba2 blueswir1
    default:
2036 81ad8ba2 blueswir1
        break;
2037 81ad8ba2 blueswir1
    }
2038 81ad8ba2 blueswir1
2039 81ad8ba2 blueswir1
    switch(asi) {
2040 81ad8ba2 blueswir1
    case 0x80: // Primary
2041 81ad8ba2 blueswir1
    case 0x88: // Primary LE
2042 81ad8ba2 blueswir1
        {
2043 81ad8ba2 blueswir1
            switch(size) {
2044 81ad8ba2 blueswir1
            case 1:
2045 1a2fb1c0 blueswir1
                stb_raw(addr, val);
2046 81ad8ba2 blueswir1
                break;
2047 81ad8ba2 blueswir1
            case 2:
2048 a4e7dd52 blueswir1
                stw_raw(addr, val);
2049 81ad8ba2 blueswir1
                break;
2050 81ad8ba2 blueswir1
            case 4:
2051 a4e7dd52 blueswir1
                stl_raw(addr, val);
2052 81ad8ba2 blueswir1
                break;
2053 81ad8ba2 blueswir1
            case 8:
2054 81ad8ba2 blueswir1
            default:
2055 a4e7dd52 blueswir1
                stq_raw(addr, val);
2056 81ad8ba2 blueswir1
                break;
2057 81ad8ba2 blueswir1
            }
2058 81ad8ba2 blueswir1
        }
2059 81ad8ba2 blueswir1
        break;
2060 81ad8ba2 blueswir1
    case 0x81: // Secondary
2061 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
2062 81ad8ba2 blueswir1
        // XXX
2063 81ad8ba2 blueswir1
        return;
2064 81ad8ba2 blueswir1
2065 81ad8ba2 blueswir1
    case 0x82: // Primary no-fault, RO
2066 81ad8ba2 blueswir1
    case 0x83: // Secondary no-fault, RO
2067 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE, RO
2068 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE, RO
2069 81ad8ba2 blueswir1
    default:
2070 e18231a3 blueswir1
        do_unassigned_access(addr, 1, 0, 1, size);
2071 81ad8ba2 blueswir1
        return;
2072 81ad8ba2 blueswir1
    }
2073 81ad8ba2 blueswir1
}
2074 81ad8ba2 blueswir1
2075 81ad8ba2 blueswir1
#else /* CONFIG_USER_ONLY */
2076 3475187d bellard
2077 1a2fb1c0 blueswir1
uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
2078 3475187d bellard
{
2079 83469015 bellard
    uint64_t ret = 0;
2080 1a2fb1c0 blueswir1
#if defined(DEBUG_ASI)
2081 1a2fb1c0 blueswir1
    target_ulong last_addr = addr;
2082 1a2fb1c0 blueswir1
#endif
2083 3475187d bellard
2084 01b5d4e5 Igor V. Kovalenko
    asi &= 0xff;
2085 01b5d4e5 Igor V. Kovalenko
2086 6f27aba6 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2087 5578ceab blueswir1
        || ((env->def->features & CPU_FEATURE_HYPV)
2088 5578ceab blueswir1
            && asi >= 0x30 && asi < 0x80
2089 fb79ceb9 blueswir1
            && !(env->hpstate & HS_PRIV)))
2090 0f8a249a blueswir1
        raise_exception(TT_PRIV_ACT);
2091 3475187d bellard
2092 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
2093 3475187d bellard
    switch (asi) {
2094 e83ce550 blueswir1
    case 0x82: // Primary no-fault
2095 e83ce550 blueswir1
    case 0x8a: // Primary no-fault LE
2096 e83ce550 blueswir1
        if (cpu_get_phys_page_debug(env, addr) == -1ULL) {
2097 e83ce550 blueswir1
#ifdef DEBUG_ASI
2098 e83ce550 blueswir1
            dump_asi("read ", last_addr, asi, size, ret);
2099 e83ce550 blueswir1
#endif
2100 e83ce550 blueswir1
            return 0;
2101 e83ce550 blueswir1
        }
2102 e83ce550 blueswir1
        // Fall through
2103 81ad8ba2 blueswir1
    case 0x10: // As if user primary
2104 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
2105 81ad8ba2 blueswir1
    case 0x80: // Primary
2106 81ad8ba2 blueswir1
    case 0x88: // Primary LE
2107 c99657d3 blueswir1
    case 0xe2: // UA2007 Primary block init
2108 c99657d3 blueswir1
    case 0xe3: // UA2007 Secondary block init
2109 81ad8ba2 blueswir1
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
2110 5578ceab blueswir1
            if ((env->def->features & CPU_FEATURE_HYPV)
2111 5578ceab blueswir1
                && env->hpstate & HS_PRIV) {
2112 6f27aba6 blueswir1
                switch(size) {
2113 6f27aba6 blueswir1
                case 1:
2114 1a2fb1c0 blueswir1
                    ret = ldub_hypv(addr);
2115 6f27aba6 blueswir1
                    break;
2116 6f27aba6 blueswir1
                case 2:
2117 a4e7dd52 blueswir1
                    ret = lduw_hypv(addr);
2118 6f27aba6 blueswir1
                    break;
2119 6f27aba6 blueswir1
                case 4:
2120 a4e7dd52 blueswir1
                    ret = ldl_hypv(addr);
2121 6f27aba6 blueswir1
                    break;
2122 6f27aba6 blueswir1
                default:
2123 6f27aba6 blueswir1
                case 8:
2124 a4e7dd52 blueswir1
                    ret = ldq_hypv(addr);
2125 6f27aba6 blueswir1
                    break;
2126 6f27aba6 blueswir1
                }
2127 6f27aba6 blueswir1
            } else {
2128 6f27aba6 blueswir1
                switch(size) {
2129 6f27aba6 blueswir1
                case 1:
2130 1a2fb1c0 blueswir1
                    ret = ldub_kernel(addr);
2131 6f27aba6 blueswir1
                    break;
2132 6f27aba6 blueswir1
                case 2:
2133 a4e7dd52 blueswir1
                    ret = lduw_kernel(addr);
2134 6f27aba6 blueswir1
                    break;
2135 6f27aba6 blueswir1
                case 4:
2136 a4e7dd52 blueswir1
                    ret = ldl_kernel(addr);
2137 6f27aba6 blueswir1
                    break;
2138 6f27aba6 blueswir1
                default:
2139 6f27aba6 blueswir1
                case 8:
2140 a4e7dd52 blueswir1
                    ret = ldq_kernel(addr);
2141 6f27aba6 blueswir1
                    break;
2142 6f27aba6 blueswir1
                }
2143 81ad8ba2 blueswir1
            }
2144 81ad8ba2 blueswir1
        } else {
2145 81ad8ba2 blueswir1
            switch(size) {
2146 81ad8ba2 blueswir1
            case 1:
2147 1a2fb1c0 blueswir1
                ret = ldub_user(addr);
2148 81ad8ba2 blueswir1
                break;
2149 81ad8ba2 blueswir1
            case 2:
2150 a4e7dd52 blueswir1
                ret = lduw_user(addr);
2151 81ad8ba2 blueswir1
                break;
2152 81ad8ba2 blueswir1
            case 4:
2153 a4e7dd52 blueswir1
                ret = ldl_user(addr);
2154 81ad8ba2 blueswir1
                break;
2155 81ad8ba2 blueswir1
            default:
2156 81ad8ba2 blueswir1
            case 8:
2157 a4e7dd52 blueswir1
                ret = ldq_user(addr);
2158 81ad8ba2 blueswir1
                break;
2159 81ad8ba2 blueswir1
            }
2160 81ad8ba2 blueswir1
        }
2161 81ad8ba2 blueswir1
        break;
2162 3475187d bellard
    case 0x14: // Bypass
2163 3475187d bellard
    case 0x15: // Bypass, non-cacheable
2164 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
2165 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
2166 0f8a249a blueswir1
        {
2167 02aab46a bellard
            switch(size) {
2168 02aab46a bellard
            case 1:
2169 1a2fb1c0 blueswir1
                ret = ldub_phys(addr);
2170 02aab46a bellard
                break;
2171 02aab46a bellard
            case 2:
2172 a4e7dd52 blueswir1
                ret = lduw_phys(addr);
2173 02aab46a bellard
                break;
2174 02aab46a bellard
            case 4:
2175 a4e7dd52 blueswir1
                ret = ldl_phys(addr);
2176 02aab46a bellard
                break;
2177 02aab46a bellard
            default:
2178 02aab46a bellard
            case 8:
2179 a4e7dd52 blueswir1
                ret = ldq_phys(addr);
2180 02aab46a bellard
                break;
2181 02aab46a bellard
            }
2182 0f8a249a blueswir1
            break;
2183 0f8a249a blueswir1
        }
2184 db166940 blueswir1
    case 0x24: // Nucleus quad LDD 128 bit atomic
2185 db166940 blueswir1
    case 0x2c: // Nucleus quad LDD 128 bit atomic LE
2186 db166940 blueswir1
        //  Only ldda allowed
2187 db166940 blueswir1
        raise_exception(TT_ILL_INSN);
2188 db166940 blueswir1
        return 0;
2189 e83ce550 blueswir1
    case 0x83: // Secondary no-fault
2190 e83ce550 blueswir1
    case 0x8b: // Secondary no-fault LE
2191 e83ce550 blueswir1
        if (cpu_get_phys_page_debug(env, addr) == -1ULL) {
2192 e83ce550 blueswir1
#ifdef DEBUG_ASI
2193 e83ce550 blueswir1
            dump_asi("read ", last_addr, asi, size, ret);
2194 e83ce550 blueswir1
#endif
2195 e83ce550 blueswir1
            return 0;
2196 e83ce550 blueswir1
        }
2197 e83ce550 blueswir1
        // Fall through
2198 83469015 bellard
    case 0x04: // Nucleus
2199 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
2200 83469015 bellard
    case 0x11: // As if user secondary
2201 83469015 bellard
    case 0x19: // As if user secondary LE
2202 83469015 bellard
    case 0x4a: // UPA config
2203 81ad8ba2 blueswir1
    case 0x81: // Secondary
2204 83469015 bellard
    case 0x89: // Secondary LE
2205 0f8a249a blueswir1
        // XXX
2206 0f8a249a blueswir1
        break;
2207 3475187d bellard
    case 0x45: // LSU
2208 0f8a249a blueswir1
        ret = env->lsu;
2209 0f8a249a blueswir1
        break;
2210 3475187d bellard
    case 0x50: // I-MMU regs
2211 0f8a249a blueswir1
        {
2212 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
2213 3475187d bellard
2214 697a77e6 Igor Kovalenko
            if (reg == 0) {
2215 697a77e6 Igor Kovalenko
                // I-TSB Tag Target register
2216 6e8e7d4c Igor Kovalenko
                ret = ultrasparc_tag_target(env->immu.tag_access);
2217 697a77e6 Igor Kovalenko
            } else {
2218 697a77e6 Igor Kovalenko
                ret = env->immuregs[reg];
2219 697a77e6 Igor Kovalenko
            }
2220 697a77e6 Igor Kovalenko
2221 0f8a249a blueswir1
            break;
2222 0f8a249a blueswir1
        }
2223 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer
2224 697a77e6 Igor Kovalenko
        {
2225 697a77e6 Igor Kovalenko
            // env->immuregs[5] holds I-MMU TSB register value
2226 697a77e6 Igor Kovalenko
            // env->immuregs[6] holds I-MMU Tag Access register value
2227 6e8e7d4c Igor Kovalenko
            ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
2228 697a77e6 Igor Kovalenko
                                         8*1024);
2229 697a77e6 Igor Kovalenko
            break;
2230 697a77e6 Igor Kovalenko
        }
2231 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer
2232 697a77e6 Igor Kovalenko
        {
2233 697a77e6 Igor Kovalenko
            // env->immuregs[5] holds I-MMU TSB register value
2234 697a77e6 Igor Kovalenko
            // env->immuregs[6] holds I-MMU Tag Access register value
2235 6e8e7d4c Igor Kovalenko
            ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
2236 697a77e6 Igor Kovalenko
                                         64*1024);
2237 697a77e6 Igor Kovalenko
            break;
2238 697a77e6 Igor Kovalenko
        }
2239 a5a52cf2 blueswir1
    case 0x55: // I-MMU data access
2240 a5a52cf2 blueswir1
        {
2241 a5a52cf2 blueswir1
            int reg = (addr >> 3) & 0x3f;
2242 a5a52cf2 blueswir1
2243 6e8e7d4c Igor Kovalenko
            ret = env->itlb[reg].tte;
2244 a5a52cf2 blueswir1
            break;
2245 a5a52cf2 blueswir1
        }
2246 83469015 bellard
    case 0x56: // I-MMU tag read
2247 0f8a249a blueswir1
        {
2248 43e9e742 blueswir1
            int reg = (addr >> 3) & 0x3f;
2249 0f8a249a blueswir1
2250 6e8e7d4c Igor Kovalenko
            ret = env->itlb[reg].tag;
2251 0f8a249a blueswir1
            break;
2252 0f8a249a blueswir1
        }
2253 3475187d bellard
    case 0x58: // D-MMU regs
2254 0f8a249a blueswir1
        {
2255 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
2256 3475187d bellard
2257 697a77e6 Igor Kovalenko
            if (reg == 0) {
2258 697a77e6 Igor Kovalenko
                // D-TSB Tag Target register
2259 6e8e7d4c Igor Kovalenko
                ret = ultrasparc_tag_target(env->dmmu.tag_access);
2260 697a77e6 Igor Kovalenko
            } else {
2261 697a77e6 Igor Kovalenko
                ret = env->dmmuregs[reg];
2262 697a77e6 Igor Kovalenko
            }
2263 697a77e6 Igor Kovalenko
            break;
2264 697a77e6 Igor Kovalenko
        }
2265 697a77e6 Igor Kovalenko
    case 0x59: // D-MMU 8k TSB pointer
2266 697a77e6 Igor Kovalenko
        {
2267 697a77e6 Igor Kovalenko
            // env->dmmuregs[5] holds D-MMU TSB register value
2268 697a77e6 Igor Kovalenko
            // env->dmmuregs[6] holds D-MMU Tag Access register value
2269 6e8e7d4c Igor Kovalenko
            ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
2270 697a77e6 Igor Kovalenko
                                         8*1024);
2271 697a77e6 Igor Kovalenko
            break;
2272 697a77e6 Igor Kovalenko
        }
2273 697a77e6 Igor Kovalenko
    case 0x5a: // D-MMU 64k TSB pointer
2274 697a77e6 Igor Kovalenko
        {
2275 697a77e6 Igor Kovalenko
            // env->dmmuregs[5] holds D-MMU TSB register value
2276 697a77e6 Igor Kovalenko
            // env->dmmuregs[6] holds D-MMU Tag Access register value
2277 6e8e7d4c Igor Kovalenko
            ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
2278 697a77e6 Igor Kovalenko
                                         64*1024);
2279 0f8a249a blueswir1
            break;
2280 0f8a249a blueswir1
        }
2281 a5a52cf2 blueswir1
    case 0x5d: // D-MMU data access
2282 a5a52cf2 blueswir1
        {
2283 a5a52cf2 blueswir1
            int reg = (addr >> 3) & 0x3f;
2284 a5a52cf2 blueswir1
2285 6e8e7d4c Igor Kovalenko
            ret = env->dtlb[reg].tte;
2286 a5a52cf2 blueswir1
            break;
2287 a5a52cf2 blueswir1
        }
2288 83469015 bellard
    case 0x5e: // D-MMU tag read
2289 0f8a249a blueswir1
        {
2290 43e9e742 blueswir1
            int reg = (addr >> 3) & 0x3f;
2291 0f8a249a blueswir1
2292 6e8e7d4c Igor Kovalenko
            ret = env->dtlb[reg].tag;
2293 0f8a249a blueswir1
            break;
2294 0f8a249a blueswir1
        }
2295 f7350b47 blueswir1
    case 0x46: // D-cache data
2296 f7350b47 blueswir1
    case 0x47: // D-cache tag access
2297 a5a52cf2 blueswir1
    case 0x4b: // E-cache error enable
2298 a5a52cf2 blueswir1
    case 0x4c: // E-cache asynchronous fault status
2299 a5a52cf2 blueswir1
    case 0x4d: // E-cache asynchronous fault address
2300 f7350b47 blueswir1
    case 0x4e: // E-cache tag data
2301 f7350b47 blueswir1
    case 0x66: // I-cache instruction access
2302 f7350b47 blueswir1
    case 0x67: // I-cache tag access
2303 f7350b47 blueswir1
    case 0x6e: // I-cache predecode
2304 f7350b47 blueswir1
    case 0x6f: // I-cache LRU etc.
2305 f7350b47 blueswir1
    case 0x76: // E-cache tag
2306 f7350b47 blueswir1
    case 0x7e: // E-cache tag
2307 f7350b47 blueswir1
        break;
2308 3475187d bellard
    case 0x5b: // D-MMU data pointer
2309 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
2310 83469015 bellard
    case 0x49: // Interrupt data receive
2311 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
2312 0f8a249a blueswir1
        // XXX
2313 0f8a249a blueswir1
        break;
2314 3475187d bellard
    case 0x54: // I-MMU data in, WO
2315 3475187d bellard
    case 0x57: // I-MMU demap, WO
2316 3475187d bellard
    case 0x5c: // D-MMU data in, WO
2317 3475187d bellard
    case 0x5f: // D-MMU demap, WO
2318 83469015 bellard
    case 0x77: // Interrupt vector, WO
2319 3475187d bellard
    default:
2320 e18231a3 blueswir1
        do_unassigned_access(addr, 0, 0, 1, size);
2321 0f8a249a blueswir1
        ret = 0;
2322 0f8a249a blueswir1
        break;
2323 3475187d bellard
    }
2324 81ad8ba2 blueswir1
2325 81ad8ba2 blueswir1
    /* Convert from little endian */
2326 81ad8ba2 blueswir1
    switch (asi) {
2327 81ad8ba2 blueswir1
    case 0x0c: // Nucleus Little Endian (LE)
2328 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
2329 81ad8ba2 blueswir1
    case 0x19: // As if user secondary LE
2330 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
2331 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
2332 81ad8ba2 blueswir1
    case 0x88: // Primary LE
2333 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
2334 81ad8ba2 blueswir1
    case 0x8a: // Primary no-fault LE
2335 81ad8ba2 blueswir1
    case 0x8b: // Secondary no-fault LE
2336 81ad8ba2 blueswir1
        switch(size) {
2337 81ad8ba2 blueswir1
        case 2:
2338 81ad8ba2 blueswir1
            ret = bswap16(ret);
2339 e32664fb blueswir1
            break;
2340 81ad8ba2 blueswir1
        case 4:
2341 81ad8ba2 blueswir1
            ret = bswap32(ret);
2342 e32664fb blueswir1
            break;
2343 81ad8ba2 blueswir1
        case 8:
2344 81ad8ba2 blueswir1
            ret = bswap64(ret);
2345 e32664fb blueswir1
            break;
2346 81ad8ba2 blueswir1
        default:
2347 81ad8ba2 blueswir1
            break;
2348 81ad8ba2 blueswir1
        }
2349 81ad8ba2 blueswir1
    default:
2350 81ad8ba2 blueswir1
        break;
2351 81ad8ba2 blueswir1
    }
2352 81ad8ba2 blueswir1
2353 81ad8ba2 blueswir1
    /* Convert to signed number */
2354 81ad8ba2 blueswir1
    if (sign) {
2355 81ad8ba2 blueswir1
        switch(size) {
2356 81ad8ba2 blueswir1
        case 1:
2357 81ad8ba2 blueswir1
            ret = (int8_t) ret;
2358 e32664fb blueswir1
            break;
2359 81ad8ba2 blueswir1
        case 2:
2360 81ad8ba2 blueswir1
            ret = (int16_t) ret;
2361 e32664fb blueswir1
            break;
2362 81ad8ba2 blueswir1
        case 4:
2363 81ad8ba2 blueswir1
            ret = (int32_t) ret;
2364 e32664fb blueswir1
            break;
2365 81ad8ba2 blueswir1
        default:
2366 81ad8ba2 blueswir1
            break;
2367 81ad8ba2 blueswir1
        }
2368 81ad8ba2 blueswir1
    }
2369 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
2370 1a2fb1c0 blueswir1
    dump_asi("read ", last_addr, asi, size, ret);
2371 1a2fb1c0 blueswir1
#endif
2372 1a2fb1c0 blueswir1
    return ret;
2373 3475187d bellard
}
2374 3475187d bellard
2375 1a2fb1c0 blueswir1
void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
2376 3475187d bellard
{
2377 1a2fb1c0 blueswir1
#ifdef DEBUG_ASI
2378 1a2fb1c0 blueswir1
    dump_asi("write", addr, asi, size, val);
2379 1a2fb1c0 blueswir1
#endif
2380 01b5d4e5 Igor V. Kovalenko
2381 01b5d4e5 Igor V. Kovalenko
    asi &= 0xff;
2382 01b5d4e5 Igor V. Kovalenko
2383 6f27aba6 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2384 5578ceab blueswir1
        || ((env->def->features & CPU_FEATURE_HYPV)
2385 5578ceab blueswir1
            && asi >= 0x30 && asi < 0x80
2386 fb79ceb9 blueswir1
            && !(env->hpstate & HS_PRIV)))
2387 0f8a249a blueswir1
        raise_exception(TT_PRIV_ACT);
2388 3475187d bellard
2389 c2bc0e38 blueswir1
    helper_check_align(addr, size - 1);
2390 81ad8ba2 blueswir1
    /* Convert to little endian */
2391 81ad8ba2 blueswir1
    switch (asi) {
2392 81ad8ba2 blueswir1
    case 0x0c: // Nucleus Little Endian (LE)
2393 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
2394 81ad8ba2 blueswir1
    case 0x19: // As if user secondary LE
2395 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
2396 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
2397 81ad8ba2 blueswir1
    case 0x88: // Primary LE
2398 81ad8ba2 blueswir1
    case 0x89: // Secondary LE
2399 81ad8ba2 blueswir1
        switch(size) {
2400 81ad8ba2 blueswir1
        case 2:
2401 5b0f0bec Igor Kovalenko
            val = bswap16(val);
2402 e32664fb blueswir1
            break;
2403 81ad8ba2 blueswir1
        case 4:
2404 5b0f0bec Igor Kovalenko
            val = bswap32(val);
2405 e32664fb blueswir1
            break;
2406 81ad8ba2 blueswir1
        case 8:
2407 5b0f0bec Igor Kovalenko
            val = bswap64(val);
2408 e32664fb blueswir1
            break;
2409 81ad8ba2 blueswir1
        default:
2410 81ad8ba2 blueswir1
            break;
2411 81ad8ba2 blueswir1
        }
2412 81ad8ba2 blueswir1
    default:
2413 81ad8ba2 blueswir1
        break;
2414 81ad8ba2 blueswir1
    }
2415 81ad8ba2 blueswir1
2416 3475187d bellard
    switch(asi) {
2417 81ad8ba2 blueswir1
    case 0x10: // As if user primary
2418 81ad8ba2 blueswir1
    case 0x18: // As if user primary LE
2419 81ad8ba2 blueswir1
    case 0x80: // Primary
2420 81ad8ba2 blueswir1
    case 0x88: // Primary LE
2421 c99657d3 blueswir1
    case 0xe2: // UA2007 Primary block init
2422 c99657d3 blueswir1
    case 0xe3: // UA2007 Secondary block init
2423 81ad8ba2 blueswir1
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
2424 5578ceab blueswir1
            if ((env->def->features & CPU_FEATURE_HYPV)
2425 5578ceab blueswir1
                && env->hpstate & HS_PRIV) {
2426 6f27aba6 blueswir1
                switch(size) {
2427 6f27aba6 blueswir1
                case 1:
2428 1a2fb1c0 blueswir1
                    stb_hypv(addr, val);
2429 6f27aba6 blueswir1
                    break;
2430 6f27aba6 blueswir1
                case 2:
2431 a4e7dd52 blueswir1
                    stw_hypv(addr, val);
2432 6f27aba6 blueswir1
                    break;
2433 6f27aba6 blueswir1
                case 4:
2434 a4e7dd52 blueswir1
                    stl_hypv(addr, val);
2435 6f27aba6 blueswir1
                    break;
2436 6f27aba6 blueswir1
                case 8:
2437 6f27aba6 blueswir1
                default:
2438 a4e7dd52 blueswir1
                    stq_hypv(addr, val);
2439 6f27aba6 blueswir1
                    break;
2440 6f27aba6 blueswir1
                }
2441 6f27aba6 blueswir1
            } else {
2442 6f27aba6 blueswir1
                switch(size) {
2443 6f27aba6 blueswir1
                case 1:
2444 1a2fb1c0 blueswir1
                    stb_kernel(addr, val);
2445 6f27aba6 blueswir1
                    break;
2446 6f27aba6 blueswir1
                case 2:
2447 a4e7dd52 blueswir1
                    stw_kernel(addr, val);
2448 6f27aba6 blueswir1
                    break;
2449 6f27aba6 blueswir1
                case 4:
2450 a4e7dd52 blueswir1
                    stl_kernel(addr, val);
2451 6f27aba6 blueswir1
                    break;
2452 6f27aba6 blueswir1
                case 8:
2453 6f27aba6 blueswir1
                default:
2454 a4e7dd52 blueswir1
                    stq_kernel(addr, val);
2455 6f27aba6 blueswir1
                    break;
2456 6f27aba6 blueswir1
                }
2457 81ad8ba2 blueswir1
            }
2458 81ad8ba2 blueswir1
        } else {
2459 81ad8ba2 blueswir1
            switch(size) {
2460 81ad8ba2 blueswir1
            case 1:
2461 1a2fb1c0 blueswir1
                stb_user(addr, val);
2462 81ad8ba2 blueswir1
                break;
2463 81ad8ba2 blueswir1
            case 2:
2464 a4e7dd52 blueswir1
                stw_user(addr, val);
2465 81ad8ba2 blueswir1
                break;
2466 81ad8ba2 blueswir1
            case 4:
2467 a4e7dd52 blueswir1
                stl_user(addr, val);
2468 81ad8ba2 blueswir1
                break;
2469 81ad8ba2 blueswir1
            case 8:
2470 81ad8ba2 blueswir1
            default:
2471 a4e7dd52 blueswir1
                stq_user(addr, val);
2472 81ad8ba2 blueswir1
                break;
2473 81ad8ba2 blueswir1
            }
2474 81ad8ba2 blueswir1
        }
2475 81ad8ba2 blueswir1
        break;
2476 3475187d bellard
    case 0x14: // Bypass
2477 3475187d bellard
    case 0x15: // Bypass, non-cacheable
2478 81ad8ba2 blueswir1
    case 0x1c: // Bypass LE
2479 81ad8ba2 blueswir1
    case 0x1d: // Bypass, non-cacheable LE
2480 0f8a249a blueswir1
        {
2481 02aab46a bellard
            switch(size) {
2482 02aab46a bellard
            case 1:
2483 1a2fb1c0 blueswir1
                stb_phys(addr, val);
2484 02aab46a bellard
                break;
2485 02aab46a bellard
            case 2:
2486 a4e7dd52 blueswir1
                stw_phys(addr, val);
2487 02aab46a bellard
                break;
2488 02aab46a bellard
            case 4:
2489 a4e7dd52 blueswir1
                stl_phys(addr, val);
2490 02aab46a bellard
                break;
2491 02aab46a bellard
            case 8:
2492 02aab46a bellard
            default:
2493 a4e7dd52 blueswir1
                stq_phys(addr, val);
2494 02aab46a bellard
                break;
2495 02aab46a bellard
            }
2496 0f8a249a blueswir1
        }
2497 0f8a249a blueswir1
        return;
2498 db166940 blueswir1
    case 0x24: // Nucleus quad LDD 128 bit atomic
2499 db166940 blueswir1
    case 0x2c: // Nucleus quad LDD 128 bit atomic LE
2500 db166940 blueswir1
        //  Only ldda allowed
2501 db166940 blueswir1
        raise_exception(TT_ILL_INSN);
2502 db166940 blueswir1
        return;
2503 83469015 bellard
    case 0x04: // Nucleus
2504 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
2505 83469015 bellard
    case 0x11: // As if user secondary
2506 83469015 bellard
    case 0x19: // As if user secondary LE
2507 83469015 bellard
    case 0x4a: // UPA config
2508 51996525 blueswir1
    case 0x81: // Secondary
2509 83469015 bellard
    case 0x89: // Secondary LE
2510 0f8a249a blueswir1
        // XXX
2511 0f8a249a blueswir1
        return;
2512 3475187d bellard
    case 0x45: // LSU
2513 0f8a249a blueswir1
        {
2514 0f8a249a blueswir1
            uint64_t oldreg;
2515 0f8a249a blueswir1
2516 0f8a249a blueswir1
            oldreg = env->lsu;
2517 1a2fb1c0 blueswir1
            env->lsu = val & (DMMU_E | IMMU_E);
2518 0f8a249a blueswir1
            // Mappings generated during D/I MMU disabled mode are
2519 0f8a249a blueswir1
            // invalid in normal mode
2520 0f8a249a blueswir1
            if (oldreg != env->lsu) {
2521 77f193da blueswir1
                DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
2522 77f193da blueswir1
                            oldreg, env->lsu);
2523 83469015 bellard
#ifdef DEBUG_MMU
2524 0f8a249a blueswir1
                dump_mmu(env);
2525 83469015 bellard
#endif
2526 0f8a249a blueswir1
                tlb_flush(env, 1);
2527 0f8a249a blueswir1
            }
2528 0f8a249a blueswir1
            return;
2529 0f8a249a blueswir1
        }
2530 3475187d bellard
    case 0x50: // I-MMU regs
2531 0f8a249a blueswir1
        {
2532 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
2533 0f8a249a blueswir1
            uint64_t oldreg;
2534 3b46e624 ths
2535 0f8a249a blueswir1
            oldreg = env->immuregs[reg];
2536 3475187d bellard
            switch(reg) {
2537 3475187d bellard
            case 0: // RO
2538 3475187d bellard
                return;
2539 3475187d bellard
            case 1: // Not in I-MMU
2540 3475187d bellard
            case 2:
2541 3475187d bellard
                return;
2542 3475187d bellard
            case 3: // SFSR
2543 1a2fb1c0 blueswir1
                if ((val & 1) == 0)
2544 1a2fb1c0 blueswir1
                    val = 0; // Clear SFSR
2545 6e8e7d4c Igor Kovalenko
                env->immu.sfsr = val;
2546 3475187d bellard
                break;
2547 6e8e7d4c Igor Kovalenko
            case 4: // RO
2548 6e8e7d4c Igor Kovalenko
                return;
2549 3475187d bellard
            case 5: // TSB access
2550 6e8e7d4c Igor Kovalenko
                DPRINTF_MMU("immu TSB write: 0x%016" PRIx64 " -> 0x%016"
2551 6e8e7d4c Igor Kovalenko
                            PRIx64 "\n", env->immu.tsb, val);
2552 6e8e7d4c Igor Kovalenko
                env->immu.tsb = val;
2553 6e8e7d4c Igor Kovalenko
                break;
2554 3475187d bellard
            case 6: // Tag access
2555 6e8e7d4c Igor Kovalenko
                env->immu.tag_access = val;
2556 6e8e7d4c Igor Kovalenko
                break;
2557 6e8e7d4c Igor Kovalenko
            case 7:
2558 6e8e7d4c Igor Kovalenko
            case 8:
2559 6e8e7d4c Igor Kovalenko
                return;
2560 3475187d bellard
            default:
2561 3475187d bellard
                break;
2562 3475187d bellard
            }
2563 6e8e7d4c Igor Kovalenko
2564 3475187d bellard
            if (oldreg != env->immuregs[reg]) {
2565 6e8e7d4c Igor Kovalenko
                DPRINTF_MMU("immu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
2566 77f193da blueswir1
                            PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
2567 3475187d bellard
            }
2568 952a328f blueswir1
#ifdef DEBUG_MMU
2569 0f8a249a blueswir1
            dump_mmu(env);
2570 3475187d bellard
#endif
2571 0f8a249a blueswir1
            return;
2572 0f8a249a blueswir1
        }
2573 3475187d bellard
    case 0x54: // I-MMU data in
2574 f707726e Igor Kovalenko
        replace_tlb_1bit_lru(env->itlb, env->immu.tag_access, val, "immu", env);
2575 f707726e Igor Kovalenko
        return;
2576 3475187d bellard
    case 0x55: // I-MMU data access
2577 0f8a249a blueswir1
        {
2578 cc6747f4 blueswir1
            // TODO: auto demap
2579 cc6747f4 blueswir1
2580 1a2fb1c0 blueswir1
            unsigned int i = (addr >> 3) & 0x3f;
2581 3475187d bellard
2582 f707726e Igor Kovalenko
            replace_tlb_entry(&env->itlb[i], env->immu.tag_access, val, env);
2583 6e8e7d4c Igor Kovalenko
2584 6e8e7d4c Igor Kovalenko
#ifdef DEBUG_MMU
2585 f707726e Igor Kovalenko
            DPRINTF_MMU("immu data access replaced entry [%i]\n", i);
2586 6e8e7d4c Igor Kovalenko
            dump_mmu(env);
2587 6e8e7d4c Igor Kovalenko
#endif
2588 0f8a249a blueswir1
            return;
2589 0f8a249a blueswir1
        }
2590 3475187d bellard
    case 0x57: // I-MMU demap
2591 f707726e Igor Kovalenko
        demap_tlb(env->itlb, val, "immu", env);
2592 0f8a249a blueswir1
        return;
2593 3475187d bellard
    case 0x58: // D-MMU regs
2594 0f8a249a blueswir1
        {
2595 1a2fb1c0 blueswir1
            int reg = (addr >> 3) & 0xf;
2596 0f8a249a blueswir1
            uint64_t oldreg;
2597 3b46e624 ths
2598 0f8a249a blueswir1
            oldreg = env->dmmuregs[reg];
2599 3475187d bellard
            switch(reg) {
2600 3475187d bellard
            case 0: // RO
2601 3475187d bellard
            case 4:
2602 3475187d bellard
                return;
2603 3475187d bellard
            case 3: // SFSR
2604 1a2fb1c0 blueswir1
                if ((val & 1) == 0) {
2605 1a2fb1c0 blueswir1
                    val = 0; // Clear SFSR, Fault address
2606 6e8e7d4c Igor Kovalenko
                    env->dmmu.sfar = 0;
2607 0f8a249a blueswir1
                }
2608 6e8e7d4c Igor Kovalenko
                env->dmmu.sfsr = val;
2609 3475187d bellard
                break;
2610 3475187d bellard
            case 1: // Primary context
2611 6e8e7d4c Igor Kovalenko
                env->dmmu.mmu_primary_context = val;
2612 6e8e7d4c Igor Kovalenko
                break;
2613 3475187d bellard
            case 2: // Secondary context
2614 6e8e7d4c Igor Kovalenko
                env->dmmu.mmu_secondary_context = val;
2615 6e8e7d4c Igor Kovalenko
                break;
2616 3475187d bellard
            case 5: // TSB access
2617 6e8e7d4c Igor Kovalenko
                DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64 " -> 0x%016"
2618 6e8e7d4c Igor Kovalenko
                            PRIx64 "\n", env->dmmu.tsb, val);
2619 6e8e7d4c Igor Kovalenko
                env->dmmu.tsb = val;
2620 6e8e7d4c Igor Kovalenko
                break;
2621 3475187d bellard
            case 6: // Tag access
2622 6e8e7d4c Igor Kovalenko
                env->dmmu.tag_access = val;
2623 6e8e7d4c Igor Kovalenko
                break;
2624 3475187d bellard
            case 7: // Virtual Watchpoint
2625 3475187d bellard
            case 8: // Physical Watchpoint
2626 3475187d bellard
            default:
2627 6e8e7d4c Igor Kovalenko
                env->dmmuregs[reg] = val;
2628 3475187d bellard
                break;
2629 3475187d bellard
            }
2630 6e8e7d4c Igor Kovalenko
2631 3475187d bellard
            if (oldreg != env->dmmuregs[reg]) {
2632 6e8e7d4c Igor Kovalenko
                DPRINTF_MMU("dmmu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
2633 77f193da blueswir1
                            PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
2634 3475187d bellard
            }
2635 952a328f blueswir1
#ifdef DEBUG_MMU
2636 0f8a249a blueswir1
            dump_mmu(env);
2637 3475187d bellard
#endif
2638 0f8a249a blueswir1
            return;
2639 0f8a249a blueswir1
        }
2640 3475187d bellard
    case 0x5c: // D-MMU data in
2641 f707726e Igor Kovalenko
        replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access, val, "dmmu", env);
2642 f707726e Igor Kovalenko
        return;
2643 3475187d bellard
    case 0x5d: // D-MMU data access
2644 0f8a249a blueswir1
        {
2645 1a2fb1c0 blueswir1
            unsigned int i = (addr >> 3) & 0x3f;
2646 3475187d bellard
2647 f707726e Igor Kovalenko
            replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access, val, env);
2648 f707726e Igor Kovalenko
2649 6e8e7d4c Igor Kovalenko
#ifdef DEBUG_MMU
2650 f707726e Igor Kovalenko
            DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i);
2651 6e8e7d4c Igor Kovalenko
            dump_mmu(env);
2652 6e8e7d4c Igor Kovalenko
#endif
2653 0f8a249a blueswir1
            return;
2654 0f8a249a blueswir1
        }
2655 3475187d bellard
    case 0x5f: // D-MMU demap
2656 f707726e Igor Kovalenko
        demap_tlb(env->dtlb, val, "dmmu", env);
2657 cc6747f4 blueswir1
        return;
2658 83469015 bellard
    case 0x49: // Interrupt data receive
2659 0f8a249a blueswir1
        // XXX
2660 0f8a249a blueswir1
        return;
2661 f7350b47 blueswir1
    case 0x46: // D-cache data
2662 f7350b47 blueswir1
    case 0x47: // D-cache tag access
2663 a5a52cf2 blueswir1
    case 0x4b: // E-cache error enable
2664 a5a52cf2 blueswir1
    case 0x4c: // E-cache asynchronous fault status
2665 a5a52cf2 blueswir1
    case 0x4d: // E-cache asynchronous fault address
2666 f7350b47 blueswir1
    case 0x4e: // E-cache tag data
2667 f7350b47 blueswir1
    case 0x66: // I-cache instruction access
2668 f7350b47 blueswir1
    case 0x67: // I-cache tag access
2669 f7350b47 blueswir1
    case 0x6e: // I-cache predecode
2670 f7350b47 blueswir1
    case 0x6f: // I-cache LRU etc.
2671 f7350b47 blueswir1
    case 0x76: // E-cache tag
2672 f7350b47 blueswir1
    case 0x7e: // E-cache tag
2673 f7350b47 blueswir1
        return;
2674 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer, RO
2675 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer, RO
2676 3475187d bellard
    case 0x56: // I-MMU tag read, RO
2677 3475187d bellard
    case 0x59: // D-MMU 8k TSB pointer, RO
2678 3475187d bellard
    case 0x5a: // D-MMU 64k TSB pointer, RO
2679 3475187d bellard
    case 0x5b: // D-MMU data pointer, RO
2680 3475187d bellard
    case 0x5e: // D-MMU tag read, RO
2681 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
2682 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
2683 83469015 bellard
    case 0x82: // Primary no-fault, RO
2684 83469015 bellard
    case 0x83: // Secondary no-fault, RO
2685 83469015 bellard
    case 0x8a: // Primary no-fault LE, RO
2686 83469015 bellard
    case 0x8b: // Secondary no-fault LE, RO
2687 3475187d bellard
    default:
2688 e18231a3 blueswir1
        do_unassigned_access(addr, 1, 0, 1, size);
2689 0f8a249a blueswir1
        return;
2690 3475187d bellard
    }
2691 3475187d bellard
}
2692 81ad8ba2 blueswir1
#endif /* CONFIG_USER_ONLY */
2693 3391c818 blueswir1
2694 db166940 blueswir1
void helper_ldda_asi(target_ulong addr, int asi, int rd)
2695 db166940 blueswir1
{
2696 db166940 blueswir1
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2697 5578ceab blueswir1
        || ((env->def->features & CPU_FEATURE_HYPV)
2698 5578ceab blueswir1
            && asi >= 0x30 && asi < 0x80
2699 fb79ceb9 blueswir1
            && !(env->hpstate & HS_PRIV)))
2700 db166940 blueswir1
        raise_exception(TT_PRIV_ACT);
2701 db166940 blueswir1
2702 db166940 blueswir1
    switch (asi) {
2703 db166940 blueswir1
    case 0x24: // Nucleus quad LDD 128 bit atomic
2704 db166940 blueswir1
    case 0x2c: // Nucleus quad LDD 128 bit atomic LE
2705 db166940 blueswir1
        helper_check_align(addr, 0xf);
2706 db166940 blueswir1
        if (rd == 0) {
2707 db166940 blueswir1
            env->gregs[1] = ldq_kernel(addr + 8);
2708 db166940 blueswir1
            if (asi == 0x2c)
2709 db166940 blueswir1
                bswap64s(&env->gregs[1]);
2710 db166940 blueswir1
        } else if (rd < 8) {
2711 db166940 blueswir1
            env->gregs[rd] = ldq_kernel(addr);
2712 db166940 blueswir1
            env->gregs[rd + 1] = ldq_kernel(addr + 8);
2713 db166940 blueswir1
            if (asi == 0x2c) {
2714 db166940 blueswir1
                bswap64s(&env->gregs[rd]);
2715 db166940 blueswir1
                bswap64s(&env->gregs[rd + 1]);
2716 db166940 blueswir1
            }
2717 db166940 blueswir1
        } else {
2718 db166940 blueswir1
            env->regwptr[rd] = ldq_kernel(addr);
2719 db166940 blueswir1
            env->regwptr[rd + 1] = ldq_kernel(addr + 8);
2720 db166940 blueswir1
            if (asi == 0x2c) {
2721 db166940 blueswir1
                bswap64s(&env->regwptr[rd]);
2722 db166940 blueswir1
                bswap64s(&env->regwptr[rd + 1]);
2723 db166940 blueswir1
            }
2724 db166940 blueswir1
        }
2725 db166940 blueswir1
        break;
2726 db166940 blueswir1
    default:
2727 db166940 blueswir1
        helper_check_align(addr, 0x3);
2728 db166940 blueswir1
        if (rd == 0)
2729 db166940 blueswir1
            env->gregs[1] = helper_ld_asi(addr + 4, asi, 4, 0);
2730 db166940 blueswir1
        else if (rd < 8) {
2731 db166940 blueswir1
            env->gregs[rd] = helper_ld_asi(addr, asi, 4, 0);
2732 db166940 blueswir1
            env->gregs[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2733 db166940 blueswir1
        } else {
2734 db166940 blueswir1
            env->regwptr[rd] = helper_ld_asi(addr, asi, 4, 0);
2735 db166940 blueswir1
            env->regwptr[rd + 1] = helper_ld_asi(addr + 4, asi, 4, 0);
2736 db166940 blueswir1
        }
2737 db166940 blueswir1
        break;
2738 db166940 blueswir1
    }
2739 db166940 blueswir1
}
2740 db166940 blueswir1
2741 1a2fb1c0 blueswir1
void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
2742 3391c818 blueswir1
{
2743 3391c818 blueswir1
    unsigned int i;
2744 1a2fb1c0 blueswir1
    target_ulong val;
2745 3391c818 blueswir1
2746 c2bc0e38 blueswir1
    helper_check_align(addr, 3);
2747 3391c818 blueswir1
    switch (asi) {
2748 3391c818 blueswir1
    case 0xf0: // Block load primary
2749 3391c818 blueswir1
    case 0xf1: // Block load secondary
2750 3391c818 blueswir1
    case 0xf8: // Block load primary LE
2751 3391c818 blueswir1
    case 0xf9: // Block load secondary LE
2752 51996525 blueswir1
        if (rd & 7) {
2753 51996525 blueswir1
            raise_exception(TT_ILL_INSN);
2754 51996525 blueswir1
            return;
2755 51996525 blueswir1
        }
2756 c2bc0e38 blueswir1
        helper_check_align(addr, 0x3f);
2757 51996525 blueswir1
        for (i = 0; i < 16; i++) {
2758 77f193da blueswir1
            *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4,
2759 77f193da blueswir1
                                                         0);
2760 1a2fb1c0 blueswir1
            addr += 4;
2761 3391c818 blueswir1
        }
2762 3391c818 blueswir1
2763 3391c818 blueswir1
        return;
2764 3391c818 blueswir1
    default:
2765 3391c818 blueswir1
        break;
2766 3391c818 blueswir1
    }
2767 3391c818 blueswir1
2768 1a2fb1c0 blueswir1
    val = helper_ld_asi(addr, asi, size, 0);
2769 3391c818 blueswir1
    switch(size) {
2770 3391c818 blueswir1
    default:
2771 3391c818 blueswir1
    case 4:
2772 714547bb blueswir1
        *((uint32_t *)&env->fpr[rd]) = val;
2773 3391c818 blueswir1
        break;
2774 3391c818 blueswir1
    case 8:
2775 1a2fb1c0 blueswir1
        *((int64_t *)&DT0) = val;
2776 3391c818 blueswir1
        break;
2777 1f587329 blueswir1
    case 16:
2778 1f587329 blueswir1
        // XXX
2779 1f587329 blueswir1
        break;
2780 3391c818 blueswir1
    }
2781 3391c818 blueswir1
}
2782 3391c818 blueswir1
2783 1a2fb1c0 blueswir1
void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
2784 3391c818 blueswir1
{
2785 3391c818 blueswir1
    unsigned int i;
2786 1a2fb1c0 blueswir1
    target_ulong val = 0;
2787 3391c818 blueswir1
2788 c2bc0e38 blueswir1
    helper_check_align(addr, 3);
2789 3391c818 blueswir1
    switch (asi) {
2790 c99657d3 blueswir1
    case 0xe0: // UA2007 Block commit store primary (cache flush)
2791 c99657d3 blueswir1
    case 0xe1: // UA2007 Block commit store secondary (cache flush)
2792 3391c818 blueswir1
    case 0xf0: // Block store primary
2793 3391c818 blueswir1
    case 0xf1: // Block store secondary
2794 3391c818 blueswir1
    case 0xf8: // Block store primary LE
2795 3391c818 blueswir1
    case 0xf9: // Block store secondary LE
2796 51996525 blueswir1
        if (rd & 7) {
2797 51996525 blueswir1
            raise_exception(TT_ILL_INSN);
2798 51996525 blueswir1
            return;
2799 51996525 blueswir1
        }
2800 c2bc0e38 blueswir1
        helper_check_align(addr, 0x3f);
2801 51996525 blueswir1
        for (i = 0; i < 16; i++) {
2802 1a2fb1c0 blueswir1
            val = *(uint32_t *)&env->fpr[rd++];
2803 1a2fb1c0 blueswir1
            helper_st_asi(addr, val, asi & 0x8f, 4);
2804 1a2fb1c0 blueswir1
            addr += 4;
2805 3391c818 blueswir1
        }
2806 3391c818 blueswir1
2807 3391c818 blueswir1
        return;
2808 3391c818 blueswir1
    default:
2809 3391c818 blueswir1
        break;
2810 3391c818 blueswir1
    }
2811 3391c818 blueswir1
2812 3391c818 blueswir1
    switch(size) {
2813 3391c818 blueswir1
    default:
2814 3391c818 blueswir1
    case 4:
2815 714547bb blueswir1
        val = *((uint32_t *)&env->fpr[rd]);
2816 3391c818 blueswir1
        break;
2817 3391c818 blueswir1
    case 8:
2818 1a2fb1c0 blueswir1
        val = *((int64_t *)&DT0);
2819 3391c818 blueswir1
        break;
2820 1f587329 blueswir1
    case 16:
2821 1f587329 blueswir1
        // XXX
2822 1f587329 blueswir1
        break;
2823 3391c818 blueswir1
    }
2824 1a2fb1c0 blueswir1
    helper_st_asi(addr, val, asi, size);
2825 1a2fb1c0 blueswir1
}
2826 1a2fb1c0 blueswir1
2827 1a2fb1c0 blueswir1
target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
2828 1a2fb1c0 blueswir1
                            target_ulong val2, uint32_t asi)
2829 1a2fb1c0 blueswir1
{
2830 1a2fb1c0 blueswir1
    target_ulong ret;
2831 1a2fb1c0 blueswir1
2832 1121f879 blueswir1
    val2 &= 0xffffffffUL;
2833 1a2fb1c0 blueswir1
    ret = helper_ld_asi(addr, asi, 4, 0);
2834 1a2fb1c0 blueswir1
    ret &= 0xffffffffUL;
2835 1121f879 blueswir1
    if (val2 == ret)
2836 1121f879 blueswir1
        helper_st_asi(addr, val1 & 0xffffffffUL, asi, 4);
2837 1a2fb1c0 blueswir1
    return ret;
2838 3391c818 blueswir1
}
2839 3391c818 blueswir1
2840 1a2fb1c0 blueswir1
target_ulong helper_casx_asi(target_ulong addr, target_ulong val1,
2841 1a2fb1c0 blueswir1
                             target_ulong val2, uint32_t asi)
2842 1a2fb1c0 blueswir1
{
2843 1a2fb1c0 blueswir1
    target_ulong ret;
2844 1a2fb1c0 blueswir1
2845 1a2fb1c0 blueswir1
    ret = helper_ld_asi(addr, asi, 8, 0);
2846 1121f879 blueswir1
    if (val2 == ret)
2847 1121f879 blueswir1
        helper_st_asi(addr, val1, asi, 8);
2848 1a2fb1c0 blueswir1
    return ret;
2849 1a2fb1c0 blueswir1
}
2850 81ad8ba2 blueswir1
#endif /* TARGET_SPARC64 */
2851 3475187d bellard
2852 3475187d bellard
#ifndef TARGET_SPARC64
2853 1a2fb1c0 blueswir1
void helper_rett(void)
2854 e8af50a3 bellard
{
2855 af7bf89b bellard
    unsigned int cwp;
2856 af7bf89b bellard
2857 d4218d99 blueswir1
    if (env->psret == 1)
2858 d4218d99 blueswir1
        raise_exception(TT_ILL_INSN);
2859 d4218d99 blueswir1
2860 e8af50a3 bellard
    env->psret = 1;
2861 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1) ;
2862 e8af50a3 bellard
    if (env->wim & (1 << cwp)) {
2863 e8af50a3 bellard
        raise_exception(TT_WIN_UNF);
2864 e8af50a3 bellard
    }
2865 e8af50a3 bellard
    set_cwp(cwp);
2866 e8af50a3 bellard
    env->psrs = env->psrps;
2867 e8af50a3 bellard
}
2868 3475187d bellard
#endif
2869 e8af50a3 bellard
2870 3b89f26c blueswir1
target_ulong helper_udiv(target_ulong a, target_ulong b)
2871 3b89f26c blueswir1
{
2872 3b89f26c blueswir1
    uint64_t x0;
2873 3b89f26c blueswir1
    uint32_t x1;
2874 3b89f26c blueswir1
2875 7621a90d blueswir1
    x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
2876 3b89f26c blueswir1
    x1 = b;
2877 3b89f26c blueswir1
2878 3b89f26c blueswir1
    if (x1 == 0) {
2879 3b89f26c blueswir1
        raise_exception(TT_DIV_ZERO);
2880 3b89f26c blueswir1
    }
2881 3b89f26c blueswir1
2882 3b89f26c blueswir1
    x0 = x0 / x1;
2883 3b89f26c blueswir1
    if (x0 > 0xffffffff) {
2884 3b89f26c blueswir1
        env->cc_src2 = 1;
2885 3b89f26c blueswir1
        return 0xffffffff;
2886 3b89f26c blueswir1
    } else {
2887 3b89f26c blueswir1
        env->cc_src2 = 0;
2888 3b89f26c blueswir1
        return x0;
2889 3b89f26c blueswir1
    }
2890 3b89f26c blueswir1
}
2891 3b89f26c blueswir1
2892 3b89f26c blueswir1
target_ulong helper_sdiv(target_ulong a, target_ulong b)
2893 3b89f26c blueswir1
{
2894 3b89f26c blueswir1
    int64_t x0;
2895 3b89f26c blueswir1
    int32_t x1;
2896 3b89f26c blueswir1
2897 7621a90d blueswir1
    x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32);
2898 3b89f26c blueswir1
    x1 = b;
2899 3b89f26c blueswir1
2900 3b89f26c blueswir1
    if (x1 == 0) {
2901 3b89f26c blueswir1
        raise_exception(TT_DIV_ZERO);
2902 3b89f26c blueswir1
    }
2903 3b89f26c blueswir1
2904 3b89f26c blueswir1
    x0 = x0 / x1;
2905 3b89f26c blueswir1
    if ((int32_t) x0 != x0) {
2906 3b89f26c blueswir1
        env->cc_src2 = 1;
2907 3b89f26c blueswir1
        return x0 < 0? 0x80000000: 0x7fffffff;
2908 3b89f26c blueswir1
    } else {
2909 3b89f26c blueswir1
        env->cc_src2 = 0;
2910 3b89f26c blueswir1
        return x0;
2911 3b89f26c blueswir1
    }
2912 3b89f26c blueswir1
}
2913 3b89f26c blueswir1
2914 7fa76c0b blueswir1
void helper_stdf(target_ulong addr, int mem_idx)
2915 7fa76c0b blueswir1
{
2916 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2917 7fa76c0b blueswir1
#if !defined(CONFIG_USER_ONLY)
2918 7fa76c0b blueswir1
    switch (mem_idx) {
2919 7fa76c0b blueswir1
    case 0:
2920 c2bc0e38 blueswir1
        stfq_user(addr, DT0);
2921 7fa76c0b blueswir1
        break;
2922 7fa76c0b blueswir1
    case 1:
2923 c2bc0e38 blueswir1
        stfq_kernel(addr, DT0);
2924 7fa76c0b blueswir1
        break;
2925 7fa76c0b blueswir1
#ifdef TARGET_SPARC64
2926 7fa76c0b blueswir1
    case 2:
2927 c2bc0e38 blueswir1
        stfq_hypv(addr, DT0);
2928 7fa76c0b blueswir1
        break;
2929 7fa76c0b blueswir1
#endif
2930 7fa76c0b blueswir1
    default:
2931 7fa76c0b blueswir1
        break;
2932 7fa76c0b blueswir1
    }
2933 7fa76c0b blueswir1
#else
2934 2cade6a3 blueswir1
    address_mask(env, &addr);
2935 c2bc0e38 blueswir1
    stfq_raw(addr, DT0);
2936 7fa76c0b blueswir1
#endif
2937 7fa76c0b blueswir1
}
2938 7fa76c0b blueswir1
2939 7fa76c0b blueswir1
void helper_lddf(target_ulong addr, int mem_idx)
2940 7fa76c0b blueswir1
{
2941 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2942 7fa76c0b blueswir1
#if !defined(CONFIG_USER_ONLY)
2943 7fa76c0b blueswir1
    switch (mem_idx) {
2944 7fa76c0b blueswir1
    case 0:
2945 c2bc0e38 blueswir1
        DT0 = ldfq_user(addr);
2946 7fa76c0b blueswir1
        break;
2947 7fa76c0b blueswir1
    case 1:
2948 c2bc0e38 blueswir1
        DT0 = ldfq_kernel(addr);
2949 7fa76c0b blueswir1
        break;
2950 7fa76c0b blueswir1
#ifdef TARGET_SPARC64
2951 7fa76c0b blueswir1
    case 2:
2952 c2bc0e38 blueswir1
        DT0 = ldfq_hypv(addr);
2953 7fa76c0b blueswir1
        break;
2954 7fa76c0b blueswir1
#endif
2955 7fa76c0b blueswir1
    default:
2956 7fa76c0b blueswir1
        break;
2957 7fa76c0b blueswir1
    }
2958 7fa76c0b blueswir1
#else
2959 2cade6a3 blueswir1
    address_mask(env, &addr);
2960 c2bc0e38 blueswir1
    DT0 = ldfq_raw(addr);
2961 7fa76c0b blueswir1
#endif
2962 7fa76c0b blueswir1
}
2963 7fa76c0b blueswir1
2964 64a88d5d blueswir1
void helper_ldqf(target_ulong addr, int mem_idx)
2965 7fa76c0b blueswir1
{
2966 7fa76c0b blueswir1
    // XXX add 128 bit load
2967 7fa76c0b blueswir1
    CPU_QuadU u;
2968 7fa76c0b blueswir1
2969 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
2970 64a88d5d blueswir1
#if !defined(CONFIG_USER_ONLY)
2971 64a88d5d blueswir1
    switch (mem_idx) {
2972 64a88d5d blueswir1
    case 0:
2973 c2bc0e38 blueswir1
        u.ll.upper = ldq_user(addr);
2974 c2bc0e38 blueswir1
        u.ll.lower = ldq_user(addr + 8);
2975 64a88d5d blueswir1
        QT0 = u.q;
2976 64a88d5d blueswir1
        break;
2977 64a88d5d blueswir1
    case 1:
2978 c2bc0e38 blueswir1
        u.ll.upper = ldq_kernel(addr);
2979 c2bc0e38 blueswir1
        u.ll.lower = ldq_kernel(addr + 8);
2980 64a88d5d blueswir1
        QT0 = u.q;
2981 64a88d5d blueswir1
        break;
2982 64a88d5d blueswir1
#ifdef TARGET_SPARC64
2983 64a88d5d blueswir1
    case 2:
2984 c2bc0e38 blueswir1
        u.ll.upper = ldq_hypv(addr);
2985 c2bc0e38 blueswir1
        u.ll.lower = ldq_hypv(addr + 8);
2986 64a88d5d blueswir1
        QT0 = u.q;
2987 64a88d5d blueswir1
        break;
2988 64a88d5d blueswir1
#endif
2989 64a88d5d blueswir1
    default:
2990 64a88d5d blueswir1
        break;
2991 64a88d5d blueswir1
    }
2992 64a88d5d blueswir1
#else
2993 2cade6a3 blueswir1
    address_mask(env, &addr);
2994 c2bc0e38 blueswir1
    u.ll.upper = ldq_raw(addr);
2995 c2bc0e38 blueswir1
    u.ll.lower = ldq_raw((addr + 8) & 0xffffffffULL);
2996 7fa76c0b blueswir1
    QT0 = u.q;
2997 64a88d5d blueswir1
#endif
2998 7fa76c0b blueswir1
}
2999 7fa76c0b blueswir1
3000 64a88d5d blueswir1
void helper_stqf(target_ulong addr, int mem_idx)
3001 7fa76c0b blueswir1
{
3002 7fa76c0b blueswir1
    // XXX add 128 bit store
3003 7fa76c0b blueswir1
    CPU_QuadU u;
3004 7fa76c0b blueswir1
3005 c2bc0e38 blueswir1
    helper_check_align(addr, 7);
3006 64a88d5d blueswir1
#if !defined(CONFIG_USER_ONLY)
3007 64a88d5d blueswir1
    switch (mem_idx) {
3008 64a88d5d blueswir1
    case 0:
3009 64a88d5d blueswir1
        u.q = QT0;
3010 c2bc0e38 blueswir1
        stq_user(addr, u.ll.upper);
3011 c2bc0e38 blueswir1
        stq_user(addr + 8, u.ll.lower);
3012 64a88d5d blueswir1
        break;
3013 64a88d5d blueswir1
    case 1:
3014 64a88d5d blueswir1
        u.q = QT0;
3015 c2bc0e38 blueswir1
        stq_kernel(addr, u.ll.upper);
3016 c2bc0e38 blueswir1
        stq_kernel(addr + 8, u.ll.lower);
3017 64a88d5d blueswir1
        break;
3018 64a88d5d blueswir1
#ifdef TARGET_SPARC64
3019 64a88d5d blueswir1
    case 2:
3020 64a88d5d blueswir1
        u.q = QT0;
3021 c2bc0e38 blueswir1
        stq_hypv(addr, u.ll.upper);
3022 c2bc0e38 blueswir1
        stq_hypv(addr + 8, u.ll.lower);
3023 64a88d5d blueswir1
        break;
3024 64a88d5d blueswir1
#endif
3025 64a88d5d blueswir1
    default:
3026 64a88d5d blueswir1
        break;
3027 64a88d5d blueswir1
    }
3028 64a88d5d blueswir1
#else
3029 7fa76c0b blueswir1
    u.q = QT0;
3030 2cade6a3 blueswir1
    address_mask(env, &addr);
3031 c2bc0e38 blueswir1
    stq_raw(addr, u.ll.upper);
3032 c2bc0e38 blueswir1
    stq_raw((addr + 8) & 0xffffffffULL, u.ll.lower);
3033 7fa76c0b blueswir1
#endif
3034 64a88d5d blueswir1
}
3035 7fa76c0b blueswir1
3036 3a3b925d blueswir1
static inline void set_fsr(void)
3037 e8af50a3 bellard
{
3038 7a0e1f41 bellard
    int rnd_mode;
3039 bb5529bb blueswir1
3040 e8af50a3 bellard
    switch (env->fsr & FSR_RD_MASK) {
3041 e8af50a3 bellard
    case FSR_RD_NEAREST:
3042 7a0e1f41 bellard
        rnd_mode = float_round_nearest_even;
3043 0f8a249a blueswir1
        break;
3044 ed910241 bellard
    default:
3045 e8af50a3 bellard
    case FSR_RD_ZERO:
3046 7a0e1f41 bellard
        rnd_mode = float_round_to_zero;
3047 0f8a249a blueswir1
        break;
3048 e8af50a3 bellard
    case FSR_RD_POS:
3049 7a0e1f41 bellard
        rnd_mode = float_round_up;
3050 0f8a249a blueswir1
        break;
3051 e8af50a3 bellard
    case FSR_RD_NEG:
3052 7a0e1f41 bellard
        rnd_mode = float_round_down;
3053 0f8a249a blueswir1
        break;
3054 e8af50a3 bellard
    }
3055 7a0e1f41 bellard
    set_float_rounding_mode(rnd_mode, &env->fp_status);
3056 e8af50a3 bellard
}
3057 e80cfcfc bellard
3058 3a3b925d blueswir1
void helper_ldfsr(uint32_t new_fsr)
3059 bb5529bb blueswir1
{
3060 3a3b925d blueswir1
    env->fsr = (new_fsr & FSR_LDFSR_MASK) | (env->fsr & FSR_LDFSR_OLDMASK);
3061 3a3b925d blueswir1
    set_fsr();
3062 bb5529bb blueswir1
}
3063 bb5529bb blueswir1
3064 3a3b925d blueswir1
#ifdef TARGET_SPARC64
3065 3a3b925d blueswir1
void helper_ldxfsr(uint64_t new_fsr)
3066 3a3b925d blueswir1
{
3067 3a3b925d blueswir1
    env->fsr = (new_fsr & FSR_LDXFSR_MASK) | (env->fsr & FSR_LDXFSR_OLDMASK);
3068 3a3b925d blueswir1
    set_fsr();
3069 3a3b925d blueswir1
}
3070 3a3b925d blueswir1
#endif
3071 3a3b925d blueswir1
3072 bb5529bb blueswir1
void helper_debug(void)
3073 e80cfcfc bellard
{
3074 e80cfcfc bellard
    env->exception_index = EXCP_DEBUG;
3075 e80cfcfc bellard
    cpu_loop_exit();
3076 e80cfcfc bellard
}
3077 af7bf89b bellard
3078 3475187d bellard
#ifndef TARGET_SPARC64
3079 72a9747b blueswir1
/* XXX: use another pointer for %iN registers to avoid slow wrapping
3080 72a9747b blueswir1
   handling ? */
3081 72a9747b blueswir1
void helper_save(void)
3082 72a9747b blueswir1
{
3083 72a9747b blueswir1
    uint32_t cwp;
3084 72a9747b blueswir1
3085 1a14026e blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
3086 72a9747b blueswir1
    if (env->wim & (1 << cwp)) {
3087 72a9747b blueswir1
        raise_exception(TT_WIN_OVF);
3088 72a9747b blueswir1
    }
3089 72a9747b blueswir1
    set_cwp(cwp);
3090 72a9747b blueswir1
}
3091 72a9747b blueswir1
3092 72a9747b blueswir1
void helper_restore(void)
3093 72a9747b blueswir1
{
3094 72a9747b blueswir1
    uint32_t cwp;
3095 72a9747b blueswir1
3096 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1);
3097 72a9747b blueswir1
    if (env->wim & (1 << cwp)) {
3098 72a9747b blueswir1
        raise_exception(TT_WIN_UNF);
3099 72a9747b blueswir1
    }
3100 72a9747b blueswir1
    set_cwp(cwp);
3101 72a9747b blueswir1
}
3102 72a9747b blueswir1
3103 1a2fb1c0 blueswir1
void helper_wrpsr(target_ulong new_psr)
3104 af7bf89b bellard
{
3105 1a14026e blueswir1
    if ((new_psr & PSR_CWP) >= env->nwindows)
3106 d4218d99 blueswir1
        raise_exception(TT_ILL_INSN);
3107 d4218d99 blueswir1
    else
3108 1a2fb1c0 blueswir1
        PUT_PSR(env, new_psr);
3109 af7bf89b bellard
}
3110 af7bf89b bellard
3111 1a2fb1c0 blueswir1
target_ulong helper_rdpsr(void)
3112 af7bf89b bellard
{
3113 1a2fb1c0 blueswir1
    return GET_PSR(env);
3114 af7bf89b bellard
}
3115 3475187d bellard
3116 3475187d bellard
#else
3117 72a9747b blueswir1
/* XXX: use another pointer for %iN registers to avoid slow wrapping
3118 72a9747b blueswir1
   handling ? */
3119 72a9747b blueswir1
void helper_save(void)
3120 72a9747b blueswir1
{
3121 72a9747b blueswir1
    uint32_t cwp;
3122 72a9747b blueswir1
3123 1a14026e blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
3124 72a9747b blueswir1
    if (env->cansave == 0) {
3125 72a9747b blueswir1
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
3126 72a9747b blueswir1
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
3127 72a9747b blueswir1
                                    ((env->wstate & 0x7) << 2)));
3128 72a9747b blueswir1
    } else {
3129 72a9747b blueswir1
        if (env->cleanwin - env->canrestore == 0) {
3130 72a9747b blueswir1
            // XXX Clean windows without trap
3131 72a9747b blueswir1
            raise_exception(TT_CLRWIN);
3132 72a9747b blueswir1
        } else {
3133 72a9747b blueswir1
            env->cansave--;
3134 72a9747b blueswir1
            env->canrestore++;
3135 72a9747b blueswir1
            set_cwp(cwp);
3136 72a9747b blueswir1
        }
3137 72a9747b blueswir1
    }
3138 72a9747b blueswir1
}
3139 72a9747b blueswir1
3140 72a9747b blueswir1
void helper_restore(void)
3141 72a9747b blueswir1
{
3142 72a9747b blueswir1
    uint32_t cwp;
3143 72a9747b blueswir1
3144 1a14026e blueswir1
    cwp = cpu_cwp_inc(env, env->cwp + 1);
3145 72a9747b blueswir1
    if (env->canrestore == 0) {
3146 72a9747b blueswir1
        raise_exception(TT_FILL | (env->otherwin != 0 ?
3147 72a9747b blueswir1
                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
3148 72a9747b blueswir1
                                   ((env->wstate & 0x7) << 2)));
3149 72a9747b blueswir1
    } else {
3150 72a9747b blueswir1
        env->cansave++;
3151 72a9747b blueswir1
        env->canrestore--;
3152 72a9747b blueswir1
        set_cwp(cwp);
3153 72a9747b blueswir1
    }
3154 72a9747b blueswir1
}
3155 72a9747b blueswir1
3156 72a9747b blueswir1
void helper_flushw(void)
3157 72a9747b blueswir1
{
3158 1a14026e blueswir1
    if (env->cansave != env->nwindows - 2) {
3159 72a9747b blueswir1
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
3160 72a9747b blueswir1
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
3161 72a9747b blueswir1
                                    ((env->wstate & 0x7) << 2)));
3162 72a9747b blueswir1
    }
3163 72a9747b blueswir1
}
3164 72a9747b blueswir1
3165 72a9747b blueswir1
void helper_saved(void)
3166 72a9747b blueswir1
{
3167 72a9747b blueswir1
    env->cansave++;
3168 72a9747b blueswir1
    if (env->otherwin == 0)
3169 72a9747b blueswir1
        env->canrestore--;
3170 72a9747b blueswir1
    else
3171 72a9747b blueswir1
        env->otherwin--;
3172 72a9747b blueswir1
}
3173 72a9747b blueswir1
3174 72a9747b blueswir1
void helper_restored(void)
3175 72a9747b blueswir1
{
3176 72a9747b blueswir1
    env->canrestore++;
3177 1a14026e blueswir1
    if (env->cleanwin < env->nwindows - 1)
3178 72a9747b blueswir1
        env->cleanwin++;
3179 72a9747b blueswir1
    if (env->otherwin == 0)
3180 72a9747b blueswir1
        env->cansave--;
3181 72a9747b blueswir1
    else
3182 72a9747b blueswir1
        env->otherwin--;
3183 72a9747b blueswir1
}
3184 72a9747b blueswir1
3185 d35527d9 blueswir1
target_ulong helper_rdccr(void)
3186 d35527d9 blueswir1
{
3187 d35527d9 blueswir1
    return GET_CCR(env);
3188 d35527d9 blueswir1
}
3189 d35527d9 blueswir1
3190 d35527d9 blueswir1
void helper_wrccr(target_ulong new_ccr)
3191 d35527d9 blueswir1
{
3192 d35527d9 blueswir1
    PUT_CCR(env, new_ccr);
3193 d35527d9 blueswir1
}
3194 d35527d9 blueswir1
3195 d35527d9 blueswir1
// CWP handling is reversed in V9, but we still use the V8 register
3196 d35527d9 blueswir1
// order.
3197 d35527d9 blueswir1
target_ulong helper_rdcwp(void)
3198 d35527d9 blueswir1
{
3199 d35527d9 blueswir1
    return GET_CWP64(env);
3200 d35527d9 blueswir1
}
3201 d35527d9 blueswir1
3202 d35527d9 blueswir1
void helper_wrcwp(target_ulong new_cwp)
3203 d35527d9 blueswir1
{
3204 d35527d9 blueswir1
    PUT_CWP64(env, new_cwp);
3205 d35527d9 blueswir1
}
3206 3475187d bellard
3207 1f5063fb blueswir1
// This function uses non-native bit order
3208 1f5063fb blueswir1
#define GET_FIELD(X, FROM, TO)                                  \
3209 1f5063fb blueswir1
    ((X) >> (63 - (TO)) & ((1ULL << ((TO) - (FROM) + 1)) - 1))
3210 1f5063fb blueswir1
3211 1f5063fb blueswir1
// This function uses the order in the manuals, i.e. bit 0 is 2^0
3212 1f5063fb blueswir1
#define GET_FIELD_SP(X, FROM, TO)               \
3213 1f5063fb blueswir1
    GET_FIELD(X, 63 - (TO), 63 - (FROM))
3214 1f5063fb blueswir1
3215 1f5063fb blueswir1
target_ulong helper_array8(target_ulong pixel_addr, target_ulong cubesize)
3216 1f5063fb blueswir1
{
3217 1f5063fb blueswir1
    return (GET_FIELD_SP(pixel_addr, 60, 63) << (17 + 2 * cubesize)) |
3218 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 39, 39 + cubesize - 1) << (17 + cubesize)) |
3219 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 17 + cubesize - 1, 17) << 17) |
3220 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 56, 59) << 13) |
3221 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 35, 38) << 9) |
3222 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 13, 16) << 5) |
3223 1f5063fb blueswir1
        (((pixel_addr >> 55) & 1) << 4) |
3224 1f5063fb blueswir1
        (GET_FIELD_SP(pixel_addr, 33, 34) << 2) |
3225 1f5063fb blueswir1
        GET_FIELD_SP(pixel_addr, 11, 12);
3226 1f5063fb blueswir1
}
3227 1f5063fb blueswir1
3228 1f5063fb blueswir1
target_ulong helper_alignaddr(target_ulong addr, target_ulong offset)
3229 1f5063fb blueswir1
{
3230 1f5063fb blueswir1
    uint64_t tmp;
3231 1f5063fb blueswir1
3232 1f5063fb blueswir1
    tmp = addr + offset;
3233 1f5063fb blueswir1
    env->gsr &= ~7ULL;
3234 1f5063fb blueswir1
    env->gsr |= tmp & 7ULL;
3235 1f5063fb blueswir1
    return tmp & ~7ULL;
3236 1f5063fb blueswir1
}
3237 1f5063fb blueswir1
3238 1a2fb1c0 blueswir1
target_ulong helper_popc(target_ulong val)
3239 3475187d bellard
{
3240 1a2fb1c0 blueswir1
    return ctpop64(val);
3241 3475187d bellard
}
3242 83469015 bellard
3243 83469015 bellard
static inline uint64_t *get_gregset(uint64_t pstate)
3244 83469015 bellard
{
3245 83469015 bellard
    switch (pstate) {
3246 83469015 bellard
    default:
3247 83469015 bellard
    case 0:
3248 0f8a249a blueswir1
        return env->bgregs;
3249 83469015 bellard
    case PS_AG:
3250 0f8a249a blueswir1
        return env->agregs;
3251 83469015 bellard
    case PS_MG:
3252 0f8a249a blueswir1
        return env->mgregs;
3253 83469015 bellard
    case PS_IG:
3254 0f8a249a blueswir1
        return env->igregs;
3255 83469015 bellard
    }
3256 83469015 bellard
}
3257 83469015 bellard
3258 91736d37 blueswir1
static inline void change_pstate(uint64_t new_pstate)
3259 83469015 bellard
{
3260 8f1f22f6 blueswir1
    uint64_t pstate_regs, new_pstate_regs;
3261 83469015 bellard
    uint64_t *src, *dst;
3262 83469015 bellard
3263 5210977a Igor Kovalenko
    if (env->def->features & CPU_FEATURE_GL) {
3264 5210977a Igor Kovalenko
        // PS_AG is not implemented in this case
3265 5210977a Igor Kovalenko
        new_pstate &= ~PS_AG;
3266 5210977a Igor Kovalenko
    }
3267 5210977a Igor Kovalenko
3268 83469015 bellard
    pstate_regs = env->pstate & 0xc01;
3269 83469015 bellard
    new_pstate_regs = new_pstate & 0xc01;
3270 5210977a Igor Kovalenko
3271 83469015 bellard
    if (new_pstate_regs != pstate_regs) {
3272 0f8a249a blueswir1
        // Switch global register bank
3273 0f8a249a blueswir1
        src = get_gregset(new_pstate_regs);
3274 0f8a249a blueswir1
        dst = get_gregset(pstate_regs);
3275 0f8a249a blueswir1
        memcpy32(dst, env->gregs);
3276 0f8a249a blueswir1
        memcpy32(env->gregs, src);
3277 83469015 bellard
    }
3278 83469015 bellard
    env->pstate = new_pstate;
3279 83469015 bellard
}
3280 83469015 bellard
3281 1a2fb1c0 blueswir1
void helper_wrpstate(target_ulong new_state)
3282 8f1f22f6 blueswir1
{
3283 5210977a Igor Kovalenko
    change_pstate(new_state & 0xf3f);
3284 8f1f22f6 blueswir1
}
3285 8f1f22f6 blueswir1
3286 1a2fb1c0 blueswir1
void helper_done(void)
3287 83469015 bellard
{
3288 8194f35a Igor Kovalenko
    trap_state* tsptr = cpu_tsptr(env);
3289 8194f35a Igor Kovalenko
3290 3723cd09 Igor V. Kovalenko
    env->pc = tsptr->tnpc;
3291 8194f35a Igor Kovalenko
    env->npc = tsptr->tnpc + 4;
3292 8194f35a Igor Kovalenko
    PUT_CCR(env, tsptr->tstate >> 32);
3293 8194f35a Igor Kovalenko
    env->asi = (tsptr->tstate >> 24) & 0xff;
3294 8194f35a Igor Kovalenko
    change_pstate((tsptr->tstate >> 8) & 0xf3f);
3295 8194f35a Igor Kovalenko
    PUT_CWP64(env, tsptr->tstate & 0xff);
3296 e6bf7d70 blueswir1
    env->tl--;
3297 83469015 bellard
}
3298 83469015 bellard
3299 1a2fb1c0 blueswir1
void helper_retry(void)
3300 83469015 bellard
{
3301 8194f35a Igor Kovalenko
    trap_state* tsptr = cpu_tsptr(env);
3302 8194f35a Igor Kovalenko
3303 8194f35a Igor Kovalenko
    env->pc = tsptr->tpc;
3304 8194f35a Igor Kovalenko
    env->npc = tsptr->tnpc;
3305 8194f35a Igor Kovalenko
    PUT_CCR(env, tsptr->tstate >> 32);
3306 8194f35a Igor Kovalenko
    env->asi = (tsptr->tstate >> 24) & 0xff;
3307 8194f35a Igor Kovalenko
    change_pstate((tsptr->tstate >> 8) & 0xf3f);
3308 8194f35a Igor Kovalenko
    PUT_CWP64(env, tsptr->tstate & 0xff);
3309 e6bf7d70 blueswir1
    env->tl--;
3310 83469015 bellard
}
3311 9d926598 blueswir1
3312 9d926598 blueswir1
void helper_set_softint(uint64_t value)
3313 9d926598 blueswir1
{
3314 9d926598 blueswir1
    env->softint |= (uint32_t)value;
3315 9d926598 blueswir1
}
3316 9d926598 blueswir1
3317 9d926598 blueswir1
void helper_clear_softint(uint64_t value)
3318 9d926598 blueswir1
{
3319 9d926598 blueswir1
    env->softint &= (uint32_t)~value;
3320 9d926598 blueswir1
}
3321 9d926598 blueswir1
3322 9d926598 blueswir1
void helper_write_softint(uint64_t value)
3323 9d926598 blueswir1
{
3324 9d926598 blueswir1
    env->softint = (uint32_t)value;
3325 9d926598 blueswir1
}
3326 3475187d bellard
#endif
3327 ee5bbe38 bellard
3328 91736d37 blueswir1
void helper_flush(target_ulong addr)
3329 ee5bbe38 bellard
{
3330 91736d37 blueswir1
    addr &= ~7;
3331 91736d37 blueswir1
    tb_invalidate_page_range(addr, addr + 8);
3332 ee5bbe38 bellard
}
3333 ee5bbe38 bellard
3334 91736d37 blueswir1
#ifdef TARGET_SPARC64
3335 91736d37 blueswir1
#ifdef DEBUG_PCALL
3336 91736d37 blueswir1
static const char * const excp_names[0x80] = {
3337 91736d37 blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
3338 91736d37 blueswir1
    [TT_TMISS] = "Instruction Access MMU Miss",
3339 91736d37 blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
3340 91736d37 blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
3341 91736d37 blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
3342 91736d37 blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
3343 91736d37 blueswir1
    [TT_FP_EXCP] = "FPU Exception",
3344 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3345 91736d37 blueswir1
    [TT_CLRWIN] = "Clean Windows",
3346 91736d37 blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
3347 91736d37 blueswir1
    [TT_DFAULT] = "Data Access Fault",
3348 91736d37 blueswir1
    [TT_DMISS] = "Data Access MMU Miss",
3349 91736d37 blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
3350 91736d37 blueswir1
    [TT_DPROT] = "Data Protection Error",
3351 91736d37 blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
3352 91736d37 blueswir1
    [TT_PRIV_ACT] = "Privileged Action",
3353 91736d37 blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
3354 91736d37 blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
3355 91736d37 blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
3356 91736d37 blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
3357 91736d37 blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
3358 91736d37 blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
3359 91736d37 blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
3360 91736d37 blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
3361 91736d37 blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
3362 91736d37 blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
3363 91736d37 blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
3364 91736d37 blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
3365 91736d37 blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
3366 91736d37 blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
3367 91736d37 blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
3368 91736d37 blueswir1
};
3369 91736d37 blueswir1
#endif
3370 91736d37 blueswir1
3371 8194f35a Igor Kovalenko
trap_state* cpu_tsptr(CPUState* env)
3372 8194f35a Igor Kovalenko
{
3373 8194f35a Igor Kovalenko
    return &env->ts[env->tl & MAXTL_MASK];
3374 8194f35a Igor Kovalenko
}
3375 8194f35a Igor Kovalenko
3376 91736d37 blueswir1
void do_interrupt(CPUState *env)
3377 91736d37 blueswir1
{
3378 91736d37 blueswir1
    int intno = env->exception_index;
3379 8194f35a Igor Kovalenko
    trap_state* tsptr;
3380 91736d37 blueswir1
3381 91736d37 blueswir1
#ifdef DEBUG_PCALL
3382 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
3383 91736d37 blueswir1
        static int count;
3384 91736d37 blueswir1
        const char *name;
3385 91736d37 blueswir1
3386 91736d37 blueswir1
        if (intno < 0 || intno >= 0x180)
3387 91736d37 blueswir1
            name = "Unknown";
3388 91736d37 blueswir1
        else if (intno >= 0x100)
3389 91736d37 blueswir1
            name = "Trap Instruction";
3390 91736d37 blueswir1
        else if (intno >= 0xc0)
3391 91736d37 blueswir1
            name = "Window Fill";
3392 91736d37 blueswir1
        else if (intno >= 0x80)
3393 91736d37 blueswir1
            name = "Window Spill";
3394 91736d37 blueswir1
        else {
3395 91736d37 blueswir1
            name = excp_names[intno];
3396 91736d37 blueswir1
            if (!name)
3397 91736d37 blueswir1
                name = "Unknown";
3398 91736d37 blueswir1
        }
3399 91736d37 blueswir1
3400 93fcfe39 aliguori
        qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
3401 91736d37 blueswir1
                " SP=%016" PRIx64 "\n",
3402 91736d37 blueswir1
                count, name, intno,
3403 91736d37 blueswir1
                env->pc,
3404 91736d37 blueswir1
                env->npc, env->regwptr[6]);
3405 93fcfe39 aliguori
        log_cpu_state(env, 0);
3406 91736d37 blueswir1
#if 0
3407 91736d37 blueswir1
        {
3408 91736d37 blueswir1
            int i;
3409 91736d37 blueswir1
            uint8_t *ptr;
3410 91736d37 blueswir1

3411 93fcfe39 aliguori
            qemu_log("       code=");
3412 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
3413 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
3414 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
3415 91736d37 blueswir1
            }
3416 93fcfe39 aliguori
            qemu_log("\n");
3417 91736d37 blueswir1
        }
3418 91736d37 blueswir1
#endif
3419 91736d37 blueswir1
        count++;
3420 91736d37 blueswir1
    }
3421 91736d37 blueswir1
#endif
3422 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
3423 91736d37 blueswir1
    if (env->tl >= env->maxtl) {
3424 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
3425 91736d37 blueswir1
                  " Error state", env->exception_index, env->tl, env->maxtl);
3426 91736d37 blueswir1
        return;
3427 91736d37 blueswir1
    }
3428 91736d37 blueswir1
#endif
3429 91736d37 blueswir1
    if (env->tl < env->maxtl - 1) {
3430 91736d37 blueswir1
        env->tl++;
3431 91736d37 blueswir1
    } else {
3432 91736d37 blueswir1
        env->pstate |= PS_RED;
3433 91736d37 blueswir1
        if (env->tl < env->maxtl)
3434 91736d37 blueswir1
            env->tl++;
3435 91736d37 blueswir1
    }
3436 8194f35a Igor Kovalenko
    tsptr = cpu_tsptr(env);
3437 8194f35a Igor Kovalenko
3438 8194f35a Igor Kovalenko
    tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
3439 91736d37 blueswir1
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
3440 91736d37 blueswir1
        GET_CWP64(env);
3441 8194f35a Igor Kovalenko
    tsptr->tpc = env->pc;
3442 8194f35a Igor Kovalenko
    tsptr->tnpc = env->npc;
3443 8194f35a Igor Kovalenko
    tsptr->tt = intno;
3444 5210977a Igor Kovalenko
3445 5210977a Igor Kovalenko
    switch (intno) {
3446 5210977a Igor Kovalenko
    case TT_IVEC:
3447 5210977a Igor Kovalenko
        change_pstate(PS_PEF | PS_PRIV | PS_IG);
3448 5210977a Igor Kovalenko
        break;
3449 5210977a Igor Kovalenko
    case TT_TFAULT:
3450 5210977a Igor Kovalenko
    case TT_TMISS:
3451 5210977a Igor Kovalenko
    case TT_DFAULT:
3452 5210977a Igor Kovalenko
    case TT_DMISS:
3453 5210977a Igor Kovalenko
    case TT_DPROT:
3454 5210977a Igor Kovalenko
        change_pstate(PS_PEF | PS_PRIV | PS_MG);
3455 5210977a Igor Kovalenko
        break;
3456 5210977a Igor Kovalenko
    default:
3457 5210977a Igor Kovalenko
        change_pstate(PS_PEF | PS_PRIV | PS_AG);
3458 5210977a Igor Kovalenko
        break;
3459 91736d37 blueswir1
    }
3460 5210977a Igor Kovalenko
3461 91736d37 blueswir1
    if (intno == TT_CLRWIN)
3462 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
3463 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_SPILL)
3464 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
3465 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_FILL)
3466 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
3467 91736d37 blueswir1
    env->tbr &= ~0x7fffULL;
3468 91736d37 blueswir1
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
3469 91736d37 blueswir1
    env->pc = env->tbr;
3470 91736d37 blueswir1
    env->npc = env->pc + 4;
3471 91736d37 blueswir1
    env->exception_index = 0;
3472 ee5bbe38 bellard
}
3473 91736d37 blueswir1
#else
3474 91736d37 blueswir1
#ifdef DEBUG_PCALL
3475 91736d37 blueswir1
static const char * const excp_names[0x80] = {
3476 91736d37 blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
3477 91736d37 blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
3478 91736d37 blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
3479 91736d37 blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
3480 91736d37 blueswir1
    [TT_WIN_OVF] = "Window Overflow",
3481 91736d37 blueswir1
    [TT_WIN_UNF] = "Window Underflow",
3482 91736d37 blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
3483 91736d37 blueswir1
    [TT_FP_EXCP] = "FPU Exception",
3484 91736d37 blueswir1
    [TT_DFAULT] = "Data Access Fault",
3485 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3486 91736d37 blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
3487 91736d37 blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
3488 91736d37 blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
3489 91736d37 blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
3490 91736d37 blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
3491 91736d37 blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
3492 91736d37 blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
3493 91736d37 blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
3494 91736d37 blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
3495 91736d37 blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
3496 91736d37 blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
3497 91736d37 blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
3498 91736d37 blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
3499 91736d37 blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
3500 91736d37 blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
3501 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3502 91736d37 blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
3503 91736d37 blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
3504 91736d37 blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
3505 91736d37 blueswir1
    [TT_NCP_INSN] = "Coprocessor Disabled",
3506 91736d37 blueswir1
};
3507 91736d37 blueswir1
#endif
3508 ee5bbe38 bellard
3509 91736d37 blueswir1
void do_interrupt(CPUState *env)
3510 ee5bbe38 bellard
{
3511 91736d37 blueswir1
    int cwp, intno = env->exception_index;
3512 91736d37 blueswir1
3513 91736d37 blueswir1
#ifdef DEBUG_PCALL
3514 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
3515 91736d37 blueswir1
        static int count;
3516 91736d37 blueswir1
        const char *name;
3517 91736d37 blueswir1
3518 91736d37 blueswir1
        if (intno < 0 || intno >= 0x100)
3519 91736d37 blueswir1
            name = "Unknown";
3520 91736d37 blueswir1
        else if (intno >= 0x80)
3521 91736d37 blueswir1
            name = "Trap Instruction";
3522 91736d37 blueswir1
        else {
3523 91736d37 blueswir1
            name = excp_names[intno];
3524 91736d37 blueswir1
            if (!name)
3525 91736d37 blueswir1
                name = "Unknown";
3526 91736d37 blueswir1
        }
3527 91736d37 blueswir1
3528 93fcfe39 aliguori
        qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
3529 91736d37 blueswir1
                count, name, intno,
3530 91736d37 blueswir1
                env->pc,
3531 91736d37 blueswir1
                env->npc, env->regwptr[6]);
3532 93fcfe39 aliguori
        log_cpu_state(env, 0);
3533 91736d37 blueswir1
#if 0
3534 91736d37 blueswir1
        {
3535 91736d37 blueswir1
            int i;
3536 91736d37 blueswir1
            uint8_t *ptr;
3537 91736d37 blueswir1

3538 93fcfe39 aliguori
            qemu_log("       code=");
3539 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
3540 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
3541 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
3542 91736d37 blueswir1
            }
3543 93fcfe39 aliguori
            qemu_log("\n");
3544 91736d37 blueswir1
        }
3545 91736d37 blueswir1
#endif
3546 91736d37 blueswir1
        count++;
3547 91736d37 blueswir1
    }
3548 91736d37 blueswir1
#endif
3549 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
3550 91736d37 blueswir1
    if (env->psret == 0) {
3551 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
3552 91736d37 blueswir1
                  env->exception_index);
3553 91736d37 blueswir1
        return;
3554 91736d37 blueswir1
    }
3555 91736d37 blueswir1
#endif
3556 91736d37 blueswir1
    env->psret = 0;
3557 91736d37 blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
3558 91736d37 blueswir1
    cpu_set_cwp(env, cwp);
3559 91736d37 blueswir1
    env->regwptr[9] = env->pc;
3560 91736d37 blueswir1
    env->regwptr[10] = env->npc;
3561 91736d37 blueswir1
    env->psrps = env->psrs;
3562 91736d37 blueswir1
    env->psrs = 1;
3563 91736d37 blueswir1
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
3564 91736d37 blueswir1
    env->pc = env->tbr;
3565 91736d37 blueswir1
    env->npc = env->pc + 4;
3566 91736d37 blueswir1
    env->exception_index = 0;
3567 ee5bbe38 bellard
}
3568 91736d37 blueswir1
#endif
3569 ee5bbe38 bellard
3570 5fafdf24 ths
#if !defined(CONFIG_USER_ONLY)
3571 ee5bbe38 bellard
3572 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3573 d2889a3e blueswir1
                                void *retaddr);
3574 d2889a3e blueswir1
3575 ee5bbe38 bellard
#define MMUSUFFIX _mmu
3576 d2889a3e blueswir1
#define ALIGNED_ONLY
3577 ee5bbe38 bellard
3578 ee5bbe38 bellard
#define SHIFT 0
3579 ee5bbe38 bellard
#include "softmmu_template.h"
3580 ee5bbe38 bellard
3581 ee5bbe38 bellard
#define SHIFT 1
3582 ee5bbe38 bellard
#include "softmmu_template.h"
3583 ee5bbe38 bellard
3584 ee5bbe38 bellard
#define SHIFT 2
3585 ee5bbe38 bellard
#include "softmmu_template.h"
3586 ee5bbe38 bellard
3587 ee5bbe38 bellard
#define SHIFT 3
3588 ee5bbe38 bellard
#include "softmmu_template.h"
3589 ee5bbe38 bellard
3590 c2bc0e38 blueswir1
/* XXX: make it generic ? */
3591 c2bc0e38 blueswir1
static void cpu_restore_state2(void *retaddr)
3592 c2bc0e38 blueswir1
{
3593 c2bc0e38 blueswir1
    TranslationBlock *tb;
3594 c2bc0e38 blueswir1
    unsigned long pc;
3595 c2bc0e38 blueswir1
3596 c2bc0e38 blueswir1
    if (retaddr) {
3597 c2bc0e38 blueswir1
        /* now we have a real cpu fault */
3598 c2bc0e38 blueswir1
        pc = (unsigned long)retaddr;
3599 c2bc0e38 blueswir1
        tb = tb_find_pc(pc);
3600 c2bc0e38 blueswir1
        if (tb) {
3601 c2bc0e38 blueswir1
            /* the PC is inside the translated code. It means that we have
3602 c2bc0e38 blueswir1
               a virtual CPU fault */
3603 c2bc0e38 blueswir1
            cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
3604 c2bc0e38 blueswir1
        }
3605 c2bc0e38 blueswir1
    }
3606 c2bc0e38 blueswir1
}
3607 c2bc0e38 blueswir1
3608 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3609 d2889a3e blueswir1
                                void *retaddr)
3610 d2889a3e blueswir1
{
3611 94554550 blueswir1
#ifdef DEBUG_UNALIGNED
3612 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
3613 c2bc0e38 blueswir1
           "\n", addr, env->pc);
3614 94554550 blueswir1
#endif
3615 c2bc0e38 blueswir1
    cpu_restore_state2(retaddr);
3616 94554550 blueswir1
    raise_exception(TT_UNALIGNED);
3617 d2889a3e blueswir1
}
3618 ee5bbe38 bellard
3619 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
3620 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
3621 ee5bbe38 bellard
   from generated code or from helper.c) */
3622 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
3623 6ebbf390 j_mayer
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
3624 ee5bbe38 bellard
{
3625 ee5bbe38 bellard
    int ret;
3626 ee5bbe38 bellard
    CPUState *saved_env;
3627 ee5bbe38 bellard
3628 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
3629 ee5bbe38 bellard
       generated code */
3630 ee5bbe38 bellard
    saved_env = env;
3631 ee5bbe38 bellard
    env = cpu_single_env;
3632 ee5bbe38 bellard
3633 6ebbf390 j_mayer
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
3634 ee5bbe38 bellard
    if (ret) {
3635 c2bc0e38 blueswir1
        cpu_restore_state2(retaddr);
3636 ee5bbe38 bellard
        cpu_loop_exit();
3637 ee5bbe38 bellard
    }
3638 ee5bbe38 bellard
    env = saved_env;
3639 ee5bbe38 bellard
}
3640 ee5bbe38 bellard
3641 ee5bbe38 bellard
#endif
3642 6c36d3fa blueswir1
3643 6c36d3fa blueswir1
#ifndef TARGET_SPARC64
3644 c227f099 Anthony Liguori
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3645 e18231a3 blueswir1
                          int is_asi, int size)
3646 6c36d3fa blueswir1
{
3647 6c36d3fa blueswir1
    CPUState *saved_env;
3648 6c36d3fa blueswir1
3649 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3650 6c36d3fa blueswir1
       generated code */
3651 6c36d3fa blueswir1
    saved_env = env;
3652 6c36d3fa blueswir1
    env = cpu_single_env;
3653 8543e2cf blueswir1
#ifdef DEBUG_UNASSIGNED
3654 8543e2cf blueswir1
    if (is_asi)
3655 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3656 77f193da blueswir1
               " asi 0x%02x from " TARGET_FMT_lx "\n",
3657 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3658 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, is_asi, env->pc);
3659 8543e2cf blueswir1
    else
3660 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3661 e18231a3 blueswir1
               " from " TARGET_FMT_lx "\n",
3662 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3663 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, env->pc);
3664 8543e2cf blueswir1
#endif
3665 6c36d3fa blueswir1
    if (env->mmuregs[3]) /* Fault status register */
3666 0f8a249a blueswir1
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
3667 6c36d3fa blueswir1
    if (is_asi)
3668 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 16;
3669 6c36d3fa blueswir1
    if (env->psrs)
3670 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 5;
3671 6c36d3fa blueswir1
    if (is_exec)
3672 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 6;
3673 6c36d3fa blueswir1
    if (is_write)
3674 6c36d3fa blueswir1
        env->mmuregs[3] |= 1 << 7;
3675 6c36d3fa blueswir1
    env->mmuregs[3] |= (5 << 2) | 2;
3676 6c36d3fa blueswir1
    env->mmuregs[4] = addr; /* Fault address register */
3677 6c36d3fa blueswir1
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
3678 1b2e93c1 blueswir1
        if (is_exec)
3679 1b2e93c1 blueswir1
            raise_exception(TT_CODE_ACCESS);
3680 1b2e93c1 blueswir1
        else
3681 1b2e93c1 blueswir1
            raise_exception(TT_DATA_ACCESS);
3682 6c36d3fa blueswir1
    }
3683 6c36d3fa blueswir1
    env = saved_env;
3684 6c36d3fa blueswir1
}
3685 6c36d3fa blueswir1
#else
3686 c227f099 Anthony Liguori
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3687 e18231a3 blueswir1
                          int is_asi, int size)
3688 6c36d3fa blueswir1
{
3689 6c36d3fa blueswir1
#ifdef DEBUG_UNASSIGNED
3690 6c36d3fa blueswir1
    CPUState *saved_env;
3691 6c36d3fa blueswir1
3692 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3693 6c36d3fa blueswir1
       generated code */
3694 6c36d3fa blueswir1
    saved_env = env;
3695 6c36d3fa blueswir1
    env = cpu_single_env;
3696 77f193da blueswir1
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
3697 77f193da blueswir1
           "\n", addr, env->pc);
3698 6c36d3fa blueswir1
    env = saved_env;
3699 6c36d3fa blueswir1
#endif
3700 1b2e93c1 blueswir1
    if (is_exec)
3701 1b2e93c1 blueswir1
        raise_exception(TT_CODE_ACCESS);
3702 1b2e93c1 blueswir1
    else
3703 1b2e93c1 blueswir1
        raise_exception(TT_DATA_ACCESS);
3704 6c36d3fa blueswir1
}
3705 6c36d3fa blueswir1
#endif
3706 20c9f095 blueswir1
3707 f4b1a842 blueswir1
#ifdef TARGET_SPARC64
3708 f4b1a842 blueswir1
void helper_tick_set_count(void *opaque, uint64_t count)
3709 f4b1a842 blueswir1
{
3710 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3711 f4b1a842 blueswir1
    cpu_tick_set_count(opaque, count);
3712 f4b1a842 blueswir1
#endif
3713 f4b1a842 blueswir1
}
3714 f4b1a842 blueswir1
3715 f4b1a842 blueswir1
uint64_t helper_tick_get_count(void *opaque)
3716 f4b1a842 blueswir1
{
3717 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3718 f4b1a842 blueswir1
    return cpu_tick_get_count(opaque);
3719 f4b1a842 blueswir1
#else
3720 f4b1a842 blueswir1
    return 0;
3721 f4b1a842 blueswir1
#endif
3722 f4b1a842 blueswir1
}
3723 f4b1a842 blueswir1
3724 f4b1a842 blueswir1
void helper_tick_set_limit(void *opaque, uint64_t limit)
3725 f4b1a842 blueswir1
{
3726 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3727 f4b1a842 blueswir1
    cpu_tick_set_limit(opaque, limit);
3728 f4b1a842 blueswir1
#endif
3729 f4b1a842 blueswir1
}
3730 f4b1a842 blueswir1
#endif