root / target-unicore32 / op_helper.c @ 5cd8f621
History | View | Annotate | Download (6.2 kB)
1 | 6e64da3c | Guan Xuetao | /*
|
---|---|---|---|
2 | 6e64da3c | Guan Xuetao | * UniCore32 helper routines
|
3 | 6e64da3c | Guan Xuetao | *
|
4 | 4f23a1e6 | Guan Xuetao | * Copyright (C) 2010-2012 Guan Xuetao
|
5 | 6e64da3c | Guan Xuetao | *
|
6 | 6e64da3c | Guan Xuetao | * This program is free software; you can redistribute it and/or modify
|
7 | 6e64da3c | Guan Xuetao | * it under the terms of the GNU General Public License version 2 as
|
8 | 2b3bc6c0 | Andreas Färber | * published by the Free Software Foundation, or (at your option) any
|
9 | 2b3bc6c0 | Andreas Färber | * later version. See the COPYING file in the top-level directory.
|
10 | 6e64da3c | Guan Xuetao | */
|
11 | 3e457172 | Blue Swirl | #include "cpu.h" |
12 | 6e64da3c | Guan Xuetao | #include "helper.h" |
13 | 6e64da3c | Guan Xuetao | |
14 | 6e64da3c | Guan Xuetao | #define SIGNBIT (uint32_t)0x80000000 |
15 | 6e64da3c | Guan Xuetao | #define SIGNBIT64 ((uint64_t)1 << 63) |
16 | 6e64da3c | Guan Xuetao | |
17 | 04a130ea | Blue Swirl | void HELPER(exception)(CPUUniCore32State *env, uint32_t excp)
|
18 | 6e64da3c | Guan Xuetao | { |
19 | 6e64da3c | Guan Xuetao | env->exception_index = excp; |
20 | 1162c041 | Blue Swirl | cpu_loop_exit(env); |
21 | 6e64da3c | Guan Xuetao | } |
22 | 6e64da3c | Guan Xuetao | |
23 | 04a130ea | Blue Swirl | static target_ulong asr_read(CPUUniCore32State *env)
|
24 | 6e64da3c | Guan Xuetao | { |
25 | 6e64da3c | Guan Xuetao | int ZF;
|
26 | 6e64da3c | Guan Xuetao | ZF = (env->ZF == 0);
|
27 | 6e64da3c | Guan Xuetao | return env->uncached_asr | (env->NF & 0x80000000) | (ZF << 30) | |
28 | 6e64da3c | Guan Xuetao | (env->CF << 29) | ((env->VF & 0x80000000) >> 3); |
29 | 6e64da3c | Guan Xuetao | } |
30 | 6e64da3c | Guan Xuetao | |
31 | 04a130ea | Blue Swirl | target_ulong cpu_asr_read(CPUUniCore32State *env) |
32 | 6e64da3c | Guan Xuetao | { |
33 | 04a130ea | Blue Swirl | return asr_read(env);
|
34 | 6e64da3c | Guan Xuetao | } |
35 | 6e64da3c | Guan Xuetao | |
36 | 04a130ea | Blue Swirl | target_ulong HELPER(asr_read)(CPUUniCore32State *env) |
37 | 6e64da3c | Guan Xuetao | { |
38 | 04a130ea | Blue Swirl | return asr_read(env);
|
39 | 6e64da3c | Guan Xuetao | } |
40 | 6e64da3c | Guan Xuetao | |
41 | 04a130ea | Blue Swirl | static void asr_write(CPUUniCore32State *env, target_ulong val, |
42 | 04a130ea | Blue Swirl | target_ulong mask) |
43 | 6e64da3c | Guan Xuetao | { |
44 | 6e64da3c | Guan Xuetao | if (mask & ASR_NZCV) {
|
45 | 6e64da3c | Guan Xuetao | env->ZF = (~val) & ASR_Z; |
46 | 6e64da3c | Guan Xuetao | env->NF = val; |
47 | 6e64da3c | Guan Xuetao | env->CF = (val >> 29) & 1; |
48 | 6e64da3c | Guan Xuetao | env->VF = (val << 3) & 0x80000000; |
49 | 6e64da3c | Guan Xuetao | } |
50 | 6e64da3c | Guan Xuetao | |
51 | 6e64da3c | Guan Xuetao | if ((env->uncached_asr ^ val) & mask & ASR_M) {
|
52 | 6e64da3c | Guan Xuetao | switch_mode(env, val & ASR_M); |
53 | 6e64da3c | Guan Xuetao | } |
54 | 6e64da3c | Guan Xuetao | mask &= ~ASR_NZCV; |
55 | 6e64da3c | Guan Xuetao | env->uncached_asr = (env->uncached_asr & ~mask) | (val & mask); |
56 | 6e64da3c | Guan Xuetao | } |
57 | 6e64da3c | Guan Xuetao | |
58 | 04a130ea | Blue Swirl | void cpu_asr_write(CPUUniCore32State *env, target_ulong val, target_ulong mask)
|
59 | 6e64da3c | Guan Xuetao | { |
60 | 04a130ea | Blue Swirl | asr_write(env, val, mask); |
61 | 6e64da3c | Guan Xuetao | } |
62 | 6e64da3c | Guan Xuetao | |
63 | 04a130ea | Blue Swirl | void HELPER(asr_write)(CPUUniCore32State *env, target_ulong val,
|
64 | 04a130ea | Blue Swirl | target_ulong mask) |
65 | 6e64da3c | Guan Xuetao | { |
66 | 04a130ea | Blue Swirl | asr_write(env, val, mask); |
67 | 6e64da3c | Guan Xuetao | } |
68 | 6e64da3c | Guan Xuetao | |
69 | 6e64da3c | Guan Xuetao | /* Access to user mode registers from privileged modes. */
|
70 | 04a130ea | Blue Swirl | uint32_t HELPER(get_user_reg)(CPUUniCore32State *env, uint32_t regno) |
71 | 6e64da3c | Guan Xuetao | { |
72 | 6e64da3c | Guan Xuetao | uint32_t val; |
73 | 6e64da3c | Guan Xuetao | |
74 | 6e64da3c | Guan Xuetao | if (regno == 29) { |
75 | 6e64da3c | Guan Xuetao | val = env->banked_r29[0];
|
76 | 6e64da3c | Guan Xuetao | } else if (regno == 30) { |
77 | 6e64da3c | Guan Xuetao | val = env->banked_r30[0];
|
78 | 6e64da3c | Guan Xuetao | } else {
|
79 | 6e64da3c | Guan Xuetao | val = env->regs[regno]; |
80 | 6e64da3c | Guan Xuetao | } |
81 | 6e64da3c | Guan Xuetao | return val;
|
82 | 6e64da3c | Guan Xuetao | } |
83 | 6e64da3c | Guan Xuetao | |
84 | 04a130ea | Blue Swirl | void HELPER(set_user_reg)(CPUUniCore32State *env, uint32_t regno, uint32_t val)
|
85 | 6e64da3c | Guan Xuetao | { |
86 | 6e64da3c | Guan Xuetao | if (regno == 29) { |
87 | 6e64da3c | Guan Xuetao | env->banked_r29[0] = val;
|
88 | 6e64da3c | Guan Xuetao | } else if (regno == 30) { |
89 | 6e64da3c | Guan Xuetao | env->banked_r30[0] = val;
|
90 | 6e64da3c | Guan Xuetao | } else {
|
91 | 6e64da3c | Guan Xuetao | env->regs[regno] = val; |
92 | 6e64da3c | Guan Xuetao | } |
93 | 6e64da3c | Guan Xuetao | } |
94 | 6e64da3c | Guan Xuetao | |
95 | 6e64da3c | Guan Xuetao | /* ??? Flag setting arithmetic is awkward because we need to do comparisons.
|
96 | 6e64da3c | Guan Xuetao | The only way to do that in TCG is a conditional branch, which clobbers
|
97 | 6e64da3c | Guan Xuetao | all our temporaries. For now implement these as helper functions. */
|
98 | 6e64da3c | Guan Xuetao | |
99 | 04a130ea | Blue Swirl | uint32_t HELPER(add_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b) |
100 | 6e64da3c | Guan Xuetao | { |
101 | 6e64da3c | Guan Xuetao | uint32_t result; |
102 | 6e64da3c | Guan Xuetao | result = a + b; |
103 | 6e64da3c | Guan Xuetao | env->NF = env->ZF = result; |
104 | 6e64da3c | Guan Xuetao | env->CF = result < a; |
105 | 6e64da3c | Guan Xuetao | env->VF = (a ^ b ^ -1) & (a ^ result);
|
106 | 6e64da3c | Guan Xuetao | return result;
|
107 | 6e64da3c | Guan Xuetao | } |
108 | 6e64da3c | Guan Xuetao | |
109 | 04a130ea | Blue Swirl | uint32_t HELPER(adc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b) |
110 | 6e64da3c | Guan Xuetao | { |
111 | 6e64da3c | Guan Xuetao | uint32_t result; |
112 | 6e64da3c | Guan Xuetao | if (!env->CF) {
|
113 | 6e64da3c | Guan Xuetao | result = a + b; |
114 | 6e64da3c | Guan Xuetao | env->CF = result < a; |
115 | 6e64da3c | Guan Xuetao | } else {
|
116 | 6e64da3c | Guan Xuetao | result = a + b + 1;
|
117 | 6e64da3c | Guan Xuetao | env->CF = result <= a; |
118 | 6e64da3c | Guan Xuetao | } |
119 | 6e64da3c | Guan Xuetao | env->VF = (a ^ b ^ -1) & (a ^ result);
|
120 | 6e64da3c | Guan Xuetao | env->NF = env->ZF = result; |
121 | 6e64da3c | Guan Xuetao | return result;
|
122 | 6e64da3c | Guan Xuetao | } |
123 | 6e64da3c | Guan Xuetao | |
124 | 04a130ea | Blue Swirl | uint32_t HELPER(sub_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b) |
125 | 6e64da3c | Guan Xuetao | { |
126 | 6e64da3c | Guan Xuetao | uint32_t result; |
127 | 6e64da3c | Guan Xuetao | result = a - b; |
128 | 6e64da3c | Guan Xuetao | env->NF = env->ZF = result; |
129 | 6e64da3c | Guan Xuetao | env->CF = a >= b; |
130 | 6e64da3c | Guan Xuetao | env->VF = (a ^ b) & (a ^ result); |
131 | 6e64da3c | Guan Xuetao | return result;
|
132 | 6e64da3c | Guan Xuetao | } |
133 | 6e64da3c | Guan Xuetao | |
134 | 04a130ea | Blue Swirl | uint32_t HELPER(sbc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b) |
135 | 6e64da3c | Guan Xuetao | { |
136 | 6e64da3c | Guan Xuetao | uint32_t result; |
137 | 6e64da3c | Guan Xuetao | if (!env->CF) {
|
138 | 6e64da3c | Guan Xuetao | result = a - b - 1;
|
139 | 6e64da3c | Guan Xuetao | env->CF = a > b; |
140 | 6e64da3c | Guan Xuetao | } else {
|
141 | 6e64da3c | Guan Xuetao | result = a - b; |
142 | 6e64da3c | Guan Xuetao | env->CF = a >= b; |
143 | 6e64da3c | Guan Xuetao | } |
144 | 6e64da3c | Guan Xuetao | env->VF = (a ^ b) & (a ^ result); |
145 | 6e64da3c | Guan Xuetao | env->NF = env->ZF = result; |
146 | 6e64da3c | Guan Xuetao | return result;
|
147 | 6e64da3c | Guan Xuetao | } |
148 | 6e64da3c | Guan Xuetao | |
149 | 6e64da3c | Guan Xuetao | /* Similarly for variable shift instructions. */
|
150 | 6e64da3c | Guan Xuetao | |
151 | 6e64da3c | Guan Xuetao | uint32_t HELPER(shl)(uint32_t x, uint32_t i) |
152 | 6e64da3c | Guan Xuetao | { |
153 | 6e64da3c | Guan Xuetao | int shift = i & 0xff; |
154 | 6e64da3c | Guan Xuetao | if (shift >= 32) { |
155 | 6e64da3c | Guan Xuetao | return 0; |
156 | 6e64da3c | Guan Xuetao | } |
157 | 6e64da3c | Guan Xuetao | return x << shift;
|
158 | 6e64da3c | Guan Xuetao | } |
159 | 6e64da3c | Guan Xuetao | |
160 | 6e64da3c | Guan Xuetao | uint32_t HELPER(shr)(uint32_t x, uint32_t i) |
161 | 6e64da3c | Guan Xuetao | { |
162 | 6e64da3c | Guan Xuetao | int shift = i & 0xff; |
163 | 6e64da3c | Guan Xuetao | if (shift >= 32) { |
164 | 6e64da3c | Guan Xuetao | return 0; |
165 | 6e64da3c | Guan Xuetao | } |
166 | 6e64da3c | Guan Xuetao | return (uint32_t)x >> shift;
|
167 | 6e64da3c | Guan Xuetao | } |
168 | 6e64da3c | Guan Xuetao | |
169 | 6e64da3c | Guan Xuetao | uint32_t HELPER(sar)(uint32_t x, uint32_t i) |
170 | 6e64da3c | Guan Xuetao | { |
171 | 6e64da3c | Guan Xuetao | int shift = i & 0xff; |
172 | 6e64da3c | Guan Xuetao | if (shift >= 32) { |
173 | 6e64da3c | Guan Xuetao | shift = 31;
|
174 | 6e64da3c | Guan Xuetao | } |
175 | 6e64da3c | Guan Xuetao | return (int32_t)x >> shift;
|
176 | 6e64da3c | Guan Xuetao | } |
177 | 6e64da3c | Guan Xuetao | |
178 | 04a130ea | Blue Swirl | uint32_t HELPER(shl_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i) |
179 | 6e64da3c | Guan Xuetao | { |
180 | 6e64da3c | Guan Xuetao | int shift = i & 0xff; |
181 | 6e64da3c | Guan Xuetao | if (shift >= 32) { |
182 | 6e64da3c | Guan Xuetao | if (shift == 32) { |
183 | 6e64da3c | Guan Xuetao | env->CF = x & 1;
|
184 | 6e64da3c | Guan Xuetao | } else {
|
185 | 6e64da3c | Guan Xuetao | env->CF = 0;
|
186 | 6e64da3c | Guan Xuetao | } |
187 | 6e64da3c | Guan Xuetao | return 0; |
188 | 6e64da3c | Guan Xuetao | } else if (shift != 0) { |
189 | 6e64da3c | Guan Xuetao | env->CF = (x >> (32 - shift)) & 1; |
190 | 6e64da3c | Guan Xuetao | return x << shift;
|
191 | 6e64da3c | Guan Xuetao | } |
192 | 6e64da3c | Guan Xuetao | return x;
|
193 | 6e64da3c | Guan Xuetao | } |
194 | 6e64da3c | Guan Xuetao | |
195 | 04a130ea | Blue Swirl | uint32_t HELPER(shr_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i) |
196 | 6e64da3c | Guan Xuetao | { |
197 | 6e64da3c | Guan Xuetao | int shift = i & 0xff; |
198 | 6e64da3c | Guan Xuetao | if (shift >= 32) { |
199 | 6e64da3c | Guan Xuetao | if (shift == 32) { |
200 | 6e64da3c | Guan Xuetao | env->CF = (x >> 31) & 1; |
201 | 6e64da3c | Guan Xuetao | } else {
|
202 | 6e64da3c | Guan Xuetao | env->CF = 0;
|
203 | 6e64da3c | Guan Xuetao | } |
204 | 6e64da3c | Guan Xuetao | return 0; |
205 | 6e64da3c | Guan Xuetao | } else if (shift != 0) { |
206 | 6e64da3c | Guan Xuetao | env->CF = (x >> (shift - 1)) & 1; |
207 | 6e64da3c | Guan Xuetao | return x >> shift;
|
208 | 6e64da3c | Guan Xuetao | } |
209 | 6e64da3c | Guan Xuetao | return x;
|
210 | 6e64da3c | Guan Xuetao | } |
211 | 6e64da3c | Guan Xuetao | |
212 | 04a130ea | Blue Swirl | uint32_t HELPER(sar_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i) |
213 | 6e64da3c | Guan Xuetao | { |
214 | 6e64da3c | Guan Xuetao | int shift = i & 0xff; |
215 | 6e64da3c | Guan Xuetao | if (shift >= 32) { |
216 | 6e64da3c | Guan Xuetao | env->CF = (x >> 31) & 1; |
217 | 6e64da3c | Guan Xuetao | return (int32_t)x >> 31; |
218 | 6e64da3c | Guan Xuetao | } else if (shift != 0) { |
219 | 6e64da3c | Guan Xuetao | env->CF = (x >> (shift - 1)) & 1; |
220 | 6e64da3c | Guan Xuetao | return (int32_t)x >> shift;
|
221 | 6e64da3c | Guan Xuetao | } |
222 | 6e64da3c | Guan Xuetao | return x;
|
223 | 6e64da3c | Guan Xuetao | } |
224 | 6e64da3c | Guan Xuetao | |
225 | 04a130ea | Blue Swirl | uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i) |
226 | 6e64da3c | Guan Xuetao | { |
227 | 6e64da3c | Guan Xuetao | int shift1, shift;
|
228 | 6e64da3c | Guan Xuetao | shift1 = i & 0xff;
|
229 | 6e64da3c | Guan Xuetao | shift = shift1 & 0x1f;
|
230 | 6e64da3c | Guan Xuetao | if (shift == 0) { |
231 | 6e64da3c | Guan Xuetao | if (shift1 != 0) { |
232 | 6e64da3c | Guan Xuetao | env->CF = (x >> 31) & 1; |
233 | 6e64da3c | Guan Xuetao | } |
234 | 6e64da3c | Guan Xuetao | return x;
|
235 | 6e64da3c | Guan Xuetao | } else {
|
236 | 6e64da3c | Guan Xuetao | env->CF = (x >> (shift - 1)) & 1; |
237 | 6e64da3c | Guan Xuetao | return ((uint32_t)x >> shift) | (x << (32 - shift)); |
238 | 6e64da3c | Guan Xuetao | } |
239 | 6e64da3c | Guan Xuetao | } |
240 | 4f23a1e6 | Guan Xuetao | |
241 | 4f23a1e6 | Guan Xuetao | #ifndef CONFIG_USER_ONLY
|
242 | b1669e5e | Richard Henderson | #include "exec/softmmu_exec.h" |
243 | b1669e5e | Richard Henderson | |
244 | 4f23a1e6 | Guan Xuetao | #define MMUSUFFIX _mmu
|
245 | 4f23a1e6 | Guan Xuetao | |
246 | 4f23a1e6 | Guan Xuetao | #define SHIFT 0 |
247 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
248 | 4f23a1e6 | Guan Xuetao | |
249 | 4f23a1e6 | Guan Xuetao | #define SHIFT 1 |
250 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
251 | 4f23a1e6 | Guan Xuetao | |
252 | 4f23a1e6 | Guan Xuetao | #define SHIFT 2 |
253 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
254 | 4f23a1e6 | Guan Xuetao | |
255 | 4f23a1e6 | Guan Xuetao | #define SHIFT 3 |
256 | 022c62cb | Paolo Bonzini | #include "exec/softmmu_template.h" |
257 | 4f23a1e6 | Guan Xuetao | |
258 | 04a130ea | Blue Swirl | void tlb_fill(CPUUniCore32State *env, target_ulong addr, int is_write, |
259 | 04a130ea | Blue Swirl | int mmu_idx, uintptr_t retaddr)
|
260 | 4f23a1e6 | Guan Xuetao | { |
261 | f3ccc323 | Guan Xuetao | int ret;
|
262 | f3ccc323 | Guan Xuetao | |
263 | f3ccc323 | Guan Xuetao | ret = uc32_cpu_handle_mmu_fault(env, addr, is_write, mmu_idx); |
264 | f3ccc323 | Guan Xuetao | if (unlikely(ret)) {
|
265 | f3ccc323 | Guan Xuetao | if (retaddr) {
|
266 | f3ccc323 | Guan Xuetao | /* now we have a real cpu fault */
|
267 | a8a826a3 | Blue Swirl | cpu_restore_state(env, retaddr); |
268 | f3ccc323 | Guan Xuetao | } |
269 | f3ccc323 | Guan Xuetao | cpu_loop_exit(env); |
270 | f3ccc323 | Guan Xuetao | } |
271 | 4f23a1e6 | Guan Xuetao | } |
272 | 4f23a1e6 | Guan Xuetao | #endif |