]>
git.proxmox.com Git - mirror_qemu.git/blob - target-sparc/op_helper.c
5 void raise_exception(int tt
)
7 env
->exception_index
= tt
;
11 #ifdef USE_INT_TO_FLOAT_HELPERS
14 FT0
= (float) *((int32_t *)&FT1
);
19 DT0
= (double) *((int32_t *)&FT1
);
25 FT0
= float32_abs(FT1
);
30 FT0
= float32_sqrt(FT1
, &env
->fp_status
);
35 DT0
= float64_sqrt(DT1
, &env
->fp_status
);
40 if (isnan(FT0
) || isnan(FT1
)) {
41 T0
= FSR_FCC1
| FSR_FCC0
;
42 env
->fsr
&= ~(FSR_FCC1
| FSR_FCC0
);
44 if (env
->fsr
& FSR_NVM
) {
45 raise_exception(TT_FP_EXCP
);
49 } else if (FT0
< FT1
) {
51 } else if (FT0
> FT1
) {
61 if (isnan(DT0
) || isnan(DT1
)) {
62 T0
= FSR_FCC1
| FSR_FCC0
;
63 env
->fsr
&= ~(FSR_FCC1
| FSR_FCC0
);
65 if (env
->fsr
& FSR_NVM
) {
66 raise_exception(TT_FP_EXCP
);
70 } else if (DT0
< DT1
) {
72 } else if (DT0
> DT1
) {
80 void helper_ld_asi(int asi
, int size
, int sign
)
85 case 3: /* MMU probe */
89 mmulev
= (T0
>> 8) & 15;
93 ret
= mmu_probe(T0
, mmulev
);
97 printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0
, mmulev
, ret
);
101 case 4: /* read MMU regs */
103 int reg
= (T0
>> 8) & 0xf;
105 ret
= env
->mmuregs
[reg
];
106 if (reg
== 3) /* Fault status cleared on read */
107 env
->mmuregs
[reg
] = 0;
109 printf("mmu_read: reg[%d] = 0x%08x\n", reg
, ret
);
113 case 0x20 ... 0x2f: /* MMU passthrough */
114 cpu_physical_memory_read(T0
, (void *) &ret
, size
);
118 tswap16s((uint16_t *)&ret
);
127 void helper_st_asi(int asi
, int size
, int sign
)
130 case 3: /* MMU flush */
134 mmulev
= (T0
>> 8) & 15;
136 printf("mmu flush level %d\n", mmulev
);
139 case 0: // flush page
140 tlb_flush_page(env
, T0
& 0xfffff000);
142 case 1: // flush segment (256k)
143 case 2: // flush region (16M)
144 case 3: // flush context (4G)
145 case 4: // flush entire
156 case 4: /* write MMU regs */
158 int reg
= (T0
>> 8) & 0xf, oldreg
;
160 oldreg
= env
->mmuregs
[reg
];
163 env
->mmuregs
[reg
] &= ~(MMU_E
| MMU_NF
);
164 env
->mmuregs
[reg
] |= T1
& (MMU_E
| MMU_NF
);
165 // Mappings generated during no-fault mode or MMU
166 // disabled mode are invalid in normal mode
167 if (oldreg
!= env
->mmuregs
[reg
])
171 env
->mmuregs
[reg
] = T1
;
172 if (oldreg
!= env
->mmuregs
[reg
]) {
173 /* we flush when the MMU context changes because
174 QEMU has no MMU context support */
182 env
->mmuregs
[reg
] = T1
;
186 if (oldreg
!= env
->mmuregs
[reg
]) {
187 printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg
, oldreg
, env
->mmuregs
[reg
]);
193 case 0x17: /* Block copy, sta access */
196 // address (T0) = dst
198 int src
= T1
, dst
= T0
;
203 cpu_physical_memory_read(src
, (void *) &temp
, 32);
204 cpu_physical_memory_write(dst
, (void *) &temp
, 32);
207 case 0x1f: /* Block fill, stda access */
210 // address (T0) = dst
215 val
= (((uint64_t)T1
) << 32) | T2
;
218 for (i
= 0; i
< 32; i
+= 8, dst
+= 8) {
219 cpu_physical_memory_write(dst
, (void *) &val
, 8);
223 case 0x20 ... 0x2f: /* MMU passthrough */
229 tswap16s((uint16_t *)&temp
);
230 cpu_physical_memory_write(T0
, (void *) &temp
, size
);
243 cwp
= (env
->cwp
+ 1) & (NWINDOWS
- 1);
244 if (env
->wim
& (1 << cwp
)) {
245 raise_exception(TT_WIN_UNF
);
248 env
->psrs
= env
->psrps
;
251 void helper_ldfsr(void)
254 switch (env
->fsr
& FSR_RD_MASK
) {
256 rnd_mode
= float_round_nearest_even
;
260 rnd_mode
= float_round_to_zero
;
263 rnd_mode
= float_round_up
;
266 rnd_mode
= float_round_down
;
269 set_float_rounding_mode(rnd_mode
, &env
->fp_status
);
272 void cpu_get_fp64(uint64_t *pmant
, uint16_t *pexp
, double f
)
276 *pmant
= ldexp(frexp(f
, &exptemp
), 53);
280 double cpu_put_fp64(uint64_t mant
, uint16_t exp
)
282 return ldexp((double) mant
, exp
- 53);
287 env
->exception_index
= EXCP_DEBUG
;