Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 3c7b48b7

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

3485 93fcfe39 aliguori
            qemu_log("       code=");
3486 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
3487 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
3488 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
3489 91736d37 blueswir1
            }
3490 93fcfe39 aliguori
            qemu_log("\n");
3491 91736d37 blueswir1
        }
3492 91736d37 blueswir1
#endif
3493 91736d37 blueswir1
        count++;
3494 91736d37 blueswir1
    }
3495 91736d37 blueswir1
#endif
3496 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
3497 91736d37 blueswir1
    if (env->tl >= env->maxtl) {
3498 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
3499 91736d37 blueswir1
                  " Error state", env->exception_index, env->tl, env->maxtl);
3500 91736d37 blueswir1
        return;
3501 91736d37 blueswir1
    }
3502 91736d37 blueswir1
#endif
3503 91736d37 blueswir1
    if (env->tl < env->maxtl - 1) {
3504 91736d37 blueswir1
        env->tl++;
3505 91736d37 blueswir1
    } else {
3506 91736d37 blueswir1
        env->pstate |= PS_RED;
3507 91736d37 blueswir1
        if (env->tl < env->maxtl)
3508 91736d37 blueswir1
            env->tl++;
3509 91736d37 blueswir1
    }
3510 8194f35a Igor Kovalenko
    tsptr = cpu_tsptr(env);
3511 8194f35a Igor Kovalenko
3512 8194f35a Igor Kovalenko
    tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
3513 91736d37 blueswir1
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
3514 91736d37 blueswir1
        GET_CWP64(env);
3515 8194f35a Igor Kovalenko
    tsptr->tpc = env->pc;
3516 8194f35a Igor Kovalenko
    tsptr->tnpc = env->npc;
3517 8194f35a Igor Kovalenko
    tsptr->tt = intno;
3518 5210977a Igor Kovalenko
3519 5210977a Igor Kovalenko
    switch (intno) {
3520 5210977a Igor Kovalenko
    case TT_IVEC:
3521 5210977a Igor Kovalenko
        change_pstate(PS_PEF | PS_PRIV | PS_IG);
3522 5210977a Igor Kovalenko
        break;
3523 5210977a Igor Kovalenko
    case TT_TFAULT:
3524 5210977a Igor Kovalenko
    case TT_DFAULT:
3525 87f6d3f6 Igor V. Kovalenko
    case TT_TMISS ... TT_TMISS + 3:
3526 87f6d3f6 Igor V. Kovalenko
    case TT_DMISS ... TT_DMISS + 3:
3527 87f6d3f6 Igor V. Kovalenko
    case TT_DPROT ... TT_DPROT + 3:
3528 5210977a Igor Kovalenko
        change_pstate(PS_PEF | PS_PRIV | PS_MG);
3529 5210977a Igor Kovalenko
        break;
3530 5210977a Igor Kovalenko
    default:
3531 5210977a Igor Kovalenko
        change_pstate(PS_PEF | PS_PRIV | PS_AG);
3532 5210977a Igor Kovalenko
        break;
3533 91736d37 blueswir1
    }
3534 5210977a Igor Kovalenko
3535 91736d37 blueswir1
    if (intno == TT_CLRWIN)
3536 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
3537 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_SPILL)
3538 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
3539 91736d37 blueswir1
    else if ((intno & 0x1c0) == TT_FILL)
3540 91736d37 blueswir1
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
3541 91736d37 blueswir1
    env->tbr &= ~0x7fffULL;
3542 91736d37 blueswir1
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
3543 91736d37 blueswir1
    env->pc = env->tbr;
3544 91736d37 blueswir1
    env->npc = env->pc + 4;
3545 821b19fe Igor V. Kovalenko
    env->exception_index = -1;
