Statistics
| Branch: | Revision:

root / target-alpha / op.c @ 01ff9cc8

History | View | Annotate | Download (9 kB)

1
/*
2
 *  Alpha emulation cpu micro-operations for qemu.
3
 *
4
 *  Copyright (c) 2007 Jocelyn Mayer
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

    
21
#define DEBUG_OP
22

    
23
#include "config.h"
24
#include "exec.h"
25
#include "host-utils.h"
26

    
27
#include "op_helper.h"
28

    
29
#define REG 0
30
#include "op_template.h"
31

    
32
#define REG 1
33
#include "op_template.h"
34

    
35
#define REG 2
36
#include "op_template.h"
37

    
38
#define REG 3
39
#include "op_template.h"
40

    
41
#define REG 4
42
#include "op_template.h"
43

    
44
#define REG 5
45
#include "op_template.h"
46

    
47
#define REG 6
48
#include "op_template.h"
49

    
50
#define REG 7
51
#include "op_template.h"
52

    
53
#define REG 8
54
#include "op_template.h"
55

    
56
#define REG 9
57
#include "op_template.h"
58

    
59
#define REG 10
60
#include "op_template.h"
61

    
62
#define REG 11
63
#include "op_template.h"
64

    
65
#define REG 12
66
#include "op_template.h"
67

    
68
#define REG 13
69
#include "op_template.h"
70

    
71
#define REG 14
72
#include "op_template.h"
73

    
74
#define REG 15
75
#include "op_template.h"
76

    
77
#define REG 16
78
#include "op_template.h"
79

    
80
#define REG 17
81
#include "op_template.h"
82

    
83
#define REG 18
84
#include "op_template.h"
85

    
86
#define REG 19
87
#include "op_template.h"
88

    
89
#define REG 20
90
#include "op_template.h"
91

    
92
#define REG 21
93
#include "op_template.h"
94

    
95
#define REG 22
96
#include "op_template.h"
97

    
98
#define REG 23
99
#include "op_template.h"
100

    
101
#define REG 24
102
#include "op_template.h"
103

    
104
#define REG 25
105
#include "op_template.h"
106

    
107
#define REG 26
108
#include "op_template.h"
109

    
110
#define REG 27
111
#include "op_template.h"
112

    
113
#define REG 28
114
#include "op_template.h"
115

    
116
#define REG 29
117
#include "op_template.h"
118

    
119
#define REG 30
120
#include "op_template.h"
121

    
122
#define REG 31
123
#include "op_template.h"
124

    
125
/* Debug stuff */
126
void OPPROTO op_no_op (void)
127
{
128
#if !defined (DEBUG_OP)
129
    __asm__ __volatile__("nop" : : : "memory");
130
#endif
131
    RETURN();
132
}
133

    
134
/* Load and stores */
135
#define MEMSUFFIX _raw
136
#include "op_mem.h"
137
#if !defined(CONFIG_USER_ONLY)
138
#define MEMSUFFIX _kernel
139
#include "op_mem.h"
140
#define MEMSUFFIX _executive
141
#include "op_mem.h"
142
#define MEMSUFFIX _supervisor
143
#include "op_mem.h"
144
#define MEMSUFFIX _user
145
#include "op_mem.h"
146
/* This is used for pal modes */
147
#define MEMSUFFIX _data
148
#include "op_mem.h"
149
#endif
150

    
151
/* Misc */
152
void OPPROTO op_load_fpcr (void)
153
{
154
    helper_load_fpcr();
155
    RETURN();
156
}
157

    
158
void OPPROTO op_store_fpcr (void)
159
{
160
    helper_store_fpcr();
161
    RETURN();
162
}
163

    
164
/* Arithmetic */
165
void OPPROTO op_addqv (void)
166
{
167
    helper_addqv();
168
    RETURN();
169
}
170

    
171
void OPPROTO op_addlv (void)
172
{
173
    helper_addlv();
174
    RETURN();
175
}
176

    
177
void OPPROTO op_subqv (void)
178
{
179
    helper_subqv();
180
    RETURN();
181
}
182

    
183
void OPPROTO op_sublv (void)
184
{
185
    helper_sublv();
186
    RETURN();
187
}
188

    
189
void OPPROTO op_mullv (void)
190
{
191
    helper_mullv();
192
    RETURN();
193
}
194

    
195
void OPPROTO op_mulqv (void)
196
{
197
    helper_mulqv();
198
    RETURN();
199
}
200

    
201
void OPPROTO op_umulh (void)
202
{
203
    uint64_t tl, th;
204

    
205
    mulu64(&tl, &th, T0, T1);
206
    T0 = th;
207
    RETURN();
208
}
209

    
210
/* Tests */
211
void OPPROTO op_cmpbge (void)
212
{
213
    helper_cmpbge();
214
    RETURN();
215
}
216

    
217
#if 0 // Qemu does not know how to do this...
218
void OPPROTO op_bcond (void)
219
{
220
    if (T0)
221
        env->pc = T1 & ~3;
222
    else
223
        env->pc = PARAM(1);
224
    RETURN();
225
}
226
#else
227
void OPPROTO op_bcond (void)
228
{
229
    if (T0)
230
        env->pc = T1 & ~3;
231
    else
232
        env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
233
    RETURN();
234
}
235
#endif
236

    
237
/* IEEE floating point arithmetic */
238
/* S floating (single) */
239
void OPPROTO op_adds (void)
240
{
241
    FT0 = float32_add(FT0, FT1, &FP_STATUS);
242
    RETURN();
243
}
244

    
245
void OPPROTO op_subs (void)
246
{
247
    FT0 = float32_sub(FT0, FT1, &FP_STATUS);
248
    RETURN();
249
}
250

    
251
void OPPROTO op_muls (void)
252
{
253
    FT0 = float32_mul(FT0, FT1, &FP_STATUS);
254
    RETURN();
255
}
256

    
257
void OPPROTO op_divs (void)
258
{
259
    FT0 = float32_div(FT0, FT1, &FP_STATUS);
260
    RETURN();
261
}
262

    
263
void OPPROTO op_sqrts (void)
264
{
265
    helper_sqrts();
266
    RETURN();
267
}
268

    
269
void OPPROTO op_cpys (void)
270
{
271
    helper_cpys();
272
    RETURN();
273
}
274

    
275
void OPPROTO op_cpysn (void)
276
{
277
    helper_cpysn();
278
    RETURN();
279
}
280

    
281
void OPPROTO op_cpyse (void)
282
{
283
    helper_cpyse();
284
    RETURN();
285
}
286

    
287
void OPPROTO op_itofs (void)
288
{
289
    helper_itofs();
290
    RETURN();
291
}
292

    
293
void OPPROTO op_ftois (void)
294
{
295
    helper_ftois();
296
    RETURN();
297
}
298

    
299
/* T floating (double) */
300
void OPPROTO op_addt (void)
301
{
302
    FT0 = float64_add(FT0, FT1, &FP_STATUS);
303
    RETURN();
304
}
305

    
306
void OPPROTO op_subt (void)
307
{
308
    FT0 = float64_sub(FT0, FT1, &FP_STATUS);
309
    RETURN();
310
}
311

    
312
void OPPROTO op_mult (void)
313
{
314
    FT0 = float64_mul(FT0, FT1, &FP_STATUS);
315
    RETURN();
316
}
317

    
318
void OPPROTO op_divt (void)
319
{
320
    FT0 = float64_div(FT0, FT1, &FP_STATUS);
321
    RETURN();
322
}
323

    
324
void OPPROTO op_sqrtt (void)
325
{
326
    helper_sqrtt();
327
    RETURN();
328
}
329

    
330
void OPPROTO op_cmptun (void)
331
{
332
    helper_cmptun();
333
    RETURN();
334
}
335

    
336
void OPPROTO op_cmpteq (void)
337
{
338
    helper_cmpteq();
339
    RETURN();
340
}
341

    
342
void OPPROTO op_cmptle (void)
343
{
344
    helper_cmptle();
345
    RETURN();
346
}
347

    
348
void OPPROTO op_cmptlt (void)
349
{
350
    helper_cmptlt();
351
    RETURN();
352
}
353

    
354
void OPPROTO op_itoft (void)
355
{
356
    helper_itoft();
357
    RETURN();
358
}
359

    
360
void OPPROTO op_ftoit (void)
361
{
362
    helper_ftoit();
363
    RETURN();
364
}
365

    
366
/* VAX floating point arithmetic */
367
/* F floating */
368
void OPPROTO op_addf (void)
369
{
370
    helper_addf();
371
    RETURN();
372
}
373

    
374
void OPPROTO op_subf (void)
375
{
376
    helper_subf();
377
    RETURN();
378
}
379

    
380
void OPPROTO op_mulf (void)
381
{
382
    helper_mulf();
383
    RETURN();
384
}
385

    
386
void OPPROTO op_divf (void)
387
{
388
    helper_divf();
389
    RETURN();
390
}
391

    
392
void OPPROTO op_sqrtf (void)
393
{
394
    helper_sqrtf();
395
    RETURN();
396
}
397

    
398
void OPPROTO op_cmpfeq (void)
399
{
400
    helper_cmpfeq();
401
    RETURN();
402
}
403

    
404
void OPPROTO op_cmpfne (void)
405
{
406
    helper_cmpfne();
407
    RETURN();
408
}
409

    
410
void OPPROTO op_cmpflt (void)
411
{
412
    helper_cmpflt();
413
    RETURN();
414
}
415

    
416
void OPPROTO op_cmpfle (void)
417
{
418
    helper_cmpfle();
419
    RETURN();
420
}
421

    
422
void OPPROTO op_cmpfgt (void)
423
{
424
    helper_cmpfgt();
425
    RETURN();
426
}
427

    
428
void OPPROTO op_cmpfge (void)
429
{
430
    helper_cmpfge();
431
    RETURN();
432
}
433

    
434
void OPPROTO op_itoff (void)
435
{
436
    helper_itoff();
437
    RETURN();
438
}
439

    
440
/* G floating */
441
void OPPROTO op_addg (void)
442
{
443
    helper_addg();
444
    RETURN();
445
}
446

    
447
void OPPROTO op_subg (void)
448
{
449
    helper_subg();
450
    RETURN();
451
}
452

    
453
void OPPROTO op_mulg (void)
454
{
455
    helper_mulg();
456
    RETURN();
457
}
458

    
459
void OPPROTO op_divg (void)
460
{
461
    helper_divg();
462
    RETURN();
463
}
464

    
465
void OPPROTO op_sqrtg (void)
466
{
467
    helper_sqrtg();
468
    RETURN();
469
}
470

    
471
void OPPROTO op_cmpgeq (void)
472
{
473
    helper_cmpgeq();
474
    RETURN();
475
}
476

    
477
void OPPROTO op_cmpglt (void)
478
{
479
    helper_cmpglt();
480
    RETURN();
481
}
482

    
483
void OPPROTO op_cmpgle (void)
484
{
485
    helper_cmpgle();
486
    RETURN();
487
}
488

    
489
/* Floating point format conversion */
490
void OPPROTO op_cvtst (void)
491
{
492
    FT0 = (float)FT0;
493
    RETURN();
494
}
495

    
496
void OPPROTO op_cvtqs (void)
497
{
498
    helper_cvtqs();
499
    RETURN();
500
}
501

    
502
void OPPROTO op_cvtts (void)
503
{
504
    FT0 = (float)FT0;
505
    RETURN();
506
}
507

    
508
void OPPROTO op_cvttq (void)
509
{
510
    helper_cvttq();
511
    RETURN();
512
}
513

    
514
void OPPROTO op_cvtqt (void)
515
{
516
    helper_cvtqt();
517
    RETURN();
518
}
519

    
520
void OPPROTO op_cvtqf (void)
521
{
522
    helper_cvtqf();
523
    RETURN();
524
}
525

    
526
void OPPROTO op_cvtgf (void)
527
{
528
    helper_cvtgf();
529
    RETURN();
530
}
531

    
532
void OPPROTO op_cvtgd (void)
533
{
534
    helper_cvtgd();
535
    RETURN();
536
}
537

    
538
void OPPROTO op_cvtgq (void)
539
{
540
    helper_cvtgq();
541
    RETURN();
542
}
543

    
544
void OPPROTO op_cvtqg (void)
545
{
546
    helper_cvtqg();
547
    RETURN();
548
}
549

    
550
void OPPROTO op_cvtdg (void)
551
{
552
    helper_cvtdg();
553
    RETURN();
554
}
555

    
556
void OPPROTO op_cvtlq (void)
557
{
558
    helper_cvtlq();
559
    RETURN();
560
}
561

    
562
void OPPROTO op_cvtql (void)
563
{
564
    helper_cvtql();
565
    RETURN();
566
}
567

    
568
void OPPROTO op_cvtqlv (void)
569
{
570
    helper_cvtqlv();
571
    RETURN();
572
}
573

    
574
void OPPROTO op_cvtqlsv (void)
575
{
576
    helper_cvtqlsv();
577
    RETURN();
578
}
579

    
580
/* PALcode support special instructions */
581
#if !defined (CONFIG_USER_ONLY)
582
void OPPROTO op_hw_rei (void)
583
{
584
    env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
585
    env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
586
    /* XXX: re-enable interrupts and memory mapping */
587
    RETURN();
588
}
589

    
590
void OPPROTO op_hw_ret (void)
591
{
592
    env->pc = T0 & ~3;
593
    env->ipr[IPR_EXC_ADDR] = T0 & 1;
594
    /* XXX: re-enable interrupts and memory mapping */
595
    RETURN();
596
}
597

    
598
void OPPROTO op_mfpr (void)
599
{
600
    helper_mfpr(PARAM(1));
601
    RETURN();
602
}
603

    
604
void OPPROTO op_mtpr (void)
605
{
606
    helper_mtpr(PARAM(1));
607
    RETURN();
608
}
609

    
610
void OPPROTO op_set_alt_mode (void)
611
{
612
    env->saved_mode = env->ps & 0xC;
613
    env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
614
    RETURN();
615
}
616

    
617
void OPPROTO op_restore_mode (void)
618
{
619
    env->ps = (env->ps & ~0xC) | env->saved_mode;
620
    RETURN();
621
}
622

    
623
void OPPROTO op_ld_phys_to_virt (void)
624
{
625
    helper_ld_phys_to_virt();
626
    RETURN();
627
}
628

    
629
void OPPROTO op_st_phys_to_virt (void)
630
{
631
    helper_st_phys_to_virt();
632
    RETURN();
633
}
634
#endif /* !defined (CONFIG_USER_ONLY) */