xref: /qemu/target/tricore/op_helper.c (revision f69c24e4584f2161f90ee7caba38728aa77f937f)
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 
8385d604afSBastian Koppelmann static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg)
84e4e39176SBastian Koppelmann {
85e4e39176SBastian Koppelmann     uint32_t ret;
8685d604afSBastian Koppelmann     uint64_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 {
9285d604afSBastian Koppelmann         env->PSW_USB_V = 0;
9385d604afSBastian Koppelmann         ret = (target_ulong)arg;
9485d604afSBastian Koppelmann      }
9585d604afSBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
9685d604afSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
9785d604afSBastian Koppelmann     return ret;
9885d604afSBastian Koppelmann }
9985d604afSBastian Koppelmann 
10085d604afSBastian Koppelmann static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg)
10185d604afSBastian Koppelmann {
10285d604afSBastian Koppelmann     uint32_t ret;
10385d604afSBastian Koppelmann 
104e4e39176SBastian Koppelmann     if (arg < 0) {
105e4e39176SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
106e4e39176SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
107e4e39176SBastian Koppelmann         ret = 0;
108e4e39176SBastian Koppelmann     } else {
109e4e39176SBastian Koppelmann         env->PSW_USB_V = 0;
110e4e39176SBastian Koppelmann         ret = (target_ulong)arg;
111e4e39176SBastian Koppelmann     }
112e4e39176SBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
113e4e39176SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
114e4e39176SBastian Koppelmann     return ret;
115e4e39176SBastian Koppelmann }
1160974257eSBastian Koppelmann 
117d5de7839SBastian Koppelmann static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
118d5de7839SBastian Koppelmann {
119d5de7839SBastian Koppelmann     int32_t max_pos = INT16_MAX;
120d5de7839SBastian Koppelmann     int32_t max_neg = INT16_MIN;
121d5de7839SBastian Koppelmann     int32_t av0, av1;
122d5de7839SBastian Koppelmann 
123d5de7839SBastian Koppelmann     env->PSW_USB_V = 0;
124d5de7839SBastian Koppelmann     av0 = hw0 ^ hw0 * 2u;
125d5de7839SBastian Koppelmann     if (hw0 > max_pos) {
126d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
127d5de7839SBastian Koppelmann         hw0 = max_pos;
128d5de7839SBastian Koppelmann     } else if (hw0 < max_neg) {
129d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
130d5de7839SBastian Koppelmann         hw0 = max_neg;
131d5de7839SBastian Koppelmann     }
132d5de7839SBastian Koppelmann 
133d5de7839SBastian Koppelmann     av1 = hw1 ^ hw1 * 2u;
134d5de7839SBastian Koppelmann     if (hw1 > max_pos) {
135d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
136d5de7839SBastian Koppelmann         hw1 = max_pos;
137d5de7839SBastian Koppelmann     } else if (hw1 < max_neg) {
138d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
139d5de7839SBastian Koppelmann         hw1 = max_neg;
140d5de7839SBastian Koppelmann     }
141d5de7839SBastian Koppelmann 
142d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
143d5de7839SBastian Koppelmann     env->PSW_USB_AV = (av0 | av1) << 16;
144d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
145d5de7839SBastian Koppelmann     return (hw0 & 0xffff) | (hw1 << 16);
146d5de7839SBastian Koppelmann }
147d5de7839SBastian Koppelmann 
148d5de7839SBastian Koppelmann static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
149d5de7839SBastian Koppelmann {
150d5de7839SBastian Koppelmann     int32_t max_pos = UINT16_MAX;
151d5de7839SBastian Koppelmann     int32_t av0, av1;
152d5de7839SBastian Koppelmann 
153d5de7839SBastian Koppelmann     env->PSW_USB_V = 0;
154d5de7839SBastian Koppelmann     av0 = hw0 ^ hw0 * 2u;
155d5de7839SBastian Koppelmann     if (hw0 > max_pos) {
156d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
157d5de7839SBastian Koppelmann         hw0 = max_pos;
158d5de7839SBastian Koppelmann     } else if (hw0 < 0) {
159d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
160d5de7839SBastian Koppelmann         hw0 = 0;
161d5de7839SBastian Koppelmann     }
162d5de7839SBastian Koppelmann 
163d5de7839SBastian Koppelmann     av1 = hw1 ^ hw1 * 2u;
164d5de7839SBastian Koppelmann     if (hw1 > max_pos) {
165d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
166d5de7839SBastian Koppelmann         hw1 = max_pos;
167d5de7839SBastian Koppelmann     } else if (hw1 < 0) {
168d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
169d5de7839SBastian Koppelmann         hw1 = 0;
170d5de7839SBastian Koppelmann     }
171d5de7839SBastian Koppelmann 
172d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
173d5de7839SBastian Koppelmann     env->PSW_USB_AV = (av0 | av1) << 16;
174d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
175d5de7839SBastian Koppelmann     return (hw0 & 0xffff) | (hw1 << 16);
176d5de7839SBastian Koppelmann }
1770974257eSBastian Koppelmann 
1782692802aSBastian Koppelmann target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
1792692802aSBastian Koppelmann                              target_ulong r2)
1802692802aSBastian Koppelmann {
1812692802aSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
1822692802aSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
1832692802aSBastian Koppelmann     int64_t result = t1 + t2;
184e4e39176SBastian Koppelmann     return ssov32(env, result);
1852692802aSBastian Koppelmann }
1862692802aSBastian Koppelmann 
1872e430e1cSBastian Koppelmann uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
1882e430e1cSBastian Koppelmann {
1892e430e1cSBastian Koppelmann     uint64_t result;
1902e430e1cSBastian Koppelmann     int64_t ovf;
1912e430e1cSBastian Koppelmann 
1922e430e1cSBastian Koppelmann     result = r1 + r2;
1932e430e1cSBastian Koppelmann     ovf = (result ^ r1) & ~(r1 ^ r2);
1942e430e1cSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
1952e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1962e430e1cSBastian Koppelmann     if (ovf < 0) {
1972e430e1cSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
1982e430e1cSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
1992e430e1cSBastian Koppelmann         /* ext_ret > MAX_INT */
2002e430e1cSBastian Koppelmann         if ((int64_t)r1 >= 0) {
2012e430e1cSBastian Koppelmann             result = INT64_MAX;
2022e430e1cSBastian Koppelmann         /* ext_ret < MIN_INT */
2032e430e1cSBastian Koppelmann         } else {
2042e430e1cSBastian Koppelmann             result = INT64_MIN;
2052e430e1cSBastian Koppelmann         }
2062e430e1cSBastian Koppelmann     } else {
2072e430e1cSBastian Koppelmann         env->PSW_USB_V = 0;
2082e430e1cSBastian Koppelmann     }
2092e430e1cSBastian Koppelmann     return result;
2102e430e1cSBastian Koppelmann }
2112e430e1cSBastian Koppelmann 
212d5de7839SBastian Koppelmann target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
213d5de7839SBastian Koppelmann                                target_ulong r2)
214d5de7839SBastian Koppelmann {
215d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
216d5de7839SBastian Koppelmann 
217d5de7839SBastian Koppelmann     ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16);
218d5de7839SBastian Koppelmann     ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16);
219d5de7839SBastian Koppelmann     return ssov16(env, ret_hw0, ret_hw1);
220d5de7839SBastian Koppelmann }
221d5de7839SBastian Koppelmann 
2222e430e1cSBastian Koppelmann uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
2232e430e1cSBastian Koppelmann                             uint32_t r2_h)
2242e430e1cSBastian Koppelmann {
2252e430e1cSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
2262e430e1cSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
2272e430e1cSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
2282e430e1cSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
2292e430e1cSBastian Koppelmann     int64_t result0, result1;
2302e430e1cSBastian Koppelmann     uint32_t ovf0, ovf1;
2312e430e1cSBastian Koppelmann     uint32_t avf0, avf1;
2322e430e1cSBastian Koppelmann 
2332e430e1cSBastian Koppelmann     ovf0 = ovf1 = 0;
2342e430e1cSBastian Koppelmann 
2352e430e1cSBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
2362e430e1cSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
2372e430e1cSBastian Koppelmann 
2382e430e1cSBastian Koppelmann     avf0 = result0 * 2u;
2392e430e1cSBastian Koppelmann     avf0 = result0 ^ avf0;
2402e430e1cSBastian Koppelmann     avf1 = result1 * 2u;
2412e430e1cSBastian Koppelmann     avf1 = result1 ^ avf1;
2422e430e1cSBastian Koppelmann 
2432e430e1cSBastian Koppelmann     if (result0 > INT32_MAX) {
2442e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
2452e430e1cSBastian Koppelmann         result0 = INT32_MAX;
2462e430e1cSBastian Koppelmann     } else if (result0 < INT32_MIN) {
2472e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
2482e430e1cSBastian Koppelmann         result0 = INT32_MIN;
2492e430e1cSBastian Koppelmann     }
2502e430e1cSBastian Koppelmann 
2512e430e1cSBastian Koppelmann     if (result1 > INT32_MAX) {
2522e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
2532e430e1cSBastian Koppelmann         result1 = INT32_MAX;
2542e430e1cSBastian Koppelmann     } else if (result1 < INT32_MIN) {
2552e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
2562e430e1cSBastian Koppelmann         result1 = INT32_MIN;
2572e430e1cSBastian Koppelmann     }
2582e430e1cSBastian Koppelmann 
2592e430e1cSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
2602e430e1cSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
2612e430e1cSBastian Koppelmann 
2622e430e1cSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
2632e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
2642e430e1cSBastian Koppelmann 
2652e430e1cSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
2662e430e1cSBastian Koppelmann }
2672e430e1cSBastian Koppelmann 
268bebe80fcSBastian Koppelmann uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
269bebe80fcSBastian Koppelmann                               uint32_t r2_h)
270bebe80fcSBastian Koppelmann {
271bebe80fcSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
272bebe80fcSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
273bebe80fcSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
274bebe80fcSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
275bebe80fcSBastian Koppelmann     int64_t result0, result1;
276bebe80fcSBastian Koppelmann     uint32_t ovf0, ovf1;
277bebe80fcSBastian Koppelmann     uint32_t avf0, avf1;
278bebe80fcSBastian Koppelmann 
279bebe80fcSBastian Koppelmann     ovf0 = ovf1 = 0;
280bebe80fcSBastian Koppelmann 
281bebe80fcSBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
282bebe80fcSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
283bebe80fcSBastian Koppelmann 
284bebe80fcSBastian Koppelmann     avf0 = result0 * 2u;
285bebe80fcSBastian Koppelmann     avf0 = result0 ^ avf0;
286bebe80fcSBastian Koppelmann     avf1 = result1 * 2u;
287bebe80fcSBastian Koppelmann     avf1 = result1 ^ avf1;
288bebe80fcSBastian Koppelmann 
289bebe80fcSBastian Koppelmann     if (result0 > INT32_MAX) {
290bebe80fcSBastian Koppelmann         ovf0 = (1 << 31);
291bebe80fcSBastian Koppelmann         result0 = INT32_MAX;
292bebe80fcSBastian Koppelmann     } else if (result0 < INT32_MIN) {
293bebe80fcSBastian Koppelmann         ovf0 = (1 << 31);
294bebe80fcSBastian Koppelmann         result0 = INT32_MIN;
295bebe80fcSBastian Koppelmann     }
296bebe80fcSBastian Koppelmann 
297bebe80fcSBastian Koppelmann     if (result1 > INT32_MAX) {
298bebe80fcSBastian Koppelmann         ovf1 = (1 << 31);
299bebe80fcSBastian Koppelmann         result1 = INT32_MAX;
300bebe80fcSBastian Koppelmann     } else if (result1 < INT32_MIN) {
301bebe80fcSBastian Koppelmann         ovf1 = (1 << 31);
302bebe80fcSBastian Koppelmann         result1 = INT32_MIN;
303bebe80fcSBastian Koppelmann     }
304bebe80fcSBastian Koppelmann 
305bebe80fcSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
306bebe80fcSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
307bebe80fcSBastian Koppelmann 
308bebe80fcSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
309bebe80fcSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
310bebe80fcSBastian Koppelmann 
311bebe80fcSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
312bebe80fcSBastian Koppelmann }
313bebe80fcSBastian Koppelmann 
3142e430e1cSBastian Koppelmann 
3150974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
3160974257eSBastian Koppelmann                              target_ulong r2)
3170974257eSBastian Koppelmann {
3180974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
3190974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
3200974257eSBastian Koppelmann     int64_t result = t1 + t2;
32185d604afSBastian Koppelmann     return suov32_pos(env, result);
3220974257eSBastian Koppelmann }
3230974257eSBastian Koppelmann 
324d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
325d5de7839SBastian Koppelmann                                target_ulong r2)
326d5de7839SBastian Koppelmann {
327d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
328d5de7839SBastian Koppelmann 
329d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
330d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
331d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
332d5de7839SBastian Koppelmann }
333d5de7839SBastian Koppelmann 
3342692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
3352692802aSBastian Koppelmann                              target_ulong r2)
3362692802aSBastian Koppelmann {
3372692802aSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3382692802aSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
3392692802aSBastian Koppelmann     int64_t result = t1 - t2;
340e4e39176SBastian Koppelmann     return ssov32(env, result);
3412692802aSBastian Koppelmann }
3422692802aSBastian Koppelmann 
343f4aef476SBastian Koppelmann uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
344f4aef476SBastian Koppelmann {
345f4aef476SBastian Koppelmann     uint64_t result;
346f4aef476SBastian Koppelmann     int64_t ovf;
347f4aef476SBastian Koppelmann 
348f4aef476SBastian Koppelmann     result = r1 - r2;
349f4aef476SBastian Koppelmann     ovf = (result ^ r1) & (r1 ^ r2);
350f4aef476SBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
351f4aef476SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
352f4aef476SBastian Koppelmann     if (ovf < 0) {
353f4aef476SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
354f4aef476SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
355f4aef476SBastian Koppelmann         /* ext_ret > MAX_INT */
356f4aef476SBastian Koppelmann         if ((int64_t)r1 >= 0) {
357f4aef476SBastian Koppelmann             result = INT64_MAX;
358f4aef476SBastian Koppelmann         /* ext_ret < MIN_INT */
359f4aef476SBastian Koppelmann         } else {
360f4aef476SBastian Koppelmann             result = INT64_MIN;
361f4aef476SBastian Koppelmann         }
362f4aef476SBastian Koppelmann     } else {
363f4aef476SBastian Koppelmann         env->PSW_USB_V = 0;
364f4aef476SBastian Koppelmann     }
365f4aef476SBastian Koppelmann     return result;
366f4aef476SBastian Koppelmann }
367f4aef476SBastian Koppelmann 
368d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
369d5de7839SBastian Koppelmann                              target_ulong r2)
370d5de7839SBastian Koppelmann {
371d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
372d5de7839SBastian Koppelmann 
373d5de7839SBastian Koppelmann     ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
374d5de7839SBastian Koppelmann     ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
375d5de7839SBastian Koppelmann     return ssov16(env, ret_hw0, ret_hw1);
376d5de7839SBastian Koppelmann }
377d5de7839SBastian Koppelmann 
378f4aef476SBastian Koppelmann uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
379f4aef476SBastian Koppelmann                             uint32_t r2_h)
380f4aef476SBastian Koppelmann {
381f4aef476SBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
382f4aef476SBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
383f4aef476SBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
384f4aef476SBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
385f4aef476SBastian Koppelmann     int64_t result0, result1;
386f4aef476SBastian Koppelmann     uint32_t ovf0, ovf1;
387f4aef476SBastian Koppelmann     uint32_t avf0, avf1;
388f4aef476SBastian Koppelmann 
389f4aef476SBastian Koppelmann     ovf0 = ovf1 = 0;
390f4aef476SBastian Koppelmann 
391f4aef476SBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
392f4aef476SBastian Koppelmann     result1 = r2_high - mul_res1 + 0x8000;
393f4aef476SBastian Koppelmann 
394f4aef476SBastian Koppelmann     avf0 = result0 * 2u;
395f4aef476SBastian Koppelmann     avf0 = result0 ^ avf0;
396f4aef476SBastian Koppelmann     avf1 = result1 * 2u;
397f4aef476SBastian Koppelmann     avf1 = result1 ^ avf1;
398f4aef476SBastian Koppelmann 
399f4aef476SBastian Koppelmann     if (result0 > INT32_MAX) {
400f4aef476SBastian Koppelmann         ovf0 = (1 << 31);
401f4aef476SBastian Koppelmann         result0 = INT32_MAX;
402f4aef476SBastian Koppelmann     } else if (result0 < INT32_MIN) {
403f4aef476SBastian Koppelmann         ovf0 = (1 << 31);
404f4aef476SBastian Koppelmann         result0 = INT32_MIN;
405f4aef476SBastian Koppelmann     }
406f4aef476SBastian Koppelmann 
407f4aef476SBastian Koppelmann     if (result1 > INT32_MAX) {
408f4aef476SBastian Koppelmann         ovf1 = (1 << 31);
409f4aef476SBastian Koppelmann         result1 = INT32_MAX;
410f4aef476SBastian Koppelmann     } else if (result1 < INT32_MIN) {
411f4aef476SBastian Koppelmann         ovf1 = (1 << 31);
412f4aef476SBastian Koppelmann         result1 = INT32_MIN;
413f4aef476SBastian Koppelmann     }
414f4aef476SBastian Koppelmann 
415f4aef476SBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
416f4aef476SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
417f4aef476SBastian Koppelmann 
418f4aef476SBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
419f4aef476SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
420f4aef476SBastian Koppelmann 
421f4aef476SBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
422f4aef476SBastian Koppelmann }
423f4aef476SBastian Koppelmann 
424068fac77SBastian Koppelmann uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
425068fac77SBastian Koppelmann                               uint32_t r2_h)
426068fac77SBastian Koppelmann {
427068fac77SBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
428068fac77SBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
429068fac77SBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
430068fac77SBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
431068fac77SBastian Koppelmann     int64_t result0, result1;
432068fac77SBastian Koppelmann     uint32_t ovf0, ovf1;
433068fac77SBastian Koppelmann     uint32_t avf0, avf1;
434068fac77SBastian Koppelmann 
435068fac77SBastian Koppelmann     ovf0 = ovf1 = 0;
436068fac77SBastian Koppelmann 
437068fac77SBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
438068fac77SBastian Koppelmann     result1 = r2_high - mul_res1 + 0x8000;
439068fac77SBastian Koppelmann 
440068fac77SBastian Koppelmann     avf0 = result0 * 2u;
441068fac77SBastian Koppelmann     avf0 = result0 ^ avf0;
442068fac77SBastian Koppelmann     avf1 = result1 * 2u;
443068fac77SBastian Koppelmann     avf1 = result1 ^ avf1;
444068fac77SBastian Koppelmann 
445068fac77SBastian Koppelmann     if (result0 > INT32_MAX) {
446068fac77SBastian Koppelmann         ovf0 = (1 << 31);
447068fac77SBastian Koppelmann         result0 = INT32_MAX;
448068fac77SBastian Koppelmann     } else if (result0 < INT32_MIN) {
449068fac77SBastian Koppelmann         ovf0 = (1 << 31);
450068fac77SBastian Koppelmann         result0 = INT32_MIN;
451068fac77SBastian Koppelmann     }
452068fac77SBastian Koppelmann 
453068fac77SBastian Koppelmann     if (result1 > INT32_MAX) {
454068fac77SBastian Koppelmann         ovf1 = (1 << 31);
455068fac77SBastian Koppelmann         result1 = INT32_MAX;
456068fac77SBastian Koppelmann     } else if (result1 < INT32_MIN) {
457068fac77SBastian Koppelmann         ovf1 = (1 << 31);
458068fac77SBastian Koppelmann         result1 = INT32_MIN;
459068fac77SBastian Koppelmann     }
460068fac77SBastian Koppelmann 
461068fac77SBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
462068fac77SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
463068fac77SBastian Koppelmann 
464068fac77SBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
465068fac77SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
466068fac77SBastian Koppelmann 
467068fac77SBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
468068fac77SBastian Koppelmann }
469068fac77SBastian Koppelmann 
4700974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
4710974257eSBastian Koppelmann                              target_ulong r2)
4720974257eSBastian Koppelmann {
4730974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
4740974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
4750974257eSBastian Koppelmann     int64_t result = t1 - t2;
47685d604afSBastian Koppelmann     return suov32_neg(env, result);
4770974257eSBastian Koppelmann }
4780974257eSBastian Koppelmann 
479d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
480d5de7839SBastian Koppelmann                                target_ulong r2)
481d5de7839SBastian Koppelmann {
482d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
483d5de7839SBastian Koppelmann 
484d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
485d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
486d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
487d5de7839SBastian Koppelmann }
488d5de7839SBastian Koppelmann 
4890974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
4900974257eSBastian Koppelmann                              target_ulong r2)
4910974257eSBastian Koppelmann {
4920974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
4930974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
4940974257eSBastian Koppelmann     int64_t result = t1 * t2;
495e4e39176SBastian Koppelmann     return ssov32(env, result);
4960974257eSBastian Koppelmann }
4970974257eSBastian Koppelmann 
4980974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
4990974257eSBastian Koppelmann                              target_ulong r2)
5000974257eSBastian Koppelmann {
5010974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
5020974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
5030974257eSBastian Koppelmann     int64_t result = t1 * t2;
5045f30046fSBastian Koppelmann 
50585d604afSBastian Koppelmann     return suov32_pos(env, result);
5060974257eSBastian Koppelmann }
5070974257eSBastian Koppelmann 
5080974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
5090974257eSBastian Koppelmann                              target_ulong r2)
5100974257eSBastian Koppelmann {
5110974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
5120974257eSBastian Koppelmann     int32_t t2 = sextract64(r2, 0, 6);
5130974257eSBastian Koppelmann     int64_t result;
5140974257eSBastian Koppelmann     if (t2 == 0) {
5150974257eSBastian Koppelmann         result = t1;
5160974257eSBastian Koppelmann     } else if (t2 > 0) {
5170974257eSBastian Koppelmann         result = t1 << t2;
5180974257eSBastian Koppelmann     } else {
5190974257eSBastian Koppelmann         result = t1 >> -t2;
5200974257eSBastian Koppelmann     }
521e4e39176SBastian Koppelmann     return ssov32(env, result);
5220974257eSBastian Koppelmann }
5230974257eSBastian Koppelmann 
524d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
525d5de7839SBastian Koppelmann {
526d5de7839SBastian Koppelmann     target_ulong result;
527d5de7839SBastian Koppelmann     result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
528d5de7839SBastian Koppelmann     return ssov32(env, result);
529d5de7839SBastian Koppelmann }
530d5de7839SBastian Koppelmann 
531d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
532d5de7839SBastian Koppelmann {
533d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
534d5de7839SBastian Koppelmann 
535d5de7839SBastian Koppelmann     ret_h0 = sextract32(r1, 0, 16);
536d5de7839SBastian Koppelmann     ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
537d5de7839SBastian Koppelmann 
538d5de7839SBastian Koppelmann     ret_h1 = sextract32(r1, 16, 16);
539d5de7839SBastian Koppelmann     ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
540d5de7839SBastian Koppelmann 
541d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
542d5de7839SBastian Koppelmann }
543d5de7839SBastian Koppelmann 
5440974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
5450974257eSBastian Koppelmann                                 target_ulong r2)
5460974257eSBastian Koppelmann {
5470974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
5480974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
5490974257eSBastian Koppelmann     int64_t result;
5500974257eSBastian Koppelmann 
5510974257eSBastian Koppelmann     if (t1 > t2) {
5520974257eSBastian Koppelmann         result = t1 - t2;
5530974257eSBastian Koppelmann     } else {
5540974257eSBastian Koppelmann         result = t2 - t1;
5550974257eSBastian Koppelmann     }
556e4e39176SBastian Koppelmann     return ssov32(env, result);
5570974257eSBastian Koppelmann }
558328f1f0fSBastian Koppelmann 
559d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
560d5de7839SBastian Koppelmann                               target_ulong r2)
561d5de7839SBastian Koppelmann {
562d5de7839SBastian Koppelmann     int32_t t1, t2;
563d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
564d5de7839SBastian Koppelmann 
565d5de7839SBastian Koppelmann     t1 = sextract32(r1, 0, 16);
566d5de7839SBastian Koppelmann     t2 = sextract32(r2, 0, 16);
567d5de7839SBastian Koppelmann     if (t1 > t2) {
568d5de7839SBastian Koppelmann         ret_h0 = t1 - t2;
569d5de7839SBastian Koppelmann     } else {
570d5de7839SBastian Koppelmann         ret_h0 = t2 - t1;
571d5de7839SBastian Koppelmann     }
572d5de7839SBastian Koppelmann 
573d5de7839SBastian Koppelmann     t1 = sextract32(r1, 16, 16);
574d5de7839SBastian Koppelmann     t2 = sextract32(r2, 16, 16);
575d5de7839SBastian Koppelmann     if (t1 > t2) {
576d5de7839SBastian Koppelmann         ret_h1 = t1 - t2;
577d5de7839SBastian Koppelmann     } else {
578d5de7839SBastian Koppelmann         ret_h1 = t2 - t1;
579d5de7839SBastian Koppelmann     }
580d5de7839SBastian Koppelmann 
581d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
582d5de7839SBastian Koppelmann }
583d5de7839SBastian Koppelmann 
584328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
585328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
586328f1f0fSBastian Koppelmann {
587328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
588328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
589328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
590328f1f0fSBastian Koppelmann     int64_t result;
591328f1f0fSBastian Koppelmann 
592328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
593e4e39176SBastian Koppelmann     return ssov32(env, result);
594328f1f0fSBastian Koppelmann }
595328f1f0fSBastian Koppelmann 
596328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
597328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
598328f1f0fSBastian Koppelmann {
599328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
600328f1f0fSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
601328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
602328f1f0fSBastian Koppelmann     int64_t result;
603328f1f0fSBastian Koppelmann 
604328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
60585d604afSBastian Koppelmann     return suov32_pos(env, result);
606328f1f0fSBastian Koppelmann }
607328f1f0fSBastian Koppelmann 
608328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
609328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
610328f1f0fSBastian Koppelmann {
611328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
612328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
613328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
614328f1f0fSBastian Koppelmann     int64_t mul;
615328f1f0fSBastian Koppelmann 
616328f1f0fSBastian Koppelmann     mul = t1 * t3;
617328f1f0fSBastian Koppelmann     ret = mul + r2;
618328f1f0fSBastian Koppelmann     ovf = (ret ^ mul) & ~(mul ^ r2);
619328f1f0fSBastian Koppelmann 
620811ea608SBastian Koppelmann     t1 = ret >> 32;
621811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
622811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
623811ea608SBastian Koppelmann 
624328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
625328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
626328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
627328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
628328f1f0fSBastian Koppelmann         if (mul >= 0) {
629328f1f0fSBastian Koppelmann             ret = INT64_MAX;
630328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
631328f1f0fSBastian Koppelmann         } else {
632328f1f0fSBastian Koppelmann             ret = INT64_MIN;
633328f1f0fSBastian Koppelmann         }
634328f1f0fSBastian Koppelmann     } else {
635328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
636328f1f0fSBastian Koppelmann     }
637328f1f0fSBastian Koppelmann 
638328f1f0fSBastian Koppelmann     return ret;
639328f1f0fSBastian Koppelmann }
640328f1f0fSBastian Koppelmann 
641b00aa8ecSBastian Koppelmann uint32_t
642b00aa8ecSBastian Koppelmann helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
643b00aa8ecSBastian Koppelmann {
644b00aa8ecSBastian Koppelmann     int64_t result;
645b00aa8ecSBastian Koppelmann 
646b00aa8ecSBastian Koppelmann     result = (r1 + r2);
647b00aa8ecSBastian Koppelmann 
648b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u);
649b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
650b00aa8ecSBastian Koppelmann 
651b00aa8ecSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
652b00aa8ecSBastian Koppelmann        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
653b00aa8ecSBastian Koppelmann        case, we flip the saturated value. */
654b00aa8ecSBastian Koppelmann     if (r2 == 0x8000000000000000LL) {
655b00aa8ecSBastian Koppelmann         if (result > 0x7fffffffLL) {
656b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
657b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
658b00aa8ecSBastian Koppelmann             result = INT32_MIN;
659b00aa8ecSBastian Koppelmann         } else if (result < -0x80000000LL) {
660b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
661b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
662b00aa8ecSBastian Koppelmann             result = INT32_MAX;
663b00aa8ecSBastian Koppelmann         } else {
664b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
665b00aa8ecSBastian Koppelmann         }
666b00aa8ecSBastian Koppelmann     } else {
667b00aa8ecSBastian Koppelmann         if (result > 0x7fffffffLL) {
668b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
669b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
670b00aa8ecSBastian Koppelmann             result = INT32_MAX;
671b00aa8ecSBastian Koppelmann         } else if (result < -0x80000000LL) {
672b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
673b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
674b00aa8ecSBastian Koppelmann             result = INT32_MIN;
675b00aa8ecSBastian Koppelmann         } else {
676b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
677b00aa8ecSBastian Koppelmann         }
678b00aa8ecSBastian Koppelmann     }
679b00aa8ecSBastian Koppelmann     return (uint32_t)result;
680b00aa8ecSBastian Koppelmann }
681b00aa8ecSBastian Koppelmann 
682b00aa8ecSBastian Koppelmann uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
683b00aa8ecSBastian Koppelmann                               uint32_t r3, uint32_t n)
684b00aa8ecSBastian Koppelmann {
685b00aa8ecSBastian Koppelmann     int64_t t1 = (int64_t)r1;
686b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
687b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
688b00aa8ecSBastian Koppelmann     int64_t result, mul;
689b00aa8ecSBastian Koppelmann     int64_t ovf;
690b00aa8ecSBastian Koppelmann 
691b00aa8ecSBastian Koppelmann     mul = (t2 * t3) << n;
692b00aa8ecSBastian Koppelmann     result = mul + t1;
693b00aa8ecSBastian Koppelmann 
694b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
695b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
696b00aa8ecSBastian Koppelmann 
697b00aa8ecSBastian Koppelmann     ovf = (result ^ mul) & ~(mul ^ t1);
698b00aa8ecSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
699b00aa8ecSBastian Koppelmann        if the mul was (0x80000000 * 0x80000000) << 1). If this is the
700b00aa8ecSBastian Koppelmann        case, we flip the saturated value. */
701b00aa8ecSBastian Koppelmann     if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) {
702b00aa8ecSBastian Koppelmann         if (ovf >= 0) {
703b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
704b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
705b00aa8ecSBastian Koppelmann             /* ext_ret > MAX_INT */
706b00aa8ecSBastian Koppelmann             if (mul < 0) {
707b00aa8ecSBastian Koppelmann                 result = INT64_MAX;
708b00aa8ecSBastian Koppelmann             /* ext_ret < MIN_INT */
709b00aa8ecSBastian Koppelmann             } else {
710b00aa8ecSBastian Koppelmann                result = INT64_MIN;
711b00aa8ecSBastian Koppelmann             }
712b00aa8ecSBastian Koppelmann         } else {
713b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
714b00aa8ecSBastian Koppelmann         }
715b00aa8ecSBastian Koppelmann     } else {
716b00aa8ecSBastian Koppelmann         if (ovf < 0) {
717b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
718b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
719b00aa8ecSBastian Koppelmann             /* ext_ret > MAX_INT */
720b00aa8ecSBastian Koppelmann             if (mul >= 0) {
721b00aa8ecSBastian Koppelmann                 result = INT64_MAX;
722b00aa8ecSBastian Koppelmann             /* ext_ret < MIN_INT */
723b00aa8ecSBastian Koppelmann             } else {
724b00aa8ecSBastian Koppelmann                result = INT64_MIN;
725b00aa8ecSBastian Koppelmann             }
726b00aa8ecSBastian Koppelmann         } else {
727b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
728b00aa8ecSBastian Koppelmann         }
729b00aa8ecSBastian Koppelmann     }
730b00aa8ecSBastian Koppelmann     return (uint64_t)result;
731b00aa8ecSBastian Koppelmann }
732b00aa8ecSBastian Koppelmann 
733b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
734b00aa8ecSBastian Koppelmann                              uint32_t r3, uint32_t n)
735b00aa8ecSBastian Koppelmann {
736b00aa8ecSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
737b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
738b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
739b00aa8ecSBastian Koppelmann     int64_t mul, ret;
740b00aa8ecSBastian Koppelmann 
741b00aa8ecSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
742b00aa8ecSBastian Koppelmann         mul = 0x7fffffff;
743b00aa8ecSBastian Koppelmann     } else {
744b00aa8ecSBastian Koppelmann         mul = (t2 * t3) << n;
745b00aa8ecSBastian Koppelmann     }
746b00aa8ecSBastian Koppelmann 
747b00aa8ecSBastian Koppelmann     ret = t1 + mul + 0x8000;
748b00aa8ecSBastian Koppelmann 
749b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
750b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
751b00aa8ecSBastian Koppelmann 
752b00aa8ecSBastian Koppelmann     if (ret > 0x7fffffffll) {
753b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
754b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
755b00aa8ecSBastian Koppelmann         ret = INT32_MAX;
756b00aa8ecSBastian Koppelmann     } else if (ret < -0x80000000ll) {
757b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
758b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
759b00aa8ecSBastian Koppelmann         ret = INT32_MIN;
760b00aa8ecSBastian Koppelmann     } else {
761b00aa8ecSBastian Koppelmann         env->PSW_USB_V = 0;
762b00aa8ecSBastian Koppelmann     }
763b00aa8ecSBastian Koppelmann     return ret & 0xffff0000ll;
764b00aa8ecSBastian Koppelmann }
765b00aa8ecSBastian Koppelmann 
766328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
767328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
768328f1f0fSBastian Koppelmann {
769328f1f0fSBastian Koppelmann     uint64_t ret, mul;
770328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
771328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
772328f1f0fSBastian Koppelmann 
773328f1f0fSBastian Koppelmann     mul = t1 * t3;
774328f1f0fSBastian Koppelmann     ret = mul + r2;
775328f1f0fSBastian Koppelmann 
776811ea608SBastian Koppelmann     t1 = ret >> 32;
777811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
778811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
779811ea608SBastian Koppelmann 
780328f1f0fSBastian Koppelmann     if (ret < r2) {
781328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
782328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
783328f1f0fSBastian Koppelmann         /* saturate */
784328f1f0fSBastian Koppelmann         ret = UINT64_MAX;
785328f1f0fSBastian Koppelmann     } else {
786328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
787328f1f0fSBastian Koppelmann     }
788328f1f0fSBastian Koppelmann     return ret;
789328f1f0fSBastian Koppelmann }
790328f1f0fSBastian Koppelmann 
791328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
792328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
793328f1f0fSBastian Koppelmann {
794328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
795328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
796328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
797328f1f0fSBastian Koppelmann     int64_t result;
798328f1f0fSBastian Koppelmann 
799328f1f0fSBastian Koppelmann     result = t2 - (t1 * t3);
800e4e39176SBastian Koppelmann     return ssov32(env, result);
801328f1f0fSBastian Koppelmann }
802328f1f0fSBastian Koppelmann 
803328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
804328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
805328f1f0fSBastian Koppelmann {
8063debbb5aSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
8073debbb5aSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
8083debbb5aSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
8093debbb5aSBastian Koppelmann     uint64_t result;
8103debbb5aSBastian Koppelmann     uint64_t mul;
811328f1f0fSBastian Koppelmann 
8123debbb5aSBastian Koppelmann     mul = (t1 * t3);
8133debbb5aSBastian Koppelmann     result = t2 - mul;
8143debbb5aSBastian Koppelmann 
8153debbb5aSBastian Koppelmann     env->PSW_USB_AV = result ^ result * 2u;
8163debbb5aSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
8173debbb5aSBastian Koppelmann     /* we calculate ovf by hand here, because the multiplication can overflow on
8183debbb5aSBastian Koppelmann        the host, which would give false results if we compare to less than
8193debbb5aSBastian Koppelmann        zero */
8203debbb5aSBastian Koppelmann     if (mul > t2) {
8213debbb5aSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
8223debbb5aSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
8233debbb5aSBastian Koppelmann         result = 0;
8243debbb5aSBastian Koppelmann     } else {
8253debbb5aSBastian Koppelmann         env->PSW_USB_V = 0;
8263debbb5aSBastian Koppelmann     }
8273debbb5aSBastian Koppelmann     return result;
828328f1f0fSBastian Koppelmann }
829328f1f0fSBastian Koppelmann 
830328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
831328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
832328f1f0fSBastian Koppelmann {
833328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
834328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
835328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
836328f1f0fSBastian Koppelmann     int64_t mul;
837328f1f0fSBastian Koppelmann 
838328f1f0fSBastian Koppelmann     mul = t1 * t3;
839328f1f0fSBastian Koppelmann     ret = r2 - mul;
840328f1f0fSBastian Koppelmann     ovf = (ret ^ r2) & (mul ^ r2);
841328f1f0fSBastian Koppelmann 
842811ea608SBastian Koppelmann     t1 = ret >> 32;
843811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
844811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
845811ea608SBastian Koppelmann 
846328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
847328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
848328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
849328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
850328f1f0fSBastian Koppelmann         if (mul < 0) {
851328f1f0fSBastian Koppelmann             ret = INT64_MAX;
852328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
853328f1f0fSBastian Koppelmann         } else {
854328f1f0fSBastian Koppelmann             ret = INT64_MIN;
855328f1f0fSBastian Koppelmann         }
856328f1f0fSBastian Koppelmann     } else {
857328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
858328f1f0fSBastian Koppelmann     }
859328f1f0fSBastian Koppelmann     return ret;
860328f1f0fSBastian Koppelmann }
861328f1f0fSBastian Koppelmann 
862328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
863328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
864328f1f0fSBastian Koppelmann {
865328f1f0fSBastian Koppelmann     uint64_t ret, mul;
866328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
867328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
868328f1f0fSBastian Koppelmann 
869328f1f0fSBastian Koppelmann     mul = t1 * t3;
870328f1f0fSBastian Koppelmann     ret = r2 - mul;
871328f1f0fSBastian Koppelmann 
872811ea608SBastian Koppelmann     t1 = ret >> 32;
873811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
874811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
875811ea608SBastian Koppelmann 
876328f1f0fSBastian Koppelmann     if (ret > r2) {
877328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
878328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
879328f1f0fSBastian Koppelmann         /* saturate */
880328f1f0fSBastian Koppelmann         ret = 0;
881328f1f0fSBastian Koppelmann     } else {
882328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
883328f1f0fSBastian Koppelmann     }
884328f1f0fSBastian Koppelmann     return ret;
885328f1f0fSBastian Koppelmann }
886328f1f0fSBastian Koppelmann 
88762e47b2eSBastian Koppelmann uint32_t
88862e47b2eSBastian Koppelmann helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
88962e47b2eSBastian Koppelmann {
89062e47b2eSBastian Koppelmann     int64_t result;
89162e47b2eSBastian Koppelmann     int64_t t1 = (int64_t)r1;
89262e47b2eSBastian Koppelmann     int64_t t2 = (int64_t)r2;
89362e47b2eSBastian Koppelmann 
89462e47b2eSBastian Koppelmann     result = t1 - t2;
89562e47b2eSBastian Koppelmann 
89662e47b2eSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u);
89762e47b2eSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
89862e47b2eSBastian Koppelmann 
89962e47b2eSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
90062e47b2eSBastian Koppelmann        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
90162e47b2eSBastian Koppelmann        case, we flip the saturated value. */
90262e47b2eSBastian Koppelmann     if (r2 == 0x8000000000000000LL) {
90362e47b2eSBastian Koppelmann         if (result > 0x7fffffffLL) {
90462e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
90562e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
90662e47b2eSBastian Koppelmann             result = INT32_MIN;
90762e47b2eSBastian Koppelmann         } else if (result < -0x80000000LL) {
90862e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
90962e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
91062e47b2eSBastian Koppelmann             result = INT32_MAX;
91162e47b2eSBastian Koppelmann         } else {
91262e47b2eSBastian Koppelmann             env->PSW_USB_V = 0;
91362e47b2eSBastian Koppelmann         }
91462e47b2eSBastian Koppelmann     } else {
91562e47b2eSBastian Koppelmann         if (result > 0x7fffffffLL) {
91662e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
91762e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
91862e47b2eSBastian Koppelmann             result = INT32_MAX;
91962e47b2eSBastian Koppelmann         } else if (result < -0x80000000LL) {
92062e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
92162e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
92262e47b2eSBastian Koppelmann             result = INT32_MIN;
92362e47b2eSBastian Koppelmann         } else {
92462e47b2eSBastian Koppelmann             env->PSW_USB_V = 0;
92562e47b2eSBastian Koppelmann         }
92662e47b2eSBastian Koppelmann     }
92762e47b2eSBastian Koppelmann     return (uint32_t)result;
92862e47b2eSBastian Koppelmann }
92962e47b2eSBastian Koppelmann 
93062e47b2eSBastian Koppelmann uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
93162e47b2eSBastian Koppelmann                               uint32_t r3, uint32_t n)
93262e47b2eSBastian Koppelmann {
93362e47b2eSBastian Koppelmann     int64_t t1 = (int64_t)r1;
93462e47b2eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
93562e47b2eSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
93662e47b2eSBastian Koppelmann     int64_t result, mul;
93762e47b2eSBastian Koppelmann     int64_t ovf;
93862e47b2eSBastian Koppelmann 
93962e47b2eSBastian Koppelmann     mul = (t2 * t3) << n;
94062e47b2eSBastian Koppelmann     result = t1 - mul;
94162e47b2eSBastian Koppelmann 
94262e47b2eSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
94362e47b2eSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
94462e47b2eSBastian Koppelmann 
94562e47b2eSBastian Koppelmann     ovf = (result ^ t1) & (t1 ^ mul);
94662e47b2eSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
94762e47b2eSBastian Koppelmann        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
94862e47b2eSBastian Koppelmann        case, we flip the saturated value. */
94962e47b2eSBastian Koppelmann     if (mul == 0x8000000000000000LL) {
95062e47b2eSBastian Koppelmann         if (ovf >= 0) {
95162e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
95262e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
95362e47b2eSBastian Koppelmann             /* ext_ret > MAX_INT */
95462e47b2eSBastian Koppelmann             if (mul >= 0) {
95562e47b2eSBastian Koppelmann                 result = INT64_MAX;
95662e47b2eSBastian Koppelmann             /* ext_ret < MIN_INT */
95762e47b2eSBastian Koppelmann             } else {
95862e47b2eSBastian Koppelmann                result = INT64_MIN;
95962e47b2eSBastian Koppelmann             }
96062e47b2eSBastian Koppelmann         }
96162e47b2eSBastian Koppelmann     } else {
96262e47b2eSBastian Koppelmann         if (ovf < 0) {
96362e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
96462e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
96562e47b2eSBastian Koppelmann             /* ext_ret > MAX_INT */
96662e47b2eSBastian Koppelmann             if (mul < 0) {
96762e47b2eSBastian Koppelmann                 result = INT64_MAX;
96862e47b2eSBastian Koppelmann             /* ext_ret < MIN_INT */
96962e47b2eSBastian Koppelmann             } else {
97062e47b2eSBastian Koppelmann                result = INT64_MIN;
97162e47b2eSBastian Koppelmann             }
97262e47b2eSBastian Koppelmann         } else {
97362e47b2eSBastian Koppelmann             env->PSW_USB_V = 0;
97462e47b2eSBastian Koppelmann         }
97562e47b2eSBastian Koppelmann     }
97662e47b2eSBastian Koppelmann 
97762e47b2eSBastian Koppelmann     return (uint64_t)result;
97862e47b2eSBastian Koppelmann }
97962e47b2eSBastian Koppelmann 
98062e47b2eSBastian Koppelmann uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
98162e47b2eSBastian Koppelmann                              uint32_t r3, uint32_t n)
98262e47b2eSBastian Koppelmann {
98362e47b2eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
98462e47b2eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
98562e47b2eSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
98662e47b2eSBastian Koppelmann     int64_t mul, ret;
98762e47b2eSBastian Koppelmann 
98862e47b2eSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
98962e47b2eSBastian Koppelmann         mul = 0x7fffffff;
99062e47b2eSBastian Koppelmann     } else {
99162e47b2eSBastian Koppelmann         mul = (t2 * t3) << n;
99262e47b2eSBastian Koppelmann     }
99362e47b2eSBastian Koppelmann 
99462e47b2eSBastian Koppelmann     ret = t1 - mul + 0x8000;
99562e47b2eSBastian Koppelmann 
99662e47b2eSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
99762e47b2eSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
99862e47b2eSBastian Koppelmann 
99962e47b2eSBastian Koppelmann     if (ret > 0x7fffffffll) {
100062e47b2eSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
100162e47b2eSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
100262e47b2eSBastian Koppelmann         ret = INT32_MAX;
100362e47b2eSBastian Koppelmann     } else if (ret < -0x80000000ll) {
100462e47b2eSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
100562e47b2eSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
100662e47b2eSBastian Koppelmann         ret = INT32_MIN;
100762e47b2eSBastian Koppelmann     } else {
100862e47b2eSBastian Koppelmann         env->PSW_USB_V = 0;
100962e47b2eSBastian Koppelmann     }
101062e47b2eSBastian Koppelmann     return ret & 0xffff0000ll;
101162e47b2eSBastian Koppelmann }
101262e47b2eSBastian Koppelmann 
1013d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
1014d5de7839SBastian Koppelmann {
1015d5de7839SBastian Koppelmann     int32_t b, i;
1016d5de7839SBastian Koppelmann     int32_t ovf = 0;
1017d5de7839SBastian Koppelmann     int32_t avf = 0;
1018d5de7839SBastian Koppelmann     int32_t ret = 0;
1019d5de7839SBastian Koppelmann 
1020d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1021d5de7839SBastian Koppelmann         b = sextract32(arg, i * 8, 8);
1022d5de7839SBastian Koppelmann         b = (b >= 0) ? b : (0 - b);
1023d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
1024d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
1025d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
1026d5de7839SBastian Koppelmann     }
1027d5de7839SBastian Koppelmann 
1028d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
1029d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1030d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
1031d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1032d5de7839SBastian Koppelmann 
1033d5de7839SBastian Koppelmann     return ret;
1034d5de7839SBastian Koppelmann }
1035d5de7839SBastian Koppelmann 
1036d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
1037d5de7839SBastian Koppelmann {
1038d5de7839SBastian Koppelmann     int32_t h, i;
1039d5de7839SBastian Koppelmann     int32_t ovf = 0;
1040d5de7839SBastian Koppelmann     int32_t avf = 0;
1041d5de7839SBastian Koppelmann     int32_t ret = 0;
1042d5de7839SBastian Koppelmann 
1043d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1044d5de7839SBastian Koppelmann         h = sextract32(arg, i * 16, 16);
1045d5de7839SBastian Koppelmann         h = (h >= 0) ? h : (0 - h);
1046d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
1047d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1048d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1049d5de7839SBastian Koppelmann     }
1050d5de7839SBastian Koppelmann 
1051d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
1052d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1053d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
1054d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1055d5de7839SBastian Koppelmann 
1056d5de7839SBastian Koppelmann     return ret;
1057d5de7839SBastian Koppelmann }
1058d5de7839SBastian Koppelmann 
1059d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1060d5de7839SBastian Koppelmann {
1061d5de7839SBastian Koppelmann     int32_t b, i;
1062d5de7839SBastian Koppelmann     int32_t extr_r2;
1063d5de7839SBastian Koppelmann     int32_t ovf = 0;
1064d5de7839SBastian Koppelmann     int32_t avf = 0;
1065d5de7839SBastian Koppelmann     int32_t ret = 0;
1066d5de7839SBastian Koppelmann 
1067d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1068d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
1069d5de7839SBastian Koppelmann         b = sextract32(r1, i * 8, 8);
1070d5de7839SBastian Koppelmann         b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
1071d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
1072d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
1073d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
1074d5de7839SBastian Koppelmann     }
1075d5de7839SBastian Koppelmann 
1076d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
1077d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1078d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
1079d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1080d5de7839SBastian Koppelmann     return ret;
1081d5de7839SBastian Koppelmann }
1082d5de7839SBastian Koppelmann 
1083d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1084d5de7839SBastian Koppelmann {
1085d5de7839SBastian Koppelmann     int32_t h, i;
1086d5de7839SBastian Koppelmann     int32_t extr_r2;
1087d5de7839SBastian Koppelmann     int32_t ovf = 0;
1088d5de7839SBastian Koppelmann     int32_t avf = 0;
1089d5de7839SBastian Koppelmann     int32_t ret = 0;
1090d5de7839SBastian Koppelmann 
1091d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1092d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
1093d5de7839SBastian Koppelmann         h = sextract32(r1, i * 16, 16);
1094d5de7839SBastian Koppelmann         h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
1095d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
1096d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1097d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1098d5de7839SBastian Koppelmann     }
1099d5de7839SBastian Koppelmann 
1100d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
1101d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1102d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
1103d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1104d5de7839SBastian Koppelmann 
1105d5de7839SBastian Koppelmann     return ret;
1106d5de7839SBastian Koppelmann }
1107d5de7839SBastian Koppelmann 
11082e430e1cSBastian Koppelmann uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
11092e430e1cSBastian Koppelmann                        uint32_t r2_h)
11102e430e1cSBastian Koppelmann {
11112e430e1cSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
11122e430e1cSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
11132e430e1cSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
11142e430e1cSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
11152e430e1cSBastian Koppelmann     int64_t result0, result1;
11162e430e1cSBastian Koppelmann     uint32_t ovf0, ovf1;
11172e430e1cSBastian Koppelmann     uint32_t avf0, avf1;
11182e430e1cSBastian Koppelmann 
11192e430e1cSBastian Koppelmann     ovf0 = ovf1 = 0;
11202e430e1cSBastian Koppelmann 
11212e430e1cSBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
11222e430e1cSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
11232e430e1cSBastian Koppelmann 
11242e430e1cSBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
11252e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
11262e430e1cSBastian Koppelmann     }
11272e430e1cSBastian Koppelmann 
11282e430e1cSBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
11292e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
11302e430e1cSBastian Koppelmann     }
11312e430e1cSBastian Koppelmann 
11322e430e1cSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
11332e430e1cSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
11342e430e1cSBastian Koppelmann 
11352e430e1cSBastian Koppelmann     avf0 = result0 * 2u;
11362e430e1cSBastian Koppelmann     avf0 = result0 ^ avf0;
11372e430e1cSBastian Koppelmann     avf1 = result1 * 2u;
11382e430e1cSBastian Koppelmann     avf1 = result1 ^ avf1;
11392e430e1cSBastian Koppelmann 
11402e430e1cSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
11412e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
11422e430e1cSBastian Koppelmann 
11432e430e1cSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
11442e430e1cSBastian Koppelmann }
11452e430e1cSBastian Koppelmann 
1146bebe80fcSBastian Koppelmann uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1147bebe80fcSBastian Koppelmann                          uint32_t r2_h)
1148bebe80fcSBastian Koppelmann {
1149bebe80fcSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
1150bebe80fcSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
1151bebe80fcSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
1152bebe80fcSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
1153bebe80fcSBastian Koppelmann     int64_t result0, result1;
1154bebe80fcSBastian Koppelmann     uint32_t ovf0, ovf1;
1155bebe80fcSBastian Koppelmann     uint32_t avf0, avf1;
1156bebe80fcSBastian Koppelmann 
1157bebe80fcSBastian Koppelmann     ovf0 = ovf1 = 0;
1158bebe80fcSBastian Koppelmann 
1159bebe80fcSBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
1160bebe80fcSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
1161bebe80fcSBastian Koppelmann 
1162bebe80fcSBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1163bebe80fcSBastian Koppelmann         ovf0 = (1 << 31);
1164bebe80fcSBastian Koppelmann     }
1165bebe80fcSBastian Koppelmann 
1166bebe80fcSBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1167bebe80fcSBastian Koppelmann         ovf1 = (1 << 31);
1168bebe80fcSBastian Koppelmann     }
1169bebe80fcSBastian Koppelmann 
1170bebe80fcSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
1171bebe80fcSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1172bebe80fcSBastian Koppelmann 
1173bebe80fcSBastian Koppelmann     avf0 = result0 * 2u;
1174bebe80fcSBastian Koppelmann     avf0 = result0 ^ avf0;
1175bebe80fcSBastian Koppelmann     avf1 = result1 * 2u;
1176bebe80fcSBastian Koppelmann     avf1 = result1 ^ avf1;
1177bebe80fcSBastian Koppelmann 
1178bebe80fcSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
1179bebe80fcSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1180bebe80fcSBastian Koppelmann 
1181bebe80fcSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1182bebe80fcSBastian Koppelmann }
1183bebe80fcSBastian Koppelmann 
1184b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1185b00aa8ecSBastian Koppelmann                         uint32_t r3, uint32_t n)
1186b00aa8ecSBastian Koppelmann {
1187b00aa8ecSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
1188b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
1189b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
1190b00aa8ecSBastian Koppelmann     int64_t mul, ret;
1191b00aa8ecSBastian Koppelmann 
1192b00aa8ecSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1193b00aa8ecSBastian Koppelmann         mul = 0x7fffffff;
1194b00aa8ecSBastian Koppelmann     } else {
1195b00aa8ecSBastian Koppelmann         mul = (t2 * t3) << n;
1196b00aa8ecSBastian Koppelmann     }
1197b00aa8ecSBastian Koppelmann 
1198b00aa8ecSBastian Koppelmann     ret = t1 + mul + 0x8000;
1199b00aa8ecSBastian Koppelmann 
1200b00aa8ecSBastian Koppelmann     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1201b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
1202b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
1203b00aa8ecSBastian Koppelmann     } else {
1204b00aa8ecSBastian Koppelmann         env->PSW_USB_V = 0;
1205b00aa8ecSBastian Koppelmann     }
1206b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
1207b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1208b00aa8ecSBastian Koppelmann 
1209b00aa8ecSBastian Koppelmann     return ret & 0xffff0000ll;
1210b00aa8ecSBastian Koppelmann }
1211b00aa8ecSBastian Koppelmann 
1212d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1213d5de7839SBastian Koppelmann {
1214d5de7839SBastian Koppelmann     int32_t b, i;
1215d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1216d5de7839SBastian Koppelmann     int32_t ovf = 0;
1217d5de7839SBastian Koppelmann     int32_t avf = 0;
1218d5de7839SBastian Koppelmann     uint32_t ret = 0;
1219d5de7839SBastian Koppelmann 
1220d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1221d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
1222d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
1223d5de7839SBastian Koppelmann 
1224d5de7839SBastian Koppelmann         b = extr_r1 + extr_r2;
1225d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
1226d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
1227d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
1228d5de7839SBastian Koppelmann     }
1229d5de7839SBastian Koppelmann 
1230d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1231d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1232d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
1233d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1234d5de7839SBastian Koppelmann 
1235d5de7839SBastian Koppelmann     return ret;
1236d5de7839SBastian Koppelmann }
1237d5de7839SBastian Koppelmann 
1238d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1239d5de7839SBastian Koppelmann {
1240d5de7839SBastian Koppelmann     int32_t h, i;
1241d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1242d5de7839SBastian Koppelmann     int32_t ovf = 0;
1243d5de7839SBastian Koppelmann     int32_t avf = 0;
1244d5de7839SBastian Koppelmann     int32_t ret = 0;
1245d5de7839SBastian Koppelmann 
1246d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1247d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
1248d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
1249d5de7839SBastian Koppelmann         h = extr_r1 + extr_r2;
1250d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
1251d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1252d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1253d5de7839SBastian Koppelmann     }
1254d5de7839SBastian Koppelmann 
1255d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1256d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1257d5de7839SBastian Koppelmann     env->PSW_USB_AV = (avf << 16);
1258d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1259d5de7839SBastian Koppelmann 
1260d5de7839SBastian Koppelmann     return ret;
1261d5de7839SBastian Koppelmann }
1262d5de7839SBastian Koppelmann 
1263f4aef476SBastian Koppelmann uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1264f4aef476SBastian Koppelmann                        uint32_t r2_h)
1265f4aef476SBastian Koppelmann {
1266f4aef476SBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
1267f4aef476SBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
1268f4aef476SBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
1269f4aef476SBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
1270f4aef476SBastian Koppelmann     int64_t result0, result1;
1271f4aef476SBastian Koppelmann     uint32_t ovf0, ovf1;
1272f4aef476SBastian Koppelmann     uint32_t avf0, avf1;
1273f4aef476SBastian Koppelmann 
1274f4aef476SBastian Koppelmann     ovf0 = ovf1 = 0;
1275f4aef476SBastian Koppelmann 
1276f4aef476SBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
1277f4aef476SBastian Koppelmann     result1 = r2_high - mul_res1 + 0x8000;
1278f4aef476SBastian Koppelmann 
1279f4aef476SBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1280f4aef476SBastian Koppelmann         ovf0 = (1 << 31);
1281f4aef476SBastian Koppelmann     }
1282f4aef476SBastian Koppelmann 
1283f4aef476SBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1284f4aef476SBastian Koppelmann         ovf1 = (1 << 31);
1285f4aef476SBastian Koppelmann     }
1286f4aef476SBastian Koppelmann 
1287f4aef476SBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
1288f4aef476SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1289f4aef476SBastian Koppelmann 
1290f4aef476SBastian Koppelmann     avf0 = result0 * 2u;
1291f4aef476SBastian Koppelmann     avf0 = result0 ^ avf0;
1292f4aef476SBastian Koppelmann     avf1 = result1 * 2u;
1293f4aef476SBastian Koppelmann     avf1 = result1 ^ avf1;
1294f4aef476SBastian Koppelmann 
1295f4aef476SBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
1296f4aef476SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1297f4aef476SBastian Koppelmann 
1298f4aef476SBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1299f4aef476SBastian Koppelmann }
1300f4aef476SBastian Koppelmann 
1301068fac77SBastian Koppelmann uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1302068fac77SBastian Koppelmann                          uint32_t r2_h)
1303068fac77SBastian Koppelmann {
1304068fac77SBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
1305068fac77SBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
1306068fac77SBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
1307068fac77SBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
1308068fac77SBastian Koppelmann     int64_t result0, result1;
1309068fac77SBastian Koppelmann     uint32_t ovf0, ovf1;
1310068fac77SBastian Koppelmann     uint32_t avf0, avf1;
1311068fac77SBastian Koppelmann 
1312068fac77SBastian Koppelmann     ovf0 = ovf1 = 0;
1313068fac77SBastian Koppelmann 
1314068fac77SBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
1315068fac77SBastian Koppelmann     result1 = r2_high - mul_res1 + 0x8000;
1316068fac77SBastian Koppelmann 
1317068fac77SBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1318068fac77SBastian Koppelmann         ovf0 = (1 << 31);
1319068fac77SBastian Koppelmann     }
1320068fac77SBastian Koppelmann 
1321068fac77SBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1322068fac77SBastian Koppelmann         ovf1 = (1 << 31);
1323068fac77SBastian Koppelmann     }
1324068fac77SBastian Koppelmann 
1325068fac77SBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
1326068fac77SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1327068fac77SBastian Koppelmann 
1328068fac77SBastian Koppelmann     avf0 = result0 * 2u;
1329068fac77SBastian Koppelmann     avf0 = result0 ^ avf0;
1330068fac77SBastian Koppelmann     avf1 = result1 * 2u;
1331068fac77SBastian Koppelmann     avf1 = result1 ^ avf1;
1332068fac77SBastian Koppelmann 
1333068fac77SBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
1334068fac77SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1335068fac77SBastian Koppelmann 
1336068fac77SBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1337068fac77SBastian Koppelmann }
1338068fac77SBastian Koppelmann 
133962e47b2eSBastian Koppelmann uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
134062e47b2eSBastian Koppelmann                         uint32_t r3, uint32_t n)
134162e47b2eSBastian Koppelmann {
134262e47b2eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
134362e47b2eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
134462e47b2eSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
134562e47b2eSBastian Koppelmann     int64_t mul, ret;
134662e47b2eSBastian Koppelmann 
134762e47b2eSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
134862e47b2eSBastian Koppelmann         mul = 0x7fffffff;
134962e47b2eSBastian Koppelmann     } else {
135062e47b2eSBastian Koppelmann         mul = (t2 * t3) << n;
135162e47b2eSBastian Koppelmann     }
135262e47b2eSBastian Koppelmann 
135362e47b2eSBastian Koppelmann     ret = t1 - mul + 0x8000;
135462e47b2eSBastian Koppelmann 
135562e47b2eSBastian Koppelmann     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
135662e47b2eSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
135762e47b2eSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
135862e47b2eSBastian Koppelmann     } else {
135962e47b2eSBastian Koppelmann         env->PSW_USB_V = 0;
136062e47b2eSBastian Koppelmann     }
136162e47b2eSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
136262e47b2eSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
136362e47b2eSBastian Koppelmann 
136462e47b2eSBastian Koppelmann     return ret & 0xffff0000ll;
136562e47b2eSBastian Koppelmann }
136662e47b2eSBastian Koppelmann 
1367d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1368d5de7839SBastian Koppelmann {
1369d5de7839SBastian Koppelmann     int32_t b, i;
1370d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1371d5de7839SBastian Koppelmann     int32_t ovf = 0;
1372d5de7839SBastian Koppelmann     int32_t avf = 0;
1373d5de7839SBastian Koppelmann     uint32_t ret = 0;
1374d5de7839SBastian Koppelmann 
1375d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1376d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
1377d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
1378d5de7839SBastian Koppelmann 
1379d5de7839SBastian Koppelmann         b = extr_r1 - extr_r2;
1380d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
1381d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
1382d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
1383d5de7839SBastian Koppelmann     }
1384d5de7839SBastian Koppelmann 
1385d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1386d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1387d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
1388d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1389d5de7839SBastian Koppelmann 
1390d5de7839SBastian Koppelmann     return ret;
1391d5de7839SBastian Koppelmann }
1392d5de7839SBastian Koppelmann 
1393d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1394d5de7839SBastian Koppelmann {
1395d5de7839SBastian Koppelmann     int32_t h, i;
1396d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1397d5de7839SBastian Koppelmann     int32_t ovf = 0;
1398d5de7839SBastian Koppelmann     int32_t avf = 0;
1399d5de7839SBastian Koppelmann     int32_t ret = 0;
1400d5de7839SBastian Koppelmann 
1401d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1402d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
1403d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
1404d5de7839SBastian Koppelmann         h = extr_r1 - extr_r2;
1405d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
1406d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1407d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1408d5de7839SBastian Koppelmann     }
1409d5de7839SBastian Koppelmann 
1410d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1411d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1412d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
1413d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1414d5de7839SBastian Koppelmann 
1415d5de7839SBastian Koppelmann     return ret;
1416d5de7839SBastian Koppelmann }
1417d5de7839SBastian Koppelmann 
1418d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
1419d5de7839SBastian Koppelmann {
1420d5de7839SBastian Koppelmann     int32_t ret;
1421d5de7839SBastian Koppelmann     int32_t i, msk;
1422d5de7839SBastian Koppelmann 
1423d5de7839SBastian Koppelmann     ret = 0;
1424d5de7839SBastian Koppelmann     msk = 0xff;
1425d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1426d5de7839SBastian Koppelmann         if ((r1 & msk) == (r2 & msk)) {
1427d5de7839SBastian Koppelmann             ret |= msk;
1428d5de7839SBastian Koppelmann         }
1429d5de7839SBastian Koppelmann         msk = msk << 8;
1430d5de7839SBastian Koppelmann     }
1431d5de7839SBastian Koppelmann 
1432d5de7839SBastian Koppelmann     return ret;
1433d5de7839SBastian Koppelmann }
1434d5de7839SBastian Koppelmann 
1435d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
1436d5de7839SBastian Koppelmann {
1437d5de7839SBastian Koppelmann     int32_t ret = 0;
1438d5de7839SBastian Koppelmann 
1439d5de7839SBastian Koppelmann     if ((r1 & 0xffff) == (r2 & 0xffff)) {
1440d5de7839SBastian Koppelmann         ret = 0xffff;
1441d5de7839SBastian Koppelmann     }
1442d5de7839SBastian Koppelmann 
1443d5de7839SBastian Koppelmann     if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
1444d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1445d5de7839SBastian Koppelmann     }
1446d5de7839SBastian Koppelmann 
1447d5de7839SBastian Koppelmann     return ret;
1448d5de7839SBastian Koppelmann }
1449d5de7839SBastian Koppelmann 
1450d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
1451d5de7839SBastian Koppelmann {
1452d5de7839SBastian Koppelmann     int32_t i;
1453d5de7839SBastian Koppelmann     uint32_t ret = 0;
1454d5de7839SBastian Koppelmann 
1455d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1456d5de7839SBastian Koppelmann         ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
1457d5de7839SBastian Koppelmann     }
1458d5de7839SBastian Koppelmann 
1459d5de7839SBastian Koppelmann     return ret;
1460d5de7839SBastian Koppelmann }
1461d5de7839SBastian Koppelmann 
1462d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
1463d5de7839SBastian Koppelmann {
1464d5de7839SBastian Koppelmann     uint32_t ret;
1465d5de7839SBastian Koppelmann 
1466d5de7839SBastian Koppelmann     ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
1467d5de7839SBastian Koppelmann     ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
1468d5de7839SBastian Koppelmann 
1469d5de7839SBastian Koppelmann     return ret;
1470d5de7839SBastian Koppelmann }
1471d5de7839SBastian Koppelmann 
1472d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
1473d5de7839SBastian Koppelmann {
1474d5de7839SBastian Koppelmann     int32_t i;
1475d5de7839SBastian Koppelmann     uint32_t ret = 0;
1476d5de7839SBastian Koppelmann 
1477d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1478d5de7839SBastian Koppelmann         if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
1479d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
1480d5de7839SBastian Koppelmann         }
1481d5de7839SBastian Koppelmann     }
1482d5de7839SBastian Koppelmann 
1483d5de7839SBastian Koppelmann     return ret;
1484d5de7839SBastian Koppelmann }
1485d5de7839SBastian Koppelmann 
1486d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
1487d5de7839SBastian Koppelmann {
1488d5de7839SBastian Koppelmann     int32_t i;
1489d5de7839SBastian Koppelmann     uint32_t ret = 0;
1490d5de7839SBastian Koppelmann 
1491d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1492d5de7839SBastian Koppelmann         if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
1493d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
1494d5de7839SBastian Koppelmann         }
1495d5de7839SBastian Koppelmann     }
1496d5de7839SBastian Koppelmann 
1497d5de7839SBastian Koppelmann     return ret;
1498d5de7839SBastian Koppelmann }
1499d5de7839SBastian Koppelmann 
1500d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
1501d5de7839SBastian Koppelmann {
1502d5de7839SBastian Koppelmann     uint32_t ret = 0;
1503d5de7839SBastian Koppelmann 
1504d5de7839SBastian Koppelmann     if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
1505d5de7839SBastian Koppelmann         ret |= 0xffff;
1506d5de7839SBastian Koppelmann     }
1507d5de7839SBastian Koppelmann 
1508d5de7839SBastian Koppelmann     if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
1509d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1510d5de7839SBastian Koppelmann     }
1511d5de7839SBastian Koppelmann 
1512d5de7839SBastian Koppelmann     return ret;
1513d5de7839SBastian Koppelmann }
1514d5de7839SBastian Koppelmann 
1515d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
1516d5de7839SBastian Koppelmann {
1517d5de7839SBastian Koppelmann     uint32_t ret = 0;
1518d5de7839SBastian Koppelmann 
1519d5de7839SBastian Koppelmann     if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
1520d5de7839SBastian Koppelmann         ret |= 0xffff;
1521d5de7839SBastian Koppelmann     }
1522d5de7839SBastian Koppelmann 
1523d5de7839SBastian Koppelmann     if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
1524d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1525d5de7839SBastian Koppelmann     }
1526d5de7839SBastian Koppelmann 
1527d5de7839SBastian Koppelmann     return ret;
1528d5de7839SBastian Koppelmann }
1529d5de7839SBastian Koppelmann 
1530d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op)                                 \
1531d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
1532d5de7839SBastian Koppelmann {                                                             \
1533d5de7839SBastian Koppelmann     int32_t i, extr_r1, extr_r2;                              \
1534d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1535d5de7839SBastian Koppelmann                                                               \
1536d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
1537d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);                   \
1538d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);                   \
1539d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1540d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1541d5de7839SBastian Koppelmann     }                                                         \
1542d5de7839SBastian Koppelmann     return ret;                                               \
1543d5de7839SBastian Koppelmann }                                                             \
1544d5de7839SBastian Koppelmann                                                               \
1545d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
1546d5de7839SBastian Koppelmann {                                                             \
1547d5de7839SBastian Koppelmann     int32_t i;                                                \
1548d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
1549d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1550d5de7839SBastian Koppelmann                                                               \
1551d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
1552d5de7839SBastian Koppelmann         extr_r1 = extract32(r1, i * 8, 8);                    \
1553d5de7839SBastian Koppelmann         extr_r2 = extract32(r2, i * 8, 8);                    \
1554d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1555d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1556d5de7839SBastian Koppelmann     }                                                         \
1557d5de7839SBastian Koppelmann     return ret;                                               \
1558d5de7839SBastian Koppelmann }                                                             \
1559d5de7839SBastian Koppelmann                                                               \
1560d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
1561d5de7839SBastian Koppelmann {                                                             \
1562d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;                                 \
1563d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1564d5de7839SBastian Koppelmann                                                               \
1565d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 0, 16);                          \
1566d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 0, 16);                          \
1567d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1568d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
1569d5de7839SBastian Koppelmann                                                               \
1570d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 16, 16);                         \
1571d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 16, 16);                         \
1572d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1573d5de7839SBastian Koppelmann     ret |= extr_r1 << 16;                                     \
1574d5de7839SBastian Koppelmann                                                               \
1575d5de7839SBastian Koppelmann     return ret;                                               \
1576d5de7839SBastian Koppelmann }                                                             \
1577d5de7839SBastian Koppelmann                                                               \
1578d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
1579d5de7839SBastian Koppelmann {                                                             \
1580d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
1581d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1582d5de7839SBastian Koppelmann                                                               \
1583d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 0, 16);                           \
1584d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 0, 16);                           \
1585d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1586d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
1587d5de7839SBastian Koppelmann                                                               \
1588d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 16, 16);                          \
1589d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 16, 16);                          \
1590d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1591d5de7839SBastian Koppelmann     ret |= extr_r1 << (16);                                   \
1592d5de7839SBastian Koppelmann                                                               \
1593d5de7839SBastian Koppelmann     return ret;                                               \
1594d5de7839SBastian Koppelmann }                                                             \
159509532255SBastian Koppelmann                                                               \
159609532255SBastian Koppelmann uint64_t helper_ix##name(uint64_t r1, uint32_t r2)            \
159709532255SBastian Koppelmann {                                                             \
159809532255SBastian Koppelmann     int64_t r2l, r2h, r1hl;                                   \
159909532255SBastian Koppelmann     uint64_t ret = 0;                                         \
160009532255SBastian Koppelmann                                                               \
160109532255SBastian Koppelmann     ret = ((r1 + 2) & 0xffff);                                \
160209532255SBastian Koppelmann     r2l = sextract64(r2, 0, 16);                              \
160309532255SBastian Koppelmann     r2h = sextract64(r2, 16, 16);                             \
160409532255SBastian Koppelmann     r1hl = sextract64(r1, 32, 16);                            \
160509532255SBastian Koppelmann                                                               \
160609532255SBastian Koppelmann     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
160709532255SBastian Koppelmann         ret |= (r2l & 0xffff) << 32;                          \
160809532255SBastian Koppelmann         ret |= extract64(r1, 0, 16) << 16;                    \
160909532255SBastian Koppelmann     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
161009532255SBastian Koppelmann         ret |= extract64(r2, 16, 16) << 32;                   \
161109532255SBastian Koppelmann         ret |= extract64(r1 + 1, 0, 16) << 16;                \
161209532255SBastian Koppelmann     } else {                                                  \
161309532255SBastian Koppelmann         ret |= r1 & 0xffffffff0000ull;                        \
161409532255SBastian Koppelmann     }                                                         \
161509532255SBastian Koppelmann     return ret;                                               \
161609532255SBastian Koppelmann }                                                             \
161709532255SBastian Koppelmann                                                               \
161809532255SBastian Koppelmann uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2)       \
161909532255SBastian Koppelmann {                                                             \
162009532255SBastian Koppelmann     int64_t r2l, r2h, r1hl;                                   \
162109532255SBastian Koppelmann     uint64_t ret = 0;                                         \
162209532255SBastian Koppelmann                                                               \
162309532255SBastian Koppelmann     ret = ((r1 + 2) & 0xffff);                                \
162409532255SBastian Koppelmann     r2l = extract64(r2, 0, 16);                               \
162509532255SBastian Koppelmann     r2h = extract64(r2, 16, 16);                              \
162609532255SBastian Koppelmann     r1hl = extract64(r1, 32, 16);                             \
162709532255SBastian Koppelmann                                                               \
162809532255SBastian Koppelmann     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
162909532255SBastian Koppelmann         ret |= (r2l & 0xffff) << 32;                          \
163009532255SBastian Koppelmann         ret |= extract64(r1, 0, 16) << 16;                    \
163109532255SBastian Koppelmann     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
163209532255SBastian Koppelmann         ret |= extract64(r2, 16, 16) << 32;                   \
163309532255SBastian Koppelmann         ret |= extract64(r1 + 1, 0, 16) << 16;                \
163409532255SBastian Koppelmann     } else {                                                  \
163509532255SBastian Koppelmann         ret |= r1 & 0xffffffff0000ull;                        \
163609532255SBastian Koppelmann     }                                                         \
163709532255SBastian Koppelmann     return ret;                                               \
163809532255SBastian Koppelmann }
1639d5de7839SBastian Koppelmann 
1640d5de7839SBastian Koppelmann EXTREMA_H_B(max, >)
1641d5de7839SBastian Koppelmann EXTREMA_H_B(min, <)
1642d5de7839SBastian Koppelmann 
1643d5de7839SBastian Koppelmann #undef EXTREMA_H_B
1644d5de7839SBastian Koppelmann 
16450b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1)
16460b79a781SBastian Koppelmann {
16470b79a781SBastian Koppelmann     return clo32(r1);
16480b79a781SBastian Koppelmann }
16490b79a781SBastian Koppelmann 
16500b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1)
16510b79a781SBastian Koppelmann {
16520b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
16530b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
16540b79a781SBastian Koppelmann 
16550b79a781SBastian Koppelmann     ret_hw0 = clo32(ret_hw0 << 16);
16560b79a781SBastian Koppelmann     ret_hw1 = clo32(ret_hw1 << 16);
16570b79a781SBastian Koppelmann 
16580b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
16590b79a781SBastian Koppelmann         ret_hw0 = 16;
16600b79a781SBastian Koppelmann     }
16610b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
16620b79a781SBastian Koppelmann         ret_hw1 = 16;
16630b79a781SBastian Koppelmann     }
16640b79a781SBastian Koppelmann 
16650b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
16660b79a781SBastian Koppelmann }
16670b79a781SBastian Koppelmann 
16680b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1)
16690b79a781SBastian Koppelmann {
16700b79a781SBastian Koppelmann     return clz32(r1);
16710b79a781SBastian Koppelmann }
16720b79a781SBastian Koppelmann 
16730b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1)
16740b79a781SBastian Koppelmann {
16750b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
16760b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
16770b79a781SBastian Koppelmann 
16780b79a781SBastian Koppelmann     ret_hw0 = clz32(ret_hw0 << 16);
16790b79a781SBastian Koppelmann     ret_hw1 = clz32(ret_hw1 << 16);
16800b79a781SBastian Koppelmann 
16810b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
16820b79a781SBastian Koppelmann         ret_hw0 = 16;
16830b79a781SBastian Koppelmann     }
16840b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
16850b79a781SBastian Koppelmann         ret_hw1 = 16;
16860b79a781SBastian Koppelmann     }
16870b79a781SBastian Koppelmann 
16880b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
16890b79a781SBastian Koppelmann }
16900b79a781SBastian Koppelmann 
16910b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1)
16920b79a781SBastian Koppelmann {
16930b79a781SBastian Koppelmann     return clrsb32(r1);
16940b79a781SBastian Koppelmann }
16950b79a781SBastian Koppelmann 
16960b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1)
16970b79a781SBastian Koppelmann {
16980b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
16990b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
17000b79a781SBastian Koppelmann 
17010b79a781SBastian Koppelmann     ret_hw0 = clrsb32(ret_hw0 << 16);
17020b79a781SBastian Koppelmann     ret_hw1 = clrsb32(ret_hw1 << 16);
17030b79a781SBastian Koppelmann 
17040b79a781SBastian Koppelmann     if (ret_hw0 > 15) {
17050b79a781SBastian Koppelmann         ret_hw0 = 15;
17060b79a781SBastian Koppelmann     }
17070b79a781SBastian Koppelmann     if (ret_hw1 > 15) {
17080b79a781SBastian Koppelmann         ret_hw1 = 15;
17090b79a781SBastian Koppelmann     }
17100b79a781SBastian Koppelmann 
17110b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
17120b79a781SBastian Koppelmann }
17130b79a781SBastian Koppelmann 
17140b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2)
17150b79a781SBastian Koppelmann {
17160b79a781SBastian Koppelmann     int32_t shift_count = sextract32(r2, 0, 6);
17170b79a781SBastian Koppelmann 
17180b79a781SBastian Koppelmann     if (shift_count == -32) {
17190b79a781SBastian Koppelmann         return 0;
17200b79a781SBastian Koppelmann     } else if (shift_count < 0) {
17210b79a781SBastian Koppelmann         return r1 >> -shift_count;
17220b79a781SBastian Koppelmann     } else {
17230b79a781SBastian Koppelmann         return r1 << shift_count;
17240b79a781SBastian Koppelmann     }
17250b79a781SBastian Koppelmann }
17260b79a781SBastian Koppelmann 
17270b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
17280b79a781SBastian Koppelmann {
17290b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
17300b79a781SBastian Koppelmann     int32_t shift_count;
17310b79a781SBastian Koppelmann 
17320b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
17330b79a781SBastian Koppelmann 
17340b79a781SBastian Koppelmann     if (shift_count == -16) {
17350b79a781SBastian Koppelmann         return 0;
17360b79a781SBastian Koppelmann     } else if (shift_count < 0) {
17370b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
17380b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
17390b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
17400b79a781SBastian Koppelmann     } else {
17410b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) << shift_count;
17420b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) << shift_count;
17430b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
17440b79a781SBastian Koppelmann     }
17450b79a781SBastian Koppelmann }
17460b79a781SBastian Koppelmann 
17470b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
17480b79a781SBastian Koppelmann {
17490b79a781SBastian Koppelmann     int32_t shift_count;
17500b79a781SBastian Koppelmann     int64_t result, t1;
17510b79a781SBastian Koppelmann     uint32_t ret;
17520b79a781SBastian Koppelmann 
17530b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 6);
17540b79a781SBastian Koppelmann     t1 = sextract32(r1, 0, 32);
17550b79a781SBastian Koppelmann 
17560b79a781SBastian Koppelmann     if (shift_count == 0) {
17570b79a781SBastian Koppelmann         env->PSW_USB_C = env->PSW_USB_V = 0;
17580b79a781SBastian Koppelmann         ret = r1;
17590b79a781SBastian Koppelmann     } else if (shift_count == -32) {
17600b79a781SBastian Koppelmann         env->PSW_USB_C = r1;
17610b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
17620b79a781SBastian Koppelmann         ret = t1 >> 31;
17630b79a781SBastian Koppelmann     } else if (shift_count > 0) {
17640b79a781SBastian Koppelmann         result = t1 << shift_count;
17650b79a781SBastian Koppelmann         /* calc carry */
1766452e3d49SPeter Maydell         env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
17670b79a781SBastian Koppelmann         /* calc v */
17680b79a781SBastian Koppelmann         env->PSW_USB_V = (((result > 0x7fffffffLL) ||
17690b79a781SBastian Koppelmann                            (result < -0x80000000LL)) << 31);
17700b79a781SBastian Koppelmann         /* calc sv */
17710b79a781SBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
17720b79a781SBastian Koppelmann         ret = (uint32_t)result;
17730b79a781SBastian Koppelmann     } else {
17740b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
17750b79a781SBastian Koppelmann         env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
17760b79a781SBastian Koppelmann         ret = t1 >> -shift_count;
17770b79a781SBastian Koppelmann     }
17780b79a781SBastian Koppelmann 
17790b79a781SBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
17800b79a781SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
17810b79a781SBastian Koppelmann 
17820b79a781SBastian Koppelmann     return ret;
17830b79a781SBastian Koppelmann }
17840b79a781SBastian Koppelmann 
17850b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
17860b79a781SBastian Koppelmann {
17870b79a781SBastian Koppelmann     int32_t shift_count;
17880b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
17890b79a781SBastian Koppelmann 
17900b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
17910b79a781SBastian Koppelmann 
17920b79a781SBastian Koppelmann     if (shift_count == 0) {
17930b79a781SBastian Koppelmann         return r1;
17940b79a781SBastian Koppelmann     } else if (shift_count < 0) {
17950b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
17960b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
17970b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
17980b79a781SBastian Koppelmann     } else {
17990b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) << shift_count;
18000b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) << shift_count;
18010b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
18020b79a781SBastian Koppelmann     }
18030b79a781SBastian Koppelmann }
18040b79a781SBastian Koppelmann 
1805e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1806e2bed107SBastian Koppelmann {
1807e2bed107SBastian Koppelmann     uint32_t i, ret;
1808e2bed107SBastian Koppelmann 
1809e2bed107SBastian Koppelmann     ret = 0;
1810e2bed107SBastian Koppelmann     for (i = 0; i < 16; i++) {
1811e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (2 * i + 1);
1812e2bed107SBastian Koppelmann         ret |= (r2 & 1) << (2 * i);
1813e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1814e2bed107SBastian Koppelmann         r2 = r2 >> 1;
1815e2bed107SBastian Koppelmann     }
1816e2bed107SBastian Koppelmann     return ret;
1817e2bed107SBastian Koppelmann }
1818e2bed107SBastian Koppelmann 
1819e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1)
1820e2bed107SBastian Koppelmann {
1821e2bed107SBastian Koppelmann     int32_t i;
1822e2bed107SBastian Koppelmann     uint64_t ret;
1823e2bed107SBastian Koppelmann 
1824e2bed107SBastian Koppelmann     ret = 0;
1825e2bed107SBastian Koppelmann     for (i = 0; i < 32; i = i + 2) {
1826e2bed107SBastian Koppelmann         /* even */
1827e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (i/2);
1828e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1829e2bed107SBastian Koppelmann         /* odd */
1830e2bed107SBastian Koppelmann         ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1831e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1832e2bed107SBastian Koppelmann     }
1833e2bed107SBastian Koppelmann     return ret;
1834e2bed107SBastian Koppelmann }
1835e2bed107SBastian Koppelmann 
1836e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1)
1837e2bed107SBastian Koppelmann {
1838e2bed107SBastian Koppelmann     uint32_t ret;
1839e2bed107SBastian Koppelmann     uint32_t nOnes, i;
1840e2bed107SBastian Koppelmann 
1841e2bed107SBastian Koppelmann     ret = 0;
1842e2bed107SBastian Koppelmann     nOnes = 0;
1843e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1844e2bed107SBastian Koppelmann         ret ^= (r1 & 1);
1845e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1846e2bed107SBastian Koppelmann     }
1847e2bed107SBastian Koppelmann     /* second byte */
1848e2bed107SBastian Koppelmann     nOnes = 0;
1849e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1850e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1851e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1852e2bed107SBastian Koppelmann     }
1853e2bed107SBastian Koppelmann     ret |= nOnes << 8;
1854e2bed107SBastian Koppelmann     /* third byte */
1855e2bed107SBastian Koppelmann     nOnes = 0;
1856e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1857e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1858e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1859e2bed107SBastian Koppelmann     }
1860e2bed107SBastian Koppelmann     ret |= nOnes << 16;
1861e2bed107SBastian Koppelmann     /* fourth byte */
1862e2bed107SBastian Koppelmann     nOnes = 0;
1863e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1864e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1865e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1866e2bed107SBastian Koppelmann     }
1867e2bed107SBastian Koppelmann     ret |= nOnes << 24;
1868e2bed107SBastian Koppelmann 
1869e2bed107SBastian Koppelmann     return ret;
1870e2bed107SBastian Koppelmann }
1871e2bed107SBastian Koppelmann 
187209532255SBastian Koppelmann uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
187309532255SBastian Koppelmann                      target_ulong r2)
187409532255SBastian Koppelmann {
187509532255SBastian Koppelmann     uint32_t ret;
187609532255SBastian Koppelmann     int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
187709532255SBastian Koppelmann     int32_t int_exp  = r1_high;
187809532255SBastian Koppelmann     int32_t int_mant = r1_low;
187909532255SBastian Koppelmann     uint32_t flag_rnd = (int_mant & (1 << 7)) && (
188009532255SBastian Koppelmann                         (int_mant & (1 << 8)) ||
188109532255SBastian Koppelmann                         (int_mant & 0x7f)     ||
188209532255SBastian Koppelmann                         (carry != 0));
188309532255SBastian Koppelmann     if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
188409532255SBastian Koppelmann         fp_exp = 255;
188509532255SBastian Koppelmann         fp_frac = extract32(int_mant, 8, 23);
188609532255SBastian Koppelmann     } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
188709532255SBastian Koppelmann         fp_exp  = 255;
188809532255SBastian Koppelmann         fp_frac = 0;
188909532255SBastian Koppelmann     } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
189009532255SBastian Koppelmann         fp_exp  = 0;
189109532255SBastian Koppelmann         fp_frac = 0;
189209532255SBastian Koppelmann     } else if (int_mant == 0) {
189309532255SBastian Koppelmann         fp_exp  = 0;
189409532255SBastian Koppelmann         fp_frac = 0;
189509532255SBastian Koppelmann     } else {
189609532255SBastian Koppelmann         if (((int_mant & (1 << 31)) == 0)) {
189709532255SBastian Koppelmann             temp_exp = 0;
189809532255SBastian Koppelmann         } else {
189909532255SBastian Koppelmann             temp_exp = int_exp + 128;
190009532255SBastian Koppelmann         }
190109532255SBastian Koppelmann         fp_exp_frac = (((temp_exp & 0xff) << 23) |
190209532255SBastian Koppelmann                       extract32(int_mant, 8, 23))
190309532255SBastian Koppelmann                       + flag_rnd;
190409532255SBastian Koppelmann         fp_exp  = extract32(fp_exp_frac, 23, 8);
190509532255SBastian Koppelmann         fp_frac = extract32(fp_exp_frac, 0, 23);
190609532255SBastian Koppelmann     }
190709532255SBastian Koppelmann     ret = r2 & (1 << 31);
190809532255SBastian Koppelmann     ret = ret + (fp_exp << 23);
190909532255SBastian Koppelmann     ret = ret + (fp_frac & 0x7fffff);
191009532255SBastian Koppelmann 
191109532255SBastian Koppelmann     return ret;
191209532255SBastian Koppelmann }
191309532255SBastian Koppelmann 
1914e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1)
1915e2bed107SBastian Koppelmann {
1916e2bed107SBastian Koppelmann     int32_t fp_exp  = extract32(arg1, 23, 8);
1917e2bed107SBastian Koppelmann     int32_t fp_frac = extract32(arg1, 0, 23);
1918e2bed107SBastian Koppelmann     uint64_t ret;
1919e2bed107SBastian Koppelmann     int32_t int_exp, int_mant;
1920e2bed107SBastian Koppelmann 
1921e2bed107SBastian Koppelmann     if (fp_exp == 255) {
1922e2bed107SBastian Koppelmann         int_exp = 255;
1923e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1924e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac == 0)) {
1925e2bed107SBastian Koppelmann         int_exp  = -127;
1926e2bed107SBastian Koppelmann         int_mant = 0;
1927e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac != 0)) {
1928e2bed107SBastian Koppelmann         int_exp  = -126;
1929e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1930e2bed107SBastian Koppelmann     } else {
1931e2bed107SBastian Koppelmann         int_exp  = fp_exp - 127;
1932e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1933e2bed107SBastian Koppelmann         int_mant |= (1 << 30);
1934e2bed107SBastian Koppelmann     }
1935e2bed107SBastian Koppelmann     ret = int_exp;
1936e2bed107SBastian Koppelmann     ret = ret << 32;
1937e2bed107SBastian Koppelmann     ret |= int_mant;
1938e2bed107SBastian Koppelmann 
1939e2bed107SBastian Koppelmann     return ret;
1940e2bed107SBastian Koppelmann }
1941e2bed107SBastian Koppelmann 
1942e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1943e2bed107SBastian Koppelmann {
1944e2bed107SBastian Koppelmann     uint64_t ret;
1945f69c24e4SBastian Koppelmann     int32_t abs_sig_dividend, abs_divisor;
1946e2bed107SBastian Koppelmann 
1947e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1948e2bed107SBastian Koppelmann     ret = ret << 24;
1949e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1950e2bed107SBastian Koppelmann         ret |= 0xffffff;
1951e2bed107SBastian Koppelmann     }
1952e2bed107SBastian Koppelmann 
1953f69c24e4SBastian Koppelmann     abs_sig_dividend = abs((int32_t)r1) >> 8;
195430a0d72fSStefan Weil     abs_divisor = abs((int32_t)r2);
1955f69c24e4SBastian Koppelmann     /* calc overflow
1956f69c24e4SBastian Koppelmann        ofv if (a/b >= 255) <=> (a/255 >= b) */
1957f69c24e4SBastian Koppelmann     env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
1958e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1959e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1960e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1961e2bed107SBastian Koppelmann 
1962e2bed107SBastian Koppelmann     return ret;
1963e2bed107SBastian Koppelmann }
1964e2bed107SBastian Koppelmann 
1965e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1966e2bed107SBastian Koppelmann {
1967e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
1968e2bed107SBastian Koppelmann 
1969e2bed107SBastian Koppelmann     ret = ret << 24;
1970e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1971e2bed107SBastian Koppelmann         ret |= 0xffffff;
1972e2bed107SBastian Koppelmann     }
1973e2bed107SBastian Koppelmann     /* calc overflow */
1974e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
1975e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1976e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1977e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1978e2bed107SBastian Koppelmann 
1979e2bed107SBastian Koppelmann     return ret;
1980e2bed107SBastian Koppelmann }
1981e2bed107SBastian Koppelmann 
1982e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1983e2bed107SBastian Koppelmann {
1984e2bed107SBastian Koppelmann     uint64_t ret;
1985f69c24e4SBastian Koppelmann     int32_t abs_sig_dividend, abs_divisor;
1986e2bed107SBastian Koppelmann 
1987e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1988e2bed107SBastian Koppelmann     ret = ret << 16;
1989e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1990e2bed107SBastian Koppelmann         ret |= 0xffff;
1991e2bed107SBastian Koppelmann     }
1992e2bed107SBastian Koppelmann 
1993f69c24e4SBastian Koppelmann     abs_sig_dividend = abs((int32_t)r1) >> 16;
199430a0d72fSStefan Weil     abs_divisor = abs((int32_t)r2);
1995f69c24e4SBastian Koppelmann     /* calc overflow
1996f69c24e4SBastian Koppelmann        ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */
1997f69c24e4SBastian Koppelmann     env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
1998e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1999e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
2000e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
2001e2bed107SBastian Koppelmann 
2002e2bed107SBastian Koppelmann     return ret;
2003e2bed107SBastian Koppelmann }
2004e2bed107SBastian Koppelmann 
2005e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2006e2bed107SBastian Koppelmann {
2007e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
2008e2bed107SBastian Koppelmann 
2009e2bed107SBastian Koppelmann     ret = ret << 16;
2010e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2011e2bed107SBastian Koppelmann         ret |= 0xffff;
2012e2bed107SBastian Koppelmann     }
2013e2bed107SBastian Koppelmann     /* calc overflow */
2014e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
2015e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
2016e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
2017e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
2018e2bed107SBastian Koppelmann 
2019e2bed107SBastian Koppelmann     return ret;
2020e2bed107SBastian Koppelmann }
2021e2bed107SBastian Koppelmann 
202209532255SBastian Koppelmann uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
202309532255SBastian Koppelmann {
202409532255SBastian Koppelmann     int32_t x_sign = (r1 >> 63);
202509532255SBastian Koppelmann     int32_t q_sign = x_sign ^ (r2 >> 31);
202609532255SBastian Koppelmann     int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
202709532255SBastian Koppelmann     int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
202809532255SBastian Koppelmann     uint32_t quotient;
202909532255SBastian Koppelmann     uint64_t ret, remainder;
203009532255SBastian Koppelmann 
203109532255SBastian Koppelmann     if ((q_sign & ~eq_neg) | eq_pos) {
203209532255SBastian Koppelmann         quotient = (r1 + 1) & 0xffffffff;
203309532255SBastian Koppelmann     } else {
203409532255SBastian Koppelmann         quotient = r1 & 0xffffffff;
203509532255SBastian Koppelmann     }
203609532255SBastian Koppelmann 
203709532255SBastian Koppelmann     if (eq_pos | eq_neg) {
203809532255SBastian Koppelmann         remainder = 0;
203909532255SBastian Koppelmann     } else {
204009532255SBastian Koppelmann         remainder = (r1 & 0xffffffff00000000ull);
204109532255SBastian Koppelmann     }
204209532255SBastian Koppelmann     ret = remainder|quotient;
204309532255SBastian Koppelmann     return ret;
204409532255SBastian Koppelmann }
204509532255SBastian Koppelmann 
204609532255SBastian Koppelmann uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
204709532255SBastian Koppelmann {
204809532255SBastian Koppelmann     int32_t dividend_sign = extract64(r1, 63, 1);
204909532255SBastian Koppelmann     int32_t divisor_sign = extract32(r2, 31, 1);
205009532255SBastian Koppelmann     int32_t quotient_sign = (dividend_sign != divisor_sign);
205109532255SBastian Koppelmann     int32_t addend, dividend_quotient, remainder;
205209532255SBastian Koppelmann     int32_t i, temp;
205309532255SBastian Koppelmann 
205409532255SBastian Koppelmann     if (quotient_sign) {
205509532255SBastian Koppelmann         addend = r2;
205609532255SBastian Koppelmann     } else {
205709532255SBastian Koppelmann         addend = -r2;
205809532255SBastian Koppelmann     }
205909532255SBastian Koppelmann     dividend_quotient = (int32_t)r1;
206009532255SBastian Koppelmann     remainder = (int32_t)(r1 >> 32);
206109532255SBastian Koppelmann 
206209532255SBastian Koppelmann     for (i = 0; i < 8; i++) {
206309532255SBastian Koppelmann         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
206409532255SBastian Koppelmann         dividend_quotient <<= 1;
206509532255SBastian Koppelmann         temp = remainder + addend;
206609532255SBastian Koppelmann         if ((temp < 0) == dividend_sign) {
206709532255SBastian Koppelmann             remainder = temp;
206809532255SBastian Koppelmann         }
206909532255SBastian Koppelmann         if (((temp < 0) == dividend_sign)) {
207009532255SBastian Koppelmann             dividend_quotient = dividend_quotient | !quotient_sign;
207109532255SBastian Koppelmann         } else {
207209532255SBastian Koppelmann             dividend_quotient = dividend_quotient | quotient_sign;
207309532255SBastian Koppelmann         }
207409532255SBastian Koppelmann     }
207509532255SBastian Koppelmann     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
207609532255SBastian Koppelmann }
207709532255SBastian Koppelmann 
207809532255SBastian Koppelmann uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
207909532255SBastian Koppelmann {
208009532255SBastian Koppelmann     int32_t dividend_quotient = extract64(r1, 0, 32);
208109532255SBastian Koppelmann     int64_t remainder = extract64(r1, 32, 32);
208209532255SBastian Koppelmann     int32_t i;
208309532255SBastian Koppelmann     int64_t temp;
208409532255SBastian Koppelmann     for (i = 0; i < 8; i++) {
208509532255SBastian Koppelmann         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
208609532255SBastian Koppelmann         dividend_quotient <<= 1;
208709532255SBastian Koppelmann         temp = (remainder & 0xffffffff) - r2;
208809532255SBastian Koppelmann         if (temp >= 0) {
208909532255SBastian Koppelmann             remainder = temp;
209009532255SBastian Koppelmann         }
209109532255SBastian Koppelmann         dividend_quotient = dividend_quotient | !(temp < 0);
209209532255SBastian Koppelmann     }
209309532255SBastian Koppelmann     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
209409532255SBastian Koppelmann }
209509532255SBastian Koppelmann 
20969655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
20979655b932SBastian Koppelmann                       uint32_t arg10, uint32_t arg11, uint32_t n)
20989655b932SBastian Koppelmann {
20999655b932SBastian Koppelmann     uint64_t ret;
21009655b932SBastian Koppelmann     uint32_t result0, result1;
21019655b932SBastian Koppelmann 
21029655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
21039655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
21049655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
21059655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
21069655b932SBastian Koppelmann     if (sc1) {
21079655b932SBastian Koppelmann         result1 = 0x7fffffff;
21089655b932SBastian Koppelmann     } else {
21099655b932SBastian Koppelmann         result1 = (((uint32_t)(arg00 * arg10)) << n);
21109655b932SBastian Koppelmann     }
21119655b932SBastian Koppelmann     if (sc0) {
21129655b932SBastian Koppelmann         result0 = 0x7fffffff;
21139655b932SBastian Koppelmann     } else {
21149655b932SBastian Koppelmann         result0 = (((uint32_t)(arg01 * arg11)) << n);
21159655b932SBastian Koppelmann     }
21169655b932SBastian Koppelmann     ret = (((uint64_t)result1 << 32)) | result0;
21179655b932SBastian Koppelmann     return ret;
21189655b932SBastian Koppelmann }
21199655b932SBastian Koppelmann 
21209655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
21219655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
21229655b932SBastian Koppelmann {
21239655b932SBastian Koppelmann     uint64_t ret;
21249655b932SBastian Koppelmann     int64_t result0, result1;
21259655b932SBastian Koppelmann 
21269655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
21279655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
21289655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
21299655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
21309655b932SBastian Koppelmann 
21319655b932SBastian Koppelmann     if (sc1) {
21329655b932SBastian Koppelmann         result1 = 0x7fffffff;
21339655b932SBastian Koppelmann     } else {
21349655b932SBastian Koppelmann         result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
21359655b932SBastian Koppelmann     }
21369655b932SBastian Koppelmann     if (sc0) {
21379655b932SBastian Koppelmann         result0 = 0x7fffffff;
21389655b932SBastian Koppelmann     } else {
21399655b932SBastian Koppelmann         result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
21409655b932SBastian Koppelmann     }
21419655b932SBastian Koppelmann     ret = (result1 + result0);
21429655b932SBastian Koppelmann     ret = ret << 16;
21439655b932SBastian Koppelmann     return ret;
21449655b932SBastian Koppelmann }
21459655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
21469655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
21479655b932SBastian Koppelmann {
21489655b932SBastian Koppelmann     uint32_t result0, result1;
21499655b932SBastian Koppelmann 
21509655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
21519655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
21529655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
21539655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
21549655b932SBastian Koppelmann 
21559655b932SBastian Koppelmann     if (sc1) {
21569655b932SBastian Koppelmann         result1 = 0x7fffffff;
21579655b932SBastian Koppelmann     } else {
21589655b932SBastian Koppelmann         result1 = ((arg00 * arg10) << n) + 0x8000;
21599655b932SBastian Koppelmann     }
21609655b932SBastian Koppelmann     if (sc0) {
21619655b932SBastian Koppelmann         result0 = 0x7fffffff;
21629655b932SBastian Koppelmann     } else {
21639655b932SBastian Koppelmann         result0 = ((arg01 * arg11) << n) + 0x8000;
21649655b932SBastian Koppelmann     }
21659655b932SBastian Koppelmann     return (result1 & 0xffff0000) | (result0 >> 16);
21669655b932SBastian Koppelmann }
21679655b932SBastian Koppelmann 
21689a31922bSBastian Koppelmann /* context save area (CSA) related helpers */
21699a31922bSBastian Koppelmann 
21709a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw)
21719a31922bSBastian Koppelmann {
21729a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
21739a31922bSBastian Koppelmann         return 0;
21749a31922bSBastian Koppelmann     }
21759a31922bSBastian Koppelmann 
21769a31922bSBastian Koppelmann     (*psw)++;
21779a31922bSBastian Koppelmann     /* check for overflow */
21789a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
21799a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
21809a31922bSBastian Koppelmann     int count = *psw & mask;
21819a31922bSBastian Koppelmann     if (count == 0) {
21829a31922bSBastian Koppelmann         (*psw)--;
21839a31922bSBastian Koppelmann         return 1;
21849a31922bSBastian Koppelmann     }
21859a31922bSBastian Koppelmann     return 0;
21869a31922bSBastian Koppelmann }
21879a31922bSBastian Koppelmann 
21889a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw)
21899a31922bSBastian Koppelmann {
21909a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
21919a31922bSBastian Koppelmann         return 0;
21929a31922bSBastian Koppelmann     }
21939a31922bSBastian Koppelmann     /* check for underflow */
21949a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
21959a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
21969a31922bSBastian Koppelmann     int count = *psw & mask;
21979a31922bSBastian Koppelmann     if (count == 0) {
21989a31922bSBastian Koppelmann         return 1;
21999a31922bSBastian Koppelmann     }
22009a31922bSBastian Koppelmann     (*psw)--;
22019a31922bSBastian Koppelmann     return 0;
22029a31922bSBastian Koppelmann }
22039a31922bSBastian Koppelmann 
220444ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw)
220544ea3430SBastian Koppelmann {
220644ea3430SBastian Koppelmann     int cdc = *psw & MASK_PSW_CDC;
220744ea3430SBastian Koppelmann     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
220844ea3430SBastian Koppelmann        7'b1111111, otherwise returns FALSE. */
220944ea3430SBastian Koppelmann     if (cdc == 0x7f) {
221044ea3430SBastian Koppelmann         return true;
221144ea3430SBastian Koppelmann     }
221244ea3430SBastian Koppelmann     /* find CDC.COUNT */
221344ea3430SBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
221444ea3430SBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
221544ea3430SBastian Koppelmann     int count = *psw & mask;
221644ea3430SBastian Koppelmann     return count == 0;
221744ea3430SBastian Koppelmann }
221844ea3430SBastian Koppelmann 
2219030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea)
22209a31922bSBastian Koppelmann {
22219a31922bSBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
22229a31922bSBastian Koppelmann     cpu_stl_data(env, ea+4, env->PSW);
22239a31922bSBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[10]);
22249a31922bSBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[11]);
22259a31922bSBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[8]);
22269a31922bSBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[9]);
22279a31922bSBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[10]);
22289a31922bSBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[11]);
22299a31922bSBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[12]);
22309a31922bSBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[13]);
22319a31922bSBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[14]);
22329a31922bSBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[15]);
22339a31922bSBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[12]);
22349a31922bSBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[13]);
22359a31922bSBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[14]);
22369a31922bSBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[15]);
22379a31922bSBastian Koppelmann }
22389a31922bSBastian Koppelmann 
2239030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea)
22405de93515SBastian Koppelmann {
22415de93515SBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
2242030c58dfSBastian Koppelmann     cpu_stl_data(env, ea+4, env->gpr_a[11]);
22435de93515SBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[2]);
22445de93515SBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[3]);
22455de93515SBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[0]);
22465de93515SBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[1]);
22475de93515SBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[2]);
22485de93515SBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[3]);
22495de93515SBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[4]);
22505de93515SBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[5]);
22515de93515SBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[6]);
22525de93515SBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[7]);
22535de93515SBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[4]);
22545de93515SBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[5]);
22555de93515SBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[6]);
22565de93515SBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[7]);
22575de93515SBastian Koppelmann }
22585de93515SBastian Koppelmann 
22599a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea,
22609a31922bSBastian Koppelmann                                   target_ulong *new_PCXI, target_ulong *new_PSW)
22619a31922bSBastian Koppelmann {
22629a31922bSBastian Koppelmann     *new_PCXI = cpu_ldl_data(env, ea);
22639a31922bSBastian Koppelmann     *new_PSW = cpu_ldl_data(env, ea+4);
22649a31922bSBastian Koppelmann     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
22659a31922bSBastian Koppelmann     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
22669a31922bSBastian Koppelmann     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
22679a31922bSBastian Koppelmann     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
22689a31922bSBastian Koppelmann     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
22699a31922bSBastian Koppelmann     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
22709a31922bSBastian Koppelmann     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
22719a31922bSBastian Koppelmann     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
22729a31922bSBastian Koppelmann     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
22739a31922bSBastian Koppelmann     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
22749a31922bSBastian Koppelmann     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
22759a31922bSBastian Koppelmann     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
22769a31922bSBastian Koppelmann     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
22779a31922bSBastian Koppelmann     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
22789a31922bSBastian Koppelmann }
22799a31922bSBastian Koppelmann 
228059543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea,
228159543d4eSBastian Koppelmann                                   target_ulong *ra, target_ulong *pcxi)
228259543d4eSBastian Koppelmann {
228359543d4eSBastian Koppelmann     *pcxi = cpu_ldl_data(env, ea);
228459543d4eSBastian Koppelmann     *ra = cpu_ldl_data(env, ea+4);
228559543d4eSBastian Koppelmann     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
228659543d4eSBastian Koppelmann     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
228759543d4eSBastian Koppelmann     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
228859543d4eSBastian Koppelmann     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
228959543d4eSBastian Koppelmann     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
229059543d4eSBastian Koppelmann     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
229159543d4eSBastian Koppelmann     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
229259543d4eSBastian Koppelmann     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
229359543d4eSBastian Koppelmann     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
229459543d4eSBastian Koppelmann     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
229559543d4eSBastian Koppelmann     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
229659543d4eSBastian Koppelmann     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
229759543d4eSBastian Koppelmann     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
229859543d4eSBastian Koppelmann     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
229959543d4eSBastian Koppelmann }
230059543d4eSBastian Koppelmann 
23019a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc)
23029a31922bSBastian Koppelmann {
23039a31922bSBastian Koppelmann     target_ulong tmp_FCX;
23049a31922bSBastian Koppelmann     target_ulong ea;
23059a31922bSBastian Koppelmann     target_ulong new_FCX;
23069a31922bSBastian Koppelmann     target_ulong psw;
23079a31922bSBastian Koppelmann 
23089a31922bSBastian Koppelmann     psw = psw_read(env);
23099a31922bSBastian Koppelmann     /* if (FCX == 0) trap(FCU); */
23109a31922bSBastian Koppelmann     if (env->FCX == 0) {
23119a31922bSBastian Koppelmann         /* FCU trap */
23129a31922bSBastian Koppelmann     }
23139a31922bSBastian Koppelmann     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
23149a31922bSBastian Koppelmann     if (psw & MASK_PSW_CDE) {
23159a31922bSBastian Koppelmann         if (cdc_increment(&psw)) {
23169a31922bSBastian Koppelmann             /* CDO trap */
23179a31922bSBastian Koppelmann         }
23189a31922bSBastian Koppelmann     }
23199a31922bSBastian Koppelmann     /* PSW.CDE = 1;*/
23209a31922bSBastian Koppelmann     psw |= MASK_PSW_CDE;
23219a31922bSBastian Koppelmann     /* tmp_FCX = FCX; */
23229a31922bSBastian Koppelmann     tmp_FCX = env->FCX;
23239a31922bSBastian Koppelmann     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
23249a31922bSBastian Koppelmann     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
23259a31922bSBastian Koppelmann          ((env->FCX & MASK_FCX_FCXO) << 6);
2326030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
2327030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
2328030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
23299a31922bSBastian Koppelmann                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
23309a31922bSBastian Koppelmann                            D[15]}; */
2331030c58dfSBastian Koppelmann     save_context_upper(env, ea);
23329a31922bSBastian Koppelmann 
23339a31922bSBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN; */
23349a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
23359a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_CCPN) << 24);
23369a31922bSBastian Koppelmann     /* PCXI.PIE = ICR.IE; */
23379a31922bSBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
23389a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_IE) << 15));
23399a31922bSBastian Koppelmann     /* PCXI.UL = 1; */
23409a31922bSBastian Koppelmann     env->PCXI |= MASK_PCXI_UL;
23419a31922bSBastian Koppelmann 
23429a31922bSBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0]; */
23439a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
23449a31922bSBastian Koppelmann     /* FCX[19: 0] = new_FCX[19: 0]; */
23459a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
23469a31922bSBastian Koppelmann     /* A[11] = next_pc[31: 0]; */
23479a31922bSBastian Koppelmann     env->gpr_a[11] = next_pc;
23489a31922bSBastian Koppelmann 
23499a31922bSBastian Koppelmann     /* if (tmp_FCX == LCX) trap(FCD);*/
23509a31922bSBastian Koppelmann     if (tmp_FCX == env->LCX) {
23519a31922bSBastian Koppelmann         /* FCD trap */
23529a31922bSBastian Koppelmann     }
23539a31922bSBastian Koppelmann     psw_write(env, psw);
23549a31922bSBastian Koppelmann }
23559a31922bSBastian Koppelmann 
23569a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env)
23579a31922bSBastian Koppelmann {
23589a31922bSBastian Koppelmann     target_ulong ea;
23599a31922bSBastian Koppelmann     target_ulong new_PCXI;
23609a31922bSBastian Koppelmann     target_ulong new_PSW, psw;
23619a31922bSBastian Koppelmann 
23629a31922bSBastian Koppelmann     psw = psw_read(env);
23639a31922bSBastian Koppelmann      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
23649a31922bSBastian Koppelmann     if (env->PSW & MASK_PSW_CDE) {
23659a31922bSBastian Koppelmann         if (cdc_decrement(&(env->PSW))) {
23669a31922bSBastian Koppelmann             /* CDU trap */
23679a31922bSBastian Koppelmann         }
23689a31922bSBastian Koppelmann     }
23699a31922bSBastian Koppelmann     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
23709a31922bSBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
23719a31922bSBastian Koppelmann         /* CSU trap */
23729a31922bSBastian Koppelmann     }
23739a31922bSBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
23749a31922bSBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
23759a31922bSBastian Koppelmann         /* CTYP trap */
23769a31922bSBastian Koppelmann     }
23779a31922bSBastian Koppelmann     /* PC = {A11 [31: 1], 1’b0}; */
23789a31922bSBastian Koppelmann     env->PC = env->gpr_a[11] & 0xfffffffe;
23799a31922bSBastian Koppelmann 
23809a31922bSBastian Koppelmann     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
23819a31922bSBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
23829a31922bSBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
23839a31922bSBastian Koppelmann     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2384030c58dfSBastian Koppelmann         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
23859a31922bSBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2386030c58dfSBastian Koppelmann     /* M(EA, word) = FCX; */
2387030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
23889a31922bSBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
23899a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
23909a31922bSBastian Koppelmann     /* PCXI = new_PCXI; */
23919a31922bSBastian Koppelmann     env->PCXI = new_PCXI;
23929a31922bSBastian Koppelmann 
23939a31922bSBastian Koppelmann     if (tricore_feature(env, TRICORE_FEATURE_13)) {
23949a31922bSBastian Koppelmann         /* PSW = new_PSW */
23959a31922bSBastian Koppelmann         psw_write(env, new_PSW);
23969a31922bSBastian Koppelmann     } else {
23979a31922bSBastian Koppelmann         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
23989a31922bSBastian Koppelmann         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
23999a31922bSBastian Koppelmann     }
24009a31922bSBastian Koppelmann }
24019a31922bSBastian Koppelmann 
24025de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9)
24035de93515SBastian Koppelmann {
24045de93515SBastian Koppelmann     target_ulong tmp_FCX;
24055de93515SBastian Koppelmann     target_ulong ea;
24065de93515SBastian Koppelmann     target_ulong new_FCX;
24075de93515SBastian Koppelmann 
24085de93515SBastian Koppelmann     if (env->FCX == 0) {
24095de93515SBastian Koppelmann         /* FCU trap */
24105de93515SBastian Koppelmann     }
24115de93515SBastian Koppelmann 
24125de93515SBastian Koppelmann     tmp_FCX = env->FCX;
24135de93515SBastian Koppelmann     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
24145de93515SBastian Koppelmann 
2415030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
2416030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
2417030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2418030c58dfSBastian Koppelmann                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2419030c58dfSBastian Koppelmann     save_context_lower(env, ea);
2420030c58dfSBastian Koppelmann 
24215de93515SBastian Koppelmann 
24225de93515SBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN */
24235de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
24245de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_CCPN) << 24);
24255de93515SBastian Koppelmann     /* PCXI.PIE  = ICR.IE */
24265de93515SBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
24275de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_IE) << 15));
24285de93515SBastian Koppelmann     /* PCXI.UL = 0 */
24295de93515SBastian Koppelmann     env->PCXI &= ~(MASK_PCXI_UL);
24305de93515SBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0] */
24315de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
24325de93515SBastian Koppelmann     /* FXC[19: 0] = new_FCX[19: 0] */
24335de93515SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
24345de93515SBastian Koppelmann     /* ICR.IE = 1 */
24355de93515SBastian Koppelmann     env->ICR |= MASK_ICR_IE;
24365de93515SBastian Koppelmann 
24375de93515SBastian Koppelmann     env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
24385de93515SBastian Koppelmann 
24395de93515SBastian Koppelmann     if (tmp_FCX == env->LCX) {
24405de93515SBastian Koppelmann         /* FCD trap */
24415de93515SBastian Koppelmann     }
24425de93515SBastian Koppelmann }
24435de93515SBastian Koppelmann 
244444ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env)
244544ea3430SBastian Koppelmann {
244644ea3430SBastian Koppelmann     target_ulong ea;
244744ea3430SBastian Koppelmann     target_ulong new_PCXI;
244844ea3430SBastian Koppelmann     target_ulong new_PSW;
244944ea3430SBastian Koppelmann     /* if (PCXI[19: 0] == 0) then trap(CSU); */
245044ea3430SBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
245144ea3430SBastian Koppelmann         /* raise csu trap */
245244ea3430SBastian Koppelmann     }
245344ea3430SBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
245444ea3430SBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
245544ea3430SBastian Koppelmann         /* raise CTYP trap */
245644ea3430SBastian Koppelmann     }
245744ea3430SBastian Koppelmann     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
245844ea3430SBastian Koppelmann     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
245944ea3430SBastian Koppelmann         /* raise MNG trap */
246044ea3430SBastian Koppelmann     }
246144ea3430SBastian Koppelmann     /* ICR.IE = PCXI.PIE; */
246244ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
246344ea3430SBastian Koppelmann     /* ICR.CCPN = PCXI.PCPN; */
246444ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
246544ea3430SBastian Koppelmann                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
246644ea3430SBastian Koppelmann     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
246744ea3430SBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
246844ea3430SBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
246944ea3430SBastian Koppelmann     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2470030c58dfSBastian Koppelmann       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
247144ea3430SBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2472030c58dfSBastian Koppelmann     /* M(EA, word) = FCX;*/
2473030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
247444ea3430SBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
247544ea3430SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
247644ea3430SBastian Koppelmann     /* PCXI = new_PCXI; */
247744ea3430SBastian Koppelmann     env->PCXI = new_PCXI;
247844ea3430SBastian Koppelmann     /* write psw */
247944ea3430SBastian Koppelmann     psw_write(env, new_PSW);
248044ea3430SBastian Koppelmann }
248144ea3430SBastian Koppelmann 
2482b724b012SBastian Koppelmann void helper_rfm(CPUTriCoreState *env)
2483b724b012SBastian Koppelmann {
2484b724b012SBastian Koppelmann     env->PC = (env->gpr_a[11] & ~0x1);
2485b724b012SBastian Koppelmann     /* ICR.IE = PCXI.PIE; */
2486b724b012SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_IE) |
2487b724b012SBastian Koppelmann                ((env->PCXI & ~MASK_PCXI_PIE) >> 15);
2488b724b012SBastian Koppelmann     /* ICR.CCPN = PCXI.PCPN; */
2489b724b012SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_CCPN) |
2490b724b012SBastian Koppelmann                ((env->PCXI & ~MASK_PCXI_PCPN) >> 24);
2491b724b012SBastian Koppelmann     /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */
2492b724b012SBastian Koppelmann     env->PCXI = cpu_ldl_data(env, env->DCX);
2493b724b012SBastian Koppelmann     psw_write(env, cpu_ldl_data(env, env->DCX+4));
2494b724b012SBastian Koppelmann     env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8);
2495b724b012SBastian Koppelmann     env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12);
2496b724b012SBastian Koppelmann 
2497b724b012SBastian Koppelmann     if (tricore_feature(env, TRICORE_FEATURE_131)) {
2498b724b012SBastian Koppelmann         env->DBGTCR = 0;
2499b724b012SBastian Koppelmann     }
2500b724b012SBastian Koppelmann }
2501b724b012SBastian Koppelmann 
250259543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
250359543d4eSBastian Koppelmann {
250459543d4eSBastian Koppelmann     uint32_t dummy;
250559543d4eSBastian Koppelmann     /* insn doesn't load PCXI and RA */
250659543d4eSBastian Koppelmann     restore_context_lower(env, ea, &dummy, &dummy);
250759543d4eSBastian Koppelmann }
250859543d4eSBastian Koppelmann 
250959543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea)
251059543d4eSBastian Koppelmann {
251159543d4eSBastian Koppelmann     uint32_t dummy;
251259543d4eSBastian Koppelmann     /* insn doesn't load PCXI and PSW */
251359543d4eSBastian Koppelmann     restore_context_upper(env, ea, &dummy, &dummy);
251459543d4eSBastian Koppelmann }
251559543d4eSBastian Koppelmann 
251659543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
251759543d4eSBastian Koppelmann {
251859543d4eSBastian Koppelmann     save_context_lower(env, ea);
251959543d4eSBastian Koppelmann }
252059543d4eSBastian Koppelmann 
252159543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea)
252259543d4eSBastian Koppelmann {
252359543d4eSBastian Koppelmann     save_context_upper(env, ea);
252459543d4eSBastian Koppelmann }
252559543d4eSBastian Koppelmann 
2526b724b012SBastian Koppelmann void helper_svlcx(CPUTriCoreState *env)
2527b724b012SBastian Koppelmann {
2528b724b012SBastian Koppelmann     target_ulong tmp_FCX;
2529b724b012SBastian Koppelmann     target_ulong ea;
2530b724b012SBastian Koppelmann     target_ulong new_FCX;
2531b724b012SBastian Koppelmann 
2532b724b012SBastian Koppelmann     if (env->FCX == 0) {
2533b724b012SBastian Koppelmann         /* FCU trap */
2534b724b012SBastian Koppelmann     }
2535b724b012SBastian Koppelmann     /* tmp_FCX = FCX; */
2536b724b012SBastian Koppelmann     tmp_FCX = env->FCX;
2537b724b012SBastian Koppelmann     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2538b724b012SBastian Koppelmann     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2539b724b012SBastian Koppelmann          ((env->FCX & MASK_FCX_FCXO) << 6);
2540b724b012SBastian Koppelmann     /* new_FCX = M(EA, word); */
2541b724b012SBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
2542b724b012SBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2543b724b012SBastian Koppelmann                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2544b724b012SBastian Koppelmann                            D[15]}; */
2545b724b012SBastian Koppelmann     save_context_lower(env, ea);
2546b724b012SBastian Koppelmann 
2547b724b012SBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN; */
2548b724b012SBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
2549b724b012SBastian Koppelmann                 ((env->ICR & MASK_ICR_CCPN) << 24);
2550b724b012SBastian Koppelmann     /* PCXI.PIE = ICR.IE; */
2551b724b012SBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2552b724b012SBastian Koppelmann                 ((env->ICR & MASK_ICR_IE) << 15));
2553b724b012SBastian Koppelmann     /* PCXI.UL = 0; */
2554b724b012SBastian Koppelmann     env->PCXI &= ~MASK_PCXI_UL;
2555b724b012SBastian Koppelmann 
2556b724b012SBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0]; */
2557b724b012SBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2558b724b012SBastian Koppelmann     /* FCX[19: 0] = new_FCX[19: 0]; */
2559b724b012SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2560b724b012SBastian Koppelmann 
2561b724b012SBastian Koppelmann     /* if (tmp_FCX == LCX) trap(FCD);*/
2562b724b012SBastian Koppelmann     if (tmp_FCX == env->LCX) {
2563b724b012SBastian Koppelmann         /* FCD trap */
2564b724b012SBastian Koppelmann     }
2565b724b012SBastian Koppelmann }
2566b724b012SBastian Koppelmann 
2567b724b012SBastian Koppelmann void helper_rslcx(CPUTriCoreState *env)
2568b724b012SBastian Koppelmann {
2569b724b012SBastian Koppelmann     target_ulong ea;
2570b724b012SBastian Koppelmann     target_ulong new_PCXI;
2571b724b012SBastian Koppelmann     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2572b724b012SBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
2573b724b012SBastian Koppelmann         /* CSU trap */
2574b724b012SBastian Koppelmann     }
2575b724b012SBastian Koppelmann     /* if (PCXI.UL == 1) then trap(CTYP); */
2576b724b012SBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 1) {
2577b724b012SBastian Koppelmann         /* CTYP trap */
2578b724b012SBastian Koppelmann     }
2579b724b012SBastian Koppelmann     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2580b724b012SBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2581b724b012SBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
2582b724b012SBastian Koppelmann     /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2583b724b012SBastian Koppelmann         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2584b724b012SBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &env->gpr_a[11]);
2585b724b012SBastian Koppelmann     /* M(EA, word) = FCX; */
2586b724b012SBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
2587b724b012SBastian Koppelmann     /* M(EA, word) = FCX; */
2588b724b012SBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
2589b724b012SBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
2590b724b012SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2591b724b012SBastian Koppelmann     /* PCXI = new_PCXI; */
2592b724b012SBastian Koppelmann     env->PCXI = new_PCXI;
2593b724b012SBastian Koppelmann }
2594b724b012SBastian Koppelmann 
25952b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
25962b2f7d97SBastian Koppelmann {
25972b2f7d97SBastian Koppelmann     psw_write(env, arg);
25982b2f7d97SBastian Koppelmann }
25992b2f7d97SBastian Koppelmann 
26002b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env)
26012b2f7d97SBastian Koppelmann {
26022b2f7d97SBastian Koppelmann     return psw_read(env);
26032b2f7d97SBastian Koppelmann }
26042b2f7d97SBastian Koppelmann 
26052b2f7d97SBastian Koppelmann 
26062d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
26072d30267eSBastian Koppelmann                                                         uint32_t exception,
26082d30267eSBastian Koppelmann                                                         int error_code,
26092d30267eSBastian Koppelmann                                                         uintptr_t pc)
26102d30267eSBastian Koppelmann {
26112d30267eSBastian Koppelmann     CPUState *cs = CPU(tricore_env_get_cpu(env));
26122d30267eSBastian Koppelmann     cs->exception_index = exception;
26132d30267eSBastian Koppelmann     env->error_code = error_code;
26142d30267eSBastian Koppelmann 
26152d30267eSBastian Koppelmann     if (pc) {
26162d30267eSBastian Koppelmann         /* now we have a real cpu fault */
26172d30267eSBastian Koppelmann         cpu_restore_state(cs, pc);
26182d30267eSBastian Koppelmann     }
26192d30267eSBastian Koppelmann 
26202d30267eSBastian Koppelmann     cpu_loop_exit(cs);
26212d30267eSBastian Koppelmann }
26222d30267eSBastian Koppelmann 
262348e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
262448e06fe0SBastian Koppelmann               uintptr_t retaddr)
262548e06fe0SBastian Koppelmann {
26262d30267eSBastian Koppelmann     int ret;
26272d30267eSBastian Koppelmann     ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
26282d30267eSBastian Koppelmann     if (ret) {
26292d30267eSBastian Koppelmann         TriCoreCPU *cpu = TRICORE_CPU(cs);
26302d30267eSBastian Koppelmann         CPUTriCoreState *env = &cpu->env;
26312d30267eSBastian Koppelmann         do_raise_exception_err(env, cs->exception_index,
26322d30267eSBastian Koppelmann                                env->error_code, retaddr);
263348e06fe0SBastian Koppelmann     }
26342d30267eSBastian Koppelmann }
2635