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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [or32/] [op.c] - Blame information for rev 486

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 jeremybenn
/* 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
#include "immu.h"
42
 
43
#include "op-support.h"
44
 
45
#include "i386-regs.h"
46
 
47
#include "dyn-rec.h"
48
 
49
register struct cpu_state *env asm(CPU_STATE_REG);
50
 
51
#include "op-i386.h"
52
 
53
/*
54
 * WARNING: Before going of and wildly editing everything in this file remember
55
 * 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
 
94
static inline void save_t_bound(oraddr_t pc)
95
{
96
  int reg;
97
 
98
  pc = (pc & immu_state->page_offset_mask) / 4;
99
  reg = env->curr_page->ts_bound[pc];
100
 
101
  if(reg & 0x1f)
102
    env->reg[reg & 0x1f] = t0;
103
 
104
  if((reg >> 5) & 0x1f)
105
    env->reg[(reg >> 5) & 0x1f] = t1;
106
 
107
  if((reg >> 10) & 0x1f)
108
    env->reg[(reg >> 10) & 0x1f] = t2;
109
}
110
 
111
void do_sched_wrap(void)
112
{
113
  env->pc += 4;
114
  //runtime.cpu.instructions++;
115
  runtime.sim.cycles -= env->cycles_dec;
116
  scheduler.job_queue->time += env->cycles_dec;
117
  if(scheduler.job_queue->time <= 0) {
118
    save_t_bound(env->pc - 4);
119
    do_scheduler();
120
  }
121
}
122
 
123
/* do_scheduler wrapper for instructions that are in the delay slot */
124
void do_sched_wrap_delay(void)
125
{
126
  /* FIXME: Can't this be eliminated? */
127
  env->pc += 4;
128
  //runtime.cpu.instructions++;
129
  runtime.sim.cycles -= env->cycles_dec;
130
  scheduler.job_queue->time += env->cycles_dec;
131
  if(scheduler.job_queue->time <= 0)
132
    do_scheduler();
133
}
134
 
135
void enter_dyn_code(oraddr_t addr, struct dyn_page *dp)
136
{
137
  uint16_t reg = 0;
138
  uint32_t t0_reg = t0, t1_reg = t1, t2_reg = t2;
139
  struct cpu_state *cpu_reg = env;
140
 
141
  addr &= immu_state->page_offset_mask;
142
  addr >>= 2;
143
 
144
  if(addr)
145
    reg = dp->ts_bound[addr - 1];
146
 
147
  t0 = cpu_state.reg[reg & 0x1f];
148
  t1 = cpu_state.reg[(reg >> 5) & 0x1f];
149
 
150
  /* Don't we all love gcc?  For some heavenly reason gcc 3.2 _knows_ that if I
151
   * don't put a condition around the assignment of t2, _all_ the assignments to
152
   * t{0,1,2} are useless and not needed.  I'm pleasently happy that gcc is so
153
   * bright, but on the other hand, t{0,1,2} are globals (!) how can you assume
154
   * that the value of a global won't be used in a function further up or
155
   * further down the stack?? */
156
  if(addr)
157
    t2 = cpu_state.reg[(reg >> 10) & 0x1f];
158
 
159
  env = &cpu_state;
160
 
161
  ((gen_code_ent *)dp->locs)[addr]();
162
  t0 = t0_reg;
163
  t1 = t1_reg;
164
  t2 = t2_reg;
165
  env = (struct cpu_state *)cpu_reg;
166
}
167
 
168
__or_dynop void op_set_pc_pc_delay(void)
169
{
170
  env->sprs[SPR_PPC] = env->pc;
171
  /* pc_delay is pulled back 4 since imediatly after this is run, the scheduler
172
   * runs which also increments it by 4 */
173
  env->pc = env->pc_delay - 4;
174
}
175
 
176
__or_dynop void op_set_pc_delay_imm(void)
177
{
178
  env->pc_delay = env->pc + (orreg_t)OP_PARAM1;
179
  env->delay_insn = 1;
180
}
181
 
182
__or_dynop void op_set_pc_delay_pc(void)
183
{
184
  env->pc_delay = env->pc;
185
  env->delay_insn = 1;
186
}
187
 
