Revision e80cfcfc target-sparc/op_helper.c

b/target-sparc/op_helper.c
2 2
#include <fenv.h>
3 3
#include "exec.h"
4 4

  
5
//#define DEBUG_MMU
6

  
5 7
#ifdef USE_INT_TO_FLOAT_HELPERS
6 8
void do_fitos(void)
7 9
{
......
33 35
{
34 36
    if (isnan(FT0) || isnan(FT1)) {
35 37
        T0 = FSR_FCC1 | FSR_FCC0;
38
	env->fsr &= ~(FSR_FCC1 | FSR_FCC0);
39
	env->fsr |= T0;
40
	if (env->fsr & FSR_NVM) {
41
	    raise_exception(TT_FP_EXCP);
42
	} else {
43
	    env->fsr |= FSR_NVA;
44
	}
36 45
    } else if (FT0 < FT1) {
37 46
        T0 = FSR_FCC0;
38 47
    } else if (FT0 > FT1) {
......
47 56
{
48 57
    if (isnan(DT0) || isnan(DT1)) {
49 58
        T0 = FSR_FCC1 | FSR_FCC0;
59
	env->fsr &= ~(FSR_FCC1 | FSR_FCC0);
60
	env->fsr |= T0;
61
	if (env->fsr & FSR_NVM) {
62
	    raise_exception(TT_FP_EXCP);
63
	} else {
64
	    env->fsr |= FSR_NVA;
65
	}
50 66
    } else if (DT0 < DT1) {
51 67
        T0 = FSR_FCC0;
52 68
    } else if (DT0 > DT1) {
......
59 75

  
60 76
void helper_ld_asi(int asi, int size, int sign)
61 77
{
62
    switch(asi) {
78
    uint32_t ret;
79

  
80
    switch (asi) {
63 81
    case 3: /* MMU probe */
64
	T1 = 0;
65
	return;
82
	{
83
	    int mmulev;
84

  
85
	    mmulev = (T0 >> 8) & 15;
86
	    if (mmulev > 4)
87
		ret = 0;
88
	    else {
89
		ret = mmu_probe(T0, mmulev);
90
		//bswap32s(&ret);
91
	    }
92
#ifdef DEBUG_MMU
93
	    printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
94
#endif
95
	}
96
	break;
66 97
    case 4: /* read MMU regs */
67 98
	{
68
	    int temp, reg = (T0 >> 8) & 0xf;
99
	    int reg = (T0 >> 8) & 0xf;
69 100
	    
70
	    temp = env->mmuregs[reg];
101
	    ret = env->mmuregs[reg];
71 102
	    if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/
72
		env->mmuregs[reg] = 0;
73
	    T1 = temp;
103
		env->mmuregs[4] = 0;
74 104
	}
75
	return;
105
	break;
76 106
    case 0x20 ... 0x2f: /* MMU passthrough */
77
	{
78
	    int temp;
79
	    
80
	    cpu_physical_memory_read(T0, (void *) &temp, size);
81
	    bswap32s(&temp);
82
	    T1 = temp;
83
	}
84
	return;
107
	cpu_physical_memory_read(T0, (void *) &ret, size);
108
	if (size == 4)
109
	    bswap32s(&ret);
110
	else if (size == 2)
111
	    bswap16s(&ret);
112
	break;
85 113
    default:
86
	T1 = 0;
87
	return;
114
	ret = 0;
115
	break;
88 116
    }
117
    T1 = ret;
89 118
}
90 119

  
91 120
void helper_st_asi(int asi, int size, int sign)
92 121
{
93 122
    switch(asi) {
94 123
    case 3: /* MMU flush */
95
	return;
124
	{
125
	    int mmulev;
126

  
127
	    mmulev = (T0 >> 8) & 15;
128
	    switch (mmulev) {
129
	    case 0: // flush page
130
		tlb_flush_page(cpu_single_env, T0 & 0xfffff000);
131
		break;
132
	    case 1: // flush segment (256k)
133
	    case 2: // flush region (16M)
134
	    case 3: // flush context (4G)
135
	    case 4: // flush entire
136
		tlb_flush(cpu_single_env, 1);
137
		break;
138
	    default:
139
		break;
140
	    }
141
	    dump_mmu();
142
	    return;
143
	}
96 144
    case 4: /* write MMU regs */
97 145
	{
98
	    int reg = (T0 >> 8) & 0xf;
146
	    int reg = (T0 >> 8) & 0xf, oldreg;
147
	    
148
	    oldreg = env->mmuregs[reg];
99 149
	    if (reg == 0) {
100 150
		env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
101 151
		env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
102 152
	    } else
103 153
		env->mmuregs[reg] = T1;
154
	    if (oldreg != env->mmuregs[reg]) {
155
#if 0
156
		// XXX: Only if MMU mapping change, we may need to flush?
157
		tlb_flush(cpu_single_env, 1);
158
		cpu_loop_exit();
159
		FORCE_RET();
160
#endif
161
	    }
162
	    dump_mmu();
104 163
	    return;
105 164
	}
165
    case 0x17: /* Block copy, sta access */
166
	{
167
	    // value (T1) = src
168
	    // address (T0) = dst
169
	    // copy 32 bytes
170
	    int src = T1, dst = T0;
171
	    uint8_t temp[32];
172
	    
173
	    bswap32s(&src);
174

  
175
	    cpu_physical_memory_read(src, (void *) &temp, 32);
176
	    cpu_physical_memory_write(dst, (void *) &temp, 32);
177
	}
178
	return;
179
    case 0x1f: /* Block fill, stda access */
180
	{
181
	    // value (T1, T2)
182
	    // address (T0) = dst
183
	    // fill 32 bytes
184
	    int i, dst = T0;
185
	    uint64_t val;
186
	    
187
	    val = (((uint64_t)T1) << 32) | T2;
188
	    bswap64s(&val);
189

  
190
	    for (i = 0; i < 32; i += 8, dst += 8) {
191
		cpu_physical_memory_write(dst, (void *) &val, 8);
192
	    }
193
	}
194
	return;
106 195
    case 0x20 ... 0x2f: /* MMU passthrough */
107 196
	{
108 197
	    int temp = T1;
109
	    
110
	    bswap32s(&temp);
198
	    if (size == 4)
199
		bswap32s(&temp);
200
	    else if (size == 2)
201
		bswap16s(&temp);
202

  
111 203
	    cpu_physical_memory_write(T0, (void *) &temp, size);
112 204
	}
113 205
	return;
......
116 208
    }
117 209
}
118 210

  
119
#if 0
120
void do_ldd_raw(uint32_t addr)
121
{
122
    T1 = ldl_raw((void *) addr);
123
    T0 = ldl_raw((void *) (addr + 4));
124
}
125

  
126
#if !defined(CONFIG_USER_ONLY)
127
void do_ldd_user(uint32_t addr)
128
{
129
    T1 = ldl_user((void *) addr);
130
    T0 = ldl_user((void *) (addr + 4));
131
}
132
void do_ldd_kernel(uint32_t addr)
133
{
134
    T1 = ldl_kernel((void *) addr);
135
    T0 = ldl_kernel((void *) (addr + 4));
136
}
137
#endif
138
#endif
139

  
140 211
void helper_rett()
141 212
{
142 213
    int cwp;
......
166 237
	break;
167 238
    }
168 239
}
240

  
241
void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f)
242
{
243
    int exptemp;
244

  
245
    *pmant = ldexp(frexp(f, &exptemp), 53);
246
    *pexp = exptemp;
247
}
248

  
249
double cpu_put_fp64(uint64_t mant, uint16_t exp)
250
{
251
    return ldexp((double) mant, exp - 53);
252
}
253

  
254
void helper_debug()
255
{
256
    env->exception_index = EXCP_DEBUG;
257
    cpu_loop_exit();
258
}

Also available in: Unified diff