]> Git Repo - qemu.git/blob - target-tricore/op_helper.c
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
[qemu.git] / target-tricore / op_helper.c
1 /*
2  *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  */
17 #include <stdlib.h>
18 #include "cpu.h"
19 #include "qemu/host-utils.h"
20 #include "exec/helper-proto.h"
21 #include "exec/cpu_ldst.h"
22
23 /* Addressing mode helper */
24
25 static uint16_t reverse16(uint16_t val)
26 {
27     uint8_t high = (uint8_t)(val >> 8);
28     uint8_t low  = (uint8_t)(val & 0xff);
29
30     uint16_t rh, rl;
31
32     rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
33     rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
34
35     return (rh << 8) | rl;
36 }
37
38 uint32_t helper_br_update(uint32_t reg)
39 {
40     uint32_t index = reg & 0xffff;
41     uint32_t incr  = reg >> 16;
42     uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
43     return reg - index + new_index;
44 }
45
46 uint32_t helper_circ_update(uint32_t reg, uint32_t off)
47 {
48     uint32_t index = reg & 0xffff;
49     uint32_t length = reg >> 16;
50     int32_t new_index = index + off;
51     if (new_index < 0) {
52         new_index += length;
53     } else {
54         new_index %= length;
55     }
56     return reg - index + new_index;
57 }
58
59 #define SSOV(env, ret, arg, len) do {               \
60     int64_t max_pos = INT##len ##_MAX;              \
61     int64_t max_neg = INT##len ##_MIN;              \
62     if (arg > max_pos) {                            \
63         env->PSW_USB_V = (1 << 31);                 \
64         env->PSW_USB_SV = (1 << 31);                \
65         ret = (target_ulong)max_pos;                \
66     } else {                                        \
67         if (arg < max_neg) {                        \
68             env->PSW_USB_V = (1 << 31);             \
69             env->PSW_USB_SV = (1 << 31);            \
70             ret = (target_ulong)max_neg;            \
71         } else {                                    \
72             env->PSW_USB_V = 0;                     \
73             ret = (target_ulong)arg;                \
74         }                                           \
75     }                                               \
76     env->PSW_USB_AV = arg ^ arg * 2u;               \
77     env->PSW_USB_SAV |= env->PSW_USB_AV;            \
78 } while (0)
79
80 #define SUOV(env, ret, arg, len) do {               \
81     int64_t max_pos = UINT##len ##_MAX;             \
82     if (arg > max_pos) {                            \
83         env->PSW_USB_V = (1 << 31);                 \
84         env->PSW_USB_SV = (1 << 31);                \
85         ret = (target_ulong)max_pos;                \
86     } else {                                        \
87         if (arg < 0) {                              \
88             env->PSW_USB_V = (1 << 31);             \
89             env->PSW_USB_SV = (1 << 31);            \
90             ret = 0;                                \
91         } else {                                    \
92             env->PSW_USB_V = 0;                     \
93             ret = (target_ulong)arg;                \
94         }                                           \
95      }                                              \
96     env->PSW_USB_AV = arg ^ arg * 2u;               \
97     env->PSW_USB_SAV |= env->PSW_USB_AV;            \
98 } while (0)
99
100
101 target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
102                              target_ulong r2)
103 {
104     target_ulong ret;
105     int64_t t1 = sextract64(r1, 0, 32);
106     int64_t t2 = sextract64(r2, 0, 32);
107     int64_t result = t1 + t2;
108     SSOV(env, ret, result, 32);
109     return ret;
110 }
111
112 target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
113                              target_ulong r2)
114 {
115     target_ulong ret;
116     int64_t t1 = extract64(r1, 0, 32);
117     int64_t t2 = extract64(r2, 0, 32);
118     int64_t result = t1 + t2;
119     SUOV(env, ret, result, 32);
120     return ret;
121 }
122
123 target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
124                              target_ulong r2)
125 {
126     target_ulong ret;
127     int64_t t1 = sextract64(r1, 0, 32);
128     int64_t t2 = sextract64(r2, 0, 32);
129     int64_t result = t1 - t2;
130     SSOV(env, ret, result, 32);
131     return ret;
132 }
133
134 target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
135                              target_ulong r2)
136 {
137     target_ulong ret;
138     int64_t t1 = extract64(r1, 0, 32);
139     int64_t t2 = extract64(r2, 0, 32);
140     int64_t result = t1 - t2;
141     SUOV(env, ret, result, 32);
142     return ret;
143 }
144
145 target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
146                              target_ulong r2)
147 {
148     target_ulong ret;
149     int64_t t1 = sextract64(r1, 0, 32);
150     int64_t t2 = sextract64(r2, 0, 32);
151     int64_t result = t1 * t2;
152     SSOV(env, ret, result, 32);
153     return ret;
154 }
155
156 target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
157                              target_ulong r2)
158 {
159     target_ulong ret;
160     int64_t t1 = extract64(r1, 0, 32);
161     int64_t t2 = extract64(r2, 0, 32);
162     int64_t result = t1 * t2;
163     SUOV(env, ret, result, 32);
164     return ret;
165 }
166
167 target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
168                              target_ulong r2)
169 {
170     target_ulong ret;
171     int64_t t1 = sextract64(r1, 0, 32);
172     int32_t t2 = sextract64(r2, 0, 6);
173     int64_t result;
174     if (t2 == 0) {
175         result = t1;
176     } else if (t2 > 0) {
177         result = t1 << t2;
178     } else {
179         result = t1 >> -t2;
180     }
181     SSOV(env, ret, result, 32);
182     return ret;
183 }
184
185 target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
186                                 target_ulong r2)
187 {
188     target_ulong ret;
189     int64_t t1 = sextract64(r1, 0, 32);
190     int64_t t2 = sextract64(r2, 0, 32);
191     int64_t result;
192
193     if (t1 > t2) {
194         result = t1 - t2;
195     } else {
196         result = t2 - t1;
197     }
198     SSOV(env, ret, result, 32);
199     return ret;
200 }
201
202 target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
203                                 target_ulong r2, target_ulong r3)
204 {
205     target_ulong ret;
206     int64_t t1 = sextract64(r1, 0, 32);
207     int64_t t2 = sextract64(r2, 0, 32);
208     int64_t t3 = sextract64(r3, 0, 32);
209     int64_t result;
210
211     result = t2 + (t1 * t3);
212     SSOV(env, ret, result, 32);
213     return ret;
214 }
215
216 target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
217                                 target_ulong r2, target_ulong r3)
218 {
219     target_ulong ret;
220     uint64_t t1 = extract64(r1, 0, 32);
221     uint64_t t2 = extract64(r2, 0, 32);
222     uint64_t t3 = extract64(r3, 0, 32);
223     int64_t result;
224
225     result = t2 + (t1 * t3);
226     SUOV(env, ret, result, 32);
227     return ret;
228 }
229
230 uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
231                             uint64_t r2, target_ulong r3)
232 {
233     uint64_t ret, ovf;
234     int64_t t1 = sextract64(r1, 0, 32);
235     int64_t t3 = sextract64(r3, 0, 32);
236     int64_t mul;
237
238     mul = t1 * t3;
239     ret = mul + r2;
240     ovf = (ret ^ mul) & ~(mul ^ r2);
241
242     if ((int64_t)ovf < 0) {
243         env->PSW_USB_V = (1 << 31);
244         env->PSW_USB_SV = (1 << 31);
245         /* ext_ret > MAX_INT */
246         if (mul >= 0) {
247             ret = INT64_MAX;
248         /* ext_ret < MIN_INT */
249         } else {
250             ret = INT64_MIN;
251         }
252     } else {
253         env->PSW_USB_V = 0;
254     }
255     t1 = ret >> 32;
256     env->PSW_USB_AV = t1 ^ t1 * 2u;
257     env->PSW_USB_SAV |= env->PSW_USB_AV;
258
259     return ret;
260 }
261
262 uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
263                             uint64_t r2, target_ulong r3)
264 {
265     uint64_t ret, mul;
266     uint64_t t1 = extract64(r1, 0, 32);
267     uint64_t t3 = extract64(r3, 0, 32);
268
269     mul = t1 * t3;
270     ret = mul + r2;
271
272     if (ret < r2) {
273         env->PSW_USB_V = (1 << 31);
274         env->PSW_USB_SV = (1 << 31);
275         /* saturate */
276         ret = UINT64_MAX;
277     } else {
278         env->PSW_USB_V = 0;
279     }
280     t1 = ret >> 32;
281     env->PSW_USB_AV = t1 ^ t1 * 2u;
282     env->PSW_USB_SAV |= env->PSW_USB_AV;
283     return ret;
284 }
285
286 target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
287                                 target_ulong r2, target_ulong r3)
288 {
289     target_ulong ret;
290     int64_t t1 = sextract64(r1, 0, 32);
291     int64_t t2 = sextract64(r2, 0, 32);
292     int64_t t3 = sextract64(r3, 0, 32);
293     int64_t result;
294
295     result = t2 - (t1 * t3);
296     SSOV(env, ret, result, 32);
297     return ret;
298 }
299
300 target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
301                                 target_ulong r2, target_ulong r3)
302 {
303     target_ulong ret;
304     int64_t t1 = extract64(r1, 0, 32);
305     int64_t t2 = extract64(r2, 0, 32);
306     int64_t t3 = extract64(r3, 0, 32);
307     int64_t result;
308
309     result = t2 - (t1 * t3);
310     SUOV(env, ret, result, 32);
311     return ret;
312 }
313
314 uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
315                             uint64_t r2, target_ulong r3)
316 {
317     uint64_t ret, ovf;
318     int64_t t1 = sextract64(r1, 0, 32);
319     int64_t t3 = sextract64(r3, 0, 32);
320     int64_t mul;
321
322     mul = t1 * t3;
323     ret = r2 - mul;
324     ovf = (ret ^ r2) & (mul ^ r2);
325
326     if ((int64_t)ovf < 0) {
327         env->PSW_USB_V = (1 << 31);
328         env->PSW_USB_SV = (1 << 31);
329         /* ext_ret > MAX_INT */
330         if (mul < 0) {
331             ret = INT64_MAX;
332         /* ext_ret < MIN_INT */
333         } else {
334             ret = INT64_MIN;
335         }
336     } else {
337         env->PSW_USB_V = 0;
338     }
339     t1 = ret >> 32;
340     env->PSW_USB_AV = t1 ^ t1 * 2u;
341     env->PSW_USB_SAV |= env->PSW_USB_AV;
342     return ret;
343 }
344
345 uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
346                             uint64_t r2, target_ulong r3)
347 {
348     uint64_t ret, mul;
349     uint64_t t1 = extract64(r1, 0, 32);
350     uint64_t t3 = extract64(r3, 0, 32);
351
352     mul = t1 * t3;
353     ret = r2 - mul;
354
355     if (ret > r2) {
356         env->PSW_USB_V = (1 << 31);
357         env->PSW_USB_SV = (1 << 31);
358         /* saturate */
359         ret = 0;
360     } else {
361         env->PSW_USB_V = 0;
362     }
363     t1 = ret >> 32;
364     env->PSW_USB_AV = t1 ^ t1 * 2u;
365     env->PSW_USB_SAV |= env->PSW_USB_AV;
366     return ret;
367 }
368
369 /* context save area (CSA) related helpers */
370
371 static int cdc_increment(target_ulong *psw)
372 {
373     if ((*psw & MASK_PSW_CDC) == 0x7f) {
374         return 0;
375     }
376
377     (*psw)++;
378     /* check for overflow */
379     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
380     int mask = (1u << (7 - lo)) - 1;
381     int count = *psw & mask;
382     if (count == 0) {
383         (*psw)--;
384         return 1;
385     }
386     return 0;
387 }
388
389 static int cdc_decrement(target_ulong *psw)
390 {
391     if ((*psw & MASK_PSW_CDC) == 0x7f) {
392         return 0;
393     }
394     /* check for underflow */
395     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
396     int mask = (1u << (7 - lo)) - 1;
397     int count = *psw & mask;
398     if (count == 0) {
399         return 1;
400     }
401     (*psw)--;
402     return 0;
403 }
404
405 static bool cdc_zero(target_ulong *psw)
406 {
407     int cdc = *psw & MASK_PSW_CDC;
408     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
409        7'b1111111, otherwise returns FALSE. */
410     if (cdc == 0x7f) {
411         return true;
412     }
413     /* find CDC.COUNT */
414     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
415     int mask = (1u << (7 - lo)) - 1;
416     int count = *psw & mask;
417     return count == 0;
418 }
419
420 static void save_context_upper(CPUTriCoreState *env, int ea)
421 {
422     cpu_stl_data(env, ea, env->PCXI);
423     cpu_stl_data(env, ea+4, env->PSW);
424     cpu_stl_data(env, ea+8, env->gpr_a[10]);
425     cpu_stl_data(env, ea+12, env->gpr_a[11]);
426     cpu_stl_data(env, ea+16, env->gpr_d[8]);
427     cpu_stl_data(env, ea+20, env->gpr_d[9]);
428     cpu_stl_data(env, ea+24, env->gpr_d[10]);
429     cpu_stl_data(env, ea+28, env->gpr_d[11]);
430     cpu_stl_data(env, ea+32, env->gpr_a[12]);
431     cpu_stl_data(env, ea+36, env->gpr_a[13]);
432     cpu_stl_data(env, ea+40, env->gpr_a[14]);
433     cpu_stl_data(env, ea+44, env->gpr_a[15]);
434     cpu_stl_data(env, ea+48, env->gpr_d[12]);
435     cpu_stl_data(env, ea+52, env->gpr_d[13]);
436     cpu_stl_data(env, ea+56, env->gpr_d[14]);
437     cpu_stl_data(env, ea+60, env->gpr_d[15]);
438 }
439
440 static void save_context_lower(CPUTriCoreState *env, int ea)
441 {
442     cpu_stl_data(env, ea, env->PCXI);
443     cpu_stl_data(env, ea+4, env->gpr_a[11]);
444     cpu_stl_data(env, ea+8, env->gpr_a[2]);
445     cpu_stl_data(env, ea+12, env->gpr_a[3]);
446     cpu_stl_data(env, ea+16, env->gpr_d[0]);
447     cpu_stl_data(env, ea+20, env->gpr_d[1]);
448     cpu_stl_data(env, ea+24, env->gpr_d[2]);
449     cpu_stl_data(env, ea+28, env->gpr_d[3]);
450     cpu_stl_data(env, ea+32, env->gpr_a[4]);
451     cpu_stl_data(env, ea+36, env->gpr_a[5]);
452     cpu_stl_data(env, ea+40, env->gpr_a[6]);
453     cpu_stl_data(env, ea+44, env->gpr_a[7]);
454     cpu_stl_data(env, ea+48, env->gpr_d[4]);
455     cpu_stl_data(env, ea+52, env->gpr_d[5]);
456     cpu_stl_data(env, ea+56, env->gpr_d[6]);
457     cpu_stl_data(env, ea+60, env->gpr_d[7]);
458 }
459
460 static void restore_context_upper(CPUTriCoreState *env, int ea,
461                                   target_ulong *new_PCXI, target_ulong *new_PSW)
462 {
463     *new_PCXI = cpu_ldl_data(env, ea);
464     *new_PSW = cpu_ldl_data(env, ea+4);
465     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
466     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
467     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
468     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
469     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
470     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
471     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
472     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
473     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
474     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
475     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
476     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
477     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
478     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
479 }
480
481 static void restore_context_lower(CPUTriCoreState *env, int ea,
482                                   target_ulong *ra, target_ulong *pcxi)
483 {
484     *pcxi = cpu_ldl_data(env, ea);
485     *ra = cpu_ldl_data(env, ea+4);
486     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
487     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
488     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
489     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
490     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
491     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
492     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
493     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
494     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
495     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
496     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
497     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
498     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
499     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
500 }
501
502 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
503 {
504     target_ulong tmp_FCX;
505     target_ulong ea;
506     target_ulong new_FCX;
507     target_ulong psw;
508
509     psw = psw_read(env);
510     /* if (FCX == 0) trap(FCU); */
511     if (env->FCX == 0) {
512         /* FCU trap */
513     }
514     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
515     if (psw & MASK_PSW_CDE) {
516         if (cdc_increment(&psw)) {
517             /* CDO trap */
518         }
519     }
520     /* PSW.CDE = 1;*/
521     psw |= MASK_PSW_CDE;
522     /* tmp_FCX = FCX; */
523     tmp_FCX = env->FCX;
524     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
525     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
526          ((env->FCX & MASK_FCX_FCXO) << 6);
527     /* new_FCX = M(EA, word); */
528     new_FCX = cpu_ldl_data(env, ea);
529     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
530                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
531                            D[15]}; */
532     save_context_upper(env, ea);
533
534     /* PCXI.PCPN = ICR.CCPN; */
535     env->PCXI = (env->PCXI & 0xffffff) +
536                 ((env->ICR & MASK_ICR_CCPN) << 24);
537     /* PCXI.PIE = ICR.IE; */
538     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
539                 ((env->ICR & MASK_ICR_IE) << 15));
540     /* PCXI.UL = 1; */
541     env->PCXI |= MASK_PCXI_UL;
542
543     /* PCXI[19: 0] = FCX[19: 0]; */
544     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
545     /* FCX[19: 0] = new_FCX[19: 0]; */
546     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
547     /* A[11] = next_pc[31: 0]; */
548     env->gpr_a[11] = next_pc;
549
550     /* if (tmp_FCX == LCX) trap(FCD);*/
551     if (tmp_FCX == env->LCX) {
552         /* FCD trap */
553     }
554     psw_write(env, psw);
555 }
556
557 void helper_ret(CPUTriCoreState *env)
558 {
559     target_ulong ea;
560     target_ulong new_PCXI;
561     target_ulong new_PSW, psw;
562
563     psw = psw_read(env);
564      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
565     if (env->PSW & MASK_PSW_CDE) {
566         if (cdc_decrement(&(env->PSW))) {
567             /* CDU trap */
568         }
569     }
570     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
571     if ((env->PCXI & 0xfffff) == 0) {
572         /* CSU trap */
573     }
574     /* if (PCXI.UL == 0) then trap(CTYP); */
575     if ((env->PCXI & MASK_PCXI_UL) == 0) {
576         /* CTYP trap */
577     }
578     /* PC = {A11 [31: 1], 1’b0}; */
579     env->PC = env->gpr_a[11] & 0xfffffffe;
580
581     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
582     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
583          ((env->PCXI & MASK_PCXI_PCXO) << 6);
584     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
585         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
586     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
587     /* M(EA, word) = FCX; */
588     cpu_stl_data(env, ea, env->FCX);
589     /* FCX[19: 0] = PCXI[19: 0]; */
590     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
591     /* PCXI = new_PCXI; */
592     env->PCXI = new_PCXI;
593
594     if (tricore_feature(env, TRICORE_FEATURE_13)) {
595         /* PSW = new_PSW */
596         psw_write(env, new_PSW);
597     } else {
598         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
599         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
600     }
601 }
602
603 void helper_bisr(CPUTriCoreState *env, uint32_t const9)
604 {
605     target_ulong tmp_FCX;
606     target_ulong ea;
607     target_ulong new_FCX;
608
609     if (env->FCX == 0) {
610         /* FCU trap */
611     }
612
613     tmp_FCX = env->FCX;
614     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
615
616     /* new_FCX = M(EA, word); */
617     new_FCX = cpu_ldl_data(env, ea);
618     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
619                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
620     save_context_lower(env, ea);
621
622
623     /* PCXI.PCPN = ICR.CCPN */
624     env->PCXI = (env->PCXI & 0xffffff) +
625                  ((env->ICR & MASK_ICR_CCPN) << 24);
626     /* PCXI.PIE  = ICR.IE */
627     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
628                  ((env->ICR & MASK_ICR_IE) << 15));
629     /* PCXI.UL = 0 */
630     env->PCXI &= ~(MASK_PCXI_UL);
631     /* PCXI[19: 0] = FCX[19: 0] */
632     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
633     /* FXC[19: 0] = new_FCX[19: 0] */
634     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
635     /* ICR.IE = 1 */
636     env->ICR |= MASK_ICR_IE;
637
638     env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
639
640     if (tmp_FCX == env->LCX) {
641         /* FCD trap */
642     }
643 }
644
645 void helper_rfe(CPUTriCoreState *env)
646 {
647     target_ulong ea;
648     target_ulong new_PCXI;
649     target_ulong new_PSW;
650     /* if (PCXI[19: 0] == 0) then trap(CSU); */
651     if ((env->PCXI & 0xfffff) == 0) {
652         /* raise csu trap */
653     }
654     /* if (PCXI.UL == 0) then trap(CTYP); */
655     if ((env->PCXI & MASK_PCXI_UL) == 0) {
656         /* raise CTYP trap */
657     }
658     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
659     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
660         /* raise MNG trap */
661     }
662     /* ICR.IE = PCXI.PIE; */
663     env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
664     /* ICR.CCPN = PCXI.PCPN; */
665     env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
666                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
667     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
668     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
669          ((env->PCXI & MASK_PCXI_PCXO) << 6);
670     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
671       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
672     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
673     /* M(EA, word) = FCX;*/
674     cpu_stl_data(env, ea, env->FCX);
675     /* FCX[19: 0] = PCXI[19: 0]; */
676     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
677     /* PCXI = new_PCXI; */
678     env->PCXI = new_PCXI;
679     /* write psw */
680     psw_write(env, new_PSW);
681 }
682
683 void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
684 {
685     uint32_t dummy;
686     /* insn doesn't load PCXI and RA */
687     restore_context_lower(env, ea, &dummy, &dummy);
688 }
689
690 void helper_lducx(CPUTriCoreState *env, uint32_t ea)
691 {
692     uint32_t dummy;
693     /* insn doesn't load PCXI and PSW */
694     restore_context_upper(env, ea, &dummy, &dummy);
695 }
696
697 void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
698 {
699     save_context_lower(env, ea);
700 }
701
702 void helper_stucx(CPUTriCoreState *env, uint32_t ea)
703 {
704     save_context_upper(env, ea);
705 }
706
707 void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
708 {
709     psw_write(env, arg);
710 }
711
712 uint32_t helper_psw_read(CPUTriCoreState *env)
713 {
714     return psw_read(env);
715 }
716
717
718 static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
719                                                         uint32_t exception,
720                                                         int error_code,
721                                                         uintptr_t pc)
722 {
723     CPUState *cs = CPU(tricore_env_get_cpu(env));
724     cs->exception_index = exception;
725     env->error_code = error_code;
726
727     if (pc) {
728         /* now we have a real cpu fault */
729         cpu_restore_state(cs, pc);
730     }
731
732     cpu_loop_exit(cs);
733 }
734
735 void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
736               uintptr_t retaddr)
737 {
738     int ret;
739     ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
740     if (ret) {
741         TriCoreCPU *cpu = TRICORE_CPU(cs);
742         CPUTriCoreState *env = &cpu->env;
743         do_raise_exception_err(env, cs->exception_index,
744                                env->error_code, retaddr);
745     }
746 }
This page took 0.06738 seconds and 4 git commands to generate.