188
__or_dynop void op_clear_pc_delay(void)
189
{
190
  env->pc_delay = 0;
191
  env->delay_insn = 1;
192
}
193
 
194
__or_dynop void op_do_jump_delay(void)
195
{
196
  env->pc = env->pc_delay;
197
}
198
 
199
__or_dynop void op_clear_delay_insn(void)
200
{
201
  env->delay_insn = 0;
202
}
203
 
204
__or_dynop void op_set_delay_insn(void)
205
{
206
  env->delay_insn = 1;
207
}
208
 
209
__or_dynop void op_check_delay_slot(void)
210
{
211
  if(!env->delay_insn)
212
    OP_JUMP(OP_PARAM1);
213
}
214
 
215
__or_dynop void op_jmp_imm(void)
216
{
217
  OP_JUMP(OP_PARAM1);
218
}
219
 
220
__or_dynop void op_set_flag(void)
221
{
222
  env->sprs[SPR_SR] |= SPR_SR_F;
223
}
224
 
225
__or_dynop void op_clear_flag(void)
226
{
227
  env->sprs[SPR_SR] &= ~SPR_SR_F;
228
}
229
 
230
/* Used for the l.bf instruction.  Therefore if the flag is not set, jump over
231
 * all the jumping stuff */
232
__or_dynop void op_check_flag(void)
233
{
234
  if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
235
    SPEEDY_CALL(do_sched_wrap);
236
    OP_JUMP(OP_PARAM1);
237
  }
238
}
239
 
240
/* Used for l.bf if the delay slot instruction is on another page */
241
__or_dynop void op_check_flag_delay(void)
242
{
243
  if(env->sprs[SPR_SR] & SPR_SR_F) {
244
    env->delay_insn = 1;
245
    env->pc_delay = env->pc + (orreg_t)OP_PARAM1;
246
  }
247
}
248
 
249
/* Used for the l.bnf instruction.  Therefore if the flag is set, jump over all
250
 * the jumping stuff */
251
__or_dynop void op_check_not_flag(void)
252
{
253
  if(env->sprs[SPR_SR] & SPR_SR_F) {
254
    SPEEDY_CALL(do_sched_wrap);
255
    OP_JUMP(OP_PARAM1);
256
  }
257
}
258
 
259
/* Used for l.bnf if the delay slot instruction is on another page */
260
__or_dynop void op_check_not_flag_delay(void)
261
{
262
  if(!(env->sprs[SPR_SR] & SPR_SR_F)) {
263
    env->delay_insn = 1;
264
    env->pc_delay = env->pc + (orreg_t)OP_PARAM1;
265
  }
266
}
267
 
268
__or_dynop void op_add_pc(void)
269
{
270
  env->pc += OP_PARAM1;
271
}
272
 
273
__or_dynop void op_nop_exit(void)
274
{
275
  op_support_nop_exit();
276
  FORCE_RET;
277
}
278
 
279
__or_dynop void op_nop_reset(void)
280
{
281
  op_support_nop_reset();
282
  FORCE_RET;
283
}
284
 
285
__or_dynop void op_nop_printf(void)
286
{
287
  op_support_nop_printf();
288
  FORCE_RET;
289
}
290
 
291
__or_dynop void op_nop_report(void)
292
{
293
  op_support_nop_report();
294
  FORCE_RET;
295
}
296
 
297
__or_dynop void op_nop_report_imm(void)
298
{
299
  op_support_nop_report_imm(OP_PARAM1);
300
}
301
 
302
/* FIXME: Create another 2 sched functions that to the actual analysis call
303
 * instead of bloating the recompiled code with this */
304
__or_dynop void op_analysis(void)
305
{
306
  SPEEDY_CALL(op_support_analysis);
307
}
308
 
309
__or_dynop void op_move_gpr1_pc_delay(void)
310
{
311
  env->pc_delay = env->reg[1];
312
  env->delay_insn = 1;
313
}
314
 
315
__or_dynop void op_move_gpr2_pc_delay(void)
316
{
317
  env->pc_delay = env->reg[2];
318
  env->delay_insn = 1;
319
}
320
 
321
__or_dynop void op_move_gpr3_pc_delay(void)
322
{
323
  env->pc_delay = env->reg[3];
324
  env->delay_insn = 1;
325
}
326
 
