~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to target-alpha/op_helper.c

  • Committer: blueswir1
  • Date: 2007-09-25 17:30:09 UTC
  • Revision ID: git-v1:eb296a0a03eebd2d73718d31cd0d8a8db0b804de
 Remove the target dependency introduced by previous patch


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3239 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
#include "exec.h"
22
 
#include "host-utils.h"
23
22
#include "softfloat.h"
24
23
 
 
24
#include "op_helper.h"
 
25
 
 
26
#define MEMSUFFIX _raw
 
27
#include "op_helper_mem.h"
 
28
 
 
29
#if !defined(CONFIG_USER_ONLY)
 
30
#define MEMSUFFIX _user
 
31
#include "op_helper_mem.h"
 
32
 
 
33
#define MEMSUFFIX _kernel
 
34
#include "op_helper_mem.h"
 
35
 
 
36
/* Those are used for supervisor and executive modes */
 
37
#define MEMSUFFIX _data
 
38
#include "op_helper_mem.h"
 
39
#endif
 
40
 
25
41
void helper_tb_flush (void)
26
42
{
27
43
    tlb_flush(env, 1);
28
44
}
29
45
 
 
46
void cpu_dump_EA (target_ulong EA);
 
47
void helper_print_mem_EA (target_ulong EA)
 
48
{
 
49
    cpu_dump_EA(EA);
 
50
}
 
51
 
30
52
/*****************************************************************************/
31
53
/* Exceptions processing helpers */
32
 
void helper_excp (int excp, int error)
 
54
void helper_excp (uint32_t excp, uint32_t error)
33
55
{
34
56
    env->exception_index = excp;
35
57
    env->error_code = error;
36
58
    cpu_loop_exit();
37
59
}
38
60
 
39
 
uint64_t helper_amask (uint64_t arg)
 
61
void helper_amask (void)
40
62
{
41
63
    switch (env->implver) {
42
64
    case IMPLVER_2106x:
45
67
    case IMPLVER_21164:
46
68
    case IMPLVER_21264:
47
69
    case IMPLVER_21364:
48
 
        arg &= ~env->amask;
 
70
        T0 &= ~env->amask;
49
71
        break;
50
72
    }
51
 
    return arg;
52
73
}
53
74
 
54
 
uint64_t helper_load_pcc (void)
 
75
void helper_load_pcc (void)
55
76
{
56
77
    /* XXX: TODO */
57
 
    return 0;
58
 
}
59
 
 
60
 
uint64_t helper_load_implver (void)
61
 
{
62
 
    return env->implver;
63
 
}
64
 
 
65
 
uint64_t helper_load_fpcr (void)
66
 
{
67
 
    uint64_t ret = 0;
 
78
    T0 = 0;
 
79
}
 
80
 
 
81
void helper_load_implver (void)
 
82
{
 
83
    T0 = env->implver;
 
84
}
 
85
 
 
86
void helper_load_fpcr (void)
 
87
{
 
88
    T0 = 0;
68
89
#ifdef CONFIG_SOFTFLOAT
69
 
    ret |= env->fp_status.float_exception_flags << 52;
 
90
    T0 |= env->fp_status.float_exception_flags << 52;
70
91
    if (env->fp_status.float_exception_flags)
71
 
        ret |= 1ULL << 63;
 
92
        T0 |= 1ULL << 63;
72
93
    env->ipr[IPR_EXC_SUM] &= ~0x3E:
73
94
    env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1;
74
95
#endif
75
96
    switch (env->fp_status.float_rounding_mode) {
76
97
    case float_round_nearest_even:
77
 
        ret |= 2ULL << 58;
 
98
        T0 |= 2ULL << 58;
78
99
        break;
79
100
    case float_round_down:
80
 
        ret |= 1ULL << 58;
 
101
        T0 |= 1ULL << 58;
81
102
        break;
82
103
    case float_round_up:
83
 
        ret |= 3ULL << 58;
 
104
        T0 |= 3ULL << 58;
84
105
        break;
85
106
    case float_round_to_zero:
86
107
        break;
87
108
    }
88
 
    return ret;
89
109
}
90
110
 
91
 
void helper_store_fpcr (uint64_t val)
 
111
void helper_store_fpcr (void)
92
112
{
93
113
#ifdef CONFIG_SOFTFLOAT
94
 
    set_float_exception_flags((val >> 52) & 0x3F, &FP_STATUS);
 
114
    set_float_exception_flags((T0 >> 52) & 0x3F, &FP_STATUS);
95
115
#endif
96
 
    switch ((val >> 58) & 3) {
 
116
    switch ((T0 >> 58) & 3) {
97
117
    case 0:
98
118
        set_float_rounding_mode(float_round_to_zero, &FP_STATUS);
99
119
        break;
109
129
    }
110
130
}
111
131
 
112
 
spinlock_t intr_cpu_lock = SPIN_LOCK_UNLOCKED;
113
 
 
114
 
uint64_t helper_rs(void)
115
 
{
116
 
    uint64_t tmp;
117
 
 
118
 
    spin_lock(&intr_cpu_lock);
119
 
    tmp = env->intr_flag;
120
 
    env->intr_flag = 1;
121
 
    spin_unlock(&intr_cpu_lock);
122
 
 
123
 
    return tmp;
124
 
}
125
 
 
126
 
uint64_t helper_rc(void)
127
 
{
128
 
    uint64_t tmp;
129
 
 
130
 
    spin_lock(&intr_cpu_lock);
131
 
    tmp = env->intr_flag;
132
 
    env->intr_flag = 0;
133
 
    spin_unlock(&intr_cpu_lock);
134
 
 
135
 
    return tmp;
136
 
}
137
 
 
138
 
uint64_t helper_addqv (uint64_t op1, uint64_t op2)
139
 
{
140
 
    uint64_t tmp = op1;
141
 
    op1 += op2;
142
 
    if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
143
 
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
144
 
    }
145
 
    return op1;
146
 
}
147
 
 
148
 
uint64_t helper_addlv (uint64_t op1, uint64_t op2)
149
 
{
150
 
    uint64_t tmp = op1;
151
 
    op1 = (uint32_t)(op1 + op2);
152
 
    if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
153
 
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
154
 
    }
155
 
    return op1;
156
 
}
157
 
 
158
 
uint64_t helper_subqv (uint64_t op1, uint64_t op2)
159
 
{
160
 
    uint64_t tmp = op1;
161
 
    op1 -= op2;
162
 
    if (unlikely(((~tmp) ^ op1 ^ (-1ULL)) & ((~tmp) ^ op2) & (1ULL << 63))) {
163
 
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
164
 
    }
165
 
    return op1;
166
 
}
167
 
 
168
 
uint64_t helper_sublv (uint64_t op1, uint64_t op2)
169
 
{
170
 
    uint64_t tmp = op1;
171
 
    op1 = (uint32_t)(op1 - op2);
172
 
    if (unlikely(((~tmp) ^ op1 ^ (-1UL)) & ((~tmp) ^ op2) & (1UL << 31))) {
173
 
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
174
 
    }
175
 
    return op1;
176
 
}
177
 
 
178
 
uint64_t helper_mullv (uint64_t op1, uint64_t op2)
179
 
{
180
 
    int64_t res = (int64_t)op1 * (int64_t)op2;
 
132
void helper_load_irf (void)
 
133
{
 
134
    /* XXX: TODO */
 
135
    T0 = 0;
 
136
}
 
137
 
 
138
void helper_set_irf (void)
 
139
{
 
140
    /* XXX: TODO */
 
141
}
 
142
 
 
143
void helper_clear_irf (void)
 
144
{
 
145
    /* XXX: TODO */
 
146
}
 
147
 
 
148
void helper_addqv (void)
 
149
{
 
150
    T2 = T0;
 
151
    T0 += T1;
 
152
    if (unlikely((T2 ^ T1 ^ (-1ULL)) & (T2 ^ T0) & (1ULL << 63))) {
 
153
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
 
154
    }
 
155
}
 
156
 
 
157
void helper_addlv (void)
 
158
{
 
159
    T2 = T0;
 
160
    T0 = (uint32_t)(T0 + T1);
 
161
    if (unlikely((T2 ^ T1 ^ (-1UL)) & (T2 ^ T0) & (1UL << 31))) {
 
162
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
 
163
    }
 
164
}
 
165
 
 
166
void helper_subqv (void)
 
167
{
 
168
    T2 = T0;
 
169
    T0 -= T1;
 
170
    if (unlikely(((~T2) ^ T0 ^ (-1ULL)) & ((~T2) ^ T1) & (1ULL << 63))) {
 
171
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
 
172
    }
 
173
}
 
174
 
 
175
void helper_sublv (void)
 
176
{
 
177
    T2 = T0;
 
178
    T0 = (uint32_t)(T0 - T1);
 
179
    if (unlikely(((~T2) ^ T0 ^ (-1UL)) & ((~T2) ^ T1) & (1UL << 31))) {
 
180
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
 
181
    }
 
182
}
 
183
 
 
184
void helper_mullv (void)
 
185
{
 
186
    int64_t res = (int64_t)T0 * (int64_t)T1;
181
187
 
182
188
    if (unlikely((int32_t)res != res)) {
183
189
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
184
190
    }
185
 
    return (int64_t)((int32_t)res);
 
191
    T0 = (int64_t)((int32_t)res);
186
192
}
187
193
 
188
 
uint64_t helper_mulqv (uint64_t op1, uint64_t op2)
 
194
void helper_mulqv ()
189
195
{
190
 
    uint64_t tl, th;
 
196
    uint64_t res, tmp0, tmp1;
191
197
 
192
 
    muls64(&tl, &th, op1, op2);
193
 
    /* If th != 0 && th != -1, then we had an overflow */
194
 
    if (unlikely((th + 1) > 1)) {
 
198
    res = (T0 >> 32) * (T1 >> 32);
 
199
    tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) +
 
200
        ((T0 >> 32) * (T1 & 0xFFFFFFFF));
 
201
    tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF);
 
202
    tmp0 += tmp1 >> 32;
 
203
    res += tmp0 >> 32;
 
204
    T0 *= T1;
 
205
    if (unlikely(res != 0)) {
195
206
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
196
207
    }
197
 
    return tl;
198
 
}
199
 
 
200
 
