OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc3/] [or1ksim/] [cpu/] [or32/] [op.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1452 nogj
/* op.c -- Micro operations for the recompiler
2
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program 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
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
 
21
#include <stdio.h>
22
#include <stdint.h>
23
#include <stdlib.h>
24
 
25
#include "config.h"
26
 
27
#ifdef HAVE_INTTYPES_H
28
#include <inttypes.h>
29
#endif
30
 
31
#include "port.h"
32
#include "arch.h"
33
#include "spr_defs.h"
34
#include "opcode/or32.h"
35
#include "sim-config.h"
36
#include "except.h"
37
#include "abstract.h"
38
#include "execute.h"
39
#include "sprs.h"
40
#include "sched.h"
41
 
42
#include "op_support.h"
43
 
44
#include "i386_regs.h"
45
 
46
#include "dyn_rec.h"
47
 
48
/* This must be here since the function in op_i386.h use this variable */
49
register struct cpu_state *env asm(CPU_STATE_REG);
50
 
51
#include "op_i386.h"
52
 
53
/*
54 1549 nogj
 * WARNING: Before going of and wildly editing everything in this file remember
55 1452 nogj
 * the following about its contents:
56
 * 1) The `functions' don't EVER return.  In otherwords haveing return state-
57
 *    ments _anywere_ in this file is likely not to work.  This is because
58
 *    dyngen just strips away the ret from the end of the function and just uses
59
 *    the function `body'.  If a ret statement is executed _anyware_ inside the
60
 *    dynamicly generated code, then it is undefined were we shall jump to.
61
 * 2) Because of 1), try not to have overly complicated functions.  In too
62
 *    complicated functions, gcc may decide to generate premature `exits'.  This
63
 *    is what passing the -fno-reorder-blocks command line switch to gcc helps
64
 *    with.  This is ofcourse not desired and is rather flaky as we don't (and
65
 *    can't) control the kind of code that gcc generates: It may work for one
66
 *    and break for another.  The less branches there are the less likely it is
67
 *    that a premature return shall occur.
68
 * 3) If gcc decides that it is going to be a basterd then it will optimise a
69
 *    very simple condition (if/switch) with a premature exit.  But gcc can't
70
 *    fuck ME over!  Just stick a FORCE_RET; at the END of the offending
71
 *    function.
72
 * 4) All operations must start with `op_'.  dyngen ignores all other functions.
73
 * 5) Local variables are depriciated: They hinder performance.
74
 * 6) Function calls are expensive as the stack has to be shifted (twice).
75
 */
76
 
77
/*#define __or_dynop __attribute__((noreturn))*/
78
#define __or_dynop
79
 
80
/* Temporaries to hold the (simulated) registers in */
81
register uint32_t t0 asm(T0_REG);
82
register uint32_t t1 asm(T1_REG);
83
register uint32_t t2 asm(T2_REG);
84
 
85
#define OP_PARAM1 ((uorreg_t)(&__op_param1))
86
#define OP_PARAM2 ((uorreg_t)(&__op_param2))
87
#define OP_PARAM3 ((uorreg_t)(&__op_param3))
88
 
89
extern uorreg_t __op_param1;
90
extern uorreg_t __op_param2;
91
extern uorreg_t __op_param3;
92
 
93
#define xglue(x, y) x ## y
94
#define glue(x, y) xglue(x, y)
95
 
96
/* Helper function.  Whenever we escape the recompiled code and there is a
97
 * potential that an exception may happen this function must be called */
98
static inline void save_t_temporary(void)
99
{
100
  env->t0 = t0;
101
  env->t1 = t1;
102
  env->t2 = t2;
103
}
104
 
105
/* Wrapper around do_scheduler.  This is needed because op_do_sched must be as
106
 * small as possible. */
107
void do_sched_wrap(void)
108
{
109
  save_t_temporary();
110
  upd_sim_cycles();
111
  do_scheduler();
112
}
113
 
114 1481 nogj
/* do_scheduler wrapper for instructions that are in the delay slot */
115
void do_sched_wrap_delay(void)
116
{
117
  save_t_temporary();
118
  upd_sim_cycles();
119
  env->ts_current = 1;
120
  /* The PC gets set to the location of the jump, but do_sched increments that
121
   * so pull it back here to point to the right location again.  This could be
122
   * done in op_add_pc/op_set_pc_pc_delay but that would enlarge the recompiled
123
   * code. */
124
  //env->pc -= 4;
125
  do_scheduler();
126
  env->ts_current = 0;
127
}
128
 
129
void enter_dyn_code(oraddr_t addr, struct dyn_page *dp)
130
{
131
  uint16_t reg;
132
 
133 1483 nogj
  addr &= config.immu.pagesize - 1;
134 1481 nogj
  addr >>= 2;
135
 
136
  reg = dp->ts_bound[addr];
137
 
138
  if(reg & 0x1f)
139
    t0 = cpu_state.reg[reg & 0x1f];
140
 
141
  if((reg >> 5) & 0x1f)
142
    t1 = cpu_state.reg[(reg >> 5) & 0x1f];
143
 
144
  if((reg >> 10) & 0x1f)
145
    t2 = cpu_state.reg[(reg >> 10) & 0x1f];
146
 
147
  or_longjmp(dp->locs[addr]);
148
}
149
 
150 1452 nogj
__or_dynop void op_t0_imm(void)
151
{
152
  t0 = OP_PARAM1;
153
}
154
 
155
__or_dynop void op_t1_imm(void)
156
{
157
  t1 = OP_PARAM1;
158
}
159
 
160
__or_dynop void op_t2_imm(void)
161
{
162
  t2 = OP_PARAM1;
163
}
164
 
165
__or_dynop void op_clear_t0(void)
166
{
167
  t0 = 0;
168
}
169
 
170
__or_dynop void op_clear_t1(void)
171
{
172
  t1 = 0;
173
}
174
 
175
__or_dynop void op_clear_t2(void)
176
{
177
  t2 = 0;
178
}
179
 
180
__or_dynop void op_move_t0_t1(void)
181
{
182
  t0 = t1;
183
}
184
 
185
__or_dynop void op_move_t0_t2(void)
186
{
187
  t0 = t2;
188
}
189
 
190
__or_dynop void op_move_t1_t0(void)
191
{
192
  t1 = t0;
193
}
194
 
195
__or_dynop void op_move_t1_t2(void)
196
{
197
  t1 = t2;
198
}
199
 
200
__or_dynop void op_move_t2_t0(void)
201
{
202
  t2 = t0;
203
}
204
 
205
__or_dynop void op_move_t2_t1(void)
206
{
207
  t2 = t1;
208
}
209
 
210 1481 nogj
__or_dynop void op_set_pc_pc_delay(void)
211 1452 nogj
{
212 1481 nogj
  env->sprs[SPR_PPC] = get_pc();
213
  /* pc_delay is pulled back 4 since imediatly after this is run, the scheduler
214
   * runs which also increments it by 4 */
215
  set_pc(env->pc_delay - 4);
216 1452 nogj
}
217
 
218
__or_dynop void op_set_pc_delay_imm(void)
219
{
220
  env->pc_delay = get_pc() + (orreg_t)OP_PARAM1;
221
  env->delay_insn = 1;
222
}
223
 
224
__or_dynop void op_set_pc_delay_pc(void)
225
{
226
  env->pc_delay = get_pc();
227
  env->delay_insn = 1;
228
}
229
 
230
__or_dynop void op_clear_pc_delay(void)
231
{
232
  env->pc_delay = 0;
233
  env->delay_insn = 1;
234
}
235
 
236
__or_dynop void op_do_jump(void)
237
{
238 1481 nogj
  do_jump(get_pc());
239
}
240
 
241
__or_dynop void op_do_jump_delay(void)
242
{
243 1452 nogj
  do_jump(env->pc_delay);
244
}
245
 
246 1481 nogj
__or_dynop void op_clear_delay_insn(void)
247 1452 nogj
{
248 1481 nogj
  env->delay_insn = 0;
249 1452 nogj
}
250
 
251 1481 nogj
__or_dynop void op_set_delay_insn(void)
252 1452 nogj
{
253 1481 nogj
  env->delay_insn = 1;
254 1452 nogj
}
255
 
256 1481 nogj
__or_dynop void op_check_delay_slot(void)
257 1452 nogj
{
258 1481 nogj
  if(!env->delay_insn)
259
    OP_JUMP(OP_PARAM1);
260 1452 nogj
}
261
 
262
__or_dynop void op_jmp_imm(void)
263
{
264
  OP_JUMP(OP_PARAM1);
265
}
266
 
267
__or_dynop void op_set_flag(void)
268
{
269
  env->sprs[SPR_SR] |= SPR_SR_F;
270
}
271
 
272
__or_dynop void op_clear_flag(void)
273
{
274
  env->sprs[SPR_SR] &= ~SPR_SR_F;
275
}
276
 
277 1481 nogj
/* Used for the l.bf instruction.  Therefore if the flag is not set, jump over
278
 * all the jumping stuff */
279 1452 nogj
__or_dynop void op_check_flag(void)
280
{
281 1481 nogj
  if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
282
    HANDLE_SCHED(do_sched_wrap, "no_sched_chk_flg");
283
    OP_JUMP(OP_PARAM1);
284
  }
285
}
286
 