327
__or_dynop void op_move_gpr4_pc_delay(void)
328
{
329
  env->pc_delay = env->reg[4];
330
  env->delay_insn = 1;
331
}
332
 
333
__or_dynop void op_move_gpr5_pc_delay(void)
334
{
335
  env->pc_delay = env->reg[5];
336
  env->delay_insn = 1;
337
}
338
 
339
__or_dynop void op_move_gpr6_pc_delay(void)
340
{
341
  env->pc_delay = env->reg[6];
342
  env->delay_insn = 1;
343
}
344
 
345
__or_dynop void op_move_gpr7_pc_delay(void)
346
{
347
  env->pc_delay = env->reg[7];
348
  env->delay_insn = 1;
349
}
350
 
351
__or_dynop void op_move_gpr8_pc_delay(void)
352
{
353
  env->pc_delay = env->reg[8];
354
  env->delay_insn = 1;
355
}
356
 
357
__or_dynop void op_move_gpr9_pc_delay(void)
358
{
359
  env->pc_delay = env->reg[9];
360
  env->delay_insn = 1;
361
}
362
 
363
__or_dynop void op_move_gpr10_pc_delay(void)
364
{
365
  env->pc_delay = env->reg[10];
366
  env->delay_insn = 1;
367
}
368
 
369
__or_dynop void op_move_gpr11_pc_delay(void)
370
{
371
  env->pc_delay = env->reg[11];
372
  env->delay_insn = 1;
373
}
374
 
375
__or_dynop void op_move_gpr12_pc_delay(void)
376
{
377
  env->pc_delay = env->reg[12];
378
  env->delay_insn = 1;
379
}
380
 
381
__or_dynop void op_move_gpr13_pc_delay(void)
382
{
383
  env->pc_delay = env->reg[13];
384
  env->delay_insn = 1;
385
}
386
 
387
__or_dynop void op_move_gpr14_pc_delay(void)
388
{
389
  env->pc_delay = env->reg[14];
390
  env->delay_insn = 1;
391
}
392
 
393
__or_dynop void op_move_gpr15_pc_delay(void)
394
{
395
  env->pc_delay = env->reg[15];
396
  env->delay_insn = 1;
397
}
398
 
399
__or_dynop void op_move_gpr16_pc_delay(void)
400
{
401
  env->pc_delay = env->reg[16];
402
  env->delay_insn = 1;
403
}
404
 
405
__or_dynop void op_move_gpr17_pc_delay(void)
406
{
407
  env->pc_delay = env->reg[17];
408
  env->delay_insn = 1;
409
}
410
 
411
__or_dynop void op_move_gpr18_pc_delay(void)
412
{
413
  env->pc_delay = env->reg[18];
414
  env->delay_insn = 1;
415
}
416
 
417
__or_dynop void op_move_gpr19_pc_delay(void)
418
{
419
  env->pc_delay = env->reg[19];
420
  env->delay_insn = 1;
421
}
422
 
423
__or_dynop void op_move_gpr20_pc_delay(void)
424
{
425
  env->pc_delay = env->reg[20];
426
  env->delay_insn = 1;
427
}
428
 
429
__or_dynop void op_move_gpr21_pc_delay(void)
430
{
431
  env->pc_delay = env->reg[21];
432
  env->delay_insn = 1;
433
}
434
 
435
__or_dynop void op_move_gpr22_pc_delay(void)
436
{
437
  env->pc_delay = env->reg[22];
438
  env->delay_insn = 1;
439
}
440
 
441
__or_dynop void op_move_gpr23_pc_delay(void)
442
{
443
  env->pc_delay = env->reg[23];
444
  env->delay_insn = 1;
445
}
446
 
447
__or_dynop void op_move_gpr24_pc_delay(void)
448
{
449
  env->pc_delay = env->reg[24];
450
  env->delay_insn = 1;
451
}
452
 
453
__or_dynop void op_move_gpr25_pc_delay(void)
454
{
455
  env->pc_delay = env->reg[25];
456
  env->delay_insn = 1;
457
}
458
 
