~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(target_ulong r1)
1737
 
{
1738
 
    return clo32(r1);
1739
 
}
1740
 
 
1741
 
uint32_t helper_clo_h(target_ulong r1)
1742
 
{
1743
 
    uint32_t ret_hw0 = extract32(r1, 0, 16);
1744
 
    uint32_t ret_hw1 = extract32(r1, 16, 16);
1745
 
 
1746
 
    ret_hw0 = clo32(ret_hw0 << 16);
1747
 
    ret_hw1 = clo32(ret_hw1 << 16);
1748
 
 
1749
 
    if (ret_hw0 > 16) {
1750
 
        ret_hw0 = 16;
1751
 
    }
1752
 
    if (ret_hw1 > 16) {
1753
 
        ret_hw1 = 16;
1754
 
    }
1755
 
 
1756
 
    return ret_hw0 | (ret_hw1 << 16);
1757
 
}
1758
 
 
1759
 
uint32_t helper_clz(target_ulong r1)
1760
 
{
1761
 
    return clz32(r1);
1762
 
}
1763
 
 
1764
 
uint32_t helper_clz_h(target_ulong r1)
1765
 
{
1766
 
    uint32_t ret_hw0 = extract32(r1, 0, 16);
1767
 
    uint32_t ret_hw1 = extract32(r1, 16, 16);
1768
 
 
1769
 
    ret_hw0 = clz32(ret_hw0 << 16);
1770
 
    ret_hw1 = clz32(ret_hw1 << 16);
1771
 
 
1772
 
    if (ret_hw0 > 16) {
1773
 
        ret_hw0 = 16;
1774
 
    }
1775
 
    if (ret_hw1 > 16) {
1776
 
        ret_hw1 = 16;
1777
 
    }
1778
 
 
1779
 
    return ret_hw0 | (ret_hw1 << 16);
1780
 
}
1781
 
 
1782
 
uint32_t helper_cls(target_ulong r1)
1783
 
{
1784
 
    return clrsb32(r1);
1785
 
}
1786
 
 
1787
 
uint32_t helper_cls_h(target_ulong r1)
1788
 
{
1789
 
    uint32_t ret_hw0 = extract32(r1, 0, 16);
1790
 
    uint32_t ret_hw1 = extract32(r1, 16, 16);
1791
 
 
1792
 
    ret_hw0 = clrsb32(ret_hw0 << 16);
1793
 
    ret_hw1 = clrsb32(ret_hw1 << 16);
1794
 
 
1795
 
    if (ret_hw0 > 15) {
1796
 
        ret_hw0 = 15;
1797
 
    }
1798
 
    if (ret_hw1 > 15) {
1799
 
        ret_hw1 = 15;
1800
 
    }
1801
 
 
1802
 
    return ret_hw0 | (ret_hw1 << 16);
1803
 
}
1804
 
 
1805
 
uint32_t helper_sh(target_ulong r1, target_ulong r2)
1806
 
{
1807
 
    int32_t shift_count = sextract32(r2, 0, 6);
1808
 
 
1809
 
    if (shift_count == -32) {
1810
 
        return 0;
1811
 
    } else if (shift_count < 0) {
1812
 
        return r1 >> -shift_count;
1813
 
    } else {
1814
 
        return r1 << shift_count;
1815
 
    }
1816
 
}
1817
 
 
1818
 
uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
1819
 
{
1820
 
    int32_t ret_hw0, ret_hw1;
1821
 
    int32_t shift_count;
1822
 
 
1823
 
    shift_count = sextract32(r2, 0, 5);
1824
 
 
1825
 
    if (shift_count == -16) {
1826
 
        return 0;
1827
 
    } else if (shift_count < 0) {
1828
 
        ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
1829
 
        ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
1830
 
        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1831
 
    } else {
1832
 
        ret_hw0 = extract32(r1, 0, 16) << shift_count;
1833
 
        ret_hw1 = extract32(r1, 16, 16) << shift_count;
1834
 
        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1835
 
    }
1836
 
}
1837
 
 
1838
 
uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1839
 
{
1840
 
    int32_t shift_count;
1841
 
    int64_t result, t1;
1842
 
    uint32_t ret;
1843
 
 
1844
 
    shift_count = sextract32(r2, 0, 6);
1845
 
    t1 = sextract32(r1, 0, 32);
1846
 
 
1847
 
    if (shift_count == 0) {
1848
 
        env->PSW_USB_C = env->PSW_USB_V = 0;
1849
 
        ret = r1;
1850
 
    } else if (shift_count == -32) {
1851
 
        env->PSW_USB_C = r1;
1852
 
        env->PSW_USB_V = 0;
1853
 
        ret = t1 >> 31;
1854
 
    } else if (shift_count > 0) {
1855
 
        result = t1 << shift_count;
1856
 
        /* calc carry */
1857
 
        env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
1858
 
        /* calc v */
1859
 
        env->PSW_USB_V = (((result > 0x7fffffffLL) ||
1860
 
                           (result < -0x80000000LL)) << 31);
1861
 
        /* calc sv */
1862
 
        env->PSW_USB_SV |= env->PSW_USB_V;
1863
 
        ret = (uint32_t)result;
1864
 
    } else {
1865
 
        env->PSW_USB_V = 0;
1866
 
        env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
1867
 
        ret = t1 >> -shift_count;
1868
 
    }
1869
 
 
1870
 
    env->PSW_USB_AV = ret ^ ret * 2u;
1871
 
    env->PSW_USB_SAV |= env->PSW_USB_AV;
1872
 
 
1873
 
    return ret;
1874
 
}
1875
 
 
1876
 
uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
1877
 
