xref: /qemu/target/tricore/op_helper.c (revision bebe80fc78cc91c4225cfb98ef3a916b9c861c60)
148e06fe0SBastian Koppelmann /*
248e06fe0SBastian Koppelmann  *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
348e06fe0SBastian Koppelmann  *
448e06fe0SBastian Koppelmann  * This library is free software; you can redistribute it and/or
548e06fe0SBastian Koppelmann  * modify it under the terms of the GNU Lesser General Public
648e06fe0SBastian Koppelmann  * License as published by the Free Software Foundation; either
748e06fe0SBastian Koppelmann  * version 2 of the License, or (at your option) any later version.
848e06fe0SBastian Koppelmann  *
948e06fe0SBastian Koppelmann  * This library is distributed in the hope that it will be useful,
1048e06fe0SBastian Koppelmann  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1148e06fe0SBastian Koppelmann  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1248e06fe0SBastian Koppelmann  * Lesser General Public License for more details.
1348e06fe0SBastian Koppelmann  *
1448e06fe0SBastian Koppelmann  * You should have received a copy of the GNU Lesser General Public
1548e06fe0SBastian Koppelmann  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1648e06fe0SBastian Koppelmann  */
1748e06fe0SBastian Koppelmann #include <stdlib.h>
1848e06fe0SBastian Koppelmann #include "cpu.h"
1948e06fe0SBastian Koppelmann #include "qemu/host-utils.h"
2048e06fe0SBastian Koppelmann #include "exec/helper-proto.h"
2148e06fe0SBastian Koppelmann #include "exec/cpu_ldst.h"
2248e06fe0SBastian Koppelmann 
233a16ecb0SBastian Koppelmann /* Addressing mode helper */
243a16ecb0SBastian Koppelmann 
253a16ecb0SBastian Koppelmann static uint16_t reverse16(uint16_t val)
263a16ecb0SBastian Koppelmann {
273a16ecb0SBastian Koppelmann     uint8_t high = (uint8_t)(val >> 8);
283a16ecb0SBastian Koppelmann     uint8_t low  = (uint8_t)(val & 0xff);
293a16ecb0SBastian Koppelmann 
303a16ecb0SBastian Koppelmann     uint16_t rh, rl;
313a16ecb0SBastian Koppelmann 
323a16ecb0SBastian Koppelmann     rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
333a16ecb0SBastian Koppelmann     rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
343a16ecb0SBastian Koppelmann 
353a16ecb0SBastian Koppelmann     return (rh << 8) | rl;
363a16ecb0SBastian Koppelmann }
373a16ecb0SBastian Koppelmann 
383a16ecb0SBastian Koppelmann uint32_t helper_br_update(uint32_t reg)
393a16ecb0SBastian Koppelmann {
403a16ecb0SBastian Koppelmann     uint32_t index = reg & 0xffff;
413a16ecb0SBastian Koppelmann     uint32_t incr  = reg >> 16;
423a16ecb0SBastian Koppelmann     uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
433a16ecb0SBastian Koppelmann     return reg - index + new_index;
443a16ecb0SBastian Koppelmann }
453a16ecb0SBastian Koppelmann 
463a16ecb0SBastian Koppelmann uint32_t helper_circ_update(uint32_t reg, uint32_t off)
473a16ecb0SBastian Koppelmann {
483a16ecb0SBastian Koppelmann     uint32_t index = reg & 0xffff;
493a16ecb0SBastian Koppelmann     uint32_t length = reg >> 16;
503a16ecb0SBastian Koppelmann     int32_t new_index = index + off;
513a16ecb0SBastian Koppelmann     if (new_index < 0) {
523a16ecb0SBastian Koppelmann         new_index += length;
533a16ecb0SBastian Koppelmann     } else {
543a16ecb0SBastian Koppelmann         new_index %= length;
553a16ecb0SBastian Koppelmann     }
563a16ecb0SBastian Koppelmann     return reg - index + new_index;
573a16ecb0SBastian Koppelmann }
583a16ecb0SBastian Koppelmann 
59e4e39176SBastian Koppelmann static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
60e4e39176SBastian Koppelmann {
61e4e39176SBastian Koppelmann     uint32_t ret;
62e4e39176SBastian Koppelmann     int64_t max_pos = INT32_MAX;
63e4e39176SBastian Koppelmann     int64_t max_neg = INT32_MIN;
64e4e39176SBastian Koppelmann     if (arg > max_pos) {
65e4e39176SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
66e4e39176SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
67e4e39176SBastian Koppelmann         ret = (target_ulong)max_pos;
68e4e39176SBastian Koppelmann     } else {
69e4e39176SBastian Koppelmann         if (arg < max_neg) {
70e4e39176SBastian Koppelmann             env->PSW_USB_V = (1 << 31);
71e4e39176SBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
72e4e39176SBastian Koppelmann             ret = (target_ulong)max_neg;
73e4e39176SBastian Koppelmann         } else {
74e4e39176SBastian Koppelmann             env->PSW_USB_V = 0;
75e4e39176SBastian Koppelmann             ret = (target_ulong)arg;
76e4e39176SBastian Koppelmann         }
77e4e39176SBastian Koppelmann     }
78e4e39176SBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
79e4e39176SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
80e4e39176SBastian Koppelmann     return ret;
81e4e39176SBastian Koppelmann }
822692802aSBastian Koppelmann 
8385d604afSBastian Koppelmann static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg)
84e4e39176SBastian Koppelmann {
85e4e39176SBastian Koppelmann     uint32_t ret;
8685d604afSBastian Koppelmann     uint64_t max_pos = UINT32_MAX;
87e4e39176SBastian Koppelmann     if (arg > max_pos) {
88e4e39176SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
89e4e39176SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
90e4e39176SBastian Koppelmann         ret = (target_ulong)max_pos;
91e4e39176SBastian Koppelmann     } else {
9285d604afSBastian Koppelmann         env->PSW_USB_V = 0;
9385d604afSBastian Koppelmann         ret = (target_ulong)arg;
9485d604afSBastian Koppelmann      }
9585d604afSBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
9685d604afSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
9785d604afSBastian Koppelmann     return ret;
9885d604afSBastian Koppelmann }
9985d604afSBastian Koppelmann 
10085d604afSBastian Koppelmann static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg)
10185d604afSBastian Koppelmann {
10285d604afSBastian Koppelmann     uint32_t ret;
10385d604afSBastian Koppelmann 
104e4e39176SBastian Koppelmann     if (arg < 0) {
105e4e39176SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
106e4e39176SBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
107e4e39176SBastian Koppelmann         ret = 0;
108e4e39176SBastian Koppelmann     } else {
109e4e39176SBastian Koppelmann         env->PSW_USB_V = 0;
110e4e39176SBastian Koppelmann         ret = (target_ulong)arg;
111e4e39176SBastian Koppelmann     }
112e4e39176SBastian Koppelmann     env->PSW_USB_AV = arg ^ arg * 2u;
113e4e39176SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
114e4e39176SBastian Koppelmann     return ret;
115e4e39176SBastian Koppelmann }
1160974257eSBastian Koppelmann 
117d5de7839SBastian Koppelmann static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
118d5de7839SBastian Koppelmann {
119d5de7839SBastian Koppelmann     int32_t max_pos = INT16_MAX;
120d5de7839SBastian Koppelmann     int32_t max_neg = INT16_MIN;
121d5de7839SBastian Koppelmann     int32_t av0, av1;
122d5de7839SBastian Koppelmann 
123d5de7839SBastian Koppelmann     env->PSW_USB_V = 0;
124d5de7839SBastian Koppelmann     av0 = hw0 ^ hw0 * 2u;
125d5de7839SBastian Koppelmann     if (hw0 > max_pos) {
126d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
127d5de7839SBastian Koppelmann         hw0 = max_pos;
128d5de7839SBastian Koppelmann     } else if (hw0 < max_neg) {
129d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
130d5de7839SBastian Koppelmann         hw0 = max_neg;
131d5de7839SBastian Koppelmann     }
132d5de7839SBastian Koppelmann 
133d5de7839SBastian Koppelmann     av1 = hw1 ^ hw1 * 2u;
134d5de7839SBastian Koppelmann     if (hw1 > max_pos) {
135d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
136d5de7839SBastian Koppelmann         hw1 = max_pos;
137d5de7839SBastian Koppelmann     } else if (hw1 < max_neg) {
138d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
139d5de7839SBastian Koppelmann         hw1 = max_neg;
140d5de7839SBastian Koppelmann     }
141d5de7839SBastian Koppelmann 
142d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
143d5de7839SBastian Koppelmann     env->PSW_USB_AV = (av0 | av1) << 16;
144d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
145d5de7839SBastian Koppelmann     return (hw0 & 0xffff) | (hw1 << 16);
146d5de7839SBastian Koppelmann }
147d5de7839SBastian Koppelmann 
148d5de7839SBastian Koppelmann static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
149d5de7839SBastian Koppelmann {
150d5de7839SBastian Koppelmann     int32_t max_pos = UINT16_MAX;
151d5de7839SBastian Koppelmann     int32_t av0, av1;
152d5de7839SBastian Koppelmann 
153d5de7839SBastian Koppelmann     env->PSW_USB_V = 0;
154d5de7839SBastian Koppelmann     av0 = hw0 ^ hw0 * 2u;
155d5de7839SBastian Koppelmann     if (hw0 > max_pos) {
156d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
157d5de7839SBastian Koppelmann         hw0 = max_pos;
158d5de7839SBastian Koppelmann     } else if (hw0 < 0) {
159d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
160d5de7839SBastian Koppelmann         hw0 = 0;
161d5de7839SBastian Koppelmann     }
162d5de7839SBastian Koppelmann 
163d5de7839SBastian Koppelmann     av1 = hw1 ^ hw1 * 2u;
164d5de7839SBastian Koppelmann     if (hw1 > max_pos) {
165d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
166d5de7839SBastian Koppelmann         hw1 = max_pos;
167d5de7839SBastian Koppelmann     } else if (hw1 < 0) {
168d5de7839SBastian Koppelmann         env->PSW_USB_V = (1 << 31);
169d5de7839SBastian Koppelmann         hw1 = 0;
170d5de7839SBastian Koppelmann     }
171d5de7839SBastian Koppelmann 
172d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
173d5de7839SBastian Koppelmann     env->PSW_USB_AV = (av0 | av1) << 16;
174d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
175d5de7839SBastian Koppelmann     return (hw0 & 0xffff) | (hw1 << 16);
176d5de7839SBastian Koppelmann }
1770974257eSBastian Koppelmann 
1782692802aSBastian Koppelmann target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
1792692802aSBastian Koppelmann                              target_ulong r2)
1802692802aSBastian Koppelmann {
1812692802aSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
1822692802aSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
1832692802aSBastian Koppelmann     int64_t result = t1 + t2;
184e4e39176SBastian Koppelmann     return ssov32(env, result);
1852692802aSBastian Koppelmann }
1862692802aSBastian Koppelmann 
1872e430e1cSBastian Koppelmann uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
1882e430e1cSBastian Koppelmann {
1892e430e1cSBastian Koppelmann     uint64_t result;
1902e430e1cSBastian Koppelmann     int64_t ovf;
1912e430e1cSBastian Koppelmann 
1922e430e1cSBastian Koppelmann     result = r1 + r2;
1932e430e1cSBastian Koppelmann     ovf = (result ^ r1) & ~(r1 ^ r2);
1942e430e1cSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
1952e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1962e430e1cSBastian Koppelmann     if (ovf < 0) {
1972e430e1cSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
1982e430e1cSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
1992e430e1cSBastian Koppelmann         /* ext_ret > MAX_INT */
2002e430e1cSBastian Koppelmann         if ((int64_t)r1 >= 0) {
2012e430e1cSBastian Koppelmann             result = INT64_MAX;
2022e430e1cSBastian Koppelmann         /* ext_ret < MIN_INT */
2032e430e1cSBastian Koppelmann         } else {
2042e430e1cSBastian Koppelmann             result = INT64_MIN;
2052e430e1cSBastian Koppelmann         }
2062e430e1cSBastian Koppelmann     } else {
2072e430e1cSBastian Koppelmann         env->PSW_USB_V = 0;
2082e430e1cSBastian Koppelmann     }
2092e430e1cSBastian Koppelmann     return result;
2102e430e1cSBastian Koppelmann }
2112e430e1cSBastian Koppelmann 
212d5de7839SBastian Koppelmann target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
213d5de7839SBastian Koppelmann                                target_ulong r2)
214d5de7839SBastian Koppelmann {
215d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
216d5de7839SBastian Koppelmann 
217d5de7839SBastian Koppelmann     ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16);
218d5de7839SBastian Koppelmann     ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16);
219d5de7839SBastian Koppelmann     return ssov16(env, ret_hw0, ret_hw1);
220d5de7839SBastian Koppelmann }
221d5de7839SBastian Koppelmann 
2222e430e1cSBastian Koppelmann uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
2232e430e1cSBastian Koppelmann                             uint32_t r2_h)
2242e430e1cSBastian Koppelmann {
2252e430e1cSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
2262e430e1cSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
2272e430e1cSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
2282e430e1cSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
2292e430e1cSBastian Koppelmann     int64_t result0, result1;
2302e430e1cSBastian Koppelmann     uint32_t ovf0, ovf1;
2312e430e1cSBastian Koppelmann     uint32_t avf0, avf1;
2322e430e1cSBastian Koppelmann 
2332e430e1cSBastian Koppelmann     ovf0 = ovf1 = 0;
2342e430e1cSBastian Koppelmann 
2352e430e1cSBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
2362e430e1cSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
2372e430e1cSBastian Koppelmann 
2382e430e1cSBastian Koppelmann     avf0 = result0 * 2u;
2392e430e1cSBastian Koppelmann     avf0 = result0 ^ avf0;
2402e430e1cSBastian Koppelmann     avf1 = result1 * 2u;
2412e430e1cSBastian Koppelmann     avf1 = result1 ^ avf1;
2422e430e1cSBastian Koppelmann 
2432e430e1cSBastian Koppelmann     if (result0 > INT32_MAX) {
2442e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
2452e430e1cSBastian Koppelmann         result0 = INT32_MAX;
2462e430e1cSBastian Koppelmann     } else if (result0 < INT32_MIN) {
2472e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
2482e430e1cSBastian Koppelmann         result0 = INT32_MIN;
2492e430e1cSBastian Koppelmann     }
2502e430e1cSBastian Koppelmann 
2512e430e1cSBastian Koppelmann     if (result1 > INT32_MAX) {
2522e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
2532e430e1cSBastian Koppelmann         result1 = INT32_MAX;
2542e430e1cSBastian Koppelmann     } else if (result1 < INT32_MIN) {
2552e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
2562e430e1cSBastian Koppelmann         result1 = INT32_MIN;
2572e430e1cSBastian Koppelmann     }
2582e430e1cSBastian Koppelmann 
2592e430e1cSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
2602e430e1cSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
2612e430e1cSBastian Koppelmann 
2622e430e1cSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
2632e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
2642e430e1cSBastian Koppelmann 
2652e430e1cSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
2662e430e1cSBastian Koppelmann }
2672e430e1cSBastian Koppelmann 
268bebe80fcSBastian Koppelmann uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
269bebe80fcSBastian Koppelmann                               uint32_t r2_h)
270bebe80fcSBastian Koppelmann {
271bebe80fcSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
272bebe80fcSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
273bebe80fcSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
274bebe80fcSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
275bebe80fcSBastian Koppelmann     int64_t result0, result1;
276bebe80fcSBastian Koppelmann     uint32_t ovf0, ovf1;
277bebe80fcSBastian Koppelmann     uint32_t avf0, avf1;
278bebe80fcSBastian Koppelmann 
279bebe80fcSBastian Koppelmann     ovf0 = ovf1 = 0;
280bebe80fcSBastian Koppelmann 
281bebe80fcSBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
282bebe80fcSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
283bebe80fcSBastian Koppelmann 
284bebe80fcSBastian Koppelmann     avf0 = result0 * 2u;
285bebe80fcSBastian Koppelmann     avf0 = result0 ^ avf0;
286bebe80fcSBastian Koppelmann     avf1 = result1 * 2u;
287bebe80fcSBastian Koppelmann     avf1 = result1 ^ avf1;
288bebe80fcSBastian Koppelmann 
289bebe80fcSBastian Koppelmann     if (result0 > INT32_MAX) {
290bebe80fcSBastian Koppelmann         ovf0 = (1 << 31);
291bebe80fcSBastian Koppelmann         result0 = INT32_MAX;
292bebe80fcSBastian Koppelmann     } else if (result0 < INT32_MIN) {
293bebe80fcSBastian Koppelmann         ovf0 = (1 << 31);
294bebe80fcSBastian Koppelmann         result0 = INT32_MIN;
295bebe80fcSBastian Koppelmann     }
296bebe80fcSBastian Koppelmann 
297bebe80fcSBastian Koppelmann     if (result1 > INT32_MAX) {
298bebe80fcSBastian Koppelmann         ovf1 = (1 << 31);
299bebe80fcSBastian Koppelmann         result1 = INT32_MAX;
300bebe80fcSBastian Koppelmann     } else if (result1 < INT32_MIN) {
301bebe80fcSBastian Koppelmann         ovf1 = (1 << 31);
302bebe80fcSBastian Koppelmann         result1 = INT32_MIN;
303bebe80fcSBastian Koppelmann     }
304bebe80fcSBastian Koppelmann 
305bebe80fcSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
306bebe80fcSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
307bebe80fcSBastian Koppelmann 
308bebe80fcSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
309bebe80fcSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
310bebe80fcSBastian Koppelmann 
311bebe80fcSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
312bebe80fcSBastian Koppelmann }
313bebe80fcSBastian Koppelmann 
3142e430e1cSBastian Koppelmann 
3150974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
3160974257eSBastian Koppelmann                              target_ulong r2)
3170974257eSBastian Koppelmann {
3180974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
3190974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
3200974257eSBastian Koppelmann     int64_t result = t1 + t2;
32185d604afSBastian Koppelmann     return suov32_pos(env, result);
3220974257eSBastian Koppelmann }
3230974257eSBastian Koppelmann 
324d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
325d5de7839SBastian Koppelmann                                target_ulong r2)
326d5de7839SBastian Koppelmann {
327d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
328d5de7839SBastian Koppelmann 
329d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
330d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
331d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
332d5de7839SBastian Koppelmann }
333d5de7839SBastian Koppelmann 
3342692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
3352692802aSBastian Koppelmann                              target_ulong r2)
3362692802aSBastian Koppelmann {
3372692802aSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3382692802aSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
3392692802aSBastian Koppelmann     int64_t result = t1 - t2;
340e4e39176SBastian Koppelmann     return ssov32(env, result);
3412692802aSBastian Koppelmann }
3422692802aSBastian Koppelmann 
343d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
344d5de7839SBastian Koppelmann                              target_ulong r2)
345d5de7839SBastian Koppelmann {
346d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
347d5de7839SBastian Koppelmann 
348d5de7839SBastian Koppelmann     ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
349d5de7839SBastian Koppelmann     ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
350d5de7839SBastian Koppelmann     return ssov16(env, ret_hw0, ret_hw1);
351d5de7839SBastian Koppelmann }
352d5de7839SBastian Koppelmann 
3530974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
3540974257eSBastian Koppelmann                              target_ulong r2)
3550974257eSBastian Koppelmann {
3560974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
3570974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
3580974257eSBastian Koppelmann     int64_t result = t1 - t2;
35985d604afSBastian Koppelmann     return suov32_neg(env, result);
3600974257eSBastian Koppelmann }
3610974257eSBastian Koppelmann 
362d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
363d5de7839SBastian Koppelmann                                target_ulong r2)
364d5de7839SBastian Koppelmann {
365d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
366d5de7839SBastian Koppelmann 
367d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
368d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
369d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
370d5de7839SBastian Koppelmann }
371d5de7839SBastian Koppelmann 
3720974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
3730974257eSBastian Koppelmann                              target_ulong r2)
3740974257eSBastian Koppelmann {
3750974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3760974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
3770974257eSBastian Koppelmann     int64_t result = t1 * t2;
378e4e39176SBastian Koppelmann     return ssov32(env, result);
3790974257eSBastian Koppelmann }
3800974257eSBastian Koppelmann 
3810974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
3820974257eSBastian Koppelmann                              target_ulong r2)
3830974257eSBastian Koppelmann {
3840974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
3850974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
3860974257eSBastian Koppelmann     int64_t result = t1 * t2;
3875f30046fSBastian Koppelmann 
38885d604afSBastian Koppelmann     return suov32_pos(env, result);
3890974257eSBastian Koppelmann }
3900974257eSBastian Koppelmann 
3910974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
3920974257eSBastian Koppelmann                              target_ulong r2)
3930974257eSBastian Koppelmann {
3940974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3950974257eSBastian Koppelmann     int32_t t2 = sextract64(r2, 0, 6);
3960974257eSBastian Koppelmann     int64_t result;
3970974257eSBastian Koppelmann     if (t2 == 0) {
3980974257eSBastian Koppelmann         result = t1;
3990974257eSBastian Koppelmann     } else if (t2 > 0) {
4000974257eSBastian Koppelmann         result = t1 << t2;
4010974257eSBastian Koppelmann     } else {
4020974257eSBastian Koppelmann         result = t1 >> -t2;
4030974257eSBastian Koppelmann     }
404e4e39176SBastian Koppelmann     return ssov32(env, result);
4050974257eSBastian Koppelmann }
4060974257eSBastian Koppelmann 
407d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
408d5de7839SBastian Koppelmann {
409d5de7839SBastian Koppelmann     target_ulong result;
410d5de7839SBastian Koppelmann     result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
411d5de7839SBastian Koppelmann     return ssov32(env, result);
412d5de7839SBastian Koppelmann }
413d5de7839SBastian Koppelmann 
414d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
415d5de7839SBastian Koppelmann {
416d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
417d5de7839SBastian Koppelmann 
418d5de7839SBastian Koppelmann     ret_h0 = sextract32(r1, 0, 16);
419d5de7839SBastian Koppelmann     ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
420d5de7839SBastian Koppelmann 
421d5de7839SBastian Koppelmann     ret_h1 = sextract32(r1, 16, 16);
422d5de7839SBastian Koppelmann     ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
423d5de7839SBastian Koppelmann 
424d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
425d5de7839SBastian Koppelmann }
426d5de7839SBastian Koppelmann 
4270974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
4280974257eSBastian Koppelmann                                 target_ulong r2)
4290974257eSBastian Koppelmann {
4300974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
4310974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
4320974257eSBastian Koppelmann     int64_t result;
4330974257eSBastian Koppelmann 
4340974257eSBastian Koppelmann     if (t1 > t2) {
4350974257eSBastian Koppelmann         result = t1 - t2;
4360974257eSBastian Koppelmann     } else {
4370974257eSBastian Koppelmann         result = t2 - t1;
4380974257eSBastian Koppelmann     }
439e4e39176SBastian Koppelmann     return ssov32(env, result);
4400974257eSBastian Koppelmann }
441328f1f0fSBastian Koppelmann 
442d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
443d5de7839SBastian Koppelmann                               target_ulong r2)
444d5de7839SBastian Koppelmann {
445d5de7839SBastian Koppelmann     int32_t t1, t2;
446d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
447d5de7839SBastian Koppelmann 
448d5de7839SBastian Koppelmann     t1 = sextract32(r1, 0, 16);
449d5de7839SBastian Koppelmann     t2 = sextract32(r2, 0, 16);
450d5de7839SBastian Koppelmann     if (t1 > t2) {
451d5de7839SBastian Koppelmann         ret_h0 = t1 - t2;
452d5de7839SBastian Koppelmann     } else {
453d5de7839SBastian Koppelmann         ret_h0 = t2 - t1;
454d5de7839SBastian Koppelmann     }
455d5de7839SBastian Koppelmann 
456d5de7839SBastian Koppelmann     t1 = sextract32(r1, 16, 16);
457d5de7839SBastian Koppelmann     t2 = sextract32(r2, 16, 16);
458d5de7839SBastian Koppelmann     if (t1 > t2) {
459d5de7839SBastian Koppelmann         ret_h1 = t1 - t2;
460d5de7839SBastian Koppelmann     } else {
461d5de7839SBastian Koppelmann         ret_h1 = t2 - t1;
462d5de7839SBastian Koppelmann     }
463d5de7839SBastian Koppelmann 
464d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
465d5de7839SBastian Koppelmann }
466d5de7839SBastian Koppelmann 
467328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
468328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
469328f1f0fSBastian Koppelmann {
470328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
471328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
472328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
473328f1f0fSBastian Koppelmann     int64_t result;
474328f1f0fSBastian Koppelmann 
475328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
476e4e39176SBastian Koppelmann     return ssov32(env, result);
477328f1f0fSBastian Koppelmann }
478328f1f0fSBastian Koppelmann 
479328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
480328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
481328f1f0fSBastian Koppelmann {
482328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
483328f1f0fSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
484328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
485328f1f0fSBastian Koppelmann     int64_t result;
486328f1f0fSBastian Koppelmann 
487328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
48885d604afSBastian Koppelmann     return suov32_pos(env, result);
489328f1f0fSBastian Koppelmann }
490328f1f0fSBastian Koppelmann 
491328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
492328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
493328f1f0fSBastian Koppelmann {
494328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
495328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
496328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
497328f1f0fSBastian Koppelmann     int64_t mul;
498328f1f0fSBastian Koppelmann 
499328f1f0fSBastian Koppelmann     mul = t1 * t3;
500328f1f0fSBastian Koppelmann     ret = mul + r2;
501328f1f0fSBastian Koppelmann     ovf = (ret ^ mul) & ~(mul ^ r2);
502328f1f0fSBastian Koppelmann 
503811ea608SBastian Koppelmann     t1 = ret >> 32;
504811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
505811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
506811ea608SBastian Koppelmann 
507328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
508328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
509328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
510328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
511328f1f0fSBastian Koppelmann         if (mul >= 0) {
512328f1f0fSBastian Koppelmann             ret = INT64_MAX;
513328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
514328f1f0fSBastian Koppelmann         } else {
515328f1f0fSBastian Koppelmann             ret = INT64_MIN;
516328f1f0fSBastian Koppelmann         }
517328f1f0fSBastian Koppelmann     } else {
518328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
519328f1f0fSBastian Koppelmann     }
520328f1f0fSBastian Koppelmann 
521328f1f0fSBastian Koppelmann     return ret;
522328f1f0fSBastian Koppelmann }
523328f1f0fSBastian Koppelmann 
524b00aa8ecSBastian Koppelmann uint32_t
525b00aa8ecSBastian Koppelmann helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
526b00aa8ecSBastian Koppelmann {
527b00aa8ecSBastian Koppelmann     int64_t result;
528b00aa8ecSBastian Koppelmann 
529b00aa8ecSBastian Koppelmann     result = (r1 + r2);
530b00aa8ecSBastian Koppelmann 
531b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u);
532b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
533b00aa8ecSBastian Koppelmann 
534b00aa8ecSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
535b00aa8ecSBastian Koppelmann        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
536b00aa8ecSBastian Koppelmann        case, we flip the saturated value. */
537b00aa8ecSBastian Koppelmann     if (r2 == 0x8000000000000000LL) {
538b00aa8ecSBastian Koppelmann         if (result > 0x7fffffffLL) {
539b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
540b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
541b00aa8ecSBastian Koppelmann             result = INT32_MIN;
542b00aa8ecSBastian Koppelmann         } else if (result < -0x80000000LL) {
543b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
544b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
545b00aa8ecSBastian Koppelmann             result = INT32_MAX;
546b00aa8ecSBastian Koppelmann         } else {
547b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
548b00aa8ecSBastian Koppelmann         }
549b00aa8ecSBastian Koppelmann     } else {
550b00aa8ecSBastian Koppelmann         if (result > 0x7fffffffLL) {
551b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
552b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
553b00aa8ecSBastian Koppelmann             result = INT32_MAX;
554b00aa8ecSBastian Koppelmann         } else if (result < -0x80000000LL) {
555b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
556b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
557b00aa8ecSBastian Koppelmann             result = INT32_MIN;
558b00aa8ecSBastian Koppelmann         } else {
559b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
560b00aa8ecSBastian Koppelmann         }
561b00aa8ecSBastian Koppelmann     }
562b00aa8ecSBastian Koppelmann     return (uint32_t)result;
563b00aa8ecSBastian Koppelmann }
564b00aa8ecSBastian Koppelmann 
565b00aa8ecSBastian Koppelmann uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
566b00aa8ecSBastian Koppelmann                               uint32_t r3, uint32_t n)
567b00aa8ecSBastian Koppelmann {
568b00aa8ecSBastian Koppelmann     int64_t t1 = (int64_t)r1;
569b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
570b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
571b00aa8ecSBastian Koppelmann     int64_t result, mul;
572b00aa8ecSBastian Koppelmann     int64_t ovf;
573b00aa8ecSBastian Koppelmann 
574b00aa8ecSBastian Koppelmann     mul = (t2 * t3) << n;
575b00aa8ecSBastian Koppelmann     result = mul + t1;
576b00aa8ecSBastian Koppelmann 
577b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
578b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
579b00aa8ecSBastian Koppelmann 
580b00aa8ecSBastian Koppelmann     ovf = (result ^ mul) & ~(mul ^ t1);
581b00aa8ecSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
582b00aa8ecSBastian Koppelmann        if the mul was (0x80000000 * 0x80000000) << 1). If this is the
583b00aa8ecSBastian Koppelmann        case, we flip the saturated value. */
584b00aa8ecSBastian Koppelmann     if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) {
585b00aa8ecSBastian Koppelmann         if (ovf >= 0) {
586b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
587b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
588b00aa8ecSBastian Koppelmann             /* ext_ret > MAX_INT */
589b00aa8ecSBastian Koppelmann             if (mul < 0) {
590b00aa8ecSBastian Koppelmann                 result = INT64_MAX;
591b00aa8ecSBastian Koppelmann             /* ext_ret < MIN_INT */
592b00aa8ecSBastian Koppelmann             } else {
593b00aa8ecSBastian Koppelmann                result = INT64_MIN;
594b00aa8ecSBastian Koppelmann             }
595b00aa8ecSBastian Koppelmann         } else {
596b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
597b00aa8ecSBastian Koppelmann         }
598b00aa8ecSBastian Koppelmann     } else {
599b00aa8ecSBastian Koppelmann         if (ovf < 0) {
600b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
601b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
602b00aa8ecSBastian Koppelmann             /* ext_ret > MAX_INT */
603b00aa8ecSBastian Koppelmann             if (mul >= 0) {
604b00aa8ecSBastian Koppelmann                 result = INT64_MAX;
605b00aa8ecSBastian Koppelmann             /* ext_ret < MIN_INT */
606b00aa8ecSBastian Koppelmann             } else {
607b00aa8ecSBastian Koppelmann                result = INT64_MIN;
608b00aa8ecSBastian Koppelmann             }
609b00aa8ecSBastian Koppelmann         } else {
610b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
611b00aa8ecSBastian Koppelmann         }
612b00aa8ecSBastian Koppelmann     }
613b00aa8ecSBastian Koppelmann     return (uint64_t)result;
614b00aa8ecSBastian Koppelmann }
615b00aa8ecSBastian Koppelmann 
616b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
617b00aa8ecSBastian Koppelmann                              uint32_t r3, uint32_t n)
618b00aa8ecSBastian Koppelmann {
619b00aa8ecSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
620b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
621b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
622b00aa8ecSBastian Koppelmann     int64_t mul, ret;
623b00aa8ecSBastian Koppelmann 
624b00aa8ecSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
625b00aa8ecSBastian Koppelmann         mul = 0x7fffffff;
626b00aa8ecSBastian Koppelmann     } else {
627b00aa8ecSBastian Koppelmann         mul = (t2 * t3) << n;
628b00aa8ecSBastian Koppelmann     }
629b00aa8ecSBastian Koppelmann 
630b00aa8ecSBastian Koppelmann     ret = t1 + mul + 0x8000;
631b00aa8ecSBastian Koppelmann 
632b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
633b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
634b00aa8ecSBastian Koppelmann 
635b00aa8ecSBastian Koppelmann     if (ret > 0x7fffffffll) {
636b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
637b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
638b00aa8ecSBastian Koppelmann         ret = INT32_MAX;
639b00aa8ecSBastian Koppelmann     } else if (ret < -0x80000000ll) {
640b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
641b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
642b00aa8ecSBastian Koppelmann         ret = INT32_MIN;
643b00aa8ecSBastian Koppelmann     } else {
644b00aa8ecSBastian Koppelmann         env->PSW_USB_V = 0;
645b00aa8ecSBastian Koppelmann     }
646b00aa8ecSBastian Koppelmann     return ret & 0xffff0000ll;
647b00aa8ecSBastian Koppelmann }
648b00aa8ecSBastian Koppelmann 
649328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
650328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
651328f1f0fSBastian Koppelmann {
652328f1f0fSBastian Koppelmann     uint64_t ret, mul;
653328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
654328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
655328f1f0fSBastian Koppelmann 
656328f1f0fSBastian Koppelmann     mul = t1 * t3;
657328f1f0fSBastian Koppelmann     ret = mul + r2;
658328f1f0fSBastian Koppelmann 
659811ea608SBastian Koppelmann     t1 = ret >> 32;
660811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
661811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
662811ea608SBastian Koppelmann 
663328f1f0fSBastian Koppelmann     if (ret < r2) {
664328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
665328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
666328f1f0fSBastian Koppelmann         /* saturate */
667328f1f0fSBastian Koppelmann         ret = UINT64_MAX;
668328f1f0fSBastian Koppelmann     } else {
669328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
670328f1f0fSBastian Koppelmann     }
671328f1f0fSBastian Koppelmann     return ret;
672328f1f0fSBastian Koppelmann }
673328f1f0fSBastian Koppelmann 
674328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
675328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
676328f1f0fSBastian Koppelmann {
677328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
678328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
679328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
680328f1f0fSBastian Koppelmann     int64_t result;
681328f1f0fSBastian Koppelmann 
682328f1f0fSBastian Koppelmann     result = t2 - (t1 * t3);
683e4e39176SBastian Koppelmann     return ssov32(env, result);
684328f1f0fSBastian Koppelmann }
685328f1f0fSBastian Koppelmann 
686328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
687328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
688328f1f0fSBastian Koppelmann {
6893debbb5aSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
6903debbb5aSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
6913debbb5aSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
6923debbb5aSBastian Koppelmann     uint64_t result;
6933debbb5aSBastian Koppelmann     uint64_t mul;
694328f1f0fSBastian Koppelmann 
6953debbb5aSBastian Koppelmann     mul = (t1 * t3);
6963debbb5aSBastian Koppelmann     result = t2 - mul;
6973debbb5aSBastian Koppelmann 
6983debbb5aSBastian Koppelmann     env->PSW_USB_AV = result ^ result * 2u;
6993debbb5aSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
7003debbb5aSBastian Koppelmann     /* we calculate ovf by hand here, because the multiplication can overflow on
7013debbb5aSBastian Koppelmann        the host, which would give false results if we compare to less than
7023debbb5aSBastian Koppelmann        zero */
7033debbb5aSBastian Koppelmann     if (mul > t2) {
7043debbb5aSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
7053debbb5aSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
7063debbb5aSBastian Koppelmann         result = 0;
7073debbb5aSBastian Koppelmann     } else {
7083debbb5aSBastian Koppelmann         env->PSW_USB_V = 0;
7093debbb5aSBastian Koppelmann     }
7103debbb5aSBastian Koppelmann     return result;
711328f1f0fSBastian Koppelmann }
712328f1f0fSBastian Koppelmann 
713328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
714328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
715328f1f0fSBastian Koppelmann {
716328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
717328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
718328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
719328f1f0fSBastian Koppelmann     int64_t mul;
720328f1f0fSBastian Koppelmann 
721328f1f0fSBastian Koppelmann     mul = t1 * t3;
722328f1f0fSBastian Koppelmann     ret = r2 - mul;
723328f1f0fSBastian Koppelmann     ovf = (ret ^ r2) & (mul ^ r2);
724328f1f0fSBastian Koppelmann 
725811ea608SBastian Koppelmann     t1 = ret >> 32;
726811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
727811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
728811ea608SBastian Koppelmann 
729328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
730328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
731328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
732328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
733328f1f0fSBastian Koppelmann         if (mul < 0) {
734328f1f0fSBastian Koppelmann             ret = INT64_MAX;
735328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
736328f1f0fSBastian Koppelmann         } else {
737328f1f0fSBastian Koppelmann             ret = INT64_MIN;
738328f1f0fSBastian Koppelmann         }
739328f1f0fSBastian Koppelmann     } else {
740328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
741328f1f0fSBastian Koppelmann     }
742328f1f0fSBastian Koppelmann     return ret;
743328f1f0fSBastian Koppelmann }
744328f1f0fSBastian Koppelmann 
745328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
746328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
747328f1f0fSBastian Koppelmann {
748328f1f0fSBastian Koppelmann     uint64_t ret, mul;
749328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
750328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
751328f1f0fSBastian Koppelmann 
752328f1f0fSBastian Koppelmann     mul = t1 * t3;
753328f1f0fSBastian Koppelmann     ret = r2 - mul;
754328f1f0fSBastian Koppelmann 
755811ea608SBastian Koppelmann     t1 = ret >> 32;
756811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
757811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
758811ea608SBastian Koppelmann 
759328f1f0fSBastian Koppelmann     if (ret > r2) {
760328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
761328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
762328f1f0fSBastian Koppelmann         /* saturate */
763328f1f0fSBastian Koppelmann         ret = 0;
764328f1f0fSBastian Koppelmann     } else {
765328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
766328f1f0fSBastian Koppelmann     }
767328f1f0fSBastian Koppelmann     return ret;
768328f1f0fSBastian Koppelmann }
769328f1f0fSBastian Koppelmann 
770d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
771d5de7839SBastian Koppelmann {
772d5de7839SBastian Koppelmann     int32_t b, i;
773d5de7839SBastian Koppelmann     int32_t ovf = 0;
774d5de7839SBastian Koppelmann     int32_t avf = 0;
775d5de7839SBastian Koppelmann     int32_t ret = 0;
776d5de7839SBastian Koppelmann 
777d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
778d5de7839SBastian Koppelmann         b = sextract32(arg, i * 8, 8);
779d5de7839SBastian Koppelmann         b = (b >= 0) ? b : (0 - b);
780d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
781d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
782d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
783d5de7839SBastian Koppelmann     }
784d5de7839SBastian Koppelmann 
785d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
786d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
787d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
788d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
789d5de7839SBastian Koppelmann 
790d5de7839SBastian Koppelmann     return ret;
791d5de7839SBastian Koppelmann }
792d5de7839SBastian Koppelmann 
793d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
794d5de7839SBastian Koppelmann {
795d5de7839SBastian Koppelmann     int32_t h, i;
796d5de7839SBastian Koppelmann     int32_t ovf = 0;
797d5de7839SBastian Koppelmann     int32_t avf = 0;
798d5de7839SBastian Koppelmann     int32_t ret = 0;
799d5de7839SBastian Koppelmann 
800d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
801d5de7839SBastian Koppelmann         h = sextract32(arg, i * 16, 16);
802d5de7839SBastian Koppelmann         h = (h >= 0) ? h : (0 - h);
803d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
804d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
805d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
806d5de7839SBastian Koppelmann     }
807d5de7839SBastian Koppelmann 
808d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
809d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
810d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
811d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
812d5de7839SBastian Koppelmann 
813d5de7839SBastian Koppelmann     return ret;
814d5de7839SBastian Koppelmann }
815d5de7839SBastian Koppelmann 
816d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
817d5de7839SBastian Koppelmann {
818d5de7839SBastian Koppelmann     int32_t b, i;
819d5de7839SBastian Koppelmann     int32_t extr_r2;
820d5de7839SBastian Koppelmann     int32_t ovf = 0;
821d5de7839SBastian Koppelmann     int32_t avf = 0;
822d5de7839SBastian Koppelmann     int32_t ret = 0;
823d5de7839SBastian Koppelmann 
824d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
825d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
826d5de7839SBastian Koppelmann         b = sextract32(r1, i * 8, 8);
827d5de7839SBastian Koppelmann         b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
828d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
829d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
830d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
831d5de7839SBastian Koppelmann     }
832d5de7839SBastian Koppelmann 
833d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
834d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
835d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
836d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
837d5de7839SBastian Koppelmann     return ret;
838d5de7839SBastian Koppelmann }
839d5de7839SBastian Koppelmann 
840d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
841d5de7839SBastian Koppelmann {
842d5de7839SBastian Koppelmann     int32_t h, i;
843d5de7839SBastian Koppelmann     int32_t extr_r2;
844d5de7839SBastian Koppelmann     int32_t ovf = 0;
845d5de7839SBastian Koppelmann     int32_t avf = 0;
846d5de7839SBastian Koppelmann     int32_t ret = 0;
847d5de7839SBastian Koppelmann 
848d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
849d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
850d5de7839SBastian Koppelmann         h = sextract32(r1, i * 16, 16);
851d5de7839SBastian Koppelmann         h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
852d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
853d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
854d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
855d5de7839SBastian Koppelmann     }
856d5de7839SBastian Koppelmann 
857d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
858d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
859d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
860d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
861d5de7839SBastian Koppelmann 
862d5de7839SBastian Koppelmann     return ret;
863d5de7839SBastian Koppelmann }
864d5de7839SBastian Koppelmann 
8652e430e1cSBastian Koppelmann uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
8662e430e1cSBastian Koppelmann                        uint32_t r2_h)
8672e430e1cSBastian Koppelmann {
8682e430e1cSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
8692e430e1cSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
8702e430e1cSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
8712e430e1cSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
8722e430e1cSBastian Koppelmann     int64_t result0, result1;
8732e430e1cSBastian Koppelmann     uint32_t ovf0, ovf1;
8742e430e1cSBastian Koppelmann     uint32_t avf0, avf1;
8752e430e1cSBastian Koppelmann 
8762e430e1cSBastian Koppelmann     ovf0 = ovf1 = 0;
8772e430e1cSBastian Koppelmann 
8782e430e1cSBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
8792e430e1cSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
8802e430e1cSBastian Koppelmann 
8812e430e1cSBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
8822e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
8832e430e1cSBastian Koppelmann     }
8842e430e1cSBastian Koppelmann 
8852e430e1cSBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
8862e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
8872e430e1cSBastian Koppelmann     }
8882e430e1cSBastian Koppelmann 
8892e430e1cSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
8902e430e1cSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
8912e430e1cSBastian Koppelmann 
8922e430e1cSBastian Koppelmann     avf0 = result0 * 2u;
8932e430e1cSBastian Koppelmann     avf0 = result0 ^ avf0;
8942e430e1cSBastian Koppelmann     avf1 = result1 * 2u;
8952e430e1cSBastian Koppelmann     avf1 = result1 ^ avf1;
8962e430e1cSBastian Koppelmann 
8972e430e1cSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
8982e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
8992e430e1cSBastian Koppelmann 
9002e430e1cSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
9012e430e1cSBastian Koppelmann }
9022e430e1cSBastian Koppelmann 
903bebe80fcSBastian Koppelmann uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
904bebe80fcSBastian Koppelmann                          uint32_t r2_h)
905bebe80fcSBastian Koppelmann {
906bebe80fcSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
907bebe80fcSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
908bebe80fcSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
909bebe80fcSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
910bebe80fcSBastian Koppelmann     int64_t result0, result1;
911bebe80fcSBastian Koppelmann     uint32_t ovf0, ovf1;
912bebe80fcSBastian Koppelmann     uint32_t avf0, avf1;
913bebe80fcSBastian Koppelmann 
914bebe80fcSBastian Koppelmann     ovf0 = ovf1 = 0;
915bebe80fcSBastian Koppelmann 
916bebe80fcSBastian Koppelmann     result0 = r2_low - mul_res0 + 0x8000;
917bebe80fcSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
918bebe80fcSBastian Koppelmann 
919bebe80fcSBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
920bebe80fcSBastian Koppelmann         ovf0 = (1 << 31);
921bebe80fcSBastian Koppelmann     }
922bebe80fcSBastian Koppelmann 
923bebe80fcSBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
924bebe80fcSBastian Koppelmann         ovf1 = (1 << 31);
925bebe80fcSBastian Koppelmann     }
926bebe80fcSBastian Koppelmann 
927bebe80fcSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
928bebe80fcSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
929bebe80fcSBastian Koppelmann 
930bebe80fcSBastian Koppelmann     avf0 = result0 * 2u;
931bebe80fcSBastian Koppelmann     avf0 = result0 ^ avf0;
932bebe80fcSBastian Koppelmann     avf1 = result1 * 2u;
933bebe80fcSBastian Koppelmann     avf1 = result1 ^ avf1;
934bebe80fcSBastian Koppelmann 
935bebe80fcSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
936bebe80fcSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
937bebe80fcSBastian Koppelmann 
938bebe80fcSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
939bebe80fcSBastian Koppelmann }
940bebe80fcSBastian Koppelmann 
941b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
942b00aa8ecSBastian Koppelmann                         uint32_t r3, uint32_t n)
943b00aa8ecSBastian Koppelmann {
944b00aa8ecSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
945b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
946b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
947b00aa8ecSBastian Koppelmann     int64_t mul, ret;
948b00aa8ecSBastian Koppelmann 
949b00aa8ecSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
950b00aa8ecSBastian Koppelmann         mul = 0x7fffffff;
951b00aa8ecSBastian Koppelmann     } else {
952b00aa8ecSBastian Koppelmann         mul = (t2 * t3) << n;
953b00aa8ecSBastian Koppelmann     }
954b00aa8ecSBastian Koppelmann 
955b00aa8ecSBastian Koppelmann     ret = t1 + mul + 0x8000;
956b00aa8ecSBastian Koppelmann 
957b00aa8ecSBastian Koppelmann     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
958b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
959b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
960b00aa8ecSBastian Koppelmann     } else {
961b00aa8ecSBastian Koppelmann         env->PSW_USB_V = 0;
962b00aa8ecSBastian Koppelmann     }
963b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
964b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
965b00aa8ecSBastian Koppelmann 
966b00aa8ecSBastian Koppelmann     return ret & 0xffff0000ll;
967b00aa8ecSBastian Koppelmann }
968b00aa8ecSBastian Koppelmann 
969d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
970d5de7839SBastian Koppelmann {
971d5de7839SBastian Koppelmann     int32_t b, i;
972d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
973d5de7839SBastian Koppelmann     int32_t ovf = 0;
974d5de7839SBastian Koppelmann     int32_t avf = 0;
975d5de7839SBastian Koppelmann     uint32_t ret = 0;
976d5de7839SBastian Koppelmann 
977d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
978d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
979d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
980d5de7839SBastian Koppelmann 
981d5de7839SBastian Koppelmann         b = extr_r1 + extr_r2;
982d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
983d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
984d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
985d5de7839SBastian Koppelmann     }
986d5de7839SBastian Koppelmann 
987d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
988d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
989d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
990d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
991d5de7839SBastian Koppelmann 
992d5de7839SBastian Koppelmann     return ret;
993d5de7839SBastian Koppelmann }
994d5de7839SBastian Koppelmann 
995d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
996d5de7839SBastian Koppelmann {
997d5de7839SBastian Koppelmann     int32_t h, i;
998d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
999d5de7839SBastian Koppelmann     int32_t ovf = 0;
1000d5de7839SBastian Koppelmann     int32_t avf = 0;
1001d5de7839SBastian Koppelmann     int32_t ret = 0;
1002d5de7839SBastian Koppelmann 
1003d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1004d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
1005d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
1006d5de7839SBastian Koppelmann         h = extr_r1 + extr_r2;
1007d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
1008d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1009d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1010d5de7839SBastian Koppelmann     }
1011d5de7839SBastian Koppelmann 
1012d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1013d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1014d5de7839SBastian Koppelmann     env->PSW_USB_AV = (avf << 16);
1015d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1016d5de7839SBastian Koppelmann 
1017d5de7839SBastian Koppelmann     return ret;
1018d5de7839SBastian Koppelmann }
1019d5de7839SBastian Koppelmann 
1020d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1021d5de7839SBastian Koppelmann {
1022d5de7839SBastian Koppelmann     int32_t b, i;
1023d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1024d5de7839SBastian Koppelmann     int32_t ovf = 0;
1025d5de7839SBastian Koppelmann     int32_t avf = 0;
1026d5de7839SBastian Koppelmann     uint32_t ret = 0;
1027d5de7839SBastian Koppelmann 
1028d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1029d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
1030d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
1031d5de7839SBastian Koppelmann 
1032d5de7839SBastian Koppelmann         b = extr_r1 - extr_r2;
1033d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
1034d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
1035d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
1036d5de7839SBastian Koppelmann     }
1037d5de7839SBastian Koppelmann 
1038d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1039d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1040d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
1041d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1042d5de7839SBastian Koppelmann 
1043d5de7839SBastian Koppelmann     return ret;
1044d5de7839SBastian Koppelmann }
1045d5de7839SBastian Koppelmann 
1046d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1047d5de7839SBastian Koppelmann {
1048d5de7839SBastian Koppelmann     int32_t h, i;
1049d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
1050d5de7839SBastian Koppelmann     int32_t ovf = 0;
1051d5de7839SBastian Koppelmann     int32_t avf = 0;
1052d5de7839SBastian Koppelmann     int32_t ret = 0;
1053d5de7839SBastian Koppelmann 
1054d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
1055d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
1056d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
1057d5de7839SBastian Koppelmann         h = extr_r1 - extr_r2;
1058d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
1059d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
1060d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
1061d5de7839SBastian Koppelmann     }
1062d5de7839SBastian Koppelmann 
1063d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
1064d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1065d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
1066d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
1067d5de7839SBastian Koppelmann 
1068d5de7839SBastian Koppelmann     return ret;
1069d5de7839SBastian Koppelmann }
1070d5de7839SBastian Koppelmann 
1071d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
1072d5de7839SBastian Koppelmann {
1073d5de7839SBastian Koppelmann     int32_t ret;
1074d5de7839SBastian Koppelmann     int32_t i, msk;
1075d5de7839SBastian Koppelmann 
1076d5de7839SBastian Koppelmann     ret = 0;
1077d5de7839SBastian Koppelmann     msk = 0xff;
1078d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1079d5de7839SBastian Koppelmann         if ((r1 & msk) == (r2 & msk)) {
1080d5de7839SBastian Koppelmann             ret |= msk;
1081d5de7839SBastian Koppelmann         }
1082d5de7839SBastian Koppelmann         msk = msk << 8;
1083d5de7839SBastian Koppelmann     }
1084d5de7839SBastian Koppelmann 
1085d5de7839SBastian Koppelmann     return ret;
1086d5de7839SBastian Koppelmann }
1087d5de7839SBastian Koppelmann 
1088d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
1089d5de7839SBastian Koppelmann {
1090d5de7839SBastian Koppelmann     int32_t ret = 0;
1091d5de7839SBastian Koppelmann 
1092d5de7839SBastian Koppelmann     if ((r1 & 0xffff) == (r2 & 0xffff)) {
1093d5de7839SBastian Koppelmann         ret = 0xffff;
1094d5de7839SBastian Koppelmann     }
1095d5de7839SBastian Koppelmann 
1096d5de7839SBastian Koppelmann     if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
1097d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1098d5de7839SBastian Koppelmann     }
1099d5de7839SBastian Koppelmann 
1100d5de7839SBastian Koppelmann     return ret;
1101d5de7839SBastian Koppelmann }
1102d5de7839SBastian Koppelmann 
1103d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
1104d5de7839SBastian Koppelmann {
1105d5de7839SBastian Koppelmann     int32_t i;
1106d5de7839SBastian Koppelmann     uint32_t ret = 0;
1107d5de7839SBastian Koppelmann 
1108d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1109d5de7839SBastian Koppelmann         ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
1110d5de7839SBastian Koppelmann     }
1111d5de7839SBastian Koppelmann 
1112d5de7839SBastian Koppelmann     return ret;
1113d5de7839SBastian Koppelmann }
1114d5de7839SBastian Koppelmann 
1115d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
1116d5de7839SBastian Koppelmann {
1117d5de7839SBastian Koppelmann     uint32_t ret;
1118d5de7839SBastian Koppelmann 
1119d5de7839SBastian Koppelmann     ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
1120d5de7839SBastian Koppelmann     ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
1121d5de7839SBastian Koppelmann 
1122d5de7839SBastian Koppelmann     return ret;
1123d5de7839SBastian Koppelmann }
1124d5de7839SBastian Koppelmann 
1125d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
1126d5de7839SBastian Koppelmann {
1127d5de7839SBastian Koppelmann     int32_t i;
1128d5de7839SBastian Koppelmann     uint32_t ret = 0;
1129d5de7839SBastian Koppelmann 
1130d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1131d5de7839SBastian Koppelmann         if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
1132d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
1133d5de7839SBastian Koppelmann         }
1134d5de7839SBastian Koppelmann     }
1135d5de7839SBastian Koppelmann 
1136d5de7839SBastian Koppelmann     return ret;
1137d5de7839SBastian Koppelmann }
1138d5de7839SBastian Koppelmann 
1139d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
1140d5de7839SBastian Koppelmann {
1141d5de7839SBastian Koppelmann     int32_t i;
1142d5de7839SBastian Koppelmann     uint32_t ret = 0;
1143d5de7839SBastian Koppelmann 
1144d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1145d5de7839SBastian Koppelmann         if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
1146d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
1147d5de7839SBastian Koppelmann         }
1148d5de7839SBastian Koppelmann     }
1149d5de7839SBastian Koppelmann 
1150d5de7839SBastian Koppelmann     return ret;
1151d5de7839SBastian Koppelmann }
1152d5de7839SBastian Koppelmann 
1153d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
1154d5de7839SBastian Koppelmann {
1155d5de7839SBastian Koppelmann     uint32_t ret = 0;
1156d5de7839SBastian Koppelmann 
1157d5de7839SBastian Koppelmann     if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
1158d5de7839SBastian Koppelmann         ret |= 0xffff;
1159d5de7839SBastian Koppelmann     }
1160d5de7839SBastian Koppelmann 
1161d5de7839SBastian Koppelmann     if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
1162d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1163d5de7839SBastian Koppelmann     }
1164d5de7839SBastian Koppelmann 
1165d5de7839SBastian Koppelmann     return ret;
1166d5de7839SBastian Koppelmann }
1167d5de7839SBastian Koppelmann 
1168d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
1169d5de7839SBastian Koppelmann {
1170d5de7839SBastian Koppelmann     uint32_t ret = 0;
1171d5de7839SBastian Koppelmann 
1172d5de7839SBastian Koppelmann     if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
1173d5de7839SBastian Koppelmann         ret |= 0xffff;
1174d5de7839SBastian Koppelmann     }
1175d5de7839SBastian Koppelmann 
1176d5de7839SBastian Koppelmann     if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
1177d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1178d5de7839SBastian Koppelmann     }
1179d5de7839SBastian Koppelmann 
1180d5de7839SBastian Koppelmann     return ret;
1181d5de7839SBastian Koppelmann }
1182d5de7839SBastian Koppelmann 
1183d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op)                                 \
1184d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
1185d5de7839SBastian Koppelmann {                                                             \
1186d5de7839SBastian Koppelmann     int32_t i, extr_r1, extr_r2;                              \
1187d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1188d5de7839SBastian Koppelmann                                                               \
1189d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
1190d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);                   \
1191d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);                   \
1192d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1193d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1194d5de7839SBastian Koppelmann     }                                                         \
1195d5de7839SBastian Koppelmann     return ret;                                               \
1196d5de7839SBastian Koppelmann }                                                             \
1197d5de7839SBastian Koppelmann                                                               \
1198d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
1199d5de7839SBastian Koppelmann {                                                             \
1200d5de7839SBastian Koppelmann     int32_t i;                                                \
1201d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
1202d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1203d5de7839SBastian Koppelmann                                                               \
1204d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
1205d5de7839SBastian Koppelmann         extr_r1 = extract32(r1, i * 8, 8);                    \
1206d5de7839SBastian Koppelmann         extr_r2 = extract32(r2, i * 8, 8);                    \
1207d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1208d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1209d5de7839SBastian Koppelmann     }                                                         \
1210d5de7839SBastian Koppelmann     return ret;                                               \
1211d5de7839SBastian Koppelmann }                                                             \
1212d5de7839SBastian Koppelmann                                                               \
1213d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
1214d5de7839SBastian Koppelmann {                                                             \
1215d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;                                 \
1216d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1217d5de7839SBastian Koppelmann                                                               \
1218d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 0, 16);                          \
1219d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 0, 16);                          \
1220d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1221d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
1222d5de7839SBastian Koppelmann                                                               \
1223d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 16, 16);                         \
1224d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 16, 16);                         \
1225d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1226d5de7839SBastian Koppelmann     ret |= extr_r1 << 16;                                     \
1227d5de7839SBastian Koppelmann                                                               \
1228d5de7839SBastian Koppelmann     return ret;                                               \
1229d5de7839SBastian Koppelmann }                                                             \
1230d5de7839SBastian Koppelmann                                                               \
1231d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
1232d5de7839SBastian Koppelmann {                                                             \
1233d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
1234d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1235d5de7839SBastian Koppelmann                                                               \
1236d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 0, 16);                           \
1237d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 0, 16);                           \
1238d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1239d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
1240d5de7839SBastian Koppelmann                                                               \
1241d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 16, 16);                          \
1242d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 16, 16);                          \
1243d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1244d5de7839SBastian Koppelmann     ret |= extr_r1 << (16);                                   \
1245d5de7839SBastian Koppelmann                                                               \
1246d5de7839SBastian Koppelmann     return ret;                                               \
1247d5de7839SBastian Koppelmann }                                                             \
124809532255SBastian Koppelmann                                                               \
124909532255SBastian Koppelmann uint64_t helper_ix##name(uint64_t r1, uint32_t r2)            \
125009532255SBastian Koppelmann {                                                             \
125109532255SBastian Koppelmann     int64_t r2l, r2h, r1hl;                                   \
125209532255SBastian Koppelmann     uint64_t ret = 0;                                         \
125309532255SBastian Koppelmann                                                               \
125409532255SBastian Koppelmann     ret = ((r1 + 2) & 0xffff);                                \
125509532255SBastian Koppelmann     r2l = sextract64(r2, 0, 16);                              \
125609532255SBastian Koppelmann     r2h = sextract64(r2, 16, 16);                             \
125709532255SBastian Koppelmann     r1hl = sextract64(r1, 32, 16);                            \
125809532255SBastian Koppelmann                                                               \
125909532255SBastian Koppelmann     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
126009532255SBastian Koppelmann         ret |= (r2l & 0xffff) << 32;                          \
126109532255SBastian Koppelmann         ret |= extract64(r1, 0, 16) << 16;                    \
126209532255SBastian Koppelmann     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
126309532255SBastian Koppelmann         ret |= extract64(r2, 16, 16) << 32;                   \
126409532255SBastian Koppelmann         ret |= extract64(r1 + 1, 0, 16) << 16;                \
126509532255SBastian Koppelmann     } else {                                                  \
126609532255SBastian Koppelmann         ret |= r1 & 0xffffffff0000ull;                        \
126709532255SBastian Koppelmann     }                                                         \
126809532255SBastian Koppelmann     return ret;                                               \
126909532255SBastian Koppelmann }                                                             \
127009532255SBastian Koppelmann                                                               \
127109532255SBastian Koppelmann uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2)       \
127209532255SBastian Koppelmann {                                                             \
127309532255SBastian Koppelmann     int64_t r2l, r2h, r1hl;                                   \
127409532255SBastian Koppelmann     uint64_t ret = 0;                                         \
127509532255SBastian Koppelmann                                                               \
127609532255SBastian Koppelmann     ret = ((r1 + 2) & 0xffff);                                \
127709532255SBastian Koppelmann     r2l = extract64(r2, 0, 16);                               \
127809532255SBastian Koppelmann     r2h = extract64(r2, 16, 16);                              \
127909532255SBastian Koppelmann     r1hl = extract64(r1, 32, 16);                             \
128009532255SBastian Koppelmann                                                               \
128109532255SBastian Koppelmann     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
128209532255SBastian Koppelmann         ret |= (r2l & 0xffff) << 32;                          \
128309532255SBastian Koppelmann         ret |= extract64(r1, 0, 16) << 16;                    \
128409532255SBastian Koppelmann     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
128509532255SBastian Koppelmann         ret |= extract64(r2, 16, 16) << 32;                   \
128609532255SBastian Koppelmann         ret |= extract64(r1 + 1, 0, 16) << 16;                \
128709532255SBastian Koppelmann     } else {                                                  \
128809532255SBastian Koppelmann         ret |= r1 & 0xffffffff0000ull;                        \
128909532255SBastian Koppelmann     }                                                         \
129009532255SBastian Koppelmann     return ret;                                               \
129109532255SBastian Koppelmann }
1292d5de7839SBastian Koppelmann 
1293d5de7839SBastian Koppelmann EXTREMA_H_B(max, >)
1294d5de7839SBastian Koppelmann EXTREMA_H_B(min, <)
1295d5de7839SBastian Koppelmann 
1296d5de7839SBastian Koppelmann #undef EXTREMA_H_B
1297d5de7839SBastian Koppelmann 
12980b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1)
12990b79a781SBastian Koppelmann {
13000b79a781SBastian Koppelmann     return clo32(r1);
13010b79a781SBastian Koppelmann }
13020b79a781SBastian Koppelmann 
13030b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1)
13040b79a781SBastian Koppelmann {
13050b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
13060b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
13070b79a781SBastian Koppelmann 
13080b79a781SBastian Koppelmann     ret_hw0 = clo32(ret_hw0 << 16);
13090b79a781SBastian Koppelmann     ret_hw1 = clo32(ret_hw1 << 16);
13100b79a781SBastian Koppelmann 
13110b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
13120b79a781SBastian Koppelmann         ret_hw0 = 16;
13130b79a781SBastian Koppelmann     }
13140b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
13150b79a781SBastian Koppelmann         ret_hw1 = 16;
13160b79a781SBastian Koppelmann     }
13170b79a781SBastian Koppelmann 
13180b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
13190b79a781SBastian Koppelmann }
13200b79a781SBastian Koppelmann 
13210b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1)
13220b79a781SBastian Koppelmann {
13230b79a781SBastian Koppelmann     return clz32(r1);
13240b79a781SBastian Koppelmann }
13250b79a781SBastian Koppelmann 
13260b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1)
13270b79a781SBastian Koppelmann {
13280b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
13290b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
13300b79a781SBastian Koppelmann 
13310b79a781SBastian Koppelmann     ret_hw0 = clz32(ret_hw0 << 16);
13320b79a781SBastian Koppelmann     ret_hw1 = clz32(ret_hw1 << 16);
13330b79a781SBastian Koppelmann 
13340b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
13350b79a781SBastian Koppelmann         ret_hw0 = 16;
13360b79a781SBastian Koppelmann     }
13370b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
13380b79a781SBastian Koppelmann         ret_hw1 = 16;
13390b79a781SBastian Koppelmann     }
13400b79a781SBastian Koppelmann 
13410b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
13420b79a781SBastian Koppelmann }
13430b79a781SBastian Koppelmann 
13440b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1)
13450b79a781SBastian Koppelmann {
13460b79a781SBastian Koppelmann     return clrsb32(r1);
13470b79a781SBastian Koppelmann }
13480b79a781SBastian Koppelmann 
13490b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1)
13500b79a781SBastian Koppelmann {
13510b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
13520b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
13530b79a781SBastian Koppelmann 
13540b79a781SBastian Koppelmann     ret_hw0 = clrsb32(ret_hw0 << 16);
13550b79a781SBastian Koppelmann     ret_hw1 = clrsb32(ret_hw1 << 16);
13560b79a781SBastian Koppelmann 
13570b79a781SBastian Koppelmann     if (ret_hw0 > 15) {
13580b79a781SBastian Koppelmann         ret_hw0 = 15;
13590b79a781SBastian Koppelmann     }
13600b79a781SBastian Koppelmann     if (ret_hw1 > 15) {
13610b79a781SBastian Koppelmann         ret_hw1 = 15;
13620b79a781SBastian Koppelmann     }
13630b79a781SBastian Koppelmann 
13640b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
13650b79a781SBastian Koppelmann }
13660b79a781SBastian Koppelmann 
13670b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2)
13680b79a781SBastian Koppelmann {
13690b79a781SBastian Koppelmann     int32_t shift_count = sextract32(r2, 0, 6);
13700b79a781SBastian Koppelmann 
13710b79a781SBastian Koppelmann     if (shift_count == -32) {
13720b79a781SBastian Koppelmann         return 0;
13730b79a781SBastian Koppelmann     } else if (shift_count < 0) {
13740b79a781SBastian Koppelmann         return r1 >> -shift_count;
13750b79a781SBastian Koppelmann     } else {
13760b79a781SBastian Koppelmann         return r1 << shift_count;
13770b79a781SBastian Koppelmann     }
13780b79a781SBastian Koppelmann }
13790b79a781SBastian Koppelmann 
13800b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
13810b79a781SBastian Koppelmann {
13820b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
13830b79a781SBastian Koppelmann     int32_t shift_count;
13840b79a781SBastian Koppelmann 
13850b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
13860b79a781SBastian Koppelmann 
13870b79a781SBastian Koppelmann     if (shift_count == -16) {
13880b79a781SBastian Koppelmann         return 0;
13890b79a781SBastian Koppelmann     } else if (shift_count < 0) {
13900b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
13910b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
13920b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
13930b79a781SBastian Koppelmann     } else {
13940b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) << shift_count;
13950b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) << shift_count;
13960b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
13970b79a781SBastian Koppelmann     }
13980b79a781SBastian Koppelmann }
13990b79a781SBastian Koppelmann 
14000b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
14010b79a781SBastian Koppelmann {
14020b79a781SBastian Koppelmann     int32_t shift_count;
14030b79a781SBastian Koppelmann     int64_t result, t1;
14040b79a781SBastian Koppelmann     uint32_t ret;
14050b79a781SBastian Koppelmann 
14060b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 6);
14070b79a781SBastian Koppelmann     t1 = sextract32(r1, 0, 32);
14080b79a781SBastian Koppelmann 
14090b79a781SBastian Koppelmann     if (shift_count == 0) {
14100b79a781SBastian Koppelmann         env->PSW_USB_C = env->PSW_USB_V = 0;
14110b79a781SBastian Koppelmann         ret = r1;
14120b79a781SBastian Koppelmann     } else if (shift_count == -32) {
14130b79a781SBastian Koppelmann         env->PSW_USB_C = r1;
14140b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
14150b79a781SBastian Koppelmann         ret = t1 >> 31;
14160b79a781SBastian Koppelmann     } else if (shift_count > 0) {
14170b79a781SBastian Koppelmann         result = t1 << shift_count;
14180b79a781SBastian Koppelmann         /* calc carry */
1419452e3d49SPeter Maydell         env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
14200b79a781SBastian Koppelmann         /* calc v */
14210b79a781SBastian Koppelmann         env->PSW_USB_V = (((result > 0x7fffffffLL) ||
14220b79a781SBastian Koppelmann                            (result < -0x80000000LL)) << 31);
14230b79a781SBastian Koppelmann         /* calc sv */
14240b79a781SBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
14250b79a781SBastian Koppelmann         ret = (uint32_t)result;
14260b79a781SBastian Koppelmann     } else {
14270b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
14280b79a781SBastian Koppelmann         env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
14290b79a781SBastian Koppelmann         ret = t1 >> -shift_count;
14300b79a781SBastian Koppelmann     }
14310b79a781SBastian Koppelmann 
14320b79a781SBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
14330b79a781SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
14340b79a781SBastian Koppelmann 
14350b79a781SBastian Koppelmann     return ret;
14360b79a781SBastian Koppelmann }
14370b79a781SBastian Koppelmann 
14380b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
14390b79a781SBastian Koppelmann {
14400b79a781SBastian Koppelmann     int32_t shift_count;
14410b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
14420b79a781SBastian Koppelmann 
14430b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
14440b79a781SBastian Koppelmann 
14450b79a781SBastian Koppelmann     if (shift_count == 0) {
14460b79a781SBastian Koppelmann         return r1;
14470b79a781SBastian Koppelmann     } else if (shift_count < 0) {
14480b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
14490b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
14500b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
14510b79a781SBastian Koppelmann     } else {
14520b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) << shift_count;
14530b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) << shift_count;
14540b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
14550b79a781SBastian Koppelmann     }
14560b79a781SBastian Koppelmann }
14570b79a781SBastian Koppelmann 
1458e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1459e2bed107SBastian Koppelmann {
1460e2bed107SBastian Koppelmann     uint32_t i, ret;
1461e2bed107SBastian Koppelmann 
1462e2bed107SBastian Koppelmann     ret = 0;
1463e2bed107SBastian Koppelmann     for (i = 0; i < 16; i++) {
1464e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (2 * i + 1);
1465e2bed107SBastian Koppelmann         ret |= (r2 & 1) << (2 * i);
1466e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1467e2bed107SBastian Koppelmann         r2 = r2 >> 1;
1468e2bed107SBastian Koppelmann     }
1469e2bed107SBastian Koppelmann     return ret;
1470e2bed107SBastian Koppelmann }
1471e2bed107SBastian Koppelmann 
1472e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1)
1473e2bed107SBastian Koppelmann {
1474e2bed107SBastian Koppelmann     int32_t i;
1475e2bed107SBastian Koppelmann     uint64_t ret;
1476e2bed107SBastian Koppelmann 
1477e2bed107SBastian Koppelmann     ret = 0;
1478e2bed107SBastian Koppelmann     for (i = 0; i < 32; i = i + 2) {
1479e2bed107SBastian Koppelmann         /* even */
1480e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (i/2);
1481e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1482e2bed107SBastian Koppelmann         /* odd */
1483e2bed107SBastian Koppelmann         ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1484e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1485e2bed107SBastian Koppelmann     }
1486e2bed107SBastian Koppelmann     return ret;
1487e2bed107SBastian Koppelmann }
1488e2bed107SBastian Koppelmann 
1489e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1)
1490e2bed107SBastian Koppelmann {
1491e2bed107SBastian Koppelmann     uint32_t ret;
1492e2bed107SBastian Koppelmann     uint32_t nOnes, i;
1493e2bed107SBastian Koppelmann 
1494e2bed107SBastian Koppelmann     ret = 0;
1495e2bed107SBastian Koppelmann     nOnes = 0;
1496e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1497e2bed107SBastian Koppelmann         ret ^= (r1 & 1);
1498e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1499e2bed107SBastian Koppelmann     }
1500e2bed107SBastian Koppelmann     /* second byte */
1501e2bed107SBastian Koppelmann     nOnes = 0;
1502e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1503e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1504e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1505e2bed107SBastian Koppelmann     }
1506e2bed107SBastian Koppelmann     ret |= nOnes << 8;
1507e2bed107SBastian Koppelmann     /* third byte */
1508e2bed107SBastian Koppelmann     nOnes = 0;
1509e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1510e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1511e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1512e2bed107SBastian Koppelmann     }
1513e2bed107SBastian Koppelmann     ret |= nOnes << 16;
1514e2bed107SBastian Koppelmann     /* fourth byte */
1515e2bed107SBastian Koppelmann     nOnes = 0;
1516e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1517e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1518e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1519e2bed107SBastian Koppelmann     }
1520e2bed107SBastian Koppelmann     ret |= nOnes << 24;
1521e2bed107SBastian Koppelmann 
1522e2bed107SBastian Koppelmann     return ret;
1523e2bed107SBastian Koppelmann }
1524e2bed107SBastian Koppelmann 
152509532255SBastian Koppelmann uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
152609532255SBastian Koppelmann                      target_ulong r2)
152709532255SBastian Koppelmann {
152809532255SBastian Koppelmann     uint32_t ret;
152909532255SBastian Koppelmann     int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
153009532255SBastian Koppelmann     int32_t int_exp  = r1_high;
153109532255SBastian Koppelmann     int32_t int_mant = r1_low;
153209532255SBastian Koppelmann     uint32_t flag_rnd = (int_mant & (1 << 7)) && (
153309532255SBastian Koppelmann                         (int_mant & (1 << 8)) ||
153409532255SBastian Koppelmann                         (int_mant & 0x7f)     ||
153509532255SBastian Koppelmann                         (carry != 0));
153609532255SBastian Koppelmann     if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
153709532255SBastian Koppelmann         fp_exp = 255;
153809532255SBastian Koppelmann         fp_frac = extract32(int_mant, 8, 23);
153909532255SBastian Koppelmann     } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
154009532255SBastian Koppelmann         fp_exp  = 255;
154109532255SBastian Koppelmann         fp_frac = 0;
154209532255SBastian Koppelmann     } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
154309532255SBastian Koppelmann         fp_exp  = 0;
154409532255SBastian Koppelmann         fp_frac = 0;
154509532255SBastian Koppelmann     } else if (int_mant == 0) {
154609532255SBastian Koppelmann         fp_exp  = 0;
154709532255SBastian Koppelmann         fp_frac = 0;
154809532255SBastian Koppelmann     } else {
154909532255SBastian Koppelmann         if (((int_mant & (1 << 31)) == 0)) {
155009532255SBastian Koppelmann             temp_exp = 0;
155109532255SBastian Koppelmann         } else {
155209532255SBastian Koppelmann             temp_exp = int_exp + 128;
155309532255SBastian Koppelmann         }
155409532255SBastian Koppelmann         fp_exp_frac = (((temp_exp & 0xff) << 23) |
155509532255SBastian Koppelmann                       extract32(int_mant, 8, 23))
155609532255SBastian Koppelmann                       + flag_rnd;
155709532255SBastian Koppelmann         fp_exp  = extract32(fp_exp_frac, 23, 8);
155809532255SBastian Koppelmann         fp_frac = extract32(fp_exp_frac, 0, 23);
155909532255SBastian Koppelmann     }
156009532255SBastian Koppelmann     ret = r2 & (1 << 31);
156109532255SBastian Koppelmann     ret = ret + (fp_exp << 23);
156209532255SBastian Koppelmann     ret = ret + (fp_frac & 0x7fffff);
156309532255SBastian Koppelmann 
156409532255SBastian Koppelmann     return ret;
156509532255SBastian Koppelmann }
156609532255SBastian Koppelmann 
1567e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1)
1568e2bed107SBastian Koppelmann {
1569e2bed107SBastian Koppelmann     int32_t fp_exp  = extract32(arg1, 23, 8);
1570e2bed107SBastian Koppelmann     int32_t fp_frac = extract32(arg1, 0, 23);
1571e2bed107SBastian Koppelmann     uint64_t ret;
1572e2bed107SBastian Koppelmann     int32_t int_exp, int_mant;
1573e2bed107SBastian Koppelmann 
1574e2bed107SBastian Koppelmann     if (fp_exp == 255) {
1575e2bed107SBastian Koppelmann         int_exp = 255;
1576e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1577e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac == 0)) {
1578e2bed107SBastian Koppelmann         int_exp  = -127;
1579e2bed107SBastian Koppelmann         int_mant = 0;
1580e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac != 0)) {
1581e2bed107SBastian Koppelmann         int_exp  = -126;
1582e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1583e2bed107SBastian Koppelmann     } else {
1584e2bed107SBastian Koppelmann         int_exp  = fp_exp - 127;
1585e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1586e2bed107SBastian Koppelmann         int_mant |= (1 << 30);
1587e2bed107SBastian Koppelmann     }
1588e2bed107SBastian Koppelmann     ret = int_exp;
1589e2bed107SBastian Koppelmann     ret = ret << 32;
1590e2bed107SBastian Koppelmann     ret |= int_mant;
1591e2bed107SBastian Koppelmann 
1592e2bed107SBastian Koppelmann     return ret;
1593e2bed107SBastian Koppelmann }
1594e2bed107SBastian Koppelmann 
1595e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1596e2bed107SBastian Koppelmann {
1597e2bed107SBastian Koppelmann     uint64_t ret;
1598e2bed107SBastian Koppelmann     int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1599e2bed107SBastian Koppelmann     int32_t quotient_sign;
1600e2bed107SBastian Koppelmann 
1601e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1602e2bed107SBastian Koppelmann     ret = ret << 24;
1603e2bed107SBastian Koppelmann     quotient_sign = 0;
1604e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1605e2bed107SBastian Koppelmann         ret |= 0xffffff;
1606e2bed107SBastian Koppelmann         quotient_sign = 1;
1607e2bed107SBastian Koppelmann     }
1608e2bed107SBastian Koppelmann 
1609e2bed107SBastian Koppelmann     abs_sig_dividend = abs(r1) >> 7;
1610e2bed107SBastian Koppelmann     abs_base_dividend = abs(r1) & 0x7f;
1611e2bed107SBastian Koppelmann     abs_divisor = abs(r1);
1612e2bed107SBastian Koppelmann     /* calc overflow */
1613e2bed107SBastian Koppelmann     env->PSW_USB_V = 0;
1614e2bed107SBastian Koppelmann     if ((quotient_sign) && (abs_divisor)) {
1615e2bed107SBastian Koppelmann         env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1616e2bed107SBastian Koppelmann                          (abs_base_dividend >= abs_divisor)) ||
1617e2bed107SBastian Koppelmann                          (abs_sig_dividend > abs_divisor));
1618e2bed107SBastian Koppelmann     } else {
1619e2bed107SBastian Koppelmann         env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1620e2bed107SBastian Koppelmann     }
1621e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1622e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1623e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1624e2bed107SBastian Koppelmann 
1625e2bed107SBastian Koppelmann     return ret;
1626e2bed107SBastian Koppelmann }
1627e2bed107SBastian Koppelmann 
1628e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1629e2bed107SBastian Koppelmann {
1630e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
1631e2bed107SBastian Koppelmann 
1632e2bed107SBastian Koppelmann     ret = ret << 24;
1633e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1634e2bed107SBastian Koppelmann         ret |= 0xffffff;
1635e2bed107SBastian Koppelmann     }
1636e2bed107SBastian Koppelmann     /* calc overflow */
1637e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
1638e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1639e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1640e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1641e2bed107SBastian Koppelmann 
1642e2bed107SBastian Koppelmann     return ret;
1643e2bed107SBastian Koppelmann }
1644e2bed107SBastian Koppelmann 
1645e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1646e2bed107SBastian Koppelmann {
1647e2bed107SBastian Koppelmann     uint64_t ret;
1648e2bed107SBastian Koppelmann     int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1649e2bed107SBastian Koppelmann     int32_t quotient_sign;
1650e2bed107SBastian Koppelmann 
1651e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1652e2bed107SBastian Koppelmann     ret = ret << 16;
1653e2bed107SBastian Koppelmann     quotient_sign = 0;
1654e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1655e2bed107SBastian Koppelmann         ret |= 0xffff;
1656e2bed107SBastian Koppelmann         quotient_sign = 1;
1657e2bed107SBastian Koppelmann     }
1658e2bed107SBastian Koppelmann 
1659e2bed107SBastian Koppelmann     abs_sig_dividend = abs(r1) >> 7;
1660e2bed107SBastian Koppelmann     abs_base_dividend = abs(r1) & 0x7f;
1661e2bed107SBastian Koppelmann     abs_divisor = abs(r1);
1662e2bed107SBastian Koppelmann     /* calc overflow */
1663e2bed107SBastian Koppelmann     env->PSW_USB_V = 0;
1664e2bed107SBastian Koppelmann     if ((quotient_sign) && (abs_divisor)) {
1665e2bed107SBastian Koppelmann         env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1666e2bed107SBastian Koppelmann                          (abs_base_dividend >= abs_divisor)) ||
1667e2bed107SBastian Koppelmann                          (abs_sig_dividend > abs_divisor));
1668e2bed107SBastian Koppelmann     } else {
1669e2bed107SBastian Koppelmann         env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1670e2bed107SBastian Koppelmann     }
1671e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1672e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1673e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1674e2bed107SBastian Koppelmann 
1675e2bed107SBastian Koppelmann     return ret;
1676e2bed107SBastian Koppelmann }
1677e2bed107SBastian Koppelmann 
1678e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1679e2bed107SBastian Koppelmann {
1680e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
1681e2bed107SBastian Koppelmann 
1682e2bed107SBastian Koppelmann     ret = ret << 16;
1683e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1684e2bed107SBastian Koppelmann         ret |= 0xffff;
1685e2bed107SBastian Koppelmann     }
1686e2bed107SBastian Koppelmann     /* calc overflow */
1687e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
1688e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1689e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1690e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1691e2bed107SBastian Koppelmann 
1692e2bed107SBastian Koppelmann     return ret;
1693e2bed107SBastian Koppelmann }
1694e2bed107SBastian Koppelmann 
169509532255SBastian Koppelmann uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
169609532255SBastian Koppelmann {
169709532255SBastian Koppelmann     int32_t x_sign = (r1 >> 63);
169809532255SBastian Koppelmann     int32_t q_sign = x_sign ^ (r2 >> 31);
169909532255SBastian Koppelmann     int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
170009532255SBastian Koppelmann     int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
170109532255SBastian Koppelmann     uint32_t quotient;
170209532255SBastian Koppelmann     uint64_t ret, remainder;
170309532255SBastian Koppelmann 
170409532255SBastian Koppelmann     if ((q_sign & ~eq_neg) | eq_pos) {
170509532255SBastian Koppelmann         quotient = (r1 + 1) & 0xffffffff;
170609532255SBastian Koppelmann     } else {
170709532255SBastian Koppelmann         quotient = r1 & 0xffffffff;
170809532255SBastian Koppelmann     }
170909532255SBastian Koppelmann 
171009532255SBastian Koppelmann     if (eq_pos | eq_neg) {
171109532255SBastian Koppelmann         remainder = 0;
171209532255SBastian Koppelmann     } else {
171309532255SBastian Koppelmann         remainder = (r1 & 0xffffffff00000000ull);
171409532255SBastian Koppelmann     }
171509532255SBastian Koppelmann     ret = remainder|quotient;
171609532255SBastian Koppelmann     return ret;
171709532255SBastian Koppelmann }
171809532255SBastian Koppelmann 
171909532255SBastian Koppelmann uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
172009532255SBastian Koppelmann {
172109532255SBastian Koppelmann     int32_t dividend_sign = extract64(r1, 63, 1);
172209532255SBastian Koppelmann     int32_t divisor_sign = extract32(r2, 31, 1);
172309532255SBastian Koppelmann     int32_t quotient_sign = (dividend_sign != divisor_sign);
172409532255SBastian Koppelmann     int32_t addend, dividend_quotient, remainder;
172509532255SBastian Koppelmann     int32_t i, temp;
172609532255SBastian Koppelmann 
172709532255SBastian Koppelmann     if (quotient_sign) {
172809532255SBastian Koppelmann         addend = r2;
172909532255SBastian Koppelmann     } else {
173009532255SBastian Koppelmann         addend = -r2;
173109532255SBastian Koppelmann     }
173209532255SBastian Koppelmann     dividend_quotient = (int32_t)r1;
173309532255SBastian Koppelmann     remainder = (int32_t)(r1 >> 32);
173409532255SBastian Koppelmann 
173509532255SBastian Koppelmann     for (i = 0; i < 8; i++) {
173609532255SBastian Koppelmann         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
173709532255SBastian Koppelmann         dividend_quotient <<= 1;
173809532255SBastian Koppelmann         temp = remainder + addend;
173909532255SBastian Koppelmann         if ((temp < 0) == dividend_sign) {
174009532255SBastian Koppelmann             remainder = temp;
174109532255SBastian Koppelmann         }
174209532255SBastian Koppelmann         if (((temp < 0) == dividend_sign)) {
174309532255SBastian Koppelmann             dividend_quotient = dividend_quotient | !quotient_sign;
174409532255SBastian Koppelmann         } else {
174509532255SBastian Koppelmann             dividend_quotient = dividend_quotient | quotient_sign;
174609532255SBastian Koppelmann         }
174709532255SBastian Koppelmann     }
174809532255SBastian Koppelmann     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
174909532255SBastian Koppelmann }
175009532255SBastian Koppelmann 
175109532255SBastian Koppelmann uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
175209532255SBastian Koppelmann {
175309532255SBastian Koppelmann     int32_t dividend_quotient = extract64(r1, 0, 32);
175409532255SBastian Koppelmann     int64_t remainder = extract64(r1, 32, 32);
175509532255SBastian Koppelmann     int32_t i;
175609532255SBastian Koppelmann     int64_t temp;
175709532255SBastian Koppelmann     for (i = 0; i < 8; i++) {
175809532255SBastian Koppelmann         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
175909532255SBastian Koppelmann         dividend_quotient <<= 1;
176009532255SBastian Koppelmann         temp = (remainder & 0xffffffff) - r2;
176109532255SBastian Koppelmann         if (temp >= 0) {
176209532255SBastian Koppelmann             remainder = temp;
176309532255SBastian Koppelmann         }
176409532255SBastian Koppelmann         dividend_quotient = dividend_quotient | !(temp < 0);
176509532255SBastian Koppelmann     }
176609532255SBastian Koppelmann     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
176709532255SBastian Koppelmann }
176809532255SBastian Koppelmann 
17699655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
17709655b932SBastian Koppelmann                       uint32_t arg10, uint32_t arg11, uint32_t n)
17719655b932SBastian Koppelmann {
17729655b932SBastian Koppelmann     uint64_t ret;
17739655b932SBastian Koppelmann     uint32_t result0, result1;
17749655b932SBastian Koppelmann 
17759655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
17769655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
17779655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
17789655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
17799655b932SBastian Koppelmann     if (sc1) {
17809655b932SBastian Koppelmann         result1 = 0x7fffffff;
17819655b932SBastian Koppelmann     } else {
17829655b932SBastian Koppelmann         result1 = (((uint32_t)(arg00 * arg10)) << n);
17839655b932SBastian Koppelmann     }
17849655b932SBastian Koppelmann     if (sc0) {
17859655b932SBastian Koppelmann         result0 = 0x7fffffff;
17869655b932SBastian Koppelmann     } else {
17879655b932SBastian Koppelmann         result0 = (((uint32_t)(arg01 * arg11)) << n);
17889655b932SBastian Koppelmann     }
17899655b932SBastian Koppelmann     ret = (((uint64_t)result1 << 32)) | result0;
17909655b932SBastian Koppelmann     return ret;
17919655b932SBastian Koppelmann }
17929655b932SBastian Koppelmann 
17939655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
17949655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
17959655b932SBastian Koppelmann {
17969655b932SBastian Koppelmann     uint64_t ret;
17979655b932SBastian Koppelmann     int64_t result0, result1;
17989655b932SBastian Koppelmann 
17999655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
18009655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
18019655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
18029655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
18039655b932SBastian Koppelmann 
18049655b932SBastian Koppelmann     if (sc1) {
18059655b932SBastian Koppelmann         result1 = 0x7fffffff;
18069655b932SBastian Koppelmann     } else {
18079655b932SBastian Koppelmann         result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
18089655b932SBastian Koppelmann     }
18099655b932SBastian Koppelmann     if (sc0) {
18109655b932SBastian Koppelmann         result0 = 0x7fffffff;
18119655b932SBastian Koppelmann     } else {
18129655b932SBastian Koppelmann         result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
18139655b932SBastian Koppelmann     }
18149655b932SBastian Koppelmann     ret = (result1 + result0);
18159655b932SBastian Koppelmann     ret = ret << 16;
18169655b932SBastian Koppelmann     return ret;
18179655b932SBastian Koppelmann }
18189655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
18199655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
18209655b932SBastian Koppelmann {
18219655b932SBastian Koppelmann     uint32_t result0, result1;
18229655b932SBastian Koppelmann 
18239655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
18249655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
18259655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
18269655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
18279655b932SBastian Koppelmann 
18289655b932SBastian Koppelmann     if (sc1) {
18299655b932SBastian Koppelmann         result1 = 0x7fffffff;
18309655b932SBastian Koppelmann     } else {
18319655b932SBastian Koppelmann         result1 = ((arg00 * arg10) << n) + 0x8000;
18329655b932SBastian Koppelmann     }
18339655b932SBastian Koppelmann     if (sc0) {
18349655b932SBastian Koppelmann         result0 = 0x7fffffff;
18359655b932SBastian Koppelmann     } else {
18369655b932SBastian Koppelmann         result0 = ((arg01 * arg11) << n) + 0x8000;
18379655b932SBastian Koppelmann     }
18389655b932SBastian Koppelmann     return (result1 & 0xffff0000) | (result0 >> 16);
18399655b932SBastian Koppelmann }
18409655b932SBastian Koppelmann 
18419a31922bSBastian Koppelmann /* context save area (CSA) related helpers */
18429a31922bSBastian Koppelmann 
18439a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw)
18449a31922bSBastian Koppelmann {
18459a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
18469a31922bSBastian Koppelmann         return 0;
18479a31922bSBastian Koppelmann     }
18489a31922bSBastian Koppelmann 
18499a31922bSBastian Koppelmann     (*psw)++;
18509a31922bSBastian Koppelmann     /* check for overflow */
18519a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
18529a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
18539a31922bSBastian Koppelmann     int count = *psw & mask;
18549a31922bSBastian Koppelmann     if (count == 0) {
18559a31922bSBastian Koppelmann         (*psw)--;
18569a31922bSBastian Koppelmann         return 1;
18579a31922bSBastian Koppelmann     }
18589a31922bSBastian Koppelmann     return 0;
18599a31922bSBastian Koppelmann }
18609a31922bSBastian Koppelmann 
18619a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw)
18629a31922bSBastian Koppelmann {
18639a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
18649a31922bSBastian Koppelmann         return 0;
18659a31922bSBastian Koppelmann     }
18669a31922bSBastian Koppelmann     /* check for underflow */
18679a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
18689a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
18699a31922bSBastian Koppelmann     int count = *psw & mask;
18709a31922bSBastian Koppelmann     if (count == 0) {
18719a31922bSBastian Koppelmann         return 1;
18729a31922bSBastian Koppelmann     }
18739a31922bSBastian Koppelmann     (*psw)--;
18749a31922bSBastian Koppelmann     return 0;
18759a31922bSBastian Koppelmann }
18769a31922bSBastian Koppelmann 
187744ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw)
187844ea3430SBastian Koppelmann {
187944ea3430SBastian Koppelmann     int cdc = *psw & MASK_PSW_CDC;
188044ea3430SBastian Koppelmann     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
188144ea3430SBastian Koppelmann        7'b1111111, otherwise returns FALSE. */
188244ea3430SBastian Koppelmann     if (cdc == 0x7f) {
188344ea3430SBastian Koppelmann         return true;
188444ea3430SBastian Koppelmann     }
188544ea3430SBastian Koppelmann     /* find CDC.COUNT */
188644ea3430SBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
188744ea3430SBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
188844ea3430SBastian Koppelmann     int count = *psw & mask;
188944ea3430SBastian Koppelmann     return count == 0;
189044ea3430SBastian Koppelmann }
189144ea3430SBastian Koppelmann 
1892030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea)
18939a31922bSBastian Koppelmann {
18949a31922bSBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
18959a31922bSBastian Koppelmann     cpu_stl_data(env, ea+4, env->PSW);
18969a31922bSBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[10]);
18979a31922bSBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[11]);
18989a31922bSBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[8]);
18999a31922bSBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[9]);
19009a31922bSBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[10]);
19019a31922bSBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[11]);
19029a31922bSBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[12]);
19039a31922bSBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[13]);
19049a31922bSBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[14]);
19059a31922bSBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[15]);
19069a31922bSBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[12]);
19079a31922bSBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[13]);
19089a31922bSBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[14]);
19099a31922bSBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[15]);
19109a31922bSBastian Koppelmann }
19119a31922bSBastian Koppelmann 
1912030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea)
19135de93515SBastian Koppelmann {
19145de93515SBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
1915030c58dfSBastian Koppelmann     cpu_stl_data(env, ea+4, env->gpr_a[11]);
19165de93515SBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[2]);
19175de93515SBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[3]);
19185de93515SBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[0]);
19195de93515SBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[1]);
19205de93515SBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[2]);
19215de93515SBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[3]);
19225de93515SBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[4]);
19235de93515SBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[5]);
19245de93515SBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[6]);
19255de93515SBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[7]);
19265de93515SBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[4]);
19275de93515SBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[5]);
19285de93515SBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[6]);
19295de93515SBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[7]);
19305de93515SBastian Koppelmann }
19315de93515SBastian Koppelmann 
19329a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea,
19339a31922bSBastian Koppelmann                                   target_ulong *new_PCXI, target_ulong *new_PSW)
19349a31922bSBastian Koppelmann {
19359a31922bSBastian Koppelmann     *new_PCXI = cpu_ldl_data(env, ea);
19369a31922bSBastian Koppelmann     *new_PSW = cpu_ldl_data(env, ea+4);
19379a31922bSBastian Koppelmann     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
19389a31922bSBastian Koppelmann     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
19399a31922bSBastian Koppelmann     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
19409a31922bSBastian Koppelmann     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
19419a31922bSBastian Koppelmann     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
19429a31922bSBastian Koppelmann     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
19439a31922bSBastian Koppelmann     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
19449a31922bSBastian Koppelmann     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
19459a31922bSBastian Koppelmann     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
19469a31922bSBastian Koppelmann     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
19479a31922bSBastian Koppelmann     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
19489a31922bSBastian Koppelmann     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
19499a31922bSBastian Koppelmann     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
19509a31922bSBastian Koppelmann     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
19519a31922bSBastian Koppelmann }
19529a31922bSBastian Koppelmann 
195359543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea,
195459543d4eSBastian Koppelmann                                   target_ulong *ra, target_ulong *pcxi)
195559543d4eSBastian Koppelmann {
195659543d4eSBastian Koppelmann     *pcxi = cpu_ldl_data(env, ea);
195759543d4eSBastian Koppelmann     *ra = cpu_ldl_data(env, ea+4);
195859543d4eSBastian Koppelmann     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
195959543d4eSBastian Koppelmann     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
196059543d4eSBastian Koppelmann     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
196159543d4eSBastian Koppelmann     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
196259543d4eSBastian Koppelmann     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
196359543d4eSBastian Koppelmann     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
196459543d4eSBastian Koppelmann     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
196559543d4eSBastian Koppelmann     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
196659543d4eSBastian Koppelmann     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
196759543d4eSBastian Koppelmann     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
196859543d4eSBastian Koppelmann     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
196959543d4eSBastian Koppelmann     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
197059543d4eSBastian Koppelmann     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
197159543d4eSBastian Koppelmann     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
197259543d4eSBastian Koppelmann }
197359543d4eSBastian Koppelmann 
19749a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc)
19759a31922bSBastian Koppelmann {
19769a31922bSBastian Koppelmann     target_ulong tmp_FCX;
19779a31922bSBastian Koppelmann     target_ulong ea;
19789a31922bSBastian Koppelmann     target_ulong new_FCX;
19799a31922bSBastian Koppelmann     target_ulong psw;
19809a31922bSBastian Koppelmann 
19819a31922bSBastian Koppelmann     psw = psw_read(env);
19829a31922bSBastian Koppelmann     /* if (FCX == 0) trap(FCU); */
19839a31922bSBastian Koppelmann     if (env->FCX == 0) {
19849a31922bSBastian Koppelmann         /* FCU trap */
19859a31922bSBastian Koppelmann     }
19869a31922bSBastian Koppelmann     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
19879a31922bSBastian Koppelmann     if (psw & MASK_PSW_CDE) {
19889a31922bSBastian Koppelmann         if (cdc_increment(&psw)) {
19899a31922bSBastian Koppelmann             /* CDO trap */
19909a31922bSBastian Koppelmann         }
19919a31922bSBastian Koppelmann     }
19929a31922bSBastian Koppelmann     /* PSW.CDE = 1;*/
19939a31922bSBastian Koppelmann     psw |= MASK_PSW_CDE;
19949a31922bSBastian Koppelmann     /* tmp_FCX = FCX; */
19959a31922bSBastian Koppelmann     tmp_FCX = env->FCX;
19969a31922bSBastian Koppelmann     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
19979a31922bSBastian Koppelmann     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
19989a31922bSBastian Koppelmann          ((env->FCX & MASK_FCX_FCXO) << 6);
1999030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
2000030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
2001030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
20029a31922bSBastian Koppelmann                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
20039a31922bSBastian Koppelmann                            D[15]}; */
2004030c58dfSBastian Koppelmann     save_context_upper(env, ea);
20059a31922bSBastian Koppelmann 
20069a31922bSBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN; */
20079a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
20089a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_CCPN) << 24);
20099a31922bSBastian Koppelmann     /* PCXI.PIE = ICR.IE; */
20109a31922bSBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
20119a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_IE) << 15));
20129a31922bSBastian Koppelmann     /* PCXI.UL = 1; */
20139a31922bSBastian Koppelmann     env->PCXI |= MASK_PCXI_UL;
20149a31922bSBastian Koppelmann 
20159a31922bSBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0]; */
20169a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
20179a31922bSBastian Koppelmann     /* FCX[19: 0] = new_FCX[19: 0]; */
20189a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
20199a31922bSBastian Koppelmann     /* A[11] = next_pc[31: 0]; */
20209a31922bSBastian Koppelmann     env->gpr_a[11] = next_pc;
20219a31922bSBastian Koppelmann 
20229a31922bSBastian Koppelmann     /* if (tmp_FCX == LCX) trap(FCD);*/
20239a31922bSBastian Koppelmann     if (tmp_FCX == env->LCX) {
20249a31922bSBastian Koppelmann         /* FCD trap */
20259a31922bSBastian Koppelmann     }
20269a31922bSBastian Koppelmann     psw_write(env, psw);
20279a31922bSBastian Koppelmann }
20289a31922bSBastian Koppelmann 
20299a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env)
20309a31922bSBastian Koppelmann {
20319a31922bSBastian Koppelmann     target_ulong ea;
20329a31922bSBastian Koppelmann     target_ulong new_PCXI;
20339a31922bSBastian Koppelmann     target_ulong new_PSW, psw;
20349a31922bSBastian Koppelmann 
20359a31922bSBastian Koppelmann     psw = psw_read(env);
20369a31922bSBastian Koppelmann      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
20379a31922bSBastian Koppelmann     if (env->PSW & MASK_PSW_CDE) {
20389a31922bSBastian Koppelmann         if (cdc_decrement(&(env->PSW))) {
20399a31922bSBastian Koppelmann             /* CDU trap */
20409a31922bSBastian Koppelmann         }
20419a31922bSBastian Koppelmann     }
20429a31922bSBastian Koppelmann     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
20439a31922bSBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
20449a31922bSBastian Koppelmann         /* CSU trap */
20459a31922bSBastian Koppelmann     }
20469a31922bSBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
20479a31922bSBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
20489a31922bSBastian Koppelmann         /* CTYP trap */
20499a31922bSBastian Koppelmann     }
20509a31922bSBastian Koppelmann     /* PC = {A11 [31: 1], 1’b0}; */
20519a31922bSBastian Koppelmann     env->PC = env->gpr_a[11] & 0xfffffffe;
20529a31922bSBastian Koppelmann 
20539a31922bSBastian Koppelmann     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
20549a31922bSBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
20559a31922bSBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
20569a31922bSBastian Koppelmann     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2057030c58dfSBastian Koppelmann         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
20589a31922bSBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2059030c58dfSBastian Koppelmann     /* M(EA, word) = FCX; */
2060030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
20619a31922bSBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
20629a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
20639a31922bSBastian Koppelmann     /* PCXI = new_PCXI; */
20649a31922bSBastian Koppelmann     env->PCXI = new_PCXI;
20659a31922bSBastian Koppelmann 
20669a31922bSBastian Koppelmann     if (tricore_feature(env, TRICORE_FEATURE_13)) {
20679a31922bSBastian Koppelmann         /* PSW = new_PSW */
20689a31922bSBastian Koppelmann         psw_write(env, new_PSW);
20699a31922bSBastian Koppelmann     } else {
20709a31922bSBastian Koppelmann         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
20719a31922bSBastian Koppelmann         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
20729a31922bSBastian Koppelmann     }
20739a31922bSBastian Koppelmann }
20749a31922bSBastian Koppelmann 
20755de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9)
20765de93515SBastian Koppelmann {
20775de93515SBastian Koppelmann     target_ulong tmp_FCX;
20785de93515SBastian Koppelmann     target_ulong ea;
20795de93515SBastian Koppelmann     target_ulong new_FCX;
20805de93515SBastian Koppelmann 
20815de93515SBastian Koppelmann     if (env->FCX == 0) {
20825de93515SBastian Koppelmann         /* FCU trap */
20835de93515SBastian Koppelmann     }
20845de93515SBastian Koppelmann 
20855de93515SBastian Koppelmann     tmp_FCX = env->FCX;
20865de93515SBastian Koppelmann     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
20875de93515SBastian Koppelmann 
2088030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
2089030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
2090030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2091030c58dfSBastian Koppelmann                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2092030c58dfSBastian Koppelmann     save_context_lower(env, ea);
2093030c58dfSBastian Koppelmann 
20945de93515SBastian Koppelmann 
20955de93515SBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN */
20965de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
20975de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_CCPN) << 24);
20985de93515SBastian Koppelmann     /* PCXI.PIE  = ICR.IE */
20995de93515SBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
21005de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_IE) << 15));
21015de93515SBastian Koppelmann     /* PCXI.UL = 0 */
21025de93515SBastian Koppelmann     env->PCXI &= ~(MASK_PCXI_UL);
21035de93515SBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0] */
21045de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
21055de93515SBastian Koppelmann     /* FXC[19: 0] = new_FCX[19: 0] */
21065de93515SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
21075de93515SBastian Koppelmann     /* ICR.IE = 1 */
21085de93515SBastian Koppelmann     env->ICR |= MASK_ICR_IE;
21095de93515SBastian Koppelmann 
21105de93515SBastian Koppelmann     env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
21115de93515SBastian Koppelmann 
21125de93515SBastian Koppelmann     if (tmp_FCX == env->LCX) {
21135de93515SBastian Koppelmann         /* FCD trap */
21145de93515SBastian Koppelmann     }
21155de93515SBastian Koppelmann }
21165de93515SBastian Koppelmann 
211744ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env)
211844ea3430SBastian Koppelmann {
211944ea3430SBastian Koppelmann     target_ulong ea;
212044ea3430SBastian Koppelmann     target_ulong new_PCXI;
212144ea3430SBastian Koppelmann     target_ulong new_PSW;
212244ea3430SBastian Koppelmann     /* if (PCXI[19: 0] == 0) then trap(CSU); */
212344ea3430SBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
212444ea3430SBastian Koppelmann         /* raise csu trap */
212544ea3430SBastian Koppelmann     }
212644ea3430SBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
212744ea3430SBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
212844ea3430SBastian Koppelmann         /* raise CTYP trap */
212944ea3430SBastian Koppelmann     }
213044ea3430SBastian Koppelmann     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
213144ea3430SBastian Koppelmann     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
213244ea3430SBastian Koppelmann         /* raise MNG trap */
213344ea3430SBastian Koppelmann     }
213444ea3430SBastian Koppelmann     /* ICR.IE = PCXI.PIE; */
213544ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
213644ea3430SBastian Koppelmann     /* ICR.CCPN = PCXI.PCPN; */
213744ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
213844ea3430SBastian Koppelmann                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
213944ea3430SBastian Koppelmann     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
214044ea3430SBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
214144ea3430SBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
214244ea3430SBastian Koppelmann     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2143030c58dfSBastian Koppelmann       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
214444ea3430SBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2145030c58dfSBastian Koppelmann     /* M(EA, word) = FCX;*/
2146030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
214744ea3430SBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
214844ea3430SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
214944ea3430SBastian Koppelmann     /* PCXI = new_PCXI; */
215044ea3430SBastian Koppelmann     env->PCXI = new_PCXI;
215144ea3430SBastian Koppelmann     /* write psw */
215244ea3430SBastian Koppelmann     psw_write(env, new_PSW);
215344ea3430SBastian Koppelmann }
215444ea3430SBastian Koppelmann 
215559543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
215659543d4eSBastian Koppelmann {
215759543d4eSBastian Koppelmann     uint32_t dummy;
215859543d4eSBastian Koppelmann     /* insn doesn't load PCXI and RA */
215959543d4eSBastian Koppelmann     restore_context_lower(env, ea, &dummy, &dummy);
216059543d4eSBastian Koppelmann }
216159543d4eSBastian Koppelmann 
216259543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea)
216359543d4eSBastian Koppelmann {
216459543d4eSBastian Koppelmann     uint32_t dummy;
216559543d4eSBastian Koppelmann     /* insn doesn't load PCXI and PSW */
216659543d4eSBastian Koppelmann     restore_context_upper(env, ea, &dummy, &dummy);
216759543d4eSBastian Koppelmann }
216859543d4eSBastian Koppelmann 
216959543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
217059543d4eSBastian Koppelmann {
217159543d4eSBastian Koppelmann     save_context_lower(env, ea);
217259543d4eSBastian Koppelmann }
217359543d4eSBastian Koppelmann 
217459543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea)
217559543d4eSBastian Koppelmann {
217659543d4eSBastian Koppelmann     save_context_upper(env, ea);
217759543d4eSBastian Koppelmann }
217859543d4eSBastian Koppelmann 
21792b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
21802b2f7d97SBastian Koppelmann {
21812b2f7d97SBastian Koppelmann     psw_write(env, arg);
21822b2f7d97SBastian Koppelmann }
21832b2f7d97SBastian Koppelmann 
21842b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env)
21852b2f7d97SBastian Koppelmann {
21862b2f7d97SBastian Koppelmann     return psw_read(env);
21872b2f7d97SBastian Koppelmann }
21882b2f7d97SBastian Koppelmann 
21892b2f7d97SBastian Koppelmann 
21902d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
21912d30267eSBastian Koppelmann                                                         uint32_t exception,
21922d30267eSBastian Koppelmann                                                         int error_code,
21932d30267eSBastian Koppelmann                                                         uintptr_t pc)
21942d30267eSBastian Koppelmann {
21952d30267eSBastian Koppelmann     CPUState *cs = CPU(tricore_env_get_cpu(env));
21962d30267eSBastian Koppelmann     cs->exception_index = exception;
21972d30267eSBastian Koppelmann     env->error_code = error_code;
21982d30267eSBastian Koppelmann 
21992d30267eSBastian Koppelmann     if (pc) {
22002d30267eSBastian Koppelmann         /* now we have a real cpu fault */
22012d30267eSBastian Koppelmann         cpu_restore_state(cs, pc);
22022d30267eSBastian Koppelmann     }
22032d30267eSBastian Koppelmann 
22042d30267eSBastian Koppelmann     cpu_loop_exit(cs);
22052d30267eSBastian Koppelmann }
22062d30267eSBastian Koppelmann 
220748e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
220848e06fe0SBastian Koppelmann               uintptr_t retaddr)
220948e06fe0SBastian Koppelmann {
22102d30267eSBastian Koppelmann     int ret;
22112d30267eSBastian Koppelmann     ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
22122d30267eSBastian Koppelmann     if (ret) {
22132d30267eSBastian Koppelmann         TriCoreCPU *cpu = TRICORE_CPU(cs);
22142d30267eSBastian Koppelmann         CPUTriCoreState *env = &cpu->env;
22152d30267eSBastian Koppelmann         do_raise_exception_err(env, cs->exception_index,
22162d30267eSBastian Koppelmann                                env->error_code, retaddr);
221748e06fe0SBastian Koppelmann     }
22182d30267eSBastian Koppelmann }
2219