~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to target/tricore/op_helper.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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/>.
 
16
 */
 
17
#include "qemu/osdep.h"
 
18
#include "cpu.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 */
 
24
 
 
25
 
 
26
/* Exception helpers */
 
27
 
 
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)
 
31
{
 
32
    CPUState *cs = CPU(tricore_env_get_cpu(env));
 
33
    /* in case we come from a helper-call we need to restore the PC */
 
34
    if (pc) {
 
35
        cpu_restore_state(cs, pc);
 
36
    }
 
37
 
 
38
    /* Tin is loaded into d[15] */
 
39
    env->gpr_d[15] = tin;
 
40
 
 
41
    if (class == TRAPC_CTX_MNG && tin == TIN3_FCU) {
 
42
        /* upper context cannot be saved, if the context list is empty */
 
43
    } else {
 
44
        helper_svucx(env);
 
45
    }
 
46
 
 
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
 
52
           the last CSA */
 
53
        env->gpr_a[11] = fcd_pc;
 
54
    } else if (class == TRAPC_SYSCALL) {
 
55
        env->gpr_a[11] = env->PC + 4;
 
56
    } else {
 
57
        env->gpr_a[11] = env->PC;
 
58
    }
 
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;
 
65
    }
 
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);
 
70
 
 
71
    /*The current Protection Register Set is set to 0: PSW.PRS = 00 B .*/
 
72
    env->PSW &= ~MASK_PSW_PRS;
 
73
 
 
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;
 
77
 
 
78
    /* Call Depth Counter is enabled, PSW.CDE = 1. */
 
79
    env->PSW |= MASK_PSW_CDE;
 
80
 
 
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;
 
84
 
 
85
    /*The interrupt system is globally disabled: ICR.IE = 0. The ‘old’
 
86
      ICR.IE and ICR.CCPN are saved */
 
87
 
 
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);
 
96
 
 
97
    cpu_loop_exit(cs);
 
98
}
 
99
 
 
100
void helper_raise_exception_sync(CPUTriCoreState *env, uint32_t class,
 
101
                                 uint32_t tin)
 
102
{
 
103
    raise_exception_sync_internal(env, class, tin, 0, 0);
 
104
}
 
105
 
 
106
static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class,
 
107
                                        uint32_t tin, uintptr_t pc)
 
108
{
 
109
    raise_exception_sync_internal(env, class, tin, pc, 0);
 
110
}
 
111
 
 
112
/* Addressing mode helper */
 
113
 
 
114
static uint16_t reverse16(uint16_t val)
 
115
{
 
116
    uint8_t high = (uint8_t)(val >> 8);
 
117
    uint8_t low  = (uint8_t)(val & 0xff);
 
118
 
 
119
    uint16_t rh, rl;
 
120
 
 
121
    rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
 
122
    rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
 
123
 
 
124
    return (rh << 8) | rl;
 
125
}
 
126
 
 
127
uint32_t helper_br_update(uint32_t reg)
 
128
{
 
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;
 
133
}
 
134
 
 
135
uint32_t helper_circ_update(uint32_t reg, uint32_t off)
 
136
{
 
137
    uint32_t index = reg & 0xffff;
 
138
    uint32_t length = reg >> 16;
 
139
    int32_t new_index = index + off;
 
140
    if (new_index < 0) {
 
141
        new_index += length;
 
142
    } else {
 
143
        new_index %= length;
 
144
    }
 
145
    return reg - index + new_index;
 
146
}
 
147
 
 
148
static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
 
149
{
 
150
    uint32_t ret;
 
151
    int64_t max_pos = INT32_MAX;
 
152
    int64_t max_neg = INT32_MIN;
 
153
    if (arg > max_pos) {
 
154
        env->PSW_USB_V = (1 << 31);
 
155
        env->PSW_USB_SV = (1 << 31);
 
156
        ret = (target_ulong)max_pos;
 
157
    } else {
 
158
        if (arg < max_neg) {
 
159
            env->PSW_USB_V = (1 << 31);
 
160
            env->PSW_USB_SV = (1 << 31);
 
161
            ret = (target_ulong)max_neg;
 
162
        } else {
 
163
            env->PSW_USB_V = 0;
 
164
            ret = (target_ulong)arg;
 
165
        }
 
166
    }
 
167
    env->PSW_USB_AV = arg ^ arg * 2u;
 
168
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
169
    return ret;
 
170
}
 
171
 
 
172
static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg)
 
173
{
 
174
    uint32_t ret;
 
175
    uint64_t max_pos = UINT32_MAX;
 
176
    if (arg > max_pos) {
 
177
        env->PSW_USB_V = (1 << 31);
 
178
        env->PSW_USB_SV = (1 << 31);
 
179
        ret = (target_ulong)max_pos;
 
180
    } else {
 
181
        env->PSW_USB_V = 0;
 
182
        ret = (target_ulong)arg;
 
183
     }
 
184
    env->PSW_USB_AV = arg ^ arg * 2u;
 
185
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
186
    return ret;
 
187
}
 
188
 
 
189
static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg)
 
190
{
 
191
    uint32_t ret;
 
192
 
 
193
    if (arg < 0) {
 
194
        env->PSW_USB_V = (1 << 31);
 
195
        env->PSW_USB_SV = (1 << 31);
 
196
        ret = 0;
 
197
    } else {
 
198
        env->PSW_USB_V = 0;
 
199
        ret = (target_ulong)arg;
 
200
    }
 
201
    env->PSW_USB_AV = arg ^ arg * 2u;
 
202
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
203
    return ret;
 
204
}
 
205
 
 
206
static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
 
207
{
 
208
    int32_t max_pos = INT16_MAX;
 
209
    int32_t max_neg = INT16_MIN;
 
210
    int32_t av0, av1;
 
211
 
 
212
    env->PSW_USB_V = 0;
 
213
    av0 = hw0 ^ hw0 * 2u;
 
214
    if (hw0 > max_pos) {
 
215
        env->PSW_USB_V = (1 << 31);
 
216
        hw0 = max_pos;
 
217
    } else if (hw0 < max_neg) {
 
218
        env->PSW_USB_V = (1 << 31);
 
219
        hw0 = max_neg;
 
220
    }
 
221
 
 
222
    av1 = hw1 ^ hw1 * 2u;
 
223
    if (hw1 > max_pos) {
 
224
        env->PSW_USB_V = (1 << 31);
 
225
        hw1 = max_pos;
 
226
    } else if (hw1 < max_neg) {
 
227
        env->PSW_USB_V = (1 << 31);
 
228
        hw1 = max_neg;
 
229
    }
 
230
 
 
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);
 
235
}
 
236
 
 
237
static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
 
238
{
 
239
    int32_t max_pos = UINT16_MAX;
 
240
    int32_t av0, av1;
 
241
 
 
242
    env->PSW_USB_V = 0;
 
243
    av0 = hw0 ^ hw0 * 2u;
 
244
    if (hw0 > max_pos) {
 
245
        env->PSW_USB_V = (1 << 31);
 
246
        hw0 = max_pos;
 
247
    } else if (hw0 < 0) {
 
248
        env->PSW_USB_V = (1 << 31);
 
249
        hw0 = 0;
 
250
    }
 
251
 
 
252
    av1 = hw1 ^ hw1 * 2u;
 
253
    if (hw1 > max_pos) {
 
254
        env->PSW_USB_V = (1 << 31);
 
255
        hw1 = max_pos;
 
256
    } else if (hw1 < 0) {
 
257
        env->PSW_USB_V = (1 << 31);
 
258
        hw1 = 0;
 
259
    }
 
260
 
 
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);
 
265
}
 
266
 
 
267
target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
 
268
                             target_ulong r2)
 
269
{
 
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);
 
274
}
 
275
 
 
276
uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
 
277
{
 
278
    uint64_t result;
 
279
    int64_t ovf;
 
280
 
 
281
    result = r1 + 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;
 
285
    if (ovf < 0) {
 
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) {
 
290
            result = INT64_MAX;
 
291
        /* ext_ret < MIN_INT */
 
292
        } else {
 
293
            result = INT64_MIN;
 
294
        }
 
295
    } else {
 
296
        env->PSW_USB_V = 0;
 
297
    }
 
298
    return result;
 
299
}
 
300
 
 
301
target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
 
302
                               target_ulong r2)
 
303
{
 
304
    int32_t ret_hw0, ret_hw1;
 
305
 
 
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);
 
309
}
 
310
 
 
311
uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 
312
                            uint32_t r2_h)
 
313
{
 
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;
 
319
    uint32_t ovf0, ovf1;
 
320
    uint32_t avf0, avf1;
 
321
 
 
322
    ovf0 = ovf1 = 0;
 
323
 
 
324
    result0 = r2_low + mul_res0 + 0x8000;
 
325
    result1 = r2_high + mul_res1 + 0x8000;
 
326
 
 
327
    avf0 = result0 * 2u;
 
328
    avf0 = result0 ^ avf0;
 
329
    avf1 = result1 * 2u;
 
330
    avf1 = result1 ^ avf1;
 
331
 
 
332
    if (result0 > INT32_MAX) {
 
333
        ovf0 = (1 << 31);
 
334
        result0 = INT32_MAX;
 
335
    } else if (result0 < INT32_MIN) {
 
336
        ovf0 = (1 << 31);
 
337
        result0 = INT32_MIN;
 
338
    }
 
339
 
 
340
    if (result1 > INT32_MAX) {
 
341
        ovf1 = (1 << 31);
 
342
        result1 = INT32_MAX;
 
343
    } else if (result1 < INT32_MIN) {
 
344
        ovf1 = (1 << 31);
 
345
        result1 = INT32_MIN;
 
346
    }
 
347
 
 
348
    env->PSW_USB_V = ovf0 | ovf1;
 
349
    env->PSW_USB_SV |= env->PSW_USB_V;
 
350
 
 
351
    env->PSW_USB_AV = avf0 | avf1;
 
352
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
353
 
 
354
    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 
355
}
 
356
 
 
357
uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 
358
                              uint32_t r2_h)
 