{
1878
 
    int32_t shift_count;
1879
 
    int32_t ret_hw0, ret_hw1;
1880
 
 
1881
 
    shift_count = sextract32(r2, 0, 5);
1882
 
 
1883
 
    if (shift_count == 0) {
1884
 
        return r1;
1885
 
    } else if (shift_count < 0) {
1886
 
        ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
1887
 
        ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
1888
 
        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1889
 
    } else {
1890
 
        ret_hw0 = sextract32(r1, 0, 16) << shift_count;
1891
 
        ret_hw1 = sextract32(r1, 16, 16) << shift_count;
1892
 
        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1893
 
    }
1894
 
}
1895
 
 
1896
 
uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1897
 
{
1898
 
    uint32_t i, ret;
1899
 
 
1900
 
    ret = 0;
1901
 
    for (i = 0; i < 16; i++) {
1902
 
        ret |= (r1 & 1) << (2 * i + 1);
1903
 
        ret |= (r2 & 1) << (2 * i);
1904
 
        r1 = r1 >> 1;
1905
 
        r2 = r2 >> 1;
1906
 
    }
1907
 
    return ret;
1908
 
}
1909
 
 
1910
 
uint64_t helper_bsplit(uint32_t r1)
1911
 
{
1912
 
    int32_t i;
1913
 
    uint64_t ret;
1914
 
 
1915
 
    ret = 0;
1916
 
    for (i = 0; i < 32; i = i + 2) {
1917
 
        /* even */
1918
 
        ret |= (r1 & 1) << (i/2);
1919
 
        r1 = r1 >> 1;
1920
 
        /* odd */
1921
 
        ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1922
 
        r1 = r1 >> 1;
1923
 
    }
1924
 
    return ret;
1925
 
}
1926
 
 
1927
 
uint32_t helper_parity(target_ulong r1)
1928
 
{
1929
 
    uint32_t ret;
1930
 
    uint32_t nOnes, i;
1931
 
 
1932
 
    ret = 0;
1933
 
    nOnes = 0;
1934
 
    for (i = 0; i < 8; i++) {
1935
 
        ret ^= (r1 & 1);
1936
 
        r1 = r1 >> 1;
1937
 
    }
1938
 
    /* second byte */
1939
 
    nOnes = 0;
1940
 
    for (i = 0; i < 8; i++) {
1941
 
        nOnes ^= (r1 & 1);
1942
 
        r1 = r1 >> 1;
1943
 
    }
1944
 
    ret |= nOnes << 8;
1945
 
    /* third byte */
1946
 
    nOnes = 0;
1947
 
    for (i = 0; i < 8; i++) {
1948
 
        nOnes ^= (r1 & 1);
1949
 
        r1 = r1 >> 1;
1950
 
    }
1951
 
    ret |= nOnes << 16;
1952
 
    /* fourth byte */
1953
 
    nOnes = 0;
1954
 
    for (i = 0; i < 8; i++) {
1955
 
        nOnes ^= (r1 & 1);
1956
 
        r1 = r1 >> 1;
1957
 
    }
1958
 
    ret |= nOnes << 24;
1959
 
 
1960
 
    return ret;
1961
 
}
1962
 
 
1963
 
uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
1964
 
                     target_ulong r2)
1965
 
{
1966
 
    uint32_t ret;
1967
 
    int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
1968
 
    int32_t int_exp  = r1_high;
1969
 
    int32_t int_mant = r1_low;
1970
 
    uint32_t flag_rnd = (int_mant & (1 << 7)) && (
1971
 
                        (int_mant & (1 << 8)) ||
1972
 
                        (int_mant & 0x7f)     ||
1973
 
                        (carry != 0));
1974
 
    if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
1975
 
        fp_exp = 255;
1976
 
        fp_frac = extract32(int_mant, 8, 23);
1977
 
    } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
1978
 
        fp_exp  = 255;
1979
 
        fp_frac = 0;
1980
 
    } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
1981
 
        fp_exp  = 0;
1982
 
        fp_frac = 0;
1983
 
    } else if (int_mant == 0) {
1984
 
        fp_exp  = 0;
1985
 
        fp_frac = 0;
1986
 
    } else {
1987
 
        if (((int_mant & (1 << 31)) == 0)) {
1988
 
            temp_exp = 0;
1989
 
        } else {
1990
 
            temp_exp = int_exp + 128;
1991
 
        }
1992
 
        fp_exp_frac = (((temp_exp & 0xff) << 23) |
1993
 
                      extract32(int_mant, 8, 23))
1994
 
                      + flag_rnd;
1995
 
        fp_exp  = extract32(fp_exp_frac, 23, 8);
1996
 
        fp_frac = extract32(fp_exp_frac, 0, 23);
1997
 
    }
1998
 
    ret = r2 & (1 << 31);
1999
 
    ret = ret + (fp_exp << 23);
2000
 
    ret = ret + (fp_frac & 0x7fffff);
2001
 
 
2002
 
    return ret;
2003
 
}
2004
 
 
2005
 
uint64_t helper_unpack(target_ulong arg1)
2006
 
{
2007
 
    int32_t fp_exp  = extract32(arg1, 23, 8);
2008
 
    int32_t fp_frac = extract32(arg1, 0, 23);
2009
 
    uint64_t ret;
2010
 
    int32_t int_exp, int_mant;
2011
 
 
2012
 
    if (fp_exp == 255) {
2013
 
        int_exp = 255;
2014
 
        int_mant = (fp_frac << 7);
2015
 
    } else if ((fp_exp == 0) && (fp_frac == 0)) {
2016
 
        int_exp  = -127;
2017
 
        int_mant = 0;
2018
 
    } else if ((fp_exp == 0) && (fp_frac != 0)) {
2019
 
        int_exp  = -126;
2020
 
        int_mant = (fp_frac << 7);
2021
 
    } else {
2022
 
        int_exp  = fp_exp - 127;
2023
 
        int_mant = (fp_frac << 7);
2024
 
        int_mant |= (1 << 30);
2025
 
    }
2026
 
    ret = int_exp;
2027
 
    ret = ret << 32;
2028
 
    ret |= int_mant;
2029
 
 
2030
 
    return ret;
2031
 
}
2032
 
 
2033
 
uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2034
 
{
2035
 
    uint64_t ret;
2036
 
    int32_t abs_sig_dividend, abs_divisor;
2037
 
 
2038
 
    ret = sextract32(r1, 0, 32);
2039
 
    ret = ret << 24;
2040
 
    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2041
 
        ret |= 0xffffff;
2042
 
    }
2043
 
 
2044
 
    abs_sig_dividend = abs((int32_t)r1) >> 8;
2045
 
    abs_divisor = abs((int32_t)r2);
2046
 
    /* calc overflow
2047
 
       ofv if (a/b >= 255) <=> (a/255 >= b) */
2048
 
    env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2049
 
    env->PSW_USB_V = env->PSW_USB_V << 31;
2050
 
    env->PSW_USB_SV |= env->PSW_USB_V;
2051
 
    env->PSW_USB_AV = 0;
2052
 
 
2053
 
    return ret;
2054
 
}
2055
 
 
2056
 
uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2057
 
{
2058
 
    uint64_t ret = sextract32(r1, 0, 32);
2059
 
 
2060
 
    ret = ret << 24;
2061
 
    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2062
 
        ret |= 0xffffff;
2063
 
    }
2064
 
    /* calc overflow */
2065
 
    env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
2066
 
    env->PSW_USB_V = env->PSW_USB_V << 31;
2067
 
    env->PSW_USB_SV |= env->PSW_USB_V;
2068
 
    env->PSW_USB_AV = 0;
2069
 
 
2070
 
    return ret;
2071
 
}
2072
 
 
2073
 
uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2074
 
{
2075
 
    uint64_t ret;
2076
 
    int32_t abs_sig_dividend, abs_divisor;
2077
 
 
2078
 
    ret = sextract32(r1, 0, 32);
2079
 
    ret = ret << 16;
2080
 
    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2081
 
        ret |= 0xffff;
2082
 
    }
2083
 
 
2084
 
    abs_sig_dividend = abs((int32_t)r1) >> 16;
2085
 
    abs_divisor = abs((int32_t)r2);
2086
 
    /* calc overflow
2087
 
       ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */
2088
 
    env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2089
 
    env->PSW_USB_V = env->PSW_USB_V << 31;
2090
 
    env->PSW_USB_SV |= env->PSW_USB_V;
2091
 
    env->PSW_USB_AV = 0;
2092
 
 
2093
 
    return ret;
2094
 
}
2095
 
 
2096
 
uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2097
 
{
2098
 
    uint64_t ret = sextract32(r1, 0, 32);
2099
 
 
2100
 
    ret = ret << 16;
2101
 
    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2102
 
        ret |= 0xffff;
2103
 
    }
2104
 
    /* calc overflow */
2105
 
    env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
2106
 
    env->PSW_USB_V = env->PSW_USB_V << 31;
2107
 
    env->PSW_USB_SV |= env->PSW_USB_V;
2108
 
    env->PSW_USB_AV = 0;
2109
 
 
2110
 
    return ret;
2111
 
}
2112
 
 
2113
 
uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
2114
 
{
2115
 
    int32_t x_sign = (r1 >> 63);
2116
 
    int32_t q_sign = x_sign ^ (r2 >> 31);
2117
 
    int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
2118
 
    int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
2119
 
    uint32_t quotient;
2120
 
    uint64_t remainder;
2121
 
 
2122
 
    if ((q_sign & ~eq_neg) | eq_pos) {
2123
 
        quotient = (r1 + 1) & 0xffffffff;
2124
 
    } else {
2125
 
        quotient = r1 & 0xffffffff;
2126
 
    }
2127
 
 
2128
 
    if (eq_pos | eq_neg) {
2129
 
        remainder = 0;
2130
 
    } else {
2131
 
        remainder = (r1 & 0xffffffff00000000ull);
2132
 
    }
2133
 
    return remainder | quotient;
2134
 
}
2135
 
 
2136
 
uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
2137
 
{
2138
 
    int32_t dividend_sign = extract64(r1, 63, 1);
2139
 
    int32_t divisor_sign = extract32(r2, 31, 1);
2140
 
    int32_t quotient_sign = (dividend_sign != divisor_sign);
2141
 
    int32_t addend, dividend_quotient, remainder;
2142
 
    int32_t i, temp;
2143
 
 
2144
 
    if (quotient_sign) {
2145
 
        addend = r2;
2146
 
    } else {
2147
 
        addend = -r2;
2148
 
    }
2149
 
    dividend_quotient = (int32_t)r1;
2150
 
    remainder = (int32_t)(r1 >> 32);
2151
 
 
2152
 
    for (i = 0; i < 8; i++) {
2153
 
        remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2154
 
        dividend_quotient <<= 1;
2155
 
        temp = remainder + addend;
2156
 
        if ((temp < 0) == dividend_sign) {
2157
 
            remainder = temp;
2158
 
        }
2159
 
        if (((temp < 0) == dividend_sign)) {
2160
 
            dividend_quotient = dividend_quotient | !quotient_sign;
2161
 
        } else {
2162
 
            dividend_quotient = dividend_quotient | quotient_sign;
2163
 
        }
2164
 
    }
2165
 
    return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2166
 
}
2167
 
 
2168
 
uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
2169
 
{
2170
 
    int32_t dividend_quotient = extract64(r1, 0, 32);
2171
 
    int64_t remainder = extract64(r1, 32, 32);
2172
 
    int32_t i;
2173
 
    int64_t temp;
2174
 
    for (i = 0; i < 8; i++) {
2175
 
        remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2176
 
        dividend_quotient <<= 1;
2177
 
        temp = (remainder & 0xffffffff) - r2;
2178
 
        if (temp >= 0) {
2179
 
            remainder = temp;
2180
 
        }
2181
 
        dividend_quotient = dividend_quotient | !(temp < 0);
2182
 
    }
2183
 
    return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2184
 
}
2185
 
 
2186
 
uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2187
 
{
2188
 
    int32_t quotient, remainder;
2189
 
    int32_t dividend = (int32_t)r1;
2190
 
    int32_t divisor = (int32_t)r2;
2191
 
 
2192
 
    if (divisor == 0) {
2193
 
        if (dividend >= 0) {
2194
 
            quotient = 0x7fffffff;
2195
 
            remainder = 0;
2196
 
        } else {
2197
 
            quotient = 0x80000000;
2198
 
            remainder = 0;
2199
 
        }
2200
 
        env->PSW_USB_V = (1 << 31);
2201
 
    } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
2202
 
        quotient = 0x7fffffff;
2203
 
        remainder = 0;
2204
 
        env->PSW_USB_V = (1 << 31);
2205
 
    } else {
2206
 
        remainder = dividend % divisor;
2207
 
        quotient = (dividend - remainder)/divisor;
2208
 
        env->PSW_USB_V = 0;
2209
 
    }
2210
 
    env->PSW_USB_SV |= env->PSW_USB_V;
2211
 
    env->PSW_USB_AV = 0;
2212
 
    return ((uint64_t)remainder << 32) | (uint32_t)quotient;
2213
 
}
2214
 
 
2215
 
uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2216
 
{
2217
 
    uint32_t quotient, remainder;
2218
 
    uint32_t dividend = r1;
2219
 
    uint32_t divisor = r2;
2220
 
 
2221
 
    if (divisor == 0) {
2222
 
        quotient = 0xffffffff;
2223
 
        remainder = 0;
2224
 
        env->PSW_USB_V = (1 << 31);
2225
 
    } else {
2226
 
        remainder = dividend % divisor;
2227
 
        quotient = (dividend - remainder)/divisor;
2228
 
        env->PSW_USB_V = 0;
2229
 
    }
2230
 
    env->PSW_USB_SV |= env->PSW_USB_V;
2231
 
    env->PSW_USB_AV = 0;
2232
 
    return ((uint64_t)remainder << 32) | quotient;
2233
 
}
2234
 
 
2235
 
uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
2236
 
                      uint32_t arg10, uint32_t arg11, uint32_t n)
2237
 
{
2238
 
    uint32_t result0, result1;
2239
 
 
2240
 
    int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2241
 
                  ((arg10 & 0xffff) == 0x8000) && (n == 1);
2242
 
    int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2243
 
                  ((arg11 & 0xffff) == 0x8000) && (n == 1);
2244
 
    if (sc1) {
2245
 
        result1 = 0x7fffffff;
2246
 
    } else {
2247
 
        result1 = (((uint32_t)(arg00 * arg10)) << n);
2248
 
    }
2249
 
    if (sc0) {
2250
 
        result0 = 0x7fffffff;
2251
 
    } else {
2252
 
        result0 = (((uint32_t)(arg01 * arg11)) << n);
2253
 
    }
2254
 
    return (((uint64_t)result1 << 32)) | result0;
2255
 
}
2256
 
 
2257
 
uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
2258
 
                       uint32_t arg10, uint32_t arg11, uint32_t n)
2259
 
{
2260
 
    uint64_t ret;
2261
 
    int64_t result0, result1;
2262
 
 
2263
 
    int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2264
 
                  ((arg10 & 0xffff) == 0x8000) && (n == 1);
2265
 
    int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2266
 
                  ((arg11 & 0xffff) == 0x8000) && (n == 1);
2267
 
 
2268
 
    if (sc1) {
2269
 
        result1 = 0x7fffffff;
2270
 
    } else {
2271
 
        result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
2272
 
    }
2273
 
    if (sc0) {
2274
 
        result0 = 0x7fffffff;
2275
 
    } else {
2276
 
        result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
2277
 
    }
2278
 
    ret = (result1 + result0);
2279
 
    ret = ret << 16;
2280
 
    return ret;
2281
 
}
2282
 
uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
2283
 
                       uint32_t arg10, uint32_t arg11, uint32_t n)
2284
 
{
2285
 
    uint32_t result0, result1;
2286
 
 
2287
 
    int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2288
 
                  ((arg10 & 0xffff) == 0x8000) && (n == 1);
2289
 
    int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2290
 
                  ((arg11 & 0xffff) == 0x8000) && (n == 1);
2291
 
 
2292
 
    if (sc1) {
2293
 
        result1 = 0x7fffffff;
2294
 
    } else {
2295
 
        result1 = ((arg00 * arg10) << n) + 0x8000;
2296
 
    }
2297
 
    if (sc0) {
2298
 
        result0 = 0x7fffffff;
2299
 
    } else {
2300
 
        result0 = ((arg01 * arg11) << n) + 0x8000;
2301
 
    }
2302
 
    return (result1 & 0xffff0000) | (result0 >> 16);
2303
 
}
2304
 
 
2305
 
uint32_t helper_crc32(uint32_t arg0, uint32_t arg1)
2306
 
{
2307
 
    uint8_t buf[4];
2308
 
    stl_be_p(buf, arg0);
2309
 
 
2310
 
    return crc32(arg1, buf, 4);
2311
 
}
2312
 
 
2313
 
/* context save area (CSA) related helpers */
2314
 
 
2315
 
static int cdc_increment(target_ulong *psw)
2316
 
{
2317
 
    if ((*psw & MASK_PSW_CDC) == 0x7f) {
2318
 
        return 0;
2319
 
    }
2320
 
 
2321
 
    (*psw)++;
2322
 
    /* check for overflow */
2323
 
    int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2324
 
    int mask = (1u << (7 - lo)) - 1;
2325
 
    int count = *psw & mask;
2326
 
    if (count == 0) {
2327
 
        (*psw)--;
2328
 
        return 1;
2329
 
    }
2330
 
    return 0;
2331
 
}
2332
 
 
2333
 
static int cdc_decrement(target_ulong *psw)
2334
 
