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 1721

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

powered by: WebSVN 2.1.0

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