359
{
 
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;
 
365
    uint32_t ovf0, ovf1;
 
366
    uint32_t avf0, avf1;
 
367
 
 
368
    ovf0 = ovf1 = 0;
 
369
 
 
370
    result0 = r2_low - mul_res0 + 0x8000;
 
371
    result1 = r2_high + mul_res1 + 0x8000;
 
372
 
 
373
    avf0 = result0 * 2u;
 
374
    avf0 = result0 ^ avf0;
 
375
    avf1 = result1 * 2u;
 
376
    avf1 = result1 ^ avf1;
 
377
 
 
378
    if (result0 > INT32_MAX) {
 
379
        ovf0 = (1 << 31);
 
380
        result0 = INT32_MAX;
 
381
    } else if (result0 < INT32_MIN) {
 
382
        ovf0 = (1 << 31);
 
383
        result0 = INT32_MIN;
 
384
    }
 
385
 
 
386
    if (result1 > INT32_MAX) {
 
387
        ovf1 = (1 << 31);
 
388
        result1 = INT32_MAX;
 
389
    } else if (result1 < INT32_MIN) {
 
390
        ovf1 = (1 << 31);
 
391
        result1 = INT32_MIN;
 
392
    }
 
393
 
 
394
    env->PSW_USB_V = ovf0 | ovf1;
 
395
    env->PSW_USB_SV |= env->PSW_USB_V;
 
396
 
 
397
    env->PSW_USB_AV = avf0 | avf1;
 
398
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
399
 
 
400
    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 
401
}
 
402
 
 
403
 
 
404
target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
 
405
                             target_ulong r2)
 
406
{
 
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);
 
411
}
 
412
 
 
413
target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
 
414
                               target_ulong r2)
 
415
{
 
416
    int32_t ret_hw0, ret_hw1;
 
417
 
 
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);
 
421
}
 
422
 
 
423
target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
 
424
                             target_ulong r2)
 
425
{
 
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);
 
430
}
 
431
 
 
432
uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
 
433
{
 
434
    uint64_t result;
 
435
    int64_t ovf;
 
436
 
 
437
    result = r1 - 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;
 
441
    if (ovf < 0) {
 
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) {
 
446
            result = INT64_MAX;
 
447
        /* ext_ret < MIN_INT */
 
448
        } else {
 
449
            result = INT64_MIN;
 
450
        }
 
451
    } else {
 
452
        env->PSW_USB_V = 0;
 
453
    }
 
454
    return result;
 
455
}
 
456
 
 
457
target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
 
458
                             target_ulong r2)
 
459
{
 
460
    int32_t ret_hw0, ret_hw1;
 
461
 
 
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);
 
465
}
 
466
 
 
467
uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 
468
                            uint32_t r2_h)
 
469
{
 
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;
 
475
    uint32_t ovf0, ovf1;
 
476
    uint32_t avf0, avf1;
 
477
 
 
478
    ovf0 = ovf1 = 0;
 
479
 
 
480
    result0 = r2_low - mul_res0 + 0x8000;
 
481
    result1 = r2_high - mul_res1 + 0x8000;
 
482
 
 
483
    avf0 = result0 * 2u;
 
484
    avf0 = result0 ^ avf0;
 
485
    avf1 = result1 * 2u;
 
486
    avf1 = result1 ^ avf1;
 
487
 
 
488
    if (result0 > INT32_MAX) {
 
489
        ovf0 = (1 << 31);
 
490
        result0 = INT32_MAX;
 
491
    } else if (result0 < INT32_MIN) {
 
492
        ovf0 = (1 << 31);
 
493
        result0 = INT32_MIN;
 
494
    }
 
495
 
 
496
    if (result1 > INT32_MAX) {
 
497
        ovf1 = (1 << 31);
 
498
        result1 = INT32_MAX;
 
499
    } else if (result1 < INT32_MIN) {
 
500
        ovf1 = (1 << 31);
 
501
        result1 = INT32_MIN;
 
502
    }
 
503
 
 
504
    env->PSW_USB_V = ovf0 | ovf1;
 
505
    env->PSW_USB_SV |= env->PSW_USB_V;
 
506
 
 
507
    env->PSW_USB_AV = avf0 | avf1;
 
508
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
509
 
 
510
    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 
511
}
 
512
 
 
513
uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 
514
                              uint32_t r2_h)
 
515
{
 
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;
 
521
    uint32_t ovf0, ovf1;
 
522
    uint32_t avf0, avf1;
 
523
 
 
524
    ovf0 = ovf1 = 0;
 
525
 
 
526
    result0 = r2_low + mul_res0 + 0x8000;
 
527
    result1 = r2_high - mul_res1 + 0x8000;
 
528
 
 
529
    avf0 = result0 * 2u;
 
530
    avf0 = result0 ^ avf0;
 
531
    avf1 = result1 * 2u;
 
532
    avf1 = result1 ^ avf1;
 
533
 
 
534
    if (result0 > INT32_MAX) {
 
535
        ovf0 = (1 << 31);
 
536
        result0 = INT32_MAX;
 
537
    } else if (result0 < INT32_MIN) {
 
538
        ovf0 = (1 << 31);
 
539
        result0 = INT32_MIN;
 
540
    }
 
541
 
 
542
    if (result1 > INT32_MAX) {
 
543
        ovf1 = (1 << 31);
 
544
        result1 = INT32_MAX;
 
545
    } else if (result1 < INT32_MIN) {
 
546
        ovf1 = (1 << 31);
 
547
        result1 = INT32_MIN;
 
548
    }
 
549
 
 
550
    env->PSW_USB_V = ovf0 | ovf1;
 
551
    env->PSW_USB_SV |= env->PSW_USB_V;
 
552
 
 
553
    env->PSW_USB_AV = avf0 | avf1;
 
554
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
555
 
 
556
    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 
557
}
 
558
 
 
559
target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
 
560
                             target_ulong r2)
 
561
{
 
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);
 
566
}
 
567
 
 
568
target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
 
569
                               target_ulong r2)
 
570
{
 
571
    int32_t ret_hw0, ret_hw1;
 
572
 
 
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);
 
576
}
 
577
 
 
578
target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
 
579
                             target_ulong r2)
 
580
{
 
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);
 
585
}
 
586
 
 
587
target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
 
588
                             target_ulong r2)
 
589
{
 
590
    int64_t t1 = extract64(r1, 0, 32);
 
591
    int64_t t2 = extract64(r2, 0, 32);
 
592
    int64_t result = t1 * t2;
 
593
 
 
594
    return suov32_pos(env, result);
 
595
}
 
596
 
 
597
target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
 
598
                             target_ulong r2)
 
599
{
 
600
    int64_t t1 = sextract64(r1, 0, 32);
 
601
    int32_t t2 = sextract64(r2, 0, 6);
 
602
    int64_t result;
 
603
    if (t2 == 0) {
 
604
        result = t1;
 
605
    } else if (t2 > 0) {
 
606
        result = t1 << t2;
 
607
    } else {
 
608
        result = t1 >> -t2;
 
609
    }
 
610
    return ssov32(env, result);
 
611
}
 
612
 
 
613
uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
 
614
{
 
615
    target_ulong result;
 
616
    result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
 
617
    return ssov32(env, result);
 
618
}
 
619
 
 
620
uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
 
621
{
 
622
    int32_t ret_h0, ret_h1;
 
623
 
 
624
    ret_h0 = sextract32(r1, 0, 16);
 
625
    ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
 
626
 
 
627
    ret_h1 = sextract32(r1, 16, 16);
 
628
    ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
 
629
 
 
630
    return ssov16(env, ret_h0, ret_h1);
 
631
}
 
632
 
 
633
target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
 
634
                                target_ulong r2)
 
635
{
 
636
    int64_t t1 = sextract64(r1, 0, 32);
 
637
    int64_t t2 = sextract64(r2, 0, 32);
 
638
    int64_t result;
 
639
 
 
640
    if (t1 > t2) {
 
641
        result = t1 - t2;
 
642
    } else {
 
643
        result = t2 - t1;
 
644
    }
 
645
    return ssov32(env, result);
 
646
}
 
647
 
 
648
uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
 
649
                              target_ulong r2)
 
650
{
 
651
    int32_t t1, t2;
 
652
    int32_t ret_h0, ret_h1;
 
653
 
 
654
    t1 = sextract32(r1, 0, 16);
 
655
    t2 = sextract32(r2, 0, 16);
 
656
    if (t1 > t2) {
 
657
        ret_h0 = t1 - t2;
 
658
    } else {
 
659
        ret_h0 = t2 - t1;
 
660
    }
 
661
 
 
662
    t1 = sextract32(r1, 16, 16);
 
663
    t2 = sextract32(r2, 16, 16);
 
664
    if (t1 > t2) {
 
665
        ret_h1 = t1 - t2;
 
666
    } else {
 
667
        ret_h1 = t2 - t1;
 
668
    }
 
669
 
 
670
    return ssov16(env, ret_h0, ret_h1);
 
671
}
 
672
 
 
673
target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
 
674
                                target_ulong r2, target_ulong r3)
 
675
{
 
676
    int64_t t1 = sextract64(r1, 0, 32);
 
677
    int64_t t2 = sextract64(r2, 0, 32);
 
678
    int64_t t3 = sextract64(r3, 0, 32);
 
679
    int64_t result;
 
680
 
 
681
    result = t2 + (t1 * t3);
 
682
    return ssov32(env, result);
 
683
}
 
684
 
 
685
target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
 
686
                                target_ulong r2, target_ulong r3)
 
687
{
 
688
    uint64_t t1 = extract64(r1, 0, 32);
 
689
    uint64_t t2 = extract64(r2, 0, 32);
 
690
    uint64_t t3 = extract64(r3, 0, 32);
 
691
    int64_t result;
 
692
 
 
693
    result = t2 + (t1 * t3);
 
694
    return suov32_pos(env, result);
 
695
}
 
696
 
 
697
uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
 
698
                            uint64_t r2, target_ulong r3)
 