3546 ee5bbe38 bellard
}
3547 91736d37 blueswir1
#else
3548 91736d37 blueswir1
#ifdef DEBUG_PCALL
3549 91736d37 blueswir1
static const char * const excp_names[0x80] = {
3550 91736d37 blueswir1
    [TT_TFAULT] = "Instruction Access Fault",
3551 91736d37 blueswir1
    [TT_ILL_INSN] = "Illegal Instruction",
3552 91736d37 blueswir1
    [TT_PRIV_INSN] = "Privileged Instruction",
3553 91736d37 blueswir1
    [TT_NFPU_INSN] = "FPU Disabled",
3554 91736d37 blueswir1
    [TT_WIN_OVF] = "Window Overflow",
3555 91736d37 blueswir1
    [TT_WIN_UNF] = "Window Underflow",
3556 91736d37 blueswir1
    [TT_UNALIGNED] = "Unaligned Memory Access",
3557 91736d37 blueswir1
    [TT_FP_EXCP] = "FPU Exception",
3558 91736d37 blueswir1
    [TT_DFAULT] = "Data Access Fault",
3559 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3560 91736d37 blueswir1
    [TT_EXTINT | 0x1] = "External Interrupt 1",
3561 91736d37 blueswir1
    [TT_EXTINT | 0x2] = "External Interrupt 2",
3562 91736d37 blueswir1
    [TT_EXTINT | 0x3] = "External Interrupt 3",
3563 91736d37 blueswir1
    [TT_EXTINT | 0x4] = "External Interrupt 4",
3564 91736d37 blueswir1
    [TT_EXTINT | 0x5] = "External Interrupt 5",
3565 91736d37 blueswir1
    [TT_EXTINT | 0x6] = "External Interrupt 6",
3566 91736d37 blueswir1
    [TT_EXTINT | 0x7] = "External Interrupt 7",
3567 91736d37 blueswir1
    [TT_EXTINT | 0x8] = "External Interrupt 8",
3568 91736d37 blueswir1
    [TT_EXTINT | 0x9] = "External Interrupt 9",
3569 91736d37 blueswir1
    [TT_EXTINT | 0xa] = "External Interrupt 10",
3570 91736d37 blueswir1
    [TT_EXTINT | 0xb] = "External Interrupt 11",
3571 91736d37 blueswir1
    [TT_EXTINT | 0xc] = "External Interrupt 12",
3572 91736d37 blueswir1
    [TT_EXTINT | 0xd] = "External Interrupt 13",
3573 91736d37 blueswir1
    [TT_EXTINT | 0xe] = "External Interrupt 14",
3574 91736d37 blueswir1
    [TT_EXTINT | 0xf] = "External Interrupt 15",
3575 91736d37 blueswir1
    [TT_TOVF] = "Tag Overflow",
3576 91736d37 blueswir1
    [TT_CODE_ACCESS] = "Instruction Access Error",
3577 91736d37 blueswir1
    [TT_DATA_ACCESS] = "Data Access Error",
3578 91736d37 blueswir1
    [TT_DIV_ZERO] = "Division By Zero",
3579 91736d37 blueswir1
    [TT_NCP_INSN] = "Coprocessor Disabled",
3580 91736d37 blueswir1
};
3581 91736d37 blueswir1
#endif
3582 ee5bbe38 bellard
3583 91736d37 blueswir1
void do_interrupt(CPUState *env)
3584 ee5bbe38 bellard
{
3585 91736d37 blueswir1
    int cwp, intno = env->exception_index;
3586 91736d37 blueswir1
3587 91736d37 blueswir1
#ifdef DEBUG_PCALL
3588 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
3589 91736d37 blueswir1
        static int count;
3590 91736d37 blueswir1
        const char *name;
3591 91736d37 blueswir1
3592 91736d37 blueswir1
        if (intno < 0 || intno >= 0x100)
3593 91736d37 blueswir1
            name = "Unknown";
3594 91736d37 blueswir1
        else if (intno >= 0x80)
3595 91736d37 blueswir1
            name = "Trap Instruction";
3596 91736d37 blueswir1
        else {
3597 91736d37 blueswir1
            name = excp_names[intno];
3598 91736d37 blueswir1
            if (!name)
3599 91736d37 blueswir1
                name = "Unknown";
3600 91736d37 blueswir1
        }
3601 91736d37 blueswir1
3602 93fcfe39 aliguori
        qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
3603 91736d37 blueswir1
                count, name, intno,
3604 91736d37 blueswir1
                env->pc,
3605 91736d37 blueswir1
                env->npc, env->regwptr[6]);
3606 93fcfe39 aliguori
        log_cpu_state(env, 0);
3607 91736d37 blueswir1
#if 0
3608 91736d37 blueswir1
        {
3609 91736d37 blueswir1
            int i;
3610 91736d37 blueswir1
            uint8_t *ptr;
3611 91736d37 blueswir1

3612 93fcfe39 aliguori
            qemu_log("       code=");
3613 91736d37 blueswir1
            ptr = (uint8_t *)env->pc;
3614 91736d37 blueswir1
            for(i = 0; i < 16; i++) {
3615 93fcfe39 aliguori
                qemu_log(" %02x", ldub(ptr + i));
3616 91736d37 blueswir1
            }
3617 93fcfe39 aliguori
            qemu_log("\n");
3618 91736d37 blueswir1
        }
3619 91736d37 blueswir1
#endif
3620 91736d37 blueswir1
        count++;
