root / target-unicore32 / helper.c @ 8141905a
History | View | Annotate | Download (10.7 kB)
1 | 6e64da3c | Guan Xuetao | /*
|
---|---|---|---|
2 | 6e64da3c | Guan Xuetao | * Copyright (C) 2010-2011 GUAN Xue-tao
|
3 | 6e64da3c | Guan Xuetao | *
|
4 | 6e64da3c | Guan Xuetao | * This program is free software; you can redistribute it and/or modify
|
5 | 6e64da3c | Guan Xuetao | * it under the terms of the GNU General Public License version 2 as
|
6 | 6e64da3c | Guan Xuetao | * published by the Free Software Foundation.
|
7 | 6e64da3c | Guan Xuetao | */
|
8 | 6e64da3c | Guan Xuetao | |
9 | 6e64da3c | Guan Xuetao | #include "cpu.h" |
10 | 6e64da3c | Guan Xuetao | #include "gdbstub.h" |
11 | 6e64da3c | Guan Xuetao | #include "helper.h" |
12 | 6e64da3c | Guan Xuetao | #include "host-utils.h" |
13 | 6e64da3c | Guan Xuetao | |
14 | 6e64da3c | Guan Xuetao | static inline void set_feature(CPUState *env, int feature) |
15 | 6e64da3c | Guan Xuetao | { |
16 | 6e64da3c | Guan Xuetao | env->features |= feature; |
17 | 6e64da3c | Guan Xuetao | } |
18 | 6e64da3c | Guan Xuetao | |
19 | 6e64da3c | Guan Xuetao | struct uc32_cpu_t {
|
20 | 6e64da3c | Guan Xuetao | uint32_t id; |
21 | 6e64da3c | Guan Xuetao | const char *name; |
22 | 6e64da3c | Guan Xuetao | }; |
23 | 6e64da3c | Guan Xuetao | |
24 | 6e64da3c | Guan Xuetao | static const struct uc32_cpu_t uc32_cpu_names[] = { |
25 | 6e64da3c | Guan Xuetao | { UC32_CPUID_UCV2, "UniCore-II"},
|
26 | 6e64da3c | Guan Xuetao | { UC32_CPUID_ANY, "any"},
|
27 | 6e64da3c | Guan Xuetao | { 0, NULL} |
28 | 6e64da3c | Guan Xuetao | }; |
29 | 6e64da3c | Guan Xuetao | |
30 | 6e64da3c | Guan Xuetao | /* return 0 if not found */
|
31 | 6e64da3c | Guan Xuetao | static uint32_t uc32_cpu_find_by_name(const char *name) |
32 | 6e64da3c | Guan Xuetao | { |
33 | 6e64da3c | Guan Xuetao | int i;
|
34 | 6e64da3c | Guan Xuetao | uint32_t id; |
35 | 6e64da3c | Guan Xuetao | |
36 | 6e64da3c | Guan Xuetao | id = 0;
|
37 | 6e64da3c | Guan Xuetao | for (i = 0; uc32_cpu_names[i].name; i++) { |
38 | 6e64da3c | Guan Xuetao | if (strcmp(name, uc32_cpu_names[i].name) == 0) { |
39 | 6e64da3c | Guan Xuetao | id = uc32_cpu_names[i].id; |
40 | 6e64da3c | Guan Xuetao | break;
|
41 | 6e64da3c | Guan Xuetao | } |
42 | 6e64da3c | Guan Xuetao | } |
43 | 6e64da3c | Guan Xuetao | return id;
|
44 | 6e64da3c | Guan Xuetao | } |
45 | 6e64da3c | Guan Xuetao | |
46 | 6e64da3c | Guan Xuetao | CPUState *uc32_cpu_init(const char *cpu_model) |
47 | 6e64da3c | Guan Xuetao | { |
48 | 6e64da3c | Guan Xuetao | CPUState *env; |
49 | 6e64da3c | Guan Xuetao | uint32_t id; |
50 | 6e64da3c | Guan Xuetao | static int inited = 1; |
51 | 6e64da3c | Guan Xuetao | |
52 | 7267c094 | Anthony Liguori | env = g_malloc0(sizeof(CPUState));
|
53 | 6e64da3c | Guan Xuetao | cpu_exec_init(env); |
54 | 6e64da3c | Guan Xuetao | |
55 | 6e64da3c | Guan Xuetao | id = uc32_cpu_find_by_name(cpu_model); |
56 | 6e64da3c | Guan Xuetao | switch (id) {
|
57 | 6e64da3c | Guan Xuetao | case UC32_CPUID_UCV2:
|
58 | 6e64da3c | Guan Xuetao | set_feature(env, UC32_HWCAP_CMOV); |
59 | 6e64da3c | Guan Xuetao | set_feature(env, UC32_HWCAP_UCF64); |
60 | 6e64da3c | Guan Xuetao | env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
|
61 | 6e64da3c | Guan Xuetao | env->cp0.c0_cachetype = 0x1dd20d2;
|
62 | 6e64da3c | Guan Xuetao | env->cp0.c1_sys = 0x00090078;
|
63 | 6e64da3c | Guan Xuetao | break;
|
64 | 6e64da3c | Guan Xuetao | case UC32_CPUID_ANY: /* For userspace emulation. */ |
65 | 6e64da3c | Guan Xuetao | set_feature(env, UC32_HWCAP_CMOV); |
66 | 6e64da3c | Guan Xuetao | set_feature(env, UC32_HWCAP_UCF64); |
67 | 6e64da3c | Guan Xuetao | break;
|
68 | 6e64da3c | Guan Xuetao | default:
|
69 | 6e64da3c | Guan Xuetao | cpu_abort(env, "Bad CPU ID: %x\n", id);
|
70 | 6e64da3c | Guan Xuetao | } |
71 | 6e64da3c | Guan Xuetao | |
72 | 6e64da3c | Guan Xuetao | env->cpu_model_str = cpu_model; |
73 | 6e64da3c | Guan Xuetao | env->cp0.c0_cpuid = id; |
74 | 6e64da3c | Guan Xuetao | env->uncached_asr = ASR_MODE_USER; |
75 | 6e64da3c | Guan Xuetao | env->regs[31] = 0; |
76 | 6e64da3c | Guan Xuetao | |
77 | 6e64da3c | Guan Xuetao | if (inited) {
|
78 | 6e64da3c | Guan Xuetao | inited = 0;
|
79 | 6e64da3c | Guan Xuetao | uc32_translate_init(); |
80 | 6e64da3c | Guan Xuetao | } |
81 | 6e64da3c | Guan Xuetao | |
82 | 6e64da3c | Guan Xuetao | tlb_flush(env, 1);
|
83 | 6e64da3c | Guan Xuetao | qemu_init_vcpu(env); |
84 | 6e64da3c | Guan Xuetao | return env;
|
85 | 6e64da3c | Guan Xuetao | } |
86 | 6e64da3c | Guan Xuetao | |
87 | 6e64da3c | Guan Xuetao | uint32_t HELPER(clo)(uint32_t x) |
88 | 6e64da3c | Guan Xuetao | { |
89 | 6e64da3c | Guan Xuetao | return clo32(x);
|
90 | 6e64da3c | Guan Xuetao | } |
91 | 6e64da3c | Guan Xuetao | |
92 | 6e64da3c | Guan Xuetao | uint32_t HELPER(clz)(uint32_t x) |
93 | 6e64da3c | Guan Xuetao | { |
94 | 6e64da3c | Guan Xuetao | return clz32(x);
|
95 | 6e64da3c | Guan Xuetao | } |
96 | 6e64da3c | Guan Xuetao | |
97 | 6e64da3c | Guan Xuetao | void do_interrupt(CPUState *env)
|
98 | 6e64da3c | Guan Xuetao | { |
99 | 6e64da3c | Guan Xuetao | env->exception_index = -1;
|
100 | 6e64da3c | Guan Xuetao | } |
101 | 6e64da3c | Guan Xuetao | |
102 | 6e64da3c | Guan Xuetao | int uc32_cpu_handle_mmu_fault(CPUState *env, target_ulong address, int rw, |
103 | 97b348e7 | Blue Swirl | int mmu_idx)
|
104 | 6e64da3c | Guan Xuetao | { |
105 | 6e64da3c | Guan Xuetao | env->exception_index = UC32_EXCP_TRAP; |
106 | 6e64da3c | Guan Xuetao | env->cp0.c4_faultaddr = address; |
107 | 6e64da3c | Guan Xuetao | return 1; |
108 | 6e64da3c | Guan Xuetao | } |
109 | 6e64da3c | Guan Xuetao | |
110 | 6e64da3c | Guan Xuetao | /* These should probably raise undefined insn exceptions. */
|
111 | 6e64da3c | Guan Xuetao | void HELPER(set_cp)(CPUState *env, uint32_t insn, uint32_t val)
|
112 | 6e64da3c | Guan Xuetao | { |
113 | 6e64da3c | Guan Xuetao | int op1 = (insn >> 8) & 0xf; |
114 | 6e64da3c | Guan Xuetao | cpu_abort(env, "cp%i insn %08x\n", op1, insn);
|
115 | 6e64da3c | Guan Xuetao | return;
|
116 | 6e64da3c | Guan Xuetao | } |
117 | 6e64da3c | Guan Xuetao | |
118 | 6e64da3c | Guan Xuetao | uint32_t HELPER(get_cp)(CPUState *env, uint32_t insn) |
119 | 6e64da3c | Guan Xuetao | { |
120 | 6e64da3c | Guan Xuetao | int op1 = (insn >> 8) & 0xf; |
121 | 6e64da3c | Guan Xuetao | cpu_abort(env, "cp%i insn %08x\n", op1, insn);
|
122 | 6e64da3c | Guan Xuetao | return 0; |
123 | 6e64da3c | Guan Xuetao | } |
124 | 6e64da3c | Guan Xuetao | |
125 | 6e64da3c | Guan Xuetao | void HELPER(set_cp0)(CPUState *env, uint32_t insn, uint32_t val)
|
126 | 6e64da3c | Guan Xuetao | { |
127 | 6e64da3c | Guan Xuetao | cpu_abort(env, "cp0 insn %08x\n", insn);
|
128 | 6e64da3c | Guan Xuetao | } |
129 | 6e64da3c | Guan Xuetao | |
130 | 6e64da3c | Guan Xuetao | uint32_t HELPER(get_cp0)(CPUState *env, uint32_t insn) |
131 | 6e64da3c | Guan Xuetao | { |
132 | 6e64da3c | Guan Xuetao | cpu_abort(env, "cp0 insn %08x\n", insn);
|
133 | 6e64da3c | Guan Xuetao | return 0; |
134 | 6e64da3c | Guan Xuetao | } |
135 | 6e64da3c | Guan Xuetao | |
136 | 6e64da3c | Guan Xuetao | void switch_mode(CPUState *env, int mode) |
137 | 6e64da3c | Guan Xuetao | { |
138 | 6e64da3c | Guan Xuetao | if (mode != ASR_MODE_USER) {
|
139 | 6e64da3c | Guan Xuetao | cpu_abort(env, "Tried to switch out of user mode\n");
|
140 | 6e64da3c | Guan Xuetao | } |
141 | 6e64da3c | Guan Xuetao | } |
142 | 6e64da3c | Guan Xuetao | |
143 | 6e64da3c | Guan Xuetao | void HELPER(set_r29_banked)(CPUState *env, uint32_t mode, uint32_t val)
|
144 | 6e64da3c | Guan Xuetao | { |
145 | 6e64da3c | Guan Xuetao | cpu_abort(env, "banked r29 write\n");
|
146 | 6e64da3c | Guan Xuetao | } |
147 | 6e64da3c | Guan Xuetao | |
148 | 6e64da3c | Guan Xuetao | uint32_t HELPER(get_r29_banked)(CPUState *env, uint32_t mode) |
149 | 6e64da3c | Guan Xuetao | { |
150 | 6e64da3c | Guan Xuetao | cpu_abort(env, "banked r29 read\n");
|
151 | 6e64da3c | Guan Xuetao | return 0; |
152 | 6e64da3c | Guan Xuetao | } |
153 | 6e64da3c | Guan Xuetao | |
154 | 6e64da3c | Guan Xuetao | /* UniCore-F64 support. We follow the convention used for F64 instrunctions:
|
155 | 6e64da3c | Guan Xuetao | Single precition routines have a "s" suffix, double precision a
|
156 | 6e64da3c | Guan Xuetao | "d" suffix. */
|
157 | 6e64da3c | Guan Xuetao | |
158 | 6e64da3c | Guan Xuetao | /* Convert host exception flags to f64 form. */
|
159 | 6e64da3c | Guan Xuetao | static inline int ucf64_exceptbits_from_host(int host_bits) |
160 | 6e64da3c | Guan Xuetao | { |
161 | 6e64da3c | Guan Xuetao | int target_bits = 0; |
162 | 6e64da3c | Guan Xuetao | |
163 | 6e64da3c | Guan Xuetao | if (host_bits & float_flag_invalid) {
|
164 | 6e64da3c | Guan Xuetao | target_bits |= UCF64_FPSCR_FLAG_INVALID; |
165 | 6e64da3c | Guan Xuetao | } |
166 | 6e64da3c | Guan Xuetao | if (host_bits & float_flag_divbyzero) {
|
167 | 6e64da3c | Guan Xuetao | target_bits |= UCF64_FPSCR_FLAG_DIVZERO; |
168 | 6e64da3c | Guan Xuetao | } |
169 | 6e64da3c | Guan Xuetao | if (host_bits & float_flag_overflow) {
|
170 | 6e64da3c | Guan Xuetao | target_bits |= UCF64_FPSCR_FLAG_OVERFLOW; |
171 | 6e64da3c | Guan Xuetao | } |
172 | 6e64da3c | Guan Xuetao | if (host_bits & float_flag_underflow) {
|
173 | 6e64da3c | Guan Xuetao | target_bits |= UCF64_FPSCR_FLAG_UNDERFLOW; |
174 | 6e64da3c | Guan Xuetao | } |
175 | 6e64da3c | Guan Xuetao | if (host_bits & float_flag_inexact) {
|
176 | 6e64da3c | Guan Xuetao | target_bits |= UCF64_FPSCR_FLAG_INEXACT; |
177 | 6e64da3c | Guan Xuetao | } |
178 | 6e64da3c | Guan Xuetao | return target_bits;
|
179 | 6e64da3c | Guan Xuetao | } |
180 | 6e64da3c | Guan Xuetao | |
181 | 6e64da3c | Guan Xuetao | uint32_t HELPER(ucf64_get_fpscr)(CPUState *env) |
182 | 6e64da3c | Guan Xuetao | { |
183 | 6e64da3c | Guan Xuetao | int i;
|
184 | 6e64da3c | Guan Xuetao | uint32_t fpscr; |
185 | 6e64da3c | Guan Xuetao | |
186 | 6e64da3c | Guan Xuetao | fpscr = (env->ucf64.xregs[UC32_UCF64_FPSCR] & UCF64_FPSCR_MASK); |
187 | 6e64da3c | Guan Xuetao | i = get_float_exception_flags(&env->ucf64.fp_status); |
188 | 6e64da3c | Guan Xuetao | fpscr |= ucf64_exceptbits_from_host(i); |
189 | 6e64da3c | Guan Xuetao | return fpscr;
|
190 | 6e64da3c | Guan Xuetao | } |
191 | 6e64da3c | Guan Xuetao | |
192 | 6e64da3c | Guan Xuetao | /* Convert ucf64 exception flags to target form. */
|
193 | 6e64da3c | Guan Xuetao | static inline int ucf64_exceptbits_to_host(int target_bits) |
194 | 6e64da3c | Guan Xuetao | { |
195 | 6e64da3c | Guan Xuetao | int host_bits = 0; |
196 | 6e64da3c | Guan Xuetao | |
197 | 6e64da3c | Guan Xuetao | if (target_bits & UCF64_FPSCR_FLAG_INVALID) {
|
198 | 6e64da3c | Guan Xuetao | host_bits |= float_flag_invalid; |
199 | 6e64da3c | Guan Xuetao | } |
200 | 6e64da3c | Guan Xuetao | if (target_bits & UCF64_FPSCR_FLAG_DIVZERO) {
|
201 | 6e64da3c | Guan Xuetao | host_bits |= float_flag_divbyzero; |
202 | 6e64da3c | Guan Xuetao | } |
203 | 6e64da3c | Guan Xuetao | if (target_bits & UCF64_FPSCR_FLAG_OVERFLOW) {
|
204 | 6e64da3c | Guan Xuetao | host_bits |= float_flag_overflow; |
205 | 6e64da3c | Guan Xuetao | } |
206 | 6e64da3c | Guan Xuetao | if (target_bits & UCF64_FPSCR_FLAG_UNDERFLOW) {
|
207 | 6e64da3c | Guan Xuetao | host_bits |= float_flag_underflow; |
208 | 6e64da3c | Guan Xuetao | } |
209 | 6e64da3c | Guan Xuetao | if (target_bits & UCF64_FPSCR_FLAG_INEXACT) {
|
210 | 6e64da3c | Guan Xuetao | host_bits |= float_flag_inexact; |
211 | 6e64da3c | Guan Xuetao | } |
212 | 6e64da3c | Guan Xuetao | return host_bits;
|
213 | 6e64da3c | Guan Xuetao | } |
214 | 6e64da3c | Guan Xuetao | |
215 | 6e64da3c | Guan Xuetao | void HELPER(ucf64_set_fpscr)(CPUState *env, uint32_t val)
|
216 | 6e64da3c | Guan Xuetao | { |
217 | 6e64da3c | Guan Xuetao | int i;
|
218 | 6e64da3c | Guan Xuetao | uint32_t changed; |
219 | 6e64da3c | Guan Xuetao | |
220 | 6e64da3c | Guan Xuetao | changed = env->ucf64.xregs[UC32_UCF64_FPSCR]; |
221 | 6e64da3c | Guan Xuetao | env->ucf64.xregs[UC32_UCF64_FPSCR] = (val & UCF64_FPSCR_MASK); |
222 | 6e64da3c | Guan Xuetao | |
223 | 6e64da3c | Guan Xuetao | changed ^= val; |
224 | 6e64da3c | Guan Xuetao | if (changed & (UCF64_FPSCR_RND_MASK)) {
|
225 | 6e64da3c | Guan Xuetao | i = UCF64_FPSCR_RND(val); |
226 | 6e64da3c | Guan Xuetao | switch (i) {
|
227 | 6e64da3c | Guan Xuetao | case 0: |
228 | 6e64da3c | Guan Xuetao | i = float_round_nearest_even; |
229 | 6e64da3c | Guan Xuetao | break;
|
230 | 6e64da3c | Guan Xuetao | case 1: |
231 | 6e64da3c | Guan Xuetao | i = float_round_to_zero; |
232 | 6e64da3c | Guan Xuetao | break;
|
233 | 6e64da3c | Guan Xuetao | case 2: |
234 | 6e64da3c | Guan Xuetao | i = float_round_up; |
235 | 6e64da3c | Guan Xuetao | break;
|
236 | 6e64da3c | Guan Xuetao | case 3: |
237 | 6e64da3c | Guan Xuetao | i = float_round_down; |
238 | 6e64da3c | Guan Xuetao | break;
|
239 | 6e64da3c | Guan Xuetao | default: /* 100 and 101 not implement */ |
240 | 6e64da3c | Guan Xuetao | cpu_abort(env, "Unsupported UniCore-F64 round mode");
|
241 | 6e64da3c | Guan Xuetao | } |
242 | 6e64da3c | Guan Xuetao | set_float_rounding_mode(i, &env->ucf64.fp_status); |
243 | 6e64da3c | Guan Xuetao | } |
244 | 6e64da3c | Guan Xuetao | |
245 | 6e64da3c | Guan Xuetao | i = ucf64_exceptbits_to_host(UCF64_FPSCR_TRAPEN(val)); |
246 | 6e64da3c | Guan Xuetao | set_float_exception_flags(i, &env->ucf64.fp_status); |
247 | 6e64da3c | Guan Xuetao | } |
248 | 6e64da3c | Guan Xuetao | |
249 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_adds)(float32 a, float32 b, CPUState *env) |
250 | 6e64da3c | Guan Xuetao | { |
251 | 6e64da3c | Guan Xuetao | return float32_add(a, b, &env->ucf64.fp_status);
|
252 | 6e64da3c | Guan Xuetao | } |
253 | 6e64da3c | Guan Xuetao | |
254 | 6e64da3c | Guan Xuetao | float64 HELPER(ucf64_addd)(float64 a, float64 b, CPUState *env) |
255 | 6e64da3c | Guan Xuetao | { |
256 | 6e64da3c | Guan Xuetao | return float64_add(a, b, &env->ucf64.fp_status);
|
257 | 6e64da3c | Guan Xuetao | } |
258 | 6e64da3c | Guan Xuetao | |
259 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_subs)(float32 a, float32 b, CPUState *env) |
260 | 6e64da3c | Guan Xuetao | { |
261 | 6e64da3c | Guan Xuetao | return float32_sub(a, b, &env->ucf64.fp_status);
|
262 | 6e64da3c | Guan Xuetao | } |
263 | 6e64da3c | Guan Xuetao | |
264 | 6e64da3c | Guan Xuetao | float64 HELPER(ucf64_subd)(float64 a, float64 b, CPUState *env) |
265 | 6e64da3c | Guan Xuetao | { |
266 | 6e64da3c | Guan Xuetao | return float64_sub(a, b, &env->ucf64.fp_status);
|
267 | 6e64da3c | Guan Xuetao | } |
268 | 6e64da3c | Guan Xuetao | |
269 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_muls)(float32 a, float32 b, CPUState *env) |
270 | 6e64da3c | Guan Xuetao | { |
271 | 6e64da3c | Guan Xuetao | return float32_mul(a, b, &env->ucf64.fp_status);
|
272 | 6e64da3c | Guan Xuetao | } |
273 | 6e64da3c | Guan Xuetao | |
274 | 6e64da3c | Guan Xuetao | float64 HELPER(ucf64_muld)(float64 a, float64 b, CPUState *env) |
275 | 6e64da3c | Guan Xuetao | { |
276 | 6e64da3c | Guan Xuetao | return float64_mul(a, b, &env->ucf64.fp_status);
|
277 | 6e64da3c | Guan Xuetao | } |
278 | 6e64da3c | Guan Xuetao | |
279 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_divs)(float32 a, float32 b, CPUState *env) |
280 | 6e64da3c | Guan Xuetao | { |
281 | 6e64da3c | Guan Xuetao | return float32_div(a, b, &env->ucf64.fp_status);
|
282 | 6e64da3c | Guan Xuetao | } |
283 | 6e64da3c | Guan Xuetao | |
284 | 6e64da3c | Guan Xuetao | float64 HELPER(ucf64_divd)(float64 a, float64 b, CPUState *env) |
285 | 6e64da3c | Guan Xuetao | { |
286 | 6e64da3c | Guan Xuetao | return float64_div(a, b, &env->ucf64.fp_status);
|
287 | 6e64da3c | Guan Xuetao | } |
288 | 6e64da3c | Guan Xuetao | |
289 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_negs)(float32 a) |
290 | 6e64da3c | Guan Xuetao | { |
291 | 6e64da3c | Guan Xuetao | return float32_chs(a);
|
292 | 6e64da3c | Guan Xuetao | } |
293 | 6e64da3c | Guan Xuetao | |
294 | 6e64da3c | Guan Xuetao | float64 HELPER(ucf64_negd)(float64 a) |
295 | 6e64da3c | Guan Xuetao | { |
296 | 6e64da3c | Guan Xuetao | return float64_chs(a);
|
297 | 6e64da3c | Guan Xuetao | } |
298 | 6e64da3c | Guan Xuetao | |
299 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_abss)(float32 a) |
300 | 6e64da3c | Guan Xuetao | { |
301 | 6e64da3c | Guan Xuetao | return float32_abs(a);
|
302 | 6e64da3c | Guan Xuetao | } |
303 | 6e64da3c | Guan Xuetao | |
304 | 6e64da3c | Guan Xuetao | float64 HELPER(ucf64_absd)(float64 a) |
305 | 6e64da3c | Guan Xuetao | { |
306 | 6e64da3c | Guan Xuetao | return float64_abs(a);
|
307 | 6e64da3c | Guan Xuetao | } |
308 | 6e64da3c | Guan Xuetao | |
309 | 6e64da3c | Guan Xuetao | /* XXX: check quiet/signaling case */
|
310 | 6e64da3c | Guan Xuetao | void HELPER(ucf64_cmps)(float32 a, float32 b, uint32_t c, CPUState *env)
|
311 | 6e64da3c | Guan Xuetao | { |
312 | 6e64da3c | Guan Xuetao | int flag;
|
313 | 6e64da3c | Guan Xuetao | flag = float32_compare_quiet(a, b, &env->ucf64.fp_status); |
314 | 6e64da3c | Guan Xuetao | env->CF = 0;
|
315 | 6e64da3c | Guan Xuetao | switch (c & 0x7) { |
316 | 6e64da3c | Guan Xuetao | case 0: /* F */ |
317 | 6e64da3c | Guan Xuetao | break;
|
318 | 6e64da3c | Guan Xuetao | case 1: /* UN */ |
319 | 6e64da3c | Guan Xuetao | if (flag == 2) { |
320 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
321 | 6e64da3c | Guan Xuetao | } |
322 | 6e64da3c | Guan Xuetao | break;
|
323 | 6e64da3c | Guan Xuetao | case 2: /* EQ */ |
324 | 6e64da3c | Guan Xuetao | if (flag == 0) { |
325 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
326 | 6e64da3c | Guan Xuetao | } |
327 | 6e64da3c | Guan Xuetao | break;
|
328 | 6e64da3c | Guan Xuetao | case 3: /* UEQ */ |
329 | 6e64da3c | Guan Xuetao | if ((flag == 0) || (flag == 2)) { |
330 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
331 | 6e64da3c | Guan Xuetao | } |
332 | 6e64da3c | Guan Xuetao | break;
|
333 | 6e64da3c | Guan Xuetao | case 4: /* OLT */ |
334 | 6e64da3c | Guan Xuetao | if (flag == -1) { |
335 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
336 | 6e64da3c | Guan Xuetao | } |
337 | 6e64da3c | Guan Xuetao | break;
|
338 | 6e64da3c | Guan Xuetao | case 5: /* ULT */ |
339 | 6e64da3c | Guan Xuetao | if ((flag == -1) || (flag == 2)) { |
340 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
341 | 6e64da3c | Guan Xuetao | } |
342 | 6e64da3c | Guan Xuetao | break;
|
343 | 6e64da3c | Guan Xuetao | case 6: /* OLE */ |
344 | 6e64da3c | Guan Xuetao | if ((flag == -1) || (flag == 0)) { |
345 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
346 | 6e64da3c | Guan Xuetao | } |
347 | 6e64da3c | Guan Xuetao | break;
|
348 | 6e64da3c | Guan Xuetao | case 7: /* ULE */ |
349 | 6e64da3c | Guan Xuetao | if (flag != 1) { |
350 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
351 | 6e64da3c | Guan Xuetao | } |
352 | 6e64da3c | Guan Xuetao | break;
|
353 | 6e64da3c | Guan Xuetao | } |
354 | 6e64da3c | Guan Xuetao | env->ucf64.xregs[UC32_UCF64_FPSCR] = (env->CF << 29)
|
355 | 6e64da3c | Guan Xuetao | | (env->ucf64.xregs[UC32_UCF64_FPSCR] & 0x0fffffff);
|
356 | 6e64da3c | Guan Xuetao | } |
357 | 6e64da3c | Guan Xuetao | |
358 | 6e64da3c | Guan Xuetao | void HELPER(ucf64_cmpd)(float64 a, float64 b, uint32_t c, CPUState *env)
|
359 | 6e64da3c | Guan Xuetao | { |
360 | 6e64da3c | Guan Xuetao | int flag;
|
361 | 6e64da3c | Guan Xuetao | flag = float64_compare_quiet(a, b, &env->ucf64.fp_status); |
362 | 6e64da3c | Guan Xuetao | env->CF = 0;
|
363 | 6e64da3c | Guan Xuetao | switch (c & 0x7) { |
364 | 6e64da3c | Guan Xuetao | case 0: /* F */ |
365 | 6e64da3c | Guan Xuetao | break;
|
366 | 6e64da3c | Guan Xuetao | case 1: /* UN */ |
367 | 6e64da3c | Guan Xuetao | if (flag == 2) { |
368 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
369 | 6e64da3c | Guan Xuetao | } |
370 | 6e64da3c | Guan Xuetao | break;
|
371 | 6e64da3c | Guan Xuetao | case 2: /* EQ */ |
372 | 6e64da3c | Guan Xuetao | if (flag == 0) { |
373 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
374 | 6e64da3c | Guan Xuetao | } |
375 | 6e64da3c | Guan Xuetao | break;
|
376 | 6e64da3c | Guan Xuetao | case 3: /* UEQ */ |
377 | 6e64da3c | Guan Xuetao | if ((flag == 0) || (flag == 2)) { |
378 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
379 | 6e64da3c | Guan Xuetao | } |
380 | 6e64da3c | Guan Xuetao | break;
|
381 | 6e64da3c | Guan Xuetao | case 4: /* OLT */ |
382 | 6e64da3c | Guan Xuetao | if (flag == -1) { |
383 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
384 | 6e64da3c | Guan Xuetao | } |
385 | 6e64da3c | Guan Xuetao | break;
|
386 | 6e64da3c | Guan Xuetao | case 5: /* ULT */ |
387 | 6e64da3c | Guan Xuetao | if ((flag == -1) || (flag == 2)) { |
388 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
389 | 6e64da3c | Guan Xuetao | } |
390 | 6e64da3c | Guan Xuetao | break;
|
391 | 6e64da3c | Guan Xuetao | case 6: /* OLE */ |
392 | 6e64da3c | Guan Xuetao | if ((flag == -1) || (flag == 0)) { |
393 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
394 | 6e64da3c | Guan Xuetao | } |
395 | 6e64da3c | Guan Xuetao | break;
|
396 | 6e64da3c | Guan Xuetao | case 7: /* ULE */ |
397 | 6e64da3c | Guan Xuetao | if (flag != 1) { |
398 | 6e64da3c | Guan Xuetao | env->CF = 1;
|
399 | 6e64da3c | Guan Xuetao | } |
400 | 6e64da3c | Guan Xuetao | break;
|
401 | 6e64da3c | Guan Xuetao | } |
402 | 6e64da3c | Guan Xuetao | env->ucf64.xregs[UC32_UCF64_FPSCR] = (env->CF << 29)
|
403 | 6e64da3c | Guan Xuetao | | (env->ucf64.xregs[UC32_UCF64_FPSCR] & 0x0fffffff);
|
404 | 6e64da3c | Guan Xuetao | } |
405 | 6e64da3c | Guan Xuetao | |
406 | 6e64da3c | Guan Xuetao | /* Helper routines to perform bitwise copies between float and int. */
|
407 | 6e64da3c | Guan Xuetao | static inline float32 ucf64_itos(uint32_t i) |
408 | 6e64da3c | Guan Xuetao | { |
409 | 6e64da3c | Guan Xuetao | union {
|
410 | 6e64da3c | Guan Xuetao | uint32_t i; |
411 | 6e64da3c | Guan Xuetao | float32 s; |
412 | 6e64da3c | Guan Xuetao | } v; |
413 | 6e64da3c | Guan Xuetao | |
414 | 6e64da3c | Guan Xuetao | v.i = i; |
415 | 6e64da3c | Guan Xuetao | return v.s;
|
416 | 6e64da3c | Guan Xuetao | } |
417 | 6e64da3c | Guan Xuetao | |
418 | 6e64da3c | Guan Xuetao | static inline uint32_t ucf64_stoi(float32 s) |
419 | 6e64da3c | Guan Xuetao | { |
420 | 6e64da3c | Guan Xuetao | union {
|
421 | 6e64da3c | Guan Xuetao | uint32_t i; |
422 | 6e64da3c | Guan Xuetao | float32 s; |
423 | 6e64da3c | Guan Xuetao | } v; |
424 | 6e64da3c | Guan Xuetao | |
425 | 6e64da3c | Guan Xuetao | v.s = s; |
426 | 6e64da3c | Guan Xuetao | return v.i;
|
427 | 6e64da3c | Guan Xuetao | } |
428 | 6e64da3c | Guan Xuetao | |
429 | 6e64da3c | Guan Xuetao | static inline float64 ucf64_itod(uint64_t i) |
430 | 6e64da3c | Guan Xuetao | { |
431 | 6e64da3c | Guan Xuetao | union {
|
432 | 6e64da3c | Guan Xuetao | uint64_t i; |
433 | 6e64da3c | Guan Xuetao | float64 d; |
434 | 6e64da3c | Guan Xuetao | } v; |
435 | 6e64da3c | Guan Xuetao | |
436 | 6e64da3c | Guan Xuetao | v.i = i; |
437 | 6e64da3c | Guan Xuetao | return v.d;
|
438 | 6e64da3c | Guan Xuetao | } |
439 | 6e64da3c | Guan Xuetao | |
440 | 6e64da3c | Guan Xuetao | static inline uint64_t ucf64_dtoi(float64 d) |
441 | 6e64da3c | Guan Xuetao | { |
442 | 6e64da3c | Guan Xuetao | union {
|
443 | 6e64da3c | Guan Xuetao | uint64_t i; |
444 | 6e64da3c | Guan Xuetao | float64 d; |
445 | 6e64da3c | Guan Xuetao | } v; |
446 | 6e64da3c | Guan Xuetao | |
447 | 6e64da3c | Guan Xuetao | v.d = d; |
448 | 6e64da3c | Guan Xuetao | return v.i;
|
449 | 6e64da3c | Guan Xuetao | } |
450 | 6e64da3c | Guan Xuetao | |
451 | 6e64da3c | Guan Xuetao | /* Integer to float conversion. */
|
452 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_si2sf)(float32 x, CPUState *env) |
453 | 6e64da3c | Guan Xuetao | { |
454 | 6e64da3c | Guan Xuetao | return int32_to_float32(ucf64_stoi(x), &env->ucf64.fp_status);
|
455 | 6e64da3c | Guan Xuetao | } |
456 | 6e64da3c | Guan Xuetao | |
457 | 6e64da3c | Guan Xuetao | float64 HELPER(ucf64_si2df)(float32 x, CPUState *env) |
458 | 6e64da3c | Guan Xuetao | { |
459 | 6e64da3c | Guan Xuetao | return int32_to_float64(ucf64_stoi(x), &env->ucf64.fp_status);
|
460 | 6e64da3c | Guan Xuetao | } |
461 | 6e64da3c | Guan Xuetao | |
462 | 6e64da3c | Guan Xuetao | /* Float to integer conversion. */
|
463 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_sf2si)(float32 x, CPUState *env) |
464 | 6e64da3c | Guan Xuetao | { |
465 | 6e64da3c | Guan Xuetao | return ucf64_itos(float32_to_int32(x, &env->ucf64.fp_status));
|
466 | 6e64da3c | Guan Xuetao | } |
467 | 6e64da3c | Guan Xuetao | |
468 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_df2si)(float64 x, CPUState *env) |
469 | 6e64da3c | Guan Xuetao | { |
470 | 6e64da3c | Guan Xuetao | return ucf64_itos(float64_to_int32(x, &env->ucf64.fp_status));
|
471 | 6e64da3c | Guan Xuetao | } |
472 | 6e64da3c | Guan Xuetao | |
473 | 6e64da3c | Guan Xuetao | /* floating point conversion */
|
474 | 6e64da3c | Guan Xuetao | float64 HELPER(ucf64_sf2df)(float32 x, CPUState *env) |
475 | 6e64da3c | Guan Xuetao | { |
476 | 6e64da3c | Guan Xuetao | return float32_to_float64(x, &env->ucf64.fp_status);
|
477 | 6e64da3c | Guan Xuetao | } |
478 | 6e64da3c | Guan Xuetao | |
479 | 6e64da3c | Guan Xuetao | float32 HELPER(ucf64_df2sf)(float64 x, CPUState *env) |
480 | 6e64da3c | Guan Xuetao | { |
481 | 6e64da3c | Guan Xuetao | return float64_to_float32(x, &env->ucf64.fp_status);
|
482 | 6e64da3c | Guan Xuetao | } |