699
{
 
700
    uint64_t ret, ovf;
 
701
    int64_t t1 = sextract64(r1, 0, 32);
 
702
    int64_t t3 = sextract64(r3, 0, 32);
 
703
    int64_t mul;
 
704
 
 
705
    mul = t1 * t3;
 
706
    ret = mul + r2;
 
707
    ovf = (ret ^ mul) & ~(mul ^ r2);
 
708
 
 
709
    t1 = ret >> 32;
 
710
    env->PSW_USB_AV = t1 ^ t1 * 2u;
 
711
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
712
 
 
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 */
 
717
        if (mul >= 0) {
 
718
            ret = INT64_MAX;
 
719
        /* ext_ret < MIN_INT */
 
720
        } else {
 
721
            ret = INT64_MIN;
 
722
        }
 
723
    } else {
 
724
        env->PSW_USB_V = 0;
 
725
    }
 
726
 
 
727
    return ret;
 
728
}
 
729
 
 
730
uint32_t
 
731
helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
 
732
{
 
733
    int64_t result;
 
734
 
 
735
    result = (r1 + r2);
 
736
 
 
737
    env->PSW_USB_AV = (result ^ result * 2u);
 
738
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
739
 
 
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);
 
747
            result = INT32_MIN;
 
748
        } else if (result < -0x80000000LL) {
 
749
            env->PSW_USB_V = (1 << 31);
 
750
            env->PSW_USB_SV = (1 << 31);
 
751
            result = INT32_MAX;
 
752
        } else {
 
753
            env->PSW_USB_V = 0;
 
754
        }
 
755
    } else {
 
756
        if (result > 0x7fffffffLL) {
 
757
            env->PSW_USB_V = (1 << 31);
 
758
            env->PSW_USB_SV = (1 << 31);
 
759
            result = INT32_MAX;
 
760
        } else if (result < -0x80000000LL) {
 
761
            env->PSW_USB_V = (1 << 31);
 
762
            env->PSW_USB_SV = (1 << 31);
 
763
            result = INT32_MIN;
 
764
        } else {
 
765
            env->PSW_USB_V = 0;
 
766
        }
 
767
    }
 
768
    return (uint32_t)result;
 
769
}
 
770
 
 
771
uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
 
772
                              uint32_t r3, uint32_t n)
 
773
{
 
774
    int64_t t1 = (int64_t)r1;
 
775
    int64_t t2 = sextract64(r2, 0, 32);
 
776
    int64_t t3 = sextract64(r3, 0, 32);
 
777
    int64_t result, mul;
 
778
    int64_t ovf;
 
779
 
 
780
    mul = (t2 * t3) << n;
 
781
    result = mul + t1;
 
782
 
 
783
    env->PSW_USB_AV = (result ^ result * 2u) >> 32;
 
784
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
785
 
 
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)) {
 
791
        if (ovf >= 0) {
 
792
            env->PSW_USB_V = (1 << 31);
 
793
            env->PSW_USB_SV = (1 << 31);
 
794
            /* ext_ret > MAX_INT */
 
795
            if (mul < 0) {
 
796
                result = INT64_MAX;
 
797
            /* ext_ret < MIN_INT */
 
798
            } else {
 
799
               result = INT64_MIN;
 
800
            }
 
801
        } else {
 
802
            env->PSW_USB_V = 0;
 
803
        }
 
804
    } else {
 
805
        if (ovf < 0) {
 
806
            env->PSW_USB_V = (1 << 31);
 
807
            env->PSW_USB_SV = (1 << 31);
 
808
            /* ext_ret > MAX_INT */
 
809
            if (mul >= 0) {
 
810
                result = INT64_MAX;
 
811
            /* ext_ret < MIN_INT */
 
812
            } else {
 
813
               result = INT64_MIN;
 
814
            }
 
815
        } else {
 
816
            env->PSW_USB_V = 0;
 
817
        }
 
818
    }
 
819
    return (uint64_t)result;
 
820
}
 
821
 
 
822
uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
 
823
                             uint32_t r3, uint32_t n)
 
824
{
 
825
    int64_t t1 = sextract64(r1, 0, 32);
 
826
    int64_t t2 = sextract64(r2, 0, 32);
 
827
    int64_t t3 = sextract64(r3, 0, 32);
 
828
    int64_t mul, ret;
 
829
 
 
830
    if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
 
831
        mul = 0x7fffffff;
 
832
    } else {
 
833
        mul = (t2 * t3) << n;
 
834
    }
 
835
 
 
836
    ret = t1 + mul + 0x8000;
 
837
 
 
838
    env->PSW_USB_AV = ret ^ ret * 2u;
 
839
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
840
 
 
841
    if (ret > 0x7fffffffll) {
 
842
        env->PSW_USB_V = (1 << 31);
 
843
        env->PSW_USB_SV |= env->PSW_USB_V;
 
844
        ret = INT32_MAX;
 
845
    } else if (ret < -0x80000000ll) {
 
846
        env->PSW_USB_V = (1 << 31);
 
847
        env->PSW_USB_SV |= env->PSW_USB_V;
 
848
        ret = INT32_MIN;
 
849
    } else {
 
850
        env->PSW_USB_V = 0;
 
851
    }
 
852
    return ret & 0xffff0000ll;
 
853
}
 
854
 
 
855
uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
 
856
                            uint64_t r2, target_ulong r3)
 
857
{
 
858
    uint64_t ret, mul;
 
859
    uint64_t t1 = extract64(r1, 0, 32);
 
860
    uint64_t t3 = extract64(r3, 0, 32);
 
861
 
 
862
    mul = t1 * t3;
 
863
    ret = mul + r2;
 
864
 
 
865
    t1 = ret >> 32;
 
866
    env->PSW_USB_AV = t1 ^ t1 * 2u;
 
867
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
868
 
 
869
    if (ret < r2) {
 
870
        env->PSW_USB_V = (1 << 31);
 
871
        env->PSW_USB_SV = (1 << 31);
 
872
        /* saturate */
 
873
        ret = UINT64_MAX;
 
874
    } else {
 
875
        env->PSW_USB_V = 0;
 
876
    }
 
877
    return ret;
 
878
}
 
879
 
 
880
target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
 
881
                                target_ulong r2, target_ulong r3)
 
882
{
 
883
    int64_t t1 = sextract64(r1, 0, 32);
 
884
    int64_t t2 = sextract64(r2, 0, 32);
 
885
    int64_t t3 = sextract64(r3, 0, 32);
 
886
    int64_t result;
 
887
 
 
888
    result = t2 - (t1 * t3);
 
889
    return ssov32(env, result);
 
890
}
 
891
 
 
892
target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
 
893
                                target_ulong r2, target_ulong r3)
 
894
{
 
895
    uint64_t t1 = extract64(r1, 0, 32);
 
896
    uint64_t t2 = extract64(r2, 0, 32);
 
897
    uint64_t t3 = extract64(r3, 0, 32);
 
898
    uint64_t result;
 
899
    uint64_t mul;
 
900
 
 
901
    mul = (t1 * t3);
 
902
    result = t2 - mul;
 
903
 
 
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
 
908
       zero */
 
909
    if (mul > t2) {
 
910
        env->PSW_USB_V = (1 << 31);
 
911
        env->PSW_USB_SV = (1 << 31);
 
912
        result = 0;
 
913
    } else {
 
914
        env->PSW_USB_V = 0;
 
915
    }
 
916
    return result;
 
917
}
 
918
 
 
919
uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
 
920
                            uint64_t r2, target_ulong r3)
 
921
{
 
922
    uint64_t ret, ovf;
 
923
    int64_t t1 = sextract64(r1, 0, 32);
 
924
    int64_t t3 = sextract64(r3, 0, 32);
 
925
    int64_t mul;
 
926
 
 
927
    mul = t1 * t3;
 
928
    ret = r2 - mul;
 
929
    ovf = (ret ^ r2) & (mul ^ r2);
 
930
 
 
931
    t1 = ret >> 32;
 
932
    env->PSW_USB_AV = t1 ^ t1 * 2u;
 
933
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
934
 
 
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 */
 
939
        if (mul < 0) {
 
940
            ret = INT64_MAX;
 
941
        /* ext_ret < MIN_INT */
 
942
        } else {
 
943
            ret = INT64_MIN;
 
944
        }
 
945
    } else {
 
946
        env->PSW_USB_V = 0;
 
947
    }
 
948
    return ret;
 
949
}
 
950
 
 
951
uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
 
952
                            uint64_t r2, target_ulong r3)
 
953
{
 
954
    uint64_t ret, mul;
 
955
    uint64_t t1 = extract64(r1, 0, 32);
 
956
    uint64_t t3 = extract64(r3, 0, 32);
 
957
 
 
958
    mul = t1 * t3;
 
959
    ret = r2 - mul;
 
960
 
 
961
    t1 = ret >> 32;
 
962
    env->PSW_USB_AV = t1 ^ t1 * 2u;
 
963
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
964
 
 
965
    if (ret > r2) {
 
966
        env->PSW_USB_V = (1 << 31);
 
967
        env->PSW_USB_SV = (1 << 31);
 
968
        /* saturate */
 
969
        ret = 0;
 
970
    } else {
 
971
        env->PSW_USB_V = 0;
 
972
    }
 
973
    return ret;
 
974
}
 
975
 
 
976
uint32_t
 
977
helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
 
978
{
 
979
    int64_t result;
 
980
    int64_t t1 = (int64_t)r1;
 
981
    int64_t t2 = (int64_t)r2;
 
982
 
 
983
    result = t1 - t2;
 
984
 
 
985
    env->PSW_USB_AV = (result ^ result * 2u);
 
986
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
987
 
 
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);
 
995
            result = INT32_MIN;
 
996
        } else if (result < -0x80000000LL) {
 
997
            env->PSW_USB_V = (1 << 31);
 
998
            env->PSW_USB_SV = (1 << 31);
 
999
            result = INT32_MAX;
 
1000
        } else {
 
1001
            env->PSW_USB_V = 0;
 
1002
        }
 
1003
    } else {
 
1004
        if (result > 0x7fffffffLL) {
 
1005
            env->PSW_USB_V = (1 << 31);
 
1006
            env->PSW_USB_SV = (1 << 31);
 
1007
            result = INT32_MAX;
 
1008
        } else if (result < -0x80000000LL) {
 
1009
            env->PSW_USB_V = (1 << 31);
 
1010
            env->PSW_USB_SV = (1 << 31);
 
1011
            result = INT32_MIN;
 
1012
        } else {
 
1013
            env->PSW_USB_V = 0;
 
1014
        }
 
1015
    }
 
