xref: /qemu/target/tricore/op_helper.c (revision 811ea608e9721dc4f6933da440f235e7d3a39c0f)
148e06fe0SBastian Koppelmann /*
248e06fe0SBastian Koppelmann  *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
348e06fe0SBastian Koppelmann  *
448e06fe0SBastian Koppelmann  * This library is free software; you can redistribute it and/or
548e06fe0SBastian Koppelmann  * modify it under the terms of the GNU Lesser General Public
648e06fe0SBastian Koppelmann  * License as published by the Free Software Foundation; either
748e06fe0SBastian Koppelmann  * version 2 of the License, or (at your option) any later version.
848e06fe0SBastian Koppelmann  *
948e06fe0SBastian Koppelmann  * This library is distributed in the hope that it will be useful,
1048e06fe0SBastian Koppelmann  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1148e06fe0SBastian Koppelmann  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1248e06fe0SBastian Koppelmann  * Lesser General Public License for more details.
1348e06fe0SBastian Koppelmann  *
1448e06fe0SBastian Koppelmann  * You should have received a copy of the GNU Lesser General Public
1548e06fe0SBastian Koppelmann  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1648e06fe0SBastian Koppelmann  */
1748e06fe0SBastian Koppelmann #include <stdlib.h>
1848e06fe0SBastian Koppelmann #include "cpu.h"
1948e06fe0SBastian Koppelmann #include "qemu/host-utils.h"
2048e06fe0SBastian Koppelmann #include "exec/helper-proto.h"
2148e06fe0SBastian Koppelmann #include "exec/cpu_ldst.h"
2248e06fe0SBastian Koppelmann 
233a16ecb0SBastian Koppelmann /* Addressing mode helper */
243a16ecb0SBastian Koppelmann 
253a16ecb0SBastian Koppelmann static uint16_t reverse16(uint16_t val)
263a16ecb0SBastian Koppelmann {
273a16ecb0SBastian Koppelmann     uint8_t high = (uint8_t)(val >> 8);
283a16ecb0SBastian Koppelmann     uint8_t low  = (uint8_t)(val & 0xff);
293a16ecb0SBastian Koppelmann 
303a16ecb0SBastian Koppelmann     uint16_t rh, rl;
313a16ecb0SBastian Koppelmann 
323a16ecb0SBastian Koppelmann     rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
333a16ecb0SBastian Koppelmann     rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
343a16ecb0SBastian Koppelmann 
353a16ecb0SBastian Koppelmann     return (rh << 8) | rl;
363a16ecb0SBastian Koppelmann }
373a16ecb0SBastian Koppelmann 
383a16ecb0SBastian Koppelmann uint32_t helper_br_update(uint32_t reg)
393a16ecb0SBastian Koppelmann {
403a16ecb0SBastian Koppelmann     uint32_t index = reg & 0xffff;
413a16ecb0SBastian Koppelmann     uint32_t incr  = reg >> 16;
423a16ecb0SBastian Koppelmann     uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
433a16ecb0SBastian Koppelmann     return reg - index + new_index;
443a16ecb0SBastian Koppelmann }
453a16ecb0SBastian Koppelmann 
463a16ecb0SBastian Koppelmann uint32_t helper_circ_update(uint32_t reg, uint32_t off)
473a16ecb0SBastian Koppelmann {
483a16ecb0SBastian Koppelmann     uint32_t index = reg & 0xffff;
493a16ecb0SBastian Koppelmann     uint32_t length = reg >> 16;
503a16ecb0SBastian Koppelmann     int32_t new_index = index + off;
513a16ecb0SBastian Koppelmann     if (new_index < 0) {
523a16ecb0SBastian Koppelmann         new_index += length;
533a16ecb0SBastian Koppelmann     } else {
543a16ecb0SBastian Koppelmann         new_index %= length;
553a16ecb0SBastian Koppelmann     }
563a16ecb0SBastian Koppelmann     return reg - index + new_index;
573a16ecb0SBastian Koppelmann }
583a16ecb0SBastian Koppelmann 
59e4e39176SBastian Koppelmann static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
60e4e39176SBastian Koppelmann {
61e4e39176SBastian Koppelmann     uint32_t ret;
62e4e39176SBastian Koppelmann     int64_t max_pos = INT32_MAX;
63e4e39176SBastian Koppelmann     int64_t max_neg = INT32_MIN;
64e4e39176SBastian Koppelmann     if (arg > max_pos) {
65e4e39176SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
66e4e39176SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
67e4e39176SBastian Koppelmann         ret = (target_ulong)max_pos;
68e4e39176SBastian Koppelmann     } else {
69e4e39176SBastian Koppelmann         if (arg < max_neg) {
70e4e39176SBastian Koppelmann             env->PSW_USB_V = (1 << 31);
71e4e39176SBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
72e4e39176SBastian Koppelmann             ret = (target_ulong)max_neg;
73e4e39176SBastian Koppelmann         } else {
74e4e39176SBastian Koppelmann             env->PSW_USB_V = 0;
75e4e39176SBastian Koppelmann             ret = (target_ulong)arg;
76e4e39176SBastian Koppelmann         }
77e4e39176SBastian Koppelmann     }
78e4e39176SBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
79e4e39176SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
80e4e39176SBastian Koppelmann     return ret;
81e4e39176SBastian Koppelmann }
822692802aSBastian Koppelmann 
83e4e39176SBastian Koppelmann static uint32_t suov32(CPUTriCoreState *env, int64_t arg)
84e4e39176SBastian Koppelmann {
85e4e39176SBastian Koppelmann     uint32_t ret;
86e4e39176SBastian Koppelmann     int64_t max_pos = UINT32_MAX;
87e4e39176SBastian Koppelmann     if (arg > max_pos) {
88e4e39176SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
89e4e39176SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
90e4e39176SBastian Koppelmann         ret = (target_ulong)max_pos;
91e4e39176SBastian Koppelmann     } else {
92e4e39176SBastian Koppelmann         if (arg < 0) {
93e4e39176SBastian Koppelmann             env->PSW_USB_V = (1 << 31);
94e4e39176SBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
95e4e39176SBastian Koppelmann             ret = 0;
96e4e39176SBastian Koppelmann         } else {
97e4e39176SBastian Koppelmann             env->PSW_USB_V = 0;
98e4e39176SBastian Koppelmann             ret = (target_ulong)arg;
99e4e39176SBastian Koppelmann         }
100e4e39176SBastian Koppelmann      }
101e4e39176SBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
102e4e39176SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
103e4e39176SBastian Koppelmann     return ret;
104e4e39176SBastian Koppelmann }
1050974257eSBastian Koppelmann 
106d5de7839SBastian Koppelmann static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
107d5de7839SBastian Koppelmann {
108d5de7839SBastian Koppelmann     int32_t max_pos = INT16_MAX;
109d5de7839SBastian Koppelmann     int32_t max_neg = INT16_MIN;
110d5de7839SBastian Koppelmann     int32_t av0, av1;
111d5de7839SBastian Koppelmann 
112d5de7839SBastian Koppelmann     env->PSW_USB_V = 0;
113d5de7839SBastian Koppelmann     av0 = hw0 ^ hw0 * 2u;
114d5de7839SBastian Koppelmann     if (hw0 > max_pos) {
115d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
116d5de7839SBastian Koppelmann         hw0 = max_pos;
117d5de7839SBastian Koppelmann     } else if (hw0 < max_neg) {
118d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
119d5de7839SBastian Koppelmann         hw0 = max_neg;
120d5de7839SBastian Koppelmann     }
121d5de7839SBastian Koppelmann 
122d5de7839SBastian Koppelmann     av1 = hw1 ^ hw1 * 2u;
123d5de7839SBastian Koppelmann     if (hw1 > max_pos) {
124d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
125d5de7839SBastian Koppelmann         hw1 = max_pos;
126d5de7839SBastian Koppelmann     } else if (hw1 < max_neg) {
127d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
128d5de7839SBastian Koppelmann         hw1 = max_neg;
129d5de7839SBastian Koppelmann     }
130d5de7839SBastian Koppelmann 
131d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
132d5de7839SBastian Koppelmann     env->PSW_USB_AV = (av0 | av1) << 16;
133d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
134d5de7839SBastian Koppelmann     return (hw0 & 0xffff) | (hw1 << 16);
135d5de7839SBastian Koppelmann }
136d5de7839SBastian Koppelmann 
137d5de7839SBastian Koppelmann static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
138d5de7839SBastian Koppelmann {
139d5de7839SBastian Koppelmann     int32_t max_pos = UINT16_MAX;
140d5de7839SBastian Koppelmann     int32_t av0, av1;
141d5de7839SBastian Koppelmann 
142d5de7839SBastian Koppelmann     env->PSW_USB_V = 0;
143d5de7839SBastian Koppelmann     av0 = hw0 ^ hw0 * 2u;
144d5de7839SBastian Koppelmann     if (hw0 > max_pos) {
145d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
146d5de7839SBastian Koppelmann         hw0 = max_pos;
147d5de7839SBastian Koppelmann     } else if (hw0 < 0) {
148d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
149d5de7839SBastian Koppelmann         hw0 = 0;
150d5de7839SBastian Koppelmann     }
151d5de7839SBastian Koppelmann 
152d5de7839SBastian Koppelmann     av1 = hw1 ^ hw1 * 2u;
153d5de7839SBastian Koppelmann     if (hw1 > max_pos) {
154d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
155d5de7839SBastian Koppelmann         hw1 = max_pos;
156d5de7839SBastian Koppelmann     } else if (hw1 < 0) {
157d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
158d5de7839SBastian Koppelmann         hw1 = 0;
159d5de7839SBastian Koppelmann     }
160d5de7839SBastian Koppelmann 
161d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
162d5de7839SBastian Koppelmann     env->PSW_USB_AV = (av0 | av1) << 16;
163d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
164d5de7839SBastian Koppelmann     return (hw0 & 0xffff) | (hw1 << 16);
165d5de7839SBastian Koppelmann }
1660974257eSBastian Koppelmann 
1672692802aSBastian Koppelmann target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
1682692802aSBastian Koppelmann                              target_ulong r2)
1692692802aSBastian Koppelmann {
1702692802aSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
1712692802aSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
1722692802aSBastian Koppelmann     int64_t result = t1 + t2;
173e4e39176SBastian Koppelmann     return ssov32(env, result);
1742692802aSBastian Koppelmann }
1752692802aSBastian Koppelmann 
176d5de7839SBastian Koppelmann target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
177d5de7839SBastian Koppelmann                                target_ulong r2)
178d5de7839SBastian Koppelmann {
179d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
180d5de7839SBastian Koppelmann 
181d5de7839SBastian Koppelmann     ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16);
182d5de7839SBastian Koppelmann     ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16);
183d5de7839SBastian Koppelmann     return ssov16(env, ret_hw0, ret_hw1);
184d5de7839SBastian Koppelmann }
185d5de7839SBastian Koppelmann 
1860974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
1870974257eSBastian Koppelmann                              target_ulong r2)
1880974257eSBastian Koppelmann {
1890974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
1900974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
1910974257eSBastian Koppelmann     int64_t result = t1 + t2;
192e4e39176SBastian Koppelmann     return suov32(env, result);
1930974257eSBastian Koppelmann }
1940974257eSBastian Koppelmann 
195d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
196d5de7839SBastian Koppelmann                                target_ulong r2)
197d5de7839SBastian Koppelmann {
198d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
199d5de7839SBastian Koppelmann 
200d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
201d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
202d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
203d5de7839SBastian Koppelmann }
204d5de7839SBastian Koppelmann 
2052692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
2062692802aSBastian Koppelmann                              target_ulong r2)
2072692802aSBastian Koppelmann {
2082692802aSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
2092692802aSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
2102692802aSBastian Koppelmann     int64_t result = t1 - t2;
211e4e39176SBastian Koppelmann     return ssov32(env, result);
2122692802aSBastian Koppelmann }
2132692802aSBastian Koppelmann 
214d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
215d5de7839SBastian Koppelmann                              target_ulong r2)
216d5de7839SBastian Koppelmann {
217d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
218d5de7839SBastian Koppelmann 
219d5de7839SBastian Koppelmann     ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
220d5de7839SBastian Koppelmann     ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
221d5de7839SBastian Koppelmann     return ssov16(env, ret_hw0, ret_hw1);
222d5de7839SBastian Koppelmann }
223d5de7839SBastian Koppelmann 
2240974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
2250974257eSBastian Koppelmann                              target_ulong r2)
2260974257eSBastian Koppelmann {
2270974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
2280974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
2290974257eSBastian Koppelmann     int64_t result = t1 - t2;
230e4e39176SBastian Koppelmann     return suov32(env, result);
2310974257eSBastian Koppelmann }
2320974257eSBastian Koppelmann 
233d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
234d5de7839SBastian Koppelmann                                target_ulong r2)
235d5de7839SBastian Koppelmann {
236d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
237d5de7839SBastian Koppelmann 
238d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
239d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
240d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
241d5de7839SBastian Koppelmann }
242d5de7839SBastian Koppelmann 
2430974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
2440974257eSBastian Koppelmann                              target_ulong r2)
2450974257eSBastian Koppelmann {
2460974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
2470974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
2480974257eSBastian Koppelmann     int64_t result = t1 * t2;
249e4e39176SBastian Koppelmann     return ssov32(env, result);
2500974257eSBastian Koppelmann }
2510974257eSBastian Koppelmann 
2520974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
2530974257eSBastian Koppelmann                              target_ulong r2)
2540974257eSBastian Koppelmann {
2550974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
2560974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
2570974257eSBastian Koppelmann     int64_t result = t1 * t2;
2585f30046fSBastian Koppelmann 
259e4e39176SBastian Koppelmann     return suov32(env, result);
2600974257eSBastian Koppelmann }
2610974257eSBastian Koppelmann 
2620974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
2630974257eSBastian Koppelmann                              target_ulong r2)
2640974257eSBastian Koppelmann {
2650974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
2660974257eSBastian Koppelmann     int32_t t2 = sextract64(r2, 0, 6);
2670974257eSBastian Koppelmann     int64_t result;
2680974257eSBastian Koppelmann     if (t2 == 0) {
2690974257eSBastian Koppelmann         result = t1;
2700974257eSBastian Koppelmann     } else if (t2 > 0) {
2710974257eSBastian Koppelmann         result = t1 << t2;
2720974257eSBastian Koppelmann     } else {
2730974257eSBastian Koppelmann         result = t1 >> -t2;
2740974257eSBastian Koppelmann     }
275e4e39176SBastian Koppelmann     return ssov32(env, result);
2760974257eSBastian Koppelmann }
2770974257eSBastian Koppelmann 
278d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
279d5de7839SBastian Koppelmann {
280d5de7839SBastian Koppelmann     target_ulong result;
281d5de7839SBastian Koppelmann     result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
282d5de7839SBastian Koppelmann     return ssov32(env, result);
283d5de7839SBastian Koppelmann }
284d5de7839SBastian Koppelmann 
285d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
286d5de7839SBastian Koppelmann {
287d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
288d5de7839SBastian Koppelmann 
289d5de7839SBastian Koppelmann     ret_h0 = sextract32(r1, 0, 16);
290d5de7839SBastian Koppelmann     ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
291d5de7839SBastian Koppelmann 
292d5de7839SBastian Koppelmann     ret_h1 = sextract32(r1, 16, 16);
293d5de7839SBastian Koppelmann     ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
294d5de7839SBastian Koppelmann 
295d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
296d5de7839SBastian Koppelmann }
297d5de7839SBastian Koppelmann 
2980974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
2990974257eSBastian Koppelmann                                 target_ulong r2)
3000974257eSBastian Koppelmann {
3010974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3020974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
3030974257eSBastian Koppelmann     int64_t result;
3040974257eSBastian Koppelmann 
3050974257eSBastian Koppelmann     if (t1 > t2) {
3060974257eSBastian Koppelmann         result = t1 - t2;
3070974257eSBastian Koppelmann     } else {
3080974257eSBastian Koppelmann         result = t2 - t1;
3090974257eSBastian Koppelmann     }
310e4e39176SBastian Koppelmann     return ssov32(env, result);
3110974257eSBastian Koppelmann }
312328f1f0fSBastian Koppelmann 
313d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
314d5de7839SBastian Koppelmann                               target_ulong r2)
315d5de7839SBastian Koppelmann {
316d5de7839SBastian Koppelmann     int32_t t1, t2;
317d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
318d5de7839SBastian Koppelmann 
319d5de7839SBastian Koppelmann     t1 = sextract32(r1, 0, 16);
320d5de7839SBastian Koppelmann     t2 = sextract32(r2, 0, 16);
321d5de7839SBastian Koppelmann     if (t1 > t2) {
322d5de7839SBastian Koppelmann         ret_h0 = t1 - t2;
323d5de7839SBastian Koppelmann     } else {
324d5de7839SBastian Koppelmann         ret_h0 = t2 - t1;
325d5de7839SBastian Koppelmann     }
326d5de7839SBastian Koppelmann 
327d5de7839SBastian Koppelmann     t1 = sextract32(r1, 16, 16);
328d5de7839SBastian Koppelmann     t2 = sextract32(r2, 16, 16);
329d5de7839SBastian Koppelmann     if (t1 > t2) {
330d5de7839SBastian Koppelmann         ret_h1 = t1 - t2;
331d5de7839SBastian Koppelmann     } else {
332d5de7839SBastian Koppelmann         ret_h1 = t2 - t1;
333d5de7839SBastian Koppelmann     }
334d5de7839SBastian Koppelmann 
335d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
336d5de7839SBastian Koppelmann }
337d5de7839SBastian Koppelmann 
338328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
339328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
340328f1f0fSBastian Koppelmann {
341328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
342328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
343328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
344328f1f0fSBastian Koppelmann     int64_t result;
345328f1f0fSBastian Koppelmann 
346328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
347e4e39176SBastian Koppelmann     return ssov32(env, result);
348328f1f0fSBastian Koppelmann }
349328f1f0fSBastian Koppelmann 
350328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
351328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
352328f1f0fSBastian Koppelmann {
353328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
354328f1f0fSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
355328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
356328f1f0fSBastian Koppelmann     int64_t result;
357328f1f0fSBastian Koppelmann 
358328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
359e4e39176SBastian Koppelmann     return suov32(env, result);
360328f1f0fSBastian Koppelmann }
361328f1f0fSBastian Koppelmann 
362328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
363328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
364328f1f0fSBastian Koppelmann {
365328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
366328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
367328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
368328f1f0fSBastian Koppelmann     int64_t mul;
369328f1f0fSBastian Koppelmann 
370328f1f0fSBastian Koppelmann     mul = t1 * t3;
371328f1f0fSBastian Koppelmann     ret = mul + r2;
372328f1f0fSBastian Koppelmann     ovf = (ret ^ mul) & ~(mul ^ r2);
373328f1f0fSBastian Koppelmann 
374811ea608SBastian Koppelmann     t1 = ret >> 32;
375811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
376811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
377811ea608SBastian Koppelmann 
378328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
379328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
380328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
381328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
382328f1f0fSBastian Koppelmann         if (mul >= 0) {
383328f1f0fSBastian Koppelmann             ret = INT64_MAX;
384328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
385328f1f0fSBastian Koppelmann         } else {
386328f1f0fSBastian Koppelmann             ret = INT64_MIN;
387328f1f0fSBastian Koppelmann         }
388328f1f0fSBastian Koppelmann     } else {
389328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
390328f1f0fSBastian Koppelmann     }
391328f1f0fSBastian Koppelmann 
392328f1f0fSBastian Koppelmann     return ret;
393328f1f0fSBastian Koppelmann }
394328f1f0fSBastian Koppelmann 
395328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
396328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
397328f1f0fSBastian Koppelmann {
398328f1f0fSBastian Koppelmann     uint64_t ret, mul;
399328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
400328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
401328f1f0fSBastian Koppelmann 
402328f1f0fSBastian Koppelmann     mul = t1 * t3;
403328f1f0fSBastian Koppelmann     ret = mul + r2;
404328f1f0fSBastian Koppelmann 
405811ea608SBastian Koppelmann     t1 = ret >> 32;
406811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
407811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
408811ea608SBastian Koppelmann 
409328f1f0fSBastian Koppelmann     if (ret < r2) {
410328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
411328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
412328f1f0fSBastian Koppelmann         /* saturate */
413328f1f0fSBastian Koppelmann         ret = UINT64_MAX;
414328f1f0fSBastian Koppelmann     } else {
415328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
416328f1f0fSBastian Koppelmann     }
417328f1f0fSBastian Koppelmann     return ret;
418328f1f0fSBastian Koppelmann }
419328f1f0fSBastian Koppelmann 
420328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
421328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
422328f1f0fSBastian Koppelmann {
423328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
424328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
425328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
426328f1f0fSBastian Koppelmann     int64_t result;
427328f1f0fSBastian Koppelmann 
428328f1f0fSBastian Koppelmann     result = t2 - (t1 * t3);
429e4e39176SBastian Koppelmann     return ssov32(env, result);
430328f1f0fSBastian Koppelmann }
431328f1f0fSBastian Koppelmann 
432328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
433328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
434328f1f0fSBastian Koppelmann {
435328f1f0fSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
436328f1f0fSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
437328f1f0fSBastian Koppelmann     int64_t t3 = extract64(r3, 0, 32);
438328f1f0fSBastian Koppelmann     int64_t result;
439328f1f0fSBastian Koppelmann 
440328f1f0fSBastian Koppelmann     result = t2 - (t1 * t3);
441e4e39176SBastian Koppelmann     return suov32(env, result);
442328f1f0fSBastian Koppelmann }
443328f1f0fSBastian Koppelmann 
444328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
445328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
446328f1f0fSBastian Koppelmann {
447328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
448328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
449328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
450328f1f0fSBastian Koppelmann     int64_t mul;
451328f1f0fSBastian Koppelmann 
452328f1f0fSBastian Koppelmann     mul = t1 * t3;
453328f1f0fSBastian Koppelmann     ret = r2 - mul;
454328f1f0fSBastian Koppelmann     ovf = (ret ^ r2) & (mul ^ r2);
455328f1f0fSBastian Koppelmann 
456811ea608SBastian Koppelmann     t1 = ret >> 32;
457811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
458811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
459811ea608SBastian Koppelmann 
460328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
461328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
462328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
463328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
464328f1f0fSBastian Koppelmann         if (mul < 0) {
465328f1f0fSBastian Koppelmann             ret = INT64_MAX;
466328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
467328f1f0fSBastian Koppelmann         } else {
468328f1f0fSBastian Koppelmann             ret = INT64_MIN;
469328f1f0fSBastian Koppelmann         }
470328f1f0fSBastian Koppelmann     } else {
471328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
472328f1f0fSBastian Koppelmann     }
473328f1f0fSBastian Koppelmann     return ret;
474328f1f0fSBastian Koppelmann }
475328f1f0fSBastian Koppelmann 
476328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
477328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
478328f1f0fSBastian Koppelmann {
479328f1f0fSBastian Koppelmann     uint64_t ret, mul;
480328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
481328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
482328f1f0fSBastian Koppelmann 
483328f1f0fSBastian Koppelmann     mul = t1 * t3;
484328f1f0fSBastian Koppelmann     ret = r2 - mul;
485328f1f0fSBastian Koppelmann 
486811ea608SBastian Koppelmann     t1 = ret >> 32;
487811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
488811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
489811ea608SBastian Koppelmann 
490328f1f0fSBastian Koppelmann     if (ret > r2) {
491328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
492328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
493328f1f0fSBastian Koppelmann         /* saturate */
494328f1f0fSBastian Koppelmann         ret = 0;
495328f1f0fSBastian Koppelmann     } else {
496328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
497328f1f0fSBastian Koppelmann     }
498328f1f0fSBastian Koppelmann     return ret;
499328f1f0fSBastian Koppelmann }
500328f1f0fSBastian Koppelmann 
501d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
502d5de7839SBastian Koppelmann {
503d5de7839SBastian Koppelmann     int32_t b, i;
504d5de7839SBastian Koppelmann     int32_t ovf = 0;
505d5de7839SBastian Koppelmann     int32_t avf = 0;
506d5de7839SBastian Koppelmann     int32_t ret = 0;
507d5de7839SBastian Koppelmann 
508d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
509d5de7839SBastian Koppelmann         b = sextract32(arg, i * 8, 8);
510d5de7839SBastian Koppelmann         b = (b >= 0) ? b : (0 - b);
511d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
512d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
513d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
514d5de7839SBastian Koppelmann     }
515d5de7839SBastian Koppelmann 
516d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
517d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
518d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
519d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
520d5de7839SBastian Koppelmann 
521d5de7839SBastian Koppelmann     return ret;
522d5de7839SBastian Koppelmann }
523d5de7839SBastian Koppelmann 
524d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
525d5de7839SBastian Koppelmann {
526d5de7839SBastian Koppelmann     int32_t h, i;
527d5de7839SBastian Koppelmann     int32_t ovf = 0;
528d5de7839SBastian Koppelmann     int32_t avf = 0;
529d5de7839SBastian Koppelmann     int32_t ret = 0;
530d5de7839SBastian Koppelmann 
531d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
532d5de7839SBastian Koppelmann         h = sextract32(arg, i * 16, 16);
533d5de7839SBastian Koppelmann         h = (h >= 0) ? h : (0 - h);
534d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
535d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
536d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
537d5de7839SBastian Koppelmann     }
538d5de7839SBastian Koppelmann 
539d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
540d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
541d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
542d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
543d5de7839SBastian Koppelmann 
544d5de7839SBastian Koppelmann     return ret;
545d5de7839SBastian Koppelmann }
546d5de7839SBastian Koppelmann 
547d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
548d5de7839SBastian Koppelmann {
549d5de7839SBastian Koppelmann     int32_t b, i;
550d5de7839SBastian Koppelmann     int32_t extr_r2;
551d5de7839SBastian Koppelmann     int32_t ovf = 0;
552d5de7839SBastian Koppelmann     int32_t avf = 0;
553d5de7839SBastian Koppelmann     int32_t ret = 0;
554d5de7839SBastian Koppelmann 
555d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
556d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
557d5de7839SBastian Koppelmann         b = sextract32(r1, i * 8, 8);
558d5de7839SBastian Koppelmann         b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
559d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
560d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
561d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
562d5de7839SBastian Koppelmann     }
563d5de7839SBastian Koppelmann 
564d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
565d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
566d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
567d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
568d5de7839SBastian Koppelmann     return ret;
569d5de7839SBastian Koppelmann }
570d5de7839SBastian Koppelmann 
571d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
572d5de7839SBastian Koppelmann {
573d5de7839SBastian Koppelmann     int32_t h, i;
574d5de7839SBastian Koppelmann     int32_t extr_r2;
575d5de7839SBastian Koppelmann     int32_t ovf = 0;
576d5de7839SBastian Koppelmann     int32_t avf = 0;
577d5de7839SBastian Koppelmann     int32_t ret = 0;
578d5de7839SBastian Koppelmann 
579d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
580d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
581d5de7839SBastian Koppelmann         h = sextract32(r1, i * 16, 16);
582d5de7839SBastian Koppelmann         h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
583d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
584d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
585d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
586d5de7839SBastian Koppelmann     }
587d5de7839SBastian Koppelmann 
588d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
589d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
590d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
591d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
592d5de7839SBastian Koppelmann 
593d5de7839SBastian Koppelmann     return ret;
594d5de7839SBastian Koppelmann }
595d5de7839SBastian Koppelmann 
596d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
597d5de7839SBastian Koppelmann {
598d5de7839SBastian Koppelmann     int32_t b, i;
599d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
600d5de7839SBastian Koppelmann     int32_t ovf = 0;
601d5de7839SBastian Koppelmann     int32_t avf = 0;
602d5de7839SBastian Koppelmann     uint32_t ret = 0;
603d5de7839SBastian Koppelmann 
604d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
605d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
606d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
607d5de7839SBastian Koppelmann 
608d5de7839SBastian Koppelmann         b = extr_r1 + extr_r2;
609d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
610d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
611d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
612d5de7839SBastian Koppelmann     }
613d5de7839SBastian Koppelmann 
614d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
615d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
616d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
617d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
618d5de7839SBastian Koppelmann 
619d5de7839SBastian Koppelmann     return ret;
620d5de7839SBastian Koppelmann }
621d5de7839SBastian Koppelmann 
622d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
623d5de7839SBastian Koppelmann {
624d5de7839SBastian Koppelmann     int32_t h, i;
625d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
626d5de7839SBastian Koppelmann     int32_t ovf = 0;
627d5de7839SBastian Koppelmann     int32_t avf = 0;
628d5de7839SBastian Koppelmann     int32_t ret = 0;
629d5de7839SBastian Koppelmann 
630d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
631d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
632d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
633d5de7839SBastian Koppelmann         h = extr_r1 + extr_r2;
634d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
635d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
636d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
637d5de7839SBastian Koppelmann     }
638d5de7839SBastian Koppelmann 
639d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
640d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
641d5de7839SBastian Koppelmann     env->PSW_USB_AV = (avf << 16);
642d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
643d5de7839SBastian Koppelmann 
644d5de7839SBastian Koppelmann     return ret;
645d5de7839SBastian Koppelmann }
646d5de7839SBastian Koppelmann 
647d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
648d5de7839SBastian Koppelmann {
649d5de7839SBastian Koppelmann     int32_t b, i;
650d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
651d5de7839SBastian Koppelmann     int32_t ovf = 0;
652d5de7839SBastian Koppelmann     int32_t avf = 0;
653d5de7839SBastian Koppelmann     uint32_t ret = 0;
654d5de7839SBastian Koppelmann 
655d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
656d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
657d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
658d5de7839SBastian Koppelmann 
659d5de7839SBastian Koppelmann         b = extr_r1 - extr_r2;
660d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
661d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
662d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
663d5de7839SBastian Koppelmann     }
664d5de7839SBastian Koppelmann 
665d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
666d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
667d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
668d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
669d5de7839SBastian Koppelmann 
670d5de7839SBastian Koppelmann     return ret;
671d5de7839SBastian Koppelmann }
672d5de7839SBastian Koppelmann 
673d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
674d5de7839SBastian Koppelmann {
675d5de7839SBastian Koppelmann     int32_t h, i;
676d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
677d5de7839SBastian Koppelmann     int32_t ovf = 0;
678d5de7839SBastian Koppelmann     int32_t avf = 0;
679d5de7839SBastian Koppelmann     int32_t ret = 0;
680d5de7839SBastian Koppelmann 
681d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
682d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
683d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
684d5de7839SBastian Koppelmann         h = extr_r1 - extr_r2;
685d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
686d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
687d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
688d5de7839SBastian Koppelmann     }
689d5de7839SBastian Koppelmann 
690d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
691d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
692d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
693d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
694d5de7839SBastian Koppelmann 
695d5de7839SBastian Koppelmann     return ret;
696d5de7839SBastian Koppelmann }
697d5de7839SBastian Koppelmann 
698d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
699d5de7839SBastian Koppelmann {
700d5de7839SBastian Koppelmann     int32_t ret;
701d5de7839SBastian Koppelmann     int32_t i, msk;
702d5de7839SBastian Koppelmann 
703d5de7839SBastian Koppelmann     ret = 0;
704d5de7839SBastian Koppelmann     msk = 0xff;
705d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
706d5de7839SBastian Koppelmann         if ((r1 & msk) == (r2 & msk)) {
707d5de7839SBastian Koppelmann             ret |= msk;
708d5de7839SBastian Koppelmann         }
709d5de7839SBastian Koppelmann         msk = msk << 8;
710d5de7839SBastian Koppelmann     }
711d5de7839SBastian Koppelmann 
712d5de7839SBastian Koppelmann     return ret;
713d5de7839SBastian Koppelmann }
714d5de7839SBastian Koppelmann 
715d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
716d5de7839SBastian Koppelmann {
717d5de7839SBastian Koppelmann     int32_t ret = 0;
718d5de7839SBastian Koppelmann 
719d5de7839SBastian Koppelmann     if ((r1 & 0xffff) == (r2 & 0xffff)) {
720d5de7839SBastian Koppelmann         ret = 0xffff;
721d5de7839SBastian Koppelmann     }
722d5de7839SBastian Koppelmann 
723d5de7839SBastian Koppelmann     if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
724d5de7839SBastian Koppelmann         ret |= 0xffff0000;
725d5de7839SBastian Koppelmann     }
726d5de7839SBastian Koppelmann 
727d5de7839SBastian Koppelmann     return ret;
728d5de7839SBastian Koppelmann }
729d5de7839SBastian Koppelmann 
730d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
731d5de7839SBastian Koppelmann {
732d5de7839SBastian Koppelmann     int32_t i;
733d5de7839SBastian Koppelmann     uint32_t ret = 0;
734d5de7839SBastian Koppelmann 
735d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
736d5de7839SBastian Koppelmann         ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
737d5de7839SBastian Koppelmann     }
738d5de7839SBastian Koppelmann 
739d5de7839SBastian Koppelmann     return ret;
740d5de7839SBastian Koppelmann }
741d5de7839SBastian Koppelmann 
742d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
743d5de7839SBastian Koppelmann {
744d5de7839SBastian Koppelmann     uint32_t ret;
745d5de7839SBastian Koppelmann 
746d5de7839SBastian Koppelmann     ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
747d5de7839SBastian Koppelmann     ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
748d5de7839SBastian Koppelmann 
749d5de7839SBastian Koppelmann     return ret;
750d5de7839SBastian Koppelmann }
751d5de7839SBastian Koppelmann 
752d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
753d5de7839SBastian Koppelmann {
754d5de7839SBastian Koppelmann     int32_t i;
755d5de7839SBastian Koppelmann     uint32_t ret = 0;
756d5de7839SBastian Koppelmann 
757d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
758d5de7839SBastian Koppelmann         if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
759d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
760d5de7839SBastian Koppelmann         }
761d5de7839SBastian Koppelmann     }
762d5de7839SBastian Koppelmann 
763d5de7839SBastian Koppelmann     return ret;
764d5de7839SBastian Koppelmann }
765d5de7839SBastian Koppelmann 
766d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
767d5de7839SBastian Koppelmann {
768d5de7839SBastian Koppelmann     int32_t i;
769d5de7839SBastian Koppelmann     uint32_t ret = 0;
770d5de7839SBastian Koppelmann 
771d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
772d5de7839SBastian Koppelmann         if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
773d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
774d5de7839SBastian Koppelmann         }
775d5de7839SBastian Koppelmann     }
776d5de7839SBastian Koppelmann 
777d5de7839SBastian Koppelmann     return ret;
778d5de7839SBastian Koppelmann }
779d5de7839SBastian Koppelmann 
780d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
781d5de7839SBastian Koppelmann {
782d5de7839SBastian Koppelmann     uint32_t ret = 0;
783d5de7839SBastian Koppelmann 
784d5de7839SBastian Koppelmann     if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
785d5de7839SBastian Koppelmann         ret |= 0xffff;
786d5de7839SBastian Koppelmann     }
787d5de7839SBastian Koppelmann 
788d5de7839SBastian Koppelmann     if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
789d5de7839SBastian Koppelmann         ret |= 0xffff0000;
790d5de7839SBastian Koppelmann     }
791d5de7839SBastian Koppelmann 
792d5de7839SBastian Koppelmann     return ret;
793d5de7839SBastian Koppelmann }
794d5de7839SBastian Koppelmann 
795d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
796d5de7839SBastian Koppelmann {
797d5de7839SBastian Koppelmann     uint32_t ret = 0;
798d5de7839SBastian Koppelmann 
799d5de7839SBastian Koppelmann     if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
800d5de7839SBastian Koppelmann         ret |= 0xffff;
801d5de7839SBastian Koppelmann     }
802d5de7839SBastian Koppelmann 
803d5de7839SBastian Koppelmann     if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
804d5de7839SBastian Koppelmann         ret |= 0xffff0000;
805d5de7839SBastian Koppelmann     }
806d5de7839SBastian Koppelmann 
807d5de7839SBastian Koppelmann     return ret;
808d5de7839SBastian Koppelmann }
809d5de7839SBastian Koppelmann 
810d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op)                                 \
811d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
812d5de7839SBastian Koppelmann {                                                             \
813d5de7839SBastian Koppelmann     int32_t i, extr_r1, extr_r2;                              \
814d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
815d5de7839SBastian Koppelmann                                                               \
816d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
817d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);                   \
818d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);                   \
819d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
820d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
821d5de7839SBastian Koppelmann     }                                                         \
822d5de7839SBastian Koppelmann     return ret;                                               \
823d5de7839SBastian Koppelmann }                                                             \
824d5de7839SBastian Koppelmann                                                               \
825d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
826d5de7839SBastian Koppelmann {                                                             \
827d5de7839SBastian Koppelmann     int32_t i;                                                \
828d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
829d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
830d5de7839SBastian Koppelmann                                                               \
831d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
832d5de7839SBastian Koppelmann         extr_r1 = extract32(r1, i * 8, 8);                    \
833d5de7839SBastian Koppelmann         extr_r2 = extract32(r2, i * 8, 8);                    \
834d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
835d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
836d5de7839SBastian Koppelmann     }                                                         \
837d5de7839SBastian Koppelmann     return ret;                                               \
838d5de7839SBastian Koppelmann }                                                             \
839d5de7839SBastian Koppelmann                                                               \
840d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
841d5de7839SBastian Koppelmann {                                                             \
842d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;                                 \
843d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
844d5de7839SBastian Koppelmann                                                               \
845d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 0, 16);                          \
846d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 0, 16);                          \
847d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
848d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
849d5de7839SBastian Koppelmann                                                               \
850d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 16, 16);                         \
851d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 16, 16);                         \
852d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
853d5de7839SBastian Koppelmann     ret |= extr_r1 << 16;                                     \
854d5de7839SBastian Koppelmann                                                               \
855d5de7839SBastian Koppelmann     return ret;                                               \
856d5de7839SBastian Koppelmann }                                                             \
857d5de7839SBastian Koppelmann                                                               \
858d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
859d5de7839SBastian Koppelmann {                                                             \
860d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
861d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
862d5de7839SBastian Koppelmann                                                               \
863d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 0, 16);                           \
864d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 0, 16);                           \
865d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
866d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
867d5de7839SBastian Koppelmann                                                               \
868d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 16, 16);                          \
869d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 16, 16);                          \
870d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
871d5de7839SBastian Koppelmann     ret |= extr_r1 << (16);                                   \
872d5de7839SBastian Koppelmann                                                               \
873d5de7839SBastian Koppelmann     return ret;                                               \
874d5de7839SBastian Koppelmann }                                                             \
875d5de7839SBastian Koppelmann 
876d5de7839SBastian Koppelmann EXTREMA_H_B(max, >)
877d5de7839SBastian Koppelmann EXTREMA_H_B(min, <)
878d5de7839SBastian Koppelmann 
879d5de7839SBastian Koppelmann #undef EXTREMA_H_B
880d5de7839SBastian Koppelmann 
8810b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1)
8820b79a781SBastian Koppelmann {
8830b79a781SBastian Koppelmann     return clo32(r1);
8840b79a781SBastian Koppelmann }
8850b79a781SBastian Koppelmann 
8860b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1)
8870b79a781SBastian Koppelmann {
8880b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
8890b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
8900b79a781SBastian Koppelmann 
8910b79a781SBastian Koppelmann     ret_hw0 = clo32(ret_hw0 << 16);
8920b79a781SBastian Koppelmann     ret_hw1 = clo32(ret_hw1 << 16);
8930b79a781SBastian Koppelmann 
8940b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
8950b79a781SBastian Koppelmann         ret_hw0 = 16;
8960b79a781SBastian Koppelmann     }
8970b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
8980b79a781SBastian Koppelmann         ret_hw1 = 16;
8990b79a781SBastian Koppelmann     }
9000b79a781SBastian Koppelmann 
9010b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
9020b79a781SBastian Koppelmann }
9030b79a781SBastian Koppelmann 
9040b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1)
9050b79a781SBastian Koppelmann {
9060b79a781SBastian Koppelmann     return clz32(r1);
9070b79a781SBastian Koppelmann }
9080b79a781SBastian Koppelmann 
9090b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1)
9100b79a781SBastian Koppelmann {
9110b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
9120b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
9130b79a781SBastian Koppelmann 
9140b79a781SBastian Koppelmann     ret_hw0 = clz32(ret_hw0 << 16);
9150b79a781SBastian Koppelmann     ret_hw1 = clz32(ret_hw1 << 16);
9160b79a781SBastian Koppelmann 
9170b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
9180b79a781SBastian Koppelmann         ret_hw0 = 16;
9190b79a781SBastian Koppelmann     }
9200b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
9210b79a781SBastian Koppelmann         ret_hw1 = 16;
9220b79a781SBastian Koppelmann     }
9230b79a781SBastian Koppelmann 
9240b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
9250b79a781SBastian Koppelmann }
9260b79a781SBastian Koppelmann 
9270b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1)
9280b79a781SBastian Koppelmann {
9290b79a781SBastian Koppelmann     return clrsb32(r1);
9300b79a781SBastian Koppelmann }
9310b79a781SBastian Koppelmann 
9320b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1)
9330b79a781SBastian Koppelmann {
9340b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
9350b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
9360b79a781SBastian Koppelmann 
9370b79a781SBastian Koppelmann     ret_hw0 = clrsb32(ret_hw0 << 16);
9380b79a781SBastian Koppelmann     ret_hw1 = clrsb32(ret_hw1 << 16);
9390b79a781SBastian Koppelmann 
9400b79a781SBastian Koppelmann     if (ret_hw0 > 15) {
9410b79a781SBastian Koppelmann         ret_hw0 = 15;
9420b79a781SBastian Koppelmann     }
9430b79a781SBastian Koppelmann     if (ret_hw1 > 15) {
9440b79a781SBastian Koppelmann         ret_hw1 = 15;
9450b79a781SBastian Koppelmann     }
9460b79a781SBastian Koppelmann 
9470b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
9480b79a781SBastian Koppelmann }
9490b79a781SBastian Koppelmann 
9500b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2)
9510b79a781SBastian Koppelmann {
9520b79a781SBastian Koppelmann     int32_t shift_count = sextract32(r2, 0, 6);
9530b79a781SBastian Koppelmann 
9540b79a781SBastian Koppelmann     if (shift_count == -32) {
9550b79a781SBastian Koppelmann         return 0;
9560b79a781SBastian Koppelmann     } else if (shift_count < 0) {
9570b79a781SBastian Koppelmann         return r1 >> -shift_count;
9580b79a781SBastian Koppelmann     } else {
9590b79a781SBastian Koppelmann         return r1 << shift_count;
9600b79a781SBastian Koppelmann     }
9610b79a781SBastian Koppelmann }
9620b79a781SBastian Koppelmann 
9630b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
9640b79a781SBastian Koppelmann {
9650b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
9660b79a781SBastian Koppelmann     int32_t shift_count;
9670b79a781SBastian Koppelmann 
9680b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
9690b79a781SBastian Koppelmann 
9700b79a781SBastian Koppelmann     if (shift_count == -16) {
9710b79a781SBastian Koppelmann         return 0;
9720b79a781SBastian Koppelmann     } else if (shift_count < 0) {
9730b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
9740b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
9750b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
9760b79a781SBastian Koppelmann     } else {
9770b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) << shift_count;
9780b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) << shift_count;
9790b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
9800b79a781SBastian Koppelmann     }
9810b79a781SBastian Koppelmann }
9820b79a781SBastian Koppelmann 
9830b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
9840b79a781SBastian Koppelmann {
9850b79a781SBastian Koppelmann     int32_t shift_count;
9860b79a781SBastian Koppelmann     int64_t result, t1;
9870b79a781SBastian Koppelmann     uint32_t ret;
9880b79a781SBastian Koppelmann 
9890b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 6);
9900b79a781SBastian Koppelmann     t1 = sextract32(r1, 0, 32);
9910b79a781SBastian Koppelmann 
9920b79a781SBastian Koppelmann     if (shift_count == 0) {
9930b79a781SBastian Koppelmann         env->PSW_USB_C = env->PSW_USB_V = 0;
9940b79a781SBastian Koppelmann         ret = r1;
9950b79a781SBastian Koppelmann     } else if (shift_count == -32) {
9960b79a781SBastian Koppelmann         env->PSW_USB_C = r1;
9970b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
9980b79a781SBastian Koppelmann         ret = t1 >> 31;
9990b79a781SBastian Koppelmann     } else if (shift_count > 0) {
10000b79a781SBastian Koppelmann         result = t1 << shift_count;
10010b79a781SBastian Koppelmann         /* calc carry */
1002452e3d49SPeter Maydell         env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
10030b79a781SBastian Koppelmann         /* calc v */
10040b79a781SBastian Koppelmann         env->PSW_USB_V = (((result > 0x7fffffffLL) ||
10050b79a781SBastian Koppelmann                            (result < -0x80000000LL)) << 31);
10060b79a781SBastian Koppelmann         /* calc sv */
10070b79a781SBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
10080b79a781SBastian Koppelmann         ret = (uint32_t)result;
10090b79a781SBastian Koppelmann     } else {
10100b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
10110b79a781SBastian Koppelmann         env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
10120b79a781SBastian Koppelmann         ret = t1 >> -shift_count;
10130b79a781SBastian Koppelmann     }
10140b79a781SBastian Koppelmann 
10150b79a781SBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
10160b79a781SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
10170b79a781SBastian Koppelmann 
10180b79a781SBastian Koppelmann     return ret;
10190b79a781SBastian Koppelmann }
10200b79a781SBastian Koppelmann 
10210b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
10220b79a781SBastian Koppelmann {
10230b79a781SBastian Koppelmann     int32_t shift_count;
10240b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
10250b79a781SBastian Koppelmann 
10260b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
10270b79a781SBastian Koppelmann 
10280b79a781SBastian Koppelmann     if (shift_count == 0) {
10290b79a781SBastian Koppelmann         return r1;
10300b79a781SBastian Koppelmann     } else if (shift_count < 0) {
10310b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
10320b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
10330b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
10340b79a781SBastian Koppelmann     } else {
10350b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) << shift_count;
10360b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) << shift_count;
10370b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
10380b79a781SBastian Koppelmann     }
10390b79a781SBastian Koppelmann }
10400b79a781SBastian Koppelmann 
1041e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1042e2bed107SBastian Koppelmann {
1043e2bed107SBastian Koppelmann     uint32_t i, ret;
1044e2bed107SBastian Koppelmann 
1045e2bed107SBastian Koppelmann     ret = 0;
1046e2bed107SBastian Koppelmann     for (i = 0; i < 16; i++) {
1047e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (2 * i + 1);
1048e2bed107SBastian Koppelmann         ret |= (r2 & 1) << (2 * i);
1049e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1050e2bed107SBastian Koppelmann         r2 = r2 >> 1;
1051e2bed107SBastian Koppelmann     }
1052e2bed107SBastian Koppelmann     return ret;
1053e2bed107SBastian Koppelmann }
1054e2bed107SBastian Koppelmann 
1055e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1)
1056e2bed107SBastian Koppelmann {
1057e2bed107SBastian Koppelmann     int32_t i;
1058e2bed107SBastian Koppelmann     uint64_t ret;
1059e2bed107SBastian Koppelmann 
1060e2bed107SBastian Koppelmann     ret = 0;
1061e2bed107SBastian Koppelmann     for (i = 0; i < 32; i = i + 2) {
1062e2bed107SBastian Koppelmann         /* even */
1063e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (i/2);
1064e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1065e2bed107SBastian Koppelmann         /* odd */
1066e2bed107SBastian Koppelmann         ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1067e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1068e2bed107SBastian Koppelmann     }
1069e2bed107SBastian Koppelmann     return ret;
1070e2bed107SBastian Koppelmann }
1071e2bed107SBastian Koppelmann 
1072e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1)
1073e2bed107SBastian Koppelmann {
1074e2bed107SBastian Koppelmann     uint32_t ret;
1075e2bed107SBastian Koppelmann     uint32_t nOnes, i;
1076e2bed107SBastian Koppelmann 
1077e2bed107SBastian Koppelmann     ret = 0;
1078e2bed107SBastian Koppelmann     nOnes = 0;
1079e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1080e2bed107SBastian Koppelmann         ret ^= (r1 & 1);
1081e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1082e2bed107SBastian Koppelmann     }
1083e2bed107SBastian Koppelmann     /* second byte */
1084e2bed107SBastian Koppelmann     nOnes = 0;
1085e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1086e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1087e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1088e2bed107SBastian Koppelmann     }
1089e2bed107SBastian Koppelmann     ret |= nOnes << 8;
1090e2bed107SBastian Koppelmann     /* third byte */
1091e2bed107SBastian Koppelmann     nOnes = 0;
1092e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1093e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1094e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1095e2bed107SBastian Koppelmann     }
1096e2bed107SBastian Koppelmann     ret |= nOnes << 16;
1097e2bed107SBastian Koppelmann     /* fourth byte */
1098e2bed107SBastian Koppelmann     nOnes = 0;
1099e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1100e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1101e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1102e2bed107SBastian Koppelmann     }
1103e2bed107SBastian Koppelmann     ret |= nOnes << 24;
1104e2bed107SBastian Koppelmann 
1105e2bed107SBastian Koppelmann     return ret;
1106e2bed107SBastian Koppelmann }
1107e2bed107SBastian Koppelmann 
1108e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1)
1109e2bed107SBastian Koppelmann {
1110e2bed107SBastian Koppelmann     int32_t fp_exp  = extract32(arg1, 23, 8);
1111e2bed107SBastian Koppelmann     int32_t fp_frac = extract32(arg1, 0, 23);
1112e2bed107SBastian Koppelmann     uint64_t ret;
1113e2bed107SBastian Koppelmann     int32_t int_exp, int_mant;
1114e2bed107SBastian Koppelmann 
1115e2bed107SBastian Koppelmann     if (fp_exp == 255) {
1116e2bed107SBastian Koppelmann         int_exp = 255;
1117e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1118e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac == 0)) {
1119e2bed107SBastian Koppelmann         int_exp  = -127;
1120e2bed107SBastian Koppelmann         int_mant = 0;
1121e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac != 0)) {
1122e2bed107SBastian Koppelmann         int_exp  = -126;
1123e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1124e2bed107SBastian Koppelmann     } else {
1125e2bed107SBastian Koppelmann         int_exp  = fp_exp - 127;
1126e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1127e2bed107SBastian Koppelmann         int_mant |= (1 << 30);
1128e2bed107SBastian Koppelmann     }
1129e2bed107SBastian Koppelmann     ret = int_exp;
1130e2bed107SBastian Koppelmann     ret = ret << 32;
1131e2bed107SBastian Koppelmann     ret |= int_mant;
1132e2bed107SBastian Koppelmann 
1133e2bed107SBastian Koppelmann     return ret;
1134e2bed107SBastian Koppelmann }
1135e2bed107SBastian Koppelmann 
1136e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1137e2bed107SBastian Koppelmann {
1138e2bed107SBastian Koppelmann     uint64_t ret;
1139e2bed107SBastian Koppelmann     int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1140e2bed107SBastian Koppelmann     int32_t quotient_sign;
1141e2bed107SBastian Koppelmann 
1142e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1143e2bed107SBastian Koppelmann     ret = ret << 24;
1144e2bed107SBastian Koppelmann     quotient_sign = 0;
1145e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1146e2bed107SBastian Koppelmann         ret |= 0xffffff;
1147e2bed107SBastian Koppelmann         quotient_sign = 1;
1148e2bed107SBastian Koppelmann     }
1149e2bed107SBastian Koppelmann 
1150e2bed107SBastian Koppelmann     abs_sig_dividend = abs(r1) >> 7;
1151e2bed107SBastian Koppelmann     abs_base_dividend = abs(r1) & 0x7f;
1152e2bed107SBastian Koppelmann     abs_divisor = abs(r1);
1153e2bed107SBastian Koppelmann     /* calc overflow */
1154e2bed107SBastian Koppelmann     env->PSW_USB_V = 0;
1155e2bed107SBastian Koppelmann     if ((quotient_sign) && (abs_divisor)) {
1156e2bed107SBastian Koppelmann         env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1157e2bed107SBastian Koppelmann                          (abs_base_dividend >= abs_divisor)) ||
1158e2bed107SBastian Koppelmann                          (abs_sig_dividend > abs_divisor));
1159e2bed107SBastian Koppelmann     } else {
1160e2bed107SBastian Koppelmann         env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1161e2bed107SBastian Koppelmann     }
1162e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1163e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1164e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1165e2bed107SBastian Koppelmann 
1166e2bed107SBastian Koppelmann     return ret;
1167e2bed107SBastian Koppelmann }
1168e2bed107SBastian Koppelmann 
1169e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1170e2bed107SBastian Koppelmann {
1171e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
1172e2bed107SBastian Koppelmann 
1173e2bed107SBastian Koppelmann     ret = ret << 24;
1174e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1175e2bed107SBastian Koppelmann         ret |= 0xffffff;
1176e2bed107SBastian Koppelmann     }
1177e2bed107SBastian Koppelmann     /* calc overflow */
1178e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
1179e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1180e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1181e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1182e2bed107SBastian Koppelmann 
1183e2bed107SBastian Koppelmann     return ret;
1184e2bed107SBastian Koppelmann }
1185e2bed107SBastian Koppelmann 
1186e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1187e2bed107SBastian Koppelmann {
1188e2bed107SBastian Koppelmann     uint64_t ret;
1189e2bed107SBastian Koppelmann     int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1190e2bed107SBastian Koppelmann     int32_t quotient_sign;
1191e2bed107SBastian Koppelmann 
1192e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1193e2bed107SBastian Koppelmann     ret = ret << 16;
1194e2bed107SBastian Koppelmann     quotient_sign = 0;
1195e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1196e2bed107SBastian Koppelmann         ret |= 0xffff;
1197e2bed107SBastian Koppelmann         quotient_sign = 1;
1198e2bed107SBastian Koppelmann     }
1199e2bed107SBastian Koppelmann 
1200e2bed107SBastian Koppelmann     abs_sig_dividend = abs(r1) >> 7;
1201e2bed107SBastian Koppelmann     abs_base_dividend = abs(r1) & 0x7f;
1202e2bed107SBastian Koppelmann     abs_divisor = abs(r1);
1203e2bed107SBastian Koppelmann     /* calc overflow */
1204e2bed107SBastian Koppelmann     env->PSW_USB_V = 0;
1205e2bed107SBastian Koppelmann     if ((quotient_sign) && (abs_divisor)) {
1206e2bed107SBastian Koppelmann         env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1207e2bed107SBastian Koppelmann                          (abs_base_dividend >= abs_divisor)) ||
1208e2bed107SBastian Koppelmann                          (abs_sig_dividend > abs_divisor));
1209e2bed107SBastian Koppelmann     } else {
1210e2bed107SBastian Koppelmann         env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1211e2bed107SBastian Koppelmann     }
1212e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1213e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1214e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1215e2bed107SBastian Koppelmann 
1216e2bed107SBastian Koppelmann     return ret;
1217e2bed107SBastian Koppelmann }
1218e2bed107SBastian Koppelmann 
1219e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1220e2bed107SBastian Koppelmann {
1221e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
1222e2bed107SBastian Koppelmann 
1223e2bed107SBastian Koppelmann     ret = ret << 16;
1224e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1225e2bed107SBastian Koppelmann         ret |= 0xffff;
1226e2bed107SBastian Koppelmann     }
1227e2bed107SBastian Koppelmann     /* calc overflow */
1228e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
1229e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1230e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1231e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1232e2bed107SBastian Koppelmann 
1233e2bed107SBastian Koppelmann     return ret;
1234e2bed107SBastian Koppelmann }
1235e2bed107SBastian Koppelmann 
12369655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
12379655b932SBastian Koppelmann                       uint32_t arg10, uint32_t arg11, uint32_t n)
12389655b932SBastian Koppelmann {
12399655b932SBastian Koppelmann     uint64_t ret;
12409655b932SBastian Koppelmann     uint32_t result0, result1;
12419655b932SBastian Koppelmann 
12429655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
12439655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
12449655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
12459655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
12469655b932SBastian Koppelmann     if (sc1) {
12479655b932SBastian Koppelmann         result1 = 0x7fffffff;
12489655b932SBastian Koppelmann     } else {
12499655b932SBastian Koppelmann         result1 = (((uint32_t)(arg00 * arg10)) << n);
12509655b932SBastian Koppelmann     }
12519655b932SBastian Koppelmann     if (sc0) {
12529655b932SBastian Koppelmann         result0 = 0x7fffffff;
12539655b932SBastian Koppelmann     } else {
12549655b932SBastian Koppelmann         result0 = (((uint32_t)(arg01 * arg11)) << n);
12559655b932SBastian Koppelmann     }
12569655b932SBastian Koppelmann     ret = (((uint64_t)result1 << 32)) | result0;
12579655b932SBastian Koppelmann     return ret;
12589655b932SBastian Koppelmann }
12599655b932SBastian Koppelmann 
12609655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
12619655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
12629655b932SBastian Koppelmann {
12639655b932SBastian Koppelmann     uint64_t ret;
12649655b932SBastian Koppelmann     int64_t result0, result1;
12659655b932SBastian Koppelmann 
12669655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
12679655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
12689655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
12699655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
12709655b932SBastian Koppelmann 
12719655b932SBastian Koppelmann     if (sc1) {
12729655b932SBastian Koppelmann         result1 = 0x7fffffff;
12739655b932SBastian Koppelmann     } else {
12749655b932SBastian Koppelmann         result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
12759655b932SBastian Koppelmann     }
12769655b932SBastian Koppelmann     if (sc0) {
12779655b932SBastian Koppelmann         result0 = 0x7fffffff;
12789655b932SBastian Koppelmann     } else {
12799655b932SBastian Koppelmann         result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
12809655b932SBastian Koppelmann     }
12819655b932SBastian Koppelmann     ret = (result1 + result0);
12829655b932SBastian Koppelmann     ret = ret << 16;
12839655b932SBastian Koppelmann     return ret;
12849655b932SBastian Koppelmann }
12859655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
12869655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
12879655b932SBastian Koppelmann {
12889655b932SBastian Koppelmann     uint32_t result0, result1;
12899655b932SBastian Koppelmann 
12909655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
12919655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
12929655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
12939655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
12949655b932SBastian Koppelmann 
12959655b932SBastian Koppelmann     if (sc1) {
12969655b932SBastian Koppelmann         result1 = 0x7fffffff;
12979655b932SBastian Koppelmann     } else {
12989655b932SBastian Koppelmann         result1 = ((arg00 * arg10) << n) + 0x8000;
12999655b932SBastian Koppelmann     }
13009655b932SBastian Koppelmann     if (sc0) {
13019655b932SBastian Koppelmann         result0 = 0x7fffffff;
13029655b932SBastian Koppelmann     } else {
13039655b932SBastian Koppelmann         result0 = ((arg01 * arg11) << n) + 0x8000;
13049655b932SBastian Koppelmann     }
13059655b932SBastian Koppelmann     return (result1 & 0xffff0000) | (result0 >> 16);
13069655b932SBastian Koppelmann }
13079655b932SBastian Koppelmann 
13089a31922bSBastian Koppelmann /* context save area (CSA) related helpers */
13099a31922bSBastian Koppelmann 
13109a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw)
13119a31922bSBastian Koppelmann {
13129a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
13139a31922bSBastian Koppelmann         return 0;
13149a31922bSBastian Koppelmann     }
13159a31922bSBastian Koppelmann 
13169a31922bSBastian Koppelmann     (*psw)++;
13179a31922bSBastian Koppelmann     /* check for overflow */
13189a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
13199a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
13209a31922bSBastian Koppelmann     int count = *psw & mask;
13219a31922bSBastian Koppelmann     if (count == 0) {
13229a31922bSBastian Koppelmann         (*psw)--;
13239a31922bSBastian Koppelmann         return 1;
13249a31922bSBastian Koppelmann     }
13259a31922bSBastian Koppelmann     return 0;
13269a31922bSBastian Koppelmann }
13279a31922bSBastian Koppelmann 
13289a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw)
13299a31922bSBastian Koppelmann {
13309a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
13319a31922bSBastian Koppelmann         return 0;
13329a31922bSBastian Koppelmann     }
13339a31922bSBastian Koppelmann     /* check for underflow */
13349a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
13359a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
13369a31922bSBastian Koppelmann     int count = *psw & mask;
13379a31922bSBastian Koppelmann     if (count == 0) {
13389a31922bSBastian Koppelmann         return 1;
13399a31922bSBastian Koppelmann     }
13409a31922bSBastian Koppelmann     (*psw)--;
13419a31922bSBastian Koppelmann     return 0;
13429a31922bSBastian Koppelmann }
13439a31922bSBastian Koppelmann 
134444ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw)
134544ea3430SBastian Koppelmann {
134644ea3430SBastian Koppelmann     int cdc = *psw & MASK_PSW_CDC;
134744ea3430SBastian Koppelmann     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
134844ea3430SBastian Koppelmann        7'b1111111, otherwise returns FALSE. */
134944ea3430SBastian Koppelmann     if (cdc == 0x7f) {
135044ea3430SBastian Koppelmann         return true;
135144ea3430SBastian Koppelmann     }
135244ea3430SBastian Koppelmann     /* find CDC.COUNT */
135344ea3430SBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
135444ea3430SBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
135544ea3430SBastian Koppelmann     int count = *psw & mask;
135644ea3430SBastian Koppelmann     return count == 0;
135744ea3430SBastian Koppelmann }
135844ea3430SBastian Koppelmann 
1359030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea)
13609a31922bSBastian Koppelmann {
13619a31922bSBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
13629a31922bSBastian Koppelmann     cpu_stl_data(env, ea+4, env->PSW);
13639a31922bSBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[10]);
13649a31922bSBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[11]);
13659a31922bSBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[8]);
13669a31922bSBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[9]);
13679a31922bSBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[10]);
13689a31922bSBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[11]);
13699a31922bSBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[12]);
13709a31922bSBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[13]);
13719a31922bSBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[14]);
13729a31922bSBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[15]);
13739a31922bSBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[12]);
13749a31922bSBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[13]);
13759a31922bSBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[14]);
13769a31922bSBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[15]);
13779a31922bSBastian Koppelmann }
13789a31922bSBastian Koppelmann 
1379030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea)
13805de93515SBastian Koppelmann {
13815de93515SBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
1382030c58dfSBastian Koppelmann     cpu_stl_data(env, ea+4, env->gpr_a[11]);
13835de93515SBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[2]);
13845de93515SBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[3]);
13855de93515SBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[0]);
13865de93515SBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[1]);
13875de93515SBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[2]);
13885de93515SBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[3]);
13895de93515SBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[4]);
13905de93515SBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[5]);
13915de93515SBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[6]);
13925de93515SBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[7]);
13935de93515SBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[4]);
13945de93515SBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[5]);
13955de93515SBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[6]);
13965de93515SBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[7]);
13975de93515SBastian Koppelmann }
13985de93515SBastian Koppelmann 
13999a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea,
14009a31922bSBastian Koppelmann                                   target_ulong *new_PCXI, target_ulong *new_PSW)
14019a31922bSBastian Koppelmann {
14029a31922bSBastian Koppelmann     *new_PCXI = cpu_ldl_data(env, ea);
14039a31922bSBastian Koppelmann     *new_PSW = cpu_ldl_data(env, ea+4);
14049a31922bSBastian Koppelmann     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
14059a31922bSBastian Koppelmann     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
14069a31922bSBastian Koppelmann     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
14079a31922bSBastian Koppelmann     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
14089a31922bSBastian Koppelmann     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
14099a31922bSBastian Koppelmann     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
14109a31922bSBastian Koppelmann     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
14119a31922bSBastian Koppelmann     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
14129a31922bSBastian Koppelmann     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
14139a31922bSBastian Koppelmann     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
14149a31922bSBastian Koppelmann     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
14159a31922bSBastian Koppelmann     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
14169a31922bSBastian Koppelmann     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
14179a31922bSBastian Koppelmann     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
14189a31922bSBastian Koppelmann }
14199a31922bSBastian Koppelmann 
142059543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea,
142159543d4eSBastian Koppelmann                                   target_ulong *ra, target_ulong *pcxi)
142259543d4eSBastian Koppelmann {
142359543d4eSBastian Koppelmann     *pcxi = cpu_ldl_data(env, ea);
142459543d4eSBastian Koppelmann     *ra = cpu_ldl_data(env, ea+4);
142559543d4eSBastian Koppelmann     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
142659543d4eSBastian Koppelmann     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
142759543d4eSBastian Koppelmann     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
142859543d4eSBastian Koppelmann     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
142959543d4eSBastian Koppelmann     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
143059543d4eSBastian Koppelmann     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
143159543d4eSBastian Koppelmann     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
143259543d4eSBastian Koppelmann     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
143359543d4eSBastian Koppelmann     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
143459543d4eSBastian Koppelmann     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
143559543d4eSBastian Koppelmann     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
143659543d4eSBastian Koppelmann     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
143759543d4eSBastian Koppelmann     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
143859543d4eSBastian Koppelmann     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
143959543d4eSBastian Koppelmann }
144059543d4eSBastian Koppelmann 
14419a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc)
14429a31922bSBastian Koppelmann {
14439a31922bSBastian Koppelmann     target_ulong tmp_FCX;
14449a31922bSBastian Koppelmann     target_ulong ea;
14459a31922bSBastian Koppelmann     target_ulong new_FCX;
14469a31922bSBastian Koppelmann     target_ulong psw;
14479a31922bSBastian Koppelmann 
14489a31922bSBastian Koppelmann     psw = psw_read(env);
14499a31922bSBastian Koppelmann     /* if (FCX == 0) trap(FCU); */
14509a31922bSBastian Koppelmann     if (env->FCX == 0) {
14519a31922bSBastian Koppelmann         /* FCU trap */
14529a31922bSBastian Koppelmann     }
14539a31922bSBastian Koppelmann     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
14549a31922bSBastian Koppelmann     if (psw & MASK_PSW_CDE) {
14559a31922bSBastian Koppelmann         if (cdc_increment(&psw)) {
14569a31922bSBastian Koppelmann             /* CDO trap */
14579a31922bSBastian Koppelmann         }
14589a31922bSBastian Koppelmann     }
14599a31922bSBastian Koppelmann     /* PSW.CDE = 1;*/
14609a31922bSBastian Koppelmann     psw |= MASK_PSW_CDE;
14619a31922bSBastian Koppelmann     /* tmp_FCX = FCX; */
14629a31922bSBastian Koppelmann     tmp_FCX = env->FCX;
14639a31922bSBastian Koppelmann     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
14649a31922bSBastian Koppelmann     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
14659a31922bSBastian Koppelmann          ((env->FCX & MASK_FCX_FCXO) << 6);
1466030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
1467030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
1468030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
14699a31922bSBastian Koppelmann                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
14709a31922bSBastian Koppelmann                            D[15]}; */
1471030c58dfSBastian Koppelmann     save_context_upper(env, ea);
14729a31922bSBastian Koppelmann 
14739a31922bSBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN; */
14749a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
14759a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_CCPN) << 24);
14769a31922bSBastian Koppelmann     /* PCXI.PIE = ICR.IE; */
14779a31922bSBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
14789a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_IE) << 15));
14799a31922bSBastian Koppelmann     /* PCXI.UL = 1; */
14809a31922bSBastian Koppelmann     env->PCXI |= MASK_PCXI_UL;
14819a31922bSBastian Koppelmann 
14829a31922bSBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0]; */
14839a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
14849a31922bSBastian Koppelmann     /* FCX[19: 0] = new_FCX[19: 0]; */
14859a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
14869a31922bSBastian Koppelmann     /* A[11] = next_pc[31: 0]; */
14879a31922bSBastian Koppelmann     env->gpr_a[11] = next_pc;
14889a31922bSBastian Koppelmann 
14899a31922bSBastian Koppelmann     /* if (tmp_FCX == LCX) trap(FCD);*/
14909a31922bSBastian Koppelmann     if (tmp_FCX == env->LCX) {
14919a31922bSBastian Koppelmann         /* FCD trap */
14929a31922bSBastian Koppelmann     }
14939a31922bSBastian Koppelmann     psw_write(env, psw);
14949a31922bSBastian Koppelmann }
14959a31922bSBastian Koppelmann 
14969a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env)
14979a31922bSBastian Koppelmann {
14989a31922bSBastian Koppelmann     target_ulong ea;
14999a31922bSBastian Koppelmann     target_ulong new_PCXI;
15009a31922bSBastian Koppelmann     target_ulong new_PSW, psw;
15019a31922bSBastian Koppelmann 
15029a31922bSBastian Koppelmann     psw = psw_read(env);
15039a31922bSBastian Koppelmann      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
15049a31922bSBastian Koppelmann     if (env->PSW & MASK_PSW_CDE) {
15059a31922bSBastian Koppelmann         if (cdc_decrement(&(env->PSW))) {
15069a31922bSBastian Koppelmann             /* CDU trap */
15079a31922bSBastian Koppelmann         }
15089a31922bSBastian Koppelmann     }
15099a31922bSBastian Koppelmann     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
15109a31922bSBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
15119a31922bSBastian Koppelmann         /* CSU trap */
15129a31922bSBastian Koppelmann     }
15139a31922bSBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
15149a31922bSBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
15159a31922bSBastian Koppelmann         /* CTYP trap */
15169a31922bSBastian Koppelmann     }
15179a31922bSBastian Koppelmann     /* PC = {A11 [31: 1], 1’b0}; */
15189a31922bSBastian Koppelmann     env->PC = env->gpr_a[11] & 0xfffffffe;
15199a31922bSBastian Koppelmann 
15209a31922bSBastian Koppelmann     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
15219a31922bSBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
15229a31922bSBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
15239a31922bSBastian Koppelmann     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
1524030c58dfSBastian Koppelmann         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
15259a31922bSBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
1526030c58dfSBastian Koppelmann     /* M(EA, word) = FCX; */
1527030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
15289a31922bSBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
15299a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
15309a31922bSBastian Koppelmann     /* PCXI = new_PCXI; */
15319a31922bSBastian Koppelmann     env->PCXI = new_PCXI;
15329a31922bSBastian Koppelmann 
15339a31922bSBastian Koppelmann     if (tricore_feature(env, TRICORE_FEATURE_13)) {
15349a31922bSBastian Koppelmann         /* PSW = new_PSW */
15359a31922bSBastian Koppelmann         psw_write(env, new_PSW);
15369a31922bSBastian Koppelmann     } else {
15379a31922bSBastian Koppelmann         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
15389a31922bSBastian Koppelmann         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
15399a31922bSBastian Koppelmann     }
15409a31922bSBastian Koppelmann }
15419a31922bSBastian Koppelmann 
15425de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9)
15435de93515SBastian Koppelmann {
15445de93515SBastian Koppelmann     target_ulong tmp_FCX;
15455de93515SBastian Koppelmann     target_ulong ea;
15465de93515SBastian Koppelmann     target_ulong new_FCX;
15475de93515SBastian Koppelmann 
15485de93515SBastian Koppelmann     if (env->FCX == 0) {
15495de93515SBastian Koppelmann         /* FCU trap */
15505de93515SBastian Koppelmann     }
15515de93515SBastian Koppelmann 
15525de93515SBastian Koppelmann     tmp_FCX = env->FCX;
15535de93515SBastian Koppelmann     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
15545de93515SBastian Koppelmann 
1555030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
1556030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
1557030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
1558030c58dfSBastian Koppelmann                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
1559030c58dfSBastian Koppelmann     save_context_lower(env, ea);
1560030c58dfSBastian Koppelmann 
15615de93515SBastian Koppelmann 
15625de93515SBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN */
15635de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
15645de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_CCPN) << 24);
15655de93515SBastian Koppelmann     /* PCXI.PIE  = ICR.IE */
15665de93515SBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
15675de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_IE) << 15));
15685de93515SBastian Koppelmann     /* PCXI.UL = 0 */
15695de93515SBastian Koppelmann     env->PCXI &= ~(MASK_PCXI_UL);
15705de93515SBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0] */
15715de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
15725de93515SBastian Koppelmann     /* FXC[19: 0] = new_FCX[19: 0] */
15735de93515SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
15745de93515SBastian Koppelmann     /* ICR.IE = 1 */
15755de93515SBastian Koppelmann     env->ICR |= MASK_ICR_IE;
15765de93515SBastian Koppelmann 
15775de93515SBastian Koppelmann     env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
15785de93515SBastian Koppelmann 
15795de93515SBastian Koppelmann     if (tmp_FCX == env->LCX) {
15805de93515SBastian Koppelmann         /* FCD trap */
15815de93515SBastian Koppelmann     }
15825de93515SBastian Koppelmann }
15835de93515SBastian Koppelmann 
158444ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env)
158544ea3430SBastian Koppelmann {
158644ea3430SBastian Koppelmann     target_ulong ea;
158744ea3430SBastian Koppelmann     target_ulong new_PCXI;
158844ea3430SBastian Koppelmann     target_ulong new_PSW;
158944ea3430SBastian Koppelmann     /* if (PCXI[19: 0] == 0) then trap(CSU); */
159044ea3430SBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
159144ea3430SBastian Koppelmann         /* raise csu trap */
159244ea3430SBastian Koppelmann     }
159344ea3430SBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
159444ea3430SBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
159544ea3430SBastian Koppelmann         /* raise CTYP trap */
159644ea3430SBastian Koppelmann     }
159744ea3430SBastian Koppelmann     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
159844ea3430SBastian Koppelmann     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
159944ea3430SBastian Koppelmann         /* raise MNG trap */
160044ea3430SBastian Koppelmann     }
160144ea3430SBastian Koppelmann     /* ICR.IE = PCXI.PIE; */
160244ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
160344ea3430SBastian Koppelmann     /* ICR.CCPN = PCXI.PCPN; */
160444ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
160544ea3430SBastian Koppelmann                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
160644ea3430SBastian Koppelmann     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
160744ea3430SBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
160844ea3430SBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
160944ea3430SBastian Koppelmann     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
1610030c58dfSBastian Koppelmann       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
161144ea3430SBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
1612030c58dfSBastian Koppelmann     /* M(EA, word) = FCX;*/
1613030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
161444ea3430SBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
161544ea3430SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
161644ea3430SBastian Koppelmann     /* PCXI = new_PCXI; */
161744ea3430SBastian Koppelmann     env->PCXI = new_PCXI;
161844ea3430SBastian Koppelmann     /* write psw */
161944ea3430SBastian Koppelmann     psw_write(env, new_PSW);
162044ea3430SBastian Koppelmann }
162144ea3430SBastian Koppelmann 
162259543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
162359543d4eSBastian Koppelmann {
162459543d4eSBastian Koppelmann     uint32_t dummy;
162559543d4eSBastian Koppelmann     /* insn doesn't load PCXI and RA */
162659543d4eSBastian Koppelmann     restore_context_lower(env, ea, &dummy, &dummy);
162759543d4eSBastian Koppelmann }
162859543d4eSBastian Koppelmann 
162959543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea)
163059543d4eSBastian Koppelmann {
163159543d4eSBastian Koppelmann     uint32_t dummy;
163259543d4eSBastian Koppelmann     /* insn doesn't load PCXI and PSW */
163359543d4eSBastian Koppelmann     restore_context_upper(env, ea, &dummy, &dummy);
163459543d4eSBastian Koppelmann }
163559543d4eSBastian Koppelmann 
163659543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
163759543d4eSBastian Koppelmann {
163859543d4eSBastian Koppelmann     save_context_lower(env, ea);
163959543d4eSBastian Koppelmann }
164059543d4eSBastian Koppelmann 
164159543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea)
164259543d4eSBastian Koppelmann {
164359543d4eSBastian Koppelmann     save_context_upper(env, ea);
164459543d4eSBastian Koppelmann }
164559543d4eSBastian Koppelmann 
16462b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
16472b2f7d97SBastian Koppelmann {
16482b2f7d97SBastian Koppelmann     psw_write(env, arg);
16492b2f7d97SBastian Koppelmann }
16502b2f7d97SBastian Koppelmann 
16512b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env)
16522b2f7d97SBastian Koppelmann {
16532b2f7d97SBastian Koppelmann     return psw_read(env);
16542b2f7d97SBastian Koppelmann }
16552b2f7d97SBastian Koppelmann 
16562b2f7d97SBastian Koppelmann 
16572d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
16582d30267eSBastian Koppelmann                                                         uint32_t exception,
16592d30267eSBastian Koppelmann                                                         int error_code,
16602d30267eSBastian Koppelmann                                                         uintptr_t pc)
16612d30267eSBastian Koppelmann {
16622d30267eSBastian Koppelmann     CPUState *cs = CPU(tricore_env_get_cpu(env));
16632d30267eSBastian Koppelmann     cs->exception_index = exception;
16642d30267eSBastian Koppelmann     env->error_code = error_code;
16652d30267eSBastian Koppelmann 
16662d30267eSBastian Koppelmann     if (pc) {
16672d30267eSBastian Koppelmann         /* now we have a real cpu fault */
16682d30267eSBastian Koppelmann         cpu_restore_state(cs, pc);
16692d30267eSBastian Koppelmann     }
16702d30267eSBastian Koppelmann 
16712d30267eSBastian Koppelmann     cpu_loop_exit(cs);
16722d30267eSBastian Koppelmann }
16732d30267eSBastian Koppelmann 
167448e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
167548e06fe0SBastian Koppelmann               uintptr_t retaddr)
167648e06fe0SBastian Koppelmann {
16772d30267eSBastian Koppelmann     int ret;
16782d30267eSBastian Koppelmann     ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
16792d30267eSBastian Koppelmann     if (ret) {
16802d30267eSBastian Koppelmann         TriCoreCPU *cpu = TRICORE_CPU(cs);
16812d30267eSBastian Koppelmann         CPUTriCoreState *env = &cpu->env;
16822d30267eSBastian Koppelmann         do_raise_exception_err(env, cs->exception_index,
16832d30267eSBastian Koppelmann                                env->error_code, retaddr);
168448e06fe0SBastian Koppelmann     }
16852d30267eSBastian Koppelmann }
1686