xref: /qemu/target/tricore/op_helper.c (revision b00aa8ecbc6fd7468178a0dabc7dfd0b7e1b8cd6)
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 
2682e430e1cSBastian Koppelmann 
2690974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
2700974257eSBastian Koppelmann                              target_ulong r2)
2710974257eSBastian Koppelmann {
2720974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
2730974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
2740974257eSBastian Koppelmann     int64_t result = t1 + t2;
27585d604afSBastian Koppelmann     return suov32_pos(env, result);
2760974257eSBastian Koppelmann }
2770974257eSBastian Koppelmann 
278d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
279d5de7839SBastian Koppelmann                                target_ulong r2)
280d5de7839SBastian Koppelmann {
281d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
282d5de7839SBastian Koppelmann 
283d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
284d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
285d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
286d5de7839SBastian Koppelmann }
287d5de7839SBastian Koppelmann 
2882692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
2892692802aSBastian Koppelmann                              target_ulong r2)
2902692802aSBastian Koppelmann {
2912692802aSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
2922692802aSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
2932692802aSBastian Koppelmann     int64_t result = t1 - t2;
294e4e39176SBastian Koppelmann     return ssov32(env, result);
2952692802aSBastian Koppelmann }
2962692802aSBastian Koppelmann 
297d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
298d5de7839SBastian Koppelmann                              target_ulong r2)
299d5de7839SBastian Koppelmann {
300d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
301d5de7839SBastian Koppelmann 
302d5de7839SBastian Koppelmann     ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
303d5de7839SBastian Koppelmann     ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
304d5de7839SBastian Koppelmann     return ssov16(env, ret_hw0, ret_hw1);
305d5de7839SBastian Koppelmann }
306d5de7839SBastian Koppelmann 
3070974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
3080974257eSBastian Koppelmann                              target_ulong r2)
3090974257eSBastian Koppelmann {
3100974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
3110974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
3120974257eSBastian Koppelmann     int64_t result = t1 - t2;
31385d604afSBastian Koppelmann     return suov32_neg(env, result);
3140974257eSBastian Koppelmann }
3150974257eSBastian Koppelmann 
316d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
317d5de7839SBastian Koppelmann                                target_ulong r2)
318d5de7839SBastian Koppelmann {
319d5de7839SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
320d5de7839SBastian Koppelmann 
321d5de7839SBastian Koppelmann     ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
322d5de7839SBastian Koppelmann     ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
323d5de7839SBastian Koppelmann     return suov16(env, ret_hw0, ret_hw1);
324d5de7839SBastian Koppelmann }
325d5de7839SBastian Koppelmann 
3260974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
3270974257eSBastian Koppelmann                              target_ulong r2)
3280974257eSBastian Koppelmann {
3290974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3300974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
3310974257eSBastian Koppelmann     int64_t result = t1 * t2;
332e4e39176SBastian Koppelmann     return ssov32(env, result);
3330974257eSBastian Koppelmann }
3340974257eSBastian Koppelmann 
3350974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
3360974257eSBastian Koppelmann                              target_ulong r2)
3370974257eSBastian Koppelmann {
3380974257eSBastian Koppelmann     int64_t t1 = extract64(r1, 0, 32);
3390974257eSBastian Koppelmann     int64_t t2 = extract64(r2, 0, 32);
3400974257eSBastian Koppelmann     int64_t result = t1 * t2;
3415f30046fSBastian Koppelmann 
34285d604afSBastian Koppelmann     return suov32_pos(env, result);
3430974257eSBastian Koppelmann }
3440974257eSBastian Koppelmann 
3450974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
3460974257eSBastian Koppelmann                              target_ulong r2)
3470974257eSBastian Koppelmann {
3480974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3490974257eSBastian Koppelmann     int32_t t2 = sextract64(r2, 0, 6);
3500974257eSBastian Koppelmann     int64_t result;
3510974257eSBastian Koppelmann     if (t2 == 0) {
3520974257eSBastian Koppelmann         result = t1;
3530974257eSBastian Koppelmann     } else if (t2 > 0) {
3540974257eSBastian Koppelmann         result = t1 << t2;
3550974257eSBastian Koppelmann     } else {
3560974257eSBastian Koppelmann         result = t1 >> -t2;
3570974257eSBastian Koppelmann     }
358e4e39176SBastian Koppelmann     return ssov32(env, result);
3590974257eSBastian Koppelmann }
3600974257eSBastian Koppelmann 
361d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
362d5de7839SBastian Koppelmann {
363d5de7839SBastian Koppelmann     target_ulong result;
364d5de7839SBastian Koppelmann     result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
365d5de7839SBastian Koppelmann     return ssov32(env, result);
366d5de7839SBastian Koppelmann }
367d5de7839SBastian Koppelmann 
368d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
369d5de7839SBastian Koppelmann {
370d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
371d5de7839SBastian Koppelmann 
372d5de7839SBastian Koppelmann     ret_h0 = sextract32(r1, 0, 16);
373d5de7839SBastian Koppelmann     ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
374d5de7839SBastian Koppelmann 
375d5de7839SBastian Koppelmann     ret_h1 = sextract32(r1, 16, 16);
376d5de7839SBastian Koppelmann     ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
377d5de7839SBastian Koppelmann 
378d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
379d5de7839SBastian Koppelmann }
380d5de7839SBastian Koppelmann 
3810974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
3820974257eSBastian Koppelmann                                 target_ulong r2)
3830974257eSBastian Koppelmann {
3840974257eSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
3850974257eSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
3860974257eSBastian Koppelmann     int64_t result;
3870974257eSBastian Koppelmann 
3880974257eSBastian Koppelmann     if (t1 > t2) {
3890974257eSBastian Koppelmann         result = t1 - t2;
3900974257eSBastian Koppelmann     } else {
3910974257eSBastian Koppelmann         result = t2 - t1;
3920974257eSBastian Koppelmann     }
393e4e39176SBastian Koppelmann     return ssov32(env, result);
3940974257eSBastian Koppelmann }
395328f1f0fSBastian Koppelmann 
396d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
397d5de7839SBastian Koppelmann                               target_ulong r2)
398d5de7839SBastian Koppelmann {
399d5de7839SBastian Koppelmann     int32_t t1, t2;
400d5de7839SBastian Koppelmann     int32_t ret_h0, ret_h1;
401d5de7839SBastian Koppelmann 
402d5de7839SBastian Koppelmann     t1 = sextract32(r1, 0, 16);
403d5de7839SBastian Koppelmann     t2 = sextract32(r2, 0, 16);
404d5de7839SBastian Koppelmann     if (t1 > t2) {
405d5de7839SBastian Koppelmann         ret_h0 = t1 - t2;
406d5de7839SBastian Koppelmann     } else {
407d5de7839SBastian Koppelmann         ret_h0 = t2 - t1;
408d5de7839SBastian Koppelmann     }
409d5de7839SBastian Koppelmann 
410d5de7839SBastian Koppelmann     t1 = sextract32(r1, 16, 16);
411d5de7839SBastian Koppelmann     t2 = sextract32(r2, 16, 16);
412d5de7839SBastian Koppelmann     if (t1 > t2) {
413d5de7839SBastian Koppelmann         ret_h1 = t1 - t2;
414d5de7839SBastian Koppelmann     } else {
415d5de7839SBastian Koppelmann         ret_h1 = t2 - t1;
416d5de7839SBastian Koppelmann     }
417d5de7839SBastian Koppelmann 
418d5de7839SBastian Koppelmann     return ssov16(env, ret_h0, ret_h1);
419d5de7839SBastian Koppelmann }
420d5de7839SBastian Koppelmann 
421328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
422328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
423328f1f0fSBastian Koppelmann {
424328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
425328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
426328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
427328f1f0fSBastian Koppelmann     int64_t result;
428328f1f0fSBastian Koppelmann 
429328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
430e4e39176SBastian Koppelmann     return ssov32(env, result);
431328f1f0fSBastian Koppelmann }
432328f1f0fSBastian Koppelmann 
433328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
434328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
435328f1f0fSBastian Koppelmann {
436328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
437328f1f0fSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
438328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
439328f1f0fSBastian Koppelmann     int64_t result;
440328f1f0fSBastian Koppelmann 
441328f1f0fSBastian Koppelmann     result = t2 + (t1 * t3);
44285d604afSBastian Koppelmann     return suov32_pos(env, result);
443328f1f0fSBastian Koppelmann }
444328f1f0fSBastian Koppelmann 
445328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
446328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
447328f1f0fSBastian Koppelmann {
448328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
449328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
450328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
451328f1f0fSBastian Koppelmann     int64_t mul;
452328f1f0fSBastian Koppelmann 
453328f1f0fSBastian Koppelmann     mul = t1 * t3;
454328f1f0fSBastian Koppelmann     ret = mul + r2;
455328f1f0fSBastian Koppelmann     ovf = (ret ^ mul) & ~(mul ^ r2);
456328f1f0fSBastian Koppelmann 
457811ea608SBastian Koppelmann     t1 = ret >> 32;
458811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
459811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
460811ea608SBastian Koppelmann 
461328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
462328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
463328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
464328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
465328f1f0fSBastian Koppelmann         if (mul >= 0) {
466328f1f0fSBastian Koppelmann             ret = INT64_MAX;
467328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
468328f1f0fSBastian Koppelmann         } else {
469328f1f0fSBastian Koppelmann             ret = INT64_MIN;
470328f1f0fSBastian Koppelmann         }
471328f1f0fSBastian Koppelmann     } else {
472328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
473328f1f0fSBastian Koppelmann     }
474328f1f0fSBastian Koppelmann 
475328f1f0fSBastian Koppelmann     return ret;
476328f1f0fSBastian Koppelmann }
477328f1f0fSBastian Koppelmann 
478b00aa8ecSBastian Koppelmann uint32_t
479b00aa8ecSBastian Koppelmann helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
480b00aa8ecSBastian Koppelmann {
481b00aa8ecSBastian Koppelmann     int64_t result;
482b00aa8ecSBastian Koppelmann 
483b00aa8ecSBastian Koppelmann     result = (r1 + r2);
484b00aa8ecSBastian Koppelmann 
485b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u);
486b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
487b00aa8ecSBastian Koppelmann 
488b00aa8ecSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
489b00aa8ecSBastian Koppelmann        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
490b00aa8ecSBastian Koppelmann        case, we flip the saturated value. */
491b00aa8ecSBastian Koppelmann     if (r2 == 0x8000000000000000LL) {
492b00aa8ecSBastian Koppelmann         if (result > 0x7fffffffLL) {
493b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
494b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
495b00aa8ecSBastian Koppelmann             result = INT32_MIN;
496b00aa8ecSBastian Koppelmann         } else if (result < -0x80000000LL) {
497b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
498b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
499b00aa8ecSBastian Koppelmann             result = INT32_MAX;
500b00aa8ecSBastian Koppelmann         } else {
501b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
502b00aa8ecSBastian Koppelmann         }
503b00aa8ecSBastian Koppelmann     } else {
504b00aa8ecSBastian Koppelmann         if (result > 0x7fffffffLL) {
505b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
506b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
507b00aa8ecSBastian Koppelmann             result = INT32_MAX;
508b00aa8ecSBastian Koppelmann         } else if (result < -0x80000000LL) {
509b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
510b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
511b00aa8ecSBastian Koppelmann             result = INT32_MIN;
512b00aa8ecSBastian Koppelmann         } else {
513b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
514b00aa8ecSBastian Koppelmann         }
515b00aa8ecSBastian Koppelmann     }
516b00aa8ecSBastian Koppelmann     return (uint32_t)result;
517b00aa8ecSBastian Koppelmann }
518b00aa8ecSBastian Koppelmann 
519b00aa8ecSBastian Koppelmann uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
520b00aa8ecSBastian Koppelmann                               uint32_t r3, uint32_t n)
521b00aa8ecSBastian Koppelmann {
522b00aa8ecSBastian Koppelmann     int64_t t1 = (int64_t)r1;
523b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
524b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
525b00aa8ecSBastian Koppelmann     int64_t result, mul;
526b00aa8ecSBastian Koppelmann     int64_t ovf;
527b00aa8ecSBastian Koppelmann 
528b00aa8ecSBastian Koppelmann     mul = (t2 * t3) << n;
529b00aa8ecSBastian Koppelmann     result = mul + t1;
530b00aa8ecSBastian Koppelmann 
531b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
532b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
533b00aa8ecSBastian Koppelmann 
534b00aa8ecSBastian Koppelmann     ovf = (result ^ mul) & ~(mul ^ t1);
535b00aa8ecSBastian Koppelmann     /* we do the saturation by hand, since we produce an overflow on the host
536b00aa8ecSBastian Koppelmann        if the mul was (0x80000000 * 0x80000000) << 1). If this is the
537b00aa8ecSBastian Koppelmann        case, we flip the saturated value. */
538b00aa8ecSBastian Koppelmann     if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) {
539b00aa8ecSBastian Koppelmann         if (ovf >= 0) {
540b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
541b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
542b00aa8ecSBastian Koppelmann             /* ext_ret > MAX_INT */
543b00aa8ecSBastian Koppelmann             if (mul < 0) {
544b00aa8ecSBastian Koppelmann                 result = INT64_MAX;
545b00aa8ecSBastian Koppelmann             /* ext_ret < MIN_INT */
546b00aa8ecSBastian Koppelmann             } else {
547b00aa8ecSBastian Koppelmann                result = INT64_MIN;
548b00aa8ecSBastian Koppelmann             }
549b00aa8ecSBastian Koppelmann         } else {
550b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
551b00aa8ecSBastian Koppelmann         }
552b00aa8ecSBastian Koppelmann     } else {
553b00aa8ecSBastian Koppelmann         if (ovf < 0) {
554b00aa8ecSBastian Koppelmann             env->PSW_USB_V = (1 << 31);
555b00aa8ecSBastian Koppelmann             env->PSW_USB_SV = (1 << 31);
556b00aa8ecSBastian Koppelmann             /* ext_ret > MAX_INT */
557b00aa8ecSBastian Koppelmann             if (mul >= 0) {
558b00aa8ecSBastian Koppelmann                 result = INT64_MAX;
559b00aa8ecSBastian Koppelmann             /* ext_ret < MIN_INT */
560b00aa8ecSBastian Koppelmann             } else {
561b00aa8ecSBastian Koppelmann                result = INT64_MIN;
562b00aa8ecSBastian Koppelmann             }
563b00aa8ecSBastian Koppelmann         } else {
564b00aa8ecSBastian Koppelmann             env->PSW_USB_V = 0;
565b00aa8ecSBastian Koppelmann         }
566b00aa8ecSBastian Koppelmann     }
567b00aa8ecSBastian Koppelmann     return (uint64_t)result;
568b00aa8ecSBastian Koppelmann }
569b00aa8ecSBastian Koppelmann 
570b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
571b00aa8ecSBastian Koppelmann                              uint32_t r3, uint32_t n)
572b00aa8ecSBastian Koppelmann {
573b00aa8ecSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
574b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
575b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
576b00aa8ecSBastian Koppelmann     int64_t mul, ret;
577b00aa8ecSBastian Koppelmann 
578b00aa8ecSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
579b00aa8ecSBastian Koppelmann         mul = 0x7fffffff;
580b00aa8ecSBastian Koppelmann     } else {
581b00aa8ecSBastian Koppelmann         mul = (t2 * t3) << n;
582b00aa8ecSBastian Koppelmann     }
583b00aa8ecSBastian Koppelmann 
584b00aa8ecSBastian Koppelmann     ret = t1 + mul + 0x8000;
585b00aa8ecSBastian Koppelmann 
586b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
587b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
588b00aa8ecSBastian Koppelmann 
589b00aa8ecSBastian Koppelmann     if (ret > 0x7fffffffll) {
590b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
591b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
592b00aa8ecSBastian Koppelmann         ret = INT32_MAX;
593b00aa8ecSBastian Koppelmann     } else if (ret < -0x80000000ll) {
594b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
595b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
596b00aa8ecSBastian Koppelmann         ret = INT32_MIN;
597b00aa8ecSBastian Koppelmann     } else {
598b00aa8ecSBastian Koppelmann         env->PSW_USB_V = 0;
599b00aa8ecSBastian Koppelmann     }
600b00aa8ecSBastian Koppelmann     return ret & 0xffff0000ll;
601b00aa8ecSBastian Koppelmann }
602b00aa8ecSBastian Koppelmann 
603328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
604328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
605328f1f0fSBastian Koppelmann {
606328f1f0fSBastian Koppelmann     uint64_t ret, mul;
607328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
608328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
609328f1f0fSBastian Koppelmann 
610328f1f0fSBastian Koppelmann     mul = t1 * t3;
611328f1f0fSBastian Koppelmann     ret = mul + r2;
612328f1f0fSBastian Koppelmann 
613811ea608SBastian Koppelmann     t1 = ret >> 32;
614811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
615811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
616811ea608SBastian Koppelmann 
617328f1f0fSBastian Koppelmann     if (ret < r2) {
618328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
619328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
620328f1f0fSBastian Koppelmann         /* saturate */
621328f1f0fSBastian Koppelmann         ret = UINT64_MAX;
622328f1f0fSBastian Koppelmann     } else {
623328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
624328f1f0fSBastian Koppelmann     }
625328f1f0fSBastian Koppelmann     return ret;
626328f1f0fSBastian Koppelmann }
627328f1f0fSBastian Koppelmann 
628328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
629328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
630328f1f0fSBastian Koppelmann {
631328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
632328f1f0fSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
633328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
634328f1f0fSBastian Koppelmann     int64_t result;
635328f1f0fSBastian Koppelmann 
636328f1f0fSBastian Koppelmann     result = t2 - (t1 * t3);
637e4e39176SBastian Koppelmann     return ssov32(env, result);
638328f1f0fSBastian Koppelmann }
639328f1f0fSBastian Koppelmann 
640328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
641328f1f0fSBastian Koppelmann                                 target_ulong r2, target_ulong r3)
642328f1f0fSBastian Koppelmann {
6433debbb5aSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
6443debbb5aSBastian Koppelmann     uint64_t t2 = extract64(r2, 0, 32);
6453debbb5aSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
6463debbb5aSBastian Koppelmann     uint64_t result;
6473debbb5aSBastian Koppelmann     uint64_t mul;
648328f1f0fSBastian Koppelmann 
6493debbb5aSBastian Koppelmann     mul = (t1 * t3);
6503debbb5aSBastian Koppelmann     result = t2 - mul;
6513debbb5aSBastian Koppelmann 
6523debbb5aSBastian Koppelmann     env->PSW_USB_AV = result ^ result * 2u;
6533debbb5aSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
6543debbb5aSBastian Koppelmann     /* we calculate ovf by hand here, because the multiplication can overflow on
6553debbb5aSBastian Koppelmann        the host, which would give false results if we compare to less than
6563debbb5aSBastian Koppelmann        zero */
6573debbb5aSBastian Koppelmann     if (mul > t2) {
6583debbb5aSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
6593debbb5aSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
6603debbb5aSBastian Koppelmann         result = 0;
6613debbb5aSBastian Koppelmann     } else {
6623debbb5aSBastian Koppelmann         env->PSW_USB_V = 0;
6633debbb5aSBastian Koppelmann     }
6643debbb5aSBastian Koppelmann     return result;
665328f1f0fSBastian Koppelmann }
666328f1f0fSBastian Koppelmann 
667328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
668328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
669328f1f0fSBastian Koppelmann {
670328f1f0fSBastian Koppelmann     uint64_t ret, ovf;
671328f1f0fSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
672328f1f0fSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
673328f1f0fSBastian Koppelmann     int64_t mul;
674328f1f0fSBastian Koppelmann 
675328f1f0fSBastian Koppelmann     mul = t1 * t3;
676328f1f0fSBastian Koppelmann     ret = r2 - mul;
677328f1f0fSBastian Koppelmann     ovf = (ret ^ r2) & (mul ^ r2);
678328f1f0fSBastian Koppelmann 
679811ea608SBastian Koppelmann     t1 = ret >> 32;
680811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
681811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
682811ea608SBastian Koppelmann 
683328f1f0fSBastian Koppelmann     if ((int64_t)ovf < 0) {
684328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
685328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
686328f1f0fSBastian Koppelmann         /* ext_ret > MAX_INT */
687328f1f0fSBastian Koppelmann         if (mul < 0) {
688328f1f0fSBastian Koppelmann             ret = INT64_MAX;
689328f1f0fSBastian Koppelmann         /* ext_ret < MIN_INT */
690328f1f0fSBastian Koppelmann         } else {
691328f1f0fSBastian Koppelmann             ret = INT64_MIN;
692328f1f0fSBastian Koppelmann         }
693328f1f0fSBastian Koppelmann     } else {
694328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
695328f1f0fSBastian Koppelmann     }
696328f1f0fSBastian Koppelmann     return ret;
697328f1f0fSBastian Koppelmann }
698328f1f0fSBastian Koppelmann 
699328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
700328f1f0fSBastian Koppelmann                             uint64_t r2, target_ulong r3)
701328f1f0fSBastian Koppelmann {
702328f1f0fSBastian Koppelmann     uint64_t ret, mul;
703328f1f0fSBastian Koppelmann     uint64_t t1 = extract64(r1, 0, 32);
704328f1f0fSBastian Koppelmann     uint64_t t3 = extract64(r3, 0, 32);
705328f1f0fSBastian Koppelmann 
706328f1f0fSBastian Koppelmann     mul = t1 * t3;
707328f1f0fSBastian Koppelmann     ret = r2 - mul;
708328f1f0fSBastian Koppelmann 
709811ea608SBastian Koppelmann     t1 = ret >> 32;
710811ea608SBastian Koppelmann     env->PSW_USB_AV = t1 ^ t1 * 2u;
711811ea608SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
712811ea608SBastian Koppelmann 
713328f1f0fSBastian Koppelmann     if (ret > r2) {
714328f1f0fSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
715328f1f0fSBastian Koppelmann         env->PSW_USB_SV = (1 << 31);
716328f1f0fSBastian Koppelmann         /* saturate */
717328f1f0fSBastian Koppelmann         ret = 0;
718328f1f0fSBastian Koppelmann     } else {
719328f1f0fSBastian Koppelmann         env->PSW_USB_V = 0;
720328f1f0fSBastian Koppelmann     }
721328f1f0fSBastian Koppelmann     return ret;
722328f1f0fSBastian Koppelmann }
723328f1f0fSBastian Koppelmann 
724d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
725d5de7839SBastian Koppelmann {
726d5de7839SBastian Koppelmann     int32_t b, i;
727d5de7839SBastian Koppelmann     int32_t ovf = 0;
728d5de7839SBastian Koppelmann     int32_t avf = 0;
729d5de7839SBastian Koppelmann     int32_t ret = 0;
730d5de7839SBastian Koppelmann 
731d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
732d5de7839SBastian Koppelmann         b = sextract32(arg, i * 8, 8);
733d5de7839SBastian Koppelmann         b = (b >= 0) ? b : (0 - b);
734d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
735d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
736d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
737d5de7839SBastian Koppelmann     }
738d5de7839SBastian Koppelmann 
739d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
740d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
741d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
742d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
743d5de7839SBastian Koppelmann 
744d5de7839SBastian Koppelmann     return ret;
745d5de7839SBastian Koppelmann }
746d5de7839SBastian Koppelmann 
747d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
748d5de7839SBastian Koppelmann {
749d5de7839SBastian Koppelmann     int32_t h, i;
750d5de7839SBastian Koppelmann     int32_t ovf = 0;
751d5de7839SBastian Koppelmann     int32_t avf = 0;
752d5de7839SBastian Koppelmann     int32_t ret = 0;
753d5de7839SBastian Koppelmann 
754d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
755d5de7839SBastian Koppelmann         h = sextract32(arg, i * 16, 16);
756d5de7839SBastian Koppelmann         h = (h >= 0) ? h : (0 - h);
757d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
758d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
759d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
760d5de7839SBastian Koppelmann     }
761d5de7839SBastian Koppelmann 
762d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
763d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
764d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
765d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
766d5de7839SBastian Koppelmann 
767d5de7839SBastian Koppelmann     return ret;
768d5de7839SBastian Koppelmann }
769d5de7839SBastian Koppelmann 
770d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
771d5de7839SBastian Koppelmann {
772d5de7839SBastian Koppelmann     int32_t b, i;
773d5de7839SBastian Koppelmann     int32_t extr_r2;
774d5de7839SBastian Koppelmann     int32_t ovf = 0;
775d5de7839SBastian Koppelmann     int32_t avf = 0;
776d5de7839SBastian Koppelmann     int32_t ret = 0;
777d5de7839SBastian Koppelmann 
778d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
779d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
780d5de7839SBastian Koppelmann         b = sextract32(r1, i * 8, 8);
781d5de7839SBastian Koppelmann         b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
782d5de7839SBastian Koppelmann         ovf |= (b > 0x7F) || (b < -0x80);
783d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
784d5de7839SBastian Koppelmann         ret |= (b & 0xff) << (i * 8);
785d5de7839SBastian Koppelmann     }
786d5de7839SBastian Koppelmann 
787d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
788d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
789d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
790d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
791d5de7839SBastian Koppelmann     return ret;
792d5de7839SBastian Koppelmann }
793d5de7839SBastian Koppelmann 
794d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
795d5de7839SBastian Koppelmann {
796d5de7839SBastian Koppelmann     int32_t h, i;
797d5de7839SBastian Koppelmann     int32_t extr_r2;
798d5de7839SBastian Koppelmann     int32_t ovf = 0;
799d5de7839SBastian Koppelmann     int32_t avf = 0;
800d5de7839SBastian Koppelmann     int32_t ret = 0;
801d5de7839SBastian Koppelmann 
802d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
803d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
804d5de7839SBastian Koppelmann         h = sextract32(r1, i * 16, 16);
805d5de7839SBastian Koppelmann         h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
806d5de7839SBastian Koppelmann         ovf |= (h > 0x7FFF) || (h < -0x8000);
807d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
808d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
809d5de7839SBastian Koppelmann     }
810d5de7839SBastian Koppelmann 
811d5de7839SBastian Koppelmann     env->PSW_USB_V = ovf << 31;
812d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
813d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
814d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
815d5de7839SBastian Koppelmann 
816d5de7839SBastian Koppelmann     return ret;
817d5de7839SBastian Koppelmann }
818d5de7839SBastian Koppelmann 
8192e430e1cSBastian Koppelmann uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
8202e430e1cSBastian Koppelmann                        uint32_t r2_h)
8212e430e1cSBastian Koppelmann {
8222e430e1cSBastian Koppelmann     int64_t mul_res0 = sextract64(r1, 0, 32);
8232e430e1cSBastian Koppelmann     int64_t mul_res1 = sextract64(r1, 32, 32);
8242e430e1cSBastian Koppelmann     int64_t r2_low = sextract64(r2_l, 0, 32);
8252e430e1cSBastian Koppelmann     int64_t r2_high = sextract64(r2_h, 0, 32);
8262e430e1cSBastian Koppelmann     int64_t result0, result1;
8272e430e1cSBastian Koppelmann     uint32_t ovf0, ovf1;
8282e430e1cSBastian Koppelmann     uint32_t avf0, avf1;
8292e430e1cSBastian Koppelmann 
8302e430e1cSBastian Koppelmann     ovf0 = ovf1 = 0;
8312e430e1cSBastian Koppelmann 
8322e430e1cSBastian Koppelmann     result0 = r2_low + mul_res0 + 0x8000;
8332e430e1cSBastian Koppelmann     result1 = r2_high + mul_res1 + 0x8000;
8342e430e1cSBastian Koppelmann 
8352e430e1cSBastian Koppelmann     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
8362e430e1cSBastian Koppelmann         ovf0 = (1 << 31);
8372e430e1cSBastian Koppelmann     }
8382e430e1cSBastian Koppelmann 
8392e430e1cSBastian Koppelmann     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
8402e430e1cSBastian Koppelmann         ovf1 = (1 << 31);
8412e430e1cSBastian Koppelmann     }
8422e430e1cSBastian Koppelmann 
8432e430e1cSBastian Koppelmann     env->PSW_USB_V = ovf0 | ovf1;
8442e430e1cSBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
8452e430e1cSBastian Koppelmann 
8462e430e1cSBastian Koppelmann     avf0 = result0 * 2u;
8472e430e1cSBastian Koppelmann     avf0 = result0 ^ avf0;
8482e430e1cSBastian Koppelmann     avf1 = result1 * 2u;
8492e430e1cSBastian Koppelmann     avf1 = result1 ^ avf1;
8502e430e1cSBastian Koppelmann 
8512e430e1cSBastian Koppelmann     env->PSW_USB_AV = avf0 | avf1;
8522e430e1cSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
8532e430e1cSBastian Koppelmann 
8542e430e1cSBastian Koppelmann     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
8552e430e1cSBastian Koppelmann }
8562e430e1cSBastian Koppelmann 
857b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
858b00aa8ecSBastian Koppelmann                         uint32_t r3, uint32_t n)
859b00aa8ecSBastian Koppelmann {
860b00aa8ecSBastian Koppelmann     int64_t t1 = sextract64(r1, 0, 32);
861b00aa8ecSBastian Koppelmann     int64_t t2 = sextract64(r2, 0, 32);
862b00aa8ecSBastian Koppelmann     int64_t t3 = sextract64(r3, 0, 32);
863b00aa8ecSBastian Koppelmann     int64_t mul, ret;
864b00aa8ecSBastian Koppelmann 
865b00aa8ecSBastian Koppelmann     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
866b00aa8ecSBastian Koppelmann         mul = 0x7fffffff;
867b00aa8ecSBastian Koppelmann     } else {
868b00aa8ecSBastian Koppelmann         mul = (t2 * t3) << n;
869b00aa8ecSBastian Koppelmann     }
870b00aa8ecSBastian Koppelmann 
871b00aa8ecSBastian Koppelmann     ret = t1 + mul + 0x8000;
872b00aa8ecSBastian Koppelmann 
873b00aa8ecSBastian Koppelmann     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
874b00aa8ecSBastian Koppelmann         env->PSW_USB_V = (1 << 31);
875b00aa8ecSBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
876b00aa8ecSBastian Koppelmann     } else {
877b00aa8ecSBastian Koppelmann         env->PSW_USB_V = 0;
878b00aa8ecSBastian Koppelmann     }
879b00aa8ecSBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
880b00aa8ecSBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
881b00aa8ecSBastian Koppelmann 
882b00aa8ecSBastian Koppelmann     return ret & 0xffff0000ll;
883b00aa8ecSBastian Koppelmann }
884b00aa8ecSBastian Koppelmann 
885d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
886d5de7839SBastian Koppelmann {
887d5de7839SBastian Koppelmann     int32_t b, i;
888d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
889d5de7839SBastian Koppelmann     int32_t ovf = 0;
890d5de7839SBastian Koppelmann     int32_t avf = 0;
891d5de7839SBastian Koppelmann     uint32_t ret = 0;
892d5de7839SBastian Koppelmann 
893d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
894d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
895d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
896d5de7839SBastian Koppelmann 
897d5de7839SBastian Koppelmann         b = extr_r1 + extr_r2;
898d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
899d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
900d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
901d5de7839SBastian Koppelmann     }
902d5de7839SBastian Koppelmann 
903d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
904d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
905d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
906d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
907d5de7839SBastian Koppelmann 
908d5de7839SBastian Koppelmann     return ret;
909d5de7839SBastian Koppelmann }
910d5de7839SBastian Koppelmann 
911d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
912d5de7839SBastian Koppelmann {
913d5de7839SBastian Koppelmann     int32_t h, i;
914d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
915d5de7839SBastian Koppelmann     int32_t ovf = 0;
916d5de7839SBastian Koppelmann     int32_t avf = 0;
917d5de7839SBastian Koppelmann     int32_t ret = 0;
918d5de7839SBastian Koppelmann 
919d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
920d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
921d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
922d5de7839SBastian Koppelmann         h = extr_r1 + extr_r2;
923d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
924d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
925d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
926d5de7839SBastian Koppelmann     }
927d5de7839SBastian Koppelmann 
928d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
929d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
930d5de7839SBastian Koppelmann     env->PSW_USB_AV = (avf << 16);
931d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
932d5de7839SBastian Koppelmann 
933d5de7839SBastian Koppelmann     return ret;
934d5de7839SBastian Koppelmann }
935d5de7839SBastian Koppelmann 
936d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
937d5de7839SBastian Koppelmann {
938d5de7839SBastian Koppelmann     int32_t b, i;
939d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
940d5de7839SBastian Koppelmann     int32_t ovf = 0;
941d5de7839SBastian Koppelmann     int32_t avf = 0;
942d5de7839SBastian Koppelmann     uint32_t ret = 0;
943d5de7839SBastian Koppelmann 
944d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
945d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);
946d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);
947d5de7839SBastian Koppelmann 
948d5de7839SBastian Koppelmann         b = extr_r1 - extr_r2;
949d5de7839SBastian Koppelmann         ovf |= ((b > 0x7f) || (b < -0x80));
950d5de7839SBastian Koppelmann         avf |= b ^ b * 2u;
951d5de7839SBastian Koppelmann         ret |= ((b & 0xff) << (i*8));
952d5de7839SBastian Koppelmann     }
953d5de7839SBastian Koppelmann 
954d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
955d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
956d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 24;
957d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
958d5de7839SBastian Koppelmann 
959d5de7839SBastian Koppelmann     return ret;
960d5de7839SBastian Koppelmann }
961d5de7839SBastian Koppelmann 
962d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
963d5de7839SBastian Koppelmann {
964d5de7839SBastian Koppelmann     int32_t h, i;
965d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;
966d5de7839SBastian Koppelmann     int32_t ovf = 0;
967d5de7839SBastian Koppelmann     int32_t avf = 0;
968d5de7839SBastian Koppelmann     int32_t ret = 0;
969d5de7839SBastian Koppelmann 
970d5de7839SBastian Koppelmann     for (i = 0; i < 2; i++) {
971d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 16, 16);
972d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 16, 16);
973d5de7839SBastian Koppelmann         h = extr_r1 - extr_r2;
974d5de7839SBastian Koppelmann         ovf |= ((h > 0x7fff) || (h < -0x8000));
975d5de7839SBastian Koppelmann         avf |= h ^ h * 2u;
976d5de7839SBastian Koppelmann         ret |= (h & 0xffff) << (i * 16);
977d5de7839SBastian Koppelmann     }
978d5de7839SBastian Koppelmann 
979d5de7839SBastian Koppelmann     env->PSW_USB_V = (ovf << 31);
980d5de7839SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
981d5de7839SBastian Koppelmann     env->PSW_USB_AV = avf << 16;
982d5de7839SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
983d5de7839SBastian Koppelmann 
984d5de7839SBastian Koppelmann     return ret;
985d5de7839SBastian Koppelmann }
986d5de7839SBastian Koppelmann 
987d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
988d5de7839SBastian Koppelmann {
989d5de7839SBastian Koppelmann     int32_t ret;
990d5de7839SBastian Koppelmann     int32_t i, msk;
991d5de7839SBastian Koppelmann 
992d5de7839SBastian Koppelmann     ret = 0;
993d5de7839SBastian Koppelmann     msk = 0xff;
994d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
995d5de7839SBastian Koppelmann         if ((r1 & msk) == (r2 & msk)) {
996d5de7839SBastian Koppelmann             ret |= msk;
997d5de7839SBastian Koppelmann         }
998d5de7839SBastian Koppelmann         msk = msk << 8;
999d5de7839SBastian Koppelmann     }
1000d5de7839SBastian Koppelmann 
1001d5de7839SBastian Koppelmann     return ret;
1002d5de7839SBastian Koppelmann }
1003d5de7839SBastian Koppelmann 
1004d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
1005d5de7839SBastian Koppelmann {
1006d5de7839SBastian Koppelmann     int32_t ret = 0;
1007d5de7839SBastian Koppelmann 
1008d5de7839SBastian Koppelmann     if ((r1 & 0xffff) == (r2 & 0xffff)) {
1009d5de7839SBastian Koppelmann         ret = 0xffff;
1010d5de7839SBastian Koppelmann     }
1011d5de7839SBastian Koppelmann 
1012d5de7839SBastian Koppelmann     if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
1013d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1014d5de7839SBastian Koppelmann     }
1015d5de7839SBastian Koppelmann 
1016d5de7839SBastian Koppelmann     return ret;
1017d5de7839SBastian Koppelmann }
1018d5de7839SBastian Koppelmann 
1019d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
1020d5de7839SBastian Koppelmann {
1021d5de7839SBastian Koppelmann     int32_t i;
1022d5de7839SBastian Koppelmann     uint32_t ret = 0;
1023d5de7839SBastian Koppelmann 
1024d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1025d5de7839SBastian Koppelmann         ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
1026d5de7839SBastian Koppelmann     }
1027d5de7839SBastian Koppelmann 
1028d5de7839SBastian Koppelmann     return ret;
1029d5de7839SBastian Koppelmann }
1030d5de7839SBastian Koppelmann 
1031d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
1032d5de7839SBastian Koppelmann {
1033d5de7839SBastian Koppelmann     uint32_t ret;
1034d5de7839SBastian Koppelmann 
1035d5de7839SBastian Koppelmann     ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
1036d5de7839SBastian Koppelmann     ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
1037d5de7839SBastian Koppelmann 
1038d5de7839SBastian Koppelmann     return ret;
1039d5de7839SBastian Koppelmann }
1040d5de7839SBastian Koppelmann 
1041d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
1042d5de7839SBastian Koppelmann {
1043d5de7839SBastian Koppelmann     int32_t i;
1044d5de7839SBastian Koppelmann     uint32_t ret = 0;
1045d5de7839SBastian Koppelmann 
1046d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1047d5de7839SBastian Koppelmann         if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
1048d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
1049d5de7839SBastian Koppelmann         }
1050d5de7839SBastian Koppelmann     }
1051d5de7839SBastian Koppelmann 
1052d5de7839SBastian Koppelmann     return ret;
1053d5de7839SBastian Koppelmann }
1054d5de7839SBastian Koppelmann 
1055d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
1056d5de7839SBastian Koppelmann {
1057d5de7839SBastian Koppelmann     int32_t i;
1058d5de7839SBastian Koppelmann     uint32_t ret = 0;
1059d5de7839SBastian Koppelmann 
1060d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {
1061d5de7839SBastian Koppelmann         if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
1062d5de7839SBastian Koppelmann             ret |= (0xff << (i * 8));
1063d5de7839SBastian Koppelmann         }
1064d5de7839SBastian Koppelmann     }
1065d5de7839SBastian Koppelmann 
1066d5de7839SBastian Koppelmann     return ret;
1067d5de7839SBastian Koppelmann }
1068d5de7839SBastian Koppelmann 
1069d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
1070d5de7839SBastian Koppelmann {
1071d5de7839SBastian Koppelmann     uint32_t ret = 0;
1072d5de7839SBastian Koppelmann 
1073d5de7839SBastian Koppelmann     if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
1074d5de7839SBastian Koppelmann         ret |= 0xffff;
1075d5de7839SBastian Koppelmann     }
1076d5de7839SBastian Koppelmann 
1077d5de7839SBastian Koppelmann     if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
1078d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1079d5de7839SBastian Koppelmann     }
1080d5de7839SBastian Koppelmann 
1081d5de7839SBastian Koppelmann     return ret;
1082d5de7839SBastian Koppelmann }
1083d5de7839SBastian Koppelmann 
1084d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
1085d5de7839SBastian Koppelmann {
1086d5de7839SBastian Koppelmann     uint32_t ret = 0;
1087d5de7839SBastian Koppelmann 
1088d5de7839SBastian Koppelmann     if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
1089d5de7839SBastian Koppelmann         ret |= 0xffff;
1090d5de7839SBastian Koppelmann     }
1091d5de7839SBastian Koppelmann 
1092d5de7839SBastian Koppelmann     if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
1093d5de7839SBastian Koppelmann         ret |= 0xffff0000;
1094d5de7839SBastian Koppelmann     }
1095d5de7839SBastian Koppelmann 
1096d5de7839SBastian Koppelmann     return ret;
1097d5de7839SBastian Koppelmann }
1098d5de7839SBastian Koppelmann 
1099d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op)                                 \
1100d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
1101d5de7839SBastian Koppelmann {                                                             \
1102d5de7839SBastian Koppelmann     int32_t i, extr_r1, extr_r2;                              \
1103d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1104d5de7839SBastian Koppelmann                                                               \
1105d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
1106d5de7839SBastian Koppelmann         extr_r1 = sextract32(r1, i * 8, 8);                   \
1107d5de7839SBastian Koppelmann         extr_r2 = sextract32(r2, i * 8, 8);                   \
1108d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1109d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1110d5de7839SBastian Koppelmann     }                                                         \
1111d5de7839SBastian Koppelmann     return ret;                                               \
1112d5de7839SBastian Koppelmann }                                                             \
1113d5de7839SBastian Koppelmann                                                               \
1114d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
1115d5de7839SBastian Koppelmann {                                                             \
1116d5de7839SBastian Koppelmann     int32_t i;                                                \
1117d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
1118d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1119d5de7839SBastian Koppelmann                                                               \
1120d5de7839SBastian Koppelmann     for (i = 0; i < 4; i++) {                                 \
1121d5de7839SBastian Koppelmann         extr_r1 = extract32(r1, i * 8, 8);                    \
1122d5de7839SBastian Koppelmann         extr_r2 = extract32(r2, i * 8, 8);                    \
1123d5de7839SBastian Koppelmann         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1124d5de7839SBastian Koppelmann         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1125d5de7839SBastian Koppelmann     }                                                         \
1126d5de7839SBastian Koppelmann     return ret;                                               \
1127d5de7839SBastian Koppelmann }                                                             \
1128d5de7839SBastian Koppelmann                                                               \
1129d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
1130d5de7839SBastian Koppelmann {                                                             \
1131d5de7839SBastian Koppelmann     int32_t extr_r1, extr_r2;                                 \
1132d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1133d5de7839SBastian Koppelmann                                                               \
1134d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 0, 16);                          \
1135d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 0, 16);                          \
1136d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1137d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
1138d5de7839SBastian Koppelmann                                                               \
1139d5de7839SBastian Koppelmann     extr_r1 = sextract32(r1, 16, 16);                         \
1140d5de7839SBastian Koppelmann     extr_r2 = sextract32(r2, 16, 16);                         \
1141d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1142d5de7839SBastian Koppelmann     ret |= extr_r1 << 16;                                     \
1143d5de7839SBastian Koppelmann                                                               \
1144d5de7839SBastian Koppelmann     return ret;                                               \
1145d5de7839SBastian Koppelmann }                                                             \
1146d5de7839SBastian Koppelmann                                                               \
1147d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
1148d5de7839SBastian Koppelmann {                                                             \
1149d5de7839SBastian Koppelmann     uint32_t extr_r1, extr_r2;                                \
1150d5de7839SBastian Koppelmann     uint32_t ret = 0;                                         \
1151d5de7839SBastian Koppelmann                                                               \
1152d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 0, 16);                           \
1153d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 0, 16);                           \
1154d5de7839SBastian Koppelmann     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1155d5de7839SBastian Koppelmann     ret = ret & 0xffff;                                       \
1156d5de7839SBastian Koppelmann                                                               \
1157d5de7839SBastian Koppelmann     extr_r1 = extract32(r1, 16, 16);                          \
1158d5de7839SBastian Koppelmann     extr_r2 = extract32(r2, 16, 16);                          \
1159d5de7839SBastian Koppelmann     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1160d5de7839SBastian Koppelmann     ret |= extr_r1 << (16);                                   \
1161d5de7839SBastian Koppelmann                                                               \
1162d5de7839SBastian Koppelmann     return ret;                                               \
1163d5de7839SBastian Koppelmann }                                                             \
116409532255SBastian Koppelmann                                                               \
116509532255SBastian Koppelmann uint64_t helper_ix##name(uint64_t r1, uint32_t r2)            \
116609532255SBastian Koppelmann {                                                             \
116709532255SBastian Koppelmann     int64_t r2l, r2h, r1hl;                                   \
116809532255SBastian Koppelmann     uint64_t ret = 0;                                         \
116909532255SBastian Koppelmann                                                               \
117009532255SBastian Koppelmann     ret = ((r1 + 2) & 0xffff);                                \
117109532255SBastian Koppelmann     r2l = sextract64(r2, 0, 16);                              \
117209532255SBastian Koppelmann     r2h = sextract64(r2, 16, 16);                             \
117309532255SBastian Koppelmann     r1hl = sextract64(r1, 32, 16);                            \
117409532255SBastian Koppelmann                                                               \
117509532255SBastian Koppelmann     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
117609532255SBastian Koppelmann         ret |= (r2l & 0xffff) << 32;                          \
117709532255SBastian Koppelmann         ret |= extract64(r1, 0, 16) << 16;                    \
117809532255SBastian Koppelmann     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
117909532255SBastian Koppelmann         ret |= extract64(r2, 16, 16) << 32;                   \
118009532255SBastian Koppelmann         ret |= extract64(r1 + 1, 0, 16) << 16;                \
118109532255SBastian Koppelmann     } else {                                                  \
118209532255SBastian Koppelmann         ret |= r1 & 0xffffffff0000ull;                        \
118309532255SBastian Koppelmann     }                                                         \
118409532255SBastian Koppelmann     return ret;                                               \
118509532255SBastian Koppelmann }                                                             \
118609532255SBastian Koppelmann                                                               \
118709532255SBastian Koppelmann uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2)       \
118809532255SBastian Koppelmann {                                                             \
118909532255SBastian Koppelmann     int64_t r2l, r2h, r1hl;                                   \
119009532255SBastian Koppelmann     uint64_t ret = 0;                                         \
119109532255SBastian Koppelmann                                                               \
119209532255SBastian Koppelmann     ret = ((r1 + 2) & 0xffff);                                \
119309532255SBastian Koppelmann     r2l = extract64(r2, 0, 16);                               \
119409532255SBastian Koppelmann     r2h = extract64(r2, 16, 16);                              \
119509532255SBastian Koppelmann     r1hl = extract64(r1, 32, 16);                             \
119609532255SBastian Koppelmann                                                               \
119709532255SBastian Koppelmann     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
119809532255SBastian Koppelmann         ret |= (r2l & 0xffff) << 32;                          \
119909532255SBastian Koppelmann         ret |= extract64(r1, 0, 16) << 16;                    \
120009532255SBastian Koppelmann     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
120109532255SBastian Koppelmann         ret |= extract64(r2, 16, 16) << 32;                   \
120209532255SBastian Koppelmann         ret |= extract64(r1 + 1, 0, 16) << 16;                \
120309532255SBastian Koppelmann     } else {                                                  \
120409532255SBastian Koppelmann         ret |= r1 & 0xffffffff0000ull;                        \
120509532255SBastian Koppelmann     }                                                         \
120609532255SBastian Koppelmann     return ret;                                               \
120709532255SBastian Koppelmann }
1208d5de7839SBastian Koppelmann 
1209d5de7839SBastian Koppelmann EXTREMA_H_B(max, >)
1210d5de7839SBastian Koppelmann EXTREMA_H_B(min, <)
1211d5de7839SBastian Koppelmann 
1212d5de7839SBastian Koppelmann #undef EXTREMA_H_B
1213d5de7839SBastian Koppelmann 
12140b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1)
12150b79a781SBastian Koppelmann {
12160b79a781SBastian Koppelmann     return clo32(r1);
12170b79a781SBastian Koppelmann }
12180b79a781SBastian Koppelmann 
12190b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1)
12200b79a781SBastian Koppelmann {
12210b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
12220b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
12230b79a781SBastian Koppelmann 
12240b79a781SBastian Koppelmann     ret_hw0 = clo32(ret_hw0 << 16);
12250b79a781SBastian Koppelmann     ret_hw1 = clo32(ret_hw1 << 16);
12260b79a781SBastian Koppelmann 
12270b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
12280b79a781SBastian Koppelmann         ret_hw0 = 16;
12290b79a781SBastian Koppelmann     }
12300b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
12310b79a781SBastian Koppelmann         ret_hw1 = 16;
12320b79a781SBastian Koppelmann     }
12330b79a781SBastian Koppelmann 
12340b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
12350b79a781SBastian Koppelmann }
12360b79a781SBastian Koppelmann 
12370b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1)
12380b79a781SBastian Koppelmann {
12390b79a781SBastian Koppelmann     return clz32(r1);
12400b79a781SBastian Koppelmann }
12410b79a781SBastian Koppelmann 
12420b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1)
12430b79a781SBastian Koppelmann {
12440b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
12450b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
12460b79a781SBastian Koppelmann 
12470b79a781SBastian Koppelmann     ret_hw0 = clz32(ret_hw0 << 16);
12480b79a781SBastian Koppelmann     ret_hw1 = clz32(ret_hw1 << 16);
12490b79a781SBastian Koppelmann 
12500b79a781SBastian Koppelmann     if (ret_hw0 > 16) {
12510b79a781SBastian Koppelmann         ret_hw0 = 16;
12520b79a781SBastian Koppelmann     }
12530b79a781SBastian Koppelmann     if (ret_hw1 > 16) {
12540b79a781SBastian Koppelmann         ret_hw1 = 16;
12550b79a781SBastian Koppelmann     }
12560b79a781SBastian Koppelmann 
12570b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
12580b79a781SBastian Koppelmann }
12590b79a781SBastian Koppelmann 
12600b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1)
12610b79a781SBastian Koppelmann {
12620b79a781SBastian Koppelmann     return clrsb32(r1);
12630b79a781SBastian Koppelmann }
12640b79a781SBastian Koppelmann 
12650b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1)
12660b79a781SBastian Koppelmann {
12670b79a781SBastian Koppelmann     uint32_t ret_hw0 = extract32(r1, 0, 16);
12680b79a781SBastian Koppelmann     uint32_t ret_hw1 = extract32(r1, 16, 16);
12690b79a781SBastian Koppelmann 
12700b79a781SBastian Koppelmann     ret_hw0 = clrsb32(ret_hw0 << 16);
12710b79a781SBastian Koppelmann     ret_hw1 = clrsb32(ret_hw1 << 16);
12720b79a781SBastian Koppelmann 
12730b79a781SBastian Koppelmann     if (ret_hw0 > 15) {
12740b79a781SBastian Koppelmann         ret_hw0 = 15;
12750b79a781SBastian Koppelmann     }
12760b79a781SBastian Koppelmann     if (ret_hw1 > 15) {
12770b79a781SBastian Koppelmann         ret_hw1 = 15;
12780b79a781SBastian Koppelmann     }
12790b79a781SBastian Koppelmann 
12800b79a781SBastian Koppelmann     return ret_hw0 | (ret_hw1 << 16);
12810b79a781SBastian Koppelmann }
12820b79a781SBastian Koppelmann 
12830b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2)
12840b79a781SBastian Koppelmann {
12850b79a781SBastian Koppelmann     int32_t shift_count = sextract32(r2, 0, 6);
12860b79a781SBastian Koppelmann 
12870b79a781SBastian Koppelmann     if (shift_count == -32) {
12880b79a781SBastian Koppelmann         return 0;
12890b79a781SBastian Koppelmann     } else if (shift_count < 0) {
12900b79a781SBastian Koppelmann         return r1 >> -shift_count;
12910b79a781SBastian Koppelmann     } else {
12920b79a781SBastian Koppelmann         return r1 << shift_count;
12930b79a781SBastian Koppelmann     }
12940b79a781SBastian Koppelmann }
12950b79a781SBastian Koppelmann 
12960b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
12970b79a781SBastian Koppelmann {
12980b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
12990b79a781SBastian Koppelmann     int32_t shift_count;
13000b79a781SBastian Koppelmann 
13010b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
13020b79a781SBastian Koppelmann 
13030b79a781SBastian Koppelmann     if (shift_count == -16) {
13040b79a781SBastian Koppelmann         return 0;
13050b79a781SBastian Koppelmann     } else if (shift_count < 0) {
13060b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
13070b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
13080b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
13090b79a781SBastian Koppelmann     } else {
13100b79a781SBastian Koppelmann         ret_hw0 = extract32(r1, 0, 16) << shift_count;
13110b79a781SBastian Koppelmann         ret_hw1 = extract32(r1, 16, 16) << shift_count;
13120b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
13130b79a781SBastian Koppelmann     }
13140b79a781SBastian Koppelmann }
13150b79a781SBastian Koppelmann 
13160b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
13170b79a781SBastian Koppelmann {
13180b79a781SBastian Koppelmann     int32_t shift_count;
13190b79a781SBastian Koppelmann     int64_t result, t1;
13200b79a781SBastian Koppelmann     uint32_t ret;
13210b79a781SBastian Koppelmann 
13220b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 6);
13230b79a781SBastian Koppelmann     t1 = sextract32(r1, 0, 32);
13240b79a781SBastian Koppelmann 
13250b79a781SBastian Koppelmann     if (shift_count == 0) {
13260b79a781SBastian Koppelmann         env->PSW_USB_C = env->PSW_USB_V = 0;
13270b79a781SBastian Koppelmann         ret = r1;
13280b79a781SBastian Koppelmann     } else if (shift_count == -32) {
13290b79a781SBastian Koppelmann         env->PSW_USB_C = r1;
13300b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
13310b79a781SBastian Koppelmann         ret = t1 >> 31;
13320b79a781SBastian Koppelmann     } else if (shift_count > 0) {
13330b79a781SBastian Koppelmann         result = t1 << shift_count;
13340b79a781SBastian Koppelmann         /* calc carry */
1335452e3d49SPeter Maydell         env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
13360b79a781SBastian Koppelmann         /* calc v */
13370b79a781SBastian Koppelmann         env->PSW_USB_V = (((result > 0x7fffffffLL) ||
13380b79a781SBastian Koppelmann                            (result < -0x80000000LL)) << 31);
13390b79a781SBastian Koppelmann         /* calc sv */
13400b79a781SBastian Koppelmann         env->PSW_USB_SV |= env->PSW_USB_V;
13410b79a781SBastian Koppelmann         ret = (uint32_t)result;
13420b79a781SBastian Koppelmann     } else {
13430b79a781SBastian Koppelmann         env->PSW_USB_V = 0;
13440b79a781SBastian Koppelmann         env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
13450b79a781SBastian Koppelmann         ret = t1 >> -shift_count;
13460b79a781SBastian Koppelmann     }
13470b79a781SBastian Koppelmann 
13480b79a781SBastian Koppelmann     env->PSW_USB_AV = ret ^ ret * 2u;
13490b79a781SBastian Koppelmann     env->PSW_USB_SAV |= env->PSW_USB_AV;
13500b79a781SBastian Koppelmann 
13510b79a781SBastian Koppelmann     return ret;
13520b79a781SBastian Koppelmann }
13530b79a781SBastian Koppelmann 
13540b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
13550b79a781SBastian Koppelmann {
13560b79a781SBastian Koppelmann     int32_t shift_count;
13570b79a781SBastian Koppelmann     int32_t ret_hw0, ret_hw1;
13580b79a781SBastian Koppelmann 
13590b79a781SBastian Koppelmann     shift_count = sextract32(r2, 0, 5);
13600b79a781SBastian Koppelmann 
13610b79a781SBastian Koppelmann     if (shift_count == 0) {
13620b79a781SBastian Koppelmann         return r1;
13630b79a781SBastian Koppelmann     } else if (shift_count < 0) {
13640b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
13650b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
13660b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
13670b79a781SBastian Koppelmann     } else {
13680b79a781SBastian Koppelmann         ret_hw0 = sextract32(r1, 0, 16) << shift_count;
13690b79a781SBastian Koppelmann         ret_hw1 = sextract32(r1, 16, 16) << shift_count;
13700b79a781SBastian Koppelmann         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
13710b79a781SBastian Koppelmann     }
13720b79a781SBastian Koppelmann }
13730b79a781SBastian Koppelmann 
1374e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1375e2bed107SBastian Koppelmann {
1376e2bed107SBastian Koppelmann     uint32_t i, ret;
1377e2bed107SBastian Koppelmann 
1378e2bed107SBastian Koppelmann     ret = 0;
1379e2bed107SBastian Koppelmann     for (i = 0; i < 16; i++) {
1380e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (2 * i + 1);
1381e2bed107SBastian Koppelmann         ret |= (r2 & 1) << (2 * i);
1382e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1383e2bed107SBastian Koppelmann         r2 = r2 >> 1;
1384e2bed107SBastian Koppelmann     }
1385e2bed107SBastian Koppelmann     return ret;
1386e2bed107SBastian Koppelmann }
1387e2bed107SBastian Koppelmann 
1388e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1)
1389e2bed107SBastian Koppelmann {
1390e2bed107SBastian Koppelmann     int32_t i;
1391e2bed107SBastian Koppelmann     uint64_t ret;
1392e2bed107SBastian Koppelmann 
1393e2bed107SBastian Koppelmann     ret = 0;
1394e2bed107SBastian Koppelmann     for (i = 0; i < 32; i = i + 2) {
1395e2bed107SBastian Koppelmann         /* even */
1396e2bed107SBastian Koppelmann         ret |= (r1 & 1) << (i/2);
1397e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1398e2bed107SBastian Koppelmann         /* odd */
1399e2bed107SBastian Koppelmann         ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1400e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1401e2bed107SBastian Koppelmann     }
1402e2bed107SBastian Koppelmann     return ret;
1403e2bed107SBastian Koppelmann }
1404e2bed107SBastian Koppelmann 
1405e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1)
1406e2bed107SBastian Koppelmann {
1407e2bed107SBastian Koppelmann     uint32_t ret;
1408e2bed107SBastian Koppelmann     uint32_t nOnes, i;
1409e2bed107SBastian Koppelmann 
1410e2bed107SBastian Koppelmann     ret = 0;
1411e2bed107SBastian Koppelmann     nOnes = 0;
1412e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1413e2bed107SBastian Koppelmann         ret ^= (r1 & 1);
1414e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1415e2bed107SBastian Koppelmann     }
1416e2bed107SBastian Koppelmann     /* second byte */
1417e2bed107SBastian Koppelmann     nOnes = 0;
1418e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1419e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1420e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1421e2bed107SBastian Koppelmann     }
1422e2bed107SBastian Koppelmann     ret |= nOnes << 8;
1423e2bed107SBastian Koppelmann     /* third byte */
1424e2bed107SBastian Koppelmann     nOnes = 0;
1425e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1426e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1427e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1428e2bed107SBastian Koppelmann     }
1429e2bed107SBastian Koppelmann     ret |= nOnes << 16;
1430e2bed107SBastian Koppelmann     /* fourth byte */
1431e2bed107SBastian Koppelmann     nOnes = 0;
1432e2bed107SBastian Koppelmann     for (i = 0; i < 8; i++) {
1433e2bed107SBastian Koppelmann         nOnes ^= (r1 & 1);
1434e2bed107SBastian Koppelmann         r1 = r1 >> 1;
1435e2bed107SBastian Koppelmann     }
1436e2bed107SBastian Koppelmann     ret |= nOnes << 24;
1437e2bed107SBastian Koppelmann 
1438e2bed107SBastian Koppelmann     return ret;
1439e2bed107SBastian Koppelmann }
1440e2bed107SBastian Koppelmann 
144109532255SBastian Koppelmann uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
144209532255SBastian Koppelmann                      target_ulong r2)
144309532255SBastian Koppelmann {
144409532255SBastian Koppelmann     uint32_t ret;
144509532255SBastian Koppelmann     int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
144609532255SBastian Koppelmann     int32_t int_exp  = r1_high;
144709532255SBastian Koppelmann     int32_t int_mant = r1_low;
144809532255SBastian Koppelmann     uint32_t flag_rnd = (int_mant & (1 << 7)) && (
144909532255SBastian Koppelmann                         (int_mant & (1 << 8)) ||
145009532255SBastian Koppelmann                         (int_mant & 0x7f)     ||
145109532255SBastian Koppelmann                         (carry != 0));
145209532255SBastian Koppelmann     if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
145309532255SBastian Koppelmann         fp_exp = 255;
145409532255SBastian Koppelmann         fp_frac = extract32(int_mant, 8, 23);
145509532255SBastian Koppelmann     } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
145609532255SBastian Koppelmann         fp_exp  = 255;
145709532255SBastian Koppelmann         fp_frac = 0;
145809532255SBastian Koppelmann     } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
145909532255SBastian Koppelmann         fp_exp  = 0;
146009532255SBastian Koppelmann         fp_frac = 0;
146109532255SBastian Koppelmann     } else if (int_mant == 0) {
146209532255SBastian Koppelmann         fp_exp  = 0;
146309532255SBastian Koppelmann         fp_frac = 0;
146409532255SBastian Koppelmann     } else {
146509532255SBastian Koppelmann         if (((int_mant & (1 << 31)) == 0)) {
146609532255SBastian Koppelmann             temp_exp = 0;
146709532255SBastian Koppelmann         } else {
146809532255SBastian Koppelmann             temp_exp = int_exp + 128;
146909532255SBastian Koppelmann         }
147009532255SBastian Koppelmann         fp_exp_frac = (((temp_exp & 0xff) << 23) |
147109532255SBastian Koppelmann                       extract32(int_mant, 8, 23))
147209532255SBastian Koppelmann                       + flag_rnd;
147309532255SBastian Koppelmann         fp_exp  = extract32(fp_exp_frac, 23, 8);
147409532255SBastian Koppelmann         fp_frac = extract32(fp_exp_frac, 0, 23);
147509532255SBastian Koppelmann     }
147609532255SBastian Koppelmann     ret = r2 & (1 << 31);
147709532255SBastian Koppelmann     ret = ret + (fp_exp << 23);
147809532255SBastian Koppelmann     ret = ret + (fp_frac & 0x7fffff);
147909532255SBastian Koppelmann 
148009532255SBastian Koppelmann     return ret;
148109532255SBastian Koppelmann }
148209532255SBastian Koppelmann 
1483e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1)
1484e2bed107SBastian Koppelmann {
1485e2bed107SBastian Koppelmann     int32_t fp_exp  = extract32(arg1, 23, 8);
1486e2bed107SBastian Koppelmann     int32_t fp_frac = extract32(arg1, 0, 23);
1487e2bed107SBastian Koppelmann     uint64_t ret;
1488e2bed107SBastian Koppelmann     int32_t int_exp, int_mant;
1489e2bed107SBastian Koppelmann 
1490e2bed107SBastian Koppelmann     if (fp_exp == 255) {
1491e2bed107SBastian Koppelmann         int_exp = 255;
1492e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1493e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac == 0)) {
1494e2bed107SBastian Koppelmann         int_exp  = -127;
1495e2bed107SBastian Koppelmann         int_mant = 0;
1496e2bed107SBastian Koppelmann     } else if ((fp_exp == 0) && (fp_frac != 0)) {
1497e2bed107SBastian Koppelmann         int_exp  = -126;
1498e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1499e2bed107SBastian Koppelmann     } else {
1500e2bed107SBastian Koppelmann         int_exp  = fp_exp - 127;
1501e2bed107SBastian Koppelmann         int_mant = (fp_frac << 7);
1502e2bed107SBastian Koppelmann         int_mant |= (1 << 30);
1503e2bed107SBastian Koppelmann     }
1504e2bed107SBastian Koppelmann     ret = int_exp;
1505e2bed107SBastian Koppelmann     ret = ret << 32;
1506e2bed107SBastian Koppelmann     ret |= int_mant;
1507e2bed107SBastian Koppelmann 
1508e2bed107SBastian Koppelmann     return ret;
1509e2bed107SBastian Koppelmann }
1510e2bed107SBastian Koppelmann 
1511e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1512e2bed107SBastian Koppelmann {
1513e2bed107SBastian Koppelmann     uint64_t ret;
1514e2bed107SBastian Koppelmann     int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1515e2bed107SBastian Koppelmann     int32_t quotient_sign;
1516e2bed107SBastian Koppelmann 
1517e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1518e2bed107SBastian Koppelmann     ret = ret << 24;
1519e2bed107SBastian Koppelmann     quotient_sign = 0;
1520e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1521e2bed107SBastian Koppelmann         ret |= 0xffffff;
1522e2bed107SBastian Koppelmann         quotient_sign = 1;
1523e2bed107SBastian Koppelmann     }
1524e2bed107SBastian Koppelmann 
1525e2bed107SBastian Koppelmann     abs_sig_dividend = abs(r1) >> 7;
1526e2bed107SBastian Koppelmann     abs_base_dividend = abs(r1) & 0x7f;
1527e2bed107SBastian Koppelmann     abs_divisor = abs(r1);
1528e2bed107SBastian Koppelmann     /* calc overflow */
1529e2bed107SBastian Koppelmann     env->PSW_USB_V = 0;
1530e2bed107SBastian Koppelmann     if ((quotient_sign) && (abs_divisor)) {
1531e2bed107SBastian Koppelmann         env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1532e2bed107SBastian Koppelmann                          (abs_base_dividend >= abs_divisor)) ||
1533e2bed107SBastian Koppelmann                          (abs_sig_dividend > abs_divisor));
1534e2bed107SBastian Koppelmann     } else {
1535e2bed107SBastian Koppelmann         env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1536e2bed107SBastian Koppelmann     }
1537e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1538e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1539e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1540e2bed107SBastian Koppelmann 
1541e2bed107SBastian Koppelmann     return ret;
1542e2bed107SBastian Koppelmann }
1543e2bed107SBastian Koppelmann 
1544e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1545e2bed107SBastian Koppelmann {
1546e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
1547e2bed107SBastian Koppelmann 
1548e2bed107SBastian Koppelmann     ret = ret << 24;
1549e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1550e2bed107SBastian Koppelmann         ret |= 0xffffff;
1551e2bed107SBastian Koppelmann     }
1552e2bed107SBastian Koppelmann     /* calc overflow */
1553e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
1554e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1555e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1556e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1557e2bed107SBastian Koppelmann 
1558e2bed107SBastian Koppelmann     return ret;
1559e2bed107SBastian Koppelmann }
1560e2bed107SBastian Koppelmann 
1561e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1562e2bed107SBastian Koppelmann {
1563e2bed107SBastian Koppelmann     uint64_t ret;
1564e2bed107SBastian Koppelmann     int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1565e2bed107SBastian Koppelmann     int32_t quotient_sign;
1566e2bed107SBastian Koppelmann 
1567e2bed107SBastian Koppelmann     ret = sextract32(r1, 0, 32);
1568e2bed107SBastian Koppelmann     ret = ret << 16;
1569e2bed107SBastian Koppelmann     quotient_sign = 0;
1570e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1571e2bed107SBastian Koppelmann         ret |= 0xffff;
1572e2bed107SBastian Koppelmann         quotient_sign = 1;
1573e2bed107SBastian Koppelmann     }
1574e2bed107SBastian Koppelmann 
1575e2bed107SBastian Koppelmann     abs_sig_dividend = abs(r1) >> 7;
1576e2bed107SBastian Koppelmann     abs_base_dividend = abs(r1) & 0x7f;
1577e2bed107SBastian Koppelmann     abs_divisor = abs(r1);
1578e2bed107SBastian Koppelmann     /* calc overflow */
1579e2bed107SBastian Koppelmann     env->PSW_USB_V = 0;
1580e2bed107SBastian Koppelmann     if ((quotient_sign) && (abs_divisor)) {
1581e2bed107SBastian Koppelmann         env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1582e2bed107SBastian Koppelmann                          (abs_base_dividend >= abs_divisor)) ||
1583e2bed107SBastian Koppelmann                          (abs_sig_dividend > abs_divisor));
1584e2bed107SBastian Koppelmann     } else {
1585e2bed107SBastian Koppelmann         env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1586e2bed107SBastian Koppelmann     }
1587e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1588e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1589e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1590e2bed107SBastian Koppelmann 
1591e2bed107SBastian Koppelmann     return ret;
1592e2bed107SBastian Koppelmann }
1593e2bed107SBastian Koppelmann 
1594e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1595e2bed107SBastian Koppelmann {
1596e2bed107SBastian Koppelmann     uint64_t ret = sextract32(r1, 0, 32);
1597e2bed107SBastian Koppelmann 
1598e2bed107SBastian Koppelmann     ret = ret << 16;
1599e2bed107SBastian Koppelmann     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1600e2bed107SBastian Koppelmann         ret |= 0xffff;
1601e2bed107SBastian Koppelmann     }
1602e2bed107SBastian Koppelmann     /* calc overflow */
1603e2bed107SBastian Koppelmann     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
1604e2bed107SBastian Koppelmann     env->PSW_USB_V = env->PSW_USB_V << 31;
1605e2bed107SBastian Koppelmann     env->PSW_USB_SV |= env->PSW_USB_V;
1606e2bed107SBastian Koppelmann     env->PSW_USB_AV = 0;
1607e2bed107SBastian Koppelmann 
1608e2bed107SBastian Koppelmann     return ret;
1609e2bed107SBastian Koppelmann }
1610e2bed107SBastian Koppelmann 
161109532255SBastian Koppelmann uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
161209532255SBastian Koppelmann {
161309532255SBastian Koppelmann     int32_t x_sign = (r1 >> 63);
161409532255SBastian Koppelmann     int32_t q_sign = x_sign ^ (r2 >> 31);
161509532255SBastian Koppelmann     int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
161609532255SBastian Koppelmann     int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
161709532255SBastian Koppelmann     uint32_t quotient;
161809532255SBastian Koppelmann     uint64_t ret, remainder;
161909532255SBastian Koppelmann 
162009532255SBastian Koppelmann     if ((q_sign & ~eq_neg) | eq_pos) {
162109532255SBastian Koppelmann         quotient = (r1 + 1) & 0xffffffff;
162209532255SBastian Koppelmann     } else {
162309532255SBastian Koppelmann         quotient = r1 & 0xffffffff;
162409532255SBastian Koppelmann     }
162509532255SBastian Koppelmann 
162609532255SBastian Koppelmann     if (eq_pos | eq_neg) {
162709532255SBastian Koppelmann         remainder = 0;
162809532255SBastian Koppelmann     } else {
162909532255SBastian Koppelmann         remainder = (r1 & 0xffffffff00000000ull);
163009532255SBastian Koppelmann     }
163109532255SBastian Koppelmann     ret = remainder|quotient;
163209532255SBastian Koppelmann     return ret;
163309532255SBastian Koppelmann }
163409532255SBastian Koppelmann 
163509532255SBastian Koppelmann uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
163609532255SBastian Koppelmann {
163709532255SBastian Koppelmann     int32_t dividend_sign = extract64(r1, 63, 1);
163809532255SBastian Koppelmann     int32_t divisor_sign = extract32(r2, 31, 1);
163909532255SBastian Koppelmann     int32_t quotient_sign = (dividend_sign != divisor_sign);
164009532255SBastian Koppelmann     int32_t addend, dividend_quotient, remainder;
164109532255SBastian Koppelmann     int32_t i, temp;
164209532255SBastian Koppelmann 
164309532255SBastian Koppelmann     if (quotient_sign) {
164409532255SBastian Koppelmann         addend = r2;
164509532255SBastian Koppelmann     } else {
164609532255SBastian Koppelmann         addend = -r2;
164709532255SBastian Koppelmann     }
164809532255SBastian Koppelmann     dividend_quotient = (int32_t)r1;
164909532255SBastian Koppelmann     remainder = (int32_t)(r1 >> 32);
165009532255SBastian Koppelmann 
165109532255SBastian Koppelmann     for (i = 0; i < 8; i++) {
165209532255SBastian Koppelmann         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
165309532255SBastian Koppelmann         dividend_quotient <<= 1;
165409532255SBastian Koppelmann         temp = remainder + addend;
165509532255SBastian Koppelmann         if ((temp < 0) == dividend_sign) {
165609532255SBastian Koppelmann             remainder = temp;
165709532255SBastian Koppelmann         }
165809532255SBastian Koppelmann         if (((temp < 0) == dividend_sign)) {
165909532255SBastian Koppelmann             dividend_quotient = dividend_quotient | !quotient_sign;
166009532255SBastian Koppelmann         } else {
166109532255SBastian Koppelmann             dividend_quotient = dividend_quotient | quotient_sign;
166209532255SBastian Koppelmann         }
166309532255SBastian Koppelmann     }
166409532255SBastian Koppelmann     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
166509532255SBastian Koppelmann }
166609532255SBastian Koppelmann 
166709532255SBastian Koppelmann uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
166809532255SBastian Koppelmann {
166909532255SBastian Koppelmann     int32_t dividend_quotient = extract64(r1, 0, 32);
167009532255SBastian Koppelmann     int64_t remainder = extract64(r1, 32, 32);
167109532255SBastian Koppelmann     int32_t i;
167209532255SBastian Koppelmann     int64_t temp;
167309532255SBastian Koppelmann     for (i = 0; i < 8; i++) {
167409532255SBastian Koppelmann         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
167509532255SBastian Koppelmann         dividend_quotient <<= 1;
167609532255SBastian Koppelmann         temp = (remainder & 0xffffffff) - r2;
167709532255SBastian Koppelmann         if (temp >= 0) {
167809532255SBastian Koppelmann             remainder = temp;
167909532255SBastian Koppelmann         }
168009532255SBastian Koppelmann         dividend_quotient = dividend_quotient | !(temp < 0);
168109532255SBastian Koppelmann     }
168209532255SBastian Koppelmann     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
168309532255SBastian Koppelmann }
168409532255SBastian Koppelmann 
16859655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
16869655b932SBastian Koppelmann                       uint32_t arg10, uint32_t arg11, uint32_t n)
16879655b932SBastian Koppelmann {
16889655b932SBastian Koppelmann     uint64_t ret;
16899655b932SBastian Koppelmann     uint32_t result0, result1;
16909655b932SBastian Koppelmann 
16919655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
16929655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
16939655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
16949655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
16959655b932SBastian Koppelmann     if (sc1) {
16969655b932SBastian Koppelmann         result1 = 0x7fffffff;
16979655b932SBastian Koppelmann     } else {
16989655b932SBastian Koppelmann         result1 = (((uint32_t)(arg00 * arg10)) << n);
16999655b932SBastian Koppelmann     }
17009655b932SBastian Koppelmann     if (sc0) {
17019655b932SBastian Koppelmann         result0 = 0x7fffffff;
17029655b932SBastian Koppelmann     } else {
17039655b932SBastian Koppelmann         result0 = (((uint32_t)(arg01 * arg11)) << n);
17049655b932SBastian Koppelmann     }
17059655b932SBastian Koppelmann     ret = (((uint64_t)result1 << 32)) | result0;
17069655b932SBastian Koppelmann     return ret;
17079655b932SBastian Koppelmann }
17089655b932SBastian Koppelmann 
17099655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
17109655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
17119655b932SBastian Koppelmann {
17129655b932SBastian Koppelmann     uint64_t ret;
17139655b932SBastian Koppelmann     int64_t result0, result1;
17149655b932SBastian Koppelmann 
17159655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
17169655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
17179655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
17189655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
17199655b932SBastian Koppelmann 
17209655b932SBastian Koppelmann     if (sc1) {
17219655b932SBastian Koppelmann         result1 = 0x7fffffff;
17229655b932SBastian Koppelmann     } else {
17239655b932SBastian Koppelmann         result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
17249655b932SBastian Koppelmann     }
17259655b932SBastian Koppelmann     if (sc0) {
17269655b932SBastian Koppelmann         result0 = 0x7fffffff;
17279655b932SBastian Koppelmann     } else {
17289655b932SBastian Koppelmann         result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
17299655b932SBastian Koppelmann     }
17309655b932SBastian Koppelmann     ret = (result1 + result0);
17319655b932SBastian Koppelmann     ret = ret << 16;
17329655b932SBastian Koppelmann     return ret;
17339655b932SBastian Koppelmann }
17349655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
17359655b932SBastian Koppelmann                        uint32_t arg10, uint32_t arg11, uint32_t n)
17369655b932SBastian Koppelmann {
17379655b932SBastian Koppelmann     uint32_t result0, result1;
17389655b932SBastian Koppelmann 
17399655b932SBastian Koppelmann     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
17409655b932SBastian Koppelmann                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
17419655b932SBastian Koppelmann     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
17429655b932SBastian Koppelmann                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
17439655b932SBastian Koppelmann 
17449655b932SBastian Koppelmann     if (sc1) {
17459655b932SBastian Koppelmann         result1 = 0x7fffffff;
17469655b932SBastian Koppelmann     } else {
17479655b932SBastian Koppelmann         result1 = ((arg00 * arg10) << n) + 0x8000;
17489655b932SBastian Koppelmann     }
17499655b932SBastian Koppelmann     if (sc0) {
17509655b932SBastian Koppelmann         result0 = 0x7fffffff;
17519655b932SBastian Koppelmann     } else {
17529655b932SBastian Koppelmann         result0 = ((arg01 * arg11) << n) + 0x8000;
17539655b932SBastian Koppelmann     }
17549655b932SBastian Koppelmann     return (result1 & 0xffff0000) | (result0 >> 16);
17559655b932SBastian Koppelmann }
17569655b932SBastian Koppelmann 
17579a31922bSBastian Koppelmann /* context save area (CSA) related helpers */
17589a31922bSBastian Koppelmann 
17599a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw)
17609a31922bSBastian Koppelmann {
17619a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
17629a31922bSBastian Koppelmann         return 0;
17639a31922bSBastian Koppelmann     }
17649a31922bSBastian Koppelmann 
17659a31922bSBastian Koppelmann     (*psw)++;
17669a31922bSBastian Koppelmann     /* check for overflow */
17679a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
17689a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
17699a31922bSBastian Koppelmann     int count = *psw & mask;
17709a31922bSBastian Koppelmann     if (count == 0) {
17719a31922bSBastian Koppelmann         (*psw)--;
17729a31922bSBastian Koppelmann         return 1;
17739a31922bSBastian Koppelmann     }
17749a31922bSBastian Koppelmann     return 0;
17759a31922bSBastian Koppelmann }
17769a31922bSBastian Koppelmann 
17779a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw)
17789a31922bSBastian Koppelmann {
17799a31922bSBastian Koppelmann     if ((*psw & MASK_PSW_CDC) == 0x7f) {
17809a31922bSBastian Koppelmann         return 0;
17819a31922bSBastian Koppelmann     }
17829a31922bSBastian Koppelmann     /* check for underflow */
17839a31922bSBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
17849a31922bSBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
17859a31922bSBastian Koppelmann     int count = *psw & mask;
17869a31922bSBastian Koppelmann     if (count == 0) {
17879a31922bSBastian Koppelmann         return 1;
17889a31922bSBastian Koppelmann     }
17899a31922bSBastian Koppelmann     (*psw)--;
17909a31922bSBastian Koppelmann     return 0;
17919a31922bSBastian Koppelmann }
17929a31922bSBastian Koppelmann 
179344ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw)
179444ea3430SBastian Koppelmann {
179544ea3430SBastian Koppelmann     int cdc = *psw & MASK_PSW_CDC;
179644ea3430SBastian Koppelmann     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
179744ea3430SBastian Koppelmann        7'b1111111, otherwise returns FALSE. */
179844ea3430SBastian Koppelmann     if (cdc == 0x7f) {
179944ea3430SBastian Koppelmann         return true;
180044ea3430SBastian Koppelmann     }
180144ea3430SBastian Koppelmann     /* find CDC.COUNT */
180244ea3430SBastian Koppelmann     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
180344ea3430SBastian Koppelmann     int mask = (1u << (7 - lo)) - 1;
180444ea3430SBastian Koppelmann     int count = *psw & mask;
180544ea3430SBastian Koppelmann     return count == 0;
180644ea3430SBastian Koppelmann }
180744ea3430SBastian Koppelmann 
1808030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea)
18099a31922bSBastian Koppelmann {
18109a31922bSBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
18119a31922bSBastian Koppelmann     cpu_stl_data(env, ea+4, env->PSW);
18129a31922bSBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[10]);
18139a31922bSBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[11]);
18149a31922bSBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[8]);
18159a31922bSBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[9]);
18169a31922bSBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[10]);
18179a31922bSBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[11]);
18189a31922bSBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[12]);
18199a31922bSBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[13]);
18209a31922bSBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[14]);
18219a31922bSBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[15]);
18229a31922bSBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[12]);
18239a31922bSBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[13]);
18249a31922bSBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[14]);
18259a31922bSBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[15]);
18269a31922bSBastian Koppelmann }
18279a31922bSBastian Koppelmann 
1828030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea)
18295de93515SBastian Koppelmann {
18305de93515SBastian Koppelmann     cpu_stl_data(env, ea, env->PCXI);
1831030c58dfSBastian Koppelmann     cpu_stl_data(env, ea+4, env->gpr_a[11]);
18325de93515SBastian Koppelmann     cpu_stl_data(env, ea+8, env->gpr_a[2]);
18335de93515SBastian Koppelmann     cpu_stl_data(env, ea+12, env->gpr_a[3]);
18345de93515SBastian Koppelmann     cpu_stl_data(env, ea+16, env->gpr_d[0]);
18355de93515SBastian Koppelmann     cpu_stl_data(env, ea+20, env->gpr_d[1]);
18365de93515SBastian Koppelmann     cpu_stl_data(env, ea+24, env->gpr_d[2]);
18375de93515SBastian Koppelmann     cpu_stl_data(env, ea+28, env->gpr_d[3]);
18385de93515SBastian Koppelmann     cpu_stl_data(env, ea+32, env->gpr_a[4]);
18395de93515SBastian Koppelmann     cpu_stl_data(env, ea+36, env->gpr_a[5]);
18405de93515SBastian Koppelmann     cpu_stl_data(env, ea+40, env->gpr_a[6]);
18415de93515SBastian Koppelmann     cpu_stl_data(env, ea+44, env->gpr_a[7]);
18425de93515SBastian Koppelmann     cpu_stl_data(env, ea+48, env->gpr_d[4]);
18435de93515SBastian Koppelmann     cpu_stl_data(env, ea+52, env->gpr_d[5]);
18445de93515SBastian Koppelmann     cpu_stl_data(env, ea+56, env->gpr_d[6]);
18455de93515SBastian Koppelmann     cpu_stl_data(env, ea+60, env->gpr_d[7]);
18465de93515SBastian Koppelmann }
18475de93515SBastian Koppelmann 
18489a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea,
18499a31922bSBastian Koppelmann                                   target_ulong *new_PCXI, target_ulong *new_PSW)
18509a31922bSBastian Koppelmann {
18519a31922bSBastian Koppelmann     *new_PCXI = cpu_ldl_data(env, ea);
18529a31922bSBastian Koppelmann     *new_PSW = cpu_ldl_data(env, ea+4);
18539a31922bSBastian Koppelmann     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
18549a31922bSBastian Koppelmann     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
18559a31922bSBastian Koppelmann     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
18569a31922bSBastian Koppelmann     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
18579a31922bSBastian Koppelmann     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
18589a31922bSBastian Koppelmann     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
18599a31922bSBastian Koppelmann     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
18609a31922bSBastian Koppelmann     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
18619a31922bSBastian Koppelmann     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
18629a31922bSBastian Koppelmann     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
18639a31922bSBastian Koppelmann     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
18649a31922bSBastian Koppelmann     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
18659a31922bSBastian Koppelmann     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
18669a31922bSBastian Koppelmann     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
18679a31922bSBastian Koppelmann }
18689a31922bSBastian Koppelmann 
186959543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea,
187059543d4eSBastian Koppelmann                                   target_ulong *ra, target_ulong *pcxi)
187159543d4eSBastian Koppelmann {
187259543d4eSBastian Koppelmann     *pcxi = cpu_ldl_data(env, ea);
187359543d4eSBastian Koppelmann     *ra = cpu_ldl_data(env, ea+4);
187459543d4eSBastian Koppelmann     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
187559543d4eSBastian Koppelmann     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
187659543d4eSBastian Koppelmann     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
187759543d4eSBastian Koppelmann     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
187859543d4eSBastian Koppelmann     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
187959543d4eSBastian Koppelmann     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
188059543d4eSBastian Koppelmann     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
188159543d4eSBastian Koppelmann     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
188259543d4eSBastian Koppelmann     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
188359543d4eSBastian Koppelmann     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
188459543d4eSBastian Koppelmann     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
188559543d4eSBastian Koppelmann     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
188659543d4eSBastian Koppelmann     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
188759543d4eSBastian Koppelmann     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
188859543d4eSBastian Koppelmann }
188959543d4eSBastian Koppelmann 
18909a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc)
18919a31922bSBastian Koppelmann {
18929a31922bSBastian Koppelmann     target_ulong tmp_FCX;
18939a31922bSBastian Koppelmann     target_ulong ea;
18949a31922bSBastian Koppelmann     target_ulong new_FCX;
18959a31922bSBastian Koppelmann     target_ulong psw;
18969a31922bSBastian Koppelmann 
18979a31922bSBastian Koppelmann     psw = psw_read(env);
18989a31922bSBastian Koppelmann     /* if (FCX == 0) trap(FCU); */
18999a31922bSBastian Koppelmann     if (env->FCX == 0) {
19009a31922bSBastian Koppelmann         /* FCU trap */
19019a31922bSBastian Koppelmann     }
19029a31922bSBastian Koppelmann     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
19039a31922bSBastian Koppelmann     if (psw & MASK_PSW_CDE) {
19049a31922bSBastian Koppelmann         if (cdc_increment(&psw)) {
19059a31922bSBastian Koppelmann             /* CDO trap */
19069a31922bSBastian Koppelmann         }
19079a31922bSBastian Koppelmann     }
19089a31922bSBastian Koppelmann     /* PSW.CDE = 1;*/
19099a31922bSBastian Koppelmann     psw |= MASK_PSW_CDE;
19109a31922bSBastian Koppelmann     /* tmp_FCX = FCX; */
19119a31922bSBastian Koppelmann     tmp_FCX = env->FCX;
19129a31922bSBastian Koppelmann     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
19139a31922bSBastian Koppelmann     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
19149a31922bSBastian Koppelmann          ((env->FCX & MASK_FCX_FCXO) << 6);
1915030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
1916030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
1917030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
19189a31922bSBastian Koppelmann                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
19199a31922bSBastian Koppelmann                            D[15]}; */
1920030c58dfSBastian Koppelmann     save_context_upper(env, ea);
19219a31922bSBastian Koppelmann 
19229a31922bSBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN; */
19239a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
19249a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_CCPN) << 24);
19259a31922bSBastian Koppelmann     /* PCXI.PIE = ICR.IE; */
19269a31922bSBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
19279a31922bSBastian Koppelmann                 ((env->ICR & MASK_ICR_IE) << 15));
19289a31922bSBastian Koppelmann     /* PCXI.UL = 1; */
19299a31922bSBastian Koppelmann     env->PCXI |= MASK_PCXI_UL;
19309a31922bSBastian Koppelmann 
19319a31922bSBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0]; */
19329a31922bSBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
19339a31922bSBastian Koppelmann     /* FCX[19: 0] = new_FCX[19: 0]; */
19349a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
19359a31922bSBastian Koppelmann     /* A[11] = next_pc[31: 0]; */
19369a31922bSBastian Koppelmann     env->gpr_a[11] = next_pc;
19379a31922bSBastian Koppelmann 
19389a31922bSBastian Koppelmann     /* if (tmp_FCX == LCX) trap(FCD);*/
19399a31922bSBastian Koppelmann     if (tmp_FCX == env->LCX) {
19409a31922bSBastian Koppelmann         /* FCD trap */
19419a31922bSBastian Koppelmann     }
19429a31922bSBastian Koppelmann     psw_write(env, psw);
19439a31922bSBastian Koppelmann }
19449a31922bSBastian Koppelmann 
19459a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env)
19469a31922bSBastian Koppelmann {
19479a31922bSBastian Koppelmann     target_ulong ea;
19489a31922bSBastian Koppelmann     target_ulong new_PCXI;
19499a31922bSBastian Koppelmann     target_ulong new_PSW, psw;
19509a31922bSBastian Koppelmann 
19519a31922bSBastian Koppelmann     psw = psw_read(env);
19529a31922bSBastian Koppelmann      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
19539a31922bSBastian Koppelmann     if (env->PSW & MASK_PSW_CDE) {
19549a31922bSBastian Koppelmann         if (cdc_decrement(&(env->PSW))) {
19559a31922bSBastian Koppelmann             /* CDU trap */
19569a31922bSBastian Koppelmann         }
19579a31922bSBastian Koppelmann     }
19589a31922bSBastian Koppelmann     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
19599a31922bSBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
19609a31922bSBastian Koppelmann         /* CSU trap */
19619a31922bSBastian Koppelmann     }
19629a31922bSBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
19639a31922bSBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
19649a31922bSBastian Koppelmann         /* CTYP trap */
19659a31922bSBastian Koppelmann     }
19669a31922bSBastian Koppelmann     /* PC = {A11 [31: 1], 1’b0}; */
19679a31922bSBastian Koppelmann     env->PC = env->gpr_a[11] & 0xfffffffe;
19689a31922bSBastian Koppelmann 
19699a31922bSBastian Koppelmann     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
19709a31922bSBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
19719a31922bSBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
19729a31922bSBastian Koppelmann     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
1973030c58dfSBastian Koppelmann         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
19749a31922bSBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
1975030c58dfSBastian Koppelmann     /* M(EA, word) = FCX; */
1976030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
19779a31922bSBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
19789a31922bSBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
19799a31922bSBastian Koppelmann     /* PCXI = new_PCXI; */
19809a31922bSBastian Koppelmann     env->PCXI = new_PCXI;
19819a31922bSBastian Koppelmann 
19829a31922bSBastian Koppelmann     if (tricore_feature(env, TRICORE_FEATURE_13)) {
19839a31922bSBastian Koppelmann         /* PSW = new_PSW */
19849a31922bSBastian Koppelmann         psw_write(env, new_PSW);
19859a31922bSBastian Koppelmann     } else {
19869a31922bSBastian Koppelmann         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
19879a31922bSBastian Koppelmann         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
19889a31922bSBastian Koppelmann     }
19899a31922bSBastian Koppelmann }
19909a31922bSBastian Koppelmann 
19915de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9)
19925de93515SBastian Koppelmann {
19935de93515SBastian Koppelmann     target_ulong tmp_FCX;
19945de93515SBastian Koppelmann     target_ulong ea;
19955de93515SBastian Koppelmann     target_ulong new_FCX;
19965de93515SBastian Koppelmann 
19975de93515SBastian Koppelmann     if (env->FCX == 0) {
19985de93515SBastian Koppelmann         /* FCU trap */
19995de93515SBastian Koppelmann     }
20005de93515SBastian Koppelmann 
20015de93515SBastian Koppelmann     tmp_FCX = env->FCX;
20025de93515SBastian Koppelmann     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
20035de93515SBastian Koppelmann 
2004030c58dfSBastian Koppelmann     /* new_FCX = M(EA, word); */
2005030c58dfSBastian Koppelmann     new_FCX = cpu_ldl_data(env, ea);
2006030c58dfSBastian Koppelmann     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2007030c58dfSBastian Koppelmann                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2008030c58dfSBastian Koppelmann     save_context_lower(env, ea);
2009030c58dfSBastian Koppelmann 
20105de93515SBastian Koppelmann 
20115de93515SBastian Koppelmann     /* PCXI.PCPN = ICR.CCPN */
20125de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xffffff) +
20135de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_CCPN) << 24);
20145de93515SBastian Koppelmann     /* PCXI.PIE  = ICR.IE */
20155de93515SBastian Koppelmann     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
20165de93515SBastian Koppelmann                  ((env->ICR & MASK_ICR_IE) << 15));
20175de93515SBastian Koppelmann     /* PCXI.UL = 0 */
20185de93515SBastian Koppelmann     env->PCXI &= ~(MASK_PCXI_UL);
20195de93515SBastian Koppelmann     /* PCXI[19: 0] = FCX[19: 0] */
20205de93515SBastian Koppelmann     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
20215de93515SBastian Koppelmann     /* FXC[19: 0] = new_FCX[19: 0] */
20225de93515SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
20235de93515SBastian Koppelmann     /* ICR.IE = 1 */
20245de93515SBastian Koppelmann     env->ICR |= MASK_ICR_IE;
20255de93515SBastian Koppelmann 
20265de93515SBastian Koppelmann     env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
20275de93515SBastian Koppelmann 
20285de93515SBastian Koppelmann     if (tmp_FCX == env->LCX) {
20295de93515SBastian Koppelmann         /* FCD trap */
20305de93515SBastian Koppelmann     }
20315de93515SBastian Koppelmann }
20325de93515SBastian Koppelmann 
203344ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env)
203444ea3430SBastian Koppelmann {
203544ea3430SBastian Koppelmann     target_ulong ea;
203644ea3430SBastian Koppelmann     target_ulong new_PCXI;
203744ea3430SBastian Koppelmann     target_ulong new_PSW;
203844ea3430SBastian Koppelmann     /* if (PCXI[19: 0] == 0) then trap(CSU); */
203944ea3430SBastian Koppelmann     if ((env->PCXI & 0xfffff) == 0) {
204044ea3430SBastian Koppelmann         /* raise csu trap */
204144ea3430SBastian Koppelmann     }
204244ea3430SBastian Koppelmann     /* if (PCXI.UL == 0) then trap(CTYP); */
204344ea3430SBastian Koppelmann     if ((env->PCXI & MASK_PCXI_UL) == 0) {
204444ea3430SBastian Koppelmann         /* raise CTYP trap */
204544ea3430SBastian Koppelmann     }
204644ea3430SBastian Koppelmann     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
204744ea3430SBastian Koppelmann     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
204844ea3430SBastian Koppelmann         /* raise MNG trap */
204944ea3430SBastian Koppelmann     }
205044ea3430SBastian Koppelmann     /* ICR.IE = PCXI.PIE; */
205144ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
205244ea3430SBastian Koppelmann     /* ICR.CCPN = PCXI.PCPN; */
205344ea3430SBastian Koppelmann     env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
205444ea3430SBastian Koppelmann                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
205544ea3430SBastian Koppelmann     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
205644ea3430SBastian Koppelmann     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
205744ea3430SBastian Koppelmann          ((env->PCXI & MASK_PCXI_PCXO) << 6);
205844ea3430SBastian Koppelmann     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2059030c58dfSBastian Koppelmann       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
206044ea3430SBastian Koppelmann     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2061030c58dfSBastian Koppelmann     /* M(EA, word) = FCX;*/
2062030c58dfSBastian Koppelmann     cpu_stl_data(env, ea, env->FCX);
206344ea3430SBastian Koppelmann     /* FCX[19: 0] = PCXI[19: 0]; */
206444ea3430SBastian Koppelmann     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
206544ea3430SBastian Koppelmann     /* PCXI = new_PCXI; */
206644ea3430SBastian Koppelmann     env->PCXI = new_PCXI;
206744ea3430SBastian Koppelmann     /* write psw */
206844ea3430SBastian Koppelmann     psw_write(env, new_PSW);
206944ea3430SBastian Koppelmann }
207044ea3430SBastian Koppelmann 
207159543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
207259543d4eSBastian Koppelmann {
207359543d4eSBastian Koppelmann     uint32_t dummy;
207459543d4eSBastian Koppelmann     /* insn doesn't load PCXI and RA */
207559543d4eSBastian Koppelmann     restore_context_lower(env, ea, &dummy, &dummy);
207659543d4eSBastian Koppelmann }
207759543d4eSBastian Koppelmann 
207859543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea)
207959543d4eSBastian Koppelmann {
208059543d4eSBastian Koppelmann     uint32_t dummy;
208159543d4eSBastian Koppelmann     /* insn doesn't load PCXI and PSW */
208259543d4eSBastian Koppelmann     restore_context_upper(env, ea, &dummy, &dummy);
208359543d4eSBastian Koppelmann }
208459543d4eSBastian Koppelmann 
208559543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
208659543d4eSBastian Koppelmann {
208759543d4eSBastian Koppelmann     save_context_lower(env, ea);
208859543d4eSBastian Koppelmann }
208959543d4eSBastian Koppelmann 
209059543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea)
209159543d4eSBastian Koppelmann {
209259543d4eSBastian Koppelmann     save_context_upper(env, ea);
209359543d4eSBastian Koppelmann }
209459543d4eSBastian Koppelmann 
20952b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
20962b2f7d97SBastian Koppelmann {
20972b2f7d97SBastian Koppelmann     psw_write(env, arg);
20982b2f7d97SBastian Koppelmann }
20992b2f7d97SBastian Koppelmann 
21002b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env)
21012b2f7d97SBastian Koppelmann {
21022b2f7d97SBastian Koppelmann     return psw_read(env);
21032b2f7d97SBastian Koppelmann }
21042b2f7d97SBastian Koppelmann 
21052b2f7d97SBastian Koppelmann 
21062d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
21072d30267eSBastian Koppelmann                                                         uint32_t exception,
21082d30267eSBastian Koppelmann                                                         int error_code,
21092d30267eSBastian Koppelmann                                                         uintptr_t pc)
21102d30267eSBastian Koppelmann {
21112d30267eSBastian Koppelmann     CPUState *cs = CPU(tricore_env_get_cpu(env));
21122d30267eSBastian Koppelmann     cs->exception_index = exception;
21132d30267eSBastian Koppelmann     env->error_code = error_code;
21142d30267eSBastian Koppelmann 
21152d30267eSBastian Koppelmann     if (pc) {
21162d30267eSBastian Koppelmann         /* now we have a real cpu fault */
21172d30267eSBastian Koppelmann         cpu_restore_state(cs, pc);
21182d30267eSBastian Koppelmann     }
21192d30267eSBastian Koppelmann 
21202d30267eSBastian Koppelmann     cpu_loop_exit(cs);
21212d30267eSBastian Koppelmann }
21222d30267eSBastian Koppelmann 
212348e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
212448e06fe0SBastian Koppelmann               uintptr_t retaddr)
212548e06fe0SBastian Koppelmann {
21262d30267eSBastian Koppelmann     int ret;
21272d30267eSBastian Koppelmann     ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
21282d30267eSBastian Koppelmann     if (ret) {
21292d30267eSBastian Koppelmann         TriCoreCPU *cpu = TRICORE_CPU(cs);
21302d30267eSBastian Koppelmann         CPUTriCoreState *env = &cpu->env;
21312d30267eSBastian Koppelmann         do_raise_exception_err(env, cs->exception_index,
21322d30267eSBastian Koppelmann                                env->error_code, retaddr);
213348e06fe0SBastian Koppelmann     }
21342d30267eSBastian Koppelmann }
2135