root / target-sh4 / op_helper.c @ db8d9902
History | View | Annotate | Download (10.6 kB)
1 | fdf9b3e8 | bellard | /*
|
---|---|---|---|
2 | fdf9b3e8 | bellard | * SH4 emulation
|
3 | 5fafdf24 | ths | *
|
4 | fdf9b3e8 | bellard | * Copyright (c) 2005 Samuel Tardieu
|
5 | fdf9b3e8 | bellard | *
|
6 | fdf9b3e8 | bellard | * This library is free software; you can redistribute it and/or
|
7 | fdf9b3e8 | bellard | * modify it under the terms of the GNU Lesser General Public
|
8 | fdf9b3e8 | bellard | * License as published by the Free Software Foundation; either
|
9 | fdf9b3e8 | bellard | * version 2 of the License, or (at your option) any later version.
|
10 | fdf9b3e8 | bellard | *
|
11 | fdf9b3e8 | bellard | * This library is distributed in the hope that it will be useful,
|
12 | fdf9b3e8 | bellard | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | fdf9b3e8 | bellard | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | fdf9b3e8 | bellard | * Lesser General Public License for more details.
|
15 | fdf9b3e8 | bellard | *
|
16 | fdf9b3e8 | bellard | * You should have received a copy of the GNU Lesser General Public
|
17 | fdf9b3e8 | bellard | * License along with this library; if not, write to the Free Software
|
18 | fdf9b3e8 | bellard | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19 | fdf9b3e8 | bellard | */
|
20 | fdf9b3e8 | bellard | #include <assert.h> |
21 | fdf9b3e8 | bellard | #include "exec.h" |
22 | a7812ae4 | pbrook | #include "helper.h" |
23 | fdf9b3e8 | bellard | |
24 | fdf9b3e8 | bellard | #ifndef CONFIG_USER_ONLY
|
25 | fdf9b3e8 | bellard | |
26 | fdf9b3e8 | bellard | #define MMUSUFFIX _mmu
|
27 | fdf9b3e8 | bellard | |
28 | fdf9b3e8 | bellard | #define SHIFT 0 |
29 | fdf9b3e8 | bellard | #include "softmmu_template.h" |
30 | fdf9b3e8 | bellard | |
31 | fdf9b3e8 | bellard | #define SHIFT 1 |
32 | fdf9b3e8 | bellard | #include "softmmu_template.h" |
33 | fdf9b3e8 | bellard | |
34 | fdf9b3e8 | bellard | #define SHIFT 2 |
35 | fdf9b3e8 | bellard | #include "softmmu_template.h" |
36 | fdf9b3e8 | bellard | |
37 | fdf9b3e8 | bellard | #define SHIFT 3 |
38 | fdf9b3e8 | bellard | #include "softmmu_template.h" |
39 | fdf9b3e8 | bellard | |
40 | 6ebbf390 | j_mayer | void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) |
41 | fdf9b3e8 | bellard | { |
42 | fdf9b3e8 | bellard | TranslationBlock *tb; |
43 | fdf9b3e8 | bellard | CPUState *saved_env; |
44 | fdf9b3e8 | bellard | unsigned long pc; |
45 | fdf9b3e8 | bellard | int ret;
|
46 | fdf9b3e8 | bellard | |
47 | fdf9b3e8 | bellard | /* XXX: hack to restore env in all cases, even if not called from
|
48 | fdf9b3e8 | bellard | generated code */
|
49 | fdf9b3e8 | bellard | saved_env = env; |
50 | fdf9b3e8 | bellard | env = cpu_single_env; |
51 | 6ebbf390 | j_mayer | ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
|
52 | fdf9b3e8 | bellard | if (ret) {
|
53 | fdf9b3e8 | bellard | if (retaddr) {
|
54 | fdf9b3e8 | bellard | /* now we have a real cpu fault */
|
55 | fdf9b3e8 | bellard | pc = (unsigned long) retaddr; |
56 | fdf9b3e8 | bellard | tb = tb_find_pc(pc); |
57 | fdf9b3e8 | bellard | if (tb) {
|
58 | fdf9b3e8 | bellard | /* the PC is inside the translated code. It means that we have
|
59 | fdf9b3e8 | bellard | a virtual CPU fault */
|
60 | fdf9b3e8 | bellard | cpu_restore_state(tb, env, pc, NULL);
|
61 | fdf9b3e8 | bellard | } |
62 | fdf9b3e8 | bellard | } |
63 | e6afc2f4 | aurel32 | cpu_loop_exit(); |
64 | fdf9b3e8 | bellard | } |
65 | fdf9b3e8 | bellard | env = saved_env; |
66 | fdf9b3e8 | bellard | } |
67 | fdf9b3e8 | bellard | |
68 | fdf9b3e8 | bellard | #endif
|
69 | fdf9b3e8 | bellard | |
70 | ea2b542a | aurel32 | void helper_ldtlb(void) |
71 | ea2b542a | aurel32 | { |
72 | ea2b542a | aurel32 | #ifdef CONFIG_USER_ONLY
|
73 | ea2b542a | aurel32 | /* XXXXX */
|
74 | ea2b542a | aurel32 | assert(0);
|
75 | ea2b542a | aurel32 | #else
|
76 | ea2b542a | aurel32 | cpu_load_tlb(env); |
77 | ea2b542a | aurel32 | #endif
|
78 | ea2b542a | aurel32 | } |
79 | ea2b542a | aurel32 | |
80 | e6afc2f4 | aurel32 | void helper_raise_illegal_instruction(void) |
81 | e6afc2f4 | aurel32 | { |
82 | e6afc2f4 | aurel32 | env->exception_index = 0x180;
|
83 | e6afc2f4 | aurel32 | cpu_loop_exit(); |
84 | e6afc2f4 | aurel32 | } |
85 | e6afc2f4 | aurel32 | |
86 | e6afc2f4 | aurel32 | void helper_raise_slot_illegal_instruction(void) |
87 | e6afc2f4 | aurel32 | { |
88 | e6afc2f4 | aurel32 | env->exception_index = 0x1a0;
|
89 | e6afc2f4 | aurel32 | cpu_loop_exit(); |
90 | e6afc2f4 | aurel32 | } |
91 | e6afc2f4 | aurel32 | |
92 | e6afc2f4 | aurel32 | void helper_debug(void) |
93 | e6afc2f4 | aurel32 | { |
94 | e6afc2f4 | aurel32 | env->exception_index = EXCP_DEBUG; |
95 | e6afc2f4 | aurel32 | cpu_loop_exit(); |
96 | e6afc2f4 | aurel32 | } |
97 | e6afc2f4 | aurel32 | |
98 | f24f381b | aurel32 | void helper_sleep(uint32_t next_pc)
|
99 | e6afc2f4 | aurel32 | { |
100 | e6afc2f4 | aurel32 | env->halted = 1;
|
101 | e6afc2f4 | aurel32 | env->exception_index = EXCP_HLT; |
102 | f24f381b | aurel32 | env->pc = next_pc; |
103 | e6afc2f4 | aurel32 | cpu_loop_exit(); |
104 | e6afc2f4 | aurel32 | } |
105 | e6afc2f4 | aurel32 | |
106 | e6afc2f4 | aurel32 | void helper_trapa(uint32_t tra)
|
107 | e6afc2f4 | aurel32 | { |
108 | e6afc2f4 | aurel32 | env->tra = tra << 2;
|
109 | e6afc2f4 | aurel32 | env->exception_index = 0x160;
|
110 | e6afc2f4 | aurel32 | cpu_loop_exit(); |
111 | e6afc2f4 | aurel32 | } |
112 | e6afc2f4 | aurel32 | |
113 | 6f06939b | aurel32 | uint32_t helper_addc(uint32_t arg0, uint32_t arg1) |
114 | fdf9b3e8 | bellard | { |
115 | fdf9b3e8 | bellard | uint32_t tmp0, tmp1; |
116 | fdf9b3e8 | bellard | |
117 | 6f06939b | aurel32 | tmp1 = arg0 + arg1; |
118 | 6f06939b | aurel32 | tmp0 = arg1; |
119 | 6f06939b | aurel32 | arg1 = tmp1 + (env->sr & 1);
|
120 | fdf9b3e8 | bellard | if (tmp0 > tmp1)
|
121 | fdf9b3e8 | bellard | env->sr |= SR_T; |
122 | fdf9b3e8 | bellard | else
|
123 | fdf9b3e8 | bellard | env->sr &= ~SR_T; |
124 | 6f06939b | aurel32 | if (tmp1 > arg1)
|
125 | fdf9b3e8 | bellard | env->sr |= SR_T; |
126 | 6f06939b | aurel32 | return arg1;
|
127 | fdf9b3e8 | bellard | } |
128 | fdf9b3e8 | bellard | |
129 | 6f06939b | aurel32 | uint32_t helper_addv(uint32_t arg0, uint32_t arg1) |
130 | fdf9b3e8 | bellard | { |
131 | fdf9b3e8 | bellard | uint32_t dest, src, ans; |
132 | fdf9b3e8 | bellard | |
133 | 6f06939b | aurel32 | if ((int32_t) arg1 >= 0) |
134 | fdf9b3e8 | bellard | dest = 0;
|
135 | fdf9b3e8 | bellard | else
|
136 | fdf9b3e8 | bellard | dest = 1;
|
137 | 6f06939b | aurel32 | if ((int32_t) arg0 >= 0) |
138 | fdf9b3e8 | bellard | src = 0;
|
139 | fdf9b3e8 | bellard | else
|
140 | fdf9b3e8 | bellard | src = 1;
|
141 | fdf9b3e8 | bellard | src += dest; |
142 | 6f06939b | aurel32 | arg1 += arg0; |
143 | 6f06939b | aurel32 | if ((int32_t) arg1 >= 0) |
144 | fdf9b3e8 | bellard | ans = 0;
|
145 | fdf9b3e8 | bellard | else
|
146 | fdf9b3e8 | bellard | ans = 1;
|
147 | fdf9b3e8 | bellard | ans += dest; |
148 | fdf9b3e8 | bellard | if (src == 0 || src == 2) { |
149 | fdf9b3e8 | bellard | if (ans == 1) |
150 | fdf9b3e8 | bellard | env->sr |= SR_T; |
151 | fdf9b3e8 | bellard | else
|
152 | fdf9b3e8 | bellard | env->sr &= ~SR_T; |
153 | fdf9b3e8 | bellard | } else
|
154 | fdf9b3e8 | bellard | env->sr &= ~SR_T; |
155 | 6f06939b | aurel32 | return arg1;
|
156 | fdf9b3e8 | bellard | } |
157 | fdf9b3e8 | bellard | |
158 | fdf9b3e8 | bellard | #define T (env->sr & SR_T)
|
159 | fdf9b3e8 | bellard | #define Q (env->sr & SR_Q ? 1 : 0) |
160 | fdf9b3e8 | bellard | #define M (env->sr & SR_M ? 1 : 0) |
161 | fdf9b3e8 | bellard | #define SETT env->sr |= SR_T
|
162 | fdf9b3e8 | bellard | #define CLRT env->sr &= ~SR_T
|
163 | fdf9b3e8 | bellard | #define SETQ env->sr |= SR_Q
|
164 | fdf9b3e8 | bellard | #define CLRQ env->sr &= ~SR_Q
|
165 | fdf9b3e8 | bellard | #define SETM env->sr |= SR_M
|
166 | fdf9b3e8 | bellard | #define CLRM env->sr &= ~SR_M
|
167 | fdf9b3e8 | bellard | |
168 | 69d6275b | aurel32 | uint32_t helper_div1(uint32_t arg0, uint32_t arg1) |
169 | fdf9b3e8 | bellard | { |
170 | fdf9b3e8 | bellard | uint32_t tmp0, tmp2; |
171 | fdf9b3e8 | bellard | uint8_t old_q, tmp1 = 0xff;
|
172 | fdf9b3e8 | bellard | |
173 | 69d6275b | aurel32 | //printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, Q, T);
|
174 | fdf9b3e8 | bellard | old_q = Q; |
175 | 69d6275b | aurel32 | if ((0x80000000 & arg1) != 0) |
176 | fdf9b3e8 | bellard | SETQ; |
177 | fdf9b3e8 | bellard | else
|
178 | fdf9b3e8 | bellard | CLRQ; |
179 | 69d6275b | aurel32 | tmp2 = arg0; |
180 | 69d6275b | aurel32 | arg1 <<= 1;
|
181 | 69d6275b | aurel32 | arg1 |= T; |
182 | fdf9b3e8 | bellard | switch (old_q) {
|
183 | fdf9b3e8 | bellard | case 0: |
184 | fdf9b3e8 | bellard | switch (M) {
|
185 | fdf9b3e8 | bellard | case 0: |
186 | 69d6275b | aurel32 | tmp0 = arg1; |
187 | 69d6275b | aurel32 | arg1 -= tmp2; |
188 | 69d6275b | aurel32 | tmp1 = arg1 > tmp0; |
189 | fdf9b3e8 | bellard | switch (Q) {
|
190 | fdf9b3e8 | bellard | case 0: |
191 | fdf9b3e8 | bellard | if (tmp1)
|
192 | fdf9b3e8 | bellard | SETQ; |
193 | fdf9b3e8 | bellard | else
|
194 | fdf9b3e8 | bellard | CLRQ; |
195 | fdf9b3e8 | bellard | break;
|
196 | fdf9b3e8 | bellard | case 1: |
197 | fdf9b3e8 | bellard | if (tmp1 == 0) |
198 | fdf9b3e8 | bellard | SETQ; |
199 | fdf9b3e8 | bellard | else
|
200 | fdf9b3e8 | bellard | CLRQ; |
201 | fdf9b3e8 | bellard | break;
|
202 | fdf9b3e8 | bellard | } |
203 | fdf9b3e8 | bellard | break;
|
204 | fdf9b3e8 | bellard | case 1: |
205 | 69d6275b | aurel32 | tmp0 = arg1; |
206 | 69d6275b | aurel32 | arg1 += tmp2; |
207 | 69d6275b | aurel32 | tmp1 = arg1 < tmp0; |
208 | fdf9b3e8 | bellard | switch (Q) {
|
209 | fdf9b3e8 | bellard | case 0: |
210 | fdf9b3e8 | bellard | if (tmp1 == 0) |
211 | fdf9b3e8 | bellard | SETQ; |
212 | fdf9b3e8 | bellard | else
|
213 | fdf9b3e8 | bellard | CLRQ; |
214 | fdf9b3e8 | bellard | break;
|
215 | fdf9b3e8 | bellard | case 1: |
216 | fdf9b3e8 | bellard | if (tmp1)
|
217 | fdf9b3e8 | bellard | SETQ; |
218 | fdf9b3e8 | bellard | else
|
219 | fdf9b3e8 | bellard | CLRQ; |
220 | fdf9b3e8 | bellard | break;
|
221 | fdf9b3e8 | bellard | } |
222 | fdf9b3e8 | bellard | break;
|
223 | fdf9b3e8 | bellard | } |
224 | fdf9b3e8 | bellard | break;
|
225 | fdf9b3e8 | bellard | case 1: |
226 | fdf9b3e8 | bellard | switch (M) {
|
227 | fdf9b3e8 | bellard | case 0: |
228 | 69d6275b | aurel32 | tmp0 = arg1; |
229 | 69d6275b | aurel32 | arg1 += tmp2; |
230 | 69d6275b | aurel32 | tmp1 = arg1 < tmp0; |
231 | fdf9b3e8 | bellard | switch (Q) {
|
232 | fdf9b3e8 | bellard | case 0: |
233 | fdf9b3e8 | bellard | if (tmp1)
|
234 | fdf9b3e8 | bellard | SETQ; |
235 | fdf9b3e8 | bellard | else
|
236 | fdf9b3e8 | bellard | CLRQ; |
237 | fdf9b3e8 | bellard | break;
|
238 | fdf9b3e8 | bellard | case 1: |
239 | fdf9b3e8 | bellard | if (tmp1 == 0) |
240 | fdf9b3e8 | bellard | SETQ; |
241 | fdf9b3e8 | bellard | else
|
242 | fdf9b3e8 | bellard | CLRQ; |
243 | fdf9b3e8 | bellard | break;
|
244 | fdf9b3e8 | bellard | } |
245 | fdf9b3e8 | bellard | break;
|
246 | fdf9b3e8 | bellard | case 1: |
247 | 69d6275b | aurel32 | tmp0 = arg1; |
248 | 69d6275b | aurel32 | arg1 -= tmp2; |
249 | 69d6275b | aurel32 | tmp1 = arg1 > tmp0; |
250 | fdf9b3e8 | bellard | switch (Q) {
|
251 | fdf9b3e8 | bellard | case 0: |
252 | fdf9b3e8 | bellard | if (tmp1 == 0) |
253 | fdf9b3e8 | bellard | SETQ; |
254 | fdf9b3e8 | bellard | else
|
255 | fdf9b3e8 | bellard | CLRQ; |
256 | fdf9b3e8 | bellard | break;
|
257 | fdf9b3e8 | bellard | case 1: |
258 | fdf9b3e8 | bellard | if (tmp1)
|
259 | fdf9b3e8 | bellard | SETQ; |
260 | fdf9b3e8 | bellard | else
|
261 | fdf9b3e8 | bellard | CLRQ; |
262 | fdf9b3e8 | bellard | break;
|
263 | fdf9b3e8 | bellard | } |
264 | fdf9b3e8 | bellard | break;
|
265 | fdf9b3e8 | bellard | } |
266 | fdf9b3e8 | bellard | break;
|
267 | fdf9b3e8 | bellard | } |
268 | fdf9b3e8 | bellard | if (Q == M)
|
269 | fdf9b3e8 | bellard | SETT; |
270 | fdf9b3e8 | bellard | else
|
271 | fdf9b3e8 | bellard | CLRT; |
272 | 69d6275b | aurel32 | //printf("Output: arg1=0x%08x M=%d Q=%d T=%d\n", arg1, M, Q, T);
|
273 | 69d6275b | aurel32 | return arg1;
|
274 | fdf9b3e8 | bellard | } |
275 | fdf9b3e8 | bellard | |
276 | 6f06939b | aurel32 | void helper_macl(uint32_t arg0, uint32_t arg1)
|
277 | fdf9b3e8 | bellard | { |
278 | fdf9b3e8 | bellard | int64_t res; |
279 | fdf9b3e8 | bellard | |
280 | fdf9b3e8 | bellard | res = ((uint64_t) env->mach << 32) | env->macl;
|
281 | 6f06939b | aurel32 | res += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1; |
282 | fdf9b3e8 | bellard | env->mach = (res >> 32) & 0xffffffff; |
283 | fdf9b3e8 | bellard | env->macl = res & 0xffffffff;
|
284 | fdf9b3e8 | bellard | if (env->sr & SR_S) {
|
285 | fdf9b3e8 | bellard | if (res < 0) |
286 | fdf9b3e8 | bellard | env->mach |= 0xffff0000;
|
287 | fdf9b3e8 | bellard | else
|
288 | fdf9b3e8 | bellard | env->mach &= 0x00007fff;
|
289 | fdf9b3e8 | bellard | } |
290 | fdf9b3e8 | bellard | } |
291 | fdf9b3e8 | bellard | |
292 | 6f06939b | aurel32 | void helper_macw(uint32_t arg0, uint32_t arg1)
|
293 | fdf9b3e8 | bellard | { |
294 | fdf9b3e8 | bellard | int64_t res; |
295 | fdf9b3e8 | bellard | |
296 | fdf9b3e8 | bellard | res = ((uint64_t) env->mach << 32) | env->macl;
|
297 | 6f06939b | aurel32 | res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1; |
298 | fdf9b3e8 | bellard | env->mach = (res >> 32) & 0xffffffff; |
299 | fdf9b3e8 | bellard | env->macl = res & 0xffffffff;
|
300 | fdf9b3e8 | bellard | if (env->sr & SR_S) {
|
301 | fdf9b3e8 | bellard | if (res < -0x80000000) { |
302 | fdf9b3e8 | bellard | env->mach = 1;
|
303 | fdf9b3e8 | bellard | env->macl = 0x80000000;
|
304 | fdf9b3e8 | bellard | } else if (res > 0x000000007fffffff) { |
305 | fdf9b3e8 | bellard | env->mach = 1;
|
306 | fdf9b3e8 | bellard | env->macl = 0x7fffffff;
|
307 | fdf9b3e8 | bellard | } |
308 | fdf9b3e8 | bellard | } |
309 | fdf9b3e8 | bellard | } |
310 | fdf9b3e8 | bellard | |
311 | 6f06939b | aurel32 | uint32_t helper_negc(uint32_t arg) |
312 | fdf9b3e8 | bellard | { |
313 | fdf9b3e8 | bellard | uint32_t temp; |
314 | fdf9b3e8 | bellard | |
315 | 6f06939b | aurel32 | temp = -arg; |
316 | 6f06939b | aurel32 | arg = temp - (env->sr & SR_T); |
317 | fdf9b3e8 | bellard | if (0 < temp) |
318 | fdf9b3e8 | bellard | env->sr |= SR_T; |
319 | fdf9b3e8 | bellard | else
|
320 | fdf9b3e8 | bellard | env->sr &= ~SR_T; |
321 | 6f06939b | aurel32 | if (temp < arg)
|
322 | fdf9b3e8 | bellard | env->sr |= SR_T; |
323 | 6f06939b | aurel32 | return arg;
|
324 | fdf9b3e8 | bellard | } |
325 | fdf9b3e8 | bellard | |
326 | 6f06939b | aurel32 | uint32_t helper_subc(uint32_t arg0, uint32_t arg1) |
327 | fdf9b3e8 | bellard | { |
328 | fdf9b3e8 | bellard | uint32_t tmp0, tmp1; |
329 | fdf9b3e8 | bellard | |
330 | 6f06939b | aurel32 | tmp1 = arg1 - arg0; |
331 | 6f06939b | aurel32 | tmp0 = arg1; |
332 | 6f06939b | aurel32 | arg1 = tmp1 - (env->sr & SR_T); |
333 | fdf9b3e8 | bellard | if (tmp0 < tmp1)
|
334 | fdf9b3e8 | bellard | env->sr |= SR_T; |
335 | fdf9b3e8 | bellard | else
|
336 | fdf9b3e8 | bellard | env->sr &= ~SR_T; |
337 | 6f06939b | aurel32 | if (tmp1 < arg1)
|
338 | fdf9b3e8 | bellard | env->sr |= SR_T; |
339 | 6f06939b | aurel32 | return arg1;
|
340 | fdf9b3e8 | bellard | } |
341 | fdf9b3e8 | bellard | |
342 | 6f06939b | aurel32 | uint32_t helper_subv(uint32_t arg0, uint32_t arg1) |
343 | fdf9b3e8 | bellard | { |
344 | fdf9b3e8 | bellard | int32_t dest, src, ans; |
345 | fdf9b3e8 | bellard | |
346 | 6f06939b | aurel32 | if ((int32_t) arg1 >= 0) |
347 | fdf9b3e8 | bellard | dest = 0;
|
348 | fdf9b3e8 | bellard | else
|
349 | fdf9b3e8 | bellard | dest = 1;
|
350 | 6f06939b | aurel32 | if ((int32_t) arg0 >= 0) |
351 | fdf9b3e8 | bellard | src = 0;
|
352 | fdf9b3e8 | bellard | else
|
353 | fdf9b3e8 | bellard | src = 1;
|
354 | fdf9b3e8 | bellard | src += dest; |
355 | 6f06939b | aurel32 | arg1 -= arg0; |
356 | 6f06939b | aurel32 | if ((int32_t) arg1 >= 0) |
357 | fdf9b3e8 | bellard | ans = 0;
|
358 | fdf9b3e8 | bellard | else
|
359 | fdf9b3e8 | bellard | ans = 1;
|
360 | fdf9b3e8 | bellard | ans += dest; |
361 | fdf9b3e8 | bellard | if (src == 1) { |
362 | fdf9b3e8 | bellard | if (ans == 1) |
363 | fdf9b3e8 | bellard | env->sr |= SR_T; |
364 | fdf9b3e8 | bellard | else
|
365 | fdf9b3e8 | bellard | env->sr &= ~SR_T; |
366 | fdf9b3e8 | bellard | } else
|
367 | fdf9b3e8 | bellard | env->sr &= ~SR_T; |
368 | 6f06939b | aurel32 | return arg1;
|
369 | fdf9b3e8 | bellard | } |
370 | fdf9b3e8 | bellard | |
371 | cc4ba6a9 | aurel32 | static inline void set_t(void) |
372 | cc4ba6a9 | aurel32 | { |
373 | cc4ba6a9 | aurel32 | env->sr |= SR_T; |
374 | cc4ba6a9 | aurel32 | } |
375 | cc4ba6a9 | aurel32 | |
376 | cc4ba6a9 | aurel32 | static inline void clr_t(void) |
377 | cc4ba6a9 | aurel32 | { |
378 | cc4ba6a9 | aurel32 | env->sr &= ~SR_T; |
379 | cc4ba6a9 | aurel32 | } |
380 | cc4ba6a9 | aurel32 | |
381 | 390af821 | aurel32 | void helper_ld_fpscr(uint32_t val)
|
382 | 390af821 | aurel32 | { |
383 | 390af821 | aurel32 | env->fpscr = val & 0x003fffff;
|
384 | 390af821 | aurel32 | if (val & 0x01) |
385 | 390af821 | aurel32 | set_float_rounding_mode(float_round_to_zero, &env->fp_status); |
386 | 390af821 | aurel32 | else
|
387 | 390af821 | aurel32 | set_float_rounding_mode(float_round_nearest_even, &env->fp_status); |
388 | 390af821 | aurel32 | } |
389 | cc4ba6a9 | aurel32 | |
390 | cc4ba6a9 | aurel32 | uint32_t helper_fabs_FT(uint32_t t0) |
391 | cc4ba6a9 | aurel32 | { |
392 | 9850d1e8 | aurel32 | CPU_FloatU f; |
393 | 9850d1e8 | aurel32 | f.l = t0; |
394 | 9850d1e8 | aurel32 | f.f = float32_abs(f.f); |
395 | 9850d1e8 | aurel32 | return f.l;
|
396 | cc4ba6a9 | aurel32 | } |
397 | cc4ba6a9 | aurel32 | |
398 | cc4ba6a9 | aurel32 | uint64_t helper_fabs_DT(uint64_t t0) |
399 | cc4ba6a9 | aurel32 | { |
400 | 9850d1e8 | aurel32 | CPU_DoubleU d; |
401 | 9850d1e8 | aurel32 | d.ll = t0; |
402 | 9850d1e8 | aurel32 | d.d = float64_abs(d.d); |
403 | 9850d1e8 | aurel32 | return d.ll;
|
404 | cc4ba6a9 | aurel32 | } |
405 | cc4ba6a9 | aurel32 | |
406 | cc4ba6a9 | aurel32 | uint32_t helper_fadd_FT(uint32_t t0, uint32_t t1) |
407 | cc4ba6a9 | aurel32 | { |
408 | 9850d1e8 | aurel32 | CPU_FloatU f0, f1; |
409 | 9850d1e8 | aurel32 | f0.l = t0; |
410 | 9850d1e8 | aurel32 | f1.l = t1; |
411 | 9850d1e8 | aurel32 | f0.f = float32_add(f0.f, f1.f, &env->fp_status); |
412 | 9850d1e8 | aurel32 | return f0.l;
|
413 | cc4ba6a9 | aurel32 | } |
414 | cc4ba6a9 | aurel32 | |
415 | cc4ba6a9 | aurel32 | uint64_t helper_fadd_DT(uint64_t t0, uint64_t t1) |
416 | cc4ba6a9 | aurel32 | { |
417 | 9850d1e8 | aurel32 | CPU_DoubleU d0, d1; |
418 | 9850d1e8 | aurel32 | d0.ll = t0; |
419 | 9850d1e8 | aurel32 | d1.ll = t1; |
420 | 9850d1e8 | aurel32 | d0.d = float64_add(d0.d, d1.d, &env->fp_status); |
421 | 9850d1e8 | aurel32 | return d0.ll;
|
422 | cc4ba6a9 | aurel32 | } |
423 | cc4ba6a9 | aurel32 | |
424 | cc4ba6a9 | aurel32 | void helper_fcmp_eq_FT(uint32_t t0, uint32_t t1)
|
425 | cc4ba6a9 | aurel32 | { |
426 | 9850d1e8 | aurel32 | CPU_FloatU f0, f1; |
427 | 9850d1e8 | aurel32 | f0.l = t0; |
428 | 9850d1e8 | aurel32 | f1.l = t1; |
429 | 9850d1e8 | aurel32 | |
430 | 9850d1e8 | aurel32 | if (float32_compare(f0.f, f1.f, &env->fp_status) == 0) |
431 | cc4ba6a9 | aurel32 | set_t(); |
432 | cc4ba6a9 | aurel32 | else
|
433 | cc4ba6a9 | aurel32 | clr_t(); |
434 | cc4ba6a9 | aurel32 | } |
435 | cc4ba6a9 | aurel32 | |
436 | cc4ba6a9 | aurel32 | void helper_fcmp_eq_DT(uint64_t t0, uint64_t t1)
|
437 | cc4ba6a9 | aurel32 | { |
438 | 9850d1e8 | aurel32 | CPU_DoubleU d0, d1; |
439 | 9850d1e8 | aurel32 | d0.ll = t0; |
440 | 9850d1e8 | aurel32 | d1.ll = t1; |
441 | 9850d1e8 | aurel32 | |
442 | 9850d1e8 | aurel32 | if (float64_compare(d0.d, d1.d, &env->fp_status) == 0) |
443 | cc4ba6a9 | aurel32 | set_t(); |
444 | cc4ba6a9 | aurel32 | else
|
445 | cc4ba6a9 | aurel32 | clr_t(); |
446 | cc4ba6a9 | aurel32 | } |
447 | cc4ba6a9 | aurel32 | |
448 | cc4ba6a9 | aurel32 | void helper_fcmp_gt_FT(uint32_t t0, uint32_t t1)
|
449 | cc4ba6a9 | aurel32 | { |
450 | 9850d1e8 | aurel32 | CPU_FloatU f0, f1; |
451 | 9850d1e8 | aurel32 | f0.l = t0; |
452 | 9850d1e8 | aurel32 | f1.l = t1; |
453 | 9850d1e8 | aurel32 | |
454 | 9850d1e8 | aurel32 | if (float32_compare(f0.f, f1.f, &env->fp_status) == 1) |
455 | cc4ba6a9 | aurel32 | set_t(); |
456 | cc4ba6a9 | aurel32 | else
|
457 | cc4ba6a9 | aurel32 | clr_t(); |
458 | cc4ba6a9 | aurel32 | } |
459 | cc4ba6a9 | aurel32 | |
460 | cc4ba6a9 | aurel32 | void helper_fcmp_gt_DT(uint64_t t0, uint64_t t1)
|
461 | cc4ba6a9 | aurel32 | { |
462 | 9850d1e8 | aurel32 | CPU_DoubleU d0, d1; |
463 | 9850d1e8 | aurel32 | d0.ll = t0; |
464 | 9850d1e8 | aurel32 | d1.ll = t1; |
465 | 9850d1e8 | aurel32 | |
466 | 9850d1e8 | aurel32 | if (float64_compare(d0.d, d1.d, &env->fp_status) == 1) |
467 | cc4ba6a9 | aurel32 | set_t(); |
468 | cc4ba6a9 | aurel32 | else
|
469 | cc4ba6a9 | aurel32 | clr_t(); |
470 | cc4ba6a9 | aurel32 | } |
471 | cc4ba6a9 | aurel32 | |
472 | cc4ba6a9 | aurel32 | uint64_t helper_fcnvsd_FT_DT(uint32_t t0) |
473 | cc4ba6a9 | aurel32 | { |
474 | 9850d1e8 | aurel32 | CPU_DoubleU d; |
475 | 9850d1e8 | aurel32 | CPU_FloatU f; |
476 | 9850d1e8 | aurel32 | f.l = t0; |
477 | 9850d1e8 | aurel32 | d.d = float32_to_float64(f.f, &env->fp_status); |
478 | 9850d1e8 | aurel32 | return d.ll;
|
479 | cc4ba6a9 | aurel32 | } |
480 | cc4ba6a9 | aurel32 | |
481 | cc4ba6a9 | aurel32 | uint32_t helper_fcnvds_DT_FT(uint64_t t0) |
482 | cc4ba6a9 | aurel32 | { |
483 | 9850d1e8 | aurel32 | CPU_DoubleU d; |
484 | 9850d1e8 | aurel32 | CPU_FloatU f; |
485 | 9850d1e8 | aurel32 | d.ll = t0; |
486 | 9850d1e8 | aurel32 | f.f = float64_to_float32(d.d, &env->fp_status); |
487 | 9850d1e8 | aurel32 | return f.l;
|
488 | cc4ba6a9 | aurel32 | } |
489 | cc4ba6a9 | aurel32 | |
490 | cc4ba6a9 | aurel32 | uint32_t helper_fdiv_FT(uint32_t t0, uint32_t t1) |
491 | cc4ba6a9 | aurel32 | { |
492 | 9850d1e8 | aurel32 | CPU_FloatU f0, f1; |
493 | 9850d1e8 | aurel32 | f0.l = t0; |
494 | 9850d1e8 | aurel32 | f1.l = t1; |
495 | 9850d1e8 | aurel32 | f0.f = float32_div(f0.f, f1.f, &env->fp_status); |
496 | 9850d1e8 | aurel32 | return f0.l;
|
497 | cc4ba6a9 | aurel32 | } |
498 | cc4ba6a9 | aurel32 | |
499 | cc4ba6a9 | aurel32 | uint64_t helper_fdiv_DT(uint64_t t0, uint64_t t1) |
500 | cc4ba6a9 | aurel32 | { |
501 | 9850d1e8 | aurel32 | CPU_DoubleU d0, d1; |
502 | 9850d1e8 | aurel32 | d0.ll = t0; |
503 | 9850d1e8 | aurel32 | d1.ll = t1; |
504 | 9850d1e8 | aurel32 | d0.d = float64_div(d0.d, d1.d, &env->fp_status); |
505 | 9850d1e8 | aurel32 | return d0.ll;
|
506 | cc4ba6a9 | aurel32 | } |
507 | cc4ba6a9 | aurel32 | |
508 | cc4ba6a9 | aurel32 | uint32_t helper_float_FT(uint32_t t0) |
509 | cc4ba6a9 | aurel32 | { |
510 | 9850d1e8 | aurel32 | CPU_FloatU f; |
511 | 9850d1e8 | aurel32 | f.f = int32_to_float32(t0, &env->fp_status); |
512 | 9850d1e8 | aurel32 | return f.l;
|
513 | cc4ba6a9 | aurel32 | } |
514 | cc4ba6a9 | aurel32 | |
515 | cc4ba6a9 | aurel32 | uint64_t helper_float_DT(uint32_t t0) |
516 | cc4ba6a9 | aurel32 | { |
517 | 9850d1e8 | aurel32 | CPU_DoubleU d; |
518 | 9850d1e8 | aurel32 | d.d = int32_to_float64(t0, &env->fp_status); |
519 | 9850d1e8 | aurel32 | return d.ll;
|
520 | cc4ba6a9 | aurel32 | } |
521 | cc4ba6a9 | aurel32 | |
522 | cc4ba6a9 | aurel32 | uint32_t helper_fmul_FT(uint32_t t0, uint32_t t1) |
523 | cc4ba6a9 | aurel32 | { |
524 | 9850d1e8 | aurel32 | CPU_FloatU f0, f1; |
525 | 9850d1e8 | aurel32 | f0.l = t0; |
526 | 9850d1e8 | aurel32 | f1.l = t1; |
527 | 9850d1e8 | aurel32 | f0.f = float32_mul(f0.f, f1.f, &env->fp_status); |
528 | 9850d1e8 | aurel32 | return f0.l;
|
529 | cc4ba6a9 | aurel32 | } |
530 | cc4ba6a9 | aurel32 | |
531 | cc4ba6a9 | aurel32 | uint64_t helper_fmul_DT(uint64_t t0, uint64_t t1) |
532 | cc4ba6a9 | aurel32 | { |
533 | 9850d1e8 | aurel32 | CPU_DoubleU d0, d1; |
534 | 9850d1e8 | aurel32 | d0.ll = t0; |
535 | 9850d1e8 | aurel32 | d1.ll = t1; |
536 | 9850d1e8 | aurel32 | d0.d = float64_mul(d0.d, d1.d, &env->fp_status); |
537 | 9850d1e8 | aurel32 | return d0.ll;
|
538 | cc4ba6a9 | aurel32 | } |
539 | cc4ba6a9 | aurel32 | |
540 | 7fdf924f | aurel32 | uint32_t helper_fneg_T(uint32_t t0) |
541 | 7fdf924f | aurel32 | { |
542 | 9850d1e8 | aurel32 | CPU_FloatU f; |
543 | 9850d1e8 | aurel32 | f.l = t0; |
544 | 9850d1e8 | aurel32 | f.f = float32_chs(f.f); |
545 | 9850d1e8 | aurel32 | return f.l;
|
546 | 7fdf924f | aurel32 | } |
547 | 7fdf924f | aurel32 | |
548 | cc4ba6a9 | aurel32 | uint32_t helper_fsqrt_FT(uint32_t t0) |
549 | cc4ba6a9 | aurel32 | { |
550 | 9850d1e8 | aurel32 | CPU_FloatU f; |
551 | 9850d1e8 | aurel32 | f.l = t0; |
552 | 9850d1e8 | aurel32 | f.f = float32_sqrt(f.f, &env->fp_status); |
553 | 9850d1e8 | aurel32 | return f.l;
|
554 | cc4ba6a9 | aurel32 | } |
555 | cc4ba6a9 | aurel32 | |
556 | cc4ba6a9 | aurel32 | uint64_t helper_fsqrt_DT(uint64_t t0) |
557 | cc4ba6a9 | aurel32 | { |
558 | 9850d1e8 | aurel32 | CPU_DoubleU d; |
559 | 9850d1e8 | aurel32 | d.ll = t0; |
560 | 9850d1e8 | aurel32 | d.d = float64_sqrt(d.d, &env->fp_status); |
561 | 9850d1e8 | aurel32 | return d.ll;
|
562 | cc4ba6a9 | aurel32 | } |
563 | cc4ba6a9 | aurel32 | |
564 | cc4ba6a9 | aurel32 | uint32_t helper_fsub_FT(uint32_t t0, uint32_t t1) |
565 | cc4ba6a9 | aurel32 | { |
566 | 9850d1e8 | aurel32 | CPU_FloatU f0, f1; |
567 | 9850d1e8 | aurel32 | f0.l = t0; |
568 | 9850d1e8 | aurel32 | f1.l = t1; |
569 | 9850d1e8 | aurel32 | f0.f = float32_sub(f0.f, f1.f, &env->fp_status); |
570 | 9850d1e8 | aurel32 | return f0.l;
|
571 | cc4ba6a9 | aurel32 | } |
572 | cc4ba6a9 | aurel32 | |
573 | cc4ba6a9 | aurel32 | uint64_t helper_fsub_DT(uint64_t t0, uint64_t t1) |
574 | cc4ba6a9 | aurel32 | { |
575 | 9850d1e8 | aurel32 | CPU_DoubleU d0, d1; |
576 | 9850d1e8 | aurel32 | d0.ll = t0; |
577 | 9850d1e8 | aurel32 | d1.ll = t1; |
578 | 9850d1e8 | aurel32 | d0.d = float64_sub(d0.d, d1.d, &env->fp_status); |
579 | 9850d1e8 | aurel32 | return d0.ll;
|
580 | cc4ba6a9 | aurel32 | } |
581 | cc4ba6a9 | aurel32 | |
582 | cc4ba6a9 | aurel32 | uint32_t helper_ftrc_FT(uint32_t t0) |
583 | cc4ba6a9 | aurel32 | { |
584 | 9850d1e8 | aurel32 | CPU_FloatU f; |
585 | 9850d1e8 | aurel32 | f.l = t0; |
586 | 9850d1e8 | aurel32 | return float32_to_int32_round_to_zero(f.f, &env->fp_status);
|
587 | cc4ba6a9 | aurel32 | } |
588 | cc4ba6a9 | aurel32 | |
589 | cc4ba6a9 | aurel32 | uint32_t helper_ftrc_DT(uint64_t t0) |
590 | cc4ba6a9 | aurel32 | { |
591 | 9850d1e8 | aurel32 | CPU_DoubleU d; |
592 | 9850d1e8 | aurel32 | d.ll = t0; |
593 | 9850d1e8 | aurel32 | return float64_to_int32_round_to_zero(d.d, &env->fp_status);
|
594 | cc4ba6a9 | aurel32 | } |