459
__or_dynop void op_move_gpr26_pc_delay(void)
460
{
461
  env->pc_delay = env->reg[26];
462
  env->delay_insn = 1;
463
}
464
 
465
__or_dynop void op_move_gpr27_pc_delay(void)
466
{
467
  env->pc_delay = env->reg[27];
468
  env->delay_insn = 1;
469
}
470
 
471
__or_dynop void op_move_gpr28_pc_delay(void)
472
{
473
  env->pc_delay = env->reg[28];
474
  env->delay_insn = 1;
475
}
476
 
477
__or_dynop void op_move_gpr29_pc_delay(void)
478
{
479
  env->pc_delay = env->reg[29];
480
  env->delay_insn = 1;
481
}
482
 
483
__or_dynop void op_move_gpr30_pc_delay(void)
484
{
485
  env->pc_delay = env->reg[30];
486
  env->delay_insn = 1;
487
}
488
 
489
__or_dynop void op_move_gpr31_pc_delay(void)
490
{
491
  env->pc_delay = env->reg[31];
492
  env->delay_insn = 1;
493
}
494
 
495
#define OP_FILE "op-1t-op.h"
496
#include "op-1t.h"
497
#undef OP_FILE
498
 
499
#define OP_FILE "op-2t-op.h"
500
#include "op-2t.h"
501
#undef OP_FILE
502
 
503
#define OP_FILE "op-3t-op.h"
504
#include "op-3t.h"
505
#undef OP_FILE
506
 
507
#define OP_FILE "op-arith-op.h"
508
#define OP_EXTRA
509
 
510
#define OP /
511
#define OP_CAST(x) (orreg_t)(x)
512
#define OP_NAME div
513
#include "op-3t.h"
514
#undef OP_NAME
515
#undef OP_CAST
516
#undef OP
517
 
518
#define OP /
519
#define OP_CAST(x) (x)
520
#define OP_NAME divu
521
#include "op-3t.h"
522
#undef OP_NAME
523
#undef OP_CAST
524
#undef OP
525
 
526
#define OP *
527
#define OP_CAST(x) (x)
528
#define OP_NAME mulu
529
#include "op-3t.h"
530
#undef OP_NAME
531
#undef OP_CAST
532
#undef OP
533
 
534
#define OP -
535
#define OP_CAST(x) (orreg_t)(x)
536
#define OP_NAME sub
537
#include "op-3t.h"
538
#undef OP_NAME
539
#undef OP_CAST
540
#undef OP
541
 
542
#undef OP_EXTRA
543
 
544
#define OP_EXTRA + ((env->sprs[SPR_SR] & SPR_SR_CY) >> 10)
545
#define OP +
546
#define OP_CAST(x) (orreg_t)(x)
547
#define OP_NAME addc
548
#include "op-3t.h"
549
#include "op-2t.h"
550
#undef OP_NAME
551
#undef OP_CAST
552
#undef OP
553
 
554
#undef OP_EXTRA
555
#define OP_EXTRA
556
 
557
#define OP +
558
#define OP_CAST(x) (orreg_t)(x)
559
#define OP_NAME add
560
#include "op-3t.h"
561
#include "op-2t.h"
562
#undef OP_NAME
563
#undef OP_CAST
564
#undef OP
565
 
566
#define OP &
567
#define OP_CAST(x) (x)
568
#define OP_NAME and
569
#include "op-3t.h"
570
#include "op-2t.h"
571
#undef OP_NAME
572
#undef OP_CAST
573
#undef OP
574
 
575
#define OP *
576
#define OP_CAST(x) (orreg_t)(x)
577
#define OP_NAME mul
578
#include "op-3t.h"
579
#include "op-2t.h"
580
#undef OP_NAME
581
#undef OP_CAST
582
#undef OP
583
 
584
#define OP |
585
#define OP_CAST(x) (x)
586
#define OP_NAME or
587
#include "op-3t.h"
588
#include "op-2t.h"
589
#undef OP_NAME
590
#undef OP_CAST
591
#undef OP
592
 
593
#define OP <<
594
#define OP_CAST(x) (x)
595
#define OP_NAME sll
596
#include "op-3t.h"
597
#include "op-2t.h"
598
#undef OP_NAME
599
#undef OP_CAST
600
#undef OP
601
 