{
2335
 
    if ((*psw & MASK_PSW_CDC) == 0x7f) {
2336
 
        return 0;
2337
 
    }
2338
 
    /* check for underflow */
2339
 
    int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2340
 
    int mask = (1u << (7 - lo)) - 1;
2341
 
    int count = *psw & mask;
2342
 
    if (count == 0) {
2343
 
        return 1;
2344
 
    }
2345
 
    (*psw)--;
2346
 
    return 0;
2347
 
}
2348
 
 
2349
 
static bool cdc_zero(target_ulong *psw)
2350
 
{
2351
 
    int cdc = *psw & MASK_PSW_CDC;
2352
 
    /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
2353
 
       7'b1111111, otherwise returns FALSE. */
2354
 
    if (cdc == 0x7f) {
2355
 
        return true;
2356
 
    }
2357
 
    /* find CDC.COUNT */
2358
 
    int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2359
 
    int mask = (1u << (7 - lo)) - 1;
2360
 
    int count = *psw & mask;
2361
 
    return count == 0;
2362
 
}
2363
 
 
2364
 
static void save_context_upper(CPUTriCoreState *env, int ea)
2365
 
{
2366
 
    cpu_stl_data(env, ea, env->PCXI);
2367
 
    cpu_stl_data(env, ea+4, psw_read(env));
2368
 
    cpu_stl_data(env, ea+8, env->gpr_a[10]);
2369
 
    cpu_stl_data(env, ea+12, env->gpr_a[11]);
2370
 
    cpu_stl_data(env, ea+16, env->gpr_d[8]);
2371
 
    cpu_stl_data(env, ea+20, env->gpr_d[9]);
2372
 
    cpu_stl_data(env, ea+24, env->gpr_d[10]);
2373
 
    cpu_stl_data(env, ea+28, env->gpr_d[11]);
2374
 
    cpu_stl_data(env, ea+32, env->gpr_a[12]);
2375
 
    cpu_stl_data(env, ea+36, env->gpr_a[13]);
2376
 
    cpu_stl_data(env, ea+40, env->gpr_a[14]);
2377
 
    cpu_stl_data(env, ea+44, env->gpr_a[15]);
2378
 
    cpu_stl_data(env, ea+48, env->gpr_d[12]);
2379
 
    cpu_stl_data(env, ea+52, env->gpr_d[13]);
2380
 
    cpu_stl_data(env, ea+56, env->gpr_d[14]);
2381
 
    cpu_stl_data(env, ea+60, env->gpr_d[15]);
2382
 
}
2383
 
 
2384
 
static void save_context_lower(CPUTriCoreState *env, int ea)
2385
 
{
2386
 
    cpu_stl_data(env, ea, env->PCXI);
2387
 
    cpu_stl_data(env, ea+4, env->gpr_a[11]);
2388
 
    cpu_stl_data(env, ea+8, env->gpr_a[2]);
2389
 
    cpu_stl_data(env, ea+12, env->gpr_a[3]);
2390
 
    cpu_stl_data(env, ea+16, env->gpr_d[0]);
2391
 
    cpu_stl_data(env, ea+20, env->gpr_d[1]);
2392
 
    cpu_stl_data(env, ea+24, env->gpr_d[2]);
2393
 
    cpu_stl_data(env, ea+28, env->gpr_d[3]);
2394
 
    cpu_stl_data(env, ea+32, env->gpr_a[4]);
2395
 
    cpu_stl_data(env, ea+36, env->gpr_a[5]);
2396
 
    cpu_stl_data(env, ea+40, env->gpr_a[6]);
2397
 
    cpu_stl_data(env, ea+44, env->gpr_a[7]);
2398
 
    cpu_stl_data(env, ea+48, env->gpr_d[4]);
2399
 
    cpu_stl_data(env, ea+52, env->gpr_d[5]);
2400
 
    cpu_stl_data(env, ea+56, env->gpr_d[6]);
2401
 
    cpu_stl_data(env, ea+60, env->gpr_d[7]);
2402
 
}
2403
 
 
2404
 
static void restore_context_upper(CPUTriCoreState *env, int ea,
2405
 
                                  target_ulong *new_PCXI, target_ulong *new_PSW)
2406
 
{
2407
 
    *new_PCXI = cpu_ldl_data(env, ea);
2408
 
    *new_PSW = cpu_ldl_data(env, ea+4);
2409
 
    env->gpr_a[10] = cpu_ldl_data(env, ea+8);
2410
 
    env->gpr_a[11] = cpu_ldl_data(env, ea+12);
2411
 
    env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
2412
 
    env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
2413
 
    env->gpr_d[10] = cpu_ldl_data(env, ea+24);
2414
 
    env->gpr_d[11] = cpu_ldl_data(env, ea+28);
2415
 
    env->gpr_a[12] = cpu_ldl_data(env, ea+32);
2416
 
    env->gpr_a[13] = cpu_ldl_data(env, ea+36);
2417
 
    env->gpr_a[14] = cpu_ldl_data(env, ea+40);
2418
 
    env->gpr_a[15] = cpu_ldl_data(env, ea+44);
2419
 
    env->gpr_d[12] = cpu_ldl_data(env, ea+48);
2420
 
    env->gpr_d[13] = cpu_ldl_data(env, ea+52);
2421
 
    env->gpr_d[14] = cpu_ldl_data(env, ea+56);
2422
 
    env->gpr_d[15] = cpu_ldl_data(env, ea+60);
2423
 
}
2424
 
 
2425
 
static void restore_context_lower(CPUTriCoreState *env, int ea,
2426
 
                                  target_ulong *ra, target_ulong *pcxi)
2427
 
