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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [or32/] [insnset.c] - Blame information for rev 121

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

Line No. Rev Author Line
1 19 jeremybenn
/* insnset.c -- Instruction specific functions.
2
 
3
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
                 2000-2002 Marko Mlinar, markom@opencores.org
5
   Copyright (C) 2008 Embecosm Limited
6 100 julius
   Copyright (C) 2009 Jungsook yang, jungsook.yang@uci.edu
7 19 jeremybenn
 
8
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
9 100 julius
   Contributor Julius Baxter julius@orsoc.se
10
 
11 19 jeremybenn
   This file is part of OpenRISC 1000 Architectural Simulator.
12
 
13
   This program is free software; you can redistribute it and/or modify it
14
   under the terms of the GNU General Public License as published by the Free
15
   Software Foundation; either version 3 of the License, or (at your option)
16
   any later version.
17
 
18
   This program is distributed in the hope that it will be useful, but WITHOUT
19
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
21
   more details.
22
 
23
   You should have received a copy of the GNU General Public License along
24
   with this program.  If not, see <http://www.gnu.org/licenses/>. */
25
 
26
/* This program is commented throughout in a fashion suitable for processing
27
   with Doxygen. */
28
 
29
 
30
INSTRUCTION (l_add) {
31
  orreg_t temp1, temp2, temp3;
32
  int8_t temp4;
33
 
34
  temp2 = (orreg_t)PARAM2;
35
  temp3 = (orreg_t)PARAM1;
36
  temp1 = temp2 + temp3;
37
  SET_PARAM0(temp1);
38 112 jeremybenn
 
39
  /* Set overflow if two negative values gave a positive sum, or if two
40
     positive values gave a negative sum. Otherwise clear it */
41
  if ((((long int) temp2 <  0) &&
42
       ((long int) temp3 <  0) &&
43
       ((long int) temp1 >= 0)) ||
44
      (((long int) temp2 >= 0) &&
45
       ((long int) temp3 >= 0) &&
46
       ((long int) temp1 <  0)))
47
    {
48
      cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
49
    }
50
  else
51
    {
52
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV;
53
    }
54
 
55
  /* Set the carry flag if (as unsigned values) the result is smaller than
56
     either operand (if it smaller than one, it will be smaller than both, so
57
     we need only test one). */
58 19 jeremybenn
  if ((uorreg_t) temp1 < (uorreg_t) temp2)
59 112 jeremybenn
    {
60
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
61
    }
62 19 jeremybenn
  else
63 112 jeremybenn
    {
64
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
65
    }
66 19 jeremybenn
 
67 112 jeremybenn
  /* Trigger a range exception if the overflow flag is set and the SR[OVE] bit
68
     is set. */
69
  if (((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) == SPR_SR_OVE) &&
70
      ((cpu_state.sprs[SPR_SR] & SPR_SR_OV)  == SPR_SR_OV))
71
    {
72
      except_handle (EXCEPT_RANGE, cpu_state.pc);
73
    }
74
 
75 19 jeremybenn
  temp4 = temp1;
76
  if (temp4 == temp1)
77
    or1k_mstats.byteadd++;
78
}
79
INSTRUCTION (l_addc) {
80
  orreg_t temp1, temp2, temp3;
81
  int8_t temp4;
82 114 jeremybenn
  int    carry_in = (cpu_state.sprs[SPR_SR] & SPR_SR_CY) == SPR_SR_CY;
83
 
84 19 jeremybenn
  temp2 = (orreg_t)PARAM2;
85
  temp3 = (orreg_t)PARAM1;
86
  temp1 = temp2 + temp3;
87 114 jeremybenn
 
88
  if(carry_in)
89
    {
90
      temp1++;                          /* Add in the carry bit */
91
    }
92
 
93 19 jeremybenn
  SET_PARAM0(temp1);
94 114 jeremybenn
 
95
  /* Set overflow if two negative values gave a positive sum, or if two
96
     positive values gave a negative sum. Otherwise clear it. There are no
97
     corner cases with the extra bit carried in (unlike the carry flag - see
98
     below). */
99
  if ((((long int) temp2 <  0) &&
100
       ((long int) temp3 <  0) &&
101
       ((long int) temp1 >= 0)) ||
102
      (((long int) temp2 >= 0) &&
103
       ((long int) temp3 >= 0) &&
104
       ((long int) temp1 <  0)))
105
    {
106
      cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
107
    }
108 19 jeremybenn
  else
109 114 jeremybenn
    {
110
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV;
111
    }
112 19 jeremybenn
 
113 114 jeremybenn
  /* Set the carry flag if (as unsigned values) the result is smaller than
114
     either operand (if it smaller than one, it will be smaller than both, so
115
     we need only test one). If there is a carry in, the test should be less
116
     than or equal, to deal with the 0 + 0xffffffff + c = 0 case (which
117
     generates a carry). */
118
  if ((carry_in && ((uorreg_t) temp1 <= (uorreg_t) temp2)) ||
119
      ((uorreg_t) temp1 < (uorreg_t) temp2))
120
    {
121
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
122
    }
123
  else
124
    {
125
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
126
    }
127
 
128
  /* Trigger a range exception if the overflow flag is set and the SR[OVE] bit
129
     is set. */
130
  if (((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) == SPR_SR_OVE) &&
131
      ((cpu_state.sprs[SPR_SR] & SPR_SR_OV)  == SPR_SR_OV))
132
    {
133
      except_handle (EXCEPT_RANGE, cpu_state.pc);
134
    }
135
 
136 19 jeremybenn
  temp4 = temp1;
137
  if (temp4 == temp1)
138
    or1k_mstats.byteadd++;
139
}
140
INSTRUCTION (l_sw) {
141
  int old_cyc = 0;
142
  if (config.cpu.sbuf_len) old_cyc = runtime.sim.mem_cycles;
143
  set_mem32(PARAM0, PARAM1, &breakpoint);
144
  if (config.cpu.sbuf_len) {
145
    int t = runtime.sim.mem_cycles;
146
    runtime.sim.mem_cycles = old_cyc;
147
    sbuf_store (t - old_cyc);
148
  }
149
}
150
INSTRUCTION (l_sb) {
151
  int old_cyc = 0;
152
  if (config.cpu.sbuf_len) old_cyc = runtime.sim.mem_cycles;
153
  set_mem8(PARAM0, PARAM1, &breakpoint);
154
  if (config.cpu.sbuf_len) {
155
    int t = runtime.sim.mem_cycles;
156
    runtime.sim.mem_cycles = old_cyc;
157
    sbuf_store (t- old_cyc);
158
  }
159
}
160
INSTRUCTION (l_sh) {
161
  int old_cyc = 0;
162
  if (config.cpu.sbuf_len) old_cyc = runtime.sim.mem_cycles;
163
  set_mem16(PARAM0, PARAM1, &breakpoint);
164
  if (config.cpu.sbuf_len) {
165
    int t = runtime.sim.mem_cycles;
166
    runtime.sim.mem_cycles = old_cyc;
167
    sbuf_store (t - old_cyc);
168
  }
169
}
170 104 jeremybenn
INSTRUCTION (l_lws) {
171
  uint32_t val;
172
  if (config.cpu.sbuf_len) sbuf_load ();
173
  val = eval_mem32(PARAM1, &breakpoint);
174
  /* If eval operand produced exception don't set anything. JPB changed to
175
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
176
  if (!(except_pending || breakpoint))
177
    SET_PARAM0(val);
178
}
179 19 jeremybenn
INSTRUCTION (l_lwz) {
180
  uint32_t val;
181
  if (config.cpu.sbuf_len) sbuf_load ();
182
  val = eval_mem32(PARAM1, &breakpoint);
183
  /* If eval operand produced exception don't set anything. JPB changed to
184
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
185
  if (!(except_pending || breakpoint))
186
    SET_PARAM0(val);
187
}
188
INSTRUCTION (l_lbs) {
189
  int8_t val;
190
  if (config.cpu.sbuf_len) sbuf_load ();
191
  val = eval_mem8(PARAM1, &breakpoint);
192
  /* If eval operand produced exception don't set anything. JPB changed to
193
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
194
  if (!(except_pending || breakpoint))
195
    SET_PARAM0(val);
196
}
197
INSTRUCTION (l_lbz) {
198
  uint8_t val;
199
  if (config.cpu.sbuf_len) sbuf_load ();
200
  val = eval_mem8(PARAM1, &breakpoint);
201
  /* If eval operand produced exception don't set anything. JPB changed to
202
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
203
  if (!(except_pending || breakpoint))
204
    SET_PARAM0(val);
205
}
206
INSTRUCTION (l_lhs) {
207
  int16_t val;
208
  if (config.cpu.sbuf_len) sbuf_load ();
209
  val = eval_mem16(PARAM1, &breakpoint);
210
  /* If eval operand produced exception don't set anything. JPB changed to
211
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
212
  if (!(except_pending || breakpoint))
213
    SET_PARAM0(val);
214
}
215
INSTRUCTION (l_lhz) {
216
  uint16_t val;
217
  if (config.cpu.sbuf_len) sbuf_load ();
218
  val = eval_mem16(PARAM1, &breakpoint);
219
  /* If eval operand produced exception don't set anything. JPB changed to
220
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
221
  if (!(except_pending || breakpoint))
222
    SET_PARAM0(val);
223
}
224
INSTRUCTION (l_movhi) {
225
  SET_PARAM0(PARAM1 << 16);
226
}
227
INSTRUCTION (l_and) {
228
  uorreg_t temp1;
229
  temp1 = PARAM1 & PARAM2;
230
  SET_OV_FLAG_FN (temp1);
231
  SET_PARAM0(temp1);
232
  if (ARITH_SET_FLAG) {
233
    if(!temp1)
234
      cpu_state.sprs[SPR_SR] |= SPR_SR_F;
235
    else
236
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
237
  }
238
}
239
INSTRUCTION (l_or) {
240
  uorreg_t temp1;
241
  temp1 = PARAM1 | PARAM2;
242
  SET_OV_FLAG_FN (temp1);
243
  SET_PARAM0(temp1);
244
}
245
INSTRUCTION (l_xor) {
246
  uorreg_t temp1;
247
  temp1 = PARAM1 ^ PARAM2;
248
  SET_OV_FLAG_FN (temp1);
249
  SET_PARAM0(temp1);
250
}
251
INSTRUCTION (l_sub) {
252
  orreg_t temp1;
253
  temp1 = (orreg_t)PARAM1 - (orreg_t)PARAM2;
254
  SET_OV_FLAG_FN (temp1);
255
  SET_PARAM0(temp1);
256
}
257
/*int mcount = 0;*/
258
INSTRUCTION (l_mul) {
259 118 jeremybenn
  orreg_t   temp0, temp1, temp2;
260
  LONGEST   ltemp0, ltemp1, ltemp2;
261
  ULONGEST  ultemp0, ultemp1, ultemp2;
262
 
263
  /* Args in 32-bit */
264
  temp2 = (orreg_t) PARAM2;
265
  temp1 = (orreg_t) PARAM1;
266
 
267
  /* Compute initially in 64-bit */
268
  ltemp1 = (LONGEST) temp1;
269
  ltemp2 = (LONGEST) temp2;
270
  ltemp0 = ltemp1 * ltemp2;
271
 
272
  temp0  = (orreg_t) (ltemp0  & 0xffffffffLL);
273
  SET_PARAM0 (temp0);
274
 
275
  /* We have 2's complement overflow, if the result is less than the smallest
276
     possible 32-bit negative number, or greater than the largest possible
277
     32-bit positive number. */
278
  if ((ltemp0 < (LONGEST) INT32_MIN) || (ltemp0 > (LONGEST) INT32_MAX))
279
    {
280
      cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
281
    }
282
  else
283
    {
284
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV;
285
    }
286
 
287
  /* We have 1's complement overflow, if, as an unsigned operation, the result
288
     is greater than the largest possible 32-bit unsigned number. This is
289
     probably quicker than unpicking the bits of the signed result. */
290
  ultemp1 = (ULONGEST) temp1 & 0xffffffffULL;
291
  ultemp2 = (ULONGEST) temp2 & 0xffffffffULL;
292
  ultemp0 = ultemp1 * ultemp2;
293
 
294
  if (ultemp0 > (ULONGEST) UINT32_MAX)
295
    {
296
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
297
    }
298
  else
299
    {
300
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
301
    }
302
 
303
  /* Trigger a range exception if the overflow flag is set and the SR[OVE] bit
304
     is set. */
305
  if (((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) == SPR_SR_OVE) &&
306
      ((cpu_state.sprs[SPR_SR] & SPR_SR_OV)  == SPR_SR_OV))
307
    {
308
      except_handle (EXCEPT_RANGE, cpu_state.pc);
309
    }
310 19 jeremybenn
}
311 118 jeremybenn
INSTRUCTION (l_mulu) {
312
  uorreg_t   temp0, temp1, temp2;
313
  ULONGEST  ultemp0, ultemp1, ultemp2;
314
 
315
  /* Args in 32-bit */
316
  temp2 = (uorreg_t) PARAM2;
317
  temp1 = (uorreg_t) PARAM1;
318
 
319
  /* Compute initially in 64-bit */
320
  ultemp1 = (ULONGEST) temp1 & 0xffffffffULL;
321
  ultemp2 = (ULONGEST) temp2 & 0xffffffffULL;
322
  ultemp0 = ultemp1 * ultemp2;
323
 
324
  temp0  = (uorreg_t) (ultemp0  & 0xffffffffULL);
325
  SET_PARAM0 (temp0);
326
 
327
  /* We never have 2's complement overflow */
328
  cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV;
329
 
330
  /* We have 1's complement overflow, if the result is greater than the
331
     largest possible 32-bit unsigned number. */
332
  if (ultemp0 > (ULONGEST) UINT32_MAX)
333
    {
334
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
335
    }
336
  else
337
    {
338
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
339
    }
340
}
341 19 jeremybenn
INSTRUCTION (l_div) {
342 118 jeremybenn
  orreg_t  temp3, temp2, temp1;
343 19 jeremybenn
 
344 118 jeremybenn
  temp3 = (orreg_t) PARAM2;
345
  temp2 = (orreg_t) PARAM1;
346
 
347
 /* Check for divide by zero (sets carry) */
348
  if (0 == temp3)
349
    {
350
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
351
    }
352
  else
353
    {
354
      temp1 = temp2 / temp3;
355
      SET_PARAM0(temp1);
356
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
357
    }
358
 
359
  cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV; /* Never set */
360
 
361
  /* Trigger a range exception if the overflow flag is set and the SR[OVE] bit
362
     is set. */
363
  if (((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) == SPR_SR_OVE) &&
364
      ((cpu_state.sprs[SPR_SR] & SPR_SR_CY)  == SPR_SR_CY))
365
    {
366
      except_handle (EXCEPT_RANGE, cpu_state.pc);
367
    }
368 19 jeremybenn
}
369
INSTRUCTION (l_divu) {
370
  uorreg_t temp3, temp2, temp1;
371
 
372 118 jeremybenn
  temp3 = (uorreg_t) PARAM2;
373
  temp2 = (uorreg_t) PARAM1;
374
 
375
 /* Check for divide by zero (sets carry) */
376
  if (0 == temp3)
377
    {
378
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
379
    }
380
  else
381
    {
382
      temp1 = temp2 / temp3;
383
      SET_PARAM0(temp1);
384
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
385
    }
386
 
387
  cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV; /* Never set */
388
 
389
  /* Trigger a range exception if the overflow flag is set and the SR[OVE] bit
390
     is set. */
391
  if (((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) == SPR_SR_OVE) &&
392
      ((cpu_state.sprs[SPR_SR] & SPR_SR_CY)  == SPR_SR_CY))
393
    {
394
      except_handle (EXCEPT_RANGE, cpu_state.pc);
395
    }
396 19 jeremybenn
}
397
INSTRUCTION (l_sll) {
398
  uorreg_t temp1;
399
 
400
  temp1 = PARAM1 << PARAM2;
401
  SET_OV_FLAG_FN (temp1);
402
  SET_PARAM0(temp1);
403
  /* runtime.sim.cycles += 2; */
404
}
405
INSTRUCTION (l_sra) {
406
  orreg_t temp1;
407
 
408
  temp1 = (orreg_t)PARAM1 >> PARAM2;
409
  SET_OV_FLAG_FN (temp1);
410
  SET_PARAM0(temp1);
411
  /* runtime.sim.cycles += 2; */
412
}
413
INSTRUCTION (l_srl) {
414
  uorreg_t temp1;
415
  temp1 = PARAM1 >> PARAM2;
416
  SET_OV_FLAG_FN (temp1);
417
  SET_PARAM0(temp1);
418
  /* runtime.sim.cycles += 2; */
419
}
420
INSTRUCTION (l_bf) {
421
  if (config.bpb.enabled) {
422
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
423
    or1k_mstats.bf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0][fwd]++;
424
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0);
425
  }