3621 91736d37 blueswir1
    }
3622 91736d37 blueswir1
#endif
3623 91736d37 blueswir1
#if !defined(CONFIG_USER_ONLY)
3624 91736d37 blueswir1
    if (env->psret == 0) {
3625 91736d37 blueswir1
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
3626 91736d37 blueswir1
                  env->exception_index);
3627 91736d37 blueswir1
        return;
3628 91736d37 blueswir1
    }
3629 91736d37 blueswir1
#endif
3630 91736d37 blueswir1
    env->psret = 0;
3631 91736d37 blueswir1
    cwp = cpu_cwp_dec(env, env->cwp - 1);
3632 91736d37 blueswir1
    cpu_set_cwp(env, cwp);
3633 91736d37 blueswir1
    env->regwptr[9] = env->pc;
3634 91736d37 blueswir1
    env->regwptr[10] = env->npc;
3635 91736d37 blueswir1
    env->psrps = env->psrs;
3636 91736d37 blueswir1
    env->psrs = 1;
3637 91736d37 blueswir1
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
3638 91736d37 blueswir1
    env->pc = env->tbr;
3639 91736d37 blueswir1
    env->npc = env->pc + 4;
3640 95372a39 Blue Swirl
    env->exception_index = -1;
3641 ee5bbe38 bellard
}
3642 91736d37 blueswir1
#endif
3643 ee5bbe38 bellard
3644 5fafdf24 ths
#if !defined(CONFIG_USER_ONLY)
3645 ee5bbe38 bellard
3646 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3647 d2889a3e blueswir1
                                void *retaddr);
3648 d2889a3e blueswir1
3649 ee5bbe38 bellard
#define MMUSUFFIX _mmu
3650 d2889a3e blueswir1
#define ALIGNED_ONLY
3651 ee5bbe38 bellard
3652 ee5bbe38 bellard
#define SHIFT 0
3653 ee5bbe38 bellard
#include "softmmu_template.h"
3654 ee5bbe38 bellard
3655 ee5bbe38 bellard
#define SHIFT 1
3656 ee5bbe38 bellard
#include "softmmu_template.h"
3657 ee5bbe38 bellard
3658 ee5bbe38 bellard
#define SHIFT 2
3659 ee5bbe38 bellard
#include "softmmu_template.h"
3660 ee5bbe38 bellard
3661 ee5bbe38 bellard
#define SHIFT 3
3662 ee5bbe38 bellard
#include "softmmu_template.h"
3663 ee5bbe38 bellard
3664 c2bc0e38 blueswir1
/* XXX: make it generic ? */
3665 c2bc0e38 blueswir1
static void cpu_restore_state2(void *retaddr)
3666 c2bc0e38 blueswir1
{
3667 c2bc0e38 blueswir1
    TranslationBlock *tb;
3668 c2bc0e38 blueswir1
    unsigned long pc;
3669 c2bc0e38 blueswir1
3670 c2bc0e38 blueswir1
    if (retaddr) {
3671 c2bc0e38 blueswir1
        /* now we have a real cpu fault */
3672 c2bc0e38 blueswir1
        pc = (unsigned long)retaddr;
3673 c2bc0e38 blueswir1
        tb = tb_find_pc(pc);
3674 c2bc0e38 blueswir1
        if (tb) {
3675 c2bc0e38 blueswir1
            /* the PC is inside the translated code. It means that we have
3676 c2bc0e38 blueswir1
               a virtual CPU fault */
3677 c2bc0e38 blueswir1
            cpu_restore_state(tb, env, pc, (void *)(long)env->cond);
3678 c2bc0e38 blueswir1
        }
3679 c2bc0e38 blueswir1
    }
3680 c2bc0e38 blueswir1
}
3681 c2bc0e38 blueswir1
3682 d2889a3e blueswir1
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
3683 d2889a3e blueswir1
                                void *retaddr)
3684 d2889a3e blueswir1
{
3685 94554550 blueswir1
#ifdef DEBUG_UNALIGNED
3686 c2bc0e38 blueswir1
    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
3687 c2bc0e38 blueswir1
           "\n", addr, env->pc);
3688 94554550 blueswir1
#endif
3689 c2bc0e38 blueswir1
    cpu_restore_state2(retaddr);
3690 94554550 blueswir1
    raise_exception(TT_UNALIGNED);
3691 d2889a3e blueswir1
}
3692 ee5bbe38 bellard
3693 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
3694 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
3695 ee5bbe38 bellard
   from generated code or from helper.c) */