{
2428
 
    *pcxi = cpu_ldl_data(env, ea);
2429
 
    *ra = cpu_ldl_data(env, ea+4);
2430
 
    env->gpr_a[2] = cpu_ldl_data(env, ea+8);
2431
 
    env->gpr_a[3] = cpu_ldl_data(env, ea+12);
2432
 
    env->gpr_d[0] = cpu_ldl_data(env, ea+16);
2433
 
    env->gpr_d[1] = cpu_ldl_data(env, ea+20);
2434
 
    env->gpr_d[2] = cpu_ldl_data(env, ea+24);
2435
 
    env->gpr_d[3] = cpu_ldl_data(env, ea+28);
2436
 
    env->gpr_a[4] = cpu_ldl_data(env, ea+32);
2437
 
    env->gpr_a[5] = cpu_ldl_data(env, ea+36);
2438
 
    env->gpr_a[6] = cpu_ldl_data(env, ea+40);
2439
 
    env->gpr_a[7] = cpu_ldl_data(env, ea+44);
2440
 
    env->gpr_d[4] = cpu_ldl_data(env, ea+48);
2441
 
    env->gpr_d[5] = cpu_ldl_data(env, ea+52);
2442
 
    env->gpr_d[6] = cpu_ldl_data(env, ea+56);
2443
 
    env->gpr_d[7] = cpu_ldl_data(env, ea+60);
2444
 
}
2445
 
 
2446
 
void helper_call(CPUTriCoreState *env, uint32_t next_pc)
2447
 
{
2448
 
    target_ulong tmp_FCX;
2449
 
    target_ulong ea;
2450
 
    target_ulong new_FCX;
2451
 
    target_ulong psw;
2452
 
 
2453
 
    psw = psw_read(env);
2454
 
    /* if (FCX == 0) trap(FCU); */
2455
 
    if (env->FCX == 0) {
2456
 
        /* FCU trap */
2457
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2458
 
    }
2459
 
    /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
2460
 
    if (psw & MASK_PSW_CDE) {
2461
 
        if (cdc_increment(&psw)) {
2462
 
            /* CDO trap */
2463
 
            raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC());
2464
 
        }
2465
 
    }
2466
 
    /* PSW.CDE = 1;*/
2467
 
    psw |= MASK_PSW_CDE;
2468
 
    /* tmp_FCX = FCX; */
2469
 
    tmp_FCX = env->FCX;
2470
 
    /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2471
 
    ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2472
 
         ((env->FCX & MASK_FCX_FCXO) << 6);
2473
 
    /* new_FCX = M(EA, word); */
2474
 
    new_FCX = cpu_ldl_data(env, ea);
2475
 
    /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2476
 
                           A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2477
 
                           D[15]}; */
2478
 
    save_context_upper(env, ea);
2479
 
 
2480
 
    /* PCXI.PCPN = ICR.CCPN; */
2481
 
    env->PCXI = (env->PCXI & 0xffffff) +
2482
 
                ((env->ICR & MASK_ICR_CCPN) << 24);
2483
 
    /* PCXI.PIE = ICR.IE; */
2484
 
    env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2485
 
                ((env->ICR & MASK_ICR_IE) << 15));
2486
 
    /* PCXI.UL = 1; */
2487
 
    env->PCXI |= MASK_PCXI_UL;
2488
 
 
2489
 
    /* PCXI[19: 0] = FCX[19: 0]; */
2490
 
    env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2491
 
    /* FCX[19: 0] = new_FCX[19: 0]; */
2492
 
    env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2493
 
    /* A[11] = next_pc[31: 0]; */
2494
 
    env->gpr_a[11] = next_pc;
2495
 
 
2496
 
    /* if (tmp_FCX == LCX) trap(FCD);*/
2497
 
    if (tmp_FCX == env->LCX) {
2498
 
        /* FCD trap */
2499
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2500
 
    }
2501
 
    psw_write(env, psw);
2502
 
}
2503
 
 
2504
 
void helper_ret(CPUTriCoreState *env)
2505
 
{
2506
 
    target_ulong ea;
2507
 
    target_ulong new_PCXI;
2508
 
    target_ulong new_PSW, psw;
2509
 
 
2510
 
    psw = psw_read(env);
2511
 
     /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
2512
 
    if (psw & MASK_PSW_CDE) {
2513
 
        if (cdc_decrement(&psw)) {
2514
 
            /* CDU trap */
2515
 
            psw_write(env, psw);
2516
 
            raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC());
2517
 
        }
2518
 
    }
2519
 
    /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2520
 
    if ((env->PCXI & 0xfffff) == 0) {
2521
 
        /* CSU trap */
2522
 
        psw_write(env, psw);
2523
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2524
 
    }
2525
 
    /* if (PCXI.UL == 0) then trap(CTYP); */
2526
 
    if ((env->PCXI & MASK_PCXI_UL) == 0) {
2527
 
        /* CTYP trap */
2528
 
        cdc_increment(&psw); /* restore to the start of helper */
2529
 
        psw_write(env, psw);
2530
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2531
 
    }
2532
 
    /* PC = {A11 [31: 1], 1’b0}; */
2533
 
    env->PC = env->gpr_a[11] & 0xfffffffe;
2534
 
 
2535
 
    /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2536
 
    ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2537
 
         ((env->PCXI & MASK_PCXI_PCXO) << 6);
2538
 
    /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2539
 
        A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2540
 
    restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2541
 
    /* M(EA, word) = FCX; */
2542
 
    cpu_stl_data(env, ea, env->FCX);
2543
 
    /* FCX[19: 0] = PCXI[19: 0]; */
2544
 
    env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2545
 
    /* PCXI = new_PCXI; */
2546
 
    env->PCXI = new_PCXI;
2547
 
 
2548
 
    if (tricore_feature(env, TRICORE_FEATURE_13)) {
2549
 
        /* PSW = new_PSW */
2550
 
        psw_write(env, new_PSW);
2551
 
    } else {
2552
 
        /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
2553
 
        psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
2554
 
    }
2555
 
}
2556
 
 
2557
 
void helper_bisr(CPUTriCoreState *env, uint32_t const9)
2558
 