uint64_t helper_umulh (uint64_t op1, uint64_t op2)
201
 
{
202
 
    uint64_t tl, th;
203
 
 
204
 
    mulu64(&tl, &th, op1, op2);
205
 
    return th;
206
 
}
207
 
 
208
 
uint64_t helper_ctpop (uint64_t arg)
209
 
{
210
 
    return ctpop64(arg);
211
 
}
212
 
 
213
 
uint64_t helper_ctlz (uint64_t arg)
214
 
{
215
 
    return clz64(arg);
216
 
}
217
 
 
218
 
uint64_t helper_cttz (uint64_t arg)
219
 
{
220
 
    return ctz64(arg);
221
 
}
222
 
 
223
 
static always_inline uint64_t byte_zap (uint64_t op, uint8_t mskb)
 
208
}
 
209
 
 
210
void helper_umulh (void)
 
211
{
 
212
    uint64_t tmp0, tmp1;
 
213
 
 
214
    tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) +
 
215
        ((T0 >> 32) * (T1 & 0xFFFFFFFF));
 
216
    tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF);
 
217
    tmp0 += tmp1 >> 32;
 
218
    T0 = (T0 >> 32) * (T0 >> 32);
 
219
    T0 += tmp0 >> 32;
 
220
}
 
221
 
 
222
void helper_ctpop (void)
 
223
{
 
224
    int n;
 
225
 
 
226
    for (n = 0; T0 != 0; n++)
 
227
        T0 = T0 ^ (T0 - 1);
 
228
    T0 = n;
 
229
}
 
230
 
 
231
void helper_ctlz (void)
 
232
{
 
233
    uint32_t op32;
 
234
    int n;
 
235
 
 
236
    n = 0;
 
237
    if (!(T0 & 0xFFFFFFFF00000000ULL)) {
 
238
        n += 32;
 
239
        T0 <<= 32;
 
240
    }
 
241
    /* Make it easier for 32 bits hosts */
 
242
    op32 = T0 >> 32;
 
243
    if (!(op32 & 0xFFFF0000UL)) {
 
244
        n += 16;
 
245
        op32 <<= 16;
 
246
    }
 
247
    if (!(op32 & 0xFF000000UL)) {
 
248
        n += 8;
 
249
        op32 <<= 8;
 
250
    }
 
251
    if (!(op32 & 0xF0000000UL)) {
 
252
        n += 4;
 
253
        op32 <<= 4;
 
254
    }
 
255
    if (!(op32 & 0xC0000000UL)) {
 
256
        n += 2;
 
257
        op32 <<= 2;
 
258
    }
 
259
    if (!(op32 & 0x80000000UL)) {
 
260
        n++;
 
261
        op32 <<= 1;
 
262
    }
 
263
    if (!(op32 & 0x80000000UL)) {
 
264
        n++;
 
265
    }
 
266
    T0 = n;
 
267
}
 
268
 
 
269
void helper_cttz (void)
 
270
{
 
271
    uint32_t op32;
 
272
    int n;
 
273
 
 
274
    n = 0;
 
275
    if (!(T0 & 0x00000000FFFFFFFFULL)) {
 
276
        n += 32;
 
277
        T0 >>= 32;
 
278
    }
 
279
    /* Make it easier for 32 bits hosts */
 
280
    op32 = T0;
 
281
    if (!(op32 & 0x0000FFFFUL)) {
 
282
        n += 16;
 
283
        op32 >>= 16;
 
284
    }
 
285
    if (!(op32 & 0x000000FFUL)) {
 
286
        n += 8;
 
287
        op32 >>= 8;
 
288
    }
 
289
    if (!(op32 & 0x0000000FUL)) {
 
290
        n += 4;
 
291
        op32 >>= 4;
 
292
    }
 
293
    if (!(op32 & 0x00000003UL)) {
 
294
        n += 2;
 
295
        op32 >>= 2;
 
296
    }
 
297
    if (!(op32 & 0x00000001UL)) {
 
298
        n++;
 
299
        op32 >>= 1;
 
300
    }
 
301
    if (!(op32 & 0x00000001UL)) {
 
302
        n++;
 
303
    }
 
304
    T0 = n;
 
305
}
 
306
 
 
307
static inline uint64_t byte_zap (uint64_t op, uint8_t mskb)
224
308
{
225
309
    uint64_t mask;
226
310
 
237
321
    return op & ~mask;
238
322
}
239
323
 
240
 
uint64_t helper_mskbl(uint64_t val, uint64_t mask)
241
 
{
242
 
    return byte_zap(val, 0x01 << (mask & 7));
243
 
}
244
 
 
245
 
uint64_t helper_insbl(uint64_t val, uint64_t mask)
246
 
{
247
 
    val <<= (mask & 7) * 8;
248
 
    return byte_zap(val, ~(0x01 << (mask & 7)));
249
 
}
250
 
 
251
 
uint64_t helper_mskwl(uint64_t val, uint64_t mask)
252
 
{
253
 
    return byte_zap(val, 0x03 << (mask & 7));
254
 
}
255
 
 
256
 
uint64_t helper_inswl(uint64_t val, uint64_t mask)
257
 
{
258
 
    val <<= (mask & 7) * 8;
259
 
    return byte_zap(val, ~(0x03 << (mask & 7)));
260
 
}
261
 
 
262
 
uint64_t helper_mskll(uint64_t val, uint64_t mask)
263
 
{
264
 
    return byte_zap(val, 0x0F << (mask & 7));
265
 
}
266
 
 
267
 
uint64_t helper_insll(uint64_t val, uint64_t mask)
268
 
{
269
 
    val <<= (mask & 7) * 8;
270
 
    return byte_zap(val, ~(0x0F << (mask & 7)));
271
 
}
272
 
 
273
 
uint64_t helper_zap(uint64_t val, uint64_t mask)
274
 
{
275
 
    return byte_zap(val, mask);
276
 
}
277
 
 
278
 
uint64_t helper_zapnot(uint64_t val, uint64_t mask)
279
 
{
280
 
    return byte_zap(val, ~mask);
281
 
}
282
 
 
283
 
uint64_t helper_mskql(uint64_t val, uint64_t mask)
284
 
{
285
 
    return byte_zap(val, 0xFF << (mask & 7));
286
 
}
287
 
 
288
 
uint64_t helper_insql(uint64_t val, uint64_t mask)
289
 
{
290
 
    val <<= (mask & 7) * 8;
291
 
    return byte_zap(val, ~(0xFF << (mask & 7)));
292
 
}
293
 
 
294
 
uint64_t helper_mskwh(uint64_t val, uint64_t mask)
295
 
{
296
 
    return byte_zap(val, (0x03 << (mask & 7)) >> 8);
297
 
}
298
 
 
299
 
uint64_t helper_inswh(uint64_t val, uint64_t mask)
300
 
{
301
 
    val >>= 64 - ((mask & 7) * 8);
302
 
    return byte_zap(val, ~((0x03 << (mask & 7)) >> 8));
303
 
}
304
 
 
305
 
uint64_t helper_msklh(uint64_t val, uint64_t mask)
306
 
{
307
 
    return byte_zap(val, (0x0F << (mask & 7)) >> 8);
308
 
}
309
 
 
310
 
uint64_t helper_inslh(uint64_t val, uint64_t mask)
311
 
{
312
 
    val >>= 64 - ((mask & 7) * 8);
313
 
    return byte_zap(val, ~((0x0F << (mask & 7)) >> 8));
314
 
}
315
 
 
316
 
uint64_t helper_mskqh(uint64_t val, uint64_t mask)
317
 
{
318
 
    return byte_zap(val, (0xFF << (mask & 7)) >> 8);
319
 
}
320
 
 
321
 
uint64_t helper_insqh(uint64_t val, uint64_t mask)
322
 
{
323
 
    val >>= 64 - ((mask & 7) * 8);
324
 
    return byte_zap(val, ~((0xFF << (mask & 7)) >> 8));
325
 
}
326
 
 
327
 
uint64_t helper_cmpbge (uint64_t op1, uint64_t op2)
 
324
void helper_mskbl (void)
 
325
{
 
326
    T0 = byte_zap(T0, 0x01 << (T1 & 7));
 
327
}
 
328
 
 
329
void helper_extbl (void)
 
330
{
 
331
    T0 >>= (T1 & 7) * 8;
 
332
    T0 = byte_zap(T0, 0xFE);
 
333
}
 
334
 
 
335
void helper_insbl (void)
 
336
{
 
337
    T0 <<= (T1 & 7) * 8;
 
338
    T0 = byte_zap(T0, ~(0x01 << (T1 & 7)));
 
339
}
 
340
 
 
341
void helper_mskwl (void)
 
342
{
 
343
    T0 = byte_zap(T0, 0x03 << (T1 & 7));
 
344
}
 
345
 
 
346
void helper_extwl (void)
 
347
{
 
348
    T0 >>= (T1 & 7) * 8;
 
349
    T0 = byte_zap(T0, 0xFC);
 
350
}
 
351
 
 
352
void helper_inswl (void)
 
353
{
 
354
    T0 <<= (T1 & 7) * 8;
 
355
    T0 = byte_zap(T0, ~(0x03 << (T1 & 7)));
 
356
}
 
357
 
 
358
void helper_mskll (void)
 