287
/* Used for l.bf if the delay slot instruction is on another page */
288
__or_dynop void op_check_flag_delay(void)
289
{
290 1452 nogj
  if(env->sprs[SPR_SR] & SPR_SR_F) {
291 1481 nogj
    env->delay_insn = 1;
292 1452 nogj
    env->pc_delay = get_pc() + (orreg_t)OP_PARAM1;
293
  }
294
}
295
 
296 1481 nogj
/* Used for the l.bnf instruction.  Therefore if the flag is set, jump over all
297
 * the jumping stuff */
298 1452 nogj
__or_dynop void op_check_not_flag(void)
299
{
300 1481 nogj
  if(env->sprs[SPR_SR] & SPR_SR_F) {
301
    HANDLE_SCHED(do_sched_wrap, "no_sched_chk_not_flg");
302
    OP_JUMP(OP_PARAM1);
303
  }
304
}
305
 
306
/* Used for l.bnf if the delay slot instruction is on another page */
307
__or_dynop void op_check_not_flag_delay(void)
308
{
309 1452 nogj
  if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
310 1481 nogj
    env->delay_insn = 1;
311 1452 nogj
    env->pc_delay = get_pc() + (orreg_t)OP_PARAM1;
312
  }
313
}
314
 
315
__or_dynop void op_set_ts_current(void)
316
{
317
  env->ts_current = 1;
318
}
319
 
320 1481 nogj
__or_dynop void op_add_pc(void)
321 1452 nogj
{
322 1481 nogj
  /* FIXME: Optimise */
323
  set_pc(get_pc() + OP_PARAM1);
324 1452 nogj
}
325
 
326
__or_dynop void op_nop_exit(void)
327
{
328
  upd_sim_cycles();
329
  save_t_temporary();
330
  op_support_nop_exit();
331
  FORCE_RET;
332
}
333
 