{
2559
 
    target_ulong tmp_FCX;
2560
 
    target_ulong ea;
2561
 
    target_ulong new_FCX;
2562
 
 
2563
 
    if (env->FCX == 0) {
2564
 
        /* FCU trap */
2565
 
       raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2566
 
    }
2567
 
 
2568
 
    tmp_FCX = env->FCX;
2569
 
    ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
2570
 
 
2571
 
    /* new_FCX = M(EA, word); */
2572
 
    new_FCX = cpu_ldl_data(env, ea);
2573
 
    /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2574
 
                           , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2575
 
    save_context_lower(env, ea);
2576
 
 
2577
 
 
2578
 
    /* PCXI.PCPN = ICR.CCPN */
2579
 
    env->PCXI = (env->PCXI & 0xffffff) +
2580
 
                 ((env->ICR & MASK_ICR_CCPN) << 24);
2581
 
    /* PCXI.PIE  = ICR.IE */
2582
 
    env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2583
 
                 ((env->ICR & MASK_ICR_IE) << 15));
2584
 
    /* PCXI.UL = 0 */
2585
 
    env->PCXI &= ~(MASK_PCXI_UL);
2586
 
    /* PCXI[19: 0] = FCX[19: 0] */
2587
 
    env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2588
 
    /* FXC[19: 0] = new_FCX[19: 0] */
2589
 
    env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2590
 
    /* ICR.IE = 1 */
2591
 
    env->ICR |= MASK_ICR_IE;
2592
 
 
2593
 
    env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
2594
 
 
2595
 
    if (tmp_FCX == env->LCX) {
2596
 
        /* FCD trap */
2597
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2598
 
    }
2599
 
}
2600
 
 
2601
 
void helper_rfe(CPUTriCoreState *env)
2602
 
{
2603
 
    target_ulong ea;
2604
 
    target_ulong new_PCXI;
2605
 
    target_ulong new_PSW;
2606
 
    /* if (PCXI[19: 0] == 0) then trap(CSU); */
2607
 
    if ((env->PCXI & 0xfffff) == 0) {
2608
 
        /* raise csu trap */
2609
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2610
 
    }
2611
 
    /* if (PCXI.UL == 0) then trap(CTYP); */
2612
 
    if ((env->PCXI & MASK_PCXI_UL) == 0) {
2613
 
        /* raise CTYP trap */
2614
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2615
 
    }
2616
 
    /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
2617
 
    if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
2618
 
        /* raise NEST trap */
2619
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC());
2620
 
    }
2621
 
    env->PC = env->gpr_a[11] & ~0x1;
2622
 
    /* ICR.IE = PCXI.PIE; */
2623
 
    env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
2624
 
    /* ICR.CCPN = PCXI.PCPN; */
2625
 
    env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
2626
 
               ((env->PCXI & MASK_PCXI_PCPN) >> 24);
2627
 
    /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
2628
 
    ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2629
 
         ((env->PCXI & MASK_PCXI_PCXO) << 6);
2630
 
    /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2631
 
      A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2632
 
    restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2633
 
    /* M(EA, word) = FCX;*/
2634
 
    cpu_stl_data(env, ea, env->FCX);
2635
 
    /* FCX[19: 0] = PCXI[19: 0]; */
2636
 
    env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2637
 
    /* PCXI = new_PCXI; */
2638
 
    env->PCXI = new_PCXI;
2639
 
    /* write psw */
2640
 
    psw_write(env, new_PSW);
2641
 
}
2642
 
 
2643
 
void helper_rfm(CPUTriCoreState *env)
2644
 
{
2645
 
    env->PC = (env->gpr_a[11] & ~0x1);
2646
 
    /* ICR.IE = PCXI.PIE; */
2647
 
    env->ICR = (env->ICR & ~MASK_ICR_IE) |
2648
 
               ((env->PCXI & MASK_PCXI_PIE) >> 15);
2649
 
    /* ICR.CCPN = PCXI.PCPN; */
2650
 
    env->ICR = (env->ICR & ~MASK_ICR_CCPN) |
2651
 
               ((env->PCXI & MASK_PCXI_PCPN) >> 24);
2652
 
    /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */
2653
 
    env->PCXI = cpu_ldl_data(env, env->DCX);
2654
 
    psw_write(env, cpu_ldl_data(env, env->DCX+4));
2655
 
    env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8);
2656
 
    env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12);
2657
 
 
2658
 
    if (tricore_feature(env, TRICORE_FEATURE_131)) {
2659
 
        env->DBGTCR = 0;
2660
 
    }
2661
 
}
2662
 
 
2663
 
void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
2664
 
{
2665
 
    uint32_t dummy;
2666
 
    /* insn doesn't load PCXI and RA */
2667
 
    restore_context_lower(env, ea, &dummy, &dummy);
2668
 
}
2669
 
 
2670
 
void helper_lducx(CPUTriCoreState *env, uint32_t ea)
2671
 
{
2672
 
    uint32_t dummy;
2673
 
    /* insn doesn't load PCXI and PSW */
2674
 
    restore_context_upper(env, ea, &dummy, &dummy);
2675
 
}
2676
 
 
2677
 
void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
2678
 
{
2679
 
    save_context_lower(env, ea);
2680
 
}
2681
 
 
2682
 
void helper_stucx(CPUTriCoreState *env, uint32_t ea)
2683
 
{
2684
 
    save_context_upper(env, ea);
2685
 
}
2686
 
 
2687
 
void helper_svlcx(CPUTriCoreState *env)
2688
 
{
2689
 
    target_ulong tmp_FCX;
2690
 
    target_ulong ea;
2691
 
    target_ulong new_FCX;
2692
 
 
2693
 
    if (env->FCX == 0) {
2694
 
        /* FCU trap */
2695
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2696
 
    }
2697
 
    /* tmp_FCX = FCX; */
2698
 
    tmp_FCX = env->FCX;
2699
 
    /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2700
 
    ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2701
 
         ((env->FCX & MASK_FCX_FCXO) << 6);
2702
 
    /* new_FCX = M(EA, word); */
2703
 
    new_FCX = cpu_ldl_data(env, ea);
2704
 
    /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2705
 
                           A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2706
 
                           D[15]}; */