359
{
 
360
    T0 = byte_zap(T0, 0x0F << (T1 & 7));
 
361
}
 
362
 
 
363
void helper_extll (void)
 
364
{
 
365
    T0 >>= (T1 & 7) * 8;
 
366
    T0 = byte_zap(T0, 0xF0);
 
367
}
 
368
 
 
369
void helper_insll (void)
 
370
{
 
371
    T0 <<= (T1 & 7) * 8;
 
372
    T0 = byte_zap(T0, ~(0x0F << (T1 & 7)));
 
373
}
 
374
 
 
375
void helper_zap (void)
 
376
{
 
377
    T0 = byte_zap(T0, T1);
 
378
}
 
379
 
 
380
void helper_zapnot (void)
 
381
{
 
382
    T0 = byte_zap(T0, ~T1);
 
383
}
 
384
 
 
385
void helper_mskql (void)
 
386
{
 
387
    T0 = byte_zap(T0, 0xFF << (T1 & 7));
 
388
}
 
389
 
 
390
void helper_extql (void)
 
391
{
 
392
    T0 >>= (T1 & 7) * 8;
 
393
    T0 = byte_zap(T0, 0x00);
 
394
}
 
395
 
 
396
void helper_insql (void)
 
397
{
 
398
    T0 <<= (T1 & 7) * 8;
 
399
    T0 = byte_zap(T0, ~(0xFF << (T1 & 7)));
 
400
}
 
401
 
 
402
void helper_mskwh (void)
 
403
{
 
404
    T0 = byte_zap(T0, (0x03 << (T1 & 7)) >> 8);
 
405
}
 
406
 
 
407
void helper_inswh (void)
 
408
{
 
409
    T0 >>= 64 - ((T1 & 7) * 8);
 
410
    T0 = byte_zap(T0, ~((0x03 << (T1 & 7)) >> 8));
 
411
}
 
412
 
 
413
void helper_extwh (void)
 
414
{
 
415
    T0 <<= 64 - ((T1 & 7) * 8);
 
416
    T0 = byte_zap(T0, ~0x07);
 
417
}
 
418
 
 
419
void helper_msklh (void)
 
420
{
 
421
    T0 = byte_zap(T0, (0x0F << (T1 & 7)) >> 8);
 
422
}
 
423
 
 
424
void helper_inslh (void)
 
425
{
 
426
    T0 >>= 64 - ((T1 & 7) * 8);
 
427
    T0 = byte_zap(T0, ~((0x0F << (T1 & 7)) >> 8));
 
428
}
 
429
 
 
430
void helper_extlh (void)
 
431
{
 
432
    T0 <<= 64 - ((T1 & 7) * 8);
 
433
    T0 = byte_zap(T0, ~0x0F);
 
434
}
 
435
 
 
436
void helper_mskqh (void)
 
437
{
 
438
    T0 = byte_zap(T0, (0xFF << (T1 & 7)) >> 8);
 
439
}
 
440
 
 
441
void helper_insqh (void)
 
442
{
 
443
    T0 >>= 64 - ((T1 & 7) * 8);
 
444
    T0 = byte_zap(T0, ~((0xFF << (T1 & 7)) >> 8));
 
445
}
 
446
 
 
447
void helper_extqh (void)
 
448
{
 
449
    T0 <<= 64 - ((T1 & 7) * 8);
 
450
    T0 = byte_zap(T0, 0x00);
 
451
}
 
452
 
 
453
void helper_cmpbge (void)
328
454
{
329
455
    uint8_t opa, opb, res;
330
456
    int i;
331
457
 
332
458
    res = 0;
333
 
    for (i = 0; i < 8; i++) {
334
 
        opa = op1 >> (i * 8);
335
 
        opb = op2 >> (i * 8);
 
459
    for (i = 0; i < 7; i++) {
 
460
        opa = T0 >> (i * 8);
 
461
        opb = T1 >> (i * 8);
336
462
        if (opa >= opb)
337
463
            res |= 1 << i;
338
464
    }
339
 
    return res;
340
 
}
341
 
 
342
 
/* Floating point helpers */
343
 
 
344
 
/* F floating (VAX) */
345
 
static always_inline uint64_t float32_to_f (float32 fa)
346
 
{
347
 
    uint32_t a;
348
 
    uint64_t r, exp, mant, sig;
349
 
 
350
 
    a = *(uint32_t*)(&fa);
351
 
    sig = ((uint64_t)a & 0x80000000) << 32;
352
 
    exp = (a >> 23) & 0xff;
353
 
    mant = ((uint64_t)a & 0x007fffff) << 29;
354
 
 
 
465
    T0 = res;
 
466
}
 
467
 
 
468
void helper_cmov_fir (int freg)
 
469
{
 
470
    if (FT0 != 0)
 
471
        env->fir[freg] = FT1;
 
472
}
 
473
 
 
474
void helper_sqrts (void)
 
475
{
 
476
    FT0 = float32_sqrt(FT0, &FP_STATUS);
 
477
}
 
478
 
 
479
void helper_cpys (void)
 
480
{
 
481
    union {
 
482
        double d;
 
483
        uint64_t i;
 
484
    } p, q, r;
 
485
 
 
486
    p.d = FT0;
 
487
    q.d = FT1;
 
488
    r.i = p.i & 0x8000000000000000ULL;
 
489
    r.i |= q.i & ~0x8000000000000000ULL;
 
490
    FT0 = r.d;
 
491
}
 
492
 
 
493
void helper_cpysn (void)
 
494
{
 
495
    union {
 
496
        double d;
 
497
        uint64_t i;
 
498
    } p, q, r;
 
499
 
 
500
    p.d = FT0;
 
501
    q.d = FT1;
 
502
    r.i = (~p.i) & 0x8000000000000000ULL;
 
503
    r.i |= q.i & ~0x8000000000000000ULL;
 
504
    FT0 = r.d;
 
505
}
 
506
 
 
507
void helper_cpyse (void)
 
508
{
 
509
    union {
 
510
        double d;
 
511
        uint64_t i;
 
512
    } p, q, r;
 
513
 
 
514
    p.d = FT0;
 
515
    q.d = FT1;
 
516
    r.i = p.i & 0xFFF0000000000000ULL;
 
517
    r.i |= q.i & ~0xFFF0000000000000ULL;
 
518
    FT0 = r.d;
 
519
}
 
520
 
 
521
void helper_itofs (void)
 
522
{
 
523
    union {
 
524
        double d;
 
525
        uint64_t i;
 
526
    } p;
 
527
 
 
528
    p.d = FT0;
 
529
    FT0 = int64_to_float32(p.i, &FP_STATUS);
 
530
}
 
531
 
 
532
void helper_ftois (void)
 
533
{
 
534
    union {
 
535
        double d;
 
536
        uint64_t i;
 
537
    } p;
 
538
 
 
539
    p.i = float32_to_int64(FT0, &FP_STATUS);
 
540
    FT0 = p.d;
 
541
}
 
542
 
 
543
void helper_sqrtt (void)
 
544
{
 
545
    FT0 = float64_sqrt(FT0, &FP_STATUS);
 
546
}
 
547
 
 
548
void helper_cmptun (void)
 
549
{
 
550
    union {
 
551
        double d;
 
552
        uint64_t i;
 
553
    } p;
 
554
 
 
555
    p.i = 0;
 
556
    if (float64_is_nan(FT0) || float64_is_nan(FT1))
 
557
        p.i = 0x4000000000000000ULL;
 
558
    FT0 = p.d;
 
559
}
 
560
 
 
561
void helper_cmpteq (void)
 
562
{
 
563
    union {
 
564
        double d;
 
565
        uint64_t i;
 
566
    } p;
 
567
 
 
568
    p.i = 0;
 
569
    if (float64_eq(FT0, FT1, &FP_STATUS))
 
570
        p.i = 0x4000000000000000ULL;
 
571
    FT0 = p.d;
 
572
}
 
573
 
 
574
void helper_cmptle (void)
 
575
{
 
576
    union {
 
577
        double d;
 
578
        uint64_t i;
 
579
    } p;
 
580
 
 
581
    p.i = 0;
 
582
    if (float64_le(FT0, FT1, &FP_STATUS))
 
583
        p.i = 0x4000000000000000ULL;
 
584
    FT0 = p.d;
 
585
}
 
586
 
 
587
void helper_cmptlt (void)
 
588
{
 
589
    union {
 
590
        double d;
 
591
        uint64_t i;
 
592
    } p;
 
593
 
 
594
    p.i = 0;
 
595
    if (float64_lt(FT0, FT1, &FP_STATUS))
 
596
        p.i = 0x4000000000000000ULL;
 
597
    FT0 = p.d;
 
598
}
 
599
 
 
600
void helper_itoft (void)
 
601
{
 
602
    union {
 
603
        double d;
 
604
        uint64_t i;
 
605
    } p;
 
606
 
 
607
    p.d = FT0;
 
608
    FT0 = int64_to_float64(p.i, &FP_STATUS);
 
609
}
 
610
 
 
611
void helper_ftoit (void)
 
612
{
 
613
    union {
 
614
        double d;
 
615
        uint64_t i;
 
616
    } p;
 
617
 
 
618
    p.i = float64_to_int64(FT0, &FP_STATUS);
 
619
    FT0 = p.d;
 
620
}
 
621
 
 
622
static int vaxf_is_valid (float ff)
 
623
{
 
624
    union {
 
625
        float f;
 
626
        uint32_t i;
 
627
    } p;
 
628
    uint32_t exp, mant;
 
629
 
 
630
    p.f = ff;
 
631
    exp = (p.i >> 23) & 0xFF;
 
632
    mant = p.i & 0x007FFFFF;
 
633
    if (exp == 0 && ((p.i & 0x80000000) || mant != 0)) {
 
634
        /* Reserved operands / Dirty zero */
 
635
        return 0;
 
636
    }
 
637
 
 
638
    return 1;
 
639
}
 
640
 
 
641
static float vaxf_to_ieee32 (float ff)
 
642
{
 
643
    union {
 
644
        float f;
 
645
        uint32_t i;
 
646
    } p;
 
647
    uint32_t exp;
 
648
 
 
649
    p.f = ff;
 
650
    exp = (p.i >> 23) & 0xFF;
 
651
    if (exp < 3) {
 
652
        /* Underflow */
 
653
        p.f = 0.0;
 
654
    } else {
 
655
        p.f *= 0.25;
 
656
    }
 
657
 
 
658
    return p.f;
 
659
}
 
660
 
 
661
static float ieee32_to_vaxf (float fi)
 
662
{
 
663
    union {
 
664
        float f;
 
665
        uint32_t i;
 
666
    } p;
 
667
    uint32_t exp, mant;
 
668
 
 
669
    p.f = fi;
 
670
    exp = (p.i >> 23) & 0xFF;
 
671
    mant = p.i & 0x007FFFFF;
355
672
    if (exp == 255) {
356
673
        /* NaN or infinity */
357
 
        r = 1; /* VAX dirty zero */
 
674
        p.i = 1;
358
675
    } else if (exp == 0) {
359
676
        if (mant == 0) {
360
677
            /* Zero */
361
 
            r = 0;
 
678
            p.i = 0;
362
679
        } else {
363
680
            /* Denormalized */
364
 
            r = sig | ((exp + 1) << 52) | mant;
 
681
            p.f *= 2.0;
365
682
        }
366
683
    } else {
367
684
        if (exp >= 253) {
368
685
            /* Overflow */
369
 
            r = 1; /* VAX dirty zero */
 
686
            p.i = 1;
370
687
        } else {
371
 
            r = sig | ((exp + 2) << 52);
 
688
            p.f *= 4.0;
372
689
        }
373
690
    }
374
691
 
375
 
    return r;
376
 
}
377
 
 
378
 
static always_inline float32 f_to_float32 (uint64_t a)
379
 
{
380
 
    uint32_t r, exp, mant_sig;
381
 
 
382
 
    exp = ((a >> 55) & 0x80) | ((a >> 52) & 0x7f);
383
 
    mant_sig = ((a >> 32) & 0x80000000) | ((a >> 29) & 0x007fffff);
384
 
 
385
 
    if (unlikely(!exp && mant_sig)) {
 
692
    return p.f;
 
693
}
 
694
 
 
695
void helper_addf (void)
 
696
{
 
697
    float ft0, ft1, ft2;
 
698
 
 
699
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
 
700
        /* XXX: TODO */
 
701
    }
 
702
    ft0 = vaxf_to_ieee32(FT0);
 
703
    ft1 = vaxf_to_ieee32(FT1);
 
704
    ft2 = float32_add(ft0, ft1, &FP_STATUS);
 
705
    FT0 = ieee32_to_vaxf(ft2);
 
706
}
 
707
 
 
708
void helper_subf (void)
 
709
{
 
710
    float ft0, ft1, ft2;
 
711
 
 
712
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
 
713
        /* XXX: TODO */
 
714
    }
 
715
    ft0 = vaxf_to_ieee32(FT0);
 
716
    ft1 = vaxf_to_ieee32(FT1);
 
717
    ft2 = float32_sub(ft0, ft1, &FP_STATUS);
 
718
    FT0 = ieee32_to_vaxf(ft2);
 
719
}
 