334
__or_dynop void op_nop_reset(void)
335
{
336
  upd_sim_cycles();
337
  op_support_nop_reset();
338 1481 nogj
  do_jump(EXCEPT_RESET);
339 1452 nogj
}
340
 
341
__or_dynop void op_nop_printf(void)
342
{
343
  save_t_temporary();
344
  upd_sim_cycles();
345
  op_support_nop_printf();
346
  FORCE_RET;
347
}
348
 
349
__or_dynop void op_nop_report(void)
350
{
351
  save_t_temporary();
352
  upd_sim_cycles();
353
  op_support_nop_report();
354
  FORCE_RET;
355
}
356
 
357
__or_dynop void op_nop_report_imm(void)
358
{
359
  save_t_temporary();
360
  upd_sim_cycles();
361
  op_support_nop_report_imm(OP_PARAM1);
362
}
363
 
364
__or_dynop void op_check_null_except_t0_delay(void)
365
{
366
  if(!t0) {
367
    /* Do exception */
368
    env->sprs[SPR_EEAR_BASE] = get_pc() - 4;
369
    env->delay_insn = 0;
370 1481 nogj
    do_jump(EXCEPT_ILLEGAL);
371 1452 nogj
  }
372
}
373
 
374
 
375
__or_dynop void op_check_null_except_t0(void)
376
{
377
  if(!t0) {
378
    /* Do exception */
379
    env->sprs[SPR_EEAR_BASE] = get_pc();
380 1481 nogj
    do_jump(EXCEPT_ILLEGAL);
381 1452 nogj
  }
382
}
383
 
384
__or_dynop void op_check_null_except_t1_delay(void)
385
{
386
  if(!t1) {
387
    /* Do exception */
388
    env->sprs[SPR_EEAR_BASE] = get_pc() - 4;
389
    env->delay_insn = 0;
390 1481 nogj
    do_jump(EXCEPT_ILLEGAL);
391 1452 nogj
  }
392
}
393
 
394
 
395
__or_dynop void op_check_null_except_t1(void)
396
{
397
  if(!t1) {
398
    /* Do exception */
399
    env->sprs[SPR_EEAR_BASE] = get_pc();
400 1481 nogj
    do_jump(EXCEPT_ILLEGAL);
401 1452 nogj
  }
402
}
403
 
404
__or_dynop void op_check_null_except_t2_delay(void)
405
{
406
  if(!t2) {
407
    /* Do exception */
408
    env->sprs[SPR_EEAR_BASE] = get_pc() - 4;
409
    env->delay_insn = 0;
410 1481 nogj
    do_jump(EXCEPT_ILLEGAL);
411 1452 nogj
  }
412
}
413
 
414
__or_dynop void op_check_null_except_t2(void)
415
{
416
  if(!t2) {
417
    /* Do exception */
418
    env->sprs[SPR_EEAR_BASE] = get_pc();
419 1481 nogj
    do_jump(EXCEPT_ILLEGAL);
420 1452 nogj
  }
421
}
422
 
423
__or_dynop void op_analysis(void)
424
{
425
  env->iqueue.insn_index = OP_PARAM1;
426
  env->iqueue.insn = OP_PARAM2;
427
  env->iqueue.insn_addr = get_pc();
428 1481 nogj
  save_t_temporary();
429
  op_support_analysis();
430 1452 nogj
  FORCE_RET;
431
}
432
 
433
#define OP_EXTRA
434
 
435
#define OP /
436
#define OP_CAST(T) (orreg_t)T
437
#define OP_NAME div
438
#include "op_arith_op.h"
439
#undef OP_NAME
440
#undef OP_CAST
441
#undef OP
442
 
443
#define OP /
444
#define OP_CAST(T) T
445
#define OP_NAME divu
446
#include "op_arith_op.h"
447
#undef OP_NAME
448
#undef OP_CAST
449
#undef OP
450
 
451
#define OP *
452
#define OP_CAST(T) T
453
#define OP_NAME mulu
454
#include "op_arith_op.h"
455
#undef OP_NAME
456
#undef OP_CAST
457
#undef OP
458
 
459
#define OP -
460
#define OP_CAST(T) (orreg_t)T
461
#define OP_NAME sub
462
#include "op_arith_op.h"
463
#undef OP_NAME
464
#undef OP_CAST
465
#undef OP
466
 
467
#undef OP_EXTRA
468
 
469
#define OP_HAS_IMM
470
 
471
#define OP_EXTRA + ((env->sprs[SPR_SR] & SPR_SR_CY) >> 10)
472
#define OP +
473
#define OP_CAST(T) (orreg_t)T
474
#define OP_NAME addc
475
#include "op_arith_op.h"
476
#undef OP_NAME
477
#undef OP_CAST
478
#undef OP
479
 
480
#undef OP_EXTRA
481
#define OP_EXTRA
482
 
483
#define OP +
484
#define OP_CAST(T) (orreg_t)T
485
#define OP_NAME add
486
#include "op_arith_op.h"
487
#undef OP_NAME
488
#undef OP_CAST
489
#undef OP
490
 
491
#define OP &
492
#define OP_CAST(T) T
493
#define OP_NAME and
494
#include "op_arith_op.h"
495
#undef OP_NAME
496
#undef OP_CAST
497
#undef OP
498
 
499
#define OP *
500
#define OP_CAST(T) (orreg_t)T
501
#define OP_NAME mul
502
#include "op_arith_op.h"
503
#undef OP_NAME
504
#undef OP_CAST
505
#undef OP
506
 
507
#define OP |
508
#define OP_CAST(T) T
509
#define OP_NAME or
510
#include "op_arith_op.h"
511
#undef OP_NAME
512
#undef OP_CAST
513
#undef OP
514
 