602
#define OP >>
603
#define OP_CAST(x) (orreg_t)(x)
604
#define OP_NAME sra
605
#include "op-3t.h"
606
#include "op-2t.h"
607
#undef OP_NAME
608
#undef OP_CAST
609
#undef OP
610
 
611
#define OP >>
612
#define OP_CAST(x) (x)
613
#define OP_NAME srl
614
#include "op-3t.h"
615
#include "op-2t.h"
616
#undef OP_NAME
617
#undef OP_CAST
618
#undef OP
619
 
620
#define OP ^
621
#define OP_CAST(x) (x)
622
#define OP_NAME xor
623
#include "op-3t.h"
624
#include "op-2t.h"
625
#undef OP_NAME
626
#undef OP_CAST
627
#undef OP
628
 
629
#undef OP_EXTRA
630
#undef OP_FILE
631
 
632
#define OP_FILE "op-extend-op.h"
633
 
634
#define EXT_NAME extbs
635
#define EXT_TYPE int8_t
636
#define EXT_CAST (orreg_t)
637
#include "op-2t.h"
638
#undef EXT_CAST
639
#undef EXT_TYPE
640
#undef EXT_NAME
641
 
642
#define EXT_NAME extbz
643
#define EXT_TYPE uint8_t
644
#define EXT_CAST (uorreg_t)
645
#include "op-2t.h"
646
#undef EXT_CAST
647
#undef EXT_TYPE
648
#undef EXT_NAME
649
 
650
#define EXT_NAME exths
651
#define EXT_TYPE int16_t
652
#define EXT_CAST (orreg_t)
653
#include "op-2t.h"
654
#undef EXT_CAST
655
#undef EXT_TYPE
656
#undef EXT_NAME
657
 
658
#define EXT_NAME exthz
659
#define EXT_TYPE uint16_t
660
#define EXT_CAST (uorreg_t)
661
#include "op-2t.h"
662
#undef EXT_CAST
663
#undef EXT_TYPE
664
#undef EXT_NAME
665
 
666
#undef OP_FILE
667
 
668
#define OP_FILE "op-comp-op.h"
669
 
670
#define COMP ==
671
#define COMP_NAME sfeq
672
#define COMP_CAST(x) (x)
673
#include "op-2t.h"
674
#include "op-1t.h"
675
#undef COMP_CAST
676
#undef COMP_NAME
677
#undef COMP
678
 
679
#define COMP !=
680
#define COMP_NAME sfne
681
#define COMP_CAST(x) (x)
682
#include "op-2t.h"
683
#include "op-1t.h"
684
#undef COMP_CAST
685
#undef COMP_NAME
686
#undef COMP
687
 
688
#define COMP >
689
#define COMP_NAME sfgtu
690
#define COMP_CAST(x) (x)
691
#include "op-2t.h"
692
#include "op-1t.h"
693
#undef COMP_CAST
694
#undef COMP_NAME
695
#undef COMP
696
 
697
#define COMP >=
698
#define COMP_NAME sfgeu
699
#define COMP_CAST(x) (x)
700
#include "op-2t.h"
701
#include "op-1t.h"
702
#undef COMP_CAST
703
#undef COMP_NAME
704
#undef COMP
705
 
706
#define COMP <
707
#define COMP_NAME sfltu
708
#define COMP_CAST(x) (x)
709
#include "op-2t.h"
710
#include "op-1t.h"
711
#undef COMP_CAST
712
#undef COMP_NAME
713
#undef COMP
714
 
715
#define COMP <=
716
#define COMP_NAME sfleu
717
#define COMP_CAST(x) (x)
718
#include "op-2t.h"
719
#include "op-1t.h"
720
#undef COMP_CAST
721
#undef COMP_NAME
722
#undef COMP
723
 
724
#define COMP >
725
#define COMP_NAME sfgts
726
#define COMP_CAST(x) (orreg_t)(x)
727
#include "op-2t.h"
728
#include "op-1t.h"
729
#undef COMP_CAST
730
#undef COMP_NAME
731
#undef COMP
732
 