720
 
 
721
void helper_mulf (void)
 
722
{
 
723
    float ft0, ft1, ft2;
 
724
 
 
725
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
 
726
        /* XXX: TODO */
 
727
    }
 
728
    ft0 = vaxf_to_ieee32(FT0);
 
729
    ft1 = vaxf_to_ieee32(FT1);
 
730
    ft2 = float32_mul(ft0, ft1, &FP_STATUS);
 
731
    FT0 = ieee32_to_vaxf(ft2);
 
732
}
 
733
 
 
734
void helper_divf (void)
 
735
{
 
736
    float ft0, ft1, ft2;
 
737
 
 
738
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
 
739
        /* XXX: TODO */
 
740
    }
 
741
    ft0 = vaxf_to_ieee32(FT0);
 
742
    ft1 = vaxf_to_ieee32(FT1);
 
743
    ft2 = float32_div(ft0, ft1, &FP_STATUS);
 
744
    FT0 = ieee32_to_vaxf(ft2);
 
745
}
 
746
 
 
747
void helper_sqrtf (void)
 
748
{
 
749
    float ft0, ft1;
 
750
 
 
751
    if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
 
752
        /* XXX: TODO */
 
753
    }
 
754
    ft0 = vaxf_to_ieee32(FT0);
 
755
    ft1 = float32_sqrt(ft0, &FP_STATUS);
 
756
    FT0 = ieee32_to_vaxf(ft1);
 
757
}
 
758
 
 
759
void helper_itoff (void)
 
760
{
 
761
    /* XXX: TODO */
 
762
}
 
763
 
 
764
static int vaxg_is_valid (double ff)
 
765
{
 
766
    union {
 
767
        double f;
 
768
        uint64_t i;
 
769
    } p;
 
770
    uint64_t exp, mant;
 
771
 
 
772
    p.f = ff;
 
773
    exp = (p.i >> 52) & 0x7FF;
 
774
    mant = p.i & 0x000FFFFFFFFFFFFFULL;
 
775
    if (exp == 0 && ((p.i & 0x8000000000000000ULL) || mant != 0)) {
386
776
        /* Reserved operands / Dirty zero */
387
 
        helper_excp(EXCP_OPCDEC, 0);
 
777
        return 0;
388
778
    }
389
779
 
 
780
    return 1;
 
781
}
 
782
 
 
783
static double vaxg_to_ieee64 (double fg)
 
784
{
 
785
    union {
 
786
        double f;
 
787
        uint64_t i;
 
788
    } p;
 
789
    uint32_t exp;
 
790
 
 
791
    p.f = fg;
 
792
    exp = (p.i >> 52) & 0x7FF;
390
793
    if (exp < 3) {
391
794
        /* Underflow */
392
 
        r = 0;
 
795
        p.f = 0.0;
393
796
    } else {
394
 
        r = ((exp - 2) << 23) | mant_sig;
 
797
        p.f *= 0.25;
395
798
    }
396
799
 
397
 
    return *(float32*)(&a);
398
 
}
399
 
 
400
 
uint32_t helper_f_to_memory (uint64_t a)
401
 
{
402
 
    uint32_t r;
403
 
    r =  (a & 0x00001fffe0000000ull) >> 13;
404
 
    r |= (a & 0x07ffe00000000000ull) >> 45;
405
 
    r |= (a & 0xc000000000000000ull) >> 48;
406
 
    return r;
407
 
}
408
 
 
409
 
uint64_t helper_memory_to_f (uint32_t a)
410
 
{
411
 
    uint64_t r;
412
 
    r =  ((uint64_t)(a & 0x0000c000)) << 48;
413
 
    r |= ((uint64_t)(a & 0x003fffff)) << 45;
414
 
    r |= ((uint64_t)(a & 0xffff0000)) << 13;
415
 
    if (!(a & 0x00004000))
416
 
        r |= 0x7ll << 59;
417
 
    return r;
418
 
}
419
 
 
420
 
uint64_t helper_addf (uint64_t a, uint64_t b)
421
 
{
422
 
    float32 fa, fb, fr;
423
 
 
424
 
    fa = f_to_float32(a);
425
 
    fb = f_to_float32(b);
426
 
    fr = float32_add(fa, fb, &FP_STATUS);
427
 
    return float32_to_f(fr);
428
 
}
429
 
 
430
 
uint64_t helper_subf (uint64_t a, uint64_t b)
431
 
{
432
 
    float32 fa, fb, fr;
433
 
 
434
 
    fa = f_to_float32(a);
435
 
    fb = f_to_float32(b);
436
 
    fr = float32_sub(fa, fb, &FP_STATUS);
437
 
    return float32_to_f(fr);
438
 
}
439
 
 
440
 
uint64_t helper_mulf (uint64_t a, uint64_t b)
441
 
{
442
 
    float32 fa, fb, fr;
443
 
 
444
 
    fa = f_to_float32(a);
445
 
    fb = f_to_float32(b);
446
 
    fr = float32_mul(fa, fb, &FP_STATUS);
447
 
    return float32_to_f(fr);
448
 
}
449
 
 
450
 
uint64_t helper_divf (uint64_t a, uint64_t b)
451
 
{
452
 
    float32 fa, fb, fr;
453
 
 
454
 
    fa = f_to_float32(a);
455
 
    fb = f_to_float32(b);
456
 
    fr = float32_div(fa, fb, &FP_STATUS);
457
 
    return float32_to_f(fr);
458
 
}
459
 
 
460
 
uint64_t helper_sqrtf (uint64_t t)
461
 
{
462
 
    float32 ft, fr;
463
 
 
464
 
    ft = f_to_float32(t);
465
 
    fr = float32_sqrt(ft, &FP_STATUS);
466
 
    return float32_to_f(fr);
467
 
}
468
 
 
469
 
 
470
 
/* G floating (VAX) */
471
 
static always_inline uint64_t float64_to_g (float64 fa)
472
 