515
#define OP <<
516
#define OP_CAST(T) T
517
#define OP_NAME sll
518
#include "op_arith_op.h"
519
#undef OP_NAME
520
#undef OP_CAST
521
#undef OP
522
 
523
#define OP >>
524
#define OP_CAST(T) (orreg_t)T
525
#define OP_NAME sra
526
#include "op_arith_op.h"
527
#undef OP_NAME
528
#undef OP_CAST
529
#undef OP
530
 
531
#define OP >>
532
#define OP_CAST(T) T
533
#define OP_NAME srl
534
#include "op_arith_op.h"
535
#undef OP_NAME
536
#undef OP_CAST
537
#undef OP
538
 
539
#define OP ^
540
#define OP_CAST(T) T
541
#define OP_NAME xor
542
#include "op_arith_op.h"
543
#undef OP_NAME
544
#undef OP_CAST
545
#undef OP
546
 
547
#undef OP_EXTRA
548
#undef OP_HAS_IMM
549
 
550
#define EXT_NAME extbs
551
#define EXT_TYPE int8_t
552
#define EXT_CAST (orreg_t)
553
#include "op_extend_op.h"
554
#undef EXT_CAST
555
#undef EXT_TYPE
556
#undef EXT_NAME
557
 
558
#define EXT_NAME extbz
559
#define EXT_TYPE uint8_t
560
#define EXT_CAST (uorreg_t)
561
#include "op_extend_op.h"
562
#undef EXT_CAST
563
#undef EXT_TYPE
564
#undef EXT_NAME
565
 
566
#define EXT_NAME exths
567
#define EXT_TYPE int16_t
568
#define EXT_CAST (orreg_t)
569
#include "op_extend_op.h"
570
#undef EXT_CAST
571
#undef EXT_TYPE
572
#undef EXT_NAME
573
 
574
#define EXT_NAME exthz
575
#define EXT_TYPE uint16_t
576
#define EXT_CAST (uorreg_t)
577
#include "op_extend_op.h"
578
#undef EXT_CAST
579
#undef EXT_TYPE
580
#undef EXT_NAME
581
 
582
#define COMP ==
583
#define COMP_NAME sfeq
584
#define COMP_CAST(t) t
585
#include "op_comp_op.h"
586
#undef COMP_CAST
587
#undef COMP_NAME
588
#undef COMP
589
 
590
#define COMP !=
591
#define COMP_NAME sfne
592
#define COMP_CAST(t) t
593
#include "op_comp_op.h"
594
#undef COMP_CAST
595
#undef COMP_NAME
596
#undef COMP
597
 
598
#define COMP >
599
#define COMP_NAME sfgtu
600
#define COMP_CAST(t) t
601
#include "op_comp_op.h"
602
#undef COMP_CAST
603
#undef COMP_NAME
604
#undef COMP
605
 
606
#define COMP >=
607
#define COMP_NAME sfgeu
608
#define COMP_CAST(t) t
609
#include "op_comp_op.h"
610
#undef COMP_CAST
611
#undef COMP_NAME
612
#undef COMP
613
 
614
#define COMP <
615
#define COMP_NAME sfltu
616
#define COMP_CAST(t) t
617
#include "op_comp_op.h"
618
#undef COMP_CAST
619
#undef COMP_NAME
620
#undef COMP
621
 
622
#define COMP <=
623
#define COMP_NAME sfleu
624
#define COMP_CAST(t) t
625
#include "op_comp_op.h"
626
#undef COMP_CAST
627
#undef COMP_NAME
628
#undef COMP
629
 
630
#define COMP >
631
#define COMP_NAME sfgts
632
#define COMP_CAST(t) (orreg_t)t
633
#include "op_comp_op.h"
634
#undef COMP_CAST
635
#undef COMP_NAME
636
#undef COMP
637
 
638
#define COMP >=
639
#define COMP_NAME sfges
640
#define COMP_CAST(t) (orreg_t)t
641
#include "op_comp_op.h"
642
#undef COMP_CAST
643
#undef COMP_NAME
644
#undef COMP
645
 
646
#define COMP <
647
#define COMP_NAME sflts
648
#define COMP_CAST(t) (orreg_t)t
649
#include "op_comp_op.h"
650
#undef COMP_CAST
651
#undef COMP_NAME
652
#undef COMP
653
 
654
#define COMP <=
655
#define COMP_NAME sfles
656
#define COMP_CAST(t) (orreg_t)t
657
#include "op_comp_op.h"
658
#undef COMP_CAST
659
#undef COMP_NAME
660
#undef COMP
661
 
662
#define REG 1
663
#include "op_t_reg_mov_op.h"
664
#undef REG
665
 
666
#define REG 2
667
#include "op_t_reg_mov_op.h"
668
#undef REG
669
 
670
#define REG 3
671
#include "op_t_reg_mov_op.h"
672
#undef REG
673
 
674
#define REG 4
675
#include "op_t_reg_mov_op.h"
676
#undef REG
677
 
678
#define REG 5
679
#include "op_t_reg_mov_op.h"
680
#undef REG
681
 
682
#define REG 6
683
#include "op_t_reg_mov_op.h"
684
#undef REG
685
 
686
#define REG 7
687
#include "op_t_reg_mov_op.h"
688
#undef REG
689
 
690
#define REG 8
691
#include "op_t_reg_mov_op.h"
692
#undef REG
693
 
694
#define REG 9
695
#include "op_t_reg_mov_op.h"
696
#undef REG
697
 
698
#define REG 10
699
#include "op_t_reg_mov_op.h"
700
#undef REG
701
 
702
#define REG 11
703
#include "op_t_reg_mov_op.h"
704
#undef REG
705
 
