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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc1/] [or1ksim/] [cpu/] [or32/] [op.c] - Blame information for rev 1728

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

powered by: WebSVN 2.1.0

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