2
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
17
#include "qemu/osdep.h"
19
#include "qemu/host-utils.h"
20
#include "exec/helper-proto.h"
21
#include "exec/exec-all.h"
22
#include "exec/cpu_ldst.h"
23
#include <zlib.h> /* for crc32 */
26
/* Exception helpers */
28
static void QEMU_NORETURN
29
raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin,
30
uintptr_t pc, uint32_t fcd_pc)
32
CPUState *cs = CPU(tricore_env_get_cpu(env));
33
/* in case we come from a helper-call we need to restore the PC */
35
cpu_restore_state(cs, pc);
38
/* Tin is loaded into d[15] */
41
if (class == TRAPC_CTX_MNG && tin == TIN3_FCU) {
42
/* upper context cannot be saved, if the context list is empty */
47
/* The return address in a[11] is updated */
48
if (class == TRAPC_CTX_MNG && tin == TIN3_FCD) {
49
env->SYSCON |= MASK_SYSCON_FCD_SF;
50
/* when we run out of CSAs after saving a context a FCD trap is taken
51
and the return address is the start of the trap handler which used
53
env->gpr_a[11] = fcd_pc;
54
} else if (class == TRAPC_SYSCALL) {
55
env->gpr_a[11] = env->PC + 4;
57
env->gpr_a[11] = env->PC;
59
/* The stack pointer in A[10] is set to the Interrupt Stack Pointer (ISP)
60
when the processor was not previously using the interrupt stack
61
(in case of PSW.IS = 0). The stack pointer bit is set for using the
62
interrupt stack: PSW.IS = 1. */
63
if ((env->PSW & MASK_PSW_IS) == 0) {
64
env->gpr_a[10] = env->ISP;
66
env->PSW |= MASK_PSW_IS;
67
/* The I/O mode is set to Supervisor mode, which means all permissions
68
are enabled: PSW.IO = 10 B .*/
69
env->PSW |= (2 << 10);
71
/*The current Protection Register Set is set to 0: PSW.PRS = 00 B .*/
72
env->PSW &= ~MASK_PSW_PRS;
74
/* The Call Depth Counter (CDC) is cleared, and the call depth limit is
75
set for 64: PSW.CDC = 0000000 B .*/
76
env->PSW &= ~MASK_PSW_CDC;
78
/* Call Depth Counter is enabled, PSW.CDE = 1. */
79
env->PSW |= MASK_PSW_CDE;
81
/* Write permission to global registers A[0], A[1], A[8], A[9] is
82
disabled: PSW.GW = 0. */
83
env->PSW &= ~MASK_PSW_GW;
85
/*The interrupt system is globally disabled: ICR.IE = 0. The ‘old’
86
ICR.IE and ICR.CCPN are saved */
88
/* PCXI.PIE = ICR.IE */
89
env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
90
((env->ICR & MASK_ICR_IE) << 15));
91
/* PCXI.PCPN = ICR.CCPN */
92
env->PCXI = (env->PCXI & 0xffffff) +
93
((env->ICR & MASK_ICR_CCPN) << 24);
94
/* Update PC using the trap vector table */
95
env->PC = env->BTV | (class << 5);
100
void helper_raise_exception_sync(CPUTriCoreState *env, uint32_t class,
103
raise_exception_sync_internal(env, class, tin, 0, 0);
106
static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class,
107
uint32_t tin, uintptr_t pc)
109
raise_exception_sync_internal(env, class, tin, pc, 0);
112
/* Addressing mode helper */
114
static uint16_t reverse16(uint16_t val)
116
uint8_t high = (uint8_t)(val >> 8);
117
uint8_t low = (uint8_t)(val & 0xff);
121
rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
122
rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
124
return (rh << 8) | rl;
127
uint32_t helper_br_update(uint32_t reg)
129
uint32_t index = reg & 0xffff;
130
uint32_t incr = reg >> 16;
131
uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
132
return reg - index + new_index;
135
uint32_t helper_circ_update(uint32_t reg, uint32_t off)
137
uint32_t index = reg & 0xffff;
138
uint32_t length = reg >> 16;
139
int32_t new_index = index + off;
145
return reg - index + new_index;
148
static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
151
int64_t max_pos = INT32_MAX;
152
int64_t max_neg = INT32_MIN;
154
env->PSW_USB_V = (1 << 31);
155
env->PSW_USB_SV = (1 << 31);
156
ret = (target_ulong)max_pos;
159
env->PSW_USB_V = (1 << 31);
160
env->PSW_USB_SV = (1 << 31);
161
ret = (target_ulong)max_neg;
164
ret = (target_ulong)arg;
167
env->PSW_USB_AV = arg ^ arg * 2u;
168
env->PSW_USB_SAV |= env->PSW_USB_AV;
172
static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg)
175
uint64_t max_pos = UINT32_MAX;
177
env->PSW_USB_V = (1 << 31);
178
env->PSW_USB_SV = (1 << 31);
179
ret = (target_ulong)max_pos;
182
ret = (target_ulong)arg;
184
env->PSW_USB_AV = arg ^ arg * 2u;
185
env->PSW_USB_SAV |= env->PSW_USB_AV;
189
static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg)
194
env->PSW_USB_V = (1 << 31);
195
env->PSW_USB_SV = (1 << 31);
199
ret = (target_ulong)arg;
201
env->PSW_USB_AV = arg ^ arg * 2u;
202
env->PSW_USB_SAV |= env->PSW_USB_AV;
206
static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
208
int32_t max_pos = INT16_MAX;
209
int32_t max_neg = INT16_MIN;
213
av0 = hw0 ^ hw0 * 2u;
215
env->PSW_USB_V = (1 << 31);
217
} else if (hw0 < max_neg) {
218
env->PSW_USB_V = (1 << 31);
222
av1 = hw1 ^ hw1 * 2u;
224
env->PSW_USB_V = (1 << 31);
226
} else if (hw1 < max_neg) {
227
env->PSW_USB_V = (1 << 31);
231
env->PSW_USB_SV |= env->PSW_USB_V;
232
env->PSW_USB_AV = (av0 | av1) << 16;
233
env->PSW_USB_SAV |= env->PSW_USB_AV;
234
return (hw0 & 0xffff) | (hw1 << 16);
237
static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
239
int32_t max_pos = UINT16_MAX;
243
av0 = hw0 ^ hw0 * 2u;
245
env->PSW_USB_V = (1 << 31);
247
} else if (hw0 < 0) {
248
env->PSW_USB_V = (1 << 31);
252
av1 = hw1 ^ hw1 * 2u;
254
env->PSW_USB_V = (1 << 31);
256
} else if (hw1 < 0) {
257
env->PSW_USB_V = (1 << 31);
261
env->PSW_USB_SV |= env->PSW_USB_V;
262
env->PSW_USB_AV = (av0 | av1) << 16;
263
env->PSW_USB_SAV |= env->PSW_USB_AV;
264
return (hw0 & 0xffff) | (hw1 << 16);
267
target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
270
int64_t t1 = sextract64(r1, 0, 32);
271
int64_t t2 = sextract64(r2, 0, 32);
272
int64_t result = t1 + t2;
273
return ssov32(env, result);
276
uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
282
ovf = (result ^ r1) & ~(r1 ^ r2);
283
env->PSW_USB_AV = (result ^ result * 2u) >> 32;
284
env->PSW_USB_SAV |= env->PSW_USB_AV;
286
env->PSW_USB_V = (1 << 31);
287
env->PSW_USB_SV = (1 << 31);
288
/* ext_ret > MAX_INT */
289
if ((int64_t)r1 >= 0) {
291
/* ext_ret < MIN_INT */
301
target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
304
int32_t ret_hw0, ret_hw1;
306
ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16);
307
ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16);
308
return ssov16(env, ret_hw0, ret_hw1);
311
uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
314
int64_t mul_res0 = sextract64(r1, 0, 32);
315
int64_t mul_res1 = sextract64(r1, 32, 32);
316
int64_t r2_low = sextract64(r2_l, 0, 32);
317
int64_t r2_high = sextract64(r2_h, 0, 32);
318
int64_t result0, result1;
324
result0 = r2_low + mul_res0 + 0x8000;
325
result1 = r2_high + mul_res1 + 0x8000;
328
avf0 = result0 ^ avf0;
330
avf1 = result1 ^ avf1;
332
if (result0 > INT32_MAX) {
335
} else if (result0 < INT32_MIN) {
340
if (result1 > INT32_MAX) {
343
} else if (result1 < INT32_MIN) {
348
env->PSW_USB_V = ovf0 | ovf1;
349
env->PSW_USB_SV |= env->PSW_USB_V;
351
env->PSW_USB_AV = avf0 | avf1;
352
env->PSW_USB_SAV |= env->PSW_USB_AV;
354
return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
357
uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
360
int64_t mul_res0 = sextract64(r1, 0, 32);
361
int64_t mul_res1 = sextract64(r1, 32, 32);
362
int64_t r2_low = sextract64(r2_l, 0, 32);
363
int64_t r2_high = sextract64(r2_h, 0, 32);
364
int64_t result0, result1;
370
result0 = r2_low - mul_res0 + 0x8000;
371
result1 = r2_high + mul_res1 + 0x8000;
374
avf0 = result0 ^ avf0;
376
avf1 = result1 ^ avf1;
378
if (result0 > INT32_MAX) {
381
} else if (result0 < INT32_MIN) {
386
if (result1 > INT32_MAX) {
389
} else if (result1 < INT32_MIN) {
394
env->PSW_USB_V = ovf0 | ovf1;
395
env->PSW_USB_SV |= env->PSW_USB_V;
397
env->PSW_USB_AV = avf0 | avf1;
398
env->PSW_USB_SAV |= env->PSW_USB_AV;
400
return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
404
target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
407
int64_t t1 = extract64(r1, 0, 32);
408
int64_t t2 = extract64(r2, 0, 32);
409
int64_t result = t1 + t2;
410
return suov32_pos(env, result);
413
target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
416
int32_t ret_hw0, ret_hw1;
418
ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
419
ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
420
return suov16(env, ret_hw0, ret_hw1);
423
target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
426
int64_t t1 = sextract64(r1, 0, 32);
427
int64_t t2 = sextract64(r2, 0, 32);
428
int64_t result = t1 - t2;
429
return ssov32(env, result);
432
uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
438
ovf = (result ^ r1) & (r1 ^ r2);
439
env->PSW_USB_AV = (result ^ result * 2u) >> 32;
440
env->PSW_USB_SAV |= env->PSW_USB_AV;
442
env->PSW_USB_V = (1 << 31);
443
env->PSW_USB_SV = (1 << 31);
444
/* ext_ret > MAX_INT */
445
if ((int64_t)r1 >= 0) {
447
/* ext_ret < MIN_INT */
457
target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
460
int32_t ret_hw0, ret_hw1;
462
ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
463
ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
464
return ssov16(env, ret_hw0, ret_hw1);
467
uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
470
int64_t mul_res0 = sextract64(r1, 0, 32);
471
int64_t mul_res1 = sextract64(r1, 32, 32);
472
int64_t r2_low = sextract64(r2_l, 0, 32);
473
int64_t r2_high = sextract64(r2_h, 0, 32);
474
int64_t result0, result1;
480
result0 = r2_low - mul_res0 + 0x8000;
481
result1 = r2_high - mul_res1 + 0x8000;
484
avf0 = result0 ^ avf0;
486
avf1 = result1 ^ avf1;
488
if (result0 > INT32_MAX) {
491
} else if (result0 < INT32_MIN) {
496
if (result1 > INT32_MAX) {
499
} else if (result1 < INT32_MIN) {
504
env->PSW_USB_V = ovf0 | ovf1;
505
env->PSW_USB_SV |= env->PSW_USB_V;
507
env->PSW_USB_AV = avf0 | avf1;
508
env->PSW_USB_SAV |= env->PSW_USB_AV;
510
return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
513
uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
516
int64_t mul_res0 = sextract64(r1, 0, 32);
517
int64_t mul_res1 = sextract64(r1, 32, 32);
518
int64_t r2_low = sextract64(r2_l, 0, 32);
519
int64_t r2_high = sextract64(r2_h, 0, 32);
520
int64_t result0, result1;
526
result0 = r2_low + mul_res0 + 0x8000;
527
result1 = r2_high - mul_res1 + 0x8000;
530
avf0 = result0 ^ avf0;
532
avf1 = result1 ^ avf1;
534
if (result0 > INT32_MAX) {
537
} else if (result0 < INT32_MIN) {
542
if (result1 > INT32_MAX) {
545
} else if (result1 < INT32_MIN) {
550
env->PSW_USB_V = ovf0 | ovf1;
551
env->PSW_USB_SV |= env->PSW_USB_V;
553
env->PSW_USB_AV = avf0 | avf1;
554
env->PSW_USB_SAV |= env->PSW_USB_AV;
556
return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
559
target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
562
int64_t t1 = extract64(r1, 0, 32);
563
int64_t t2 = extract64(r2, 0, 32);
564
int64_t result = t1 - t2;
565
return suov32_neg(env, result);
568
target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
571
int32_t ret_hw0, ret_hw1;
573
ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
574
ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
575
return suov16(env, ret_hw0, ret_hw1);
578
target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
581
int64_t t1 = sextract64(r1, 0, 32);
582
int64_t t2 = sextract64(r2, 0, 32);
583
int64_t result = t1 * t2;
584
return ssov32(env, result);
587
target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
590
int64_t t1 = extract64(r1, 0, 32);
591
int64_t t2 = extract64(r2, 0, 32);
592
int64_t result = t1 * t2;
594
return suov32_pos(env, result);
597
target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
600
int64_t t1 = sextract64(r1, 0, 32);
601
int32_t t2 = sextract64(r2, 0, 6);
610
return ssov32(env, result);
613
uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
616
result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
617
return ssov32(env, result);
620
uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
622
int32_t ret_h0, ret_h1;
624
ret_h0 = sextract32(r1, 0, 16);
625
ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
627
ret_h1 = sextract32(r1, 16, 16);
628
ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
630
return ssov16(env, ret_h0, ret_h1);
633
target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
636
int64_t t1 = sextract64(r1, 0, 32);
637
int64_t t2 = sextract64(r2, 0, 32);
645
return ssov32(env, result);
648
uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
652
int32_t ret_h0, ret_h1;
654
t1 = sextract32(r1, 0, 16);
655
t2 = sextract32(r2, 0, 16);
662
t1 = sextract32(r1, 16, 16);
663
t2 = sextract32(r2, 16, 16);
670
return ssov16(env, ret_h0, ret_h1);
673
target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
674
target_ulong r2, target_ulong r3)
676
int64_t t1 = sextract64(r1, 0, 32);
677
int64_t t2 = sextract64(r2, 0, 32);
678
int64_t t3 = sextract64(r3, 0, 32);
681
result = t2 + (t1 * t3);
682
return ssov32(env, result);
685
target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
686
target_ulong r2, target_ulong r3)
688
uint64_t t1 = extract64(r1, 0, 32);
689
uint64_t t2 = extract64(r2, 0, 32);
690
uint64_t t3 = extract64(r3, 0, 32);
693
result = t2 + (t1 * t3);
694
return suov32_pos(env, result);
697
uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
698
uint64_t r2, target_ulong r3)
701
int64_t t1 = sextract64(r1, 0, 32);
702
int64_t t3 = sextract64(r3, 0, 32);
707
ovf = (ret ^ mul) & ~(mul ^ r2);
710
env->PSW_USB_AV = t1 ^ t1 * 2u;
711
env->PSW_USB_SAV |= env->PSW_USB_AV;
713
if ((int64_t)ovf < 0) {
714
env->PSW_USB_V = (1 << 31);
715
env->PSW_USB_SV = (1 << 31);
716
/* ext_ret > MAX_INT */
719
/* ext_ret < MIN_INT */
731
helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
737
env->PSW_USB_AV = (result ^ result * 2u);
738
env->PSW_USB_SAV |= env->PSW_USB_AV;
740
/* we do the saturation by hand, since we produce an overflow on the host
741
if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
742
case, we flip the saturated value. */
743
if (r2 == 0x8000000000000000LL) {
744
if (result > 0x7fffffffLL) {
745
env->PSW_USB_V = (1 << 31);
746
env->PSW_USB_SV = (1 << 31);
748
} else if (result < -0x80000000LL) {
749
env->PSW_USB_V = (1 << 31);
750
env->PSW_USB_SV = (1 << 31);
756
if (result > 0x7fffffffLL) {
757
env->PSW_USB_V = (1 << 31);
758
env->PSW_USB_SV = (1 << 31);
760
} else if (result < -0x80000000LL) {
761
env->PSW_USB_V = (1 << 31);
762
env->PSW_USB_SV = (1 << 31);
768
return (uint32_t)result;
771
uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
772
uint32_t r3, uint32_t n)
774
int64_t t1 = (int64_t)r1;
775
int64_t t2 = sextract64(r2, 0, 32);
776
int64_t t3 = sextract64(r3, 0, 32);
780
mul = (t2 * t3) << n;
783
env->PSW_USB_AV = (result ^ result * 2u) >> 32;
784
env->PSW_USB_SAV |= env->PSW_USB_AV;
786
ovf = (result ^ mul) & ~(mul ^ t1);
787
/* we do the saturation by hand, since we produce an overflow on the host
788
if the mul was (0x80000000 * 0x80000000) << 1). If this is the
789
case, we flip the saturated value. */
790
if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) {
792
env->PSW_USB_V = (1 << 31);
793
env->PSW_USB_SV = (1 << 31);
794
/* ext_ret > MAX_INT */
797
/* ext_ret < MIN_INT */
806
env->PSW_USB_V = (1 << 31);
807
env->PSW_USB_SV = (1 << 31);
808
/* ext_ret > MAX_INT */
811
/* ext_ret < MIN_INT */
819
return (uint64_t)result;
822
uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
823
uint32_t r3, uint32_t n)
825
int64_t t1 = sextract64(r1, 0, 32);
826
int64_t t2 = sextract64(r2, 0, 32);
827
int64_t t3 = sextract64(r3, 0, 32);
830
if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
833
mul = (t2 * t3) << n;
836
ret = t1 + mul + 0x8000;
838
env->PSW_USB_AV = ret ^ ret * 2u;
839
env->PSW_USB_SAV |= env->PSW_USB_AV;
841
if (ret > 0x7fffffffll) {
842
env->PSW_USB_V = (1 << 31);
843
env->PSW_USB_SV |= env->PSW_USB_V;
845
} else if (ret < -0x80000000ll) {
846
env->PSW_USB_V = (1 << 31);
847
env->PSW_USB_SV |= env->PSW_USB_V;
852
return ret & 0xffff0000ll;
855
uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
856
uint64_t r2, target_ulong r3)
859
uint64_t t1 = extract64(r1, 0, 32);
860
uint64_t t3 = extract64(r3, 0, 32);
866
env->PSW_USB_AV = t1 ^ t1 * 2u;
867
env->PSW_USB_SAV |= env->PSW_USB_AV;
870
env->PSW_USB_V = (1 << 31);
871
env->PSW_USB_SV = (1 << 31);
880
target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
881
target_ulong r2, target_ulong r3)
883
int64_t t1 = sextract64(r1, 0, 32);
884
int64_t t2 = sextract64(r2, 0, 32);
885
int64_t t3 = sextract64(r3, 0, 32);
888
result = t2 - (t1 * t3);
889
return ssov32(env, result);
892
target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
893
target_ulong r2, target_ulong r3)
895
uint64_t t1 = extract64(r1, 0, 32);
896
uint64_t t2 = extract64(r2, 0, 32);
897
uint64_t t3 = extract64(r3, 0, 32);
904
env->PSW_USB_AV = result ^ result * 2u;
905
env->PSW_USB_SAV |= env->PSW_USB_AV;
906
/* we calculate ovf by hand here, because the multiplication can overflow on
907
the host, which would give false results if we compare to less than
910
env->PSW_USB_V = (1 << 31);
911
env->PSW_USB_SV = (1 << 31);
919
uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
920
uint64_t r2, target_ulong r3)
923
int64_t t1 = sextract64(r1, 0, 32);
924
int64_t t3 = sextract64(r3, 0, 32);
929
ovf = (ret ^ r2) & (mul ^ r2);
932
env->PSW_USB_AV = t1 ^ t1 * 2u;
933
env->PSW_USB_SAV |= env->PSW_USB_AV;
935
if ((int64_t)ovf < 0) {
936
env->PSW_USB_V = (1 << 31);
937
env->PSW_USB_SV = (1 << 31);
938
/* ext_ret > MAX_INT */
941
/* ext_ret < MIN_INT */
951
uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
952
uint64_t r2, target_ulong r3)
955
uint64_t t1 = extract64(r1, 0, 32);
956
uint64_t t3 = extract64(r3, 0, 32);
962
env->PSW_USB_AV = t1 ^ t1 * 2u;
963
env->PSW_USB_SAV |= env->PSW_USB_AV;
966
env->PSW_USB_V = (1 << 31);
967
env->PSW_USB_SV = (1 << 31);
977
helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
980
int64_t t1 = (int64_t)r1;
981
int64_t t2 = (int64_t)r2;
985
env->PSW_USB_AV = (result ^ result * 2u);
986
env->PSW_USB_SAV |= env->PSW_USB_AV;
988
/* we do the saturation by hand, since we produce an overflow on the host
989
if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
990
case, we flip the saturated value. */
991
if (r2 == 0x8000000000000000LL) {
992
if (result > 0x7fffffffLL) {
993
env->PSW_USB_V = (1 << 31);
994
env->PSW_USB_SV = (1 << 31);
996
} else if (result < -0x80000000LL) {
997
env->PSW_USB_V = (1 << 31);
998
env->PSW_USB_SV = (1 << 31);
1004
if (result > 0x7fffffffLL) {
1005
env->PSW_USB_V = (1 << 31);
1006
env->PSW_USB_SV = (1 << 31);
1008
} else if (result < -0x80000000LL) {
1009
env->PSW_USB_V = (1 << 31);
1010
env->PSW_USB_SV = (1 << 31);
1016
return (uint32_t)result;
1019
uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
1020
uint32_t r3, uint32_t n)
1022
int64_t t1 = (int64_t)r1;
1023
int64_t t2 = sextract64(r2, 0, 32);
1024
int64_t t3 = sextract64(r3, 0, 32);
1025
int64_t result, mul;
1028
mul = (t2 * t3) << n;
1031
env->PSW_USB_AV = (result ^ result * 2u) >> 32;
1032
env->PSW_USB_SAV |= env->PSW_USB_AV;
1034
ovf = (result ^ t1) & (t1 ^ mul);
1035
/* we do the saturation by hand, since we produce an overflow on the host
1036
if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
1037
case, we flip the saturated value. */
1038
if (mul == 0x8000000000000000LL) {
1040
env->PSW_USB_V = (1 << 31);
1041
env->PSW_USB_SV = (1 << 31);
1042
/* ext_ret > MAX_INT */
1045
/* ext_ret < MIN_INT */
1054
env->PSW_USB_V = (1 << 31);
1055
env->PSW_USB_SV = (1 << 31);
1056
/* ext_ret > MAX_INT */
1059
/* ext_ret < MIN_INT */
1068
return (uint64_t)result;
1071
uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1072
uint32_t r3, uint32_t n)
1074
int64_t t1 = sextract64(r1, 0, 32);
1075
int64_t t2 = sextract64(r2, 0, 32);
1076
int64_t t3 = sextract64(r3, 0, 32);
1079
if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1082
mul = (t2 * t3) << n;
1085
ret = t1 - mul + 0x8000;
1087
env->PSW_USB_AV = ret ^ ret * 2u;
1088
env->PSW_USB_SAV |= env->PSW_USB_AV;
1090
if (ret > 0x7fffffffll) {
1091
env->PSW_USB_V = (1 << 31);
1092
env->PSW_USB_SV |= env->PSW_USB_V;
1094
} else if (ret < -0x80000000ll) {
1095
env->PSW_USB_V = (1 << 31);
1096
env->PSW_USB_SV |= env->PSW_USB_V;
1101
return ret & 0xffff0000ll;
1104
uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
1111
for (i = 0; i < 4; i++) {
1112
b = sextract32(arg, i * 8, 8);
1113
b = (b >= 0) ? b : (0 - b);
1114
ovf |= (b > 0x7F) || (b < -0x80);
1116
ret |= (b & 0xff) << (i * 8);
1119
env->PSW_USB_V = ovf << 31;
1120
env->PSW_USB_SV |= env->PSW_USB_V;
1121
env->PSW_USB_AV = avf << 24;
1122
env->PSW_USB_SAV |= env->PSW_USB_AV;
1127
uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
1134
for (i = 0; i < 2; i++) {
1135
h = sextract32(arg, i * 16, 16);
1136
h = (h >= 0) ? h : (0 - h);
1137
ovf |= (h > 0x7FFF) || (h < -0x8000);
1139
ret |= (h & 0xffff) << (i * 16);
1142
env->PSW_USB_V = ovf << 31;
1143
env->PSW_USB_SV |= env->PSW_USB_V;
1144
env->PSW_USB_AV = avf << 16;
1145
env->PSW_USB_SAV |= env->PSW_USB_AV;
1150
uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1158
for (i = 0; i < 4; i++) {
1159
extr_r2 = sextract32(r2, i * 8, 8);
1160
b = sextract32(r1, i * 8, 8);
1161
b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
1162
ovf |= (b > 0x7F) || (b < -0x80);
1164
ret |= (b & 0xff) << (i * 8);
1167
env->PSW_USB_V = ovf << 31;
1168
env->PSW_USB_SV |= env->PSW_USB_V;
1169
env->PSW_USB_AV = avf << 24;
1170
env->PSW_USB_SAV |= env->PSW_USB_AV;
1174
uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1182
for (i = 0; i < 2; i++) {
1183
extr_r2 = sextract32(r2, i * 16, 16);
1184
h = sextract32(r1, i * 16, 16);
1185
h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
1186
ovf |= (h > 0x7FFF) || (h < -0x8000);
1188
ret |= (h & 0xffff) << (i * 16);
1191
env->PSW_USB_V = ovf << 31;
1192
env->PSW_USB_SV |= env->PSW_USB_V;
1193
env->PSW_USB_AV = avf << 16;
1194
env->PSW_USB_SAV |= env->PSW_USB_AV;
1199
uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1202
int64_t mul_res0 = sextract64(r1, 0, 32);
1203
int64_t mul_res1 = sextract64(r1, 32, 32);
1204
int64_t r2_low = sextract64(r2_l, 0, 32);
1205
int64_t r2_high = sextract64(r2_h, 0, 32);
1206
int64_t result0, result1;
1207
uint32_t ovf0, ovf1;
1208
uint32_t avf0, avf1;
1212
result0 = r2_low + mul_res0 + 0x8000;
1213
result1 = r2_high + mul_res1 + 0x8000;
1215
if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1219
if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1223
env->PSW_USB_V = ovf0 | ovf1;
1224
env->PSW_USB_SV |= env->PSW_USB_V;
1226
avf0 = result0 * 2u;
1227
avf0 = result0 ^ avf0;
1228
avf1 = result1 * 2u;
1229
avf1 = result1 ^ avf1;
1231
env->PSW_USB_AV = avf0 | avf1;
1232
env->PSW_USB_SAV |= env->PSW_USB_AV;
1234
return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1237
uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1240
int64_t mul_res0 = sextract64(r1, 0, 32);
1241
int64_t mul_res1 = sextract64(r1, 32, 32);
1242
int64_t r2_low = sextract64(r2_l, 0, 32);
1243
int64_t r2_high = sextract64(r2_h, 0, 32);
1244
int64_t result0, result1;
1245
uint32_t ovf0, ovf1;
1246
uint32_t avf0, avf1;
1250
result0 = r2_low - mul_res0 + 0x8000;
1251
result1 = r2_high + mul_res1 + 0x8000;
1253
if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1257
if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1261
env->PSW_USB_V = ovf0 | ovf1;
1262
env->PSW_USB_SV |= env->PSW_USB_V;
1264
avf0 = result0 * 2u;
1265
avf0 = result0 ^ avf0;
1266
avf1 = result1 * 2u;
1267
avf1 = result1 ^ avf1;
1269
env->PSW_USB_AV = avf0 | avf1;
1270
env->PSW_USB_SAV |= env->PSW_USB_AV;
1272
return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1275
uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1276
uint32_t r3, uint32_t n)
1278
int64_t t1 = sextract64(r1, 0, 32);
1279
int64_t t2 = sextract64(r2, 0, 32);
1280
int64_t t3 = sextract64(r3, 0, 32);
1283
if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1286
mul = (t2 * t3) << n;
1289
ret = t1 + mul + 0x8000;
1291
if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1292
env->PSW_USB_V = (1 << 31);
1293
env->PSW_USB_SV |= env->PSW_USB_V;
1297
env->PSW_USB_AV = ret ^ ret * 2u;
1298
env->PSW_USB_SAV |= env->PSW_USB_AV;
1300
return ret & 0xffff0000ll;
1303
uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1306
int32_t extr_r1, extr_r2;
1311
for (i = 0; i < 4; i++) {
1312
extr_r1 = sextract32(r1, i * 8, 8);
1313
extr_r2 = sextract32(r2, i * 8, 8);
1315
b = extr_r1 + extr_r2;
1316
ovf |= ((b > 0x7f) || (b < -0x80));
1318
ret |= ((b & 0xff) << (i*8));
1321
env->PSW_USB_V = (ovf << 31);
1322
env->PSW_USB_SV |= env->PSW_USB_V;
1323
env->PSW_USB_AV = avf << 24;
1324
env->PSW_USB_SAV |= env->PSW_USB_AV;
1329
uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1332
int32_t extr_r1, extr_r2;
1337
for (i = 0; i < 2; i++) {
1338
extr_r1 = sextract32(r1, i * 16, 16);
1339
extr_r2 = sextract32(r2, i * 16, 16);
1340
h = extr_r1 + extr_r2;
1341
ovf |= ((h > 0x7fff) || (h < -0x8000));
1343
ret |= (h & 0xffff) << (i * 16);
1346
env->PSW_USB_V = (ovf << 31);
1347
env->PSW_USB_SV |= env->PSW_USB_V;
1348
env->PSW_USB_AV = (avf << 16);
1349
env->PSW_USB_SAV |= env->PSW_USB_AV;
1354
uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1357
int64_t mul_res0 = sextract64(r1, 0, 32);
1358
int64_t mul_res1 = sextract64(r1, 32, 32);
1359
int64_t r2_low = sextract64(r2_l, 0, 32);
1360
int64_t r2_high = sextract64(r2_h, 0, 32);
1361
int64_t result0, result1;
1362
uint32_t ovf0, ovf1;
1363
uint32_t avf0, avf1;
1367
result0 = r2_low - mul_res0 + 0x8000;
1368
result1 = r2_high - mul_res1 + 0x8000;
1370
if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1374
if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1378
env->PSW_USB_V = ovf0 | ovf1;
1379
env->PSW_USB_SV |= env->PSW_USB_V;
1381
avf0 = result0 * 2u;
1382
avf0 = result0 ^ avf0;
1383
avf1 = result1 * 2u;
1384
avf1 = result1 ^ avf1;
1386
env->PSW_USB_AV = avf0 | avf1;
1387
env->PSW_USB_SAV |= env->PSW_USB_AV;
1389
return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1392
uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1395
int64_t mul_res0 = sextract64(r1, 0, 32);
1396
int64_t mul_res1 = sextract64(r1, 32, 32);
1397
int64_t r2_low = sextract64(r2_l, 0, 32);
1398
int64_t r2_high = sextract64(r2_h, 0, 32);
1399
int64_t result0, result1;
1400
uint32_t ovf0, ovf1;
1401
uint32_t avf0, avf1;
1405
result0 = r2_low + mul_res0 + 0x8000;
1406
result1 = r2_high - mul_res1 + 0x8000;
1408
if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1412
if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1416
env->PSW_USB_V = ovf0 | ovf1;
1417
env->PSW_USB_SV |= env->PSW_USB_V;
1419
avf0 = result0 * 2u;
1420
avf0 = result0 ^ avf0;
1421
avf1 = result1 * 2u;
1422
avf1 = result1 ^ avf1;
1424
env->PSW_USB_AV = avf0 | avf1;
1425
env->PSW_USB_SAV |= env->PSW_USB_AV;
1427
return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1430
uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1431
uint32_t r3, uint32_t n)
1433
int64_t t1 = sextract64(r1, 0, 32);
1434
int64_t t2 = sextract64(r2, 0, 32);
1435
int64_t t3 = sextract64(r3, 0, 32);
1438
if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1441
mul = (t2 * t3) << n;
1444
ret = t1 - mul + 0x8000;
1446
if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1447
env->PSW_USB_V = (1 << 31);
1448
env->PSW_USB_SV |= env->PSW_USB_V;
1452
env->PSW_USB_AV = ret ^ ret * 2u;
1453
env->PSW_USB_SAV |= env->PSW_USB_AV;
1455
return ret & 0xffff0000ll;
1458
uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1461
int32_t extr_r1, extr_r2;
1466
for (i = 0; i < 4; i++) {
1467
extr_r1 = sextract32(r1, i * 8, 8);
1468
extr_r2 = sextract32(r2, i * 8, 8);
1470
b = extr_r1 - extr_r2;
1471
ovf |= ((b > 0x7f) || (b < -0x80));
1473
ret |= ((b & 0xff) << (i*8));
1476
env->PSW_USB_V = (ovf << 31);
1477
env->PSW_USB_SV |= env->PSW_USB_V;
1478
env->PSW_USB_AV = avf << 24;
1479
env->PSW_USB_SAV |= env->PSW_USB_AV;
1484
uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1487
int32_t extr_r1, extr_r2;
1492
for (i = 0; i < 2; i++) {
1493
extr_r1 = sextract32(r1, i * 16, 16);
1494
extr_r2 = sextract32(r2, i * 16, 16);
1495
h = extr_r1 - extr_r2;
1496
ovf |= ((h > 0x7fff) || (h < -0x8000));
1498
ret |= (h & 0xffff) << (i * 16);
1501
env->PSW_USB_V = (ovf << 31);
1502
env->PSW_USB_SV |= env->PSW_USB_V;
1503
env->PSW_USB_AV = avf << 16;
1504
env->PSW_USB_SAV |= env->PSW_USB_AV;
1509
uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
1516
for (i = 0; i < 4; i++) {
1517
if ((r1 & msk) == (r2 & msk)) {
1526
uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
1530
if ((r1 & 0xffff) == (r2 & 0xffff)) {
1534
if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
1541
uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
1546
for (i = 0; i < 4; i++) {
1547
ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8));
1553
uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
1557
ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16));
1558
ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16));
1563
uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
1568
for (i = 0; i < 4; i++) {
1569
if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) {
1570
ret |= (0xff << (i * 8));
1577
uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
1582
for (i = 0; i < 4; i++) {
1583
if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) {
1584
ret |= (0xff << (i * 8));
1591
uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
1595
if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) {
1599
if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) {
1606
uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
1610
if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) {
1614
if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) {
1621
#define EXTREMA_H_B(name, op) \
1622
uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
1624
int32_t i, extr_r1, extr_r2; \
1627
for (i = 0; i < 4; i++) { \
1628
extr_r1 = sextract32(r1, i * 8, 8); \
1629
extr_r2 = sextract32(r2, i * 8, 8); \
1630
extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1631
ret |= (extr_r1 & 0xff) << (i * 8); \
1636
uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
1639
uint32_t extr_r1, extr_r2; \
1642
for (i = 0; i < 4; i++) { \
1643
extr_r1 = extract32(r1, i * 8, 8); \
1644
extr_r2 = extract32(r2, i * 8, 8); \
1645
extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1646
ret |= (extr_r1 & 0xff) << (i * 8); \
1651
uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
1653
int32_t extr_r1, extr_r2; \
1656
extr_r1 = sextract32(r1, 0, 16); \
1657
extr_r2 = sextract32(r2, 0, 16); \
1658
ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1659
ret = ret & 0xffff; \
1661
extr_r1 = sextract32(r1, 16, 16); \
1662
extr_r2 = sextract32(r2, 16, 16); \
1663
extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1664
ret |= extr_r1 << 16; \
1669
uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
1671
uint32_t extr_r1, extr_r2; \
1674
extr_r1 = extract32(r1, 0, 16); \
1675
extr_r2 = extract32(r2, 0, 16); \
1676
ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1677
ret = ret & 0xffff; \
1679
extr_r1 = extract32(r1, 16, 16); \
1680
extr_r2 = extract32(r2, 16, 16); \
1681
extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1682
ret |= extr_r1 << (16); \
1687
uint64_t helper_ix##name(uint64_t r1, uint32_t r2) \
1689
int64_t r2l, r2h, r1hl; \
1692
ret = ((r1 + 2) & 0xffff); \
1693
r2l = sextract64(r2, 0, 16); \
1694
r2h = sextract64(r2, 16, 16); \
1695
r1hl = sextract64(r1, 32, 16); \
1697
if ((r2l op ## = r2h) && (r2l op r1hl)) { \
1698
ret |= (r2l & 0xffff) << 32; \
1699
ret |= extract64(r1, 0, 16) << 16; \
1700
} else if ((r2h op r2l) && (r2h op r1hl)) { \
1701
ret |= extract64(r2, 16, 16) << 32; \
1702
ret |= extract64(r1 + 1, 0, 16) << 16; \
1704
ret |= r1 & 0xffffffff0000ull; \
1709
uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2) \
1711
int64_t r2l, r2h, r1hl; \
1714
ret = ((r1 + 2) & 0xffff); \
1715
r2l = extract64(r2, 0, 16); \
1716
r2h = extract64(r2, 16, 16); \
1717
r1hl = extract64(r1, 32, 16); \
1719
if ((r2l op ## = r2h) && (r2l op r1hl)) { \
1720
ret |= (r2l & 0xffff) << 32; \
1721
ret |= extract64(r1, 0, 16) << 16; \
1722
} else if ((r2h op r2l) && (r2h op r1hl)) { \
1723
ret |= extract64(r2, 16, 16) << 32; \
1724
ret |= extract64(r1 + 1, 0, 16) << 16; \
1726
ret |= r1 & 0xffffffff0000ull; \
1736
uint32_t helper_clo_h(target_ulong r1)
1738
uint32_t ret_hw0 = extract32(r1, 0, 16);
1739
uint32_t ret_hw1 = extract32(r1, 16, 16);
1741
ret_hw0 = clo32(ret_hw0 << 16);
1742
ret_hw1 = clo32(ret_hw1 << 16);
1751
return ret_hw0 | (ret_hw1 << 16);
1754
uint32_t helper_clz_h(target_ulong r1)
1756
uint32_t ret_hw0 = extract32(r1, 0, 16);
1757
uint32_t ret_hw1 = extract32(r1, 16, 16);
1759
ret_hw0 = clz32(ret_hw0 << 16);
1760
ret_hw1 = clz32(ret_hw1 << 16);
1769
return ret_hw0 | (ret_hw1 << 16);
1772
uint32_t helper_cls_h(target_ulong r1)
1774
uint32_t ret_hw0 = extract32(r1, 0, 16);
1775
uint32_t ret_hw1 = extract32(r1, 16, 16);
1777
ret_hw0 = clrsb32(ret_hw0 << 16);
1778
ret_hw1 = clrsb32(ret_hw1 << 16);
1787
return ret_hw0 | (ret_hw1 << 16);
1790
uint32_t helper_sh(target_ulong r1, target_ulong r2)
1792
int32_t shift_count = sextract32(r2, 0, 6);
1794
if (shift_count == -32) {
1796
} else if (shift_count < 0) {
1797
return r1 >> -shift_count;
1799
return r1 << shift_count;
1803
uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
1805
int32_t ret_hw0, ret_hw1;
1806
int32_t shift_count;
1808
shift_count = sextract32(r2, 0, 5);
1810
if (shift_count == -16) {
1812
} else if (shift_count < 0) {
1813
ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
1814
ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
1815
return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1817
ret_hw0 = extract32(r1, 0, 16) << shift_count;
1818
ret_hw1 = extract32(r1, 16, 16) << shift_count;
1819
return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1823
uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1825
int32_t shift_count;
1829
shift_count = sextract32(r2, 0, 6);
1830
t1 = sextract32(r1, 0, 32);
1832
if (shift_count == 0) {
1833
env->PSW_USB_C = env->PSW_USB_V = 0;
1835
} else if (shift_count == -32) {
1836
env->PSW_USB_C = r1;
1839
} else if (shift_count > 0) {
1840
result = t1 << shift_count;
1842
env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
1844
env->PSW_USB_V = (((result > 0x7fffffffLL) ||
1845
(result < -0x80000000LL)) << 31);
1847
env->PSW_USB_SV |= env->PSW_USB_V;
1848
ret = (uint32_t)result;
1851
env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
1852
ret = t1 >> -shift_count;
1855
env->PSW_USB_AV = ret ^ ret * 2u;
1856
env->PSW_USB_SAV |= env->PSW_USB_AV;
1861
uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
1863
int32_t shift_count;
1864
int32_t ret_hw0, ret_hw1;
1866
shift_count = sextract32(r2, 0, 5);
1868
if (shift_count == 0) {
1870
} else if (shift_count < 0) {
1871
ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
1872
ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
1873
return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1875
ret_hw0 = sextract32(r1, 0, 16) << shift_count;
1876
ret_hw1 = sextract32(r1, 16, 16) << shift_count;
1877
return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1881
uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1886
for (i = 0; i < 16; i++) {
1887
ret |= (r1 & 1) << (2 * i + 1);
1888
ret |= (r2 & 1) << (2 * i);
1895
uint64_t helper_bsplit(uint32_t r1)
1901
for (i = 0; i < 32; i = i + 2) {
1903
ret |= (r1 & 1) << (i/2);
1906
ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1912
uint32_t helper_parity(target_ulong r1)
1919
for (i = 0; i < 8; i++) {
1925
for (i = 0; i < 8; i++) {
1932
for (i = 0; i < 8; i++) {
1939
for (i = 0; i < 8; i++) {
1948
uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
1952
int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
1953
int32_t int_exp = r1_high;
1954
int32_t int_mant = r1_low;
1955
uint32_t flag_rnd = (int_mant & (1 << 7)) && (
1956
(int_mant & (1 << 8)) ||
1957
(int_mant & 0x7f) ||
1959
if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
1961
fp_frac = extract32(int_mant, 8, 23);
1962
} else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
1965
} else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
1968
} else if (int_mant == 0) {
1972
if (((int_mant & (1 << 31)) == 0)) {
1975
temp_exp = int_exp + 128;
1977
fp_exp_frac = (((temp_exp & 0xff) << 23) |
1978
extract32(int_mant, 8, 23))
1980
fp_exp = extract32(fp_exp_frac, 23, 8);
1981
fp_frac = extract32(fp_exp_frac, 0, 23);
1983
ret = r2 & (1 << 31);
1984
ret = ret + (fp_exp << 23);
1985
ret = ret + (fp_frac & 0x7fffff);
1990
uint64_t helper_unpack(target_ulong arg1)
1992
int32_t fp_exp = extract32(arg1, 23, 8);
1993
int32_t fp_frac = extract32(arg1, 0, 23);
1995
int32_t int_exp, int_mant;
1997
if (fp_exp == 255) {
1999
int_mant = (fp_frac << 7);
2000
} else if ((fp_exp == 0) && (fp_frac == 0)) {
2003
} else if ((fp_exp == 0) && (fp_frac != 0)) {
2005
int_mant = (fp_frac << 7);
2007
int_exp = fp_exp - 127;
2008
int_mant = (fp_frac << 7);
2009
int_mant |= (1 << 30);
2018
uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2021
int32_t abs_sig_dividend, abs_divisor;
2023
ret = sextract32(r1, 0, 32);
2025
if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2029
abs_sig_dividend = abs((int32_t)r1) >> 8;
2030
abs_divisor = abs((int32_t)r2);
2032
ofv if (a/b >= 255) <=> (a/255 >= b) */
2033
env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2034
env->PSW_USB_V = env->PSW_USB_V << 31;
2035
env->PSW_USB_SV |= env->PSW_USB_V;
2036
env->PSW_USB_AV = 0;
2041
uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2043
uint64_t ret = sextract32(r1, 0, 32);
2046
if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2050
env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
2051
env->PSW_USB_V = env->PSW_USB_V << 31;
2052
env->PSW_USB_SV |= env->PSW_USB_V;
2053
env->PSW_USB_AV = 0;
2058
uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2061
int32_t abs_sig_dividend, abs_divisor;
2063
ret = sextract32(r1, 0, 32);
2065
if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2069
abs_sig_dividend = abs((int32_t)r1) >> 16;
2070
abs_divisor = abs((int32_t)r2);
2072
ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */
2073
env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2074
env->PSW_USB_V = env->PSW_USB_V << 31;
2075
env->PSW_USB_SV |= env->PSW_USB_V;
2076
env->PSW_USB_AV = 0;
2081
uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2083
uint64_t ret = sextract32(r1, 0, 32);
2086
if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2090
env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
2091
env->PSW_USB_V = env->PSW_USB_V << 31;
2092
env->PSW_USB_SV |= env->PSW_USB_V;
2093
env->PSW_USB_AV = 0;
2098
uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
2100
int32_t x_sign = (r1 >> 63);
2101
int32_t q_sign = x_sign ^ (r2 >> 31);
2102
int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
2103
int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
2107
if ((q_sign & ~eq_neg) | eq_pos) {
2108
quotient = (r1 + 1) & 0xffffffff;
2110
quotient = r1 & 0xffffffff;
2113
if (eq_pos | eq_neg) {
2116
remainder = (r1 & 0xffffffff00000000ull);
2118
return remainder | quotient;
2121
uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
2123
int32_t dividend_sign = extract64(r1, 63, 1);
2124
int32_t divisor_sign = extract32(r2, 31, 1);
2125
int32_t quotient_sign = (dividend_sign != divisor_sign);
2126
int32_t addend, dividend_quotient, remainder;
2129
if (quotient_sign) {
2134
dividend_quotient = (int32_t)r1;
2135
remainder = (int32_t)(r1 >> 32);
2137
for (i = 0; i < 8; i++) {
2138
remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2139
dividend_quotient <<= 1;
2140
temp = remainder + addend;
2141
if ((temp < 0) == dividend_sign) {
2144
if (((temp < 0) == dividend_sign)) {
2145
dividend_quotient = dividend_quotient | !quotient_sign;
2147
dividend_quotient = dividend_quotient | quotient_sign;
2150
return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2153
uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
2155
int32_t dividend_quotient = extract64(r1, 0, 32);
2156
int64_t remainder = extract64(r1, 32, 32);
2159
for (i = 0; i < 8; i++) {
2160
remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2161
dividend_quotient <<= 1;
2162
temp = (remainder & 0xffffffff) - r2;
2166
dividend_quotient = dividend_quotient | !(temp < 0);
2168
return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2171
uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2173
int32_t quotient, remainder;
2174
int32_t dividend = (int32_t)r1;
2175
int32_t divisor = (int32_t)r2;
2178
if (dividend >= 0) {
2179
quotient = 0x7fffffff;
2182
quotient = 0x80000000;
2185
env->PSW_USB_V = (1 << 31);
2186
} else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
2187
quotient = 0x7fffffff;
2189
env->PSW_USB_V = (1 << 31);
2191
remainder = dividend % divisor;
2192
quotient = (dividend - remainder)/divisor;
2195
env->PSW_USB_SV |= env->PSW_USB_V;
2196
env->PSW_USB_AV = 0;
2197
return ((uint64_t)remainder << 32) | (uint32_t)quotient;
2200
uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2202
uint32_t quotient, remainder;
2203
uint32_t dividend = r1;
2204
uint32_t divisor = r2;
2207
quotient = 0xffffffff;
2209
env->PSW_USB_V = (1 << 31);
2211
remainder = dividend % divisor;
2212
quotient = (dividend - remainder)/divisor;
2215
env->PSW_USB_SV |= env->PSW_USB_V;
2216
env->PSW_USB_AV = 0;
2217
return ((uint64_t)remainder << 32) | quotient;
2220
uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
2221
uint32_t arg10, uint32_t arg11, uint32_t n)
2223
uint32_t result0, result1;
2225
int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2226
((arg10 & 0xffff) == 0x8000) && (n == 1);
2227
int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2228
((arg11 & 0xffff) == 0x8000) && (n == 1);
2230
result1 = 0x7fffffff;
2232
result1 = (((uint32_t)(arg00 * arg10)) << n);
2235
result0 = 0x7fffffff;
2237
result0 = (((uint32_t)(arg01 * arg11)) << n);
2239
return (((uint64_t)result1 << 32)) | result0;
2242
uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
2243
uint32_t arg10, uint32_t arg11, uint32_t n)
2246
int64_t result0, result1;
2248
int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2249
((arg10 & 0xffff) == 0x8000) && (n == 1);
2250
int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2251
((arg11 & 0xffff) == 0x8000) && (n == 1);
2254
result1 = 0x7fffffff;
2256
result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
2259
result0 = 0x7fffffff;
2261
result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
2263
ret = (result1 + result0);
2267
uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
2268
uint32_t arg10, uint32_t arg11, uint32_t n)
2270
uint32_t result0, result1;
2272
int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2273
((arg10 & 0xffff) == 0x8000) && (n == 1);
2274
int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2275
((arg11 & 0xffff) == 0x8000) && (n == 1);
2278
result1 = 0x7fffffff;
2280
result1 = ((arg00 * arg10) << n) + 0x8000;
2283
result0 = 0x7fffffff;
2285
result0 = ((arg01 * arg11) << n) + 0x8000;
2287
return (result1 & 0xffff0000) | (result0 >> 16);
2290
uint32_t helper_crc32(uint32_t arg0, uint32_t arg1)
2293
stl_be_p(buf, arg0);
2295
return crc32(arg1, buf, 4);
2298
/* context save area (CSA) related helpers */
2300
static int cdc_increment(target_ulong *psw)
2302
if ((*psw & MASK_PSW_CDC) == 0x7f) {
2307
/* check for overflow */
2308
int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2309
int mask = (1u << (7 - lo)) - 1;
2310
int count = *psw & mask;
2318
static int cdc_decrement(target_ulong *psw)
2320
if ((*psw & MASK_PSW_CDC) == 0x7f) {
2323
/* check for underflow */
2324
int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2325
int mask = (1u << (7 - lo)) - 1;
2326
int count = *psw & mask;
2334
static bool cdc_zero(target_ulong *psw)
2336
int cdc = *psw & MASK_PSW_CDC;
2337
/* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
2338
7'b1111111, otherwise returns FALSE. */
2342
/* find CDC.COUNT */
2343
int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2344
int mask = (1u << (7 - lo)) - 1;
2345
int count = *psw & mask;
2349
static void save_context_upper(CPUTriCoreState *env, int ea)
2351
cpu_stl_data(env, ea, env->PCXI);
2352
cpu_stl_data(env, ea+4, psw_read(env));
2353
cpu_stl_data(env, ea+8, env->gpr_a[10]);
2354
cpu_stl_data(env, ea+12, env->gpr_a[11]);
2355
cpu_stl_data(env, ea+16, env->gpr_d[8]);
2356
cpu_stl_data(env, ea+20, env->gpr_d[9]);
2357
cpu_stl_data(env, ea+24, env->gpr_d[10]);
2358
cpu_stl_data(env, ea+28, env->gpr_d[11]);
2359
cpu_stl_data(env, ea+32, env->gpr_a[12]);
2360
cpu_stl_data(env, ea+36, env->gpr_a[13]);
2361
cpu_stl_data(env, ea+40, env->gpr_a[14]);
2362
cpu_stl_data(env, ea+44, env->gpr_a[15]);
2363
cpu_stl_data(env, ea+48, env->gpr_d[12]);
2364
cpu_stl_data(env, ea+52, env->gpr_d[13]);
2365
cpu_stl_data(env, ea+56, env->gpr_d[14]);
2366
cpu_stl_data(env, ea+60, env->gpr_d[15]);
2369
static void save_context_lower(CPUTriCoreState *env, int ea)
2371
cpu_stl_data(env, ea, env->PCXI);
2372
cpu_stl_data(env, ea+4, env->gpr_a[11]);
2373
cpu_stl_data(env, ea+8, env->gpr_a[2]);
2374
cpu_stl_data(env, ea+12, env->gpr_a[3]);
2375
cpu_stl_data(env, ea+16, env->gpr_d[0]);
2376
cpu_stl_data(env, ea+20, env->gpr_d[1]);
2377
cpu_stl_data(env, ea+24, env->gpr_d[2]);
2378
cpu_stl_data(env, ea+28, env->gpr_d[3]);
2379
cpu_stl_data(env, ea+32, env->gpr_a[4]);
2380
cpu_stl_data(env, ea+36, env->gpr_a[5]);
2381
cpu_stl_data(env, ea+40, env->gpr_a[6]);
2382
cpu_stl_data(env, ea+44, env->gpr_a[7]);
2383
cpu_stl_data(env, ea+48, env->gpr_d[4]);
2384
cpu_stl_data(env, ea+52, env->gpr_d[5]);
2385
cpu_stl_data(env, ea+56, env->gpr_d[6]);
2386
cpu_stl_data(env, ea+60, env->gpr_d[7]);
2389
static void restore_context_upper(CPUTriCoreState *env, int ea,
2390
target_ulong *new_PCXI, target_ulong *new_PSW)
2392
*new_PCXI = cpu_ldl_data(env, ea);
2393
*new_PSW = cpu_ldl_data(env, ea+4);
2394
env->gpr_a[10] = cpu_ldl_data(env, ea+8);
2395
env->gpr_a[11] = cpu_ldl_data(env, ea+12);
2396
env->gpr_d[8] = cpu_ldl_data(env, ea+16);
2397
env->gpr_d[9] = cpu_ldl_data(env, ea+20);
2398
env->gpr_d[10] = cpu_ldl_data(env, ea+24);
2399
env->gpr_d[11] = cpu_ldl_data(env, ea+28);
2400
env->gpr_a[12] = cpu_ldl_data(env, ea+32);
2401
env->gpr_a[13] = cpu_ldl_data(env, ea+36);
2402
env->gpr_a[14] = cpu_ldl_data(env, ea+40);
2403
env->gpr_a[15] = cpu_ldl_data(env, ea+44);
2404
env->gpr_d[12] = cpu_ldl_data(env, ea+48);
2405
env->gpr_d[13] = cpu_ldl_data(env, ea+52);
2406
env->gpr_d[14] = cpu_ldl_data(env, ea+56);
2407
env->gpr_d[15] = cpu_ldl_data(env, ea+60);
2410
static void restore_context_lower(CPUTriCoreState *env, int ea,
2411
target_ulong *ra, target_ulong *pcxi)
2413
*pcxi = cpu_ldl_data(env, ea);
2414
*ra = cpu_ldl_data(env, ea+4);
2415
env->gpr_a[2] = cpu_ldl_data(env, ea+8);
2416
env->gpr_a[3] = cpu_ldl_data(env, ea+12);
2417
env->gpr_d[0] = cpu_ldl_data(env, ea+16);
2418
env->gpr_d[1] = cpu_ldl_data(env, ea+20);
2419
env->gpr_d[2] = cpu_ldl_data(env, ea+24);
2420
env->gpr_d[3] = cpu_ldl_data(env, ea+28);
2421
env->gpr_a[4] = cpu_ldl_data(env, ea+32);
2422
env->gpr_a[5] = cpu_ldl_data(env, ea+36);
2423
env->gpr_a[6] = cpu_ldl_data(env, ea+40);
2424
env->gpr_a[7] = cpu_ldl_data(env, ea+44);
2425
env->gpr_d[4] = cpu_ldl_data(env, ea+48);
2426
env->gpr_d[5] = cpu_ldl_data(env, ea+52);
2427
env->gpr_d[6] = cpu_ldl_data(env, ea+56);
2428
env->gpr_d[7] = cpu_ldl_data(env, ea+60);
2431
void helper_call(CPUTriCoreState *env, uint32_t next_pc)
2433
target_ulong tmp_FCX;
2435
target_ulong new_FCX;
2438
psw = psw_read(env);
2439
/* if (FCX == 0) trap(FCU); */
2440
if (env->FCX == 0) {
2442
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2444
/* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
2445
if (psw & MASK_PSW_CDE) {
2446
if (cdc_increment(&psw)) {
2448
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC());
2452
psw |= MASK_PSW_CDE;
2453
/* tmp_FCX = FCX; */
2455
/* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2456
ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2457
((env->FCX & MASK_FCX_FCXO) << 6);
2458
/* new_FCX = M(EA, word); */
2459
new_FCX = cpu_ldl_data(env, ea);
2460
/* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2461
A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2463
save_context_upper(env, ea);
2465
/* PCXI.PCPN = ICR.CCPN; */
2466
env->PCXI = (env->PCXI & 0xffffff) +
2467
((env->ICR & MASK_ICR_CCPN) << 24);
2468
/* PCXI.PIE = ICR.IE; */
2469
env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2470
((env->ICR & MASK_ICR_IE) << 15));
2472
env->PCXI |= MASK_PCXI_UL;
2474
/* PCXI[19: 0] = FCX[19: 0]; */
2475
env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2476
/* FCX[19: 0] = new_FCX[19: 0]; */
2477
env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2478
/* A[11] = next_pc[31: 0]; */
2479
env->gpr_a[11] = next_pc;
2481
/* if (tmp_FCX == LCX) trap(FCD);*/
2482
if (tmp_FCX == env->LCX) {
2484
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2486
psw_write(env, psw);
2489
void helper_ret(CPUTriCoreState *env)
2492
target_ulong new_PCXI;
2493
target_ulong new_PSW, psw;
2495
psw = psw_read(env);
2496
/* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
2497
if (psw & MASK_PSW_CDE) {
2498
if (cdc_decrement(&psw)) {
2500
psw_write(env, psw);
2501
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC());
2504
/* if (PCXI[19: 0] == 0) then trap(CSU); */
2505
if ((env->PCXI & 0xfffff) == 0) {
2507
psw_write(env, psw);
2508
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2510
/* if (PCXI.UL == 0) then trap(CTYP); */
2511
if ((env->PCXI & MASK_PCXI_UL) == 0) {
2513
cdc_increment(&psw); /* restore to the start of helper */
2514
psw_write(env, psw);
2515
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2517
/* PC = {A11 [31: 1], 1’b0}; */
2518
env->PC = env->gpr_a[11] & 0xfffffffe;
2520
/* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2521
ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2522
((env->PCXI & MASK_PCXI_PCXO) << 6);
2523
/* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2524
A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2525
restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2526
/* M(EA, word) = FCX; */
2527
cpu_stl_data(env, ea, env->FCX);
2528
/* FCX[19: 0] = PCXI[19: 0]; */
2529
env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2530
/* PCXI = new_PCXI; */
2531
env->PCXI = new_PCXI;
2533
if (tricore_feature(env, TRICORE_FEATURE_13)) {
2535
psw_write(env, new_PSW);
2537
/* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
2538
psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
2542
void helper_bisr(CPUTriCoreState *env, uint32_t const9)
2544
target_ulong tmp_FCX;
2546
target_ulong new_FCX;
2548
if (env->FCX == 0) {
2550
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2554
ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
2556
/* new_FCX = M(EA, word); */
2557
new_FCX = cpu_ldl_data(env, ea);
2558
/* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2559
, A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2560
save_context_lower(env, ea);
2563
/* PCXI.PCPN = ICR.CCPN */
2564
env->PCXI = (env->PCXI & 0xffffff) +
2565
((env->ICR & MASK_ICR_CCPN) << 24);
2566
/* PCXI.PIE = ICR.IE */
2567
env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2568
((env->ICR & MASK_ICR_IE) << 15));
2570
env->PCXI &= ~(MASK_PCXI_UL);
2571
/* PCXI[19: 0] = FCX[19: 0] */
2572
env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2573
/* FXC[19: 0] = new_FCX[19: 0] */
2574
env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2576
env->ICR |= MASK_ICR_IE;
2578
env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
2580
if (tmp_FCX == env->LCX) {
2582
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2586
void helper_rfe(CPUTriCoreState *env)
2589
target_ulong new_PCXI;
2590
target_ulong new_PSW;
2591
/* if (PCXI[19: 0] == 0) then trap(CSU); */
2592
if ((env->PCXI & 0xfffff) == 0) {
2593
/* raise csu trap */
2594
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2596
/* if (PCXI.UL == 0) then trap(CTYP); */
2597
if ((env->PCXI & MASK_PCXI_UL) == 0) {
2598
/* raise CTYP trap */
2599
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2601
/* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
2602
if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
2603
/* raise NEST trap */
2604
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC());
2606
env->PC = env->gpr_a[11] & ~0x1;
2607
/* ICR.IE = PCXI.PIE; */
2608
env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
2609
/* ICR.CCPN = PCXI.PCPN; */
2610
env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
2611
((env->PCXI & MASK_PCXI_PCPN) >> 24);
2612
/*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
2613
ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2614
((env->PCXI & MASK_PCXI_PCXO) << 6);
2615
/*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2616
A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2617
restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2618
/* M(EA, word) = FCX;*/
2619
cpu_stl_data(env, ea, env->FCX);
2620
/* FCX[19: 0] = PCXI[19: 0]; */
2621
env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2622
/* PCXI = new_PCXI; */
2623
env->PCXI = new_PCXI;
2625
psw_write(env, new_PSW);
2628
void helper_rfm(CPUTriCoreState *env)
2630
env->PC = (env->gpr_a[11] & ~0x1);
2631
/* ICR.IE = PCXI.PIE; */
2632
env->ICR = (env->ICR & ~MASK_ICR_IE) |
2633
((env->PCXI & MASK_PCXI_PIE) >> 15);
2634
/* ICR.CCPN = PCXI.PCPN; */
2635
env->ICR = (env->ICR & ~MASK_ICR_CCPN) |
2636
((env->PCXI & MASK_PCXI_PCPN) >> 24);
2637
/* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */
2638
env->PCXI = cpu_ldl_data(env, env->DCX);
2639
psw_write(env, cpu_ldl_data(env, env->DCX+4));
2640
env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8);
2641
env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12);
2643
if (tricore_feature(env, TRICORE_FEATURE_131)) {
2648
void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
2651
/* insn doesn't load PCXI and RA */
2652
restore_context_lower(env, ea, &dummy, &dummy);
2655
void helper_lducx(CPUTriCoreState *env, uint32_t ea)
2658
/* insn doesn't load PCXI and PSW */
2659
restore_context_upper(env, ea, &dummy, &dummy);
2662
void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
2664
save_context_lower(env, ea);
2667
void helper_stucx(CPUTriCoreState *env, uint32_t ea)
2669
save_context_upper(env, ea);
2672
void helper_svlcx(CPUTriCoreState *env)
2674
target_ulong tmp_FCX;
2676
target_ulong new_FCX;
2678
if (env->FCX == 0) {
2680
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2682
/* tmp_FCX = FCX; */
2684
/* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2685
ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2686
((env->FCX & MASK_FCX_FCXO) << 6);
2687
/* new_FCX = M(EA, word); */
2688
new_FCX = cpu_ldl_data(env, ea);
2689
/* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2690
A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2692
save_context_lower(env, ea);
2694
/* PCXI.PCPN = ICR.CCPN; */
2695
env->PCXI = (env->PCXI & 0xffffff) +
2696
((env->ICR & MASK_ICR_CCPN) << 24);
2697
/* PCXI.PIE = ICR.IE; */
2698
env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2699
((env->ICR & MASK_ICR_IE) << 15));
2701
env->PCXI &= ~MASK_PCXI_UL;
2703
/* PCXI[19: 0] = FCX[19: 0]; */
2704
env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2705
/* FCX[19: 0] = new_FCX[19: 0]; */
2706
env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2708
/* if (tmp_FCX == LCX) trap(FCD);*/
2709
if (tmp_FCX == env->LCX) {
2711
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2715
void helper_svucx(CPUTriCoreState *env)
2717
target_ulong tmp_FCX;
2719
target_ulong new_FCX;
2721
if (env->FCX == 0) {
2723
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2725
/* tmp_FCX = FCX; */
2727
/* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2728
ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2729
((env->FCX & MASK_FCX_FCXO) << 6);
2730
/* new_FCX = M(EA, word); */
2731
new_FCX = cpu_ldl_data(env, ea);
2732
/* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2733
A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2735
save_context_upper(env, ea);
2737
/* PCXI.PCPN = ICR.CCPN; */
2738
env->PCXI = (env->PCXI & 0xffffff) +
2739
((env->ICR & MASK_ICR_CCPN) << 24);
2740
/* PCXI.PIE = ICR.IE; */
2741
env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2742
((env->ICR & MASK_ICR_IE) << 15));
2744
env->PCXI |= MASK_PCXI_UL;
2746
/* PCXI[19: 0] = FCX[19: 0]; */
2747
env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2748
/* FCX[19: 0] = new_FCX[19: 0]; */
2749
env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2751
/* if (tmp_FCX == LCX) trap(FCD);*/
2752
if (tmp_FCX == env->LCX) {
2754
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2758
void helper_rslcx(CPUTriCoreState *env)
2761
target_ulong new_PCXI;
2762
/* if (PCXI[19: 0] == 0) then trap(CSU); */
2763
if ((env->PCXI & 0xfffff) == 0) {
2765
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2767
/* if (PCXI.UL == 1) then trap(CTYP); */
2768
if ((env->PCXI & MASK_PCXI_UL) != 0) {
2770
raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2772
/* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2773
ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2774
((env->PCXI & MASK_PCXI_PCXO) << 6);
2775
/* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2776
A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2777
restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI);
2778
/* M(EA, word) = FCX; */
2779
cpu_stl_data(env, ea, env->FCX);
2780
/* M(EA, word) = FCX; */
2781
cpu_stl_data(env, ea, env->FCX);
2782
/* FCX[19: 0] = PCXI[19: 0]; */
2783
env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2784
/* PCXI = new_PCXI; */
2785
env->PCXI = new_PCXI;
2788
void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
2790
psw_write(env, arg);
2793
uint32_t helper_psw_read(CPUTriCoreState *env)
2795
return psw_read(env);
2799
static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
2804
CPUState *cs = CPU(tricore_env_get_cpu(env));
2805
cs->exception_index = exception;
2806
env->error_code = error_code;
2809
/* now we have a real cpu fault */
2810
cpu_restore_state(cs, pc);
2816
void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
2817
int mmu_idx, uintptr_t retaddr)
2820
ret = cpu_tricore_handle_mmu_fault(cs, addr, access_type, mmu_idx);
2822
TriCoreCPU *cpu = TRICORE_CPU(cs);
2823
CPUTriCoreState *env = &cpu->env;
2824
do_raise_exception_err(env, cs->exception_index,
2825
env->error_code, retaddr);