706
#define REG 12
707
#include "op_t_reg_mov_op.h"
708
#undef REG
709
 
710
#define REG 13
711
#include "op_t_reg_mov_op.h"
712
#undef REG
713
 
714
#define REG 14
715
#include "op_t_reg_mov_op.h"
716
#undef REG
717
 
718
#define REG 15
719
#include "op_t_reg_mov_op.h"
720
#undef REG
721
 
722
#define REG 16
723
#include "op_t_reg_mov_op.h"
724
#undef REG
725
 
726
#define REG 17
727
#include "op_t_reg_mov_op.h"
728
#undef REG
729
 
730
#define REG 18
731
#include "op_t_reg_mov_op.h"
732
#undef REG
733
 
734
#define REG 19
735
#include "op_t_reg_mov_op.h"
736
#undef REG
737
 
738
#define REG 20
739
#include "op_t_reg_mov_op.h"
740
#undef REG
741
 
742
#define REG 21
743
#include "op_t_reg_mov_op.h"
744
#undef REG
745
 
746
#define REG 22
747
#include "op_t_reg_mov_op.h"
748
#undef REG
749
 
750
#define REG 23
751
#include "op_t_reg_mov_op.h"
752
#undef REG
753
 
754
#define REG 24
755
#include "op_t_reg_mov_op.h"
756
#undef REG
757
 
758
#define REG 25
759
#include "op_t_reg_mov_op.h"
760
#undef REG
761
 
762
#define REG 26
763
#include "op_t_reg_mov_op.h"
764
#undef REG
765
 
766
#define REG 27
767
#include "op_t_reg_mov_op.h"
768
#undef REG
769
 
770
#define REG 28
771
#include "op_t_reg_mov_op.h"
772
#undef REG
773
 
774
#define REG 29
775
#include "op_t_reg_mov_op.h"
776
#undef REG
777
 
778
#define REG 30
779
#include "op_t_reg_mov_op.h"
780
#undef REG
781
 
782
#define REG 31
783
#include "op_t_reg_mov_op.h"
784
#undef REG
785
 
786
#define DST_T t0
787
#define SRC_T t0
788
#include "op_ff1_op.h"
789
#undef SRC_T
790
 
791
#define SRC_T t1
792
#include "op_ff1_op.h"
793
#undef SRC_T
794
 
795
#define SRC_T t2
796
#include "op_ff1_op.h"
797
#undef SRC_T
798
#undef DST_T
799
 
800
#define DST_T t1
801
#define SRC_T t0
802
#include "op_ff1_op.h"
803
#undef SRC_T
804
 
805
#define SRC_T t1
806
#include "op_ff1_op.h"
807
#undef SRC_T
808
 
809
#define SRC_T t2
810
#include "op_ff1_op.h"
811
#undef SRC_T
812
#undef DST_T
813
 
814
#define DST_T t2
815
#define SRC_T t0
816
#include "op_ff1_op.h"
817
#undef SRC_T
818
 
819
#define SRC_T t1
820
#include "op_ff1_op.h"
821
#undef SRC_T
822
 
823
#define SRC_T t2
824
#include "op_ff1_op.h"
825
#undef SRC_T
826
#undef DST_T
827
 
828
#define SPR_T_NAME SPR_T
829
#define GPR_T_NAME GPR_T
830
 
831
#define SPR_T t0
832
#define GPR_T t0
833
#include "op_mftspr_op.h"
834
#undef GPR_T
835
 
836
#define GPR_T t1
837
#include "op_mftspr_op.h"
838
#undef GPR_T
839
 
840
#define GPR_T t2
841
#include "op_mftspr_op.h"
842
#undef GPR_T
843
#undef SPR_T
844
 
845
#define SPR_T t1
846
#define GPR_T t0
847
#include "op_mftspr_op.h"
848
#undef GPR_T
849
 
850
#define GPR_T t1
851
#include "op_mftspr_op.h"
852
#undef GPR_T
853
 
854
#define GPR_T t2
855
#include "op_mftspr_op.h"
856
#undef GPR_T
857
#undef SPR_T
858
 
859
#define SPR_T t2
860
#define GPR_T t0
861
#include "op_mftspr_op.h"
862
#undef GPR_T
863
 
864
#define GPR_T t1
865
#include "op_mftspr_op.h"
866
#undef GPR_T
867
 
868
#define GPR_T t2
869
#include "op_mftspr_op.h"
870
#undef GPR_T
871
#undef SPR_T
872
 
873
#undef GPR_T_NAME
874
#undef SPR_T_NAME
875
 
876
#define SPR_T_NAME imm
877
#define GPR_T_NAME GPR_T
878
 
879
#define SPR_T 0
880
 
881
#define GPR_T t0
882
#include "op_mftspr_op.h"
883
#undef GPR_T
884
 
885
#define GPR_T t1
886
#include "op_mftspr_op.h"
887
#undef GPR_T
888
 
889
#define GPR_T t2
890
#include "op_mftspr_op.h"
891
#undef GPR_T
892
#undef SPR_T
893
 
894
#undef SPR_T_NAME
895
#undef GPR_T_NAME
896
 
897
#define ONLY_MTSPR
898
#define SPR_T_NAME SPR_T
899
#define GPR_T_NAME clear
900
 
901
#define GPR_T 0
902
 
903
#define SPR_T t0
904
#include "op_mftspr_op.h"
905
#undef SPR_T
906
 
907
#define SPR_T t1
908
#include "op_mftspr_op.h"
909
#undef SPR_T
910
 
911
#define SPR_T t2
912
#include "op_mftspr_op.h"
913
#undef SPR_T
914
 
915
#undef GPR_T
916
 
917
#undef SPR_T_NAME
918
#undef GPR_T_NAME
919
 