{
473
 
    uint64_t a, r, exp, mant, sig;
474
 
 
475
 
    a = *(uint64_t*)(&fa);
476
 
    sig = a & 0x8000000000000000ull;
477
 
    exp = (a >> 52) & 0x7ff;
478
 
    mant = a & 0x000fffffffffffffull;
479
 
 
480
 
    if (exp == 2047) {
 
800
    return p.f;
 
801
}
 
802
 
 
803
static double ieee64_to_vaxg (double fi)
 
804
{
 
805
    union {
 
806
        double f;
 
807
        uint64_t i;
 
808
    } p;
 
809
    uint64_t mant;
 
810
    uint32_t exp;
 
811
 
 
812
    p.f = fi;
 
813
    exp = (p.i >> 52) & 0x7FF;
 
814
    mant = p.i & 0x000FFFFFFFFFFFFFULL;
 
815
    if (exp == 255) {
481
816
        /* NaN or infinity */
482
 
        r = 1; /* VAX dirty zero */
 
817
        p.i = 1; /* VAX dirty zero */
483
818
    } else if (exp == 0) {
484
819
        if (mant == 0) {
485
820
            /* Zero */
486
 
            r = 0;
 
821
            p.i = 0;
487
822
        } else {
488
823
            /* Denormalized */
489
 
            r = sig | ((exp + 1) << 52) | mant;
 
824
            p.f *= 2.0;
490
825
        }
491
826
    } else {
492
827
        if (exp >= 2045) {
493
828
            /* Overflow */
494
 
            r = 1; /* VAX dirty zero */
 
829
            p.i = 1; /* VAX dirty zero */
495
830
        } else {
496
 
            r = sig | ((exp + 2) << 52);
 
831
            p.f *= 4.0;
497
832
        }
498
833
    }
499
834
 
500
 
    return r;
501
 
}
502
 
 
503
 
static always_inline float64 g_to_float64 (uint64_t a)
504
 
{
505
 
    uint64_t r, exp, mant_sig;
506
 
 
507
 
    exp = (a >> 52) & 0x7ff;
508
 
    mant_sig = a & 0x800fffffffffffffull;
509
 
 
510
 
    if (!exp && mant_sig) {
511
 
        /* Reserved operands / Dirty zero */
512
 
        helper_excp(EXCP_OPCDEC, 0);
513
 
    }
514
 
 
515
 
    if (exp < 3) {
516
 
        /* Underflow */
517
 
        r = 0;
518
 
    } else {
519
 
        r = ((exp - 2) << 52) | mant_sig;
520
 
    }
521
 
 
522
 
    return *(float64*)(&a);
523
 
}
524
 
 
525
 
uint64_t helper_g_to_memory (uint64_t a)
526
 
{
527
 
    uint64_t r;
528
 
    r =  (a & 0x000000000000ffffull) << 48;
529
 
    r |= (a & 0x00000000ffff0000ull) << 16;
530
 
    r |= (a & 0x0000ffff00000000ull) >> 16;
531
 
    r |= (a & 0xffff000000000000ull) >> 48;
532
 
    return r;
533
 
}
534
 
 
535
 
uint64_t helper_memory_to_g (uint64_t a)
536
 
{
537
 
    uint64_t r;
538
 
    r =  (a & 0x000000000000ffffull) << 48;
539
 
    r |= (a & 0x00000000ffff0000ull) << 16;
540
 
    r |= (a & 0x0000ffff00000000ull) >> 16;
541
 
    r |= (a & 0xffff000000000000ull) >> 48;
542
 
    return r;
543
 
}
544
 
 
545
 
uint64_t helper_addg (uint64_t a, uint64_t b)
546
 
{
547
 
    float64 fa, fb, fr;
548
 
 
549
 
    fa = g_to_float64(a);
550
 
    fb = g_to_float64(b);
551
 
    fr = float64_add(fa, fb, &FP_STATUS);
552
 
    return float64_to_g(fr);
553
 
}
554
 
 
555
 
uint64_t helper_subg (uint64_t a, uint64_t b)
556
 
{
557
 
    float64 fa, fb, fr;
558
 
 
559
 
    fa = g_to_float64(a);
560
 
    fb = g_to_float64(b);
561
 
    fr = float64_sub(fa, fb, &FP_STATUS);
562
 
    return float64_to_g(fr);
563
 
}
564
 
 
565
 
uint64_t helper_mulg (uint64_t a, uint64_t b)
566
 
{
567
 
    float64 fa, fb, fr;
568
 
 
569
 
    fa = g_to_float64(a);
570
 
    fb = g_to_float64(b);
571
 
    fr = float64_mul(fa, fb, &FP_STATUS);
572
 
    return float64_to_g(fr);
573
 
}
574
 
 
575
 
uint64_t helper_divg (uint64_t a, uint64_t b)
576
 
{
577
 
    float64 fa, fb, fr;
578
 
 
579
 
    fa = g_to_float64(a);
580
 
    fb = g_to_float64(b);
581
 
    fr = float64_div(fa, fb, &FP_STATUS);
582
 
    return float64_to_g(fr);
583
 
}
584
 
 
585
 
uint64_t helper_sqrtg (uint64_t a)
586
 
{
587
 
    float64 fa, fr;
588
 
 
589
 
    fa = g_to_float64(a);
590
 
    fr = float64_sqrt(fa, &FP_STATUS);
591
 
    return float64_to_g(fr);
592
 
}
593
 
 
594
 
 
595
 
/* S floating (single) */
596
 
static always_inline uint64_t float32_to_s (float32 fa)
597
 
{
598
 
    uint32_t a;
599
 
    uint64_t r;
600
 
 
601
 
    a = *(uint32_t*)(&fa);
602
 
 
603
 
    r = (((uint64_t)(a & 0xc0000000)) << 32) | (((uint64_t)(a & 0x3fffffff)) << 29);
604
 
    if (((a & 0x7f800000) != 0x7f800000) && (!(a & 0x40000000)))
605
 
        r |= 0x7ll << 59;
606
 
    return r;
607
 
}
608
 
 
609
 
static always_inline float32 s_to_float32 (uint64_t a)
610
 
{
611
 
    uint32_t r = ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff);
612
 
    return *(float32*)(&r);
613
 
}
614
 
 
615
 
uint32_t helper_s_to_memory (uint64_t a)
616
 
{
617
 
    /* Memory format is the same as float32 */
618
 
    float32 fa = s_to_float32(a);
619
 
    return *(uint32_t*)(&fa);
620
 
}
621
 
 
622
 
uint64_t helper_memory_to_s (uint32_t a)
623
 
{
624
 
    /* Memory format is the same as float32 */
625
 
    return float32_to_s(*(float32*)(&a));
626
 
}
627
 
 
628
 
uint64_t helper_adds (uint64_t a, uint64_t b)
629
 
{
630
 
    float32 fa, fb, fr;
631
 
 
632
 
    fa = s_to_float32(a);
633
 
    fb = s_to_float32(b);
634
 
    fr = float32_add(fa, fb, &FP_STATUS);
635
 
    return float32_to_s(fr);
636
 
}
637
 
 
638
 
uint64_t helper_subs (uint64_t a, uint64_t b)
639
 
{
640
 
    float32 fa, fb, fr;
641
 
 
642
 
    fa = s_to_float32(a);
643
 
    fb = s_to_float32(b);
644
 
    fr = float32_sub(fa, fb, &FP_STATUS);
645
 
    return float32_to_s(fr);
646
 
}
647
 
 
648
 
uint64_t helper_muls (uint64_t a, uint64_t b)
649
 
{
650
 
    float32 fa, fb, fr;
651
 
 
652
 
    fa = s_to_float32(a);
653
 
    fb = s_to_float32(b);
654
 
    fr = float32_mul(fa, fb, &FP_STATUS);
655
 
    return float32_to_s(fr);
656
 
}
657
 
 
658
 
uint64_t helper_divs (uint64_t a, uint64_t b)
659
 
{
660
 
    float32 fa, fb, fr;
661
 
 
662
 
    fa = s_to_float32(a);
663
 
    fb = s_to_float32(b);
664
 
    fr = float32_div(fa, fb, &FP_STATUS);
665
 
    return float32_to_s(fr);
666
 
}
667
 
 
668
 
uint64_t helper_sqrts (uint64_t a)
669
 
{
670
 
    float32 fa, fr;
671
 
 
672
 
    fa = s_to_float32(a);
673
 
    fr = float32_sqrt(fa, &FP_STATUS);
674
 
    return float32_to_s(fr);
675
 
}
676
 
 
677
 
 
678
 
/* T floating (double) */
679
 
static always_inline float64 t_to_float64 (uint64_t a)
680
 
{
681
 
    /* Memory format is the same as float64 */
682
 
    return *(float64*)(&a);
683
 
}
684
 
 
685
 
static always_inline uint64_t float64_to_t (float64 fa)
686
 
{
687
 
    /* Memory format is the same as float64 */
688
 
    return *(uint64*)(&fa);
689
 
}
690
 
 
691
 
uint64_t helper_addt (uint64_t a, uint64_t b)
692
 
{
693
 
    float64 fa, fb, fr;
694
 
 
695
 
    fa = t_to_float64(a);
696
 
    fb = t_to_float64(b);
697
 
    fr = float64_add(fa, fb, &FP_STATUS);
698
 
    return float64_to_t(fr);
699
 
}
700
 
 
701
 
uint64_t helper_subt (uint64_t a, uint64_t b)
702
 
{
703
 
    float64 fa, fb, fr;
704
 
 
705
 
    fa = t_to_float64(a);
706
 
    fb = t_to_float64(b);
707
 
    fr = float64_sub(fa, fb, &FP_STATUS);
708
 
    return float64_to_t(fr);
709
 
}
710
 
 
711
 
uint64_t helper_mult (uint64_t a, uint64_t b)
712
 
{
713
 
    float64 fa, fb, fr;
714
 
 
715
 
    fa = t_to_float64(a);
716
 
    fb = t_to_float64(b);
717
 
    fr = float64_mul(fa, fb, &FP_STATUS);
718
 
    return float64_to_t(fr);
719
 
}
720
 
 
721
 
uint64_t helper_divt (uint64_t a, uint64_t b)
722
 