733
#define COMP >=
734
#define COMP_NAME sfges
735
#define COMP_CAST(x) (orreg_t)(x)
736
#include "op-2t.h"
737
#include "op-1t.h"
738
#undef COMP_CAST
739
#undef COMP_NAME
740
#undef COMP
741
 
742
#define COMP <
743
#define COMP_NAME sflts
744
#define COMP_CAST(x) (orreg_t)(x)
745
#include "op-2t.h"
746
#include "op-1t.h"
747
#undef COMP_CAST
748
#undef COMP_NAME
749
#undef COMP
750
 
751
#define COMP <=
752
#define COMP_NAME sfles
753
#define COMP_CAST(x) (orreg_t)(x)
754
#include "op-2t.h"
755
#include "op-1t.h"
756
#undef COMP_CAST
757
#undef COMP_NAME
758
#undef COMP
759
 
760
#undef OP_FILE
761
 
762
#define OP_FILE "op-t-reg-mov-op.h"
763
#include "op-1t.h"
764
#undef OP_FILE
765
 
766
#define OP_FILE "op-mftspr-op.h"
767
#include "op-1t.h"
768
#include "op-2t.h"
769
#undef OP_FILE
770
#include "op-mftspr-op.h"
771
 
772
#define OP_FILE "op-mac-op.h"
773
 
774
#define OP +=
775
#define OP_NAME mac
776
#include "op-2t.h"
777
#undef OP_NAME
778
#undef OP
779
 
780
#define OP -=
781
#define OP_NAME msb
782
#include "op-2t.h"
783
#undef OP_NAME
784
#undef OP
785
 
786
#undef OP_FILE
787
 
788
#define OP_FILE "op-lwhb-op.h"
789
 
790
#define LS_OP_NAME lbz
791
#define LS_OP_CAST
792
#define LS_OP_FUNC eval_mem8
793
#include "op-2t.h"
794
#include "op-1t.h"
795
#undef LS_OP_FUNC
796
#undef LS_OP_CAST
797
#undef LS_OP_NAME
798
 
799
#define LS_OP_NAME lbs
800
#define LS_OP_CAST (int8_t)
801
#define LS_OP_FUNC eval_mem8
802
#include "op-2t.h"
803
#include "op-1t.h"
804
#undef LS_OP_FUNC
805
#undef LS_OP_CAST
806
#undef LS_OP_NAME
807
 
808
#define LS_OP_NAME lhz
809
#define LS_OP_CAST
810
#define LS_OP_FUNC eval_mem16
811
#include "op-2t.h"
812
#include "op-1t.h"
813
#undef LS_OP_FUNC
814
#undef LS_OP_CAST
815
#undef LS_OP_NAME
816
 
817
#define LS_OP_NAME lhs
818
#define LS_OP_CAST (int16_t)
819
#define LS_OP_FUNC eval_mem16
820
#include "op-2t.h"
821
#include "op-1t.h"
822
#undef LS_OP_FUNC
823
#undef LS_OP_CAST
824
#undef LS_OP_NAME
825
 
826
#define LS_OP_NAME lwz
827
#define LS_OP_CAST
828
#define LS_OP_FUNC eval_mem32
829
#include "op-2t.h"
830
#include "op-1t.h"
831
#undef LS_OP_FUNC
832
#undef LS_OP_CAST
833
#undef LS_OP_NAME
834
 
835
#define LS_OP_NAME lws
836
#define LS_OP_CAST (int32_t)
837
#define LS_OP_FUNC eval_mem32
838
#include "op-2t.h"
839
#include "op-1t.h"
840
#undef LS_OP_FUNC
841
#undef LS_OP_CAST
842
#undef LS_OP_NAME
843
 
844
#undef OP_FILE
845
 
846
#define OP_FILE "op-swhb-op.h"
847
 
848
#define S_OP_NAME sb
849
#define S_FUNC set_mem8
850
#include "op-swhb-op.h"
851
#include "op-2t.h"
852
#include "op-1t.h"
853
#undef S_FUNC
854
#undef S_OP_NAME
855
 
856
#define S_OP_NAME sh
857
#define S_FUNC set_mem16
858
#include "op-swhb-op.h"
859
#include "op-2t.h"
860
#include "op-1t.h"
861
#undef S_FUNC
862
#undef S_OP_NAME
863
 