920
#define SPR_T_NAME imm
921
#define GPR_T_NAME clear
922
#define GPR_T 0
923
#define SPR_T 0
924
#include "op_mftspr_op.h"
925
#undef SPR_T
926
#undef GPR_T
927
#undef GPR_T_NAME
928
#undef SPR_T_NAME
929
 
930
#undef ONLY_MTSPR
931
 
932
#define OP +=
933
#define OP_NAME mac
934
#include "op_mac_op.h"
935
#undef OP_NAME
936
#undef OP
937
 
938
#define OP -=
939
#define OP_NAME msb
940
#include "op_mac_op.h"
941
#undef OP_NAME
942
#undef OP
943
 
944
#define LS_OP_NAME lbz
945
#define LS_OP_CAST
946
#define LS_OP_FUNC eval_mem8
947
#include "op_lwhb_op.h"
948
#undef LS_OP_FUNC
949
#undef LS_OP_CAST
950
#undef LS_OP_NAME
951
 
952
#define LS_OP_NAME lbs
953
#define LS_OP_CAST (int8_t)
954
#define LS_OP_FUNC eval_mem8
955
#include "op_lwhb_op.h"
956
#undef LS_OP_FUNC
957
#undef LS_OP_CAST
958
#undef LS_OP_NAME
959
 
960
#define LS_OP_NAME lhz
961
#define LS_OP_CAST
962
#define LS_OP_FUNC eval_mem16
963
#include "op_lwhb_op.h"
964
#undef LS_OP_FUNC
965
#undef LS_OP_CAST
966
#undef LS_OP_NAME
967
 
968
#define LS_OP_NAME lhs
969
#define LS_OP_CAST (int16_t)
970
#define LS_OP_FUNC eval_mem16
971
#include "op_lwhb_op.h"
972
#undef LS_OP_FUNC
973
#undef LS_OP_CAST
974
#undef LS_OP_NAME
975
 
976
#define LS_OP_NAME lwz
977
#define LS_OP_CAST
978
#define LS_OP_FUNC eval_mem32
979
#include "op_lwhb_op.h"
980
#undef LS_OP_FUNC
981
#undef LS_OP_CAST
982
#undef LS_OP_NAME
983
 
984
#define LS_OP_NAME lws
985
#define LS_OP_CAST (int32_t)
986
#define LS_OP_FUNC eval_mem32
987
#include "op_lwhb_op.h"
988
#undef LS_OP_FUNC
989
#undef LS_OP_CAST
990
#undef LS_OP_NAME
991
 
992
#define S_OP_NAME sb
993
#define S_FUNC set_mem8
994
#include "op_swhb_op.h"
995
#undef S_FUNC
996
#undef S_OP_NAME
997
 
998
#define S_OP_NAME sh
999
#define S_FUNC set_mem16
1000
#include "op_swhb_op.h"
1001
#undef S_FUNC
1002
#undef S_OP_NAME
1003
 
1004
#define S_OP_NAME sw
1005
#define S_FUNC set_mem32
1006
#include "op_swhb_op.h"
1007
#undef S_FUNC
1008
#undef S_OP_NAME
1009
 
1010
__or_dynop void op_join_mem_cycles(void)
1011
{
1012
  join_mem_cycles();
1013
}
1014
 
1015
__or_dynop void op_store_link_addr_gpr(void)
1016
{
1017
  env->reg[LINK_REGNO] = get_pc() + 8;
1018
}
1019
 
1020
__or_dynop void op_prep_rfe(void)
1021
{
1022
  env->sprs[SPR_SR] = env->sprs[SPR_ESR_BASE] | SPR_SR_FO;
1023
  env->sprs[SPR_PPC] = get_pc();
1024 1481 nogj
  env->ts_current = 1;
1025
  set_pc(env->sprs[SPR_EPCR_BASE] - 4);
1026 1452 nogj
}
1027
 
1028
static inline void prep_except(oraddr_t epcr_base)
1029
{
1030
  env->sprs[SPR_EPCR_BASE] = epcr_base;
1031
 
1032
  env->sprs[SPR_ESR_BASE] = env->sprs[SPR_SR];
1033
 
1034
  /* Address translation is always disabled when starting exception. */
1035
  env->sprs[SPR_SR] &= ~SPR_SR_DME;
1036
  env->sprs[SPR_SR] &= ~SPR_SR_IME;
1037
 
1038
  env->sprs[SPR_SR] &= ~SPR_SR_OVE;   /* Disable overflow flag exception. */
1039
 
1040
  env->sprs[SPR_SR] |= SPR_SR_SM;     /* SUPV mode */
1041
  env->sprs[SPR_SR] &= ~(SPR_SR_IEE | SPR_SR_TEE);    /* Disable interrupts. */
1042
}
1043
 
1044
__or_dynop void op_set_except_pc(void)
1045
{
1046
  set_pc(OP_PARAM1);
1047
}
1048
 
1049
/* Before the code in op_{sys,trap}{,_delay} gets run, the scheduler runs.
1050
 * Therefore the pc will point to the instruction after the l.sys or l.trap
1051
 * instruction */
1052
__or_dynop void op_prep_sys_delay(void)
1053
{
1054
  env->delay_insn = 0;
1055 1481 nogj
  env->ts_current = 1;
1056 1452 nogj
  prep_except(get_pc() - 4);
1057 1481 nogj
  set_pc(EXCEPT_SYSCALL - 4);
1058 1452 nogj
}
1059
 
1060
__or_dynop void op_prep_sys(void)
1061
{
1062 1481 nogj
  env->ts_current = 1;
1063 1452 nogj
  prep_except(get_pc() + 4);
1064 1481 nogj
  set_pc(EXCEPT_SYSCALL - 4);
1065 1452 nogj
}
1066
 