3696 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
3697 6ebbf390 j_mayer
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
3698 ee5bbe38 bellard
{
3699 ee5bbe38 bellard
    int ret;
3700 ee5bbe38 bellard
    CPUState *saved_env;
3701 ee5bbe38 bellard
3702 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
3703 ee5bbe38 bellard
       generated code */
3704 ee5bbe38 bellard
    saved_env = env;
3705 ee5bbe38 bellard
    env = cpu_single_env;
3706 ee5bbe38 bellard
3707 6ebbf390 j_mayer
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
3708 ee5bbe38 bellard
    if (ret) {
3709 c2bc0e38 blueswir1
        cpu_restore_state2(retaddr);
3710 ee5bbe38 bellard
        cpu_loop_exit();
3711 ee5bbe38 bellard
    }
3712 ee5bbe38 bellard
    env = saved_env;
3713 ee5bbe38 bellard
}
3714 ee5bbe38 bellard
3715 3c7b48b7 Paul Brook
#endif /* !CONFIG_USER_ONLY */
3716 6c36d3fa blueswir1
3717 6c36d3fa blueswir1
#ifndef TARGET_SPARC64
3718 3c7b48b7 Paul Brook
#if !defined(CONFIG_USER_ONLY)
3719 c227f099 Anthony Liguori
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3720 e18231a3 blueswir1
                          int is_asi, int size)
3721 6c36d3fa blueswir1
{
3722 6c36d3fa blueswir1
    CPUState *saved_env;
3723 576c2cdc Artyom Tarasenko
    int fault_type;
3724 6c36d3fa blueswir1
3725 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3726 6c36d3fa blueswir1
       generated code */
3727 6c36d3fa blueswir1
    saved_env = env;
3728 6c36d3fa blueswir1
    env = cpu_single_env;
3729 8543e2cf blueswir1
#ifdef DEBUG_UNASSIGNED
3730 8543e2cf blueswir1
    if (is_asi)
3731 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3732 77f193da blueswir1
               " asi 0x%02x from " TARGET_FMT_lx "\n",
3733 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3734 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, is_asi, env->pc);
3735 8543e2cf blueswir1
    else
3736 e18231a3 blueswir1
        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
3737 e18231a3 blueswir1
               " from " TARGET_FMT_lx "\n",
3738 e18231a3 blueswir1
               is_exec ? "exec" : is_write ? "write" : "read", size,
3739 e18231a3 blueswir1
               size == 1 ? "" : "s", addr, env->pc);
3740 8543e2cf blueswir1
#endif
3741 576c2cdc Artyom Tarasenko
    /* Don't overwrite translation and access faults */
3742 576c2cdc Artyom Tarasenko
    fault_type = (env->mmuregs[3] & 0x1c) >> 2;
3743 576c2cdc Artyom Tarasenko
    if ((fault_type > 4) || (fault_type == 0)) {
3744 576c2cdc Artyom Tarasenko
        env->mmuregs[3] = 0; /* Fault status register */
3745 576c2cdc Artyom Tarasenko
        if (is_asi)
3746 576c2cdc Artyom Tarasenko
            env->mmuregs[3] |= 1 << 16;
3747 576c2cdc Artyom Tarasenko
        if (env->psrs)
3748 576c2cdc Artyom Tarasenko
            env->mmuregs[3] |= 1 << 5;
3749 576c2cdc Artyom Tarasenko
        if (is_exec)
3750 576c2cdc Artyom Tarasenko
            env->mmuregs[3] |= 1 << 6;
3751 576c2cdc Artyom Tarasenko
        if (is_write)
3752 576c2cdc Artyom Tarasenko
            env->mmuregs[3] |= 1 << 7;
3753 576c2cdc Artyom Tarasenko
        env->mmuregs[3] |= (5 << 2) | 2;
3754 576c2cdc Artyom Tarasenko
        /* SuperSPARC will never place instruction fault addresses in the FAR */
3755 576c2cdc Artyom Tarasenko
        if (!is_exec) {
3756 576c2cdc Artyom Tarasenko
            env->mmuregs[4] = addr; /* Fault address register */
3757 576c2cdc Artyom Tarasenko
        }
3758 576c2cdc Artyom Tarasenko
    }
3759 576c2cdc Artyom Tarasenko
    /* overflow (same type fault was not read before another fault) */
3760 576c2cdc Artyom Tarasenko
    if (fault_type == ((env->mmuregs[3] & 0x1c)) >> 2) {
3761 576c2cdc Artyom Tarasenko
        env->mmuregs[3] |= 1;
3762 576c2cdc Artyom Tarasenko
    }