1016
    return (uint32_t)result;
 
1017
}
 
1018
 
 
1019
uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
 
1020
                              uint32_t r3, uint32_t n)
 
1021
{
 
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;
 
1026
    int64_t ovf;
 
1027
 
 
1028
    mul = (t2 * t3) << n;
 
1029
    result = t1 - mul;
 
1030
 
 
1031
    env->PSW_USB_AV = (result ^ result * 2u) >> 32;
 
1032
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
1033
 
 
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) {
 
1039
        if (ovf >= 0) {
 
1040
            env->PSW_USB_V = (1 << 31);
 
1041
            env->PSW_USB_SV = (1 << 31);
 
1042
            /* ext_ret > MAX_INT */
 
1043
            if (mul >= 0) {
 
1044
                result = INT64_MAX;
 
1045
            /* ext_ret < MIN_INT */
 
1046
            } else {
 
1047
               result = INT64_MIN;
 
1048
            }
 
1049
        } else {
 
1050
            env->PSW_USB_V = 0;
 
1051
        }
 
1052
    } else {
 
1053
        if (ovf < 0) {
 
1054
            env->PSW_USB_V = (1 << 31);
 
1055
            env->PSW_USB_SV = (1 << 31);
 
1056
            /* ext_ret > MAX_INT */
 
1057
            if (mul < 0) {
 
1058
                result = INT64_MAX;
 
1059
            /* ext_ret < MIN_INT */
 
1060
            } else {
 
1061
               result = INT64_MIN;
 
1062
            }
 
1063
        } else {
 
1064
            env->PSW_USB_V = 0;
 
1065
        }
 
1066
    }
 
1067
 
 
1068
    return (uint64_t)result;
 
1069
}
 
1070
 
 
1071
uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
 
1072
                             uint32_t r3, uint32_t n)
 
1073
{
 
1074
    int64_t t1 = sextract64(r1, 0, 32);
 
1075
    int64_t t2 = sextract64(r2, 0, 32);
 
1076
    int64_t t3 = sextract64(r3, 0, 32);
 
1077
    int64_t mul, ret;
 
1078
 
 
1079
    if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
 
1080
        mul = 0x7fffffff;
 
1081
    } else {
 
1082
        mul = (t2 * t3) << n;
 
1083
    }
 
1084
 
 
1085
    ret = t1 - mul + 0x8000;
 
1086
 
 
1087
    env->PSW_USB_AV = ret ^ ret * 2u;
 
1088
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
1089
 
 
1090
    if (ret > 0x7fffffffll) {
 
1091
        env->PSW_USB_V = (1 << 31);
 
1092
        env->PSW_USB_SV |= env->PSW_USB_V;
 
1093
        ret = INT32_MAX;
 
1094
    } else if (ret < -0x80000000ll) {
 
1095
        env->PSW_USB_V = (1 << 31);
 
1096
        env->PSW_USB_SV |= env->PSW_USB_V;
 
1097
        ret = INT32_MIN;
 
1098
    } else {
 
1099
        env->PSW_USB_V = 0;
 
1100
    }
 
1101
    return ret & 0xffff0000ll;
 
1102
}
 
1103
 
 
1104
uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
 
1105
{
 
1106
    int32_t b, i;
 
1107
    int32_t ovf = 0;
 
1108
    int32_t avf = 0;
 
1109
    int32_t ret = 0;
 
1110
 
 
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);
 
1115
        avf |= b ^ b * 2u;
 
1116
        ret |= (b & 0xff) << (i * 8);
 
1117
    }
 
1118
 
 
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;
 
1123
 
 
1124
    return ret;
 
1125
}
 
1126
 
 
1127
uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
 
1128
{
 
1129
    int32_t h, i;
 
1130
    int32_t ovf = 0;
 
1131
    int32_t avf = 0;
 
1132
    int32_t ret = 0;
 
1133
 
 
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);
 
1138
        avf |= h ^ h * 2u;
 
1139
        ret |= (h & 0xffff) << (i * 16);
 
1140
    }
 
1141
 
 
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;
 
1146
 
 
1147
    return ret;
 
1148
}
 
1149
 
 
1150
uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
 
1151
{
 
1152
    int32_t b, i;
 
1153
    int32_t extr_r2;
 
1154
    int32_t ovf = 0;
 
1155
    int32_t avf = 0;
 
1156
    int32_t ret = 0;
 
1157
 
 
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);
 
1163
        avf |= b ^ b * 2u;
 
1164
        ret |= (b & 0xff) << (i * 8);
 
1165
    }
 
1166
 
 
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;
 
1171
    return ret;
 
1172
}
 
1173
 
 
1174
uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
 
1175
{
 
1176
    int32_t h, i;
 
1177
    int32_t extr_r2;
 
1178
    int32_t ovf = 0;
 
1179
    int32_t avf = 0;
 
1180
    int32_t ret = 0;
 
1181
 
 
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);
 
1187
        avf |= h ^ h * 2u;
 
1188
        ret |= (h & 0xffff) << (i * 16);
 
1189
    }
 
1190
 
 
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;
 
1195
 
 
1196
    return ret;
 
1197
}
 
1198
 
 
1199
uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 
1200
                       uint32_t r2_h)
 
1201
{
 
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;
 
1209
 
 
1210
    ovf0 = ovf1 = 0;
 
1211
 
 
1212
    result0 = r2_low + mul_res0 + 0x8000;
 
1213
    result1 = r2_high + mul_res1 + 0x8000;
 
1214
 
 
1215
    if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
 
1216
        ovf0 = (1 << 31);
 
1217
    }
 
1218
 
 
1219
    if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
 
1220
        ovf1 = (1 << 31);
 
1221
    }
 
1222
 
 
1223
    env->PSW_USB_V = ovf0 | ovf1;
 
1224
    env->PSW_USB_SV |= env->PSW_USB_V;
 
1225
 
 
1226
    avf0 = result0 * 2u;
 
1227
    avf0 = result0 ^ avf0;
 
1228
    avf1 = result1 * 2u;
 
1229
    avf1 = result1 ^ avf1;
 
1230
 
 
1231
    env->PSW_USB_AV = avf0 | avf1;
 
1232
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
1233
 
 
1234
    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 
1235
}
 
1236
 
 
1237
uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 
1238
                         uint32_t r2_h)
 
1239
{
 
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;
 
1247
 
 
1248
    ovf0 = ovf1 = 0;
 
1249
 
 
1250
    result0 = r2_low - mul_res0 + 0x8000;
 
1251
    result1 = r2_high + mul_res1 + 0x8000;
 
1252
 
 
1253
    if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
 
1254
        ovf0 = (1 << 31);
 
1255
    }
 
1256
 
 
1257
    if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
 
1258
        ovf1 = (1 << 31);
 
1259
    }
 
1260
 
 
1261
    env->PSW_USB_V = ovf0 | ovf1;
 
1262
    env->PSW_USB_SV |= env->PSW_USB_V;
 
1263
 
 
1264
    avf0 = result0 * 2u;
 
1265
    avf0 = result0 ^ avf0;
 
1266
    avf1 = result1 * 2u;
 
1267
    avf1 = result1 ^ avf1;
 
1268
 
 
1269
    env->PSW_USB_AV = avf0 | avf1;
 
1270
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
1271
 
 
1272
    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 
1273
}
 
1274
 
 
1275
uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
 
1276
                        uint32_t r3, uint32_t n)
 
1277
{
 
1278
    int64_t t1 = sextract64(r1, 0, 32);
 
1279
    int64_t t2 = sextract64(r2, 0, 32);
 
1280
    int64_t t3 = sextract64(r3, 0, 32);
 
1281
    int64_t mul, ret;
 
1282
 
 
1283
    if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
 
1284
        mul = 0x7fffffff;
 
1285
    } else {
 
1286
        mul = (t2 * t3) << n;
 
1287
    }
 
1288
 
 
1289
    ret = t1 + mul + 0x8000;
 
1290
 
 
1291
    if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
 
1292
        env->PSW_USB_V = (1 << 31);
 
1293
        env->PSW_USB_SV |= env->PSW_USB_V;
 
1294
    } else {
 
1295
        env->PSW_USB_V = 0;
 
1296
    }
 
1297
    env->PSW_USB_AV = ret ^ ret * 2u;
 
1298
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
1299
 
 
1300
    return ret & 0xffff0000ll;
 
1301
}
 
1302
 
 
1303
uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
 
1304
{
 
1305
    int32_t b, i;
 
1306
    int32_t extr_r1, extr_r2;
 
1307
    int32_t ovf = 0;
 
1308
    int32_t avf = 0;
 
1309
    uint32_t ret = 0;
 
1310
 
 
1311
    for (i = 0; i < 4; i++) {
 
1312
        extr_r1 = sextract32(r1, i * 8, 8);
 
1313
        extr_r2 = sextract32(r2, i * 8, 8);
 
1314
 
 
1315
        b = extr_r1 + extr_r2;
 
1316
        ovf |= ((b > 0x7f) || (b < -0x80));
 
1317
        avf |= b ^ b * 2u;
 
1318
        ret |= ((b & 0xff) << (i*8));
 
1319
    }
 
1320
 
 
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;
 
1325
 
 
1326
    return ret;
 
1327
}
 
1328
 
 
1329
uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
 
1330
{
 
1331
    int32_t h, i;
 
1332
    int32_t extr_r1, extr_r2;
 
1333
    int32_t ovf = 0;
 
1334
    int32_t avf = 0;
 
1335
    int32_t ret = 0;
 
1336
 
 
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));
 
1342
        avf |= h ^ h * 2u;
 
1343
        ret |= (h & 0xffff) << (i * 16);
 
1344
    }
 
1345
 
 
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;
 
1350
 
 
1351
    return ret;
 
1352
}
 
1353
 
 
1354
uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 
1355
                       uint32_t r2_h)
 
1356
{
 
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;
 
1364
 
 
1365
    ovf0 = ovf1 = 0;
 
1366
 
 
1367
    result0 = r2_low - mul_res0 + 0x8000;
 
1368
    result1 = r2_high - mul_res1 + 0x8000;
 
1369
 
 
1370
    if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
 
1371
        ovf0 = (1 << 31);
 
1372
    }
 
