Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ afc7df11

History | View | Annotate | Download (4.9 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 e8af50a3 bellard
            if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/
109 e80cfcfc bellard
                env->mmuregs[4] = 0;
110 e8af50a3 bellard
        }
111 e80cfcfc bellard
        break;
112 e8af50a3 bellard
    case 0x20 ... 0x2f: /* MMU passthrough */
113 e80cfcfc bellard
        cpu_physical_memory_read(T0, (void *) &ret, size);
114 e80cfcfc bellard
        if (size == 4)
115 49be8030 bellard
            tswap32s(&ret);
116 49be8030 bellard
        else if (size == 2)
117 49be8030 bellard
            tswap16s((uint16_t *)&ret);
118 e80cfcfc bellard
        break;
119 e8af50a3 bellard
    default:
120 e80cfcfc bellard
        ret = 0;
121 e80cfcfc bellard
        break;
122 e8af50a3 bellard
    }
123 e80cfcfc bellard
    T1 = ret;
124 e8af50a3 bellard
}
125 e8af50a3 bellard
126 a0c4cb4a bellard
void helper_st_asi(int asi, int size, int sign)
127 e8af50a3 bellard
{
128 e8af50a3 bellard
    switch(asi) {
129 e8af50a3 bellard
    case 3: /* MMU flush */
130 e80cfcfc bellard
        {
131 e80cfcfc bellard
            int mmulev;
132 e80cfcfc bellard
133 e80cfcfc bellard
            mmulev = (T0 >> 8) & 15;
134 e80cfcfc bellard
            switch (mmulev) {
135 e80cfcfc bellard
            case 0: // flush page
136 e80cfcfc bellard
                tlb_flush_page(cpu_single_env, T0 & 0xfffff000);
137 e80cfcfc bellard
                break;
138 e80cfcfc bellard
            case 1: // flush segment (256k)
139 e80cfcfc bellard
            case 2: // flush region (16M)
140 e80cfcfc bellard
            case 3: // flush context (4G)
141 e80cfcfc bellard
            case 4: // flush entire
142 e80cfcfc bellard
                tlb_flush(cpu_single_env, 1);
143 e80cfcfc bellard
                break;
144 e80cfcfc bellard
            default:
145 e80cfcfc bellard
                break;
146 e80cfcfc bellard
            }
147 e80cfcfc bellard
            dump_mmu();
148 e80cfcfc bellard
            return;
149 e80cfcfc bellard
        }
150 e8af50a3 bellard
    case 4: /* write MMU regs */
151 e8af50a3 bellard
        {
152 e80cfcfc bellard
            int reg = (T0 >> 8) & 0xf, oldreg;
153 e80cfcfc bellard
            
154 e80cfcfc bellard
            oldreg = env->mmuregs[reg];
155 e8af50a3 bellard
            if (reg == 0) {
156 e8af50a3 bellard
                env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
157 e8af50a3 bellard
                env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
158 e8af50a3 bellard
            } else
159 e8af50a3 bellard
                env->mmuregs[reg] = T1;
160 e80cfcfc bellard
            if (oldreg != env->mmuregs[reg]) {
161 e80cfcfc bellard
#if 0
162 e80cfcfc bellard
                // XXX: Only if MMU mapping change, we may need to flush?
163 e80cfcfc bellard
                tlb_flush(cpu_single_env, 1);
164 e80cfcfc bellard
                cpu_loop_exit();
165 e80cfcfc bellard
                FORCE_RET();
166 e80cfcfc bellard
#endif
167 e80cfcfc bellard
            }
168 e80cfcfc bellard
            dump_mmu();
169 e8af50a3 bellard
            return;
170 e8af50a3 bellard
        }
171 e80cfcfc bellard
    case 0x17: /* Block copy, sta access */
172 e80cfcfc bellard
        {
173 e80cfcfc bellard
            // value (T1) = src
174 e80cfcfc bellard
            // address (T0) = dst
175 e80cfcfc bellard
            // copy 32 bytes
176 e80cfcfc bellard
            int src = T1, dst = T0;
177 e80cfcfc bellard
            uint8_t temp[32];
178 e80cfcfc bellard
            
179 49be8030 bellard
            tswap32s(&src);
180 e80cfcfc bellard
181 e80cfcfc bellard
            cpu_physical_memory_read(src, (void *) &temp, 32);
182 e80cfcfc bellard
            cpu_physical_memory_write(dst, (void *) &temp, 32);
183 e80cfcfc bellard
        }
184 e80cfcfc bellard
        return;
185 e80cfcfc bellard
    case 0x1f: /* Block fill, stda access */
186 e80cfcfc bellard
        {
187 e80cfcfc bellard
            // value (T1, T2)
188 e80cfcfc bellard
            // address (T0) = dst
189 e80cfcfc bellard
            // fill 32 bytes
190 e80cfcfc bellard
            int i, dst = T0;
191 e80cfcfc bellard
            uint64_t val;
192 e80cfcfc bellard
            
193 e80cfcfc bellard
            val = (((uint64_t)T1) << 32) | T2;
194 49be8030 bellard
            tswap64s(&val);
195 e80cfcfc bellard
196 e80cfcfc bellard
            for (i = 0; i < 32; i += 8, dst += 8) {
197 e80cfcfc bellard
                cpu_physical_memory_write(dst, (void *) &val, 8);
198 e80cfcfc bellard
            }
199 e80cfcfc bellard
        }
200 e80cfcfc bellard
        return;
201 e8af50a3 bellard
    case 0x20 ... 0x2f: /* MMU passthrough */
202 e8af50a3 bellard
        {
203 e8af50a3 bellard
            int temp = T1;
204 e80cfcfc bellard
            if (size == 4)
205 49be8030 bellard
                tswap32s(&temp);
206 e80cfcfc bellard
            else if (size == 2)
207 49be8030 bellard
                tswap16s((uint16_t *)&temp);
208 e8af50a3 bellard
            cpu_physical_memory_write(T0, (void *) &temp, size);
209 e8af50a3 bellard
        }
210 e8af50a3 bellard
        return;
211 e8af50a3 bellard
    default:
212 e8af50a3 bellard
        return;
213 e8af50a3 bellard
    }
214 e8af50a3 bellard
}
215 e8af50a3 bellard
216 a0c4cb4a bellard
void helper_rett()
217 e8af50a3 bellard
{
218 af7bf89b bellard
    unsigned int cwp;
219 af7bf89b bellard
220 e8af50a3 bellard
    env->psret = 1;
221 e8af50a3 bellard
    cwp = (env->cwp + 1) & (NWINDOWS - 1); 
222 e8af50a3 bellard
    if (env->wim & (1 << cwp)) {
223 e8af50a3 bellard
        raise_exception(TT_WIN_UNF);
224 e8af50a3 bellard
    }
225 e8af50a3 bellard
    set_cwp(cwp);
226 e8af50a3 bellard
    env->psrs = env->psrps;
227 e8af50a3 bellard
}
228 e8af50a3 bellard
229 8d5f07fa bellard
void helper_ldfsr(void)
230 e8af50a3 bellard
{
231 e8af50a3 bellard
    switch (env->fsr & FSR_RD_MASK) {
232 e8af50a3 bellard
    case FSR_RD_NEAREST:
233 e8af50a3 bellard
        fesetround(FE_TONEAREST);
234 e8af50a3 bellard
        break;
235 e8af50a3 bellard
    case FSR_RD_ZERO:
236 e8af50a3 bellard
        fesetround(FE_TOWARDZERO);
237 e8af50a3 bellard
        break;
238 e8af50a3 bellard
    case FSR_RD_POS:
239 e8af50a3 bellard
        fesetround(FE_UPWARD);
240 e8af50a3 bellard
        break;
241 e8af50a3 bellard
    case FSR_RD_NEG:
242 e8af50a3 bellard
        fesetround(FE_DOWNWARD);
243 e8af50a3 bellard
        break;
244 e8af50a3 bellard
    }
245 e8af50a3 bellard
}
246 e80cfcfc bellard
247 e80cfcfc bellard
void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f)
248 e80cfcfc bellard
{
249 e80cfcfc bellard
    int exptemp;
250 e80cfcfc bellard
251 e80cfcfc bellard
    *pmant = ldexp(frexp(f, &exptemp), 53);
252 e80cfcfc bellard
    *pexp = exptemp;
253 e80cfcfc bellard
}
254 e80cfcfc bellard
255 e80cfcfc bellard
double cpu_put_fp64(uint64_t mant, uint16_t exp)
256 e80cfcfc bellard
{
257 e80cfcfc bellard
    return ldexp((double) mant, exp - 53);
258 e80cfcfc bellard
}
259 e80cfcfc bellard
260 e80cfcfc bellard
void helper_debug()
261 e80cfcfc bellard
{
262 e80cfcfc bellard
    env->exception_index = EXCP_DEBUG;
263 e80cfcfc bellard
    cpu_loop_exit();
264 e80cfcfc bellard
}
265 af7bf89b bellard
266 af7bf89b bellard
void do_wrpsr()
267 af7bf89b bellard
{
268 af7bf89b bellard
    PUT_PSR(env, T0);
269 af7bf89b bellard
}
270 af7bf89b bellard
271 af7bf89b bellard
void do_rdpsr()
272 af7bf89b bellard
{
273 af7bf89b bellard
    T0 = GET_PSR(env);
274 af7bf89b bellard
}