1067
__or_dynop void op_prep_trap_delay(void)
1068
{
1069 1481 nogj
  env->ts_current = 1;
1070 1452 nogj
  env->delay_insn = 0;
1071
  prep_except(get_pc() - 4);
1072 1481 nogj
  set_pc(EXCEPT_TRAP - 4);
1073 1452 nogj
}
1074
 
1075
__or_dynop void op_prep_trap(void)
1076
{
1077 1481 nogj
  env->ts_current = 1;
1078 1452 nogj
  prep_except(get_pc());
1079 1481 nogj
  set_pc(EXCEPT_TRAP - 4);
1080 1452 nogj
}
1081
 
1082
/* FIXME: This `instruction' should be split up like the l.trap and l.sys
1083
 * instructions are done */
1084
__or_dynop void op_illegal_delay(void)
1085
{
1086
  env->delay_insn = 0;
1087 1481 nogj
  env->ts_current = 1;
1088 1452 nogj
  env->sprs[SPR_EEAR_BASE] = get_pc() - 4;
1089 1481 nogj
  do_jump(EXCEPT_ILLEGAL - 4);
1090 1452 nogj
}
1091
 
1092
__or_dynop void op_illegal(void)
1093
{
1094
  env->sprs[SPR_EEAR_BASE] = get_pc();
1095 1481 nogj
  do_jump(EXCEPT_ILLEGAL);
1096 1452 nogj
}
1097
 
1098
__or_dynop void op_do_sched(void)
1099
{
1100 1481 nogj
  HANDLE_SCHED(do_sched_wrap, "no_sched");
1101 1452 nogj
}
1102
 
1103 1481 nogj
__or_dynop void op_do_sched_delay(void)
1104
{
1105
  HANDLE_SCHED(do_sched_wrap_delay, "no_sched_delay");
1106
}
1107
 
1108 1452 nogj
__or_dynop void op_macc(void)
1109
{
1110
  env->sprs[SPR_MACLO] = 0;
1111
  env->sprs[SPR_MACHI] = 0;
1112
}
1113
 
1114
__or_dynop void op_store_insn_ea(void)
1115
{
1116
  env->insn_ea = OP_PARAM1;
1117
}
1118
 
1119
__or_dynop void op_calc_insn_ea_t0(void)
1120
{
1121
  env->insn_ea = t0 + OP_PARAM1;
1122
}
1123
 
1124
__or_dynop void op_calc_insn_ea_t1(void)
1125
{
1126
  env->insn_ea = t1 + OP_PARAM1;
1127
}
1128
 
1129
__or_dynop void op_calc_insn_ea_t2(void)
1130
{
1131
  env->insn_ea = t2 + OP_PARAM1;
1132
}
1133
 
1134
__or_dynop void op_macrc_t0(void)
1135
{
1136
  /* FIXME: How is this supposed to work?  The architechture manual says that
1137
   * the low 32-bits shall be saved into rD.  I have just copied this code from
1138
   * insnset.c to make testbench/mul pass */
1139
  int64_t temp = env->sprs[SPR_MACLO] | ((int64_t)env->sprs[SPR_MACHI] << 32);
1140
 
1141
  t0 = (orreg_t)(temp >> 28);
1142
  env->sprs[SPR_MACLO] = 0;
1143
  env->sprs[SPR_MACHI] = 0;
1144
}
1145
 
1146
__or_dynop void op_macrc_t1(void)
1147
{
1148
  /* FIXME: How is this supposed to work?  The architechture manual says that
1149
   * the low 32-bits shall be saved into rD.  I have just copied this code from
1150
   * insnset.c to make testbench/mul pass */
1151
  int64_t temp = env->sprs[SPR_MACLO] | ((int64_t)env->sprs[SPR_MACHI] << 32);
1152
 
1153
  t1 = (orreg_t)(temp >> 28);
1154
 
1155
  env->sprs[SPR_MACLO] = 0;
1156
  env->sprs[SPR_MACHI] = 0;
1157
}
1158
 
1159
__or_dynop void op_macrc_t2(void)
1160
{
1161
  /* FIXME: How is this supposed to work?  The architechture manual says that
1162
   * the low 32-bits shall be saved into rD.  I have just copied this code from
1163
   * insnset.c to make testbench/mul pass */
1164
  int64_t temp = env->sprs[SPR_MACLO] | ((int64_t)env->sprs[SPR_MACHI] << 32);
1165
 
1166
  t2 = (orreg_t)(temp >> 28);
1167
 
1168
  env->sprs[SPR_MACLO] = 0;
1169
  env->sprs[SPR_MACHI] = 0;
1170
}
1171
 
1172
__or_dynop void op_mac_imm_t0(void)
1173
{
1174
  int64_t temp = env->sprs[SPR_MACLO] | ((int64_t)env->sprs[SPR_MACHI] << 32);
1175
 
1176
  temp += (int64_t)t0 * (int64_t)OP_PARAM1;
1177
 
1178
  env->sprs[SPR_MACLO] = temp & 0xffffffff;
1179
  env->sprs[SPR_MACHI] = temp >> 32;
1180
}
1181
 
1182
__or_dynop void op_mac_imm_t1(void)
1183
{
1184
  int64_t temp = env->sprs[SPR_MACLO] | ((int64_t)env->sprs[SPR_MACHI] << 32);
1185
 
1186
  temp += (int64_t)t1 * (int64_t)OP_PARAM1;
1187
 
1188
  env->sprs[SPR_MACLO] = temp & 0xffffffff;
1189
  env->sprs[SPR_MACHI] = temp >> 32;
1190
}
1191
 