1373
 
 
1374
    if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
 
1375
        ovf1 = (1 << 31);
 
1376
    }
 
1377
 
 
1378
    env->PSW_USB_V = ovf0 | ovf1;
 
1379
    env->PSW_USB_SV |= env->PSW_USB_V;
 
1380
 
 
1381
    avf0 = result0 * 2u;
 
1382
    avf0 = result0 ^ avf0;
 
1383
    avf1 = result1 * 2u;
 
1384
    avf1 = result1 ^ avf1;
 
1385
 
 
1386
    env->PSW_USB_AV = avf0 | avf1;
 
1387
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
1388
 
 
1389
    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 
1390
}
 
1391
 
 
1392
uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 
1393
                         uint32_t r2_h)
 
1394
{
 
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;
 
1402
 
 
1403
    ovf0 = ovf1 = 0;
 
1404
 
 
1405
    result0 = r2_low + mul_res0 + 0x8000;
 
1406
    result1 = r2_high - mul_res1 + 0x8000;
 
1407
 
 
1408
    if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
 
1409
        ovf0 = (1 << 31);
 
1410
    }
 
1411
 
 
1412
    if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
 
1413
        ovf1 = (1 << 31);
 
1414
    }
 
1415
 
 
1416
    env->PSW_USB_V = ovf0 | ovf1;
 
1417
    env->PSW_USB_SV |= env->PSW_USB_V;
 
1418
 
 
1419
    avf0 = result0 * 2u;
 
1420
    avf0 = result0 ^ avf0;
 
1421
    avf1 = result1 * 2u;
 
1422
    avf1 = result1 ^ avf1;
 
1423
 
 
1424
    env->PSW_USB_AV = avf0 | avf1;
 
1425
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
1426
 
 
1427
    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 
1428
}
 
1429
 
 
1430
uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
 
1431
                        uint32_t r3, uint32_t n)
 
1432
{
 
1433
    int64_t t1 = sextract64(r1, 0, 32);
 
1434
    int64_t t2 = sextract64(r2, 0, 32);
 
1435
    int64_t t3 = sextract64(r3, 0, 32);
 
1436
    int64_t mul, ret;
 
1437
 
 
1438
    if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
 
1439
        mul = 0x7fffffff;
 
1440
    } else {
 
1441
        mul = (t2 * t3) << n;
 
1442
    }
 
1443
 
 
1444
    ret = t1 - mul + 0x8000;
 
1445
 
 
1446
    if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
 
1447
        env->PSW_USB_V = (1 << 31);
 
1448
        env->PSW_USB_SV |= env->PSW_USB_V;
 
1449
    } else {
 
1450
        env->PSW_USB_V = 0;
 
1451
    }
 
1452
    env->PSW_USB_AV = ret ^ ret * 2u;
 
1453
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
1454
 
 
1455
    return ret & 0xffff0000ll;
 
1456
}
 
1457
 
 
1458
uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
 
1459
{
 
1460
    int32_t b, i;
 
1461
    int32_t extr_r1, extr_r2;
 
1462
    int32_t ovf = 0;
 
1463
    int32_t avf = 0;
 
1464
    uint32_t ret = 0;
 
1465
 
 
1466
    for (i = 0; i < 4; i++) {
 
1467
        extr_r1 = sextract32(r1, i * 8, 8);
 
1468
        extr_r2 = sextract32(r2, i * 8, 8);
 
1469
 
 
1470
        b = extr_r1 - extr_r2;
 
1471
        ovf |= ((b > 0x7f) || (b < -0x80));
 
1472
        avf |= b ^ b * 2u;
 
1473
        ret |= ((b & 0xff) << (i*8));
 
1474
    }
 
1475
 
 
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;
 
1480
 
 
1481
    return ret;
 
1482
}
 
1483
 
 
1484
uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
 
1485
{
 
1486
    int32_t h, i;
 
1487
    int32_t extr_r1, extr_r2;
 
1488
    int32_t ovf = 0;
 
1489
    int32_t avf = 0;
 
1490
    int32_t ret = 0;
 
1491
 
 
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));
 
1497
        avf |= h ^ h * 2u;
 
1498
        ret |= (h & 0xffff) << (i * 16);
 
1499
    }
 
1500
 
 
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;
 
1505
 
 
1506
    return ret;
 
1507
}
 
1508
 
 
1509
uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
 
1510
{
 
1511
    int32_t ret;
 
1512
    int32_t i, msk;
 
1513
 
 
1514
    ret = 0;
 
1515
    msk = 0xff;
 
1516
    for (i = 0; i < 4; i++) {
 
1517
        if ((r1 & msk) == (r2 & msk)) {
 
1518
            ret |= msk;
 
1519
        }
 
1520
        msk = msk << 8;
 
1521
    }
 
1522
 
 
1523
    return ret;
 
1524
}
 
1525
 
 
1526
uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
 
1527
{
 
1528
    int32_t ret = 0;
 
1529
 
 
1530
    if ((r1 & 0xffff) == (r2 & 0xffff)) {
 
1531
        ret = 0xffff;
 
1532
    }
 
1533
 
 
1534
    if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
 
1535
        ret |= 0xffff0000;
 
1536
    }
 
1537
 
 
1538
    return ret;
 
1539
}
 
1540
 
 
1541
uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
 
1542
{
 
1543
    int32_t i;
 
1544
    uint32_t ret = 0;
 
1545
 
 
1546
    for (i = 0; i < 4; i++) {
 
1547
        ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
 
1548
    }
 
1549
 
 
1550
    return ret;
 
1551
}
 
1552
 
 
1553
uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
 
1554
{
 
1555
    uint32_t ret;
 
1556
 
 
1557
    ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
 
1558
    ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
 
1559
 
 
1560
    return ret;
 
1561
}
 
1562
 
 
1563
uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
 
1564
{
 
1565
    int32_t i;
 
1566
    uint32_t ret = 0;
 
1567
 
 
1568
    for (i = 0; i < 4; i++) {
 
1569
        if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
 
1570
            ret |= (0xff << (i * 8));
 
1571
        }
 
1572
    }
 
1573
 
 
1574
    return ret;
 
1575
}
 
1576
 
 
1577
uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
 
1578
{
 
1579
    int32_t i;
 
1580
    uint32_t ret = 0;
 
1581
 
 
1582
    for (i = 0; i < 4; i++) {
 
1583
        if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
 
1584
            ret |= (0xff << (i * 8));
 
1585
        }
 
1586
    }
 
1587
 
 
1588
    return ret;
 
1589
}
 
1590
 
 
1591
uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
 
1592
{
 
1593
    uint32_t ret = 0;
 
1594
 
 
1595
    if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
 
1596
        ret |= 0xffff;
 
1597
    }
 
1598
 
 
1599
    if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
 
1600
        ret |= 0xffff0000;
 
1601
    }
 
1602
 
 
1603
    return ret;
 
1604
}
 
1605
 
 
1606
uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
 
1607
{
 
1608
    uint32_t ret = 0;
 
1609
 
 
1610
    if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
 
1611
        ret |= 0xffff;
 
1612
    }
 
1613
 
 
1614
    if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
 
1615
        ret |= 0xffff0000;
 
1616
    }
 
1617
 
 
1618
    return ret;
 
1619
}
 
1620
 
 
1621
#define EXTREMA_H_B(name, op)                                 \
 
1622
uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
 
1623
{                                                             \
 
1624
    int32_t i, extr_r1, extr_r2;                              \
 
1625
    uint32_t ret = 0;                                         \
 
1626
                                                              \
 
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);                   \
 
1632
    }                                                         \
 
1633
    return ret;                                               \
 
1634
}                                                             \
 
1635
                                                              \
 
1636
uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
 
1637
{                                                             \
 
1638
    int32_t i;                                                \
 
1639
    uint32_t extr_r1, extr_r2;                                \
 
1640
    uint32_t ret = 0;                                         \
 
1641
                                                              \
 
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);                   \
 
1647
    }                                                         \
 
1648
    return ret;                                               \
 
1649
}                                                             \
 
1650
                                                              \
 
1651
uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
 
1652
{                                                             \
 
1653
    int32_t extr_r1, extr_r2;                                 \
 
1654
    uint32_t ret = 0;                                         \
 
1655
                                                              \
 
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;                                       \
 
1660
                                                              \
 
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;                                     \
 
1665
                                                              \
 
1666
    return ret;                                               \
 
1667
}                                                             \
 
1668
                                                              \
 
1669
uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
 
1670
{                                                             \
 
1671
    uint32_t extr_r1, extr_r2;                                \
 
1672
    uint32_t ret = 0;                                         \
 
1673
                                                              \
 
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;                                       \
 
1678
                                                              \
 
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);                                   \
 
1683
                                                              \
 
1684
    return ret;                                               \
 
1685
}                                                             \
 
1686
                                                              \
 
1687
uint64_t helper_ix##name(uint64_t r1, uint32_t r2)            \
 
1688
{                                                             \
 
1689
    int64_t r2l, r2h, r1hl;                                   \
 
1690
    uint64_t ret = 0;                                         \
 
1691
                                                              \
 
1692
    ret = ((r1 + 2) & 0xffff);                                \
 
1693
    r2l = sextract64(r2, 0, 16);                              \
 
1694
    r2h = sextract64(r2, 16, 16);                             \
 
1695
    r1hl = sextract64(r1, 32, 16);                            \
 
1696
                                                              \
 
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;                \
 
1703
    } else {                                                  \
 
1704
        ret |= r1 & 0xffffffff0000ull;                        \
 
1705
    }                                                         \
 
1706
    return ret;                                               \
 
1707
}                                                             \
 
1708
                                                              \
 
1709
uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2)       \
 
1710
{                                                             \
 
1711
    int64_t r2l, r2h, r1hl;                                   \
 
1712
    uint64_t ret = 0;                                         \
 
1713
                                                              \
 
1714
    ret = ((r1 + 2) & 0xffff);                                \
 
1715
    r2l = extract64(r2, 0, 16);                               \
 
1716
    r2h = extract64(r2, 16, 16);                              \
 
1717
    r1hl = extract64(r1, 32, 16);                             \
 
1718
                                                              \
 
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;                \
 
1725
    } else {                                                  \
 
1726
        ret |= r1 & 0xffffffff0000ull;                        \
 
1727
    }                                                         \
 