426
  if(cpu_state.sprs[SPR_SR] & SPR_SR_F) {
427
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
428
    btic_update(pcnext);
429
    next_delay_insn = 1;
430
  } else {
431
    btic_update(cpu_state.pc);
432
  }
433
}
434
INSTRUCTION (l_bnf) {
435
  if (config.bpb.enabled) {
436
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
437
    or1k_mstats.bnf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1][fwd]++;
438
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1);
439
  }
440
  if (!(cpu_state.sprs[SPR_SR] & SPR_SR_F)) {
441
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
442
    btic_update(pcnext);
443
    next_delay_insn = 1;
444
  } else {
445
    btic_update(cpu_state.pc);
446
  }
447
}
448
INSTRUCTION (l_j) {
449
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
450
  next_delay_insn = 1;
451
}
452
INSTRUCTION (l_jal) {
453
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
454
 
455
  setsim_reg(LINK_REGNO, cpu_state.pc + 8);
456
  next_delay_insn = 1;
457
  if (config.sim.profile) {
458
    struct label_entry *tmp;
459
    if (verify_memoryarea(cpu_state.pc_delay) && (tmp = get_label (cpu_state.pc_delay)))
460
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" %s\n",
461
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
462
               tmp->name);
463
    else
464
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" @%"PRIxADDR"\n",
465
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
466
               cpu_state.pc_delay);
