xref: /qemu/target/tricore/op_helper.c (revision 9371557115a734412974f8d4096cbe8a62ca2731)
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"
22e5c96c82SBastian Koppelmann #include <zlib.h> /* for crc32 */
2348e06fe0SBastian Koppelmann 
243a16ecb0SBastian Koppelmann /* Addressing mode helper */
253a16ecb0SBastian Koppelmann 
263a16ecb0SBastian Koppelmann static uint16_t reverse16(uint16_t val)
273a16ecb0SBastian Koppelmann {
283a16ecb0SBastian Koppelmann     uint8_t high = (uint8_t)(val >> 8);
293a16ecb0SBastian Koppelmann     uint8_t low  = (uint8_t)(val & 0xff);
303a16ecb0SBastian Koppelmann 
313a16ecb0SBastian Koppelmann     uint16_t rh, rl;
323a16ecb0SBastian Koppelmann 
333a16ecb0SBastian Koppelmann     rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
343a16ecb0SBastian Koppelmann     rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
353a16ecb0SBastian Koppelmann 
363a16ecb0SBastian Koppelmann     return (rh << 8) | rl;
373a16ecb0SBastian Koppelmann }
383a16ecb0SBastian Koppelmann 
393a16ecb0SBastian Koppelmann uint32_t helper_br_update(uint32_t reg)
403a16ecb0SBastian Koppelmann {
413a16ecb0SBastian Koppelmann     uint32_t index = reg & 0xffff;
423a16ecb0SBastian Koppelmann     uint32_t incr  = reg >> 16;
433a16ecb0SBastian Koppelmann     uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
443a16ecb0SBastian Koppelmann     return reg - index + new_index;
453a16ecb0SBastian Koppelmann }
463a16ecb0SBastian Koppelmann 
473a16ecb0SBastian Koppelmann uint32_t helper_circ_update(uint32_t reg, uint32_t off)
483a16ecb0SBastian Koppelmann {
493a16ecb0SBastian Koppelmann     uint32_t index = reg & 0xffff;
503a16ecb0SBastian Koppelmann     uint32_t length = reg >> 16;
513a16ecb0SBastian Koppelmann     int32_t new_index = index + off;
523a16ecb0SBastian Koppelmann     if (new_index < 0) {
533a16ecb0SBastian Koppelmann         new_index += length;
543a16ecb0SBastian Koppelmann     } else {
553a16ecb0SBastian Koppelmann         new_index %= length;
563a16ecb0SBastian Koppelmann     }
573a16ecb0SBastian Koppelmann     return reg - index + new_index;
583a16ecb0SBastian Koppelmann }
593a16ecb0SBastian Koppelmann 
60e4e39176SBastian Koppelmann static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
61e4e39176SBastian Koppelmann {
62e4e39176SBastian Koppelmann     uint32_t ret;
63e4e39176SBastian Koppelmann     int64_t max_pos = INT32_MAX;
64e4e39176SBastian Koppelmann     int64_t max_neg = INT32_MIN;
65e4e39176SBastian Koppelmann     if (arg > max_pos) {
66e4e39176SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
67e4e39176SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
68e4e39176SBastian Koppelmann         ret = (target_ulong)max_pos;
69e4e39176SBastian Koppelmann     } else {
70e4e39176SBastian Koppelmann         if (arg < max_neg) {
71e4e39176SBastian Koppelmann             env->PSW_USB_V = (1 << 31);
72e4e39176SBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
73e4e39176SBastian Koppelmann             ret = (target_ulong)max_neg;
74e4e39176SBastian Koppelmann         } else {
75e4e39176SBastian Koppelmann             env->PSW_USB_V = 0;
76e4e39176SBastian Koppelmann             ret = (target_ulong)arg;
77e4e39176SBastian Koppelmann         }
78e4e39176SBastian Koppelmann     }
79e4e39176SBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
80e4e39176SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
81e4e39176SBastian Koppelmann     return ret;
82e4e39176SBastian Koppelmann }
832692802aSBastian Koppelmann 
8485d604afSBastian Koppelmann static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg)
85e4e39176SBastian Koppelmann {
86e4e39176SBastian Koppelmann     uint32_t ret;
8785d604afSBastian Koppelmann     uint64_t max_pos = UINT32_MAX;
88e4e39176SBastian Koppelmann     if (arg > max_pos) {
89e4e39176SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
90e4e39176SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
91e4e39176SBastian Koppelmann         ret = (target_ulong)max_pos;
92e4e39176SBastian Koppelmann     } else {
9385d604afSBastian Koppelmann         env->PSW_USB_V = 0;
9485d604afSBastian Koppelmann         ret = (target_ulong)arg;
9585d604afSBastian Koppelmann      }
9685d604afSBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
9785d604afSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
9885d604afSBastian Koppelmann     return ret;
9985d604afSBastian Koppelmann }
10085d604afSBastian Koppelmann 
10185d604afSBastian Koppelmann static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg)
10285d604afSBastian Koppelmann {
10385d604afSBastian Koppelmann     uint32_t ret;
10485d604afSBastian Koppelmann 
105e4e39176SBastian Koppelmann     if (arg < 0) {
106e4e39176SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
107e4e39176SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
108e4e39176SBastian Koppelmann         ret = 0;
109e4e39176SBastian Koppelmann     } else {
110e4e39176SBastian Koppelmann         env->PSW_USB_V = 0;
111e4e39176SBastian Koppelmann         ret = (target_ulong)arg;
112e4e39176SBastian Koppelmann     }
113e4e39176SBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
114e4e39176SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
115e4e39176SBastian Koppelmann     return ret;
116e4e39176SBastian Koppelmann }
1170974257eSBastian Koppelmann 
118d5de7839SBastian Koppelmann static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
119d5de7839SBastian Koppelmann {
120d5de7839SBastian Koppelmann     int32_t max_pos = INT16_MAX;
121d5de7839SBastian Koppelmann     int32_t max_neg = INT16_MIN;
122d5de7839SBastian Koppelmann     int32_t av0, av1;
123d5de7839SBastian Koppelmann 
124d5de7839SBastian Koppelmann     env->PSW_USB_V = 0;
125d5de7839SBastian Koppelmann     av0 = hw0 ^ hw0 * 2u;
126d5de7839SBastian Koppelmann     if (hw0 > max_pos) {
127d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
128d5de7839SBastian Koppelmann         hw0 = max_pos;
129d5de7839SBastian Koppelmann     } else if (hw0 < max_neg) {
130d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
131d5de7839SBastian Koppelmann         hw0 = max_neg;
132d5de7839SBastian Koppelmann     }
133d5de7839SBastian Koppelmann 
134d5de7839SBastian Koppelmann     av1 = hw1 ^ hw1 * 2u;
135d5de7839SBastian Koppelmann     if (hw1 > max_pos) {
136d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
137d5de7839SBastian Koppelmann         hw1 = max_pos;
138d5de7839SBastian Koppelmann     } else if (hw1 < max_neg) {
139d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
140d5de7839SBastian Koppelmann         hw1 = max_neg;
141d5de7839SBastian Koppelmann     }
142d5de7839SBastian Koppelmann 
143d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
144d5de7839SBastian Koppelmann     env->PSW_USB_AV = (av0 | av1) << 16;
145d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
146d5de7839SBastian Koppelmann     return (hw0 & 0xffff) | (hw1 << 16);
147d5de7839SBastian Koppelmann }
148d5de7839SBastian Koppelmann 
149d5de7839SBastian Koppelmann static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
150d5de7839SBastian Koppelmann {
151d5de7839SBastian Koppelmann     int32_t max_pos = UINT16_MAX;
152d5de7839SBastian Koppelmann     int32_t av0, av1;
153d5de7839SBastian Koppelmann 
154d5de7839SBastian Koppelmann     env->PSW_USB_V = 0;
155d5de7839SBastian Koppelmann     av0 = hw0 ^ hw0 * 2u;
156d5de7839SBastian Koppelmann     if (hw0 > max_pos) {
157d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
158d5de7839SBastian Koppelmann         hw0 = max_pos;
159d5de7839SBastian Koppelmann     } else if (hw0 < 0) {
160d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
161d5de7839SBastian Koppelmann         hw0 = 0;
162d5de7839SBastian Koppelmann     }
163d5de7839SBastian Koppelmann 
164d5de7839SBastian Koppelmann     av1 = hw1 ^ hw1 * 2u;
165d5de7839SBastian Koppelmann     if (hw1 > max_pos) {
166d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
167d5de7839SBastian Koppelmann         hw1 = max_pos;
168d5de7839SBastian Koppelmann     } else if (hw1 < 0) {
169d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
170d5de7839SBastian Koppelmann         hw1 = 0;
171d5de7839SBastian Koppelmann     }
172d5de7839SBastian Koppelmann 
173d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
174d5de7839SBastian Koppelmann     env->PSW_USB_AV = (av0 | av1) << 16;
175d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
176d5de7839SBastian Koppelmann     return (hw0 & 0xffff) | (hw1 << 16);
177d5de7839SBastian Koppelmann }
1780974257eSBastian Koppelmann 
1792692802aSBastian Koppelmann target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
1802692802aSBastian Koppelmann                              target_ulong r2)
1812692802aSBastian Koppelmann {
1822692802aSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
1832692802aSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
1842692802aSBastian Koppelmann     int64_t result = t1 + t2;
185e4e39176SBastian Koppelmann     return ssov32(env, result);
1862692802aSBastian Koppelmann }
1872692802aSBastian Koppelmann 
1882e430e1cSBastian Koppelmann uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
1892e430e1cSBastian Koppelmann {
1902e430e1cSBastian Koppelmann     uint64_t result;
1912e430e1cSBastian Koppelmann     int64_t ovf;
1922e430e1cSBastian Koppelmann 
1932e430e1cSBastian Koppelmann     result = r1 + r2;
1942e430e1cSBastian Koppelmann     ovf = (result ^ r1) & ~(r1 ^ r2);
1952e430e1cSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
1962e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1972e430e1cSBastian Koppelmann     if (ovf < 0) {
1982e430e1cSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
1992e430e1cSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
2002e430e1cSBastian Koppelmann         /* ext_ret > MAX_INT */
2012e430e1cSBastian Koppelmann         if ((int64_t)r1 >= 0) {
2022e430e1cSBastian Koppelmann             result = INT64_MAX;
2032e430e1cSBastian Koppelmann         /* ext_ret < MIN_INT */
2042e430e1cSBastian Koppelmann         } else {
2052e430e1cSBastian Koppelmann             result = INT64_MIN;
2062e430e1cSBastian Koppelmann         }
2072e430e1cSBastian Koppelmann     } else {
2082e430e1cSBastian Koppelmann         env->PSW_USB_V = 0;
2092e430e1cSBastian Koppelmann     }
2102e430e1cSBastian Koppelmann     return result;
2112e430e1cSBastian Koppelmann }
2122e430e1cSBastian Koppelmann 
213d5de7839SBastian Koppelmann target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
214d5de7839SBastian Koppelmann                                target_ulong r2)
215d5de7839SBastian Koppelmann {
216d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
217d5de7839SBastian Koppelmann 
218d5de7839SBastian Koppelmann     ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16);
219d5de7839SBastian Koppelmann     ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16);
220d5de7839SBastian Koppelmann     return ssov16(env, ret_hw0, ret_hw1);
221d5de7839SBastian Koppelmann }
222d5de7839SBastian Koppelmann 
2232e430e1cSBastian Koppelmann uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
2242e430e1cSBastian Koppelmann                             uint32_t r2_h)
2252e430e1cSBastian Koppelmann {
2262e430e1cSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
2272e430e1cSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
2282e430e1cSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
2292e430e1cSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
2302e430e1cSBastian Koppelmann     int64_t result0, result1;
2312e430e1cSBastian Koppelmann     uint32_t ovf0, ovf1;
2322e430e1cSBastian Koppelmann     uint32_t avf0, avf1;
2332e430e1cSBastian Koppelmann 
2342e430e1cSBastian Koppelmann     ovf0 = ovf1 = 0;
2352e430e1cSBastian Koppelmann 
2362e430e1cSBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
2372e430e1cSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
2382e430e1cSBastian Koppelmann 
2392e430e1cSBastian Koppelmann     avf0 = result0 * 2u;
2402e430e1cSBastian Koppelmann     avf0 = result0 ^ avf0;
2412e430e1cSBastian Koppelmann     avf1 = result1 * 2u;
2422e430e1cSBastian Koppelmann     avf1 = result1 ^ avf1;
2432e430e1cSBastian Koppelmann 
2442e430e1cSBastian Koppelmann     if (result0 > INT32_MAX) {
2452e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
2462e430e1cSBastian Koppelmann         result0 = INT32_MAX;
2472e430e1cSBastian Koppelmann     } else if (result0 < INT32_MIN) {
2482e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
2492e430e1cSBastian Koppelmann         result0 = INT32_MIN;
2502e430e1cSBastian Koppelmann     }
2512e430e1cSBastian Koppelmann 
2522e430e1cSBastian Koppelmann     if (result1 > INT32_MAX) {
2532e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
2542e430e1cSBastian Koppelmann         result1 = INT32_MAX;
2552e430e1cSBastian Koppelmann     } else if (result1 < INT32_MIN) {
2562e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
2572e430e1cSBastian Koppelmann         result1 = INT32_MIN;
2582e430e1cSBastian Koppelmann     }
2592e430e1cSBastian Koppelmann 
2602e430e1cSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
2612e430e1cSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
2622e430e1cSBastian Koppelmann 
2632e430e1cSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
2642e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
2652e430e1cSBastian Koppelmann 
2662e430e1cSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
2672e430e1cSBastian Koppelmann }
2682e430e1cSBastian Koppelmann 
269bebe80fcSBastian Koppelmann uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
270bebe80fcSBastian Koppelmann                               uint32_t r2_h)
271bebe80fcSBastian Koppelmann {
272bebe80fcSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
273bebe80fcSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
274bebe80fcSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
275bebe80fcSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
276bebe80fcSBastian Koppelmann     int64_t result0, result1;
277bebe80fcSBastian Koppelmann     uint32_t ovf0, ovf1;
278bebe80fcSBastian Koppelmann     uint32_t avf0, avf1;
279bebe80fcSBastian Koppelmann 
280bebe80fcSBastian Koppelmann     ovf0 = ovf1 = 0;
281bebe80fcSBastian Koppelmann 
282bebe80fcSBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
283bebe80fcSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
284bebe80fcSBastian Koppelmann 
285bebe80fcSBastian Koppelmann     avf0 = result0 * 2u;
286bebe80fcSBastian Koppelmann     avf0 = result0 ^ avf0;
287bebe80fcSBastian Koppelmann     avf1 = result1 * 2u;
288bebe80fcSBastian Koppelmann     avf1 = result1 ^ avf1;
289bebe80fcSBastian Koppelmann 
290bebe80fcSBastian Koppelmann     if (result0 > INT32_MAX) {
291bebe80fcSBastian Koppelmann         ovf0 = (1 << 31);
292bebe80fcSBastian Koppelmann         result0 = INT32_MAX;
293bebe80fcSBastian Koppelmann     } else if (result0 < INT32_MIN) {
294bebe80fcSBastian Koppelmann         ovf0 = (1 << 31);
295bebe80fcSBastian Koppelmann         result0 = INT32_MIN;
296bebe80fcSBastian Koppelmann     }
297bebe80fcSBastian Koppelmann 
298bebe80fcSBastian Koppelmann     if (result1 > INT32_MAX) {
299bebe80fcSBastian Koppelmann         ovf1 = (1 << 31);
300bebe80fcSBastian Koppelmann         result1 = INT32_MAX;
301bebe80fcSBastian Koppelmann     } else if (result1 < INT32_MIN) {
302bebe80fcSBastian Koppelmann         ovf1 = (1 << 31);
303bebe80fcSBastian Koppelmann         result1 = INT32_MIN;
304bebe80fcSBastian Koppelmann     }
305bebe80fcSBastian Koppelmann 
306bebe80fcSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
307bebe80fcSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
308bebe80fcSBastian Koppelmann 
309bebe80fcSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
310bebe80fcSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
311bebe80fcSBastian Koppelmann 
312bebe80fcSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
313bebe80fcSBastian Koppelmann }
314bebe80fcSBastian Koppelmann 
3152e430e1cSBastian Koppelmann 
3160974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
3170974257eSBastian Koppelmann                              target_ulong r2)
3180974257eSBastian Koppelmann {
3190974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
3200974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
3210974257eSBastian Koppelmann     int64_t result = t1 + t2;
32285d604afSBastian Koppelmann     return suov32_pos(env, result);
3230974257eSBastian Koppelmann }
3240974257eSBastian Koppelmann 
325d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
326d5de7839SBastian Koppelmann                                target_ulong r2)
327d5de7839SBastian Koppelmann {
328d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
329d5de7839SBastian Koppelmann 
330d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
331d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
332d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
333d5de7839SBastian Koppelmann }
334d5de7839SBastian Koppelmann 
3352692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
3362692802aSBastian Koppelmann                              target_ulong r2)
3372692802aSBastian Koppelmann {
3382692802aSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3392692802aSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
3402692802aSBastian Koppelmann     int64_t result = t1 - t2;
341e4e39176SBastian Koppelmann     return ssov32(env, result);
3422692802aSBastian Koppelmann }
3432692802aSBastian Koppelmann 
344f4aef476SBastian Koppelmann uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
345f4aef476SBastian Koppelmann {
346f4aef476SBastian Koppelmann     uint64_t result;
347f4aef476SBastian Koppelmann     int64_t ovf;
348f4aef476SBastian Koppelmann 
349f4aef476SBastian Koppelmann     result = r1 - r2;
350f4aef476SBastian Koppelmann     ovf = (result ^ r1) & (r1 ^ r2);
351f4aef476SBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
352f4aef476SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
353f4aef476SBastian Koppelmann     if (ovf < 0) {
354f4aef476SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
355f4aef476SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
356f4aef476SBastian Koppelmann         /* ext_ret > MAX_INT */
357f4aef476SBastian Koppelmann         if ((int64_t)r1 >= 0) {
358f4aef476SBastian Koppelmann             result = INT64_MAX;
359f4aef476SBastian Koppelmann         /* ext_ret < MIN_INT */
360f4aef476SBastian Koppelmann         } else {
361f4aef476SBastian Koppelmann             result = INT64_MIN;
362f4aef476SBastian Koppelmann         }
363f4aef476SBastian Koppelmann     } else {
364f4aef476SBastian Koppelmann         env->PSW_USB_V = 0;
365f4aef476SBastian Koppelmann     }
366f4aef476SBastian Koppelmann     return result;
367f4aef476SBastian Koppelmann }
368f4aef476SBastian Koppelmann 
369d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
370d5de7839SBastian Koppelmann                              target_ulong r2)
371d5de7839SBastian Koppelmann {
372d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
373d5de7839SBastian Koppelmann 
374d5de7839SBastian Koppelmann     ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
375d5de7839SBastian Koppelmann     ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
376d5de7839SBastian Koppelmann     return ssov16(env, ret_hw0, ret_hw1);
377d5de7839SBastian Koppelmann }
378d5de7839SBastian Koppelmann 
379f4aef476SBastian Koppelmann uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
380f4aef476SBastian Koppelmann                             uint32_t r2_h)
381f4aef476SBastian Koppelmann {
382f4aef476SBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
383f4aef476SBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
384f4aef476SBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
385f4aef476SBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
386f4aef476SBastian Koppelmann     int64_t result0, result1;
387f4aef476SBastian Koppelmann     uint32_t ovf0, ovf1;
388f4aef476SBastian Koppelmann     uint32_t avf0, avf1;
389f4aef476SBastian Koppelmann 
390f4aef476SBastian Koppelmann     ovf0 = ovf1 = 0;
391f4aef476SBastian Koppelmann 
392f4aef476SBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
393f4aef476SBastian Koppelmann     result1 = r2_high - mul_res1 + 0x8000;
394f4aef476SBastian Koppelmann 
395f4aef476SBastian Koppelmann     avf0 = result0 * 2u;
396f4aef476SBastian Koppelmann     avf0 = result0 ^ avf0;
397f4aef476SBastian Koppelmann     avf1 = result1 * 2u;
398f4aef476SBastian Koppelmann     avf1 = result1 ^ avf1;
399f4aef476SBastian Koppelmann 
400f4aef476SBastian Koppelmann     if (result0 > INT32_MAX) {
401f4aef476SBastian Koppelmann         ovf0 = (1 << 31);
402f4aef476SBastian Koppelmann         result0 = INT32_MAX;
403f4aef476SBastian Koppelmann     } else if (result0 < INT32_MIN) {
404f4aef476SBastian Koppelmann         ovf0 = (1 << 31);
405f4aef476SBastian Koppelmann         result0 = INT32_MIN;
406f4aef476SBastian Koppelmann     }
407f4aef476SBastian Koppelmann 
408f4aef476SBastian Koppelmann     if (result1 > INT32_MAX) {
409f4aef476SBastian Koppelmann         ovf1 = (1 << 31);
410f4aef476SBastian Koppelmann         result1 = INT32_MAX;
411f4aef476SBastian Koppelmann     } else if (result1 < INT32_MIN) {
412f4aef476SBastian Koppelmann         ovf1 = (1 << 31);
413f4aef476SBastian Koppelmann         result1 = INT32_MIN;
414f4aef476SBastian Koppelmann     }
415f4aef476SBastian Koppelmann 
416f4aef476SBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
417f4aef476SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
418f4aef476SBastian Koppelmann 
419f4aef476SBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
420f4aef476SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
421f4aef476SBastian Koppelmann 
422f4aef476SBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
423f4aef476SBastian Koppelmann }
424f4aef476SBastian Koppelmann 
425068fac77SBastian Koppelmann uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
426068fac77SBastian Koppelmann                               uint32_t r2_h)
427068fac77SBastian Koppelmann {
428068fac77SBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
429068fac77SBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
430068fac77SBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
431068fac77SBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
432068fac77SBastian Koppelmann     int64_t result0, result1;
433068fac77SBastian Koppelmann     uint32_t ovf0, ovf1;
434068fac77SBastian Koppelmann     uint32_t avf0, avf1;
435068fac77SBastian Koppelmann 
436068fac77SBastian Koppelmann     ovf0 = ovf1 = 0;
437068fac77SBastian Koppelmann 
438068fac77SBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
439068fac77SBastian Koppelmann     result1 = r2_high - mul_res1 + 0x8000;
440068fac77SBastian Koppelmann 
441068fac77SBastian Koppelmann     avf0 = result0 * 2u;
442068fac77SBastian Koppelmann     avf0 = result0 ^ avf0;
443068fac77SBastian Koppelmann     avf1 = result1 * 2u;
444068fac77SBastian Koppelmann     avf1 = result1 ^ avf1;
445068fac77SBastian Koppelmann 
446068fac77SBastian Koppelmann     if (result0 > INT32_MAX) {
447068fac77SBastian Koppelmann         ovf0 = (1 << 31);
448068fac77SBastian Koppelmann         result0 = INT32_MAX;
449068fac77SBastian Koppelmann     } else if (result0 < INT32_MIN) {
450068fac77SBastian Koppelmann         ovf0 = (1 << 31);
451068fac77SBastian Koppelmann         result0 = INT32_MIN;
452068fac77SBastian Koppelmann     }
453068fac77SBastian Koppelmann 
454068fac77SBastian Koppelmann     if (result1 > INT32_MAX) {
455068fac77SBastian Koppelmann         ovf1 = (1 << 31);
456068fac77SBastian Koppelmann         result1 = INT32_MAX;
457068fac77SBastian Koppelmann     } else if (result1 < INT32_MIN) {
458068fac77SBastian Koppelmann         ovf1 = (1 << 31);
459068fac77SBastian Koppelmann         result1 = INT32_MIN;
460068fac77SBastian Koppelmann     }
461068fac77SBastian Koppelmann 
462068fac77SBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
463068fac77SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
464068fac77SBastian Koppelmann 
465068fac77SBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
466068fac77SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
467068fac77SBastian Koppelmann 
468068fac77SBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
469068fac77SBastian Koppelmann }
470068fac77SBastian Koppelmann 
4710974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
4720974257eSBastian Koppelmann                              target_ulong r2)
4730974257eSBastian Koppelmann {
4740974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
4750974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
4760974257eSBastian Koppelmann     int64_t result = t1 - t2;
47785d604afSBastian Koppelmann     return suov32_neg(env, result);
4780974257eSBastian Koppelmann }
4790974257eSBastian Koppelmann 
480d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
481d5de7839SBastian Koppelmann                                target_ulong r2)
482d5de7839SBastian Koppelmann {
483d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
484d5de7839SBastian Koppelmann 
485d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
486d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
487d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
488d5de7839SBastian Koppelmann }
489d5de7839SBastian Koppelmann 
4900974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
4910974257eSBastian Koppelmann                              target_ulong r2)
4920974257eSBastian Koppelmann {
4930974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
4940974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
4950974257eSBastian Koppelmann     int64_t result = t1 * t2;
496e4e39176SBastian Koppelmann     return ssov32(env, result);
4970974257eSBastian Koppelmann }
4980974257eSBastian Koppelmann 
4990974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
5000974257eSBastian Koppelmann                              target_ulong r2)
5010974257eSBastian Koppelmann {
5020974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
5030974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
5040974257eSBastian Koppelmann     int64_t result = t1 * t2;
5055f30046fSBastian Koppelmann 
50685d604afSBastian Koppelmann     return suov32_pos(env, result);
5070974257eSBastian Koppelmann }
5080974257eSBastian Koppelmann 
5090974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
5100974257eSBastian Koppelmann                              target_ulong r2)
5110974257eSBastian Koppelmann {
5120974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
5130974257eSBastian Koppelmann     int32_t t2 = sextract64(r2, 0, 6);
5140974257eSBastian Koppelmann     int64_t result;
5150974257eSBastian Koppelmann     if (t2 == 0) {
5160974257eSBastian Koppelmann         result = t1;
5170974257eSBastian Koppelmann     } else if (t2 > 0) {
5180974257eSBastian Koppelmann         result = t1 << t2;
5190974257eSBastian Koppelmann     } else {
5200974257eSBastian Koppelmann         result = t1 >> -t2;
5210974257eSBastian Koppelmann     }
522e4e39176SBastian Koppelmann     return ssov32(env, result);
5230974257eSBastian Koppelmann }
5240974257eSBastian Koppelmann 
525d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
526d5de7839SBastian Koppelmann {
527d5de7839SBastian Koppelmann     target_ulong result;
528d5de7839SBastian Koppelmann     result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
529d5de7839SBastian Koppelmann     return ssov32(env, result);
530d5de7839SBastian Koppelmann }
531d5de7839SBastian Koppelmann 
532d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
533d5de7839SBastian Koppelmann {
534d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
535d5de7839SBastian Koppelmann 
536d5de7839SBastian Koppelmann     ret_h0 = sextract32(r1, 0, 16);
537d5de7839SBastian Koppelmann     ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
538d5de7839SBastian Koppelmann 
539d5de7839SBastian Koppelmann     ret_h1 = sextract32(r1, 16, 16);
540d5de7839SBastian Koppelmann     ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
541d5de7839SBastian Koppelmann 
542d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
543d5de7839SBastian Koppelmann }
544d5de7839SBastian Koppelmann 
5450974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
5460974257eSBastian Koppelmann                                 target_ulong r2)
5470974257eSBastian Koppelmann {
5480974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
5490974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
5500974257eSBastian Koppelmann     int64_t result;
5510974257eSBastian Koppelmann 
5520974257eSBastian Koppelmann     if (t1 > t2) {
5530974257eSBastian Koppelmann         result = t1 - t2;
5540974257eSBastian Koppelmann     } else {
5550974257eSBastian Koppelmann         result = t2 - t1;
5560974257eSBastian Koppelmann     }
557e4e39176SBastian Koppelmann     return ssov32(env, result);
5580974257eSBastian Koppelmann }
559328f1f0fSBastian Koppelmann 
560d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
561d5de7839SBastian Koppelmann                               target_ulong r2)
562d5de7839SBastian Koppelmann {
563d5de7839SBastian Koppelmann     int32_t t1, t2;
564d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
565d5de7839SBastian Koppelmann 
566d5de7839SBastian Koppelmann     t1 = sextract32(r1, 0, 16);
567d5de7839SBastian Koppelmann     t2 = sextract32(r2, 0, 16);
568d5de7839SBastian Koppelmann     if (t1 > t2) {
569d5de7839SBastian Koppelmann         ret_h0 = t1 - t2;
570d5de7839SBastian Koppelmann     } else {
571d5de7839SBastian Koppelmann         ret_h0 = t2 - t1;
572d5de7839SBastian Koppelmann     }
573d5de7839SBastian Koppelmann 
574d5de7839SBastian Koppelmann     t1 = sextract32(r1, 16, 16);
575d5de7839SBastian Koppelmann     t2 = sextract32(r2, 16, 16);
576d5de7839SBastian Koppelmann     if (t1 > t2) {
577d5de7839SBastian Koppelmann         ret_h1 = t1 - t2;
578d5de7839SBastian Koppelmann     } else {
579d5de7839SBastian Koppelmann         ret_h1 = t2 - t1;
580d5de7839SBastian Koppelmann     }
581d5de7839SBastian Koppelmann 
582d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
583d5de7839SBastian Koppelmann }
584d5de7839SBastian Koppelmann 
585328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
586328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
587328f1f0fSBastian Koppelmann {
588328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
589328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
590328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
591328f1f0fSBastian Koppelmann     int64_t result;
592328f1f0fSBastian Koppelmann 
593328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
594e4e39176SBastian Koppelmann     return ssov32(env, result);
595328f1f0fSBastian Koppelmann }
596328f1f0fSBastian Koppelmann 
597328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
598328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
599328f1f0fSBastian Koppelmann {
600328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
601328f1f0fSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
602328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
603328f1f0fSBastian Koppelmann     int64_t result;
604328f1f0fSBastian Koppelmann 
605328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
60685d604afSBastian Koppelmann     return suov32_pos(env, result);
607328f1f0fSBastian Koppelmann }
608328f1f0fSBastian Koppelmann 
609328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
610328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
611328f1f0fSBastian Koppelmann {
612328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
613328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
614328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
615328f1f0fSBastian Koppelmann     int64_t mul;
616328f1f0fSBastian Koppelmann 
617328f1f0fSBastian Koppelmann     mul = t1 * t3;
618328f1f0fSBastian Koppelmann     ret = mul + r2;
619328f1f0fSBastian Koppelmann     ovf = (ret ^ mul) & ~(mul ^ r2);
620328f1f0fSBastian Koppelmann 
621811ea608SBastian Koppelmann     t1 = ret >> 32;
622811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
623811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
624811ea608SBastian Koppelmann 
625328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
626328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
627328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
628328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
629328f1f0fSBastian Koppelmann         if (mul >= 0) {
630328f1f0fSBastian Koppelmann             ret = INT64_MAX;
631328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
632328f1f0fSBastian Koppelmann         } else {
633328f1f0fSBastian Koppelmann             ret = INT64_MIN;
634328f1f0fSBastian Koppelmann         }
635328f1f0fSBastian Koppelmann     } else {
636328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
637328f1f0fSBastian Koppelmann     }
638328f1f0fSBastian Koppelmann 
639328f1f0fSBastian Koppelmann     return ret;
640328f1f0fSBastian Koppelmann }
641328f1f0fSBastian Koppelmann 
642b00aa8ecSBastian Koppelmann uint32_t
643b00aa8ecSBastian Koppelmann helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
644b00aa8ecSBastian Koppelmann {
645b00aa8ecSBastian Koppelmann     int64_t result;
646b00aa8ecSBastian Koppelmann 
647b00aa8ecSBastian Koppelmann     result = (r1 + r2);
648b00aa8ecSBastian Koppelmann 
649b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u);
650b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
651b00aa8ecSBastian Koppelmann 
652b00aa8ecSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
653b00aa8ecSBastian Koppelmann        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
654b00aa8ecSBastian Koppelmann        case, we flip the saturated value. */
655b00aa8ecSBastian Koppelmann     if (r2 == 0x8000000000000000LL) {
656b00aa8ecSBastian Koppelmann         if (result > 0x7fffffffLL) {
657b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
658b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
659b00aa8ecSBastian Koppelmann             result = INT32_MIN;
660b00aa8ecSBastian Koppelmann         } else if (result < -0x80000000LL) {
661b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
662b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
663b00aa8ecSBastian Koppelmann             result = INT32_MAX;
664b00aa8ecSBastian Koppelmann         } else {
665b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
666b00aa8ecSBastian Koppelmann         }
667b00aa8ecSBastian Koppelmann     } else {
668b00aa8ecSBastian Koppelmann         if (result > 0x7fffffffLL) {
669b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
670b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
671b00aa8ecSBastian Koppelmann             result = INT32_MAX;
672b00aa8ecSBastian Koppelmann         } else if (result < -0x80000000LL) {
673b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
674b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
675b00aa8ecSBastian Koppelmann             result = INT32_MIN;
676b00aa8ecSBastian Koppelmann         } else {
677b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
678b00aa8ecSBastian Koppelmann         }
679b00aa8ecSBastian Koppelmann     }
680b00aa8ecSBastian Koppelmann     return (uint32_t)result;
681b00aa8ecSBastian Koppelmann }
682b00aa8ecSBastian Koppelmann 
683b00aa8ecSBastian Koppelmann uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
684b00aa8ecSBastian Koppelmann                               uint32_t r3, uint32_t n)
685b00aa8ecSBastian Koppelmann {
686b00aa8ecSBastian Koppelmann     int64_t t1 = (int64_t)r1;
687b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
688b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
689b00aa8ecSBastian Koppelmann     int64_t result, mul;
690b00aa8ecSBastian Koppelmann     int64_t ovf;
691b00aa8ecSBastian Koppelmann 
692b00aa8ecSBastian Koppelmann     mul = (t2 * t3) << n;
693b00aa8ecSBastian Koppelmann     result = mul + t1;
694b00aa8ecSBastian Koppelmann 
695b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
696b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
697b00aa8ecSBastian Koppelmann 
698b00aa8ecSBastian Koppelmann     ovf = (result ^ mul) & ~(mul ^ t1);
699b00aa8ecSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
700b00aa8ecSBastian Koppelmann        if the mul was (0x80000000 * 0x80000000) << 1). If this is the
701b00aa8ecSBastian Koppelmann        case, we flip the saturated value. */
702b00aa8ecSBastian Koppelmann     if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) {
703b00aa8ecSBastian Koppelmann         if (ovf >= 0) {
704b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
705b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
706b00aa8ecSBastian Koppelmann             /* ext_ret > MAX_INT */
707b00aa8ecSBastian Koppelmann             if (mul < 0) {
708b00aa8ecSBastian Koppelmann                 result = INT64_MAX;
709b00aa8ecSBastian Koppelmann             /* ext_ret < MIN_INT */
710b00aa8ecSBastian Koppelmann             } else {
711b00aa8ecSBastian Koppelmann                result = INT64_MIN;
712b00aa8ecSBastian Koppelmann             }
713b00aa8ecSBastian Koppelmann         } else {
714b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
715b00aa8ecSBastian Koppelmann         }
716b00aa8ecSBastian Koppelmann     } else {
717b00aa8ecSBastian Koppelmann         if (ovf < 0) {
718b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
719b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
720b00aa8ecSBastian Koppelmann             /* ext_ret > MAX_INT */
721b00aa8ecSBastian Koppelmann             if (mul >= 0) {
722b00aa8ecSBastian Koppelmann                 result = INT64_MAX;
723b00aa8ecSBastian Koppelmann             /* ext_ret < MIN_INT */
724b00aa8ecSBastian Koppelmann             } else {
725b00aa8ecSBastian Koppelmann                result = INT64_MIN;
726b00aa8ecSBastian Koppelmann             }
727b00aa8ecSBastian Koppelmann         } else {
728b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
729b00aa8ecSBastian Koppelmann         }
730b00aa8ecSBastian Koppelmann     }
731b00aa8ecSBastian Koppelmann     return (uint64_t)result;
732b00aa8ecSBastian Koppelmann }
733b00aa8ecSBastian Koppelmann 
734b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
735b00aa8ecSBastian Koppelmann                              uint32_t r3, uint32_t n)
736b00aa8ecSBastian Koppelmann {
737b00aa8ecSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
738b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
739b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
740b00aa8ecSBastian Koppelmann     int64_t mul, ret;
741b00aa8ecSBastian Koppelmann 
742b00aa8ecSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
743b00aa8ecSBastian Koppelmann         mul = 0x7fffffff;
744b00aa8ecSBastian Koppelmann     } else {
745b00aa8ecSBastian Koppelmann         mul = (t2 * t3) << n;
746b00aa8ecSBastian Koppelmann     }
747b00aa8ecSBastian Koppelmann 
748b00aa8ecSBastian Koppelmann     ret = t1 + mul + 0x8000;
749b00aa8ecSBastian Koppelmann 
750b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
751b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
752b00aa8ecSBastian Koppelmann 
753b00aa8ecSBastian Koppelmann     if (ret > 0x7fffffffll) {
754b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
755b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
756b00aa8ecSBastian Koppelmann         ret = INT32_MAX;
757b00aa8ecSBastian Koppelmann     } else if (ret < -0x80000000ll) {
758b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
759b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
760b00aa8ecSBastian Koppelmann         ret = INT32_MIN;
761b00aa8ecSBastian Koppelmann     } else {
762b00aa8ecSBastian Koppelmann         env->PSW_USB_V = 0;
763b00aa8ecSBastian Koppelmann     }
764b00aa8ecSBastian Koppelmann     return ret & 0xffff0000ll;
765b00aa8ecSBastian Koppelmann }
766b00aa8ecSBastian Koppelmann 
767328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
768328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
769328f1f0fSBastian Koppelmann {
770328f1f0fSBastian Koppelmann     uint64_t ret, mul;
771328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
772328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
773328f1f0fSBastian Koppelmann 
774328f1f0fSBastian Koppelmann     mul = t1 * t3;
775328f1f0fSBastian Koppelmann     ret = mul + r2;
776328f1f0fSBastian Koppelmann 
777811ea608SBastian Koppelmann     t1 = ret >> 32;
778811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
779811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
780811ea608SBastian Koppelmann 
781328f1f0fSBastian Koppelmann     if (ret < r2) {
782328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
783328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
784328f1f0fSBastian Koppelmann         /* saturate */
785328f1f0fSBastian Koppelmann         ret = UINT64_MAX;
786328f1f0fSBastian Koppelmann     } else {
787328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
788328f1f0fSBastian Koppelmann     }
789328f1f0fSBastian Koppelmann     return ret;
790328f1f0fSBastian Koppelmann }
791328f1f0fSBastian Koppelmann 
792328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
793328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
794328f1f0fSBastian Koppelmann {
795328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
796328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
797328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
798328f1f0fSBastian Koppelmann     int64_t result;
799328f1f0fSBastian Koppelmann 
800328f1f0fSBastian Koppelmann     result = t2 - (t1 * t3);
801e4e39176SBastian Koppelmann     return ssov32(env, result);
802328f1f0fSBastian Koppelmann }
803328f1f0fSBastian Koppelmann 
804328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
805328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
806328f1f0fSBastian Koppelmann {
8073debbb5aSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
8083debbb5aSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
8093debbb5aSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
8103debbb5aSBastian Koppelmann     uint64_t result;
8113debbb5aSBastian Koppelmann     uint64_t mul;
812328f1f0fSBastian Koppelmann 
8133debbb5aSBastian Koppelmann     mul = (t1 * t3);
8143debbb5aSBastian Koppelmann     result = t2 - mul;
8153debbb5aSBastian Koppelmann 
8163debbb5aSBastian Koppelmann     env->PSW_USB_AV = result ^ result * 2u;
8173debbb5aSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
8183debbb5aSBastian Koppelmann     /* we calculate ovf by hand here, because the multiplication can overflow on
8193debbb5aSBastian Koppelmann        the host, which would give false results if we compare to less than
8203debbb5aSBastian Koppelmann        zero */
8213debbb5aSBastian Koppelmann     if (mul > t2) {
8223debbb5aSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
8233debbb5aSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
8243debbb5aSBastian Koppelmann         result = 0;
8253debbb5aSBastian Koppelmann     } else {
8263debbb5aSBastian Koppelmann         env->PSW_USB_V = 0;
8273debbb5aSBastian Koppelmann     }
8283debbb5aSBastian Koppelmann     return result;
829328f1f0fSBastian Koppelmann }
830328f1f0fSBastian Koppelmann 
831328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
832328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
833328f1f0fSBastian Koppelmann {
834328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
835328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
836328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
837328f1f0fSBastian Koppelmann     int64_t mul;
838328f1f0fSBastian Koppelmann 
839328f1f0fSBastian Koppelmann     mul = t1 * t3;
840328f1f0fSBastian Koppelmann     ret = r2 - mul;
841328f1f0fSBastian Koppelmann     ovf = (ret ^ r2) & (mul ^ r2);
842328f1f0fSBastian Koppelmann 
843811ea608SBastian Koppelmann     t1 = ret >> 32;
844811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
845811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
846811ea608SBastian Koppelmann 
847328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
848328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
849328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
850328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
851328f1f0fSBastian Koppelmann         if (mul < 0) {
852328f1f0fSBastian Koppelmann             ret = INT64_MAX;
853328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
854328f1f0fSBastian Koppelmann         } else {
855328f1f0fSBastian Koppelmann             ret = INT64_MIN;
856328f1f0fSBastian Koppelmann         }
857328f1f0fSBastian Koppelmann     } else {
858328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
859328f1f0fSBastian Koppelmann     }
860328f1f0fSBastian Koppelmann     return ret;
861328f1f0fSBastian Koppelmann }
862328f1f0fSBastian Koppelmann 
863328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
864328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
865328f1f0fSBastian Koppelmann {
866328f1f0fSBastian Koppelmann     uint64_t ret, mul;
867328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
868328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
869328f1f0fSBastian Koppelmann 
870328f1f0fSBastian Koppelmann     mul = t1 * t3;
871328f1f0fSBastian Koppelmann     ret = r2 - mul;
872328f1f0fSBastian Koppelmann 
873811ea608SBastian Koppelmann     t1 = ret >> 32;
874811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
875811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
876811ea608SBastian Koppelmann 
877328f1f0fSBastian Koppelmann     if (ret > r2) {
878328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
879328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
880328f1f0fSBastian Koppelmann         /* saturate */
881328f1f0fSBastian Koppelmann         ret = 0;
882328f1f0fSBastian Koppelmann     } else {
883328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
884328f1f0fSBastian Koppelmann     }
885328f1f0fSBastian Koppelmann     return ret;
886328f1f0fSBastian Koppelmann }
887328f1f0fSBastian Koppelmann 
88862e47b2eSBastian Koppelmann uint32_t
88962e47b2eSBastian Koppelmann helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
89062e47b2eSBastian Koppelmann {
89162e47b2eSBastian Koppelmann     int64_t result;
89262e47b2eSBastian Koppelmann     int64_t t1 = (int64_t)r1;
89362e47b2eSBastian Koppelmann     int64_t t2 = (int64_t)r2;
89462e47b2eSBastian Koppelmann 
89562e47b2eSBastian Koppelmann     result = t1 - t2;
89662e47b2eSBastian Koppelmann 
89762e47b2eSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u);
89862e47b2eSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
89962e47b2eSBastian Koppelmann 
90062e47b2eSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
90162e47b2eSBastian Koppelmann        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
90262e47b2eSBastian Koppelmann        case, we flip the saturated value. */
90362e47b2eSBastian Koppelmann     if (r2 == 0x8000000000000000LL) {
90462e47b2eSBastian Koppelmann         if (result > 0x7fffffffLL) {
90562e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
90662e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
90762e47b2eSBastian Koppelmann             result = INT32_MIN;
90862e47b2eSBastian Koppelmann         } else if (result < -0x80000000LL) {
90962e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
91062e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
91162e47b2eSBastian Koppelmann             result = INT32_MAX;
91262e47b2eSBastian Koppelmann         } else {
91362e47b2eSBastian Koppelmann             env->PSW_USB_V = 0;
91462e47b2eSBastian Koppelmann         }
91562e47b2eSBastian Koppelmann     } else {
91662e47b2eSBastian Koppelmann         if (result > 0x7fffffffLL) {
91762e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
91862e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
91962e47b2eSBastian Koppelmann             result = INT32_MAX;
92062e47b2eSBastian Koppelmann         } else if (result < -0x80000000LL) {
92162e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
92262e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
92362e47b2eSBastian Koppelmann             result = INT32_MIN;
92462e47b2eSBastian Koppelmann         } else {
92562e47b2eSBastian Koppelmann             env->PSW_USB_V = 0;
92662e47b2eSBastian Koppelmann         }
92762e47b2eSBastian Koppelmann     }
92862e47b2eSBastian Koppelmann     return (uint32_t)result;
92962e47b2eSBastian Koppelmann }
93062e47b2eSBastian Koppelmann 
93162e47b2eSBastian Koppelmann uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
93262e47b2eSBastian Koppelmann                               uint32_t r3, uint32_t n)
93362e47b2eSBastian Koppelmann {
93462e47b2eSBastian Koppelmann     int64_t t1 = (int64_t)r1;
93562e47b2eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
93662e47b2eSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
93762e47b2eSBastian Koppelmann     int64_t result, mul;
93862e47b2eSBastian Koppelmann     int64_t ovf;
93962e47b2eSBastian Koppelmann 
94062e47b2eSBastian Koppelmann     mul = (t2 * t3) << n;
94162e47b2eSBastian Koppelmann     result = t1 - mul;
94262e47b2eSBastian Koppelmann 
94362e47b2eSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
94462e47b2eSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
94562e47b2eSBastian Koppelmann 
94662e47b2eSBastian Koppelmann     ovf = (result ^ t1) & (t1 ^ mul);
94762e47b2eSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
94862e47b2eSBastian Koppelmann        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
94962e47b2eSBastian Koppelmann        case, we flip the saturated value. */
95062e47b2eSBastian Koppelmann     if (mul == 0x8000000000000000LL) {
95162e47b2eSBastian Koppelmann         if (ovf >= 0) {
95262e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
95362e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
95462e47b2eSBastian Koppelmann             /* ext_ret > MAX_INT */
95562e47b2eSBastian Koppelmann             if (mul >= 0) {
95662e47b2eSBastian Koppelmann                 result = INT64_MAX;
95762e47b2eSBastian Koppelmann             /* ext_ret < MIN_INT */
95862e47b2eSBastian Koppelmann             } else {
95962e47b2eSBastian Koppelmann                result = INT64_MIN;
96062e47b2eSBastian Koppelmann             }
96162e47b2eSBastian Koppelmann         }
96262e47b2eSBastian Koppelmann     } else {
96362e47b2eSBastian Koppelmann         if (ovf < 0) {
96462e47b2eSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
96562e47b2eSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
96662e47b2eSBastian Koppelmann             /* ext_ret > MAX_INT */
96762e47b2eSBastian Koppelmann             if (mul < 0) {
96862e47b2eSBastian Koppelmann                 result = INT64_MAX;
96962e47b2eSBastian Koppelmann             /* ext_ret < MIN_INT */
97062e47b2eSBastian Koppelmann             } else {
97162e47b2eSBastian Koppelmann                result = INT64_MIN;
97262e47b2eSBastian Koppelmann             }
97362e47b2eSBastian Koppelmann         } else {
97462e47b2eSBastian Koppelmann             env->PSW_USB_V = 0;
97562e47b2eSBastian Koppelmann         }
97662e47b2eSBastian Koppelmann     }
97762e47b2eSBastian Koppelmann 
97862e47b2eSBastian Koppelmann     return (uint64_t)result;
97962e47b2eSBastian Koppelmann }
98062e47b2eSBastian Koppelmann 
98162e47b2eSBastian Koppelmann uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
98262e47b2eSBastian Koppelmann                              uint32_t r3, uint32_t n)
98362e47b2eSBastian Koppelmann {
98462e47b2eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
98562e47b2eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
98662e47b2eSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
98762e47b2eSBastian Koppelmann     int64_t mul, ret;
98862e47b2eSBastian Koppelmann 
98962e47b2eSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
99062e47b2eSBastian Koppelmann         mul = 0x7fffffff;
99162e47b2eSBastian Koppelmann     } else {
99262e47b2eSBastian Koppelmann         mul = (t2 * t3) << n;
99362e47b2eSBastian Koppelmann     }
99462e47b2eSBastian Koppelmann 
99562e47b2eSBastian Koppelmann     ret = t1 - mul + 0x8000;
99662e47b2eSBastian Koppelmann 
99762e47b2eSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
99862e47b2eSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
99962e47b2eSBastian Koppelmann 
100062e47b2eSBastian Koppelmann     if (ret > 0x7fffffffll) {
100162e47b2eSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
100262e47b2eSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
100362e47b2eSBastian Koppelmann         ret = INT32_MAX;
100462e47b2eSBastian Koppelmann     } else if (ret < -0x80000000ll) {
100562e47b2eSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
100662e47b2eSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
100762e47b2eSBastian Koppelmann         ret = INT32_MIN;
100862e47b2eSBastian Koppelmann     } else {
100962e47b2eSBastian Koppelmann         env->PSW_USB_V = 0;
101062e47b2eSBastian Koppelmann     }
101162e47b2eSBastian Koppelmann     return ret & 0xffff0000ll;
101262e47b2eSBastian Koppelmann }
101362e47b2eSBastian Koppelmann 
1014d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
1015d5de7839SBastian Koppelmann {
1016d5de7839SBastian Koppelmann     int32_t b, i;
1017d5de7839SBastian Koppelmann     int32_t ovf = 0;
1018d5de7839SBastian Koppelmann     int32_t avf = 0;
1019d5de7839SBastian Koppelmann     int32_t ret = 0;
1020d5de7839SBastian Koppelmann 
1021d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1022d5de7839SBastian Koppelmann         b = sextract32(arg, i * 8, 8);
1023d5de7839SBastian Koppelmann         b = (b >= 0) ? b : (0 - b);
1024d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
1025d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
1026d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
1027d5de7839SBastian Koppelmann     }
1028d5de7839SBastian Koppelmann 
1029d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
1030d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1031d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
1032d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1033d5de7839SBastian Koppelmann 
1034d5de7839SBastian Koppelmann     return ret;
1035d5de7839SBastian Koppelmann }
1036d5de7839SBastian Koppelmann 
1037d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
1038d5de7839SBastian Koppelmann {
1039d5de7839SBastian Koppelmann     int32_t h, i;
1040d5de7839SBastian Koppelmann     int32_t ovf = 0;
1041d5de7839SBastian Koppelmann     int32_t avf = 0;
1042d5de7839SBastian Koppelmann     int32_t ret = 0;
1043d5de7839SBastian Koppelmann 
1044d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1045d5de7839SBastian Koppelmann         h = sextract32(arg, i * 16, 16);
1046d5de7839SBastian Koppelmann         h = (h >= 0) ? h : (0 - h);
1047d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
1048d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1049d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1050d5de7839SBastian Koppelmann     }
1051d5de7839SBastian Koppelmann 
1052d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
1053d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1054d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
1055d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1056d5de7839SBastian Koppelmann 
1057d5de7839SBastian Koppelmann     return ret;
1058d5de7839SBastian Koppelmann }
1059d5de7839SBastian Koppelmann 
1060d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1061d5de7839SBastian Koppelmann {
1062d5de7839SBastian Koppelmann     int32_t b, i;
1063d5de7839SBastian Koppelmann     int32_t extr_r2;
1064d5de7839SBastian Koppelmann     int32_t ovf = 0;
1065d5de7839SBastian Koppelmann     int32_t avf = 0;
1066d5de7839SBastian Koppelmann     int32_t ret = 0;
1067d5de7839SBastian Koppelmann 
1068d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1069d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
1070d5de7839SBastian Koppelmann         b = sextract32(r1, i * 8, 8);
1071d5de7839SBastian Koppelmann         b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
1072d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
1073d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
1074d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
1075d5de7839SBastian Koppelmann     }
1076d5de7839SBastian Koppelmann 
1077d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
1078d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1079d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
1080d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1081d5de7839SBastian Koppelmann     return ret;
1082d5de7839SBastian Koppelmann }
1083d5de7839SBastian Koppelmann 
1084d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1085d5de7839SBastian Koppelmann {
1086d5de7839SBastian Koppelmann     int32_t h, i;
1087d5de7839SBastian Koppelmann     int32_t extr_r2;
1088d5de7839SBastian Koppelmann     int32_t ovf = 0;
1089d5de7839SBastian Koppelmann     int32_t avf = 0;
1090d5de7839SBastian Koppelmann     int32_t ret = 0;
1091d5de7839SBastian Koppelmann 
1092d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1093d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
1094d5de7839SBastian Koppelmann         h = sextract32(r1, i * 16, 16);
1095d5de7839SBastian Koppelmann         h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
1096d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
1097d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1098d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1099d5de7839SBastian Koppelmann     }
1100d5de7839SBastian Koppelmann 
1101d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
1102d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1103d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
1104d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1105d5de7839SBastian Koppelmann 
1106d5de7839SBastian Koppelmann     return ret;
1107d5de7839SBastian Koppelmann }
1108d5de7839SBastian Koppelmann 
11092e430e1cSBastian Koppelmann uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
11102e430e1cSBastian Koppelmann                        uint32_t r2_h)
11112e430e1cSBastian Koppelmann {
11122e430e1cSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
11132e430e1cSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
11142e430e1cSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
11152e430e1cSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
11162e430e1cSBastian Koppelmann     int64_t result0, result1;
11172e430e1cSBastian Koppelmann     uint32_t ovf0, ovf1;
11182e430e1cSBastian Koppelmann     uint32_t avf0, avf1;
11192e430e1cSBastian Koppelmann 
11202e430e1cSBastian Koppelmann     ovf0 = ovf1 = 0;
11212e430e1cSBastian Koppelmann 
11222e430e1cSBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
11232e430e1cSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
11242e430e1cSBastian Koppelmann 
11252e430e1cSBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
11262e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
11272e430e1cSBastian Koppelmann     }
11282e430e1cSBastian Koppelmann 
11292e430e1cSBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
11302e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
11312e430e1cSBastian Koppelmann     }
11322e430e1cSBastian Koppelmann 
11332e430e1cSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
11342e430e1cSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
11352e430e1cSBastian Koppelmann 
11362e430e1cSBastian Koppelmann     avf0 = result0 * 2u;
11372e430e1cSBastian Koppelmann     avf0 = result0 ^ avf0;
11382e430e1cSBastian Koppelmann     avf1 = result1 * 2u;
11392e430e1cSBastian Koppelmann     avf1 = result1 ^ avf1;
11402e430e1cSBastian Koppelmann 
11412e430e1cSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
11422e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
11432e430e1cSBastian Koppelmann 
11442e430e1cSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
11452e430e1cSBastian Koppelmann }
11462e430e1cSBastian Koppelmann 
1147bebe80fcSBastian Koppelmann uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1148bebe80fcSBastian Koppelmann                          uint32_t r2_h)
1149bebe80fcSBastian Koppelmann {
1150bebe80fcSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
1151bebe80fcSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
1152bebe80fcSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
1153bebe80fcSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
1154bebe80fcSBastian Koppelmann     int64_t result0, result1;
1155bebe80fcSBastian Koppelmann     uint32_t ovf0, ovf1;
1156bebe80fcSBastian Koppelmann     uint32_t avf0, avf1;
1157bebe80fcSBastian Koppelmann 
1158bebe80fcSBastian Koppelmann     ovf0 = ovf1 = 0;
1159bebe80fcSBastian Koppelmann 
1160bebe80fcSBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
1161bebe80fcSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
1162bebe80fcSBastian Koppelmann 
1163bebe80fcSBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1164bebe80fcSBastian Koppelmann         ovf0 = (1 << 31);
1165bebe80fcSBastian Koppelmann     }
1166bebe80fcSBastian Koppelmann 
1167bebe80fcSBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1168bebe80fcSBastian Koppelmann         ovf1 = (1 << 31);
1169bebe80fcSBastian Koppelmann     }
1170bebe80fcSBastian Koppelmann 
1171bebe80fcSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
1172bebe80fcSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1173bebe80fcSBastian Koppelmann 
1174bebe80fcSBastian Koppelmann     avf0 = result0 * 2u;
1175bebe80fcSBastian Koppelmann     avf0 = result0 ^ avf0;
1176bebe80fcSBastian Koppelmann     avf1 = result1 * 2u;
1177bebe80fcSBastian Koppelmann     avf1 = result1 ^ avf1;
1178bebe80fcSBastian Koppelmann 
1179bebe80fcSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
1180bebe80fcSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1181bebe80fcSBastian Koppelmann 
1182bebe80fcSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1183bebe80fcSBastian Koppelmann }
1184bebe80fcSBastian Koppelmann 
1185b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1186b00aa8ecSBastian Koppelmann                         uint32_t r3, uint32_t n)
1187b00aa8ecSBastian Koppelmann {
1188b00aa8ecSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
1189b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
1190b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
1191b00aa8ecSBastian Koppelmann     int64_t mul, ret;
1192b00aa8ecSBastian Koppelmann 
1193b00aa8ecSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1194b00aa8ecSBastian Koppelmann         mul = 0x7fffffff;
1195b00aa8ecSBastian Koppelmann     } else {
1196b00aa8ecSBastian Koppelmann         mul = (t2 * t3) << n;
1197b00aa8ecSBastian Koppelmann     }
1198b00aa8ecSBastian Koppelmann 
1199b00aa8ecSBastian Koppelmann     ret = t1 + mul + 0x8000;
1200b00aa8ecSBastian Koppelmann 
1201b00aa8ecSBastian Koppelmann     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1202b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
1203b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
1204b00aa8ecSBastian Koppelmann     } else {
1205b00aa8ecSBastian Koppelmann         env->PSW_USB_V = 0;
1206b00aa8ecSBastian Koppelmann     }
1207b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
1208b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1209b00aa8ecSBastian Koppelmann 
1210b00aa8ecSBastian Koppelmann     return ret & 0xffff0000ll;
1211b00aa8ecSBastian Koppelmann }
1212b00aa8ecSBastian Koppelmann 
1213d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1214d5de7839SBastian Koppelmann {
1215d5de7839SBastian Koppelmann     int32_t b, i;
1216d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1217d5de7839SBastian Koppelmann     int32_t ovf = 0;
1218d5de7839SBastian Koppelmann     int32_t avf = 0;
1219d5de7839SBastian Koppelmann     uint32_t ret = 0;
1220d5de7839SBastian Koppelmann 
1221d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1222d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
1223d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
1224d5de7839SBastian Koppelmann 
1225d5de7839SBastian Koppelmann         b = extr_r1 + extr_r2;
1226d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
1227d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
1228d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
1229d5de7839SBastian Koppelmann     }
1230d5de7839SBastian Koppelmann 
1231d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1232d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1233d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
1234d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1235d5de7839SBastian Koppelmann 
1236d5de7839SBastian Koppelmann     return ret;
1237d5de7839SBastian Koppelmann }
1238d5de7839SBastian Koppelmann 
1239d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1240d5de7839SBastian Koppelmann {
1241d5de7839SBastian Koppelmann     int32_t h, i;
1242d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1243d5de7839SBastian Koppelmann     int32_t ovf = 0;
1244d5de7839SBastian Koppelmann     int32_t avf = 0;
1245d5de7839SBastian Koppelmann     int32_t ret = 0;
1246d5de7839SBastian Koppelmann 
1247d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1248d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
1249d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
1250d5de7839SBastian Koppelmann         h = extr_r1 + extr_r2;
1251d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
1252d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1253d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1254d5de7839SBastian Koppelmann     }
1255d5de7839SBastian Koppelmann 
1256d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1257d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1258d5de7839SBastian Koppelmann     env->PSW_USB_AV = (avf << 16);
1259d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1260d5de7839SBastian Koppelmann 
1261d5de7839SBastian Koppelmann     return ret;
1262d5de7839SBastian Koppelmann }
1263d5de7839SBastian Koppelmann 
1264f4aef476SBastian Koppelmann uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1265f4aef476SBastian Koppelmann                        uint32_t r2_h)
1266f4aef476SBastian Koppelmann {
1267f4aef476SBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
1268f4aef476SBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
1269f4aef476SBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
1270f4aef476SBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
1271f4aef476SBastian Koppelmann     int64_t result0, result1;
1272f4aef476SBastian Koppelmann     uint32_t ovf0, ovf1;
1273f4aef476SBastian Koppelmann     uint32_t avf0, avf1;
1274f4aef476SBastian Koppelmann 
1275f4aef476SBastian Koppelmann     ovf0 = ovf1 = 0;
1276f4aef476SBastian Koppelmann 
1277f4aef476SBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
1278f4aef476SBastian Koppelmann     result1 = r2_high - mul_res1 + 0x8000;
1279f4aef476SBastian Koppelmann 
1280f4aef476SBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1281f4aef476SBastian Koppelmann         ovf0 = (1 << 31);
1282f4aef476SBastian Koppelmann     }
1283f4aef476SBastian Koppelmann 
1284f4aef476SBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1285f4aef476SBastian Koppelmann         ovf1 = (1 << 31);
1286f4aef476SBastian Koppelmann     }
1287f4aef476SBastian Koppelmann 
1288f4aef476SBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
1289f4aef476SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1290f4aef476SBastian Koppelmann 
1291f4aef476SBastian Koppelmann     avf0 = result0 * 2u;
1292f4aef476SBastian Koppelmann     avf0 = result0 ^ avf0;
1293f4aef476SBastian Koppelmann     avf1 = result1 * 2u;
1294f4aef476SBastian Koppelmann     avf1 = result1 ^ avf1;
1295f4aef476SBastian Koppelmann 
1296f4aef476SBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
1297f4aef476SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1298f4aef476SBastian Koppelmann 
1299f4aef476SBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1300f4aef476SBastian Koppelmann }
1301f4aef476SBastian Koppelmann 
1302068fac77SBastian Koppelmann uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1303068fac77SBastian Koppelmann                          uint32_t r2_h)
1304068fac77SBastian Koppelmann {
1305068fac77SBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
1306068fac77SBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
1307068fac77SBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
1308068fac77SBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
1309068fac77SBastian Koppelmann     int64_t result0, result1;
1310068fac77SBastian Koppelmann     uint32_t ovf0, ovf1;
1311068fac77SBastian Koppelmann     uint32_t avf0, avf1;
1312068fac77SBastian Koppelmann 
1313068fac77SBastian Koppelmann     ovf0 = ovf1 = 0;
1314068fac77SBastian Koppelmann 
1315068fac77SBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
1316068fac77SBastian Koppelmann     result1 = r2_high - mul_res1 + 0x8000;
1317068fac77SBastian Koppelmann 
1318068fac77SBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1319068fac77SBastian Koppelmann         ovf0 = (1 << 31);
1320068fac77SBastian Koppelmann     }
1321068fac77SBastian Koppelmann 
1322068fac77SBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1323068fac77SBastian Koppelmann         ovf1 = (1 << 31);
1324068fac77SBastian Koppelmann     }
1325068fac77SBastian Koppelmann 
1326068fac77SBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
1327068fac77SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1328068fac77SBastian Koppelmann 
1329068fac77SBastian Koppelmann     avf0 = result0 * 2u;
1330068fac77SBastian Koppelmann     avf0 = result0 ^ avf0;
1331068fac77SBastian Koppelmann     avf1 = result1 * 2u;
1332068fac77SBastian Koppelmann     avf1 = result1 ^ avf1;
1333068fac77SBastian Koppelmann 
1334068fac77SBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
1335068fac77SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1336068fac77SBastian Koppelmann 
1337068fac77SBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1338068fac77SBastian Koppelmann }
1339068fac77SBastian Koppelmann 
134062e47b2eSBastian Koppelmann uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
134162e47b2eSBastian Koppelmann                         uint32_t r3, uint32_t n)
134262e47b2eSBastian Koppelmann {
134362e47b2eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
134462e47b2eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
134562e47b2eSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
134662e47b2eSBastian Koppelmann     int64_t mul, ret;
134762e47b2eSBastian Koppelmann 
134862e47b2eSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
134962e47b2eSBastian Koppelmann         mul = 0x7fffffff;
135062e47b2eSBastian Koppelmann     } else {
135162e47b2eSBastian Koppelmann         mul = (t2 * t3) << n;
135262e47b2eSBastian Koppelmann     }
135362e47b2eSBastian Koppelmann 
135462e47b2eSBastian Koppelmann     ret = t1 - mul + 0x8000;
135562e47b2eSBastian Koppelmann 
135662e47b2eSBastian Koppelmann     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
135762e47b2eSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
135862e47b2eSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
135962e47b2eSBastian Koppelmann     } else {
136062e47b2eSBastian Koppelmann         env->PSW_USB_V = 0;
136162e47b2eSBastian Koppelmann     }
136262e47b2eSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
136362e47b2eSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
136462e47b2eSBastian Koppelmann 
136562e47b2eSBastian Koppelmann     return ret & 0xffff0000ll;
136662e47b2eSBastian Koppelmann }
136762e47b2eSBastian Koppelmann 
1368d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1369d5de7839SBastian Koppelmann {
1370d5de7839SBastian Koppelmann     int32_t b, i;
1371d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1372d5de7839SBastian Koppelmann     int32_t ovf = 0;
1373d5de7839SBastian Koppelmann     int32_t avf = 0;
1374d5de7839SBastian Koppelmann     uint32_t ret = 0;
1375d5de7839SBastian Koppelmann 
1376d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1377d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
1378d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
1379d5de7839SBastian Koppelmann 
1380d5de7839SBastian Koppelmann         b = extr_r1 - extr_r2;
1381d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
1382d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
1383d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
1384d5de7839SBastian Koppelmann     }
1385d5de7839SBastian Koppelmann 
1386d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1387d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1388d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
1389d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1390d5de7839SBastian Koppelmann 
1391d5de7839SBastian Koppelmann     return ret;
1392d5de7839SBastian Koppelmann }
1393d5de7839SBastian Koppelmann 
1394d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1395d5de7839SBastian Koppelmann {
1396d5de7839SBastian Koppelmann     int32_t h, i;
1397d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1398d5de7839SBastian Koppelmann     int32_t ovf = 0;
1399d5de7839SBastian Koppelmann     int32_t avf = 0;
1400d5de7839SBastian Koppelmann     int32_t ret = 0;
1401d5de7839SBastian Koppelmann 
1402d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1403d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
1404d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
1405d5de7839SBastian Koppelmann         h = extr_r1 - extr_r2;
1406d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
1407d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1408d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1409d5de7839SBastian Koppelmann     }
1410d5de7839SBastian Koppelmann 
1411d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1412d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1413d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
1414d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1415d5de7839SBastian Koppelmann 
1416d5de7839SBastian Koppelmann     return ret;
1417d5de7839SBastian Koppelmann }
1418d5de7839SBastian Koppelmann 
1419d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
1420d5de7839SBastian Koppelmann {
1421d5de7839SBastian Koppelmann     int32_t ret;
1422d5de7839SBastian Koppelmann     int32_t i, msk;
1423d5de7839SBastian Koppelmann 
1424d5de7839SBastian Koppelmann     ret = 0;
1425d5de7839SBastian Koppelmann     msk = 0xff;
1426d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1427d5de7839SBastian Koppelmann         if ((r1 & msk) == (r2 & msk)) {
1428d5de7839SBastian Koppelmann             ret |= msk;
1429d5de7839SBastian Koppelmann         }
1430d5de7839SBastian Koppelmann         msk = msk << 8;
1431d5de7839SBastian Koppelmann     }
1432d5de7839SBastian Koppelmann 
1433d5de7839SBastian Koppelmann     return ret;
1434d5de7839SBastian Koppelmann }
1435d5de7839SBastian Koppelmann 
1436d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
1437d5de7839SBastian Koppelmann {
1438d5de7839SBastian Koppelmann     int32_t ret = 0;
1439d5de7839SBastian Koppelmann 
1440d5de7839SBastian Koppelmann     if ((r1 & 0xffff) == (r2 & 0xffff)) {
1441d5de7839SBastian Koppelmann         ret = 0xffff;
1442d5de7839SBastian Koppelmann     }
1443d5de7839SBastian Koppelmann 
1444d5de7839SBastian Koppelmann     if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
1445d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1446d5de7839SBastian Koppelmann     }
1447d5de7839SBastian Koppelmann 
1448d5de7839SBastian Koppelmann     return ret;
1449d5de7839SBastian Koppelmann }
1450d5de7839SBastian Koppelmann 
1451d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
1452d5de7839SBastian Koppelmann {
1453d5de7839SBastian Koppelmann     int32_t i;
1454d5de7839SBastian Koppelmann     uint32_t ret = 0;
1455d5de7839SBastian Koppelmann 
1456d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1457d5de7839SBastian Koppelmann         ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
1458d5de7839SBastian Koppelmann     }
1459d5de7839SBastian Koppelmann 
1460d5de7839SBastian Koppelmann     return ret;
1461d5de7839SBastian Koppelmann }
1462d5de7839SBastian Koppelmann 
1463d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
1464d5de7839SBastian Koppelmann {
1465d5de7839SBastian Koppelmann     uint32_t ret;
1466d5de7839SBastian Koppelmann 
1467d5de7839SBastian Koppelmann     ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
1468d5de7839SBastian Koppelmann     ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
1469d5de7839SBastian Koppelmann 
1470d5de7839SBastian Koppelmann     return ret;
1471d5de7839SBastian Koppelmann }
1472d5de7839SBastian Koppelmann 
1473d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
1474d5de7839SBastian Koppelmann {
1475d5de7839SBastian Koppelmann     int32_t i;
1476d5de7839SBastian Koppelmann     uint32_t ret = 0;
1477d5de7839SBastian Koppelmann 
1478d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1479d5de7839SBastian Koppelmann         if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
1480d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
1481d5de7839SBastian Koppelmann         }
1482d5de7839SBastian Koppelmann     }
1483d5de7839SBastian Koppelmann 
1484d5de7839SBastian Koppelmann     return ret;
1485d5de7839SBastian Koppelmann }
1486d5de7839SBastian Koppelmann 
1487d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
1488d5de7839SBastian Koppelmann {
1489d5de7839SBastian Koppelmann     int32_t i;
1490d5de7839SBastian Koppelmann     uint32_t ret = 0;
1491d5de7839SBastian Koppelmann 
1492d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1493d5de7839SBastian Koppelmann         if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
1494d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
1495d5de7839SBastian Koppelmann         }
1496d5de7839SBastian Koppelmann     }
1497d5de7839SBastian Koppelmann 
1498d5de7839SBastian Koppelmann     return ret;
1499d5de7839SBastian Koppelmann }
1500d5de7839SBastian Koppelmann 
1501d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
1502d5de7839SBastian Koppelmann {
1503d5de7839SBastian Koppelmann     uint32_t ret = 0;
1504d5de7839SBastian Koppelmann 
1505d5de7839SBastian Koppelmann     if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
1506d5de7839SBastian Koppelmann         ret |= 0xffff;
1507d5de7839SBastian Koppelmann     }
1508d5de7839SBastian Koppelmann 
1509d5de7839SBastian Koppelmann     if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
1510d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1511d5de7839SBastian Koppelmann     }
1512d5de7839SBastian Koppelmann 
1513d5de7839SBastian Koppelmann     return ret;
1514d5de7839SBastian Koppelmann }
1515d5de7839SBastian Koppelmann 
1516d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
1517d5de7839SBastian Koppelmann {
1518d5de7839SBastian Koppelmann     uint32_t ret = 0;
1519d5de7839SBastian Koppelmann 
1520d5de7839SBastian Koppelmann     if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
1521d5de7839SBastian Koppelmann         ret |= 0xffff;
1522d5de7839SBastian Koppelmann     }
1523d5de7839SBastian Koppelmann 
1524d5de7839SBastian Koppelmann     if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
1525d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1526d5de7839SBastian Koppelmann     }
1527d5de7839SBastian Koppelmann 
1528d5de7839SBastian Koppelmann     return ret;
1529d5de7839SBastian Koppelmann }
1530d5de7839SBastian Koppelmann 
1531d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op)                                 \
1532d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
1533d5de7839SBastian Koppelmann {                                                             \
1534d5de7839SBastian Koppelmann     int32_t i, extr_r1, extr_r2;                              \
1535d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1536d5de7839SBastian Koppelmann                                                               \
1537d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
1538d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);                   \
1539d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);                   \
1540d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1541d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1542d5de7839SBastian Koppelmann     }                                                         \
1543d5de7839SBastian Koppelmann     return ret;                                               \
1544d5de7839SBastian Koppelmann }                                                             \
1545d5de7839SBastian Koppelmann                                                               \
1546d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
1547d5de7839SBastian Koppelmann {                                                             \
1548d5de7839SBastian Koppelmann     int32_t i;                                                \
1549d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
1550d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1551d5de7839SBastian Koppelmann                                                               \
1552d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
1553d5de7839SBastian Koppelmann         extr_r1 = extract32(r1, i * 8, 8);                    \
1554d5de7839SBastian Koppelmann         extr_r2 = extract32(r2, i * 8, 8);                    \
1555d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1556d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1557d5de7839SBastian Koppelmann     }                                                         \
1558d5de7839SBastian Koppelmann     return ret;                                               \
1559d5de7839SBastian Koppelmann }                                                             \
1560d5de7839SBastian Koppelmann                                                               \
1561d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
1562d5de7839SBastian Koppelmann {                                                             \
1563d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;                                 \
1564d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1565d5de7839SBastian Koppelmann                                                               \
1566d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 0, 16);                          \
1567d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 0, 16);                          \
1568d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1569d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
1570d5de7839SBastian Koppelmann                                                               \
1571d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 16, 16);                         \
1572d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 16, 16);                         \
1573d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1574d5de7839SBastian Koppelmann     ret |= extr_r1 << 16;                                     \
1575d5de7839SBastian Koppelmann                                                               \
1576d5de7839SBastian Koppelmann     return ret;                                               \
1577d5de7839SBastian Koppelmann }                                                             \
1578d5de7839SBastian Koppelmann                                                               \
1579d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
1580d5de7839SBastian Koppelmann {                                                             \
1581d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
1582d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1583d5de7839SBastian Koppelmann                                                               \
1584d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 0, 16);                           \
1585d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 0, 16);                           \
1586d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1587d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
1588d5de7839SBastian Koppelmann                                                               \
1589d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 16, 16);                          \
1590d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 16, 16);                          \
1591d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1592d5de7839SBastian Koppelmann     ret |= extr_r1 << (16);                                   \
1593d5de7839SBastian Koppelmann                                                               \
1594d5de7839SBastian Koppelmann     return ret;                                               \
1595d5de7839SBastian Koppelmann }                                                             \
159609532255SBastian Koppelmann                                                               \
159709532255SBastian Koppelmann uint64_t helper_ix##name(uint64_t r1, uint32_t r2)            \
159809532255SBastian Koppelmann {                                                             \
159909532255SBastian Koppelmann     int64_t r2l, r2h, r1hl;                                   \
160009532255SBastian Koppelmann     uint64_t ret = 0;                                         \
160109532255SBastian Koppelmann                                                               \
160209532255SBastian Koppelmann     ret = ((r1 + 2) & 0xffff);                                \
160309532255SBastian Koppelmann     r2l = sextract64(r2, 0, 16);                              \
160409532255SBastian Koppelmann     r2h = sextract64(r2, 16, 16);                             \
160509532255SBastian Koppelmann     r1hl = sextract64(r1, 32, 16);                            \
160609532255SBastian Koppelmann                                                               \
160709532255SBastian Koppelmann     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
160809532255SBastian Koppelmann         ret |= (r2l & 0xffff) << 32;                          \
160909532255SBastian Koppelmann         ret |= extract64(r1, 0, 16) << 16;                    \
161009532255SBastian Koppelmann     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
161109532255SBastian Koppelmann         ret |= extract64(r2, 16, 16) << 32;                   \
161209532255SBastian Koppelmann         ret |= extract64(r1 + 1, 0, 16) << 16;                \
161309532255SBastian Koppelmann     } else {                                                  \
161409532255SBastian Koppelmann         ret |= r1 & 0xffffffff0000ull;                        \
161509532255SBastian Koppelmann     }                                                         \
161609532255SBastian Koppelmann     return ret;                                               \
161709532255SBastian Koppelmann }                                                             \
161809532255SBastian Koppelmann                                                               \
161909532255SBastian Koppelmann uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2)       \
162009532255SBastian Koppelmann {                                                             \
162109532255SBastian Koppelmann     int64_t r2l, r2h, r1hl;                                   \
162209532255SBastian Koppelmann     uint64_t ret = 0;                                         \
162309532255SBastian Koppelmann                                                               \
162409532255SBastian Koppelmann     ret = ((r1 + 2) & 0xffff);                                \
162509532255SBastian Koppelmann     r2l = extract64(r2, 0, 16);                               \
162609532255SBastian Koppelmann     r2h = extract64(r2, 16, 16);                              \
162709532255SBastian Koppelmann     r1hl = extract64(r1, 32, 16);                             \
162809532255SBastian Koppelmann                                                               \
162909532255SBastian Koppelmann     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
163009532255SBastian Koppelmann         ret |= (r2l & 0xffff) << 32;                          \
163109532255SBastian Koppelmann         ret |= extract64(r1, 0, 16) << 16;                    \
163209532255SBastian Koppelmann     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
163309532255SBastian Koppelmann         ret |= extract64(r2, 16, 16) << 32;                   \
163409532255SBastian Koppelmann         ret |= extract64(r1 + 1, 0, 16) << 16;                \
163509532255SBastian Koppelmann     } else {                                                  \
163609532255SBastian Koppelmann         ret |= r1 & 0xffffffff0000ull;                        \
163709532255SBastian Koppelmann     }                                                         \
163809532255SBastian Koppelmann     return ret;                                               \
163909532255SBastian Koppelmann }
1640d5de7839SBastian Koppelmann 
1641d5de7839SBastian Koppelmann EXTREMA_H_B(max, >)
1642d5de7839SBastian Koppelmann EXTREMA_H_B(min, <)
1643d5de7839SBastian Koppelmann 
1644d5de7839SBastian Koppelmann #undef EXTREMA_H_B
1645d5de7839SBastian Koppelmann 
16460b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1)
16470b79a781SBastian Koppelmann {
16480b79a781SBastian Koppelmann     return clo32(r1);
16490b79a781SBastian Koppelmann }
16500b79a781SBastian Koppelmann 
16510b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1)
16520b79a781SBastian Koppelmann {
16530b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
16540b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
16550b79a781SBastian Koppelmann 
16560b79a781SBastian Koppelmann     ret_hw0 = clo32(ret_hw0 << 16);
16570b79a781SBastian Koppelmann     ret_hw1 = clo32(ret_hw1 << 16);
16580b79a781SBastian Koppelmann 
16590b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
16600b79a781SBastian Koppelmann         ret_hw0 = 16;
16610b79a781SBastian Koppelmann     }
16620b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
16630b79a781SBastian Koppelmann         ret_hw1 = 16;
16640b79a781SBastian Koppelmann     }
16650b79a781SBastian Koppelmann 
16660b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
16670b79a781SBastian Koppelmann }
16680b79a781SBastian Koppelmann 
16690b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1)
16700b79a781SBastian Koppelmann {
16710b79a781SBastian Koppelmann     return clz32(r1);
16720b79a781SBastian Koppelmann }
16730b79a781SBastian Koppelmann 
16740b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1)
16750b79a781SBastian Koppelmann {
16760b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
16770b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
16780b79a781SBastian Koppelmann 
16790b79a781SBastian Koppelmann     ret_hw0 = clz32(ret_hw0 << 16);
16800b79a781SBastian Koppelmann     ret_hw1 = clz32(ret_hw1 << 16);
16810b79a781SBastian Koppelmann 
16820b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
16830b79a781SBastian Koppelmann         ret_hw0 = 16;
16840b79a781SBastian Koppelmann     }
16850b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
16860b79a781SBastian Koppelmann         ret_hw1 = 16;
16870b79a781SBastian Koppelmann     }
16880b79a781SBastian Koppelmann 
16890b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
16900b79a781SBastian Koppelmann }
16910b79a781SBastian Koppelmann 
16920b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1)
16930b79a781SBastian Koppelmann {
16940b79a781SBastian Koppelmann     return clrsb32(r1);
16950b79a781SBastian Koppelmann }
16960b79a781SBastian Koppelmann 
16970b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1)
16980b79a781SBastian Koppelmann {
16990b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
17000b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
17010b79a781SBastian Koppelmann 
17020b79a781SBastian Koppelmann     ret_hw0 = clrsb32(ret_hw0 << 16);
17030b79a781SBastian Koppelmann     ret_hw1 = clrsb32(ret_hw1 << 16);
17040b79a781SBastian Koppelmann 
17050b79a781SBastian Koppelmann     if (ret_hw0 > 15) {
17060b79a781SBastian Koppelmann         ret_hw0 = 15;
17070b79a781SBastian Koppelmann     }
17080b79a781SBastian Koppelmann     if (ret_hw1 > 15) {
17090b79a781SBastian Koppelmann         ret_hw1 = 15;
17100b79a781SBastian Koppelmann     }
17110b79a781SBastian Koppelmann 
17120b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
17130b79a781SBastian Koppelmann }
17140b79a781SBastian Koppelmann 
17150b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2)
17160b79a781SBastian Koppelmann {
17170b79a781SBastian Koppelmann     int32_t shift_count = sextract32(r2, 0, 6);
17180b79a781SBastian Koppelmann 
17190b79a781SBastian Koppelmann     if (shift_count == -32) {
17200b79a781SBastian Koppelmann         return 0;
17210b79a781SBastian Koppelmann     } else if (shift_count < 0) {
17220b79a781SBastian Koppelmann         return r1 >> -shift_count;
17230b79a781SBastian Koppelmann     } else {
17240b79a781SBastian Koppelmann         return r1 << shift_count;
17250b79a781SBastian Koppelmann     }
17260b79a781SBastian Koppelmann }
17270b79a781SBastian Koppelmann 
17280b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
17290b79a781SBastian Koppelmann {
17300b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
17310b79a781SBastian Koppelmann     int32_t shift_count;
17320b79a781SBastian Koppelmann 
17330b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
17340b79a781SBastian Koppelmann 
17350b79a781SBastian Koppelmann     if (shift_count == -16) {
17360b79a781SBastian Koppelmann         return 0;
17370b79a781SBastian Koppelmann     } else if (shift_count < 0) {
17380b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
17390b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
17400b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
17410b79a781SBastian Koppelmann     } else {
17420b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) << shift_count;
17430b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) << shift_count;
17440b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
17450b79a781SBastian Koppelmann     }
17460b79a781SBastian Koppelmann }
17470b79a781SBastian Koppelmann 
17480b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
17490b79a781SBastian Koppelmann {
17500b79a781SBastian Koppelmann     int32_t shift_count;
17510b79a781SBastian Koppelmann     int64_t result, t1;
17520b79a781SBastian Koppelmann     uint32_t ret;
17530b79a781SBastian Koppelmann 
17540b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 6);
17550b79a781SBastian Koppelmann     t1 = sextract32(r1, 0, 32);
17560b79a781SBastian Koppelmann 
17570b79a781SBastian Koppelmann     if (shift_count == 0) {
17580b79a781SBastian Koppelmann         env->PSW_USB_C = env->PSW_USB_V = 0;
17590b79a781SBastian Koppelmann         ret = r1;
17600b79a781SBastian Koppelmann     } else if (shift_count == -32) {
17610b79a781SBastian Koppelmann         env->PSW_USB_C = r1;
17620b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
17630b79a781SBastian Koppelmann         ret = t1 >> 31;
17640b79a781SBastian Koppelmann     } else if (shift_count > 0) {
17650b79a781SBastian Koppelmann         result = t1 << shift_count;
17660b79a781SBastian Koppelmann         /* calc carry */
1767452e3d49SPeter Maydell         env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
17680b79a781SBastian Koppelmann         /* calc v */
17690b79a781SBastian Koppelmann         env->PSW_USB_V = (((result > 0x7fffffffLL) ||
17700b79a781SBastian Koppelmann                            (result < -0x80000000LL)) << 31);
17710b79a781SBastian Koppelmann         /* calc sv */
17720b79a781SBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
17730b79a781SBastian Koppelmann         ret = (uint32_t)result;
17740b79a781SBastian Koppelmann     } else {
17750b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
17760b79a781SBastian Koppelmann         env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
17770b79a781SBastian Koppelmann         ret = t1 >> -shift_count;
17780b79a781SBastian Koppelmann     }
17790b79a781SBastian Koppelmann 
17800b79a781SBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
17810b79a781SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
17820b79a781SBastian Koppelmann 
17830b79a781SBastian Koppelmann     return ret;
17840b79a781SBastian Koppelmann }
17850b79a781SBastian Koppelmann 
17860b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
17870b79a781SBastian Koppelmann {
17880b79a781SBastian Koppelmann     int32_t shift_count;
17890b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
17900b79a781SBastian Koppelmann 
17910b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
17920b79a781SBastian Koppelmann 
17930b79a781SBastian Koppelmann     if (shift_count == 0) {
17940b79a781SBastian Koppelmann         return r1;
17950b79a781SBastian Koppelmann     } else if (shift_count < 0) {
17960b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
17970b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
17980b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
17990b79a781SBastian Koppelmann     } else {
18000b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) << shift_count;
18010b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) << shift_count;
18020b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
18030b79a781SBastian Koppelmann     }
18040b79a781SBastian Koppelmann }
18050b79a781SBastian Koppelmann 
1806e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1807e2bed107SBastian Koppelmann {
1808e2bed107SBastian Koppelmann     uint32_t i, ret;
1809e2bed107SBastian Koppelmann 
1810e2bed107SBastian Koppelmann     ret = 0;
1811e2bed107SBastian Koppelmann     for (i = 0; i < 16; i++) {
1812e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (2 * i + 1);
1813e2bed107SBastian Koppelmann         ret |= (r2 & 1) << (2 * i);
1814e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1815e2bed107SBastian Koppelmann         r2 = r2 >> 1;
1816e2bed107SBastian Koppelmann     }
1817e2bed107SBastian Koppelmann     return ret;
1818e2bed107SBastian Koppelmann }
1819e2bed107SBastian Koppelmann 
1820e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1)
1821e2bed107SBastian Koppelmann {
1822e2bed107SBastian Koppelmann     int32_t i;
1823e2bed107SBastian Koppelmann     uint64_t ret;
1824e2bed107SBastian Koppelmann 
1825e2bed107SBastian Koppelmann     ret = 0;
1826e2bed107SBastian Koppelmann     for (i = 0; i < 32; i = i + 2) {
1827e2bed107SBastian Koppelmann         /* even */
1828e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (i/2);
1829e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1830e2bed107SBastian Koppelmann         /* odd */
1831e2bed107SBastian Koppelmann         ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1832e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1833e2bed107SBastian Koppelmann     }
1834e2bed107SBastian Koppelmann     return ret;
1835e2bed107SBastian Koppelmann }
1836e2bed107SBastian Koppelmann 
1837e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1)
1838e2bed107SBastian Koppelmann {
1839e2bed107SBastian Koppelmann     uint32_t ret;
1840e2bed107SBastian Koppelmann     uint32_t nOnes, i;
1841e2bed107SBastian Koppelmann 
1842e2bed107SBastian Koppelmann     ret = 0;
1843e2bed107SBastian Koppelmann     nOnes = 0;
1844e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1845e2bed107SBastian Koppelmann         ret ^= (r1 & 1);
1846e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1847e2bed107SBastian Koppelmann     }
1848e2bed107SBastian Koppelmann     /* second byte */
1849e2bed107SBastian Koppelmann     nOnes = 0;
1850e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1851e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1852e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1853e2bed107SBastian Koppelmann     }
1854e2bed107SBastian Koppelmann     ret |= nOnes << 8;
1855e2bed107SBastian Koppelmann     /* third byte */
1856e2bed107SBastian Koppelmann     nOnes = 0;
1857e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1858e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1859e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1860e2bed107SBastian Koppelmann     }
1861e2bed107SBastian Koppelmann     ret |= nOnes << 16;
1862e2bed107SBastian Koppelmann     /* fourth byte */
1863e2bed107SBastian Koppelmann     nOnes = 0;
1864e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1865e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1866e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1867e2bed107SBastian Koppelmann     }
1868e2bed107SBastian Koppelmann     ret |= nOnes << 24;
1869e2bed107SBastian Koppelmann 
1870e2bed107SBastian Koppelmann     return ret;
1871e2bed107SBastian Koppelmann }
1872e2bed107SBastian Koppelmann 
187309532255SBastian Koppelmann uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
187409532255SBastian Koppelmann                      target_ulong r2)
187509532255SBastian Koppelmann {
187609532255SBastian Koppelmann     uint32_t ret;
187709532255SBastian Koppelmann     int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
187809532255SBastian Koppelmann     int32_t int_exp  = r1_high;
187909532255SBastian Koppelmann     int32_t int_mant = r1_low;
188009532255SBastian Koppelmann     uint32_t flag_rnd = (int_mant & (1 << 7)) && (
188109532255SBastian Koppelmann                         (int_mant & (1 << 8)) ||
188209532255SBastian Koppelmann                         (int_mant & 0x7f)     ||
188309532255SBastian Koppelmann                         (carry != 0));
188409532255SBastian Koppelmann     if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
188509532255SBastian Koppelmann         fp_exp = 255;
188609532255SBastian Koppelmann         fp_frac = extract32(int_mant, 8, 23);
188709532255SBastian Koppelmann     } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
188809532255SBastian Koppelmann         fp_exp  = 255;
188909532255SBastian Koppelmann         fp_frac = 0;
189009532255SBastian Koppelmann     } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
189109532255SBastian Koppelmann         fp_exp  = 0;
189209532255SBastian Koppelmann         fp_frac = 0;
189309532255SBastian Koppelmann     } else if (int_mant == 0) {
189409532255SBastian Koppelmann         fp_exp  = 0;
189509532255SBastian Koppelmann         fp_frac = 0;
189609532255SBastian Koppelmann     } else {
189709532255SBastian Koppelmann         if (((int_mant & (1 << 31)) == 0)) {
189809532255SBastian Koppelmann             temp_exp = 0;
189909532255SBastian Koppelmann         } else {
190009532255SBastian Koppelmann             temp_exp = int_exp + 128;
190109532255SBastian Koppelmann         }
190209532255SBastian Koppelmann         fp_exp_frac = (((temp_exp & 0xff) << 23) |
190309532255SBastian Koppelmann                       extract32(int_mant, 8, 23))
190409532255SBastian Koppelmann                       + flag_rnd;
190509532255SBastian Koppelmann         fp_exp  = extract32(fp_exp_frac, 23, 8);
190609532255SBastian Koppelmann         fp_frac = extract32(fp_exp_frac, 0, 23);
190709532255SBastian Koppelmann     }
190809532255SBastian Koppelmann     ret = r2 & (1 << 31);
190909532255SBastian Koppelmann     ret = ret + (fp_exp << 23);
191009532255SBastian Koppelmann     ret = ret + (fp_frac & 0x7fffff);
191109532255SBastian Koppelmann 
191209532255SBastian Koppelmann     return ret;
191309532255SBastian Koppelmann }
191409532255SBastian Koppelmann 
1915e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1)
1916e2bed107SBastian Koppelmann {
1917e2bed107SBastian Koppelmann     int32_t fp_exp  = extract32(arg1, 23, 8);
1918e2bed107SBastian Koppelmann     int32_t fp_frac = extract32(arg1, 0, 23);
1919e2bed107SBastian Koppelmann     uint64_t ret;
1920e2bed107SBastian Koppelmann     int32_t int_exp, int_mant;
1921e2bed107SBastian Koppelmann 
1922e2bed107SBastian Koppelmann     if (fp_exp == 255) {
1923e2bed107SBastian Koppelmann         int_exp = 255;
1924e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1925e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac == 0)) {
1926e2bed107SBastian Koppelmann         int_exp  = -127;
1927e2bed107SBastian Koppelmann         int_mant = 0;
1928e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac != 0)) {
1929e2bed107SBastian Koppelmann         int_exp  = -126;
1930e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1931e2bed107SBastian Koppelmann     } else {
1932e2bed107SBastian Koppelmann         int_exp  = fp_exp - 127;
1933e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1934e2bed107SBastian Koppelmann         int_mant |= (1 << 30);
1935e2bed107SBastian Koppelmann     }
1936e2bed107SBastian Koppelmann     ret = int_exp;
1937e2bed107SBastian Koppelmann     ret = ret << 32;
1938e2bed107SBastian Koppelmann     ret |= int_mant;
1939e2bed107SBastian Koppelmann 
1940e2bed107SBastian Koppelmann     return ret;
1941e2bed107SBastian Koppelmann }
1942e2bed107SBastian Koppelmann 
1943e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1944e2bed107SBastian Koppelmann {
1945e2bed107SBastian Koppelmann     uint64_t ret;
1946f69c24e4SBastian Koppelmann     int32_t abs_sig_dividend, abs_divisor;
1947e2bed107SBastian Koppelmann 
1948e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1949e2bed107SBastian Koppelmann     ret = ret << 24;
1950e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1951e2bed107SBastian Koppelmann         ret |= 0xffffff;
1952e2bed107SBastian Koppelmann     }
1953e2bed107SBastian Koppelmann 
1954f69c24e4SBastian Koppelmann     abs_sig_dividend = abs((int32_t)r1) >> 8;
195530a0d72fSStefan Weil     abs_divisor = abs((int32_t)r2);
1956f69c24e4SBastian Koppelmann     /* calc overflow
1957f69c24e4SBastian Koppelmann        ofv if (a/b >= 255) <=> (a/255 >= b) */
1958f69c24e4SBastian Koppelmann     env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
1959e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1960e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1961e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1962e2bed107SBastian Koppelmann 
1963e2bed107SBastian Koppelmann     return ret;
1964e2bed107SBastian Koppelmann }
1965e2bed107SBastian Koppelmann 
1966e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1967e2bed107SBastian Koppelmann {
1968e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
1969e2bed107SBastian Koppelmann 
1970e2bed107SBastian Koppelmann     ret = ret << 24;
1971e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1972e2bed107SBastian Koppelmann         ret |= 0xffffff;
1973e2bed107SBastian Koppelmann     }
1974e2bed107SBastian Koppelmann     /* calc overflow */
1975e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
1976e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1977e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1978e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1979e2bed107SBastian Koppelmann 
1980e2bed107SBastian Koppelmann     return ret;
1981e2bed107SBastian Koppelmann }
1982e2bed107SBastian Koppelmann 
1983e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1984e2bed107SBastian Koppelmann {
1985e2bed107SBastian Koppelmann     uint64_t ret;
1986f69c24e4SBastian Koppelmann     int32_t abs_sig_dividend, abs_divisor;
1987e2bed107SBastian Koppelmann 
1988e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1989e2bed107SBastian Koppelmann     ret = ret << 16;
1990e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1991e2bed107SBastian Koppelmann         ret |= 0xffff;
1992e2bed107SBastian Koppelmann     }
1993e2bed107SBastian Koppelmann 
1994f69c24e4SBastian Koppelmann     abs_sig_dividend = abs((int32_t)r1) >> 16;
199530a0d72fSStefan Weil     abs_divisor = abs((int32_t)r2);
1996f69c24e4SBastian Koppelmann     /* calc overflow
1997f69c24e4SBastian Koppelmann        ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */
1998f69c24e4SBastian Koppelmann     env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
1999e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
2000e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
2001e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
2002e2bed107SBastian Koppelmann 
2003e2bed107SBastian Koppelmann     return ret;
2004e2bed107SBastian Koppelmann }
2005e2bed107SBastian Koppelmann 
2006e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2007e2bed107SBastian Koppelmann {
2008e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
2009e2bed107SBastian Koppelmann 
2010e2bed107SBastian Koppelmann     ret = ret << 16;
2011e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2012e2bed107SBastian Koppelmann         ret |= 0xffff;
2013e2bed107SBastian Koppelmann     }
2014e2bed107SBastian Koppelmann     /* calc overflow */
2015e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
2016e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
2017e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
2018e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
2019e2bed107SBastian Koppelmann 
2020e2bed107SBastian Koppelmann     return ret;
2021e2bed107SBastian Koppelmann }
2022e2bed107SBastian Koppelmann 
202309532255SBastian Koppelmann uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
202409532255SBastian Koppelmann {
202509532255SBastian Koppelmann     int32_t x_sign = (r1 >> 63);
202609532255SBastian Koppelmann     int32_t q_sign = x_sign ^ (r2 >> 31);
202709532255SBastian Koppelmann     int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
202809532255SBastian Koppelmann     int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
202909532255SBastian Koppelmann     uint32_t quotient;
203009532255SBastian Koppelmann     uint64_t ret, remainder;
203109532255SBastian Koppelmann 
203209532255SBastian Koppelmann     if ((q_sign & ~eq_neg) | eq_pos) {
203309532255SBastian Koppelmann         quotient = (r1 + 1) & 0xffffffff;
203409532255SBastian Koppelmann     } else {
203509532255SBastian Koppelmann         quotient = r1 & 0xffffffff;
203609532255SBastian Koppelmann     }
203709532255SBastian Koppelmann 
203809532255SBastian Koppelmann     if (eq_pos | eq_neg) {
203909532255SBastian Koppelmann         remainder = 0;
204009532255SBastian Koppelmann     } else {
204109532255SBastian Koppelmann         remainder = (r1 & 0xffffffff00000000ull);
204209532255SBastian Koppelmann     }
204309532255SBastian Koppelmann     ret = remainder|quotient;
204409532255SBastian Koppelmann     return ret;
204509532255SBastian Koppelmann }
204609532255SBastian Koppelmann 
204709532255SBastian Koppelmann uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
204809532255SBastian Koppelmann {
204909532255SBastian Koppelmann     int32_t dividend_sign = extract64(r1, 63, 1);
205009532255SBastian Koppelmann     int32_t divisor_sign = extract32(r2, 31, 1);
205109532255SBastian Koppelmann     int32_t quotient_sign = (dividend_sign != divisor_sign);
205209532255SBastian Koppelmann     int32_t addend, dividend_quotient, remainder;
205309532255SBastian Koppelmann     int32_t i, temp;
205409532255SBastian Koppelmann 
205509532255SBastian Koppelmann     if (quotient_sign) {
205609532255SBastian Koppelmann         addend = r2;
205709532255SBastian Koppelmann     } else {
205809532255SBastian Koppelmann         addend = -r2;
205909532255SBastian Koppelmann     }
206009532255SBastian Koppelmann     dividend_quotient = (int32_t)r1;
206109532255SBastian Koppelmann     remainder = (int32_t)(r1 >> 32);
206209532255SBastian Koppelmann 
206309532255SBastian Koppelmann     for (i = 0; i < 8; i++) {
206409532255SBastian Koppelmann         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
206509532255SBastian Koppelmann         dividend_quotient <<= 1;
206609532255SBastian Koppelmann         temp = remainder + addend;
206709532255SBastian Koppelmann         if ((temp < 0) == dividend_sign) {
206809532255SBastian Koppelmann             remainder = temp;
206909532255SBastian Koppelmann         }
207009532255SBastian Koppelmann         if (((temp < 0) == dividend_sign)) {
207109532255SBastian Koppelmann             dividend_quotient = dividend_quotient | !quotient_sign;
207209532255SBastian Koppelmann         } else {
207309532255SBastian Koppelmann             dividend_quotient = dividend_quotient | quotient_sign;
207409532255SBastian Koppelmann         }
207509532255SBastian Koppelmann     }
207609532255SBastian Koppelmann     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
207709532255SBastian Koppelmann }
207809532255SBastian Koppelmann 
207909532255SBastian Koppelmann uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
208009532255SBastian Koppelmann {
208109532255SBastian Koppelmann     int32_t dividend_quotient = extract64(r1, 0, 32);
208209532255SBastian Koppelmann     int64_t remainder = extract64(r1, 32, 32);
208309532255SBastian Koppelmann     int32_t i;
208409532255SBastian Koppelmann     int64_t temp;
208509532255SBastian Koppelmann     for (i = 0; i < 8; i++) {
208609532255SBastian Koppelmann         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
208709532255SBastian Koppelmann         dividend_quotient <<= 1;
208809532255SBastian Koppelmann         temp = (remainder & 0xffffffff) - r2;
208909532255SBastian Koppelmann         if (temp >= 0) {
209009532255SBastian Koppelmann             remainder = temp;
209109532255SBastian Koppelmann         }
209209532255SBastian Koppelmann         dividend_quotient = dividend_quotient | !(temp < 0);
209309532255SBastian Koppelmann     }
209409532255SBastian Koppelmann     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
209509532255SBastian Koppelmann }
209609532255SBastian Koppelmann 
209793715571SBastian Koppelmann uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
209893715571SBastian Koppelmann {
209993715571SBastian Koppelmann     int32_t quotient, remainder;
210093715571SBastian Koppelmann     int32_t dividend = (int32_t)r1;
210193715571SBastian Koppelmann     int32_t divisor = (int32_t)r2;
210293715571SBastian Koppelmann 
210393715571SBastian Koppelmann     if (divisor == 0) {
210493715571SBastian Koppelmann         if (dividend >= 0) {
210593715571SBastian Koppelmann             quotient = 0x7fffffff;
210693715571SBastian Koppelmann             remainder = 0;
210793715571SBastian Koppelmann         } else {
210893715571SBastian Koppelmann             quotient = 0x80000000;
210993715571SBastian Koppelmann             remainder = 0;
211093715571SBastian Koppelmann         }
211193715571SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
211293715571SBastian Koppelmann     } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
211393715571SBastian Koppelmann         quotient = 0x7fffffff;
211493715571SBastian Koppelmann         remainder = 0;
211593715571SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
211693715571SBastian Koppelmann     } else {
211793715571SBastian Koppelmann         remainder = dividend % divisor;
211893715571SBastian Koppelmann         quotient = (dividend - remainder)/divisor;
211993715571SBastian Koppelmann         env->PSW_USB_V = 0;
212093715571SBastian Koppelmann     }
212193715571SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
212293715571SBastian Koppelmann     env->PSW_USB_AV = 0;
212393715571SBastian Koppelmann     return ((uint64_t)remainder << 32) | (uint32_t)quotient;
212493715571SBastian Koppelmann }
212593715571SBastian Koppelmann 
212693715571SBastian Koppelmann uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
212793715571SBastian Koppelmann {
212893715571SBastian Koppelmann     uint32_t quotient, remainder;
212993715571SBastian Koppelmann     uint32_t dividend = r1;
213093715571SBastian Koppelmann     uint32_t divisor = r2;
213193715571SBastian Koppelmann 
213293715571SBastian Koppelmann     if (divisor == 0) {
213393715571SBastian Koppelmann         quotient = 0xffffffff;
213493715571SBastian Koppelmann         remainder = 0;
213593715571SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
213693715571SBastian Koppelmann     } else {
213793715571SBastian Koppelmann         remainder = dividend % divisor;
213893715571SBastian Koppelmann         quotient = (dividend - remainder)/divisor;
213993715571SBastian Koppelmann         env->PSW_USB_V = 0;
214093715571SBastian Koppelmann     }
214193715571SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
214293715571SBastian Koppelmann     env->PSW_USB_AV = 0;
214393715571SBastian Koppelmann     return ((uint64_t)remainder << 32) | quotient;
214493715571SBastian Koppelmann }
214593715571SBastian Koppelmann 
21469655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
21479655b932SBastian Koppelmann                       uint32_t arg10, uint32_t arg11, uint32_t n)
21489655b932SBastian Koppelmann {
21499655b932SBastian Koppelmann     uint64_t ret;
21509655b932SBastian Koppelmann     uint32_t result0, result1;
21519655b932SBastian Koppelmann 
21529655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
21539655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
21549655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
21559655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
21569655b932SBastian Koppelmann     if (sc1) {
21579655b932SBastian Koppelmann         result1 = 0x7fffffff;
21589655b932SBastian Koppelmann     } else {
21599655b932SBastian Koppelmann         result1 = (((uint32_t)(arg00 * arg10)) << n);
21609655b932SBastian Koppelmann     }
21619655b932SBastian Koppelmann     if (sc0) {
21629655b932SBastian Koppelmann         result0 = 0x7fffffff;
21639655b932SBastian Koppelmann     } else {
21649655b932SBastian Koppelmann         result0 = (((uint32_t)(arg01 * arg11)) << n);
21659655b932SBastian Koppelmann     }
21669655b932SBastian Koppelmann     ret = (((uint64_t)result1 << 32)) | result0;
21679655b932SBastian Koppelmann     return ret;
21689655b932SBastian Koppelmann }
21699655b932SBastian Koppelmann 
21709655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
21719655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
21729655b932SBastian Koppelmann {
21739655b932SBastian Koppelmann     uint64_t ret;
21749655b932SBastian Koppelmann     int64_t result0, result1;
21759655b932SBastian Koppelmann 
21769655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
21779655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
21789655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
21799655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
21809655b932SBastian Koppelmann 
21819655b932SBastian Koppelmann     if (sc1) {
21829655b932SBastian Koppelmann         result1 = 0x7fffffff;
21839655b932SBastian Koppelmann     } else {
21849655b932SBastian Koppelmann         result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
21859655b932SBastian Koppelmann     }
21869655b932SBastian Koppelmann     if (sc0) {
21879655b932SBastian Koppelmann         result0 = 0x7fffffff;
21889655b932SBastian Koppelmann     } else {
21899655b932SBastian Koppelmann         result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
21909655b932SBastian Koppelmann     }
21919655b932SBastian Koppelmann     ret = (result1 + result0);
21929655b932SBastian Koppelmann     ret = ret << 16;
21939655b932SBastian Koppelmann     return ret;
21949655b932SBastian Koppelmann }
21959655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
21969655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
21979655b932SBastian Koppelmann {
21989655b932SBastian Koppelmann     uint32_t result0, result1;
21999655b932SBastian Koppelmann 
22009655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
22019655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
22029655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
22039655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
22049655b932SBastian Koppelmann 
22059655b932SBastian Koppelmann     if (sc1) {
22069655b932SBastian Koppelmann         result1 = 0x7fffffff;
22079655b932SBastian Koppelmann     } else {
22089655b932SBastian Koppelmann         result1 = ((arg00 * arg10) << n) + 0x8000;
22099655b932SBastian Koppelmann     }
22109655b932SBastian Koppelmann     if (sc0) {
22119655b932SBastian Koppelmann         result0 = 0x7fffffff;
22129655b932SBastian Koppelmann     } else {
22139655b932SBastian Koppelmann         result0 = ((arg01 * arg11) << n) + 0x8000;
22149655b932SBastian Koppelmann     }
22159655b932SBastian Koppelmann     return (result1 & 0xffff0000) | (result0 >> 16);
22169655b932SBastian Koppelmann }
22179655b932SBastian Koppelmann 
2218e5c96c82SBastian Koppelmann uint32_t helper_crc32(uint32_t arg0, uint32_t arg1)
2219e5c96c82SBastian Koppelmann {
2220e5c96c82SBastian Koppelmann     uint8_t buf[4];
2221e5c96c82SBastian Koppelmann     uint32_t ret;
2222e5c96c82SBastian Koppelmann     stl_be_p(buf, arg0);
2223e5c96c82SBastian Koppelmann 
2224e5c96c82SBastian Koppelmann     ret = crc32(arg1, buf, 4);
2225e5c96c82SBastian Koppelmann     return ret;
2226e5c96c82SBastian Koppelmann }
2227e5c96c82SBastian Koppelmann 
22289a31922bSBastian Koppelmann /* context save area (CSA) related helpers */
22299a31922bSBastian Koppelmann 
22309a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw)
22319a31922bSBastian Koppelmann {
22329a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
22339a31922bSBastian Koppelmann         return 0;
22349a31922bSBastian Koppelmann     }
22359a31922bSBastian Koppelmann 
22369a31922bSBastian Koppelmann     (*psw)++;
22379a31922bSBastian Koppelmann     /* check for overflow */
22389a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
22399a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
22409a31922bSBastian Koppelmann     int count = *psw & mask;
22419a31922bSBastian Koppelmann     if (count == 0) {
22429a31922bSBastian Koppelmann         (*psw)--;
22439a31922bSBastian Koppelmann         return 1;
22449a31922bSBastian Koppelmann     }
22459a31922bSBastian Koppelmann     return 0;
22469a31922bSBastian Koppelmann }
22479a31922bSBastian Koppelmann 
22489a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw)
22499a31922bSBastian Koppelmann {
22509a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
22519a31922bSBastian Koppelmann         return 0;
22529a31922bSBastian Koppelmann     }
22539a31922bSBastian Koppelmann     /* check for underflow */
22549a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
22559a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
22569a31922bSBastian Koppelmann     int count = *psw & mask;
22579a31922bSBastian Koppelmann     if (count == 0) {
22589a31922bSBastian Koppelmann         return 1;
22599a31922bSBastian Koppelmann     }
22609a31922bSBastian Koppelmann     (*psw)--;
22619a31922bSBastian Koppelmann     return 0;
22629a31922bSBastian Koppelmann }
22639a31922bSBastian Koppelmann 
226444ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw)
226544ea3430SBastian Koppelmann {
226644ea3430SBastian Koppelmann     int cdc = *psw & MASK_PSW_CDC;
226744ea3430SBastian Koppelmann     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
226844ea3430SBastian Koppelmann        7'b1111111, otherwise returns FALSE. */
226944ea3430SBastian Koppelmann     if (cdc == 0x7f) {
227044ea3430SBastian Koppelmann         return true;
227144ea3430SBastian Koppelmann     }
227244ea3430SBastian Koppelmann     /* find CDC.COUNT */
227344ea3430SBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
227444ea3430SBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
227544ea3430SBastian Koppelmann     int count = *psw & mask;
227644ea3430SBastian Koppelmann     return count == 0;
227744ea3430SBastian Koppelmann }
227844ea3430SBastian Koppelmann 
2279030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea)
22809a31922bSBastian Koppelmann {
22819a31922bSBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
22829a31922bSBastian Koppelmann     cpu_stl_data(env, ea+4, env->PSW);
22839a31922bSBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[10]);
22849a31922bSBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[11]);
22859a31922bSBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[8]);
22869a31922bSBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[9]);
22879a31922bSBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[10]);
22889a31922bSBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[11]);
22899a31922bSBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[12]);
22909a31922bSBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[13]);
22919a31922bSBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[14]);
22929a31922bSBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[15]);
22939a31922bSBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[12]);
22949a31922bSBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[13]);
22959a31922bSBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[14]);
22969a31922bSBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[15]);
22979a31922bSBastian Koppelmann }
22989a31922bSBastian Koppelmann 
2299030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea)
23005de93515SBastian Koppelmann {
23015de93515SBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
2302030c58dfSBastian Koppelmann     cpu_stl_data(env, ea+4, env->gpr_a[11]);
23035de93515SBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[2]);
23045de93515SBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[3]);
23055de93515SBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[0]);
23065de93515SBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[1]);
23075de93515SBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[2]);
23085de93515SBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[3]);
23095de93515SBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[4]);
23105de93515SBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[5]);
23115de93515SBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[6]);
23125de93515SBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[7]);
23135de93515SBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[4]);
23145de93515SBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[5]);
23155de93515SBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[6]);
23165de93515SBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[7]);
23175de93515SBastian Koppelmann }
23185de93515SBastian Koppelmann 
23199a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea,
23209a31922bSBastian Koppelmann                                   target_ulong *new_PCXI, target_ulong *new_PSW)
23219a31922bSBastian Koppelmann {
23229a31922bSBastian Koppelmann     *new_PCXI = cpu_ldl_data(env, ea);
23239a31922bSBastian Koppelmann     *new_PSW = cpu_ldl_data(env, ea+4);
23249a31922bSBastian Koppelmann     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
23259a31922bSBastian Koppelmann     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
23269a31922bSBastian Koppelmann     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
23279a31922bSBastian Koppelmann     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
23289a31922bSBastian Koppelmann     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
23299a31922bSBastian Koppelmann     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
23309a31922bSBastian Koppelmann     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
23319a31922bSBastian Koppelmann     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
23329a31922bSBastian Koppelmann     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
23339a31922bSBastian Koppelmann     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
23349a31922bSBastian Koppelmann     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
23359a31922bSBastian Koppelmann     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
23369a31922bSBastian Koppelmann     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
23379a31922bSBastian Koppelmann     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
23389a31922bSBastian Koppelmann }
23399a31922bSBastian Koppelmann 
234059543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea,
234159543d4eSBastian Koppelmann                                   target_ulong *ra, target_ulong *pcxi)
234259543d4eSBastian Koppelmann {
234359543d4eSBastian Koppelmann     *pcxi = cpu_ldl_data(env, ea);
234459543d4eSBastian Koppelmann     *ra = cpu_ldl_data(env, ea+4);
234559543d4eSBastian Koppelmann     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
234659543d4eSBastian Koppelmann     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
234759543d4eSBastian Koppelmann     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
234859543d4eSBastian Koppelmann     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
234959543d4eSBastian Koppelmann     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
235059543d4eSBastian Koppelmann     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
235159543d4eSBastian Koppelmann     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
235259543d4eSBastian Koppelmann     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
235359543d4eSBastian Koppelmann     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
235459543d4eSBastian Koppelmann     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
235559543d4eSBastian Koppelmann     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
235659543d4eSBastian Koppelmann     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
235759543d4eSBastian Koppelmann     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
235859543d4eSBastian Koppelmann     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
235959543d4eSBastian Koppelmann }
236059543d4eSBastian Koppelmann 
23619a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc)
23629a31922bSBastian Koppelmann {
23639a31922bSBastian Koppelmann     target_ulong tmp_FCX;
23649a31922bSBastian Koppelmann     target_ulong ea;
23659a31922bSBastian Koppelmann     target_ulong new_FCX;
23669a31922bSBastian Koppelmann     target_ulong psw;
23679a31922bSBastian Koppelmann 
23689a31922bSBastian Koppelmann     psw = psw_read(env);
23699a31922bSBastian Koppelmann     /* if (FCX == 0) trap(FCU); */
23709a31922bSBastian Koppelmann     if (env->FCX == 0) {
23719a31922bSBastian Koppelmann         /* FCU trap */
23729a31922bSBastian Koppelmann     }
23739a31922bSBastian Koppelmann     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
23749a31922bSBastian Koppelmann     if (psw & MASK_PSW_CDE) {
23759a31922bSBastian Koppelmann         if (cdc_increment(&psw)) {
23769a31922bSBastian Koppelmann             /* CDO trap */
23779a31922bSBastian Koppelmann         }
23789a31922bSBastian Koppelmann     }
23799a31922bSBastian Koppelmann     /* PSW.CDE = 1;*/
23809a31922bSBastian Koppelmann     psw |= MASK_PSW_CDE;
23819a31922bSBastian Koppelmann     /* tmp_FCX = FCX; */
23829a31922bSBastian Koppelmann     tmp_FCX = env->FCX;
23839a31922bSBastian Koppelmann     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
23849a31922bSBastian Koppelmann     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
23859a31922bSBastian Koppelmann          ((env->FCX & MASK_FCX_FCXO) << 6);
2386030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
2387030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
2388030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
23899a31922bSBastian Koppelmann                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
23909a31922bSBastian Koppelmann                            D[15]}; */
2391030c58dfSBastian Koppelmann     save_context_upper(env, ea);
23929a31922bSBastian Koppelmann 
23939a31922bSBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN; */
23949a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
23959a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_CCPN) << 24);
23969a31922bSBastian Koppelmann     /* PCXI.PIE = ICR.IE; */
23979a31922bSBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
23989a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_IE) << 15));
23999a31922bSBastian Koppelmann     /* PCXI.UL = 1; */
24009a31922bSBastian Koppelmann     env->PCXI |= MASK_PCXI_UL;
24019a31922bSBastian Koppelmann 
24029a31922bSBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0]; */
24039a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
24049a31922bSBastian Koppelmann     /* FCX[19: 0] = new_FCX[19: 0]; */
24059a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
24069a31922bSBastian Koppelmann     /* A[11] = next_pc[31: 0]; */
24079a31922bSBastian Koppelmann     env->gpr_a[11] = next_pc;
24089a31922bSBastian Koppelmann 
24099a31922bSBastian Koppelmann     /* if (tmp_FCX == LCX) trap(FCD);*/
24109a31922bSBastian Koppelmann     if (tmp_FCX == env->LCX) {
24119a31922bSBastian Koppelmann         /* FCD trap */
24129a31922bSBastian Koppelmann     }
24139a31922bSBastian Koppelmann     psw_write(env, psw);
24149a31922bSBastian Koppelmann }
24159a31922bSBastian Koppelmann 
24169a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env)
24179a31922bSBastian Koppelmann {
24189a31922bSBastian Koppelmann     target_ulong ea;
24199a31922bSBastian Koppelmann     target_ulong new_PCXI;
24209a31922bSBastian Koppelmann     target_ulong new_PSW, psw;
24219a31922bSBastian Koppelmann 
24229a31922bSBastian Koppelmann     psw = psw_read(env);
24239a31922bSBastian Koppelmann      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
24249a31922bSBastian Koppelmann     if (env->PSW & MASK_PSW_CDE) {
24259a31922bSBastian Koppelmann         if (cdc_decrement(&(env->PSW))) {
24269a31922bSBastian Koppelmann             /* CDU trap */
24279a31922bSBastian Koppelmann         }
24289a31922bSBastian Koppelmann     }
24299a31922bSBastian Koppelmann     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
24309a31922bSBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
24319a31922bSBastian Koppelmann         /* CSU trap */
24329a31922bSBastian Koppelmann     }
24339a31922bSBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
24349a31922bSBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
24359a31922bSBastian Koppelmann         /* CTYP trap */
24369a31922bSBastian Koppelmann     }
24379a31922bSBastian Koppelmann     /* PC = {A11 [31: 1], 1’b0}; */
24389a31922bSBastian Koppelmann     env->PC = env->gpr_a[11] & 0xfffffffe;
24399a31922bSBastian Koppelmann 
24409a31922bSBastian Koppelmann     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
24419a31922bSBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
24429a31922bSBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
24439a31922bSBastian Koppelmann     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2444030c58dfSBastian Koppelmann         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
24459a31922bSBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2446030c58dfSBastian Koppelmann     /* M(EA, word) = FCX; */
2447030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
24489a31922bSBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
24499a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
24509a31922bSBastian Koppelmann     /* PCXI = new_PCXI; */
24519a31922bSBastian Koppelmann     env->PCXI = new_PCXI;
24529a31922bSBastian Koppelmann 
24539a31922bSBastian Koppelmann     if (tricore_feature(env, TRICORE_FEATURE_13)) {
24549a31922bSBastian Koppelmann         /* PSW = new_PSW */
24559a31922bSBastian Koppelmann         psw_write(env, new_PSW);
24569a31922bSBastian Koppelmann     } else {
24579a31922bSBastian Koppelmann         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
24589a31922bSBastian Koppelmann         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
24599a31922bSBastian Koppelmann     }
24609a31922bSBastian Koppelmann }
24619a31922bSBastian Koppelmann 
24625de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9)
24635de93515SBastian Koppelmann {
24645de93515SBastian Koppelmann     target_ulong tmp_FCX;
24655de93515SBastian Koppelmann     target_ulong ea;
24665de93515SBastian Koppelmann     target_ulong new_FCX;
24675de93515SBastian Koppelmann 
24685de93515SBastian Koppelmann     if (env->FCX == 0) {
24695de93515SBastian Koppelmann         /* FCU trap */
24705de93515SBastian Koppelmann     }
24715de93515SBastian Koppelmann 
24725de93515SBastian Koppelmann     tmp_FCX = env->FCX;
24735de93515SBastian Koppelmann     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
24745de93515SBastian Koppelmann 
2475030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
2476030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
2477030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2478030c58dfSBastian Koppelmann                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2479030c58dfSBastian Koppelmann     save_context_lower(env, ea);
2480030c58dfSBastian Koppelmann 
24815de93515SBastian Koppelmann 
24825de93515SBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN */
24835de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
24845de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_CCPN) << 24);
24855de93515SBastian Koppelmann     /* PCXI.PIE  = ICR.IE */
24865de93515SBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
24875de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_IE) << 15));
24885de93515SBastian Koppelmann     /* PCXI.UL = 0 */
24895de93515SBastian Koppelmann     env->PCXI &= ~(MASK_PCXI_UL);
24905de93515SBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0] */
24915de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
24925de93515SBastian Koppelmann     /* FXC[19: 0] = new_FCX[19: 0] */
24935de93515SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
24945de93515SBastian Koppelmann     /* ICR.IE = 1 */
24955de93515SBastian Koppelmann     env->ICR |= MASK_ICR_IE;
24965de93515SBastian Koppelmann 
24975de93515SBastian Koppelmann     env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
24985de93515SBastian Koppelmann 
24995de93515SBastian Koppelmann     if (tmp_FCX == env->LCX) {
25005de93515SBastian Koppelmann         /* FCD trap */
25015de93515SBastian Koppelmann     }
25025de93515SBastian Koppelmann }
25035de93515SBastian Koppelmann 
250444ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env)
250544ea3430SBastian Koppelmann {
250644ea3430SBastian Koppelmann     target_ulong ea;
250744ea3430SBastian Koppelmann     target_ulong new_PCXI;
250844ea3430SBastian Koppelmann     target_ulong new_PSW;
250944ea3430SBastian Koppelmann     /* if (PCXI[19: 0] == 0) then trap(CSU); */
251044ea3430SBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
251144ea3430SBastian Koppelmann         /* raise csu trap */
251244ea3430SBastian Koppelmann     }
251344ea3430SBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
251444ea3430SBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
251544ea3430SBastian Koppelmann         /* raise CTYP trap */
251644ea3430SBastian Koppelmann     }
251744ea3430SBastian Koppelmann     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
251844ea3430SBastian Koppelmann     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
251944ea3430SBastian Koppelmann         /* raise MNG trap */
252044ea3430SBastian Koppelmann     }
25213446a111SBastian Koppelmann     env->PC = env->gpr_a[11] & ~0x1;
252244ea3430SBastian Koppelmann     /* ICR.IE = PCXI.PIE; */
252344ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
252444ea3430SBastian Koppelmann     /* ICR.CCPN = PCXI.PCPN; */
252544ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
252644ea3430SBastian Koppelmann                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
252744ea3430SBastian Koppelmann     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
252844ea3430SBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
252944ea3430SBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
253044ea3430SBastian Koppelmann     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2531030c58dfSBastian Koppelmann       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
253244ea3430SBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2533030c58dfSBastian Koppelmann     /* M(EA, word) = FCX;*/
2534030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
253544ea3430SBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
253644ea3430SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
253744ea3430SBastian Koppelmann     /* PCXI = new_PCXI; */
253844ea3430SBastian Koppelmann     env->PCXI = new_PCXI;
253944ea3430SBastian Koppelmann     /* write psw */
254044ea3430SBastian Koppelmann     psw_write(env, new_PSW);
254144ea3430SBastian Koppelmann }
254244ea3430SBastian Koppelmann 
2543b724b012SBastian Koppelmann void helper_rfm(CPUTriCoreState *env)
2544b724b012SBastian Koppelmann {
2545b724b012SBastian Koppelmann     env->PC = (env->gpr_a[11] & ~0x1);
2546b724b012SBastian Koppelmann     /* ICR.IE = PCXI.PIE; */
2547b724b012SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_IE) |
2548b724b012SBastian Koppelmann                ((env->PCXI & ~MASK_PCXI_PIE) >> 15);
2549b724b012SBastian Koppelmann     /* ICR.CCPN = PCXI.PCPN; */
2550b724b012SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_CCPN) |
2551b724b012SBastian Koppelmann                ((env->PCXI & ~MASK_PCXI_PCPN) >> 24);
2552b724b012SBastian Koppelmann     /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */
2553b724b012SBastian Koppelmann     env->PCXI = cpu_ldl_data(env, env->DCX);
2554b724b012SBastian Koppelmann     psw_write(env, cpu_ldl_data(env, env->DCX+4));
2555b724b012SBastian Koppelmann     env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8);
2556b724b012SBastian Koppelmann     env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12);
2557b724b012SBastian Koppelmann 
2558b724b012SBastian Koppelmann     if (tricore_feature(env, TRICORE_FEATURE_131)) {
2559b724b012SBastian Koppelmann         env->DBGTCR = 0;
2560b724b012SBastian Koppelmann     }
2561b724b012SBastian Koppelmann }
2562b724b012SBastian Koppelmann 
256359543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
256459543d4eSBastian Koppelmann {
256559543d4eSBastian Koppelmann     uint32_t dummy;
256659543d4eSBastian Koppelmann     /* insn doesn't load PCXI and RA */
256759543d4eSBastian Koppelmann     restore_context_lower(env, ea, &dummy, &dummy);
256859543d4eSBastian Koppelmann }
256959543d4eSBastian Koppelmann 
257059543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea)
257159543d4eSBastian Koppelmann {
257259543d4eSBastian Koppelmann     uint32_t dummy;
257359543d4eSBastian Koppelmann     /* insn doesn't load PCXI and PSW */
257459543d4eSBastian Koppelmann     restore_context_upper(env, ea, &dummy, &dummy);
257559543d4eSBastian Koppelmann }
257659543d4eSBastian Koppelmann 
257759543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
257859543d4eSBastian Koppelmann {
257959543d4eSBastian Koppelmann     save_context_lower(env, ea);
258059543d4eSBastian Koppelmann }
258159543d4eSBastian Koppelmann 
258259543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea)
258359543d4eSBastian Koppelmann {
258459543d4eSBastian Koppelmann     save_context_upper(env, ea);
258559543d4eSBastian Koppelmann }
258659543d4eSBastian Koppelmann 
2587b724b012SBastian Koppelmann void helper_svlcx(CPUTriCoreState *env)
2588b724b012SBastian Koppelmann {
2589b724b012SBastian Koppelmann     target_ulong tmp_FCX;
2590b724b012SBastian Koppelmann     target_ulong ea;
2591b724b012SBastian Koppelmann     target_ulong new_FCX;
2592b724b012SBastian Koppelmann 
2593b724b012SBastian Koppelmann     if (env->FCX == 0) {
2594b724b012SBastian Koppelmann         /* FCU trap */
2595b724b012SBastian Koppelmann     }
2596b724b012SBastian Koppelmann     /* tmp_FCX = FCX; */
2597b724b012SBastian Koppelmann     tmp_FCX = env->FCX;
2598b724b012SBastian Koppelmann     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2599b724b012SBastian Koppelmann     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2600b724b012SBastian Koppelmann          ((env->FCX & MASK_FCX_FCXO) << 6);
2601b724b012SBastian Koppelmann     /* new_FCX = M(EA, word); */
2602b724b012SBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
2603b724b012SBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2604b724b012SBastian Koppelmann                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2605b724b012SBastian Koppelmann                            D[15]}; */
2606b724b012SBastian Koppelmann     save_context_lower(env, ea);
2607b724b012SBastian Koppelmann 
2608b724b012SBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN; */
2609b724b012SBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
2610b724b012SBastian Koppelmann                 ((env->ICR & MASK_ICR_CCPN) << 24);
2611b724b012SBastian Koppelmann     /* PCXI.PIE = ICR.IE; */
2612b724b012SBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2613b724b012SBastian Koppelmann                 ((env->ICR & MASK_ICR_IE) << 15));
2614b724b012SBastian Koppelmann     /* PCXI.UL = 0; */
2615b724b012SBastian Koppelmann     env->PCXI &= ~MASK_PCXI_UL;
2616b724b012SBastian Koppelmann 
2617b724b012SBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0]; */
2618b724b012SBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2619b724b012SBastian Koppelmann     /* FCX[19: 0] = new_FCX[19: 0]; */
2620b724b012SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2621b724b012SBastian Koppelmann 
2622b724b012SBastian Koppelmann     /* if (tmp_FCX == LCX) trap(FCD);*/
2623b724b012SBastian Koppelmann     if (tmp_FCX == env->LCX) {
2624b724b012SBastian Koppelmann         /* FCD trap */
2625b724b012SBastian Koppelmann     }
2626b724b012SBastian Koppelmann }
2627b724b012SBastian Koppelmann 
2628b724b012SBastian Koppelmann void helper_rslcx(CPUTriCoreState *env)
2629b724b012SBastian Koppelmann {
2630b724b012SBastian Koppelmann     target_ulong ea;
2631b724b012SBastian Koppelmann     target_ulong new_PCXI;
2632b724b012SBastian Koppelmann     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2633b724b012SBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
2634b724b012SBastian Koppelmann         /* CSU trap */
2635b724b012SBastian Koppelmann     }
2636b724b012SBastian Koppelmann     /* if (PCXI.UL == 1) then trap(CTYP); */
26377b4b0b57SStefan Weil     if ((env->PCXI & MASK_PCXI_UL) != 0) {
2638b724b012SBastian Koppelmann         /* CTYP trap */
2639b724b012SBastian Koppelmann     }
2640b724b012SBastian Koppelmann     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2641b724b012SBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2642b724b012SBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
2643b724b012SBastian Koppelmann     /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2644b724b012SBastian Koppelmann         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2645bc72f8aaSBastian Koppelmann     restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI);
2646b724b012SBastian Koppelmann     /* M(EA, word) = FCX; */
2647b724b012SBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
2648b724b012SBastian Koppelmann     /* M(EA, word) = FCX; */
2649b724b012SBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
2650b724b012SBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
2651b724b012SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2652b724b012SBastian Koppelmann     /* PCXI = new_PCXI; */
2653b724b012SBastian Koppelmann     env->PCXI = new_PCXI;
2654b724b012SBastian Koppelmann }
2655b724b012SBastian Koppelmann 
26562b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
26572b2f7d97SBastian Koppelmann {
26582b2f7d97SBastian Koppelmann     psw_write(env, arg);
26592b2f7d97SBastian Koppelmann }
26602b2f7d97SBastian Koppelmann 
26612b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env)
26622b2f7d97SBastian Koppelmann {
26632b2f7d97SBastian Koppelmann     return psw_read(env);
26642b2f7d97SBastian Koppelmann }
26652b2f7d97SBastian Koppelmann 
26662b2f7d97SBastian Koppelmann 
26672d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
26682d30267eSBastian Koppelmann                                                         uint32_t exception,
26692d30267eSBastian Koppelmann                                                         int error_code,
26702d30267eSBastian Koppelmann                                                         uintptr_t pc)
26712d30267eSBastian Koppelmann {
26722d30267eSBastian Koppelmann     CPUState *cs = CPU(tricore_env_get_cpu(env));
26732d30267eSBastian Koppelmann     cs->exception_index = exception;
26742d30267eSBastian Koppelmann     env->error_code = error_code;
26752d30267eSBastian Koppelmann 
26762d30267eSBastian Koppelmann     if (pc) {
26772d30267eSBastian Koppelmann         /* now we have a real cpu fault */
26782d30267eSBastian Koppelmann         cpu_restore_state(cs, pc);
26792d30267eSBastian Koppelmann     }
26802d30267eSBastian Koppelmann 
26812d30267eSBastian Koppelmann     cpu_loop_exit(cs);
26822d30267eSBastian Koppelmann }
26832d30267eSBastian Koppelmann 
268448e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
268548e06fe0SBastian Koppelmann               uintptr_t retaddr)
268648e06fe0SBastian Koppelmann {
26872d30267eSBastian Koppelmann     int ret;
26882d30267eSBastian Koppelmann     ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
26892d30267eSBastian Koppelmann     if (ret) {
26902d30267eSBastian Koppelmann         TriCoreCPU *cpu = TRICORE_CPU(cs);
26912d30267eSBastian Koppelmann         CPUTriCoreState *env = &cpu->env;
26922d30267eSBastian Koppelmann         do_raise_exception_err(env, cs->exception_index,
26932d30267eSBastian Koppelmann                                env->error_code, retaddr);
269448e06fe0SBastian Koppelmann     }
26952d30267eSBastian Koppelmann }
2696