1728
    return ret;                                               \
 
1729
}
 
1730
 
 
1731
EXTREMA_H_B(max, >)
 
1732
EXTREMA_H_B(min, <)
 
1733
 
 
1734
#undef EXTREMA_H_B
 
1735
 
 
1736
uint32_t helper_clo_h(target_ulong r1)
 
1737
{
 
1738
    uint32_t ret_hw0 = extract32(r1, 0, 16);
 
1739
    uint32_t ret_hw1 = extract32(r1, 16, 16);
 
1740
 
 
1741
    ret_hw0 = clo32(ret_hw0 << 16);
 
1742
    ret_hw1 = clo32(ret_hw1 << 16);
 
1743
 
 
1744
    if (ret_hw0 > 16) {
 
1745
        ret_hw0 = 16;
 
1746
    }
 
1747
    if (ret_hw1 > 16) {
 
1748
        ret_hw1 = 16;
 
1749
    }
 
1750
 
 
1751
    return ret_hw0 | (ret_hw1 << 16);
 
1752
}
 
1753
 
 
1754
uint32_t helper_clz_h(target_ulong r1)
 
1755
{
 
1756
    uint32_t ret_hw0 = extract32(r1, 0, 16);
 
1757
    uint32_t ret_hw1 = extract32(r1, 16, 16);
 
1758
 
 
1759
    ret_hw0 = clz32(ret_hw0 << 16);
 
1760
    ret_hw1 = clz32(ret_hw1 << 16);
 
1761
 
 
1762
    if (ret_hw0 > 16) {
 
1763
        ret_hw0 = 16;
 
1764
    }
 
1765
    if (ret_hw1 > 16) {
 
1766
        ret_hw1 = 16;
 
1767
    }
 
1768
 
 
1769
    return ret_hw0 | (ret_hw1 << 16);
 
1770
}
 
1771
 
 
1772
uint32_t helper_cls_h(target_ulong r1)
 
1773
{
 
1774
    uint32_t ret_hw0 = extract32(r1, 0, 16);
 
1775
    uint32_t ret_hw1 = extract32(r1, 16, 16);
 
1776
 
 
1777
    ret_hw0 = clrsb32(ret_hw0 << 16);
 
1778
    ret_hw1 = clrsb32(ret_hw1 << 16);
 
1779
 
 
1780
    if (ret_hw0 > 15) {
 
1781
        ret_hw0 = 15;
 
1782
    }
 
1783
    if (ret_hw1 > 15) {
 
1784
        ret_hw1 = 15;
 
1785
    }
 
1786
 
 
1787
    return ret_hw0 | (ret_hw1 << 16);
 
1788
}
 
1789
 
 
1790
uint32_t helper_sh(target_ulong r1, target_ulong r2)
 
1791
{
 
1792
    int32_t shift_count = sextract32(r2, 0, 6);
 
1793
 
 
1794
    if (shift_count == -32) {
 
1795
        return 0;
 
1796
    } else if (shift_count < 0) {
 
1797
        return r1 >> -shift_count;
 
1798
    } else {
 
1799
        return r1 << shift_count;
 
1800
    }
 
1801
}
 
1802
 
 
1803
uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
 
1804
{
 
1805
    int32_t ret_hw0, ret_hw1;
 
1806
    int32_t shift_count;
 
1807
 
 
1808
    shift_count = sextract32(r2, 0, 5);
 
1809
 
 
1810
    if (shift_count == -16) {
 
1811
        return 0;
 
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);
 
1816
    } else {
 
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);
 
1820
    }
 
1821
}
 
1822
 
 
1823
uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
 
1824
{
 
1825
    int32_t shift_count;
 
1826
    int64_t result, t1;
 
1827
    uint32_t ret;
 
1828
 
 
1829
    shift_count = sextract32(r2, 0, 6);
 
1830
    t1 = sextract32(r1, 0, 32);
 
1831
 
 
1832
    if (shift_count == 0) {
 
1833
        env->PSW_USB_C = env->PSW_USB_V = 0;
 
1834
        ret = r1;
 
1835
    } else if (shift_count == -32) {
 
1836
        env->PSW_USB_C = r1;
 
1837
        env->PSW_USB_V = 0;
 
1838
        ret = t1 >> 31;
 
1839
    } else if (shift_count > 0) {
 
1840
        result = t1 << shift_count;
 
1841
        /* calc carry */
 
1842
        env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
 
1843
        /* calc v */
 
1844
        env->PSW_USB_V = (((result > 0x7fffffffLL) ||
 
1845
                           (result < -0x80000000LL)) << 31);
 
1846
        /* calc sv */
 
1847
        env->PSW_USB_SV |= env->PSW_USB_V;
 
1848
        ret = (uint32_t)result;
 
1849
    } else {
 
1850
        env->PSW_USB_V = 0;
 
1851
        env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
 
1852
        ret = t1 >> -shift_count;
 
1853
    }
 
1854
 
 
1855
    env->PSW_USB_AV = ret ^ ret * 2u;
 
1856
    env->PSW_USB_SAV |= env->PSW_USB_AV;
 
1857
 
 
1858
    return ret;
 
1859
}
 
1860
 
 
1861
uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
 
1862
{
 
1863
    int32_t shift_count;
 
1864
    int32_t ret_hw0, ret_hw1;
 
1865
 
 
1866
    shift_count = sextract32(r2, 0, 5);
 
1867
 
 
1868
    if (shift_count == 0) {
 
1869
        return r1;
 
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);
 
1874
    } else {
 
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);
 
1878
    }
 
1879
}
 
1880
 
 
1881
uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
 
1882
{
 
1883
    uint32_t i, ret;
 
1884
 
 
1885
    ret = 0;
 
1886
    for (i = 0; i < 16; i++) {
 
1887
        ret |= (r1 & 1) << (2 * i + 1);
 
1888
        ret |= (r2 & 1) << (2 * i);
 
1889
        r1 = r1 >> 1;
 
1890
        r2 = r2 >> 1;
 
1891
    }
 
1892
    return ret;
 
1893
}
 
1894
 
 
1895
uint64_t helper_bsplit(uint32_t r1)
 
1896
{
 
1897
    int32_t i;
 
1898
    uint64_t ret;
 
1899
 
 
1900
    ret = 0;
 
1901
    for (i = 0; i < 32; i = i + 2) {
 
1902
        /* even */
 
1903
        ret |= (r1 & 1) << (i/2);
 
1904
        r1 = r1 >> 1;
 
1905
        /* odd */
 
1906
        ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
 
1907
        r1 = r1 >> 1;
 
1908
    }
 
1909
    return ret;
 
1910
}
 
1911
 
 
1912
uint32_t helper_parity(target_ulong r1)
 
1913
{
 
1914
    uint32_t ret;
 
1915
    uint32_t nOnes, i;
 
1916
 
 
1917
    ret = 0;
 
1918
    nOnes = 0;
 
1919
    for (i = 0; i < 8; i++) {
 
1920
        ret ^= (r1 & 1);
 
1921
        r1 = r1 >> 1;
 
1922
    }
 
1923
    /* second byte */
 
1924
    nOnes = 0;
 
1925
    for (i = 0; i < 8; i++) {
 
1926
        nOnes ^= (r1 & 1);
 
1927
        r1 = r1 >> 1;
 
1928
    }
 
1929
    ret |= nOnes << 8;
 
1930
    /* third byte */
 
1931
    nOnes = 0;
 
1932
    for (i = 0; i < 8; i++) {
 
1933
        nOnes ^= (r1 & 1);
 
1934
        r1 = r1 >> 1;
 
1935
    }
 
1936
    ret |= nOnes << 16;
 
1937
    /* fourth byte */
 
1938
    nOnes = 0;
 
1939
    for (i = 0; i < 8; i++) {
 
1940
        nOnes ^= (r1 & 1);
 
1941
        r1 = r1 >> 1;
 
1942
    }
 
1943
    ret |= nOnes << 24;
 
1944
 
 
1945
    return ret;
 
1946
}
 
1947
 
 
1948
uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
 
1949
                     target_ulong r2)
 
1950
{
 
1951
    uint32_t ret;
 
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)     ||
 
1958
                        (carry != 0));
 
1959
    if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
 
1960
        fp_exp = 255;
 
1961
        fp_frac = extract32(int_mant, 8, 23);
 
1962
    } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
 
1963
        fp_exp  = 255;
 
1964
        fp_frac = 0;
 
1965
    } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
 
1966
        fp_exp  = 0;
 
1967
        fp_frac = 0;
 
1968
    } else if (int_mant == 0) {
 
1969
        fp_exp  = 0;
 
1970
        fp_frac = 0;
 
1971
    } else {
 
1972
        if (((int_mant & (1 << 31)) == 0)) {
 
1973
            temp_exp = 0;
 
1974
        } else {
 
1975
            temp_exp = int_exp + 128;
 
1976
        }
 
1977
        fp_exp_frac = (((temp_exp & 0xff) << 23) |
 
1978
                      extract32(int_mant, 8, 23))
 
1979
                      + flag_rnd;
 
1980
        fp_exp  = extract32(fp_exp_frac, 23, 8);
 
1981
        fp_frac = extract32(fp_exp_frac, 0, 23);
 
1982
    }
 
1983
    ret = r2 & (1 << 31);
 
1984
    ret = ret + (fp_exp << 23);
 
1985
    ret = ret + (fp_frac & 0x7fffff);
 
1986
 
 
1987
    return ret;
 
1988
}
 
1989
 
 
1990
uint64_t helper_unpack(target_ulong arg1)
 