{
723
 
    float64 fa, fb, fr;
724
 
 
725
 
    fa = t_to_float64(a);
726
 
    fb = t_to_float64(b);
727
 
    fr = float64_div(fa, fb, &FP_STATUS);
728
 
    return float64_to_t(fr);
729
 
}
730
 
 
731
 
uint64_t helper_sqrtt (uint64_t a)
732
 
{
733
 
    float64 fa, fr;
734
 
 
735
 
    fa = t_to_float64(a);
736
 
    fr = float64_sqrt(fa, &FP_STATUS);
737
 
    return float64_to_t(fr);
738
 
}
739
 
 
740
 
 
741
 
/* Sign copy */
742
 
uint64_t helper_cpys(uint64_t a, uint64_t b)
743
 
{
744
 
    return (a & 0x8000000000000000ULL) | (b & ~0x8000000000000000ULL);
745
 
}
746
 
 
747
 
uint64_t helper_cpysn(uint64_t a, uint64_t b)
748
 
{
749
 
    return ((~a) & 0x8000000000000000ULL) | (b & ~0x8000000000000000ULL);
750
 
}
751
 
 
752
 
uint64_t helper_cpyse(uint64_t a, uint64_t b)
753
 
{
754
 
    return (a & 0xFFF0000000000000ULL) | (b & ~0xFFF0000000000000ULL);
755
 
}
756
 
 
757
 
 
758
 
/* Comparisons */
759
 
uint64_t helper_cmptun (uint64_t a, uint64_t b)
760
 
{
761
 
    float64 fa, fb;
762
 
 
763
 
    fa = t_to_float64(a);
764
 
    fb = t_to_float64(b);
765
 
 
766
 
    if (float64_is_nan(fa) || float64_is_nan(fb))
767
 
        return 0x4000000000000000ULL;
768
 
    else
769
 
        return 0;
770
 
}
771
 
 
772
 
uint64_t helper_cmpteq(uint64_t a, uint64_t b)
773
 
{
774
 
    float64 fa, fb;
775
 
 
776
 
    fa = t_to_float64(a);
777
 
    fb = t_to_float64(b);
778
 
 
779
 
    if (float64_eq(fa, fb, &FP_STATUS))
780
 
        return 0x4000000000000000ULL;
781
 
    else
782
 
        return 0;
783
 
}
784
 
 
785
 
uint64_t helper_cmptle(uint64_t a, uint64_t b)
786
 
{
787
 
    float64 fa, fb;
788
 
 
789
 
    fa = t_to_float64(a);
790
 
    fb = t_to_float64(b);
791
 
 
792
 
    if (float64_le(fa, fb, &FP_STATUS))
793
 
        return 0x4000000000000000ULL;
794
 
    else
795
 
        return 0;
796
 
}
797
 
 
798
 
uint64_t helper_cmptlt(uint64_t a, uint64_t b)
799
 
{
800
 
    float64 fa, fb;
801
 
 
802
 
    fa = t_to_float64(a);
803
 
    fb = t_to_float64(b);
804
 
 
805
 
    if (float64_lt(fa, fb, &FP_STATUS))
806
 
        return 0x4000000000000000ULL;
807
 
    else
808
 
        return 0;
809
 
}
810
 
 
811
 
uint64_t helper_cmpgeq(uint64_t a, uint64_t b)
812
 
{
813
 
    float64 fa, fb;
814
 
 
815
 
    fa = g_to_float64(a);
816
 
    fb = g_to_float64(b);
817
 
 
818
 
    if (float64_eq(fa, fb, &FP_STATUS))
819
 
        return 0x4000000000000000ULL;
820
 
    else
821
 
        return 0;
822
 
}
823
 
 
824
 
uint64_t helper_cmpgle(uint64_t a, uint64_t b)
825
 
{
826
 
    float64 fa, fb;
827
 
 
828
 
    fa = g_to_float64(a);
829
 
    fb = g_to_float64(b);
830
 
 
831
 
    if (float64_le(fa, fb, &FP_STATUS))
832
 
        return 0x4000000000000000ULL;
833
 
    else
834
 
        return 0;
835
 
}
836
 
 
837
 
uint64_t helper_cmpglt(uint64_t a, uint64_t b)
838
 
{
839
 
    float64 fa, fb;
840
 
 
841
 
    fa = g_to_float64(a);
842
 
    fb = g_to_float64(b);
843
 
 
844
 
    if (float64_lt(fa, fb, &FP_STATUS))
845
 
        return 0x4000000000000000ULL;
846
 
    else
847
 
        return 0;
848
 
}
849
 
 
850
 
uint64_t helper_cmpfeq (uint64_t a)
851
 
{
852
 
    return !(a & 0x7FFFFFFFFFFFFFFFULL);
853
 
}
854
 
 
855
 
uint64_t helper_cmpfne (uint64_t a)
856
 
{
857
 
    return (a & 0x7FFFFFFFFFFFFFFFULL);
858
 
}
859
 
 
860
 
uint64_t helper_cmpflt (uint64_t a)
861
 
{
862
 
    return (a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL);
863
 
}
864
 
 
865
 
uint64_t helper_cmpfle (uint64_t a)
866
 
{
867
 
    return (a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL);
868
 
}
869
 
 
870
 
uint64_t helper_cmpfgt (uint64_t a)
871
 
{
872
 
    return !(a & 0x8000000000000000ULL) && (a & 0x7FFFFFFFFFFFFFFFULL);
873
 
}
874
 
 
875
 
uint64_t helper_cmpfge (uint64_t a)
876
 
{
877
 
    return !(a & 0x8000000000000000ULL) || !(a & 0x7FFFFFFFFFFFFFFFULL);
878
 
}
879
 
 
880
 
 
881
 
/* Floating point format conversion */
882
 
uint64_t helper_cvtts (uint64_t a)
883
 
{
884
 
    float64 fa;
885
 
    float32 fr;
886
 
 
887
 
    fa = t_to_float64(a);
888
 
    fr = float64_to_float32(fa, &FP_STATUS);
889
 
    return float32_to_s(fr);
890
 
}
891
 
 
892
 
uint64_t helper_cvtst (uint64_t a)
893
 
{
894
 
    float32 fa;
895
 
    float64 fr;
896
 
 
897
 
    fa = s_to_float32(a);
898
 
    fr = float32_to_float64(fa, &FP_STATUS);
899
 
    return float64_to_t(fr);
900
 
}
901
 
 
902
 
uint64_t helper_cvtqs (uint64_t a)
903
 
{
904
 
    float32 fr = int64_to_float32(a, &FP_STATUS);
905
 
    return float32_to_s(fr);
906
 
}
907
 
 
908
 
uint64_t helper_cvttq (uint64_t a)
909
 
{
910
 
    float64 fa = t_to_float64(a);
911
 
    return float64_to_int64_round_to_zero(fa, &FP_STATUS);
912
 
}
913
 
 
914
 
uint64_t helper_cvtqt (uint64_t a)
915
 
{
916
 
    float64 fr = int64_to_float64(a, &FP_STATUS);
917
 
    return float64_to_t(fr);
918
 
}
919
 
 
920
 
uint64_t helper_cvtqf (uint64_t a)
921
 
{
922
 
    float32 fr = int64_to_float32(a, &FP_STATUS);
923
 
    return float32_to_f(fr);
924
 
}
925
 
 
926
 
uint64_t helper_cvtgf (uint64_t a)
927
 
{
928
 
    float64 fa;
929
 
    float32 fr;
930
 
 
931
 
    fa = g_to_float64(a);
932
 
    fr = float64_to_float32(fa, &FP_STATUS);
933
 
    return float32_to_f(fr);
934
 
}
935
 
 
936
 
uint64_t helper_cvtgq (uint64_t a)
937
 
{
938
 
    float64 fa = g_to_float64(a);
939
 
    return float64_to_int64_round_to_zero(fa, &FP_STATUS);
940
 
}
941
 
 
942
 
uint64_t helper_cvtqg (uint64_t a)
943
 
{
944
 
    float64 fr;
945
 
    fr = int64_to_float64(a, &FP_STATUS);
946
 
    return float64_to_g(fr);
947
 
}
948
 
 
949
 
uint64_t helper_cvtlq (uint64_t a)
950
 
{
951
 
    return (int64_t)((int32_t)((a >> 32) | ((a >> 29) & 0x3FFFFFFF)));
952
 
}
953
 
 
954
 
static always_inline uint64_t __helper_cvtql (uint64_t a, int s, int v)
955
 
{
956
 
    uint64_t r;
957
 
 
958
 
    r = ((uint64_t)(a & 0xC0000000)) << 32;
959
 
    r |= ((uint64_t)(a & 0x7FFFFFFF)) << 29;
960
 
 
961
 
    if (v && (int64_t)((int32_t)r) != (int64_t)r) {
 
835
    return p.f;
 
836
}
 
837
 
 
838
void helper_addg (void)
 
839
{
 
840
    double ft0, ft1, ft2;
 
841
 
 
842
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
 
843
        /* XXX: TODO */
 
844
    }
 
845
    ft0 = vaxg_to_ieee64(FT0);
 
846
    ft1 = vaxg_to_ieee64(FT1);
 
847
    ft2 = float64_add(ft0, ft1, &FP_STATUS);
 
848
    FT0 = ieee64_to_vaxg(ft2);
 
849
}
 
850
 
 
851
void helper_subg (void)
 
852
{
 
853
    double ft0, ft1, ft2;
 
854
 
 
855
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
 
856
        /* XXX: TODO */
 
857
    }
 
858
    ft0 = vaxg_to_ieee64(FT0);
 
859
    ft1 = vaxg_to_ieee64(FT1);
 
860
    ft2 = float64_sub(ft0, ft1, &FP_STATUS);
 
861
    FT0 = ieee64_to_vaxg(ft2);
 
