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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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