xref: /qemu/target/tricore/op_helper.c (revision 0b79a78169d813d11ad32f103e7a2c64c32bd705)
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;
258e4e39176SBastian Koppelmann     return suov32(env, result);
2590974257eSBastian Koppelmann }
2600974257eSBastian Koppelmann 
2610974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
2620974257eSBastian Koppelmann                              target_ulong r2)
2630974257eSBastian Koppelmann {
2640974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
2650974257eSBastian Koppelmann     int32_t t2 = sextract64(r2, 0, 6);
2660974257eSBastian Koppelmann     int64_t result;
2670974257eSBastian Koppelmann     if (t2 == 0) {
2680974257eSBastian Koppelmann         result = t1;
2690974257eSBastian Koppelmann     } else if (t2 > 0) {
2700974257eSBastian Koppelmann         result = t1 << t2;
2710974257eSBastian Koppelmann     } else {
2720974257eSBastian Koppelmann         result = t1 >> -t2;
2730974257eSBastian Koppelmann     }
274e4e39176SBastian Koppelmann     return ssov32(env, result);
2750974257eSBastian Koppelmann }
2760974257eSBastian Koppelmann 
277d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
278d5de7839SBastian Koppelmann {
279d5de7839SBastian Koppelmann     target_ulong result;
280d5de7839SBastian Koppelmann     result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
281d5de7839SBastian Koppelmann     return ssov32(env, result);
282d5de7839SBastian Koppelmann }
283d5de7839SBastian Koppelmann 
284d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
285d5de7839SBastian Koppelmann {
286d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
287d5de7839SBastian Koppelmann 
288d5de7839SBastian Koppelmann     ret_h0 = sextract32(r1, 0, 16);
289d5de7839SBastian Koppelmann     ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
290d5de7839SBastian Koppelmann 
291d5de7839SBastian Koppelmann     ret_h1 = sextract32(r1, 16, 16);
292d5de7839SBastian Koppelmann     ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
293d5de7839SBastian Koppelmann 
294d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
295d5de7839SBastian Koppelmann }
296d5de7839SBastian Koppelmann 
2970974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
2980974257eSBastian Koppelmann                                 target_ulong r2)
2990974257eSBastian Koppelmann {
3000974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3010974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
3020974257eSBastian Koppelmann     int64_t result;
3030974257eSBastian Koppelmann 
3040974257eSBastian Koppelmann     if (t1 > t2) {
3050974257eSBastian Koppelmann         result = t1 - t2;
3060974257eSBastian Koppelmann     } else {
3070974257eSBastian Koppelmann         result = t2 - t1;
3080974257eSBastian Koppelmann     }
309e4e39176SBastian Koppelmann     return ssov32(env, result);
3100974257eSBastian Koppelmann }
311328f1f0fSBastian Koppelmann 
312d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
313d5de7839SBastian Koppelmann                               target_ulong r2)
314d5de7839SBastian Koppelmann {
315d5de7839SBastian Koppelmann     int32_t t1, t2;
316d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
317d5de7839SBastian Koppelmann 
318d5de7839SBastian Koppelmann     t1 = sextract32(r1, 0, 16);
319d5de7839SBastian Koppelmann     t2 = sextract32(r2, 0, 16);
320d5de7839SBastian Koppelmann     if (t1 > t2) {
321d5de7839SBastian Koppelmann         ret_h0 = t1 - t2;
322d5de7839SBastian Koppelmann     } else {
323d5de7839SBastian Koppelmann         ret_h0 = t2 - t1;
324d5de7839SBastian Koppelmann     }
325d5de7839SBastian Koppelmann 
326d5de7839SBastian Koppelmann     t1 = sextract32(r1, 16, 16);
327d5de7839SBastian Koppelmann     t2 = sextract32(r2, 16, 16);
328d5de7839SBastian Koppelmann     if (t1 > t2) {
329d5de7839SBastian Koppelmann         ret_h1 = t1 - t2;
330d5de7839SBastian Koppelmann     } else {
331d5de7839SBastian Koppelmann         ret_h1 = t2 - t1;
332d5de7839SBastian Koppelmann     }
333d5de7839SBastian Koppelmann 
334d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
335d5de7839SBastian Koppelmann }
336d5de7839SBastian Koppelmann 
337328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
338328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
339328f1f0fSBastian Koppelmann {
340328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
341328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
342328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
343328f1f0fSBastian Koppelmann     int64_t result;
344328f1f0fSBastian Koppelmann 
345328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
346e4e39176SBastian Koppelmann     return ssov32(env, result);
347328f1f0fSBastian Koppelmann }
348328f1f0fSBastian Koppelmann 
349328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
350328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
351328f1f0fSBastian Koppelmann {
352328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
353328f1f0fSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
354328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
355328f1f0fSBastian Koppelmann     int64_t result;
356328f1f0fSBastian Koppelmann 
357328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
358e4e39176SBastian Koppelmann     return suov32(env, result);
359328f1f0fSBastian Koppelmann }
360328f1f0fSBastian Koppelmann 
361328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
362328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
363328f1f0fSBastian Koppelmann {
364328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
365328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
366328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
367328f1f0fSBastian Koppelmann     int64_t mul;
368328f1f0fSBastian Koppelmann 
369328f1f0fSBastian Koppelmann     mul = t1 * t3;
370328f1f0fSBastian Koppelmann     ret = mul + r2;
371328f1f0fSBastian Koppelmann     ovf = (ret ^ mul) & ~(mul ^ r2);
372328f1f0fSBastian Koppelmann 
373328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
374328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
375328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
376328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
377328f1f0fSBastian Koppelmann         if (mul >= 0) {
378328f1f0fSBastian Koppelmann             ret = INT64_MAX;
379328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
380328f1f0fSBastian Koppelmann         } else {
381328f1f0fSBastian Koppelmann             ret = INT64_MIN;
382328f1f0fSBastian Koppelmann         }
383328f1f0fSBastian Koppelmann     } else {
384328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
385328f1f0fSBastian Koppelmann     }
386328f1f0fSBastian Koppelmann     t1 = ret >> 32;
387328f1f0fSBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
388328f1f0fSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
389328f1f0fSBastian Koppelmann 
390328f1f0fSBastian Koppelmann     return ret;
391328f1f0fSBastian Koppelmann }
392328f1f0fSBastian Koppelmann 
393328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
394328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
395328f1f0fSBastian Koppelmann {
396328f1f0fSBastian Koppelmann     uint64_t ret, mul;
397328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
398328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
399328f1f0fSBastian Koppelmann 
400328f1f0fSBastian Koppelmann     mul = t1 * t3;
401328f1f0fSBastian Koppelmann     ret = mul + r2;
402328f1f0fSBastian Koppelmann 
403328f1f0fSBastian Koppelmann     if (ret < r2) {
404328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
405328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
406328f1f0fSBastian Koppelmann         /* saturate */
407328f1f0fSBastian Koppelmann         ret = UINT64_MAX;
408328f1f0fSBastian Koppelmann     } else {
409328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
410328f1f0fSBastian Koppelmann     }
411328f1f0fSBastian Koppelmann     t1 = ret >> 32;
412328f1f0fSBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
413328f1f0fSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
414328f1f0fSBastian Koppelmann     return ret;
415328f1f0fSBastian Koppelmann }
416328f1f0fSBastian Koppelmann 
417328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
418328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
419328f1f0fSBastian Koppelmann {
420328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
421328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
422328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
423328f1f0fSBastian Koppelmann     int64_t result;
424328f1f0fSBastian Koppelmann 
425328f1f0fSBastian Koppelmann     result = t2 - (t1 * t3);
426e4e39176SBastian Koppelmann     return ssov32(env, result);
427328f1f0fSBastian Koppelmann }
428328f1f0fSBastian Koppelmann 
429328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
430328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
431328f1f0fSBastian Koppelmann {
432328f1f0fSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
433328f1f0fSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
434328f1f0fSBastian Koppelmann     int64_t t3 = extract64(r3, 0, 32);
435328f1f0fSBastian Koppelmann     int64_t result;
436328f1f0fSBastian Koppelmann 
437328f1f0fSBastian Koppelmann     result = t2 - (t1 * t3);
438e4e39176SBastian Koppelmann     return suov32(env, result);
439328f1f0fSBastian Koppelmann }
440328f1f0fSBastian Koppelmann 
441328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
442328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
443328f1f0fSBastian Koppelmann {
444328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
445328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
446328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
447328f1f0fSBastian Koppelmann     int64_t mul;
448328f1f0fSBastian Koppelmann 
449328f1f0fSBastian Koppelmann     mul = t1 * t3;
450328f1f0fSBastian Koppelmann     ret = r2 - mul;
451328f1f0fSBastian Koppelmann     ovf = (ret ^ r2) & (mul ^ r2);
452328f1f0fSBastian Koppelmann 
453328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
454328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
455328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
456328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
457328f1f0fSBastian Koppelmann         if (mul < 0) {
458328f1f0fSBastian Koppelmann             ret = INT64_MAX;
459328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
460328f1f0fSBastian Koppelmann         } else {
461328f1f0fSBastian Koppelmann             ret = INT64_MIN;
462328f1f0fSBastian Koppelmann         }
463328f1f0fSBastian Koppelmann     } else {
464328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
465328f1f0fSBastian Koppelmann     }
466328f1f0fSBastian Koppelmann     t1 = ret >> 32;
467328f1f0fSBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
468328f1f0fSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
469328f1f0fSBastian Koppelmann     return ret;
470328f1f0fSBastian Koppelmann }
471328f1f0fSBastian Koppelmann 
472328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
473328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
474328f1f0fSBastian Koppelmann {
475328f1f0fSBastian Koppelmann     uint64_t ret, mul;
476328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
477328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
478328f1f0fSBastian Koppelmann 
479328f1f0fSBastian Koppelmann     mul = t1 * t3;
480328f1f0fSBastian Koppelmann     ret = r2 - mul;
481328f1f0fSBastian Koppelmann 
482328f1f0fSBastian Koppelmann     if (ret > r2) {
483328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
484328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
485328f1f0fSBastian Koppelmann         /* saturate */
486328f1f0fSBastian Koppelmann         ret = 0;
487328f1f0fSBastian Koppelmann     } else {
488328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
489328f1f0fSBastian Koppelmann     }
490328f1f0fSBastian Koppelmann     t1 = ret >> 32;
491328f1f0fSBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
492328f1f0fSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
493328f1f0fSBastian Koppelmann     return ret;
494328f1f0fSBastian Koppelmann }
495328f1f0fSBastian Koppelmann 
496d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
497d5de7839SBastian Koppelmann {
498d5de7839SBastian Koppelmann     int32_t b, i;
499d5de7839SBastian Koppelmann     int32_t ovf = 0;
500d5de7839SBastian Koppelmann     int32_t avf = 0;
501d5de7839SBastian Koppelmann     int32_t ret = 0;
502d5de7839SBastian Koppelmann 
503d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
504d5de7839SBastian Koppelmann         b = sextract32(arg, i * 8, 8);
505d5de7839SBastian Koppelmann         b = (b >= 0) ? b : (0 - b);
506d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
507d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
508d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
509d5de7839SBastian Koppelmann     }
510d5de7839SBastian Koppelmann 
511d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
512d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
513d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
514d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
515d5de7839SBastian Koppelmann 
516d5de7839SBastian Koppelmann     return ret;
517d5de7839SBastian Koppelmann }
518d5de7839SBastian Koppelmann 
519d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
520d5de7839SBastian Koppelmann {
521d5de7839SBastian Koppelmann     int32_t h, i;
522d5de7839SBastian Koppelmann     int32_t ovf = 0;
523d5de7839SBastian Koppelmann     int32_t avf = 0;
524d5de7839SBastian Koppelmann     int32_t ret = 0;
525d5de7839SBastian Koppelmann 
526d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
527d5de7839SBastian Koppelmann         h = sextract32(arg, i * 16, 16);
528d5de7839SBastian Koppelmann         h = (h >= 0) ? h : (0 - h);
529d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
530d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
531d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
532d5de7839SBastian Koppelmann     }
533d5de7839SBastian Koppelmann 
534d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
535d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
536d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
537d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
538d5de7839SBastian Koppelmann 
539d5de7839SBastian Koppelmann     return ret;
540d5de7839SBastian Koppelmann }
541d5de7839SBastian Koppelmann 
542d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
543d5de7839SBastian Koppelmann {
544d5de7839SBastian Koppelmann     int32_t b, i;
545d5de7839SBastian Koppelmann     int32_t extr_r2;
546d5de7839SBastian Koppelmann     int32_t ovf = 0;
547d5de7839SBastian Koppelmann     int32_t avf = 0;
548d5de7839SBastian Koppelmann     int32_t ret = 0;
549d5de7839SBastian Koppelmann 
550d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
551d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
552d5de7839SBastian Koppelmann         b = sextract32(r1, i * 8, 8);
553d5de7839SBastian Koppelmann         b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
554d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
555d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
556d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
557d5de7839SBastian Koppelmann     }
558d5de7839SBastian Koppelmann 
559d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
560d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
561d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
562d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
563d5de7839SBastian Koppelmann     return ret;
564d5de7839SBastian Koppelmann }
565d5de7839SBastian Koppelmann 
566d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
567d5de7839SBastian Koppelmann {
568d5de7839SBastian Koppelmann     int32_t h, i;
569d5de7839SBastian Koppelmann     int32_t extr_r2;
570d5de7839SBastian Koppelmann     int32_t ovf = 0;
571d5de7839SBastian Koppelmann     int32_t avf = 0;
572d5de7839SBastian Koppelmann     int32_t ret = 0;
573d5de7839SBastian Koppelmann 
574d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
575d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
576d5de7839SBastian Koppelmann         h = sextract32(r1, i * 16, 16);
577d5de7839SBastian Koppelmann         h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
578d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
579d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
580d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
581d5de7839SBastian Koppelmann     }
582d5de7839SBastian Koppelmann 
583d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
584d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
585d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
586d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
587d5de7839SBastian Koppelmann 
588d5de7839SBastian Koppelmann     return ret;
589d5de7839SBastian Koppelmann }
590d5de7839SBastian Koppelmann 
591d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
592d5de7839SBastian Koppelmann {
593d5de7839SBastian Koppelmann     int32_t b, i;
594d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
595d5de7839SBastian Koppelmann     int32_t ovf = 0;
596d5de7839SBastian Koppelmann     int32_t avf = 0;
597d5de7839SBastian Koppelmann     uint32_t ret = 0;
598d5de7839SBastian Koppelmann 
599d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
600d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
601d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
602d5de7839SBastian Koppelmann 
603d5de7839SBastian Koppelmann         b = extr_r1 + extr_r2;
604d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
605d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
606d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
607d5de7839SBastian Koppelmann     }
608d5de7839SBastian Koppelmann 
609d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
610d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
611d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
612d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
613d5de7839SBastian Koppelmann 
614d5de7839SBastian Koppelmann     return ret;
615d5de7839SBastian Koppelmann }
616d5de7839SBastian Koppelmann 
617d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
618d5de7839SBastian Koppelmann {
619d5de7839SBastian Koppelmann     int32_t h, i;
620d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
621d5de7839SBastian Koppelmann     int32_t ovf = 0;
622d5de7839SBastian Koppelmann     int32_t avf = 0;
623d5de7839SBastian Koppelmann     int32_t ret = 0;
624d5de7839SBastian Koppelmann 
625d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
626d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
627d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
628d5de7839SBastian Koppelmann         h = extr_r1 + extr_r2;
629d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
630d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
631d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
632d5de7839SBastian Koppelmann     }
633d5de7839SBastian Koppelmann 
634d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
635d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
636d5de7839SBastian Koppelmann     env->PSW_USB_AV = (avf << 16);
637d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
638d5de7839SBastian Koppelmann 
639d5de7839SBastian Koppelmann     return ret;
640d5de7839SBastian Koppelmann }
641d5de7839SBastian Koppelmann 
642d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
643d5de7839SBastian Koppelmann {
644d5de7839SBastian Koppelmann     int32_t b, i;
645d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
646d5de7839SBastian Koppelmann     int32_t ovf = 0;
647d5de7839SBastian Koppelmann     int32_t avf = 0;
648d5de7839SBastian Koppelmann     uint32_t ret = 0;
649d5de7839SBastian Koppelmann 
650d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
651d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
652d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
653d5de7839SBastian Koppelmann 
654d5de7839SBastian Koppelmann         b = extr_r1 - extr_r2;
655d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
656d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
657d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
658d5de7839SBastian Koppelmann     }
659d5de7839SBastian Koppelmann 
660d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
661d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
662d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
663d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
664d5de7839SBastian Koppelmann 
665d5de7839SBastian Koppelmann     return ret;
666d5de7839SBastian Koppelmann }
667d5de7839SBastian Koppelmann 
668d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
669d5de7839SBastian Koppelmann {
670d5de7839SBastian Koppelmann     int32_t h, i;
671d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
672d5de7839SBastian Koppelmann     int32_t ovf = 0;
673d5de7839SBastian Koppelmann     int32_t avf = 0;
674d5de7839SBastian Koppelmann     int32_t ret = 0;
675d5de7839SBastian Koppelmann 
676d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
677d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
678d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
679d5de7839SBastian Koppelmann         h = extr_r1 - extr_r2;
680d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
681d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
682d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
683d5de7839SBastian Koppelmann     }
684d5de7839SBastian Koppelmann 
685d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
686d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
687d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
688d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
689d5de7839SBastian Koppelmann 
690d5de7839SBastian Koppelmann     return ret;
691d5de7839SBastian Koppelmann }
692d5de7839SBastian Koppelmann 
693d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
694d5de7839SBastian Koppelmann {
695d5de7839SBastian Koppelmann     int32_t ret;
696d5de7839SBastian Koppelmann     int32_t i, msk;
697d5de7839SBastian Koppelmann 
698d5de7839SBastian Koppelmann     ret = 0;
699d5de7839SBastian Koppelmann     msk = 0xff;
700d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
701d5de7839SBastian Koppelmann         if ((r1 & msk) == (r2 & msk)) {
702d5de7839SBastian Koppelmann             ret |= msk;
703d5de7839SBastian Koppelmann         }
704d5de7839SBastian Koppelmann         msk = msk << 8;
705d5de7839SBastian Koppelmann     }
706d5de7839SBastian Koppelmann 
707d5de7839SBastian Koppelmann     return ret;
708d5de7839SBastian Koppelmann }
709d5de7839SBastian Koppelmann 
710d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
711d5de7839SBastian Koppelmann {
712d5de7839SBastian Koppelmann     int32_t ret = 0;
713d5de7839SBastian Koppelmann 
714d5de7839SBastian Koppelmann     if ((r1 & 0xffff) == (r2 & 0xffff)) {
715d5de7839SBastian Koppelmann         ret = 0xffff;
716d5de7839SBastian Koppelmann     }
717d5de7839SBastian Koppelmann 
718d5de7839SBastian Koppelmann     if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
719d5de7839SBastian Koppelmann         ret |= 0xffff0000;
720d5de7839SBastian Koppelmann     }
721d5de7839SBastian Koppelmann 
722d5de7839SBastian Koppelmann     return ret;
723d5de7839SBastian Koppelmann }
724d5de7839SBastian Koppelmann 
725d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
726d5de7839SBastian Koppelmann {
727d5de7839SBastian Koppelmann     int32_t i;
728d5de7839SBastian Koppelmann     uint32_t ret = 0;
729d5de7839SBastian Koppelmann 
730d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
731d5de7839SBastian Koppelmann         ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
732d5de7839SBastian Koppelmann     }
733d5de7839SBastian Koppelmann 
734d5de7839SBastian Koppelmann     return ret;
735d5de7839SBastian Koppelmann }
736d5de7839SBastian Koppelmann 
737d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
738d5de7839SBastian Koppelmann {
739d5de7839SBastian Koppelmann     uint32_t ret;
740d5de7839SBastian Koppelmann 
741d5de7839SBastian Koppelmann     ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
742d5de7839SBastian Koppelmann     ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
743d5de7839SBastian Koppelmann 
744d5de7839SBastian Koppelmann     return ret;
745d5de7839SBastian Koppelmann }
746d5de7839SBastian Koppelmann 
747d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
748d5de7839SBastian Koppelmann {
749d5de7839SBastian Koppelmann     int32_t i;
750d5de7839SBastian Koppelmann     uint32_t ret = 0;
751d5de7839SBastian Koppelmann 
752d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
753d5de7839SBastian Koppelmann         if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
754d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
755d5de7839SBastian Koppelmann         }
756d5de7839SBastian Koppelmann     }
757d5de7839SBastian Koppelmann 
758d5de7839SBastian Koppelmann     return ret;
759d5de7839SBastian Koppelmann }
760d5de7839SBastian Koppelmann 
761d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
762d5de7839SBastian Koppelmann {
763d5de7839SBastian Koppelmann     int32_t i;
764d5de7839SBastian Koppelmann     uint32_t ret = 0;
765d5de7839SBastian Koppelmann 
766d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
767d5de7839SBastian Koppelmann         if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
768d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
769d5de7839SBastian Koppelmann         }
770d5de7839SBastian Koppelmann     }
771d5de7839SBastian Koppelmann 
772d5de7839SBastian Koppelmann     return ret;
773d5de7839SBastian Koppelmann }
774d5de7839SBastian Koppelmann 
775d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
776d5de7839SBastian Koppelmann {
777d5de7839SBastian Koppelmann     uint32_t ret = 0;
778d5de7839SBastian Koppelmann 
779d5de7839SBastian Koppelmann     if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
780d5de7839SBastian Koppelmann         ret |= 0xffff;
781d5de7839SBastian Koppelmann     }
782d5de7839SBastian Koppelmann 
783d5de7839SBastian Koppelmann     if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
784d5de7839SBastian Koppelmann         ret |= 0xffff0000;
785d5de7839SBastian Koppelmann     }
786d5de7839SBastian Koppelmann 
787d5de7839SBastian Koppelmann     return ret;
788d5de7839SBastian Koppelmann }
789d5de7839SBastian Koppelmann 
790d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
791d5de7839SBastian Koppelmann {
792d5de7839SBastian Koppelmann     uint32_t ret = 0;
793d5de7839SBastian Koppelmann 
794d5de7839SBastian Koppelmann     if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
795d5de7839SBastian Koppelmann         ret |= 0xffff;
796d5de7839SBastian Koppelmann     }
797d5de7839SBastian Koppelmann 
798d5de7839SBastian Koppelmann     if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
799d5de7839SBastian Koppelmann         ret |= 0xffff0000;
800d5de7839SBastian Koppelmann     }
801d5de7839SBastian Koppelmann 
802d5de7839SBastian Koppelmann     return ret;
803d5de7839SBastian Koppelmann }
804d5de7839SBastian Koppelmann 
805d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op)                                 \
806d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
807d5de7839SBastian Koppelmann {                                                             \
808d5de7839SBastian Koppelmann     int32_t i, extr_r1, extr_r2;                              \
809d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
810d5de7839SBastian Koppelmann                                                               \
811d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
812d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);                   \
813d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);                   \
814d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
815d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
816d5de7839SBastian Koppelmann     }                                                         \
817d5de7839SBastian Koppelmann     return ret;                                               \
818d5de7839SBastian Koppelmann }                                                             \
819d5de7839SBastian Koppelmann                                                               \
820d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
821d5de7839SBastian Koppelmann {                                                             \
822d5de7839SBastian Koppelmann     int32_t i;                                                \
823d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
824d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
825d5de7839SBastian Koppelmann                                                               \
826d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
827d5de7839SBastian Koppelmann         extr_r1 = extract32(r1, i * 8, 8);                    \
828d5de7839SBastian Koppelmann         extr_r2 = extract32(r2, i * 8, 8);                    \
829d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
830d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
831d5de7839SBastian Koppelmann     }                                                         \
832d5de7839SBastian Koppelmann     return ret;                                               \
833d5de7839SBastian Koppelmann }                                                             \
834d5de7839SBastian Koppelmann                                                               \
835d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
836d5de7839SBastian Koppelmann {                                                             \
837d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;                                 \
838d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
839d5de7839SBastian Koppelmann                                                               \
840d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 0, 16);                          \
841d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 0, 16);                          \
842d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
843d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
844d5de7839SBastian Koppelmann                                                               \
845d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 16, 16);                         \
846d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 16, 16);                         \
847d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
848d5de7839SBastian Koppelmann     ret |= extr_r1 << 16;                                     \
849d5de7839SBastian Koppelmann                                                               \
850d5de7839SBastian Koppelmann     return ret;                                               \
851d5de7839SBastian Koppelmann }                                                             \
852d5de7839SBastian Koppelmann                                                               \
853d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
854d5de7839SBastian Koppelmann {                                                             \
855d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
856d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
857d5de7839SBastian Koppelmann                                                               \
858d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 0, 16);                           \
859d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 0, 16);                           \
860d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
861d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
862d5de7839SBastian Koppelmann                                                               \
863d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 16, 16);                          \
864d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 16, 16);                          \
865d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
866d5de7839SBastian Koppelmann     ret |= extr_r1 << (16);                                   \
867d5de7839SBastian Koppelmann                                                               \
868d5de7839SBastian Koppelmann     return ret;                                               \
869d5de7839SBastian Koppelmann }                                                             \
870d5de7839SBastian Koppelmann 
871d5de7839SBastian Koppelmann EXTREMA_H_B(max, >)
872d5de7839SBastian Koppelmann EXTREMA_H_B(min, <)
873d5de7839SBastian Koppelmann 
874d5de7839SBastian Koppelmann #undef EXTREMA_H_B
875d5de7839SBastian Koppelmann 
8760b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1)
8770b79a781SBastian Koppelmann {
8780b79a781SBastian Koppelmann     return clo32(r1);
8790b79a781SBastian Koppelmann }
8800b79a781SBastian Koppelmann 
8810b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1)
8820b79a781SBastian Koppelmann {
8830b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
8840b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
8850b79a781SBastian Koppelmann 
8860b79a781SBastian Koppelmann     ret_hw0 = clo32(ret_hw0 << 16);
8870b79a781SBastian Koppelmann     ret_hw1 = clo32(ret_hw1 << 16);
8880b79a781SBastian Koppelmann 
8890b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
8900b79a781SBastian Koppelmann         ret_hw0 = 16;
8910b79a781SBastian Koppelmann     }
8920b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
8930b79a781SBastian Koppelmann         ret_hw1 = 16;
8940b79a781SBastian Koppelmann     }
8950b79a781SBastian Koppelmann 
8960b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
8970b79a781SBastian Koppelmann }
8980b79a781SBastian Koppelmann 
8990b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1)
9000b79a781SBastian Koppelmann {
9010b79a781SBastian Koppelmann     return clz32(r1);
9020b79a781SBastian Koppelmann }
9030b79a781SBastian Koppelmann 
9040b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1)
9050b79a781SBastian Koppelmann {
9060b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
9070b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
9080b79a781SBastian Koppelmann 
9090b79a781SBastian Koppelmann     ret_hw0 = clz32(ret_hw0 << 16);
9100b79a781SBastian Koppelmann     ret_hw1 = clz32(ret_hw1 << 16);
9110b79a781SBastian Koppelmann 
9120b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
9130b79a781SBastian Koppelmann         ret_hw0 = 16;
9140b79a781SBastian Koppelmann     }
9150b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
9160b79a781SBastian Koppelmann         ret_hw1 = 16;
9170b79a781SBastian Koppelmann     }
9180b79a781SBastian Koppelmann 
9190b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
9200b79a781SBastian Koppelmann }
9210b79a781SBastian Koppelmann 
9220b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1)
9230b79a781SBastian Koppelmann {
9240b79a781SBastian Koppelmann     return clrsb32(r1);
9250b79a781SBastian Koppelmann }
9260b79a781SBastian Koppelmann 
9270b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1)
9280b79a781SBastian Koppelmann {
9290b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
9300b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
9310b79a781SBastian Koppelmann 
9320b79a781SBastian Koppelmann     ret_hw0 = clrsb32(ret_hw0 << 16);
9330b79a781SBastian Koppelmann     ret_hw1 = clrsb32(ret_hw1 << 16);
9340b79a781SBastian Koppelmann 
9350b79a781SBastian Koppelmann     if (ret_hw0 > 15) {
9360b79a781SBastian Koppelmann         ret_hw0 = 15;
9370b79a781SBastian Koppelmann     }
9380b79a781SBastian Koppelmann     if (ret_hw1 > 15) {
9390b79a781SBastian Koppelmann         ret_hw1 = 15;
9400b79a781SBastian Koppelmann     }
9410b79a781SBastian Koppelmann 
9420b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
9430b79a781SBastian Koppelmann }
9440b79a781SBastian Koppelmann 
9450b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2)
9460b79a781SBastian Koppelmann {
9470b79a781SBastian Koppelmann     int32_t shift_count = sextract32(r2, 0, 6);
9480b79a781SBastian Koppelmann 
9490b79a781SBastian Koppelmann     if (shift_count == -32) {
9500b79a781SBastian Koppelmann         return 0;
9510b79a781SBastian Koppelmann     } else if (shift_count < 0) {
9520b79a781SBastian Koppelmann         return r1 >> -shift_count;
9530b79a781SBastian Koppelmann     } else {
9540b79a781SBastian Koppelmann         return r1 << shift_count;
9550b79a781SBastian Koppelmann     }
9560b79a781SBastian Koppelmann }
9570b79a781SBastian Koppelmann 
9580b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
9590b79a781SBastian Koppelmann {
9600b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
9610b79a781SBastian Koppelmann     int32_t shift_count;
9620b79a781SBastian Koppelmann 
9630b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
9640b79a781SBastian Koppelmann 
9650b79a781SBastian Koppelmann     if (shift_count == -16) {
9660b79a781SBastian Koppelmann         return 0;
9670b79a781SBastian Koppelmann     } else if (shift_count < 0) {
9680b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
9690b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
9700b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
9710b79a781SBastian Koppelmann     } else {
9720b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) << shift_count;
9730b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) << shift_count;
9740b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
9750b79a781SBastian Koppelmann     }
9760b79a781SBastian Koppelmann }
9770b79a781SBastian Koppelmann 
9780b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
9790b79a781SBastian Koppelmann {
9800b79a781SBastian Koppelmann     int32_t shift_count;
9810b79a781SBastian Koppelmann     int64_t result, t1;
9820b79a781SBastian Koppelmann     uint32_t ret;
9830b79a781SBastian Koppelmann 
9840b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 6);
9850b79a781SBastian Koppelmann     t1 = sextract32(r1, 0, 32);
9860b79a781SBastian Koppelmann 
9870b79a781SBastian Koppelmann     if (shift_count == 0) {
9880b79a781SBastian Koppelmann         env->PSW_USB_C = env->PSW_USB_V = 0;
9890b79a781SBastian Koppelmann         ret = r1;
9900b79a781SBastian Koppelmann     } else if (shift_count == -32) {
9910b79a781SBastian Koppelmann         env->PSW_USB_C = r1;
9920b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
9930b79a781SBastian Koppelmann         ret = t1 >> 31;
9940b79a781SBastian Koppelmann     } else if (shift_count > 0) {
9950b79a781SBastian Koppelmann         result = t1 << shift_count;
9960b79a781SBastian Koppelmann         /* calc carry */
9970b79a781SBastian Koppelmann         env->PSW_USB_C = ((result & 0xffffffff00000000) != 0);
9980b79a781SBastian Koppelmann         /* calc v */
9990b79a781SBastian Koppelmann         env->PSW_USB_V = (((result > 0x7fffffffLL) ||
10000b79a781SBastian Koppelmann                            (result < -0x80000000LL)) << 31);
10010b79a781SBastian Koppelmann         /* calc sv */
10020b79a781SBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
10030b79a781SBastian Koppelmann         ret = (uint32_t)result;
10040b79a781SBastian Koppelmann     } else {
10050b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
10060b79a781SBastian Koppelmann         env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
10070b79a781SBastian Koppelmann         ret = t1 >> -shift_count;
10080b79a781SBastian Koppelmann     }
10090b79a781SBastian Koppelmann 
10100b79a781SBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
10110b79a781SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
10120b79a781SBastian Koppelmann 
10130b79a781SBastian Koppelmann     return ret;
10140b79a781SBastian Koppelmann }
10150b79a781SBastian Koppelmann 
10160b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
10170b79a781SBastian Koppelmann {
10180b79a781SBastian Koppelmann     int32_t shift_count;
10190b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
10200b79a781SBastian Koppelmann 
10210b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
10220b79a781SBastian Koppelmann 
10230b79a781SBastian Koppelmann     if (shift_count == 0) {
10240b79a781SBastian Koppelmann         return r1;
10250b79a781SBastian Koppelmann     } else if (shift_count < 0) {
10260b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
10270b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
10280b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
10290b79a781SBastian Koppelmann     } else {
10300b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) << shift_count;
10310b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) << shift_count;
10320b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
10330b79a781SBastian Koppelmann     }
10340b79a781SBastian Koppelmann }
10350b79a781SBastian Koppelmann 
10369a31922bSBastian Koppelmann /* context save area (CSA) related helpers */
10379a31922bSBastian Koppelmann 
10389a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw)
10399a31922bSBastian Koppelmann {
10409a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
10419a31922bSBastian Koppelmann         return 0;
10429a31922bSBastian Koppelmann     }
10439a31922bSBastian Koppelmann 
10449a31922bSBastian Koppelmann     (*psw)++;
10459a31922bSBastian Koppelmann     /* check for overflow */
10469a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
10479a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
10489a31922bSBastian Koppelmann     int count = *psw & mask;
10499a31922bSBastian Koppelmann     if (count == 0) {
10509a31922bSBastian Koppelmann         (*psw)--;
10519a31922bSBastian Koppelmann         return 1;
10529a31922bSBastian Koppelmann     }
10539a31922bSBastian Koppelmann     return 0;
10549a31922bSBastian Koppelmann }
10559a31922bSBastian Koppelmann 
10569a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw)
10579a31922bSBastian Koppelmann {
10589a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
10599a31922bSBastian Koppelmann         return 0;
10609a31922bSBastian Koppelmann     }
10619a31922bSBastian Koppelmann     /* check for underflow */
10629a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
10639a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
10649a31922bSBastian Koppelmann     int count = *psw & mask;
10659a31922bSBastian Koppelmann     if (count == 0) {
10669a31922bSBastian Koppelmann         return 1;
10679a31922bSBastian Koppelmann     }
10689a31922bSBastian Koppelmann     (*psw)--;
10699a31922bSBastian Koppelmann     return 0;
10709a31922bSBastian Koppelmann }
10719a31922bSBastian Koppelmann 
107244ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw)
107344ea3430SBastian Koppelmann {
107444ea3430SBastian Koppelmann     int cdc = *psw & MASK_PSW_CDC;
107544ea3430SBastian Koppelmann     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
107644ea3430SBastian Koppelmann        7'b1111111, otherwise returns FALSE. */
107744ea3430SBastian Koppelmann     if (cdc == 0x7f) {
107844ea3430SBastian Koppelmann         return true;
107944ea3430SBastian Koppelmann     }
108044ea3430SBastian Koppelmann     /* find CDC.COUNT */
108144ea3430SBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
108244ea3430SBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
108344ea3430SBastian Koppelmann     int count = *psw & mask;
108444ea3430SBastian Koppelmann     return count == 0;
108544ea3430SBastian Koppelmann }
108644ea3430SBastian Koppelmann 
1087030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea)
10889a31922bSBastian Koppelmann {
10899a31922bSBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
10909a31922bSBastian Koppelmann     cpu_stl_data(env, ea+4, env->PSW);
10919a31922bSBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[10]);
10929a31922bSBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[11]);
10939a31922bSBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[8]);
10949a31922bSBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[9]);
10959a31922bSBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[10]);
10969a31922bSBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[11]);
10979a31922bSBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[12]);
10989a31922bSBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[13]);
10999a31922bSBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[14]);
11009a31922bSBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[15]);
11019a31922bSBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[12]);
11029a31922bSBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[13]);
11039a31922bSBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[14]);
11049a31922bSBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[15]);
11059a31922bSBastian Koppelmann }
11069a31922bSBastian Koppelmann 
1107030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea)
11085de93515SBastian Koppelmann {
11095de93515SBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
1110030c58dfSBastian Koppelmann     cpu_stl_data(env, ea+4, env->gpr_a[11]);
11115de93515SBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[2]);
11125de93515SBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[3]);
11135de93515SBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[0]);
11145de93515SBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[1]);
11155de93515SBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[2]);
11165de93515SBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[3]);
11175de93515SBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[4]);
11185de93515SBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[5]);
11195de93515SBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[6]);
11205de93515SBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[7]);
11215de93515SBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[4]);
11225de93515SBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[5]);
11235de93515SBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[6]);
11245de93515SBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[7]);
11255de93515SBastian Koppelmann }
11265de93515SBastian Koppelmann 
11279a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea,
11289a31922bSBastian Koppelmann                                   target_ulong *new_PCXI, target_ulong *new_PSW)
11299a31922bSBastian Koppelmann {
11309a31922bSBastian Koppelmann     *new_PCXI = cpu_ldl_data(env, ea);
11319a31922bSBastian Koppelmann     *new_PSW = cpu_ldl_data(env, ea+4);
11329a31922bSBastian Koppelmann     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
11339a31922bSBastian Koppelmann     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
11349a31922bSBastian Koppelmann     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
11359a31922bSBastian Koppelmann     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
11369a31922bSBastian Koppelmann     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
11379a31922bSBastian Koppelmann     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
11389a31922bSBastian Koppelmann     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
11399a31922bSBastian Koppelmann     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
11409a31922bSBastian Koppelmann     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
11419a31922bSBastian Koppelmann     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
11429a31922bSBastian Koppelmann     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
11439a31922bSBastian Koppelmann     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
11449a31922bSBastian Koppelmann     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
11459a31922bSBastian Koppelmann     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
11469a31922bSBastian Koppelmann }
11479a31922bSBastian Koppelmann 
114859543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea,
114959543d4eSBastian Koppelmann                                   target_ulong *ra, target_ulong *pcxi)
115059543d4eSBastian Koppelmann {
115159543d4eSBastian Koppelmann     *pcxi = cpu_ldl_data(env, ea);
115259543d4eSBastian Koppelmann     *ra = cpu_ldl_data(env, ea+4);
115359543d4eSBastian Koppelmann     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
115459543d4eSBastian Koppelmann     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
115559543d4eSBastian Koppelmann     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
115659543d4eSBastian Koppelmann     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
115759543d4eSBastian Koppelmann     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
115859543d4eSBastian Koppelmann     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
115959543d4eSBastian Koppelmann     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
116059543d4eSBastian Koppelmann     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
116159543d4eSBastian Koppelmann     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
116259543d4eSBastian Koppelmann     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
116359543d4eSBastian Koppelmann     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
116459543d4eSBastian Koppelmann     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
116559543d4eSBastian Koppelmann     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
116659543d4eSBastian Koppelmann     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
116759543d4eSBastian Koppelmann }
116859543d4eSBastian Koppelmann 
11699a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc)
11709a31922bSBastian Koppelmann {
11719a31922bSBastian Koppelmann     target_ulong tmp_FCX;
11729a31922bSBastian Koppelmann     target_ulong ea;
11739a31922bSBastian Koppelmann     target_ulong new_FCX;
11749a31922bSBastian Koppelmann     target_ulong psw;
11759a31922bSBastian Koppelmann 
11769a31922bSBastian Koppelmann     psw = psw_read(env);
11779a31922bSBastian Koppelmann     /* if (FCX == 0) trap(FCU); */
11789a31922bSBastian Koppelmann     if (env->FCX == 0) {
11799a31922bSBastian Koppelmann         /* FCU trap */
11809a31922bSBastian Koppelmann     }
11819a31922bSBastian Koppelmann     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
11829a31922bSBastian Koppelmann     if (psw & MASK_PSW_CDE) {
11839a31922bSBastian Koppelmann         if (cdc_increment(&psw)) {
11849a31922bSBastian Koppelmann             /* CDO trap */
11859a31922bSBastian Koppelmann         }
11869a31922bSBastian Koppelmann     }
11879a31922bSBastian Koppelmann     /* PSW.CDE = 1;*/
11889a31922bSBastian Koppelmann     psw |= MASK_PSW_CDE;
11899a31922bSBastian Koppelmann     /* tmp_FCX = FCX; */
11909a31922bSBastian Koppelmann     tmp_FCX = env->FCX;
11919a31922bSBastian Koppelmann     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
11929a31922bSBastian Koppelmann     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
11939a31922bSBastian Koppelmann          ((env->FCX & MASK_FCX_FCXO) << 6);
1194030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
1195030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
1196030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
11979a31922bSBastian Koppelmann                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
11989a31922bSBastian Koppelmann                            D[15]}; */
1199030c58dfSBastian Koppelmann     save_context_upper(env, ea);
12009a31922bSBastian Koppelmann 
12019a31922bSBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN; */
12029a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
12039a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_CCPN) << 24);
12049a31922bSBastian Koppelmann     /* PCXI.PIE = ICR.IE; */
12059a31922bSBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
12069a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_IE) << 15));
12079a31922bSBastian Koppelmann     /* PCXI.UL = 1; */
12089a31922bSBastian Koppelmann     env->PCXI |= MASK_PCXI_UL;
12099a31922bSBastian Koppelmann 
12109a31922bSBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0]; */
12119a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
12129a31922bSBastian Koppelmann     /* FCX[19: 0] = new_FCX[19: 0]; */
12139a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
12149a31922bSBastian Koppelmann     /* A[11] = next_pc[31: 0]; */
12159a31922bSBastian Koppelmann     env->gpr_a[11] = next_pc;
12169a31922bSBastian Koppelmann 
12179a31922bSBastian Koppelmann     /* if (tmp_FCX == LCX) trap(FCD);*/
12189a31922bSBastian Koppelmann     if (tmp_FCX == env->LCX) {
12199a31922bSBastian Koppelmann         /* FCD trap */
12209a31922bSBastian Koppelmann     }
12219a31922bSBastian Koppelmann     psw_write(env, psw);
12229a31922bSBastian Koppelmann }
12239a31922bSBastian Koppelmann 
12249a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env)
12259a31922bSBastian Koppelmann {
12269a31922bSBastian Koppelmann     target_ulong ea;
12279a31922bSBastian Koppelmann     target_ulong new_PCXI;
12289a31922bSBastian Koppelmann     target_ulong new_PSW, psw;
12299a31922bSBastian Koppelmann 
12309a31922bSBastian Koppelmann     psw = psw_read(env);
12319a31922bSBastian Koppelmann      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
12329a31922bSBastian Koppelmann     if (env->PSW & MASK_PSW_CDE) {
12339a31922bSBastian Koppelmann         if (cdc_decrement(&(env->PSW))) {
12349a31922bSBastian Koppelmann             /* CDU trap */
12359a31922bSBastian Koppelmann         }
12369a31922bSBastian Koppelmann     }
12379a31922bSBastian Koppelmann     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
12389a31922bSBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
12399a31922bSBastian Koppelmann         /* CSU trap */
12409a31922bSBastian Koppelmann     }
12419a31922bSBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
12429a31922bSBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
12439a31922bSBastian Koppelmann         /* CTYP trap */
12449a31922bSBastian Koppelmann     }
12459a31922bSBastian Koppelmann     /* PC = {A11 [31: 1], 1’b0}; */
12469a31922bSBastian Koppelmann     env->PC = env->gpr_a[11] & 0xfffffffe;
12479a31922bSBastian Koppelmann 
12489a31922bSBastian Koppelmann     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
12499a31922bSBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
12509a31922bSBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
12519a31922bSBastian Koppelmann     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
1252030c58dfSBastian Koppelmann         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
12539a31922bSBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
1254030c58dfSBastian Koppelmann     /* M(EA, word) = FCX; */
1255030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
12569a31922bSBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
12579a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
12589a31922bSBastian Koppelmann     /* PCXI = new_PCXI; */
12599a31922bSBastian Koppelmann     env->PCXI = new_PCXI;
12609a31922bSBastian Koppelmann 
12619a31922bSBastian Koppelmann     if (tricore_feature(env, TRICORE_FEATURE_13)) {
12629a31922bSBastian Koppelmann         /* PSW = new_PSW */
12639a31922bSBastian Koppelmann         psw_write(env, new_PSW);
12649a31922bSBastian Koppelmann     } else {
12659a31922bSBastian Koppelmann         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
12669a31922bSBastian Koppelmann         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
12679a31922bSBastian Koppelmann     }
12689a31922bSBastian Koppelmann }
12699a31922bSBastian Koppelmann 
12705de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9)
12715de93515SBastian Koppelmann {
12725de93515SBastian Koppelmann     target_ulong tmp_FCX;
12735de93515SBastian Koppelmann     target_ulong ea;
12745de93515SBastian Koppelmann     target_ulong new_FCX;
12755de93515SBastian Koppelmann 
12765de93515SBastian Koppelmann     if (env->FCX == 0) {
12775de93515SBastian Koppelmann         /* FCU trap */
12785de93515SBastian Koppelmann     }
12795de93515SBastian Koppelmann 
12805de93515SBastian Koppelmann     tmp_FCX = env->FCX;
12815de93515SBastian Koppelmann     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
12825de93515SBastian Koppelmann 
1283030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
1284030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
1285030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
1286030c58dfSBastian Koppelmann                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
1287030c58dfSBastian Koppelmann     save_context_lower(env, ea);
1288030c58dfSBastian Koppelmann 
12895de93515SBastian Koppelmann 
12905de93515SBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN */
12915de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
12925de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_CCPN) << 24);
12935de93515SBastian Koppelmann     /* PCXI.PIE  = ICR.IE */
12945de93515SBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
12955de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_IE) << 15));
12965de93515SBastian Koppelmann     /* PCXI.UL = 0 */
12975de93515SBastian Koppelmann     env->PCXI &= ~(MASK_PCXI_UL);
12985de93515SBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0] */
12995de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
13005de93515SBastian Koppelmann     /* FXC[19: 0] = new_FCX[19: 0] */
13015de93515SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
13025de93515SBastian Koppelmann     /* ICR.IE = 1 */
13035de93515SBastian Koppelmann     env->ICR |= MASK_ICR_IE;
13045de93515SBastian Koppelmann 
13055de93515SBastian Koppelmann     env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
13065de93515SBastian Koppelmann 
13075de93515SBastian Koppelmann     if (tmp_FCX == env->LCX) {
13085de93515SBastian Koppelmann         /* FCD trap */
13095de93515SBastian Koppelmann     }
13105de93515SBastian Koppelmann }
13115de93515SBastian Koppelmann 
131244ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env)
131344ea3430SBastian Koppelmann {
131444ea3430SBastian Koppelmann     target_ulong ea;
131544ea3430SBastian Koppelmann     target_ulong new_PCXI;
131644ea3430SBastian Koppelmann     target_ulong new_PSW;
131744ea3430SBastian Koppelmann     /* if (PCXI[19: 0] == 0) then trap(CSU); */
131844ea3430SBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
131944ea3430SBastian Koppelmann         /* raise csu trap */
132044ea3430SBastian Koppelmann     }
132144ea3430SBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
132244ea3430SBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
132344ea3430SBastian Koppelmann         /* raise CTYP trap */
132444ea3430SBastian Koppelmann     }
132544ea3430SBastian Koppelmann     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
132644ea3430SBastian Koppelmann     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
132744ea3430SBastian Koppelmann         /* raise MNG trap */
132844ea3430SBastian Koppelmann     }
132944ea3430SBastian Koppelmann     /* ICR.IE = PCXI.PIE; */
133044ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
133144ea3430SBastian Koppelmann     /* ICR.CCPN = PCXI.PCPN; */
133244ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
133344ea3430SBastian Koppelmann                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
133444ea3430SBastian Koppelmann     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
133544ea3430SBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
133644ea3430SBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
133744ea3430SBastian Koppelmann     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
1338030c58dfSBastian Koppelmann       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
133944ea3430SBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
1340030c58dfSBastian Koppelmann     /* M(EA, word) = FCX;*/
1341030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
134244ea3430SBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
134344ea3430SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
134444ea3430SBastian Koppelmann     /* PCXI = new_PCXI; */
134544ea3430SBastian Koppelmann     env->PCXI = new_PCXI;
134644ea3430SBastian Koppelmann     /* write psw */
134744ea3430SBastian Koppelmann     psw_write(env, new_PSW);
134844ea3430SBastian Koppelmann }
134944ea3430SBastian Koppelmann 
135059543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
135159543d4eSBastian Koppelmann {
135259543d4eSBastian Koppelmann     uint32_t dummy;
135359543d4eSBastian Koppelmann     /* insn doesn't load PCXI and RA */
135459543d4eSBastian Koppelmann     restore_context_lower(env, ea, &dummy, &dummy);
135559543d4eSBastian Koppelmann }
135659543d4eSBastian Koppelmann 
135759543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea)
135859543d4eSBastian Koppelmann {
135959543d4eSBastian Koppelmann     uint32_t dummy;
136059543d4eSBastian Koppelmann     /* insn doesn't load PCXI and PSW */
136159543d4eSBastian Koppelmann     restore_context_upper(env, ea, &dummy, &dummy);
136259543d4eSBastian Koppelmann }
136359543d4eSBastian Koppelmann 
136459543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
136559543d4eSBastian Koppelmann {
136659543d4eSBastian Koppelmann     save_context_lower(env, ea);
136759543d4eSBastian Koppelmann }
136859543d4eSBastian Koppelmann 
136959543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea)
137059543d4eSBastian Koppelmann {
137159543d4eSBastian Koppelmann     save_context_upper(env, ea);
137259543d4eSBastian Koppelmann }
137359543d4eSBastian Koppelmann 
13742b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
13752b2f7d97SBastian Koppelmann {
13762b2f7d97SBastian Koppelmann     psw_write(env, arg);
13772b2f7d97SBastian Koppelmann }
13782b2f7d97SBastian Koppelmann 
13792b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env)
13802b2f7d97SBastian Koppelmann {
13812b2f7d97SBastian Koppelmann     return psw_read(env);
13822b2f7d97SBastian Koppelmann }
13832b2f7d97SBastian Koppelmann 
13842b2f7d97SBastian Koppelmann 
13852d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
13862d30267eSBastian Koppelmann                                                         uint32_t exception,
13872d30267eSBastian Koppelmann                                                         int error_code,
13882d30267eSBastian Koppelmann                                                         uintptr_t pc)
13892d30267eSBastian Koppelmann {
13902d30267eSBastian Koppelmann     CPUState *cs = CPU(tricore_env_get_cpu(env));
13912d30267eSBastian Koppelmann     cs->exception_index = exception;
13922d30267eSBastian Koppelmann     env->error_code = error_code;
13932d30267eSBastian Koppelmann 
13942d30267eSBastian Koppelmann     if (pc) {
13952d30267eSBastian Koppelmann         /* now we have a real cpu fault */
13962d30267eSBastian Koppelmann         cpu_restore_state(cs, pc);
13972d30267eSBastian Koppelmann     }
13982d30267eSBastian Koppelmann 
13992d30267eSBastian Koppelmann     cpu_loop_exit(cs);
14002d30267eSBastian Koppelmann }
14012d30267eSBastian Koppelmann 
140248e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
140348e06fe0SBastian Koppelmann               uintptr_t retaddr)
140448e06fe0SBastian Koppelmann {
14052d30267eSBastian Koppelmann     int ret;
14062d30267eSBastian Koppelmann     ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
14072d30267eSBastian Koppelmann     if (ret) {
14082d30267eSBastian Koppelmann         TriCoreCPU *cpu = TRICORE_CPU(cs);
14092d30267eSBastian Koppelmann         CPUTriCoreState *env = &cpu->env;
14102d30267eSBastian Koppelmann         do_raise_exception_err(env, cs->exception_index,
14112d30267eSBastian Koppelmann                                env->error_code, retaddr);
141248e06fe0SBastian Koppelmann     }
14132d30267eSBastian Koppelmann }
1414