862
}
 
863
 
 
864
void helper_mulg (void)
 
865
{
 
866
    double ft0, ft1, ft2;
 
867
 
 
868
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
 
869
        /* XXX: TODO */
 
870
    }
 
871
    ft0 = vaxg_to_ieee64(FT0);
 
872
    ft1 = vaxg_to_ieee64(FT1);
 
873
    ft2 = float64_mul(ft0, ft1, &FP_STATUS);
 
874
    FT0 = ieee64_to_vaxg(ft2);
 
875
}
 
876
 
 
877
void helper_divg (void)
 
878
{
 
879
    double ft0, ft1, ft2;
 
880
 
 
881
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
 
882
        /* XXX: TODO */
 
883
    }
 
884
    ft0 = vaxg_to_ieee64(FT0);
 
885
    ft1 = vaxg_to_ieee64(FT1);
 
886
    ft2 = float64_div(ft0, ft1, &FP_STATUS);
 
887
    FT0 = ieee64_to_vaxg(ft2);
 
888
}
 
889
 
 
890
void helper_sqrtg (void)
 
891
{
 
892
    double ft0, ft1;
 
893
 
 
894
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
 
895
        /* XXX: TODO */
 
896
    }
 
897
    ft0 = vaxg_to_ieee64(FT0);
 
898
    ft1 = float64_sqrt(ft0, &FP_STATUS);
 
899
    FT0 = ieee64_to_vaxg(ft1);
 
900
}
 
901
 
 
902
void helper_cmpgeq (void)
 
903
{
 
904
    union {
 
905
        double d;
 
906
        uint64_t u;
 
907
    } p;
 
908
    double ft0, ft1;
 
909
 
 
910
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
 
911
        /* XXX: TODO */
 
912
    }
 
913
    ft0 = vaxg_to_ieee64(FT0);
 
914
    ft1 = vaxg_to_ieee64(FT1);
 
915
    p.u = 0;
 
916
    if (float64_eq(ft0, ft1, &FP_STATUS))
 
917
        p.u = 0x4000000000000000ULL;
 
918
    FT0 = p.d;
 
919
}
 
920
 
 
921
void helper_cmpglt (void)
 
922
{
 
923
    union {
 
924
        double d;
 
925
        uint64_t u;
 
926
    } p;
 
927
    double ft0, ft1;
 
928
 
 
929
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
 
930
        /* XXX: TODO */
 
931
    }
 
932
    ft0 = vaxg_to_ieee64(FT0);
 
933
    ft1 = vaxg_to_ieee64(FT1);
 
934
    p.u = 0;
 
935
    if (float64_lt(ft0, ft1, &FP_STATUS))
 
936
        p.u = 0x4000000000000000ULL;
 
937
    FT0 = p.d;
 
938
}
 
939
 
 
940
void helper_cmpgle (void)
 
941
{
 
942
    union {
 
943
        double d;
 
944
        uint64_t u;
 
945
    } p;
 
946
    double ft0, ft1;
 
947
 
 
948
    if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
 
949
        /* XXX: TODO */
 
950
    }
 
951
    ft0 = vaxg_to_ieee64(FT0);
 
952
    ft1 = vaxg_to_ieee64(FT1);
 
953
    p.u = 0;
 
954
    if (float64_le(ft0, ft1, &FP_STATUS))
 
955
        p.u = 0x4000000000000000ULL;
 
956
    FT0 = p.d;
 
957
}
 
958
 
 
959
void helper_cvtqs (void)
 
960
{
 
961
    union {
 
962
        double d;
 
963
        uint64_t u;
 
964
    } p;
 
965
 
 
966
    p.d = FT0;
 
967
    FT0 = (float)p.u;
 
968
}
 
969
 
 
970
void helper_cvttq (void)
 
971
{
 
972
    union {
 
973
        double d;
 
974
        uint64_t u;
 
975
    } p;
 
976
 
 
977
    p.u = FT0;
 
978
    FT0 = p.d;
 
979
}
 
980
 
 
981
void helper_cvtqt (void)
 
982
{
 
983
    union {
 
984
        double d;
 
985
        uint64_t u;
 
986
    } p;
 
987
 
 
988
    p.d = FT0;
 
989
    FT0 = p.u;
 
990
}
 
991
 
 
992
void helper_cvtqf (void)
 
993
{
 
994
    union {
 
995
        double d;
 
996
        uint64_t u;
 
997
    } p;
 
998
 
 
999
    p.d = FT0;
 
1000
    FT0 = ieee32_to_vaxf(p.u);
 
1001
}
 
1002
 
 
1003
void helper_cvtgf (void)
 
1004
{
 
1005
    double ft0;
 
1006
 
 
1007
    ft0 = vaxg_to_ieee64(FT0);
 
1008
    FT0 = ieee32_to_vaxf(ft0);
 
1009
}
 
1010
 
 
1011
void helper_cvtgd (void)
 
1012
{
 
1013
    /* XXX: TODO */
 
1014
}
 
1015
 
 
1016
void helper_cvtgq (void)
 
1017
{
 
1018
    union {
 
1019
        double d;
 
1020
        uint64_t u;
 
1021
    } p;
 
1022
 
 
1023
    p.u = vaxg_to_ieee64(FT0);
 
1024
    FT0 = p.d;
 
1025
}
 
1026
 
 
1027
void helper_cvtqg (void)
 
1028
{
 
1029
    union {
 
1030
        double d;
 
1031
        uint64_t u;
 
1032
    } p;
 
1033
 
 
1034
    p.d = FT0;
 
1035
    FT0 = ieee64_to_vaxg(p.u);
 
1036
}
 
1037
 
 
1038
void helper_cvtdg (void)
 
1039
{
 
1040
    /* XXX: TODO */
 
1041
}
 
1042
 
 
1043
void helper_cvtlq (void)
 
1044
{
 
1045
    union {
 
1046
        double d;
 
1047
        uint64_t u;
 
1048
    } p, q;
 
1049
 
 
1050
    p.d = FT0;
 
1051
    q.u = (p.u >> 29) & 0x3FFFFFFF;
 
1052
    q.u |= (p.u >> 32);
 
1053
    q.u = (int64_t)((int32_t)q.u);
 
1054
    FT0 = q.d;
 
1055
}
 
1056
 
 
1057
static inline void __helper_cvtql (int s, int v)
 
1058
{
 
1059
    union {
 
1060
        double d;
 
1061
        uint64_t u;
 
1062
    } p, q;
 
1063
 
 
1064
    p.d = FT0;
 
1065
    q.u = ((uint64_t)(p.u & 0xC0000000)) << 32;
 
1066
    q.u |= ((uint64_t)(p.u & 0x7FFFFFFF)) << 29;
 
1067
    FT0 = q.d;
 
1068
    if (v && (int64_t)((int32_t)p.u) != (int64_t)p.u) {
962
1069
        helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
963
1070
    }
964
1071
    if (s) {
965
1072
        /* TODO */
966
1073
    }
967
 
    return r;
968
 
}
969
 
 
970
 
uint64_t helper_cvtql (uint64_t a)
971
 
{
972
 
    return __helper_cvtql(a, 0, 0);
973
 
}
974
 
 
975
 
uint64_t helper_cvtqlv (uint64_t a)
976
 
{
977
 
    return __helper_cvtql(a, 0, 1);
978
 
}
979
 
 
980
 
uint64_t helper_cvtqlsv (uint64_t a)
981
 
{
982
 
    return __helper_cvtql(a, 1, 1);
983
 
}
984
 
 
985
 
/* PALcode support special instructions */
 
1074
}
 
1075
 
 
1076
void helper_cvtql (void)
 
1077
{
 
1078
    __helper_cvtql(0, 0);
 
1079
}
 
1080
 
 
1081
void helper_cvtqlv (void)
 
1082
{
 
1083
    __helper_cvtql(0, 1);
 
1084
}
 
1085
 
 
1086
void helper_cvtqlsv (void)
 
1087
{
 
1088
    __helper_cvtql(1, 1);
 
1089
}
 
1090
 
 
1091
void helper_cmpfeq (void)
 
1092
{
 
1093
    if (float64_eq(FT0, FT1, &FP_STATUS))
 
1094
        T0 = 1;
 
1095
    else
 
1096
        T0 = 0;
 
1097
}
 
1098
 
 
1099
void helper_cmpfne (void)
 
1100
{
 
1101
    if (float64_eq(FT0, FT1, &FP_STATUS))
 
1102
        T0 = 0;
 
1103
    else
 
1104
        T0 = 1;
 
1105
}
 
1106
 
 
1107
void helper_cmpflt (void)
 
1108
{
 
1109
    if (float64_lt(FT0, FT1, &FP_STATUS))
 
1110
        T0 = 1;
 
1111
    else
 
1112
        T0 = 0;
 
1113
}
 
1114
 
 
1115
void helper_cmpfle (void)
 
1116
{
 
1117
    if (float64_lt(FT0, FT1, &FP_STATUS))
 
1118
        T0 = 1;
 
1119
    else
 
1120
        T0 = 0;
 
1121
}
 
1122
 
 
1123
void helper_cmpfgt (void)
 
1124
{
 
1125
    if (float64_le(FT0, FT1, &FP_STATUS))
 
1126
        T0 = 0;
 
1127
    else
 
1128
        T0 = 1;
 
1129
}
 
1130
 
 
1131
void helper_cmpfge (void)
 
1132
{
 
1133
    if (float64_lt(FT0, FT1, &FP_STATUS))
 
1134
        T0 = 0;
 
1135
    else
 
1136
        T0 = 1;
 
1137
}
 
1138
 
986
1139
#if !defined (CONFIG_USER_ONLY)
987
 
void helper_hw_rei (void)
988
 