467
  }
468
}
469
INSTRUCTION (l_jalr) {
470 121 jeremybenn
  /* Badly aligned destination or use of link register triggers an exception */
471
  uorreg_t  temp1 = PARAM0;
472
 
473
  if (REG_PARAM0 == LINK_REGNO)
474
    {
475
      except_handle (EXCEPT_ILLEGAL, cpu_state.pc);
476
    }
477
  else if ((temp1 & 0x3) != 0)
478
    {
479
      except_handle (EXCEPT_ALIGN, cpu_state.pc);
480
    }
481
  else
482
    {
483
      cpu_state.pc_delay = temp1;
484
      setsim_reg(LINK_REGNO, cpu_state.pc + 8);
485
      next_delay_insn = 1;
486
    }
487 19 jeremybenn
}
488
INSTRUCTION (l_jr) {
489 121 jeremybenn
  /* Badly aligned destination triggers an exception */
490
  uorreg_t  temp1 = PARAM0;
491
 
492
  if ((temp1 & 0x3) != 0)
493
    {
494
      except_handle (EXCEPT_ALIGN, cpu_state.pc);
495
    }
496
  else
497
    {
498
      cpu_state.pc_delay = temp1;
499
      next_delay_insn = 1;
500
 
501
      if (config.sim.profile)
502
        {
503
          fprintf (runtime.sim.fprof, "-%08llX %"PRIxADDR"\n",
504
                   runtime.sim.cycles, cpu_state.pc_delay);
505
        }
506
    }
507 19 jeremybenn
}
508
INSTRUCTION (l_rfe) {
509
  pcnext = cpu_state.sprs[SPR_EPCR_BASE];
510
  mtspr(SPR_SR, cpu_state.sprs[SPR_ESR_BASE]);
511
}
512
INSTRUCTION (l_nop) {
513
  uint32_t k = PARAM0;
514
  switch (k) {
515
    case NOP_NOP:
516
      break;
517
    case NOP_EXIT:
518
      PRINTF("exit(%"PRIdREG")\n", evalsim_reg (3));
519
      fprintf(stderr, "@reset : cycles %lld, insn #%lld\n",
520
              runtime.sim.reset_cycles, runtime.cpu.reset_instructions);
521
      fprintf(stderr, "@exit  : cycles %lld, insn #%lld\n", runtime.sim.cycles,
522
              runtime.cpu.instructions);
523
      fprintf(stderr, " diff  : cycles %lld, insn #%lld\n",
524
              runtime.sim.cycles - runtime.sim.reset_cycles,
525
              runtime.cpu.instructions - runtime.cpu.reset_instructions);
526
      if (config.debug.gdb_enabled)
527
        set_stall_state (1);
528
      else
529
        sim_done();
530
      break;
531
    case NOP_CNT_RESET:
532
      PRINTF("****************** counters reset ******************\n");
533
      PRINTF("cycles %lld, insn #%lld\n", runtime.sim.cycles, runtime.cpu.instructions);
534
      PRINTF("****************** counters reset ******************\n");
535
      runtime.sim.reset_cycles = runtime.sim.cycles;
536
      runtime.cpu.reset_instructions = runtime.cpu.instructions;
537
      break;
538
    case NOP_PUTC:              /*JPB */
539
      printf( "%c", (char)(evalsim_reg( 3 ) & 0xff));
540
      fflush( stdout );
541
      break;
542 82 jeremybenn
    case NOP_GET_TICKS:
543
      cpu_state.reg[11] = runtime.sim.cycles & 0xffffffff;
544
      cpu_state.reg[12] = runtime.sim.cycles >> 32;
545
      break;
546
    case NOP_GET_PS:
547
      cpu_state.reg[11] = config.sim.clkcycle_ps;
548
      break;
549 19 jeremybenn
    case NOP_REPORT:
550
      PRINTF("report(0x%"PRIxREG");\n", evalsim_reg(3));
551
    default:
552
      if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
553
      PRINTF("report %" PRIdREG " (0x%"PRIxREG");\n", k - NOP_REPORT_FIRST,
554
             evalsim_reg(3));
555
      break;
556
  }
557
}
558
INSTRUCTION (l_sfeq) {
559
  if(PARAM0 == PARAM1)
560
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
561
  else
562
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
563
}
564
INSTRUCTION (l_sfne) {
565
  if(PARAM0 != PARAM1)
566
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
567
  else
568
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
569
}
570
INSTRUCTION (l_sfgts) {
571
  if((orreg_t)PARAM0 > (orreg_t)PARAM1)
572
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
573
  else
574
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
575
}
576
INSTRUCTION (l_sfges) {
577
  if((orreg_t)PARAM0 >= (orreg_t)PARAM1)
578
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
579
  else
580
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
581
}
582
INSTRUCTION (l_sflts) {
583
  if((orreg_t)PARAM0 < (orreg_t)PARAM1)
584
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
585
  else
586
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
587
}
588
INSTRUCTION (l_sfles) {
589
  if((orreg_t)PARAM0 <= (orreg_t)PARAM1)
590
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
591
  else
592
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
593
}
594
INSTRUCTION (l_sfgtu) {
595
  if(PARAM0 > PARAM1)
596
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
597
  else
598
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
599
}
600
INSTRUCTION (l_sfgeu) {
601
  if(PARAM0 >= PARAM1)
602
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
603
  else
604
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
605
}
606
INSTRUCTION (l_sfltu) {
607
  if(PARAM0 < PARAM1)
608
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
609
  else
610
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
611
}
612
INSTRUCTION (l_sfleu) {
613
  if(PARAM0 <= PARAM1)
614
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
615
  else
616
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
617
}
618
INSTRUCTION (l_extbs) {
619
  int8_t x;
620
  x = PARAM1;
621
  SET_PARAM0((orreg_t)x);
622
}
623
INSTRUCTION (l_extbz) {
624
  uint8_t x;
625
  x = PARAM1;
626
  SET_PARAM0((uorreg_t)x);
627
}
628
INSTRUCTION (l_exths) {
629
  int16_t x;
630
  x = PARAM1;
631
  SET_PARAM0((orreg_t)x);
632
}
633
INSTRUCTION (l_exthz) {
634
  uint16_t x;
635
  x = PARAM1;
636
  SET_PARAM0((uorreg_t)x);
637
}
638
INSTRUCTION (l_extws) {
639
  int32_t x;
640
  x = PARAM1;
641
  SET_PARAM0((orreg_t)x);
642
}
643
INSTRUCTION (l_extwz) {
644
  uint32_t x;
645
  x = PARAM1;
646
  SET_PARAM0((uorreg_t)x);
647
}
648
INSTRUCTION (l_mtspr) {
649
  uint16_t regno = PARAM0 + PARAM2;
650
  uorreg_t value = PARAM1;
651
 
652
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
653
    mtspr(regno, value);
654
  else {
655
    PRINTF("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
656
    sim_done();
657
  }
658
}
659
INSTRUCTION (l_mfspr) {
660
  uint16_t regno = PARAM1 + PARAM2;
661
  uorreg_t value = mfspr(regno);
662
 
663
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
664
    SET_PARAM0(value);
665
  else {
666
    SET_PARAM0(0);
667
    PRINTF("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
668
    sim_done();
669
  }
670
}
671
INSTRUCTION (l_sys) {
672
  except_handle(EXCEPT_SYSCALL, cpu_state.sprs[SPR_EEAR_BASE]);
673
}
674
INSTRUCTION (l_trap) {
675
  /* TODO: some SR related code here! */
676
  except_handle(EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
677
}
678
INSTRUCTION (l_mac) {
679
  uorreg_t lo, hi;
680
  LONGEST l;
681 116 jeremybenn
  orreg_t x, y, t;
682 19 jeremybenn
 
683
  lo = cpu_state.sprs[SPR_MACLO];
684
  hi = cpu_state.sprs[SPR_MACHI];
685
  x = PARAM0;
686
  y = PARAM1;
687
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
688 116 jeremybenn
 
689
  /* Compute the temporary as (signed) 32-bits, then sign-extend to 64 when
690
     adding in. */
691 19 jeremybenn
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
692 116 jeremybenn
  t = x * y;
693
  l += (LONGEST) t;
694 19 jeremybenn
 
695
  /* This implementation is very fast - it needs only one cycle for mac.  */
696
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
697
  hi = ((LONGEST)l) >> 32;
698
  cpu_state.sprs[SPR_MACLO] = lo;
699
  cpu_state.sprs[SPR_MACHI] = hi;
700
/*   PRINTF ("(%"PRIxREG",%"PRIxREG"\n", hi, lo); */
701
}
702
INSTRUCTION (l_msb) {
703
  uorreg_t lo, hi;
704
  LONGEST l;
705
  orreg_t x, y;
706
 
707
  lo = cpu_state.sprs[SPR_MACLO];
708
  hi = cpu_state.sprs[SPR_MACHI];
709
  x = PARAM0;
710
  y = PARAM1;
711
 
712
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
713
 
714
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
715
  l -= x * y;
716
 
717
  /* This implementation is very fast - it needs only one cycle for msb.  */
718
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
719
  hi = ((LONGEST)l) >> 32;
720
  cpu_state.sprs[SPR_MACLO] = lo;
721
  cpu_state.sprs[SPR_MACHI] = hi;
722
/*   PRINTF ("(%"PRIxREG",%"PRIxREG")\n", hi, lo); */
723
}
724
INSTRUCTION (l_macrc) {
725 116 jeremybenn
  orreg_t lo;
726 19 jeremybenn
  /* No need for synchronization here -- all MAC instructions are 1 cycle long.  */
727
  lo =  cpu_state.sprs[SPR_MACLO];
728
  //PRINTF ("<%08x>\n", (unsigned long)l);
729 116 jeremybenn
  SET_PARAM0(lo);
730 19 jeremybenn
  cpu_state.sprs[SPR_MACLO] = 0;
731
  cpu_state.sprs[SPR_MACHI] = 0;
732
}
733
INSTRUCTION (l_cmov) {
734
  SET_PARAM0(cpu_state.sprs[SPR_SR] & SPR_SR_F ? PARAM1 : PARAM2);
735
}
736
INSTRUCTION (l_ff1) {
737
  SET_PARAM0(ffs(PARAM1));
738
}
739 115 jeremybenn
INSTRUCTION (l_fl1) {
740
  orreg_t t = (orreg_t)PARAM1;
741
 
742
  /* Reverse the word and use ffs */
743
  t = (((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1));
744
  t = (((t & 0xcccccccc) >> 2) | ((t & 0x33333333) << 2));
745
  t = (((t & 0xf0f0f0f0) >> 4) | ((t & 0x0f0f0f0f) << 4));
746
  t = (((t & 0xff00ff00) >> 8) | ((t & 0x00ff00ff) << 8));
747
  t = ffs ((t >> 16) | (t << 16));
748
 
749
  SET_PARAM0 (0 == t ? t : 33 - t);
750
}
751 19 jeremybenn
/******* Floating point instructions *******/
752
/* Single precision */
753
INSTRUCTION (lf_add_s) {
754 100 julius
  if (config.cpu.hardfloat) {
755
  FLOAT param0, param1, param2;
756
  param1.hval = (uorreg_t)PARAM1;
757
  param2.hval = (uorreg_t)PARAM2;
758
  param0.fval = param1.fval + param2.fval;
759
  SET_PARAM0(param0.hval);
760
  } else l_invalid();
761 19 jeremybenn
}
762
INSTRUCTION (lf_div_s) {
763 100 julius
  if (config.cpu.hardfloat) {
764
  FLOAT param0, param1, param2;
765
  param1.hval = (uorreg_t)PARAM1;
766
  param2.hval = (uorreg_t)PARAM2;
767
  param0.fval = param1.fval / param2.fval;
768
  SET_PARAM0(param0.hval);
769
  } else l_invalid();
770 19 jeremybenn
}
771
INSTRUCTION (lf_ftoi_s) {
772 100 julius
  if (config.cpu.hardfloat) {
773
    // no other way appeared to work --jb
774
    float tmp_f; memcpy((void*)&tmp_f, (void*)&PARAM1, sizeof(float));
775
    SET_PARAM0((int)tmp_f);
776
  } else l_invalid();
777 19 jeremybenn
}
778
INSTRUCTION (lf_itof_s) {
779 100 julius
  if (config.cpu.hardfloat) {
780
  FLOAT param0;
781
  param0.fval = (float)((int)PARAM1);
782
  SET_PARAM0(param0.hval);
783
  } else l_invalid();
784 19 jeremybenn
}
785
INSTRUCTION (lf_madd_s) {
786 100 julius
  if (config.cpu.hardfloat) {
787
  FLOAT param0,param1, param2;
788 104 jeremybenn
  param0.hval = (uorreg_t)PARAM0;
789
  param1.hval = (uorreg_t)PARAM1;
790 100 julius
  param2.hval = PARAM2;
791
  param0.fval += param1.fval * param2.fval;
792
  SET_PARAM0(param0.hval);
793
  } else l_invalid();
794 19 jeremybenn
}
795
INSTRUCTION (lf_mul_s) {
796 100 julius
  if (config.cpu.hardfloat) {
797
  FLOAT param0, param1, param2;
798
  param1.hval = (uorreg_t)PARAM1;
799
  param2.hval = (uorreg_t)PARAM2;
800
  param0.fval = param1.fval * param2.fval;
801
  SET_PARAM0(param0.hval);
802
  } else l_invalid();
803 19 jeremybenn
}
804
INSTRUCTION (lf_rem_s) {
805 100 julius
  if (config.cpu.hardfloat) {
806
  FLOAT param0, param1, param2;
807
  param1.hval = PARAM1;
808
  param2.hval = PARAM2;
809 104 jeremybenn
  param0.fval = fmodf (param1.fval, param2.fval);
810 100 julius
  SET_PARAM0(param0.hval);
811
  } else l_invalid();
812 19 jeremybenn
}
813
INSTRUCTION (lf_sfeq_s) {
814 100 julius
  if (config.cpu.hardfloat) {
815
  FLOAT param0, param1;
816
  param0.hval = PARAM0;
817
  param1.hval = PARAM1;
818
  if(param0.fval == param1.fval)
819 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
820
  else
821
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
822 100 julius
  } else l_invalid();
823 19 jeremybenn
}
824
INSTRUCTION (lf_sfge_s) {
825 100 julius
  if (config.cpu.hardfloat) {
826
  FLOAT param0, param1;
827
  param0.hval = PARAM0;
828
  param1.hval = PARAM1;
829
  if(param0.fval >= param1.fval)
830 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
831
  else
832
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
833 100 julius
  } else l_invalid();
834 19 jeremybenn
}
835
INSTRUCTION (lf_sfgt_s) {
836 100 julius
  if (config.cpu.hardfloat) {
837
  FLOAT param0, param1;
838
  param0.hval = PARAM0;
839
  param1.hval = PARAM1;
840
  if(param0.fval > param1.fval)
841 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
842
  else
843
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
844 100 julius
  } else l_invalid();
845 19 jeremybenn
}
846
INSTRUCTION (lf_sfle_s) {
847 100 julius
  if (config.cpu.hardfloat) {
848
  FLOAT param0, param1;
849
  param0.hval = PARAM0;
850
  param1.hval = PARAM1;
851
  if(param0.fval <= param1.fval)
852 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
853
  else
854
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
855 100 julius
  } else l_invalid();
856 19 jeremybenn
}
857
INSTRUCTION (lf_sflt_s) {
858 100 julius
  if (config.cpu.hardfloat) {
859
  FLOAT param0, param1;
860
  param0.hval = PARAM0;
861
  param1.hval = PARAM1;
862
  if(param0.fval < param1.fval)
863 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
864
  else
865
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
866 100 julius
  } else l_invalid();
867 19 jeremybenn
}
868
INSTRUCTION (lf_sfne_s) {
869 100 julius
  if (config.cpu.hardfloat) {
870
  FLOAT param0, param1;
871
  param0.hval = PARAM0;
872
  param1.hval = PARAM1;
873
  if(param0.fval != param1.fval)
874 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
875
  else
876
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
877 100 julius
  } else l_invalid();
878 19 jeremybenn
}
879
INSTRUCTION (lf_sub_s) {
880 100 julius
  if (config.cpu.hardfloat) {
881
  FLOAT param0, param1, param2;
882
  param1.hval = PARAM1;
883
  param2.hval = PARAM2;
884
  param0.fval = param1.fval - param2.fval;
885
  SET_PARAM0(param0.hval);
886
  } else l_invalid();
887 19 jeremybenn
}
888
 
889
/******* Custom instructions *******/
890
INSTRUCTION (l_cust1) {
891
  /*int destr = current->insn >> 21;
892
    int src1r = current->insn >> 15;
893
    int src2r = current->insn >> 9;*/
894
}
895
INSTRUCTION (l_cust2) {
896
}
897
INSTRUCTION (l_cust3) {
898
}
899
INSTRUCTION (l_cust4) {
900
}
901 100 julius
INSTRUCTION (lf_cust1) {
902
}

powered by: WebSVN 2.1.0

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