2707
 
    save_context_lower(env, ea);
2708
 
 
2709
 
    /* PCXI.PCPN = ICR.CCPN; */
2710
 
    env->PCXI = (env->PCXI & 0xffffff) +
2711
 
                ((env->ICR & MASK_ICR_CCPN) << 24);
2712
 
    /* PCXI.PIE = ICR.IE; */
2713
 
    env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2714
 
                ((env->ICR & MASK_ICR_IE) << 15));
2715
 
    /* PCXI.UL = 0; */
2716
 
    env->PCXI &= ~MASK_PCXI_UL;
2717
 
 
2718
 
    /* PCXI[19: 0] = FCX[19: 0]; */
2719
 
    env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2720
 
    /* FCX[19: 0] = new_FCX[19: 0]; */
2721
 
    env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2722
 
 
2723
 
    /* if (tmp_FCX == LCX) trap(FCD);*/
2724
 
    if (tmp_FCX == env->LCX) {
2725
 
        /* FCD trap */
2726
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2727
 
    }
2728
 
}
2729
 
 
2730
 
void helper_svucx(CPUTriCoreState *env)
2731
 
{
2732
 
    target_ulong tmp_FCX;
2733
 
    target_ulong ea;
2734
 
    target_ulong new_FCX;
2735
 
 
2736
 
    if (env->FCX == 0) {
2737
 
        /* FCU trap */
2738
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2739
 
    }
2740
 
    /* tmp_FCX = FCX; */
2741
 
    tmp_FCX = env->FCX;
2742
 
    /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2743
 
    ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2744
 
         ((env->FCX & MASK_FCX_FCXO) << 6);
2745
 
    /* new_FCX = M(EA, word); */
2746
 
    new_FCX = cpu_ldl_data(env, ea);
2747
 
    /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2748
 
                           A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2749
 
                           D[15]}; */
2750
 
    save_context_upper(env, ea);
2751
 
 
2752
 
    /* PCXI.PCPN = ICR.CCPN; */
2753
 
    env->PCXI = (env->PCXI & 0xffffff) +
2754
 
                ((env->ICR & MASK_ICR_CCPN) << 24);
2755
 
    /* PCXI.PIE = ICR.IE; */
2756
 
    env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2757
 
                ((env->ICR & MASK_ICR_IE) << 15));
2758
 
    /* PCXI.UL = 1; */
2759
 
    env->PCXI |= MASK_PCXI_UL;
2760
 
 
2761
 
    /* PCXI[19: 0] = FCX[19: 0]; */
2762
 
    env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2763
 
    /* FCX[19: 0] = new_FCX[19: 0]; */
2764
 
    env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2765
 
 
2766
 
    /* if (tmp_FCX == LCX) trap(FCD);*/
2767
 
    if (tmp_FCX == env->LCX) {
2768
 
        /* FCD trap */
2769
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2770
 
    }
2771
 
}
2772
 
 
2773
 
void helper_rslcx(CPUTriCoreState *env)
2774
 
{
2775
 
    target_ulong ea;
2776
 
    target_ulong new_PCXI;
2777
 
    /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2778
 
    if ((env->PCXI & 0xfffff) == 0) {
2779
 
        /* CSU trap */
2780
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2781
 
    }
2782
 
    /* if (PCXI.UL == 1) then trap(CTYP); */
2783
 
    if ((env->PCXI & MASK_PCXI_UL) != 0) {
2784
 
        /* CTYP trap */
2785
 
        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2786
 
    }
2787
 
    /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2788
 
    ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2789
 
         ((env->PCXI & MASK_PCXI_PCXO) << 6);
2790
 
    /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2791
 
        A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2792
 
    restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI);
2793
 
    /* M(EA, word) = FCX; */
2794
 
    cpu_stl_data(env, ea, env->FCX);
2795
 
    /* M(EA, word) = FCX; */
2796
 
    cpu_stl_data(env, ea, env->FCX);
2797
 
    /* FCX[19: 0] = PCXI[19: 0]; */
2798
 
    env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2799
 
    /* PCXI = new_PCXI; */
2800
 
    env->PCXI = new_PCXI;
2801
 
}
2802
 
 
2803
 
void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
2804
 
{
2805
 
    psw_write(env, arg);
2806
 
}
2807
 
 
2808
 
uint32_t helper_psw_read(CPUTriCoreState *env)
2809
 
{
2810
 
    return psw_read(env);
2811
 
}
2812
 
 
2813
 
 
2814
 
static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
2815
 
                                                        uint32_t exception,
2816
 
                                                        int error_code,
2817
 
                                                        uintptr_t pc)
2818
 
{
2819
 
    CPUState *cs = CPU(tricore_env_get_cpu(env));
2820
 
    cs->exception_index = exception;
2821
 
    env->error_code = error_code;
2822
 
 
2823
 
    if (pc) {
2824
 
        /* now we have a real cpu fault */
2825
 
        cpu_restore_state(cs, pc);
2826
 
    }
2827
 
 
2828
 
    cpu_loop_exit(cs);
2829
 
}
2830
 
 
2831
 
void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
2832
 
              int mmu_idx, uintptr_t retaddr)
2833
 
{
2834
 
    int ret;
2835
 
    ret = cpu_tricore_handle_mmu_fault(cs, addr, access_type, mmu_idx);
2836
 
    if (ret) {
2837
 
        TriCoreCPU *cpu = TRICORE_CPU(cs);
2838
 
        CPUTriCoreState *env = &cpu->env;
2839
 
        do_raise_exception_err(env, cs->exception_index,
2840
 
                               env->error_code, retaddr);
2841
 
    }
2842
 
}