864
#define S_OP_NAME sw
865
#define S_FUNC set_mem32
866
#include "op-swhb-op.h"
867
#include "op-2t.h"
868
#include "op-1t.h"
869
#undef S_FUNC
870
#undef S_OP_NAME
871
 
872
__or_dynop void op_join_mem_cycles(void)
873
{
874
  runtime.sim.cycles += runtime.sim.mem_cycles;
875
  scheduler.job_queue->time -= runtime.sim.mem_cycles;
876
  runtime.sim.mem_cycles = 0;
877
}
878
 
879
__or_dynop void op_store_link_addr_gpr(void)
880
{
881
  env->reg[LINK_REGNO] = env->pc + 8;
882
}
883
 
884
__or_dynop void op_prep_rfe(void)
885
{
886
  env->sprs[SPR_SR] = env->sprs[SPR_ESR_BASE] | SPR_SR_FO;
887
  env->sprs[SPR_PPC] = env->pc;
888
  env->pc = env->sprs[SPR_EPCR_BASE] - 4;
889
}
890
 
891
static inline void prep_except(oraddr_t epcr_base)
892
{
893
  env->sprs[SPR_EPCR_BASE] = epcr_base;
894
 
895
  env->sprs[SPR_ESR_BASE] = env->sprs[SPR_SR];
896
 
897
  /* Address translation is always disabled when starting exception. */
898
  env->sprs[SPR_SR] &= ~SPR_SR_DME;
899
  env->sprs[SPR_SR] &= ~SPR_SR_IME;
900
 
901
  env->sprs[SPR_SR] &= ~SPR_SR_OVE;   /* Disable overflow flag exception. */
902
 
903
  env->sprs[SPR_SR] |= SPR_SR_SM;     /* SUPV mode */
904
  env->sprs[SPR_SR] &= ~(SPR_SR_IEE | SPR_SR_TEE);    /* Disable interrupts. */
905
}
906
 
907
/* Before the code in op_{sys,trap}{,_delay} gets run, the scheduler runs.
908
 * Therefore the pc will point to the instruction after the l.sys or l.trap
909
 * instruction */
910
__or_dynop void op_prep_sys_delay(void)
911
{
912
  env->delay_insn = 0;
913
  prep_except(env->pc - 4);
914
  env->pc = EXCEPT_SYSCALL - 4;
915
}
916
 
917
__or_dynop void op_prep_sys(void)
918
{
919
  prep_except(env->pc + 4);
920
  env->pc = EXCEPT_SYSCALL - 4;
921
}
922
 
923
__or_dynop void op_prep_trap_delay(void)
924
{
925
  env->delay_insn = 0;
926
  prep_except(env->pc - 4);
927
  env->pc = EXCEPT_TRAP - 4;
928
}
929
 
930
__or_dynop void op_prep_trap(void)
931
{
932
  prep_except(env->pc);
933
  env->pc = EXCEPT_TRAP - 4;
934
}
935
 
936
/* FIXME: This `instruction' should be split up like the l.trap and l.sys
937
 * instructions are done */
938
__or_dynop void op_illegal_delay(void)
939
{
940
  env->delay_insn = 0;
941
  env->sprs[SPR_EEAR_BASE] = env->pc - 4;
942
  env->pc = EXCEPT_ILLEGAL - 4;
943
}
944
 
945
__or_dynop void op_illegal(void)
946
{
947
  env->sprs[SPR_EEAR_BASE] = env->pc;
948
  env->pc = EXCEPT_ILLEGAL;
949
}
950
 
951
__or_dynop void op_do_sched(void)
952
{
953
  SPEEDY_CALL(do_sched_wrap);
954
}
955
 
956
__or_dynop void op_do_sched_delay(void)
957
{
958
  SPEEDY_CALL(do_sched_wrap_delay);
959
}
960
 
961
__or_dynop void op_macc(void)
962
{
963
  env->sprs[SPR_MACLO] = 0;
964
  env->sprs[SPR_MACHI] = 0;
965
}
966
 
967
__or_dynop void op_store_insn_ea(void)
968
{
969
  env->insn_ea = OP_PARAM1;
970
}
971
 

powered by: WebSVN 2.1.0

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