Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 6f7e9aec

History | View | Annotate | Download (5.6 kB)

1 e8af50a3 bellard
#include <math.h>
2 e8af50a3 bellard
#include <fenv.h>
3 e8af50a3 bellard
#include "exec.h"
4 e8af50a3 bellard
5 e80cfcfc bellard
//#define DEBUG_MMU
6 e80cfcfc bellard
7 9d893301 bellard
void raise_exception(int tt)
8 9d893301 bellard
{
9 9d893301 bellard
    env->exception_index = tt;
10 9d893301 bellard
    cpu_loop_exit();
11 9d893301 bellard
}   
12 9d893301 bellard
13 a0c4cb4a bellard
#ifdef USE_INT_TO_FLOAT_HELPERS
14 a0c4cb4a bellard
void do_fitos(void)
15 a0c4cb4a bellard
{
16 a0c4cb4a bellard
    FT0 = (float) *((int32_t *)&FT1);
17 a0c4cb4a bellard
}
18 a0c4cb4a bellard
19 a0c4cb4a bellard
void do_fitod(void)
20 a0c4cb4a bellard
{
21 a0c4cb4a bellard
    DT0 = (double) *((int32_t *)&FT1);
22 a0c4cb4a bellard
}
23 a0c4cb4a bellard
#endif
24 a0c4cb4a bellard
25 a0c4cb4a bellard
void do_fabss(void)
26 e8af50a3 bellard
{
27 e8af50a3 bellard
    FT0 = fabsf(FT1);
28 e8af50a3 bellard
}
29 e8af50a3 bellard
30 a0c4cb4a bellard
void do_fsqrts(void)
31 e8af50a3 bellard
{
32 e8af50a3 bellard
    FT0 = sqrtf(FT1);
33 e8af50a3 bellard
}
34 e8af50a3 bellard
35 a0c4cb4a bellard
void do_fsqrtd(void)
36 e8af50a3 bellard
{
37 e8af50a3 bellard
    DT0 = sqrt(DT1);
38 e8af50a3 bellard
}
39 e8af50a3 bellard
40 a0c4cb4a bellard
void do_fcmps (void)
41 e8af50a3 bellard
{
42 e8af50a3 bellard
    if (isnan(FT0) || isnan(FT1)) {
43 e8af50a3 bellard
        T0 = FSR_FCC1 | FSR_FCC0;
44 e80cfcfc bellard
        env->fsr &= ~(FSR_FCC1 | FSR_FCC0);
45 e80cfcfc bellard
        env->fsr |= T0;
46 e80cfcfc bellard
        if (env->fsr & FSR_NVM) {
47 e80cfcfc bellard
            raise_exception(TT_FP_EXCP);
48 e80cfcfc bellard
        } else {
49 e80cfcfc bellard
            env->fsr |= FSR_NVA;
50 e80cfcfc bellard
        }
51 e8af50a3 bellard
    } else if (FT0 < FT1) {
52 e8af50a3 bellard
        T0 = FSR_FCC0;
53 e8af50a3 bellard
    } else if (FT0 > FT1) {
54 e8af50a3 bellard
        T0 = FSR_FCC1;
55 e8af50a3 bellard
    } else {
56 e8af50a3 bellard
        T0 = 0;
57 e8af50a3 bellard
    }
58 e8af50a3 bellard
    env->fsr = T0;
59 e8af50a3 bellard
}
60 e8af50a3 bellard
61 a0c4cb4a bellard
void do_fcmpd (void)
62 e8af50a3 bellard
{
63 e8af50a3 bellard
    if (isnan(DT0) || isnan(DT1)) {
64 e8af50a3 bellard
        T0 = FSR_FCC1 | FSR_FCC0;
65 e80cfcfc bellard
        env->fsr &= ~(FSR_FCC1 | FSR_FCC0);
66 e80cfcfc bellard
        env->fsr |= T0;
67 e80cfcfc bellard
        if (env->fsr & FSR_NVM) {
68 e80cfcfc bellard
            raise_exception(TT_FP_EXCP);
69 e80cfcfc bellard
        } else {
70 e80cfcfc bellard
            env->fsr |= FSR_NVA;
71 e80cfcfc bellard
        }
72 e8af50a3 bellard
    } else if (DT0 < DT1) {
73 e8af50a3 bellard
        T0 = FSR_FCC0;
74 e8af50a3 bellard
    } else if (DT0 > DT1) {
75 e8af50a3 bellard
        T0 = FSR_FCC1;
76 e8af50a3 bellard
    } else {
77 e8af50a3 bellard
        T0 = 0;
78 e8af50a3 bellard
    }
79 e8af50a3 bellard
    env->fsr = T0;
80 e8af50a3 bellard
}
81 e8af50a3 bellard
82 a0c4cb4a bellard
void helper_ld_asi(int asi, int size, int sign)
83 e8af50a3 bellard
{
84 e80cfcfc bellard
    uint32_t ret;
85 e80cfcfc bellard
86 e80cfcfc bellard
    switch (asi) {
87 e8af50a3 bellard
    case 3: /* MMU probe */
88 e80cfcfc bellard
        {
89 e80cfcfc bellard
            int mmulev;
90 e80cfcfc bellard
91 e80cfcfc bellard
            mmulev = (T0 >> 8) & 15;
92 e80cfcfc bellard
            if (mmulev > 4)
93 e80cfcfc bellard
                ret = 0;
94 e80cfcfc bellard
            else {
95 e80cfcfc bellard
                ret = mmu_probe(T0, mmulev);
96 e80cfcfc bellard
                //bswap32s(&ret);
97 e80cfcfc bellard
            }
98 e80cfcfc bellard
#ifdef DEBUG_MMU
99 e80cfcfc bellard
            printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
100 e80cfcfc bellard
#endif
101 e80cfcfc bellard
        }
102 e80cfcfc bellard
        break;
103 e8af50a3 bellard
    case 4: /* read MMU regs */
104 e8af50a3 bellard
        {
105 e80cfcfc bellard
            int reg = (T0 >> 8) & 0xf;
106 e8af50a3 bellard
            
107 e80cfcfc bellard
            ret = env->mmuregs[reg];
108 55754d9e bellard
            if (reg == 3) /* Fault status cleared on read */
109 55754d9e bellard
                env->mmuregs[reg] = 0;
110 55754d9e bellard
#ifdef DEBUG_MMU
111 55754d9e bellard
            printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
112 55754d9e bellard
#endif
113 e8af50a3 bellard
        }
114 e80cfcfc bellard
        break;
115 e8af50a3 bellard
    case 0x20 ... 0x2f: /* MMU passthrough */
116 e80cfcfc bellard
        cpu_physical_memory_read(T0, (void *) &ret, size);
117 e80cfcfc bellard
        if (size == 4)
118 49be8030 bellard
            tswap32s(&ret);
119 49be8030 bellard
        else if (size == 2)
120 49be8030 bellard
            tswap16s((uint16_t *)&ret);
121 e80cfcfc bellard
        break;
122 e8af50a3 bellard
    default:
123 e80cfcfc bellard
        ret = 0;
124 e80cfcfc bellard
        break;
125 e8af50a3 bellard
    }
126 e80cfcfc bellard
    T1 = ret;
127 e8af50a3 bellard
}
128 e8af50a3 bellard
129 a0c4cb4a bellard
void helper_st_asi(int asi, int size, int sign)
130 e8af50a3 bellard
{
131 e8af50a3 bellard
    switch(asi) {
132 e8af50a3 bellard
    case 3: /* MMU flush */
133 e80cfcfc bellard
        {
134 e80cfcfc bellard
            int mmulev;
135 e80cfcfc bellard
136 e80cfcfc bellard
            mmulev = (T0 >> 8) & 15;
137 55754d9e bellard
#ifdef DEBUG_MMU
138 55754d9e bellard
            printf("mmu flush level %d\n", mmulev);
139 55754d9e bellard
#endif
140 e80cfcfc bellard
            switch (mmulev) {
141 e80cfcfc bellard
            case 0: // flush page
142 55754d9e bellard
                tlb_flush_page(env, T0 & 0xfffff000);
143 e80cfcfc bellard
                break;
144 e80cfcfc bellard
            case 1: // flush segment (256k)
145 e80cfcfc bellard
            case 2: // flush region (16M)
146 e80cfcfc bellard
            case 3: // flush context (4G)
147 e80cfcfc bellard
            case 4: // flush entire
148 55754d9e bellard
                tlb_flush(env, 1);
149 e80cfcfc bellard
                break;
150 e80cfcfc bellard
            default:
151 e80cfcfc bellard
                break;
152 e80cfcfc bellard
            }
153 55754d9e bellard
#ifdef DEBUG_MMU
154 e80cfcfc bellard
            dump_mmu();
155 55754d9e bellard
#endif
156 e80cfcfc bellard
            return;
157 e80cfcfc bellard
        }
158 e8af50a3 bellard
    case 4: /* write MMU regs */
159 e8af50a3 bellard
        {
160 e80cfcfc bellard
            int reg = (T0 >> 8) & 0xf, oldreg;
161 e80cfcfc bellard
            
162 e80cfcfc bellard
            oldreg = env->mmuregs[reg];
163 55754d9e bellard
            switch(reg) {
164 55754d9e bellard
            case 0:
165 e8af50a3 bellard
                env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
166 e8af50a3 bellard
                env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
167 6f7e9aec bellard
                // Mappings generated during no-fault mode or MMU
168 6f7e9aec bellard
                // disabled mode are invalid in normal mode
169 6f7e9aec bellard
                if (oldreg != env->mmuregs[reg])
170 55754d9e bellard
                    tlb_flush(env, 1);
171 55754d9e bellard
                break;
172 55754d9e bellard
            case 2:
173 e8af50a3 bellard
                env->mmuregs[reg] = T1;
174 55754d9e bellard
                if (oldreg != env->mmuregs[reg]) {
175 55754d9e bellard
                    /* we flush when the MMU context changes because
176 55754d9e bellard
                       QEMU has no MMU context support */
177 55754d9e bellard
                    tlb_flush(env, 1);
178 55754d9e bellard
                }
179 55754d9e bellard
                break;
180 55754d9e bellard
            case 3:
181 55754d9e bellard
            case 4:
182 55754d9e bellard
                break;
183 55754d9e bellard
            default:
184 55754d9e bellard
                env->mmuregs[reg] = T1;
185 55754d9e bellard
                break;
186 55754d9e bellard
            }
187 55754d9e bellard
#ifdef DEBUG_MMU
188 55754d9e bellard
            if (oldreg != env->mmuregs[reg]) {
189 55754d9e bellard
                printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
190 55754d9e bellard
            }
191 e80cfcfc bellard
            dump_mmu();
192 55754d9e bellard
#endif
193 e8af50a3 bellard
            return;
194 e8af50a3 bellard
        }
195 e80cfcfc bellard
    case 0x17: /* Block copy, sta access */
196 e80cfcfc bellard
        {
197 e80cfcfc bellard
            // value (T1) = src
198 e80cfcfc bellard
            // address (T0) = dst
199 e80cfcfc bellard
            // copy 32 bytes
200 e80cfcfc bellard
            int src = T1, dst = T0;
201 e80cfcfc bellard
            uint8_t temp[32];
202 e80cfcfc bellard
            
203 49be8030 bellard
            tswap32s(&src);
204 e80cfcfc bellard
205 e80cfcfc bellard
            cpu_physical_memory_read(src, (void *) &temp, 32);
206 e80cfcfc bellard
            cpu_physical_memory_write(dst, (void *) &temp, 32);
207 e80cfcfc bellard
        }
208 e80cfcfc bellard
        return;
209 e80cfcfc bellard
    case 0x1f: /* Block fill, stda access */
210 e80cfcfc bellard
        {
211 e80cfcfc bellard
            // value (T1, T2)
212 e80cfcfc bellard
            // address (T0) = dst
213 e80cfcfc bellard
            // fill 32 bytes
214 e80cfcfc bellard
            int i, dst = T0;
215 e80cfcfc bellard
            uint64_t val;
216 e80cfcfc bellard
            
217 e80cfcfc bellard
            val = (((uint64_t)T1) << 32) | T2;
218 49be8030 bellard
            tswap64s(&val);
219 e80cfcfc bellard
220 e80cfcfc bellard
            for (i = 0; i < 32; i += 8, dst += 8) {
221 e80cfcfc bellard
                cpu_physical_memory_write(dst, (void *) &val, 8);
222 e80cfcfc bellard
            }
223 e80cfcfc bellard
        }
224 e80cfcfc bellard
        return;
225 e8af50a3 bellard
    case 0x20 ... 0x2f: /* MMU passthrough */
226 e8af50a3 bellard
        {
227 e8af50a3 bellard
            int temp = T1;
228 e80cfcfc bellard
            if (size == 4)
229 49be8030 bellard
                tswap32s(&temp);
230 e80cfcfc bellard
            else if (size == 2)
231 49be8030 bellard
                tswap16s((uint16_t *)&temp);
232 e8af50a3 bellard
            cpu_physical_memory_write(T0, (void *) &temp, size);
233 e8af50a3 bellard
        }
234 e8af50a3 bellard
        return;
235 e8af50a3 bellard
    default:
236 e8af50a3 bellard
        return;
237 e8af50a3 bellard
    }
238 e8af50a3 bellard
}
239 e8af50a3 bellard
240 a0c4cb4a bellard
void helper_rett()
241 e8af50a3 bellard
{
242 af7bf89b bellard
    unsigned int cwp;
243 af7bf89b bellard
244 e8af50a3 bellard
    env->psret = 1;
245 e8af50a3 bellard
    cwp = (env->cwp + 1) & (NWINDOWS - 1); 
246 e8af50a3 bellard
    if (env->wim & (1 << cwp)) {
247 e8af50a3 bellard
        raise_exception(TT_WIN_UNF);
248 e8af50a3 bellard
    }
249 e8af50a3 bellard
    set_cwp(cwp);
250 e8af50a3 bellard
    env->psrs = env->psrps;
251 e8af50a3 bellard
}
252 e8af50a3 bellard
253 8d5f07fa bellard
void helper_ldfsr(void)
254 e8af50a3 bellard
{
255 e8af50a3 bellard
    switch (env->fsr & FSR_RD_MASK) {
256 e8af50a3 bellard
    case FSR_RD_NEAREST:
257 e8af50a3 bellard
        fesetround(FE_TONEAREST);
258 e8af50a3 bellard
        break;
259 e8af50a3 bellard
    case FSR_RD_ZERO:
260 e8af50a3 bellard
        fesetround(FE_TOWARDZERO);
261 e8af50a3 bellard
        break;
262 e8af50a3 bellard
    case FSR_RD_POS:
263 e8af50a3 bellard
        fesetround(FE_UPWARD);
264 e8af50a3 bellard
        break;
265 e8af50a3 bellard
    case FSR_RD_NEG:
266 e8af50a3 bellard
        fesetround(FE_DOWNWARD);
267 e8af50a3 bellard
        break;
268 e8af50a3 bellard
    }
269 e8af50a3 bellard
}
270 e80cfcfc bellard
271 e80cfcfc bellard
void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f)
272 e80cfcfc bellard
{
273 e80cfcfc bellard
    int exptemp;
274 e80cfcfc bellard
275 e80cfcfc bellard
    *pmant = ldexp(frexp(f, &exptemp), 53);
276 e80cfcfc bellard
    *pexp = exptemp;
277 e80cfcfc bellard
}
278 e80cfcfc bellard
279 e80cfcfc bellard
double cpu_put_fp64(uint64_t mant, uint16_t exp)
280 e80cfcfc bellard
{
281 e80cfcfc bellard
    return ldexp((double) mant, exp - 53);
282 e80cfcfc bellard
}
283 e80cfcfc bellard
284 e80cfcfc bellard
void helper_debug()
285 e80cfcfc bellard
{
286 e80cfcfc bellard
    env->exception_index = EXCP_DEBUG;
287 e80cfcfc bellard
    cpu_loop_exit();
288 e80cfcfc bellard
}
289 af7bf89b bellard
290 af7bf89b bellard
void do_wrpsr()
291 af7bf89b bellard
{
292 af7bf89b bellard
    PUT_PSR(env, T0);
293 af7bf89b bellard
}
294 af7bf89b bellard
295 af7bf89b bellard
void do_rdpsr()
296 af7bf89b bellard
{
297 af7bf89b bellard
    T0 = GET_PSR(env);
298 af7bf89b bellard
}