{
989
 
    env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
990
 
    env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
991
 
    /* XXX: re-enable interrupts and memory mapping */
992
 
}
993
 
 
994
 
void helper_hw_ret (uint64_t a)
995
 
{
996
 
    env->pc = a & ~3;
997
 
    env->ipr[IPR_EXC_ADDR] = a & 1;
998
 
    /* XXX: re-enable interrupts and memory mapping */
999
 
}
1000
 
 
1001
 
uint64_t helper_mfpr (int iprn, uint64_t val)
1002
 
{
1003
 
    uint64_t tmp;
1004
 
 
1005
 
    if (cpu_alpha_mfpr(env, iprn, &tmp) == 0)
1006
 
        val = tmp;
1007
 
 
1008
 
    return val;
1009
 
}
1010
 
 
1011
 
void helper_mtpr (int iprn, uint64_t val)
1012
 
{
1013
 
    cpu_alpha_mtpr(env, iprn, val, NULL);
1014
 
}
1015
 
 
1016
 
void helper_set_alt_mode (void)
1017
 
{
1018
 
    env->saved_mode = env->ps & 0xC;
1019
 
    env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
1020
 
}
1021
 
 
1022
 
void helper_restore_mode (void)
1023
 
{
1024
 
    env->ps = (env->ps & ~0xC) | env->saved_mode;
1025
 
}
1026
 
 
 
1140
void helper_mfpr (int iprn)
 
1141
{
 
1142
    uint64_t val;
 
1143
 
 
1144
    if (cpu_alpha_mfpr(env, iprn, &val) == 0)
 
1145
        T0 = val;
 
1146
}
 
1147
 
 
1148
void helper_mtpr (int iprn)
 
1149
{
 
1150
    cpu_alpha_mtpr(env, iprn, T0, NULL);
 
1151
}
1027
1152
#endif
1028
1153
 
1029
1154
/*****************************************************************************/
1030
1155
/* Softmmu support */
1031
1156
#if !defined (CONFIG_USER_ONLY)
1032
1157
 
 
1158
#define GETPC() (__builtin_return_address(0))
 
1159
 
1033
1160
/* XXX: the two following helpers are pure hacks.
1034
1161
 *      Hopefully, we emulate the PALcode, then we should never see
1035
1162
 *      HW_LD / HW_ST instructions.
1036
1163
 */
1037
 
uint64_t helper_ld_virt_to_phys (uint64_t virtaddr)
1038
 
{
1039
 
    uint64_t tlb_addr, physaddr;
1040
 
    int index, mmu_idx;
1041
 
    void *retaddr;
1042
 
 
1043
 
    mmu_idx = cpu_mmu_index(env);
1044
 
    index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1045
 
 redo:
1046
 
    tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
1047
 
    if ((virtaddr & TARGET_PAGE_MASK) ==
1048
 
        (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1049
 
        physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend;
1050
 
    } else {
1051
 
        /* the page is not in the TLB : fill it */
1052
 
        retaddr = GETPC();
1053
 
        tlb_fill(virtaddr, 0, mmu_idx, retaddr);
1054
 
        goto redo;
1055
 
    }
1056
 
    return physaddr;
1057
 
}
1058
 
 
1059
 
uint64_t helper_st_virt_to_phys (uint64_t virtaddr)
1060
 
{
1061
 
    uint64_t tlb_addr, physaddr;
1062
 
    int index, mmu_idx;
1063
 
    void *retaddr;
1064
 
 
1065
 
    mmu_idx = cpu_mmu_index(env);
1066
 
    index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1067
 
 redo:
1068
 
    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
1069
 
    if ((virtaddr & TARGET_PAGE_MASK) ==
1070
 
        (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1071
 
        physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend;
1072
 
    } else {
1073
 
        /* the page is not in the TLB : fill it */
1074
 
        retaddr = GETPC();
1075
 
        tlb_fill(virtaddr, 1, mmu_idx, retaddr);
1076
 
        goto redo;
1077
 
    }
1078
 
    return physaddr;
1079
 
}
1080
 
 
1081
 
void helper_ldl_raw(uint64_t t0, uint64_t t1)
1082
 
{
1083
 
    ldl_raw(t1, t0);
1084
 
}
1085
 
 
1086
 
void helper_ldq_raw(uint64_t t0, uint64_t t1)
1087
 
{
1088
 
    ldq_raw(t1, t0);
1089
 
}
1090
 
 
1091
 
void helper_ldl_l_raw(uint64_t t0, uint64_t t1)
1092
 
{
1093
 
    env->lock = t1;
1094
 
    ldl_raw(t1, t0);
1095
 
}
1096
 
 
1097
 
void helper_ldq_l_raw(uint64_t t0, uint64_t t1)
1098
 
{
1099
 
    env->lock = t1;
1100
 
    ldl_raw(t1, t0);
1101
 
}
1102
 
 
1103
 
void helper_ldl_kernel(uint64_t t0, uint64_t t1)
1104
 
{
1105
 
    ldl_kernel(t1, t0);
1106
 
}
1107
 
 
1108
 
void helper_ldq_kernel(uint64_t t0, uint64_t t1)
1109
 
{
1110
 
    ldq_kernel(t1, t0);
1111
 
}
1112
 
 
1113
 
void helper_ldl_data(uint64_t t0, uint64_t t1)
1114
 
{
1115
 
    ldl_data(t1, t0);
1116
 
}
1117
 
 
1118
 
void helper_ldq_data(uint64_t t0, uint64_t t1)
1119
 
{
1120
 
    ldq_data(t1, t0);
1121
 
}
1122
 
 
1123
 
void helper_stl_raw(uint64_t t0, uint64_t t1)
1124
 
{
1125
 
    stl_raw(t1, t0);
1126
 
}
1127
 
 
1128
 
void helper_stq_raw(uint64_t t0, uint64_t t1)
1129
 
{
1130
 
    stq_raw(t1, t0);
1131
 
}
1132
 
 
1133
 
uint64_t helper_stl_c_raw(uint64_t t0, uint64_t t1)
1134
 
{
1135
 
    uint64_t ret;
1136
 
 
1137
 
    if (t1 == env->lock) {
1138
 
        stl_raw(t1, t0);
1139
 
        ret = 0;
1140
 
    } else
1141
 
        ret = 1;
1142
 
 
1143
 
    env->lock = 1;
1144
 
 
1145
 
    return ret;
1146
 
}
1147
 
 
1148
 
uint64_t helper_stq_c_raw(uint64_t t0, uint64_t t1)
1149
 
{
1150
 
    uint64_t ret;
1151
 
 
1152
 
    if (t1 == env->lock) {
1153
 
        stq_raw(t1, t0);
1154
 
        ret = 0;
1155
 
    } else
1156
 
        ret = 1;
1157
 
 
1158
 
    env->lock = 1;
1159
 
 
1160
 
    return ret;
 
1164
void helper_ld_phys_to_virt (void)
 
1165
{
 
1166
    uint64_t tlb_addr, physaddr;
 
1167
    int index, is_user;
 
1168
    void *retaddr;
 
1169
 
 
1170
    is_user = (env->ps >> 3) & 3;
 
1171
    index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
 
1172
 redo:
 
1173
    tlb_addr = env->tlb_table[is_user][index].addr_read;
 
1174
    if ((T0 & TARGET_PAGE_MASK) ==
 
1175
        (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
 
1176
        physaddr = T0 + env->tlb_table[is_user][index].addend;
 
1177
    } else {
 
1178
        /* the page is not in the TLB : fill it */
 
1179
        retaddr = GETPC();
 
1180
        tlb_fill(T0, 0, is_user, retaddr);
 
1181
        goto redo;
 
1182
    }
 
1183
    T0 = physaddr;
 
1184
}
 
1185
 
 
1186
void helper_st_phys_to_virt (void)
 
1187
{
 
1188
    uint64_t tlb_addr, physaddr;
 
1189
    int index, is_user;
 
1190
    void *retaddr;
 
1191
 
 
1192
    is_user = (env->ps >> 3) & 3;
 
1193
    index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
 
1194
 redo:
 
1195
    tlb_addr = env->tlb_table[is_user][index].addr_write;
 
1196
    if ((T0 & TARGET_PAGE_MASK) ==
 
1197
        (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
 
1198
        physaddr = T0 + env->tlb_table[is_user][index].addend;
 
1199
    } else {
 
1200
        /* the page is not in the TLB : fill it */
 
1201
        retaddr = GETPC();
 
1202
        tlb_fill(T0, 1, is_user, retaddr);
 
1203
        goto redo;
 
1204
    }
 
1205
    T0 = physaddr;
1161
1206
}
1162
1207
 
1163
1208
#define MMUSUFFIX _mmu
1178
1223
   NULL, it means that the function was called in C code (i.e. not
1179
1224
   from generated code or from helper.c) */
1180
1225
/* XXX: fix it to restore all registers */
1181
 
void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 
1226
void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
1182
1227
{
1183
1228
    TranslationBlock *tb;
1184
1229
    CPUState *saved_env;
1185
 
    unsigned long pc;
 
1230
    target_phys_addr_t pc;
1186
1231
    int ret;
1187
1232
 
1188
1233
    /* XXX: hack to restore env in all cases, even if not called from
1189
1234
       generated code */
1190
1235
    saved_env = env;
1191
1236
    env = cpu_single_env;
1192
 
    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
 
1237
    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, is_user, 1);
1193
1238
    if (!likely(ret == 0)) {
1194
1239
        if (likely(retaddr)) {
1195
1240
            /* now we have a real cpu fault */
1196
 
            pc = (unsigned long)retaddr;
 
1241
            pc = (target_phys_addr_t)retaddr;
1197
1242
            tb = tb_find_pc(pc);
1198
1243
            if (likely(tb)) {
1199
1244
                /* the PC is inside the translated code. It means that we have