3763 576c2cdc Artyom Tarasenko
3764 6c36d3fa blueswir1
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
3765 1b2e93c1 blueswir1
        if (is_exec)
3766 1b2e93c1 blueswir1
            raise_exception(TT_CODE_ACCESS);
3767 1b2e93c1 blueswir1
        else
3768 1b2e93c1 blueswir1
            raise_exception(TT_DATA_ACCESS);
3769 6c36d3fa blueswir1
    }
3770 576c2cdc Artyom Tarasenko
3771 576c2cdc Artyom Tarasenko
    /* flush neverland mappings created during no-fault mode,
3772 576c2cdc Artyom Tarasenko
       so the sequential MMU faults report proper fault types */
3773 576c2cdc Artyom Tarasenko
    if (env->mmuregs[0] & MMU_NF) {
3774 576c2cdc Artyom Tarasenko
        tlb_flush(env, 1);
3775 576c2cdc Artyom Tarasenko
    }
3776 15e7c451 Artyom Tarasenko
3777 15e7c451 Artyom Tarasenko
    env = saved_env;
3778 6c36d3fa blueswir1
}
3779 3c7b48b7 Paul Brook
#endif
3780 3c7b48b7 Paul Brook
#else
3781 3c7b48b7 Paul Brook
#if defined(CONFIG_USER_ONLY)
3782 3c7b48b7 Paul Brook
static void do_unassigned_access(target_ulong addr, int is_write, int is_exec,
3783 3c7b48b7 Paul Brook
                          int is_asi, int size)
3784 6c36d3fa blueswir1
#else
3785 c227f099 Anthony Liguori
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
3786 e18231a3 blueswir1
                          int is_asi, int size)
3787 3c7b48b7 Paul Brook
#endif
3788 6c36d3fa blueswir1
{
3789 6c36d3fa blueswir1
    CPUState *saved_env;
3790 6c36d3fa blueswir1
3791 6c36d3fa blueswir1
    /* XXX: hack to restore env in all cases, even if not called from
3792 6c36d3fa blueswir1
       generated code */
3793 6c36d3fa blueswir1
    saved_env = env;
3794 6c36d3fa blueswir1
    env = cpu_single_env;
3795 dffbe217 Igor V. Kovalenko
3796 dffbe217 Igor V. Kovalenko
#ifdef DEBUG_UNASSIGNED
3797 77f193da blueswir1
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
3798 77f193da blueswir1
           "\n", addr, env->pc);
3799 6c36d3fa blueswir1
#endif
3800 dffbe217 Igor V. Kovalenko
3801 1b2e93c1 blueswir1
    if (is_exec)
3802 1b2e93c1 blueswir1
        raise_exception(TT_CODE_ACCESS);
3803 1b2e93c1 blueswir1
    else
3804 1b2e93c1 blueswir1
        raise_exception(TT_DATA_ACCESS);
3805 dffbe217 Igor V. Kovalenko
3806 dffbe217 Igor V. Kovalenko
    env = saved_env;
3807 6c36d3fa blueswir1
}
3808 6c36d3fa blueswir1
#endif
3809 20c9f095 blueswir1
3810 3c7b48b7 Paul Brook
3811 f4b1a842 blueswir1
#ifdef TARGET_SPARC64
3812 f4b1a842 blueswir1
void helper_tick_set_count(void *opaque, uint64_t count)
3813 f4b1a842 blueswir1
{
3814 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3815 f4b1a842 blueswir1
    cpu_tick_set_count(opaque, count);
3816 f4b1a842 blueswir1
#endif
3817 f4b1a842 blueswir1
}
3818 f4b1a842 blueswir1
3819 f4b1a842 blueswir1
uint64_t helper_tick_get_count(void *opaque)
3820 f4b1a842 blueswir1
{
3821 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3822 f4b1a842 blueswir1
    return cpu_tick_get_count(opaque);
3823 f4b1a842 blueswir1
#else
3824 f4b1a842 blueswir1
    return 0;
3825 f4b1a842 blueswir1
#endif
3826 f4b1a842 blueswir1
}
3827 f4b1a842 blueswir1
3828 f4b1a842 blueswir1
void helper_tick_set_limit(void *opaque, uint64_t limit)
3829 f4b1a842 blueswir1
{
3830 f4b1a842 blueswir1
#if !defined(CONFIG_USER_ONLY)
3831 f4b1a842 blueswir1
    cpu_tick_set_limit(opaque, limit);
3832 f4b1a842 blueswir1
#endif
3833 f4b1a842 blueswir1
}
3834 f4b1a842 blueswir1
#endif