1192
__or_dynop void op_mac_imm_t2(void)
1193
{
1194
  int64_t temp = env->sprs[SPR_MACLO] | ((int64_t)env->sprs[SPR_MACHI] << 32);
1195
 
1196
  temp += (int64_t)t2 * (int64_t)OP_PARAM1;
1197
 
1198
  env->sprs[SPR_MACLO] = temp & 0xffffffff;
1199
  env->sprs[SPR_MACHI] = temp >> 32;
1200
}
1201
 
1202
__or_dynop void op_cmov_t0_t0_t1(void)
1203
{
1204
  t0 = env->sprs[SPR_SR] & SPR_SR_F ? t0 : t1;
1205
}
1206
 
1207
__or_dynop void op_cmov_t0_t0_t2(void)
1208
{
1209
  t0 = env->sprs[SPR_SR] & SPR_SR_F ? t0 : t2;
1210
}
1211
 
1212
__or_dynop void op_cmov_t0_t1_t0(void)
1213
{
1214
  t0 = env->sprs[SPR_SR] & SPR_SR_F ? t1 : t0;
1215
}
1216
 
1217
__or_dynop void op_cmov_t0_t1_t2(void)
1218
{
1219
  t0 = env->sprs[SPR_SR] & SPR_SR_F ? t1 : t2;
1220
  FORCE_RET;
1221
}
1222
 
1223
__or_dynop void op_cmov_t0_t2_t0(void)
1224
{
1225
  t0 = env->sprs[SPR_SR] & SPR_SR_F ? t2 : t0;
1226
}
1227
 
1228
__or_dynop void op_cmov_t0_t2_t1(void)
1229
{
1230
  t0 = env->sprs[SPR_SR] & SPR_SR_F ? t2 : t1;
1231
  FORCE_RET;
1232
}
1233
 
1234
__or_dynop void op_cmov_t1_t0_t1(void)
1235
{
1236
  t1 = env->sprs[SPR_SR] & SPR_SR_F ? t0 : t1;
1237
}
1238
 
1239
__or_dynop void op_cmov_t1_t0_t2(void)
1240
{
1241
  t1 = env->sprs[SPR_SR] & SPR_SR_F ? t0 : t2;
1242
  FORCE_RET;
1243
}
1244
 
1245
__or_dynop void op_cmov_t1_t1_t0(void)
1246
{
1247
  t1 = env->sprs[SPR_SR] & SPR_SR_F ? t1 : t0;
1248
}
1249
 
1250
__or_dynop void op_cmov_t1_t1_t2(void)
1251
{
1252
  t1 = env->sprs[SPR_SR] & SPR_SR_F ? t1 : t2;
1253
}
1254
 
1255
__or_dynop void op_cmov_t1_t2_t0(void)
1256
{
1257
  t1 = env->sprs[SPR_SR] & SPR_SR_F ? t2 : t0;
1258
  FORCE_RET;
1259
}
1260
 
1261
__or_dynop void op_cmov_t1_t2_t1(void)
1262
{
1263
  t1 = env->sprs[SPR_SR] & SPR_SR_F ? t2 : t1;
1264
}
1265
 
1266
__or_dynop void op_cmov_t2_t0_t1(void)
1267
{
1268
  t2 = env->sprs[SPR_SR] & SPR_SR_F ? t0 : t1;
1269
  FORCE_RET;
1270
}
1271
 
1272
__or_dynop void op_cmov_t2_t0_t2(void)
1273
{
1274
  t2 = env->sprs[SPR_SR] & SPR_SR_F ? t0 : t2;
1275
}
1276
 
1277
__or_dynop void op_cmov_t2_t1_t0(void)
1278
{
1279
  t2 = env->sprs[SPR_SR] & SPR_SR_F ? t1 : t0;
1280
  FORCE_RET;
1281
}
1282
 
1283
__or_dynop void op_cmov_t2_t1_t2(void)
1284
{
1285
  t2 = env->sprs[SPR_SR] & SPR_SR_F ? t1 : t2;
1286
}
1287
 
1288
__or_dynop void op_cmov_t2_t2_t0(void)
1289
{
1290
  t2 = env->sprs[SPR_SR] & SPR_SR_F ? t2 : t0;
1291
}
1292
 
1293
__or_dynop void op_cmov_t2_t2_t1(void)
1294
{
1295
  t2 = env->sprs[SPR_SR] & SPR_SR_F ? t2 : t1;
1296
}
1297
 
1298
__or_dynop void op_neg_t0_t0(void)
1299
{
1300
  t0 = -t0;
1301
}
1302
 
1303
__or_dynop void op_neg_t0_t1(void)
1304
{
1305
  t0 = -t1;
1306
}
1307
 
1308
__or_dynop void op_neg_t0_t2(void)
1309
{
1310
  t0 = -t2;
1311
}
1312
 
1313
__or_dynop void op_neg_t1_t0(void)
1314
{
1315
  t1 = -t0;
1316
}
1317
 
1318
__or_dynop void op_neg_t1_t1(void)
1319
{
1320
  t1 = -t1;
1321
}
1322
 
1323
__or_dynop void op_neg_t1_t2(void)
1324
{
1325
  t1 = -t2;
1326
}
1327
 
1328
__or_dynop void op_neg_t2_t0(void)
1329
{
1330
  t2 = -t0;
1331
}
1332
 
1333
__or_dynop void op_neg_t2_t1(void)
1334
{
1335
  t2 = -t1;
1336
}
1337
 
1338
__or_dynop void op_neg_t2_t2(void)
1339
{
1340
  t2 = -t2;
1341
}
1342
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.