1991
{
 
1992
    int32_t fp_exp  = extract32(arg1, 23, 8);
 
1993
    int32_t fp_frac = extract32(arg1, 0, 23);
 
1994
    uint64_t ret;
 
1995
    int32_t int_exp, int_mant;
 
1996
 
 
1997
    if (fp_exp == 255) {
 
1998
        int_exp = 255;
 
1999
        int_mant = (fp_frac << 7);
 
2000
    } else if ((fp_exp == 0) && (fp_frac == 0)) {
 
2001
        int_exp  = -127;
 
2002
        int_mant = 0;
 
2003
    } else if ((fp_exp == 0) && (fp_frac != 0)) {
 
2004
        int_exp  = -126;
 
2005
        int_mant = (fp_frac << 7);
 
2006
    } else {
 
2007
        int_exp  = fp_exp - 127;
 
2008
        int_mant = (fp_frac << 7);
 
2009
        int_mant |= (1 << 30);
 
2010
    }
 
2011
    ret = int_exp;
 
2012
    ret = ret << 32;
 
2013
    ret |= int_mant;
 
2014
 
 
2015
    return ret;
 
2016
}
 
2017
 
 
2018
uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
 
2019
{
 
2020
    uint64_t ret;
 
2021
    int32_t abs_sig_dividend, abs_divisor;
 
2022
 
 
2023
    ret = sextract32(r1, 0, 32);
 
2024
    ret = ret << 24;
 
2025
    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
 
2026
        ret |= 0xffffff;
 
2027
    }
 
2028
 
 
2029
    abs_sig_dividend = abs((int32_t)r1) >> 8;
 
2030
    abs_divisor = abs((int32_t)r2);
 
2031
    /* calc overflow
 
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;
 
2037
 
 
2038
    return ret;
 
2039
}
 
2040
 
 
2041
uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
 
2042
{
 
2043
    uint64_t ret = sextract32(r1, 0, 32);
 
2044
 
 
2045
    ret = ret << 24;
 
2046
    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
 
2047
        ret |= 0xffffff;
 
2048
    }
 
2049
    /* calc overflow */
 
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;
 
2054
 
 
2055
    return ret;
 
2056
}
 
2057
 
 
2058
uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
 
2059
{
 
2060
    uint64_t ret;
 
2061
    int32_t abs_sig_dividend, abs_divisor;
 
2062
 
 
2063
    ret = sextract32(r1, 0, 32);
 
2064
    ret = ret << 16;
 
2065
    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
 
2066
        ret |= 0xffff;
 
2067
    }
 
2068
 
 
2069
    abs_sig_dividend = abs((int32_t)r1) >> 16;
 
2070
    abs_divisor = abs((int32_t)r2);
 
2071
    /* calc overflow
 
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;
 
2077
 
 
2078
    return ret;
 
2079
}
 
2080
 
 
2081
uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
 
2082
{
 
2083
    uint64_t ret = sextract32(r1, 0, 32);
 
2084
 
 
2085
    ret = ret << 16;
 
2086
    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
 
2087
        ret |= 0xffff;
 
2088
    }
 
2089
    /* calc overflow */
 
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;
 
2094
 
 
2095
    return ret;
 
2096
}
 
2097
 
 
2098
uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
 
2099
{
 
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);
 
2104
    uint32_t quotient;
 
2105
    uint64_t remainder;
 
2106
 
 
2107
    if ((q_sign & ~eq_neg) | eq_pos) {
 
2108
        quotient = (r1 + 1) & 0xffffffff;
 
2109
    } else {
 
2110
        quotient = r1 & 0xffffffff;
 
2111
    }
 
2112
 
 
2113
    if (eq_pos | eq_neg) {
 
2114
        remainder = 0;
 
2115
    } else {
 
2116
        remainder = (r1 & 0xffffffff00000000ull);
 
2117
    }
 
2118
    return remainder | quotient;
 
2119
}
 
2120
 
 
2121
uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
 
2122
{
 
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;
 
2127
    int32_t i, temp;
 
2128
 
 
2129
    if (quotient_sign) {
 
2130
        addend = r2;
 
2131
    } else {
 
2132
        addend = -r2;
 
2133
    }
 
2134
    dividend_quotient = (int32_t)r1;
 
2135
    remainder = (int32_t)(r1 >> 32);
 
2136
 
 
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) {
 
2142
            remainder = temp;
 
2143
        }
 
2144
        if (((temp < 0) == dividend_sign)) {
 
2145
            dividend_quotient = dividend_quotient | !quotient_sign;
 
2146
        } else {
 
2147
            dividend_quotient = dividend_quotient | quotient_sign;
 
2148
        }
 
2149
    }
 
2150
    return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
 
2151
}
 
2152
 
 
2153
uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
 
2154
{
 
2155
    int32_t dividend_quotient = extract64(r1, 0, 32);
 
2156
    int64_t remainder = extract64(r1, 32, 32);
 
2157
    int32_t i;
 
2158
    int64_t temp;
 
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;
 
2163
        if (temp >= 0) {
 
2164
            remainder = temp;
 
2165
        }
 
2166
        dividend_quotient = dividend_quotient | !(temp < 0);
 
2167
    }
 
2168
    return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
 
2169
}
 
2170
 
 
2171
uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
 
2172
{
 
2173
    int32_t quotient, remainder;
 
2174
    int32_t dividend = (int32_t)r1;
 
2175
    int32_t divisor = (int32_t)r2;
 
2176
 
 
2177
    if (divisor == 0) {
 
2178
        if (dividend >= 0) {
 
2179
            quotient = 0x7fffffff;
 
2180
            remainder = 0;
 
2181
        } else {
 
2182
            quotient = 0x80000000;
 
2183
            remainder = 0;
 
2184
        }
 
2185
        env->PSW_USB_V = (1 << 31);
 
2186
    } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
 
2187
        quotient = 0x7fffffff;
 
2188
        remainder = 0;
 
2189
        env->PSW_USB_V = (1 << 31);
 
2190
    } else {
 
2191
        remainder = dividend % divisor;
 
2192
        quotient = (dividend - remainder)/divisor;
 
2193
        env->PSW_USB_V = 0;
 
2194
    }
 
2195
    env->PSW_USB_SV |= env->PSW_USB_V;
 
2196
    env->PSW_USB_AV = 0;
 
2197
    return ((uint64_t)remainder << 32) | (uint32_t)quotient;
 
2198
}
 
2199
 
 
2200
uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
 
2201
{
 
2202
    uint32_t quotient, remainder;
 
2203
    uint32_t dividend = r1;
 
2204
    uint32_t divisor = r2;
 
2205
 
 
2206
    if (divisor == 0) {
 
2207
        quotient = 0xffffffff;
 
2208
        remainder = 0;
 
2209
        env->PSW_USB_V = (1 << 31);
 
2210
    } else {
 
2211
        remainder = dividend % divisor;
 
2212
        quotient = (dividend - remainder)/divisor;
 
2213
        env->PSW_USB_V = 0;
 
2214
    }
 
2215
    env->PSW_USB_SV |= env->PSW_USB_V;
 
2216
    env->PSW_USB_AV = 0;
 
2217
    return ((uint64_t)remainder << 32) | quotient;
 
2218
}
 
2219
 
 
2220
uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
 
2221
                      uint32_t arg10, uint32_t arg11, uint32_t n)
 
2222
{
 
2223
    uint32_t result0, result1;
 
2224
 
 
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);
 
2229
    if (sc1) {
 
2230
        result1 = 0x7fffffff;
 
2231
    } else {
 
2232
        result1 = (((uint32_t)(arg00 * arg10)) << n);
 
2233
    }
 
2234
    if (sc0) {
 
2235
        result0 = 0x7fffffff;
 
2236
    } else {
 
2237
        result0 = (((uint32_t)(arg01 * arg11)) << n);
 
2238
    }
 
2239
    return (((uint64_t)result1 << 32)) | result0;
 
2240
}
 
2241
 
 
2242
uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
 
2243
                       uint32_t arg10, uint32_t arg11, uint32_t n)
 
2244
{
 
2245
    uint64_t ret;
 
2246
    int64_t result0, result1;
 
2247
 
 
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);
 
2252
 
 
2253
    if (sc1) {
 
2254
        result1 = 0x7fffffff;
 
2255
    } else {
 
2256
        result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
 
2257
    }
 
2258
    if (sc0) {
 
2259
        result0 = 0x7fffffff;
 
2260
    } else {
 
2261
        result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
 
2262
    }
 
2263
    ret = (result1 + result0);
 
2264
    ret = ret << 16;
 
2265
    return ret;
 
2266
}
 
2267
uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
 
2268
                       uint32_t arg10, uint32_t arg11, uint32_t n)
 
2269
{
 
2270
    uint32_t result0, result1;
 
2271
 
 
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);
 
2276
 
 
2277
    if (sc1) {
 
2278
        result1 = 0x7fffffff;
 
2279
    } else {
 
2280
        result1 = ((arg00 * arg10) << n) + 0x8000;
 
2281
    }
 
2282
    if (sc0) {
 
2283
        result0 = 0x7fffffff;
 
2284
    } else {
 
2285
        result0 = ((arg01 * arg11) << n) + 0x8000;
 
2286
    }
 
2287
    return (result1 & 0xffff0000) | (result0 >> 16);
 
2288
}
 
2289
 
 
2290
uint32_t helper_crc32(uint32_t arg0, uint32_t arg1)
 
2291
{
 
2292
    uint8_t buf[4];
 
2293
    stl_be_p(buf, arg0);
 
2294
 
 
2295
    return crc32(arg1, buf, 4);
 
2296
}
 
2297
 
 
2298
/* context save area (CSA) related helpers */
 
2299
 
 
2300
static int cdc_increment(target_ulong *psw)
 
2301
{
 
2302
    if ((*psw & MASK_PSW_CDC) == 0x7f) {
 
2303
        return 0;
 
2304
    }
 
2305
 
 
2306
    (*psw)++;
 
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;
 
2311
    if (count == 0) {
 
2312
        (*psw)--;
 
2313
        return 1;
 
2314
    }
 
2315
    return 0;
 
2316
}
 
2317
 
 
2318
static int cdc_decrement(target_ulong *psw)
 
2319
{
 
2320
    if ((*psw & MASK_PSW_CDC) == 0x7f) {
 
2321
        return 0;
 
2322
    }
 
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;
 
2327
    if (count == 0) {
 
2328
        return 1;
 
2329
    }
 
2330
    (*psw)--;
 
2331
    return 0;
 
2332
}
 
2333
 
 
2334
static bool cdc_zero(target_ulong *psw)
 
2335
{
 
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. */
 
2339
    if (cdc == 0x7f) {
 
2340
        return true;
 
2341
    }
 
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;
 
2346
    return count == 0;
 
2347
}
 
2348
 
 
2349
static void save_context_upper(CPUTriCoreState *env, int ea)
 
2350
{
 
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]);
 
2367
}
 
2368
 
 
2369
static void save_context_lower(CPUTriCoreState *env, int ea)
 
2370
{
 
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]);
 
2387
}
 
2388
 
 
2389
static void restore_context_upper(CPUTriCoreState *env, int ea,
 
2390
                                  target_ulong *new_PCXI, target_ulong *new_PSW)
 
2391
{
 
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);
 
2408
}
 
2409
 
 
2410
static void restore_context_lower(CPUTriCoreState *env, int ea,
 
2411
                                  target_ulong *ra, target_ulong *pcxi)
 
2412
{
 
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);
 
2429
}
 
2430
 
 
2431
void helper_call(CPUTriCoreState *env, uint32_t next_pc)
 
2432
{
 
2433
    target_ulong tmp_FCX;
 
2434
    target_ulong ea;
 
2435
    target_ulong new_FCX;
 
2436
    target_ulong psw;
 
2437
 
 
2438
    psw = psw_read(env);
 
2439
    /* if (FCX == 0) trap(FCU); */
 
2440
    if (env->FCX == 0) {
 
2441
        /* FCU trap */
 
2442
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
 
2443
    }
 
2444
    /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
 
2445
    if (psw & MASK_PSW_CDE) {
 
2446
        if (cdc_increment(&psw)) {
 
2447
            /* CDO trap */
 
2448
            raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC());
 
2449
        }
 
2450
    }
 
2451
    /* PSW.CDE = 1;*/
 
2452
    psw |= MASK_PSW_CDE;
 
2453
    /* tmp_FCX = FCX; */
 
2454
    tmp_FCX = env->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],
 
2462
                           D[15]}; */
 
2463
    save_context_upper(env, ea);
 
2464
 
 
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));
 
2471
    /* PCXI.UL = 1; */
 
2472
    env->PCXI |= MASK_PCXI_UL;
 
2473
 
 
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;
 
2480
 
 
2481
    /* if (tmp_FCX == LCX) trap(FCD);*/
 
2482
    if (tmp_FCX == env->LCX) {
 
2483
        /* FCD trap */
 
2484
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
 
2485
    }
 
2486
    psw_write(env, psw);
 
2487
}
 
2488
 
 
2489
void helper_ret(CPUTriCoreState *env)
 
2490
{
 
2491
    target_ulong ea;
 
2492
    target_ulong new_PCXI;
 
2493
    target_ulong new_PSW, psw;
 
2494
 
 
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)) {
 
2499
            /* CDU trap */
 
2500
            psw_write(env, psw);
 
2501
            raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC());
 
2502
        }
 
2503
    }
 
2504
    /*   if (PCXI[19: 0] == 0) then trap(CSU); */
 
2505
    if ((env->PCXI & 0xfffff) == 0) {
 
2506
        /* CSU trap */
 
2507
        psw_write(env, psw);
 
2508
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
 
2509
    }
 
2510
    /* if (PCXI.UL == 0) then trap(CTYP); */
 
2511
    if ((env->PCXI & MASK_PCXI_UL) == 0) {
 
2512
        /* CTYP trap */
 
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());
 
2516
    }
 
2517
    /* PC = {A11 [31: 1], 1’b0}; */
 
2518
    env->PC = env->gpr_a[11] & 0xfffffffe;
 
2519
 
 
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;
 
2532
 
 
2533
    if (tricore_feature(env, TRICORE_FEATURE_13)) {
 
2534
        /* PSW = new_PSW */
 
2535
        psw_write(env, new_PSW);
 
2536
    } else {
 
2537
        /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
 
2538
        psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
 
2539
    }
 
2540
}
 
2541
 
 
2542
void helper_bisr(CPUTriCoreState *env, uint32_t const9)
 
2543
{
 
2544
    target_ulong tmp_FCX;
 
2545
    target_ulong ea;
 
2546
    target_ulong new_FCX;
 
2547
 
 
2548
    if (env->FCX == 0) {
 
2549
        /* FCU trap */
 
2550
       raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
 
2551
    }
 
2552
 
 
2553
    tmp_FCX = env->FCX;
 
2554
    ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
 
2555
 
 
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);
 
2561
 
 
2562
 
 
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));
 
2569
    /* PCXI.UL = 0 */
 
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);
 
2575
    /* ICR.IE = 1 */
 
2576
    env->ICR |= MASK_ICR_IE;
 
2577
 
 
2578
    env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
 
2579
 
 
2580
    if (tmp_FCX == env->LCX) {
 
2581
        /* FCD trap */
 
2582
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
 
2583
    }
 
2584
}
 
2585
 
 
2586
void helper_rfe(CPUTriCoreState *env)
 
2587
{
 
2588
    target_ulong ea;
 
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());
 
2595
    }
 
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());
 
2600
    }
 
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());
 
2605
    }
 
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;
 
2624
    /* write psw */
 
2625
    psw_write(env, new_PSW);
 
2626
}
 
2627
 
 
2628
void helper_rfm(CPUTriCoreState *env)
 
2629
{
 
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);
 
2642
 
 
2643
    if (tricore_feature(env, TRICORE_FEATURE_131)) {
 
2644
        env->DBGTCR = 0;
 
2645
    }
 
2646
}
 
2647
 
 
2648
void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
 
2649
{
 
2650
    uint32_t dummy;
 
2651
    /* insn doesn't load PCXI and RA */
 
2652
    restore_context_lower(env, ea, &dummy, &dummy);
 
2653
}
 
2654
 
 
2655
void helper_lducx(CPUTriCoreState *env, uint32_t ea)
 
2656
{
 
2657
    uint32_t dummy;
 
2658
    /* insn doesn't load PCXI and PSW */
 
2659
    restore_context_upper(env, ea, &dummy, &dummy);
 
2660
}
 
2661
 
 
2662
void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
 
2663
{
 
2664
    save_context_lower(env, ea);
 
2665
}
 
2666
 
 
2667
void helper_stucx(CPUTriCoreState *env, uint32_t ea)
 
2668
{
 
2669
    save_context_upper(env, ea);
 
2670
}
 
2671
 
 
2672
void helper_svlcx(CPUTriCoreState *env)
 
2673
{
 
2674
    target_ulong tmp_FCX;
 
2675
    target_ulong ea;
 
2676
    target_ulong new_FCX;
 
2677
 
 
2678
    if (env->FCX == 0) {
 
2679
        /* FCU trap */
 
2680
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
 
2681
    }
 
2682
    /* tmp_FCX = FCX; */
 
2683
    tmp_FCX = env->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],
 
2691
                           D[15]}; */
 
2692
    save_context_lower(env, ea);
 
2693
 
 
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));
 
2700
    /* PCXI.UL = 0; */
 
2701
    env->PCXI &= ~MASK_PCXI_UL;
 
2702
 
 
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);
 
2707
 
 
2708
    /* if (tmp_FCX == LCX) trap(FCD);*/
 
2709
    if (tmp_FCX == env->LCX) {
 
2710
        /* FCD trap */
 
2711
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
 
2712
    }
 
2713
}
 
2714
 
 
2715
void helper_svucx(CPUTriCoreState *env)
 
2716
{
 
2717
    target_ulong tmp_FCX;
 
2718
    target_ulong ea;
 
2719
    target_ulong new_FCX;
 
2720
 
 
2721
    if (env->FCX == 0) {
 
2722
        /* FCU trap */
 
2723
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
 
2724
    }
 
2725
    /* tmp_FCX = FCX; */
 
2726
    tmp_FCX = env->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],
 
2734
                           D[15]}; */
 
2735
    save_context_upper(env, ea);
 
2736
 
 
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));
 
2743
    /* PCXI.UL = 1; */
 
2744
    env->PCXI |= MASK_PCXI_UL;
 
2745
 
 
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);
 
2750
 
 
2751
    /* if (tmp_FCX == LCX) trap(FCD);*/
 
2752
    if (tmp_FCX == env->LCX) {
 
2753
        /* FCD trap */
 
2754
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
 
2755
    }
 
2756
}
 
2757
 
 
2758
void helper_rslcx(CPUTriCoreState *env)
 
2759
{
 
2760
    target_ulong ea;
 
2761
    target_ulong new_PCXI;
 
2762
    /*   if (PCXI[19: 0] == 0) then trap(CSU); */
 
2763
    if ((env->PCXI & 0xfffff) == 0) {
 
2764
        /* CSU trap */
 
2765
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
 
2766
    }
 
2767
    /* if (PCXI.UL == 1) then trap(CTYP); */
 
2768
    if ((env->PCXI & MASK_PCXI_UL) != 0) {
 
2769
        /* CTYP trap */
 
2770
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
 
2771
    }
 
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;
 
2786
}
 
2787
 
 
2788
void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
 
2789
{
 
2790
    psw_write(env, arg);
 
2791
}
 
2792
 
 
2793
uint32_t helper_psw_read(CPUTriCoreState *env)
 
2794
{
 
2795
    return psw_read(env);
 
2796
}
 
2797
 
 
2798
 
 
2799
static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
 
2800
                                                        uint32_t exception,
 
2801
                                                        int error_code,
 
2802
                                                        uintptr_t pc)
 
2803
{
 
2804
    CPUState *cs = CPU(tricore_env_get_cpu(env));
 
2805
    cs->exception_index = exception;
 
2806
    env->error_code = error_code;
 
2807
 
 
2808
    if (pc) {
 
2809
        /* now we have a real cpu fault */
 
2810
        cpu_restore_state(cs, pc);
 
2811
    }
 
2812
 
 
2813
    cpu_loop_exit(cs);
 
2814
}
 
2815
 
 
2816
void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
 
2817
              int mmu_idx, uintptr_t retaddr)
 
2818
{
 
2819
    int ret;
 
2820
    ret = cpu_tricore_handle_mmu_fault(cs, addr, access_type, mmu_idx);
 
2821
    if (ret) {
 
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);
 
2826
    }
 
2827
}