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

Subversion Repositories openrisc

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

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 122 jeremybenn
INSTRUCTION (l_ror) {
421
  uorreg_t temp1;
422
  temp1  = PARAM1 >> (PARAM2 & 0x1f);
423
  temp1 |= PARAM1 << (32 - (PARAM2 & 0x1f));
424
  SET_PARAM0(temp1);
425
}
426 19 jeremybenn
INSTRUCTION (l_bf) {
427
  if (config.bpb.enabled) {
428
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
429
    or1k_mstats.bf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0][fwd]++;
430
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0);
431
  }
432
  if(cpu_state.sprs[SPR_SR] & SPR_SR_F) {
433
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
434
    btic_update(pcnext);
435
    next_delay_insn = 1;
436
  } else {
437
    btic_update(cpu_state.pc);
438
  }
439
}
440
INSTRUCTION (l_bnf) {
441
  if (config.bpb.enabled) {
442
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
443
    or1k_mstats.bnf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1][fwd]++;
444
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1);
445
  }
446
  if (!(cpu_state.sprs[SPR_SR] & SPR_SR_F)) {
447
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
448
    btic_update(pcnext);
449
    next_delay_insn = 1;
450
  } else {
451
    btic_update(cpu_state.pc);
452
  }
453
}
454
INSTRUCTION (l_j) {
455
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
456
  next_delay_insn = 1;
457
}
458
INSTRUCTION (l_jal) {
459
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
460
 
461
  setsim_reg(LINK_REGNO, cpu_state.pc + 8);
462
  next_delay_insn = 1;
463
  if (config.sim.profile) {
464
    struct label_entry *tmp;
465
    if (verify_memoryarea(cpu_state.pc_delay) && (tmp = get_label (cpu_state.pc_delay)))
466
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" %s\n",
467
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
468
               tmp->name);
469
    else
470
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" @%"PRIxADDR"\n",
471
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
472
               cpu_state.pc_delay);
473
  }
474
}
475
INSTRUCTION (l_jalr) {
476 121 jeremybenn
  /* Badly aligned destination or use of link register triggers an exception */
477
  uorreg_t  temp1 = PARAM0;
478
 
479
  if (REG_PARAM0 == LINK_REGNO)
480
    {
481
      except_handle (EXCEPT_ILLEGAL, cpu_state.pc);
482
    }
483
  else if ((temp1 & 0x3) != 0)
484
    {
485
      except_handle (EXCEPT_ALIGN, cpu_state.pc);
486
    }
487
  else
488
    {
489
      cpu_state.pc_delay = temp1;
490
      setsim_reg(LINK_REGNO, cpu_state.pc + 8);
491
      next_delay_insn = 1;
492
    }
493 19 jeremybenn
}
494
INSTRUCTION (l_jr) {
495 121 jeremybenn
  /* Badly aligned destination triggers an exception */
496
  uorreg_t  temp1 = PARAM0;
497
 
498
  if ((temp1 & 0x3) != 0)
499
    {
500
      except_handle (EXCEPT_ALIGN, cpu_state.pc);
501
    }
502
  else
503
    {
504
      cpu_state.pc_delay = temp1;
505
      next_delay_insn = 1;
506
 
507
      if (config.sim.profile)
508
        {
509
          fprintf (runtime.sim.fprof, "-%08llX %"PRIxADDR"\n",
510
                   runtime.sim.cycles, cpu_state.pc_delay);
511
        }
512
    }
513 19 jeremybenn
}
514
INSTRUCTION (l_rfe) {
515
  pcnext = cpu_state.sprs[SPR_EPCR_BASE];
516
  mtspr(SPR_SR, cpu_state.sprs[SPR_ESR_BASE]);
517
}
518
INSTRUCTION (l_nop) {
519
  uint32_t k = PARAM0;
520
  switch (k) {
521
    case NOP_NOP:
522
      break;
523
    case NOP_EXIT:
524
      PRINTF("exit(%"PRIdREG")\n", evalsim_reg (3));
525
      fprintf(stderr, "@reset : cycles %lld, insn #%lld\n",
526
              runtime.sim.reset_cycles, runtime.cpu.reset_instructions);
527
      fprintf(stderr, "@exit  : cycles %lld, insn #%lld\n", runtime.sim.cycles,
528
              runtime.cpu.instructions);
529
      fprintf(stderr, " diff  : cycles %lld, insn #%lld\n",
530
              runtime.sim.cycles - runtime.sim.reset_cycles,
531
              runtime.cpu.instructions - runtime.cpu.reset_instructions);
532
      if (config.debug.gdb_enabled)
533
        set_stall_state (1);
534
      else
535
        sim_done();
536
      break;
537
    case NOP_CNT_RESET:
538
      PRINTF("****************** counters reset ******************\n");
539
      PRINTF("cycles %lld, insn #%lld\n", runtime.sim.cycles, runtime.cpu.instructions);
540
      PRINTF("****************** counters reset ******************\n");
541
      runtime.sim.reset_cycles = runtime.sim.cycles;
542
      runtime.cpu.reset_instructions = runtime.cpu.instructions;
543
      break;
544
    case NOP_PUTC:              /*JPB */
545
      printf( "%c", (char)(evalsim_reg( 3 ) & 0xff));
546
      fflush( stdout );
547
      break;
548 82 jeremybenn
    case NOP_GET_TICKS:
549
      cpu_state.reg[11] = runtime.sim.cycles & 0xffffffff;
550
      cpu_state.reg[12] = runtime.sim.cycles >> 32;
551
      break;
552
    case NOP_GET_PS:
553
      cpu_state.reg[11] = config.sim.clkcycle_ps;
554
      break;
555 19 jeremybenn
    case NOP_REPORT:
556
      PRINTF("report(0x%"PRIxREG");\n", evalsim_reg(3));
557
    default:
558
      if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
559
      PRINTF("report %" PRIdREG " (0x%"PRIxREG");\n", k - NOP_REPORT_FIRST,
560
             evalsim_reg(3));
561
      break;
562
  }
563
}
564
INSTRUCTION (l_sfeq) {
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_sfne) {
571
  if(PARAM0 != 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_sfgts) {
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_sfges) {
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_sflts) {
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_sfles) {
595
  if((orreg_t)PARAM0 <= (orreg_t)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_sfgtu) {
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_sfgeu) {
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_sfltu) {
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_sfleu) {
619
  if(PARAM0 <= PARAM1)
620
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
621
  else
622
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
623
}
624
INSTRUCTION (l_extbs) {
625
  int8_t x;
626
  x = PARAM1;
627
  SET_PARAM0((orreg_t)x);
628
}
629
INSTRUCTION (l_extbz) {
630
  uint8_t x;
631
  x = PARAM1;
632
  SET_PARAM0((uorreg_t)x);
633
}
634
INSTRUCTION (l_exths) {
635
  int16_t x;
636
  x = PARAM1;
637
  SET_PARAM0((orreg_t)x);
638
}
639
INSTRUCTION (l_exthz) {
640
  uint16_t x;
641
  x = PARAM1;
642
  SET_PARAM0((uorreg_t)x);
643
}
644
INSTRUCTION (l_extws) {
645
  int32_t x;
646
  x = PARAM1;
647
  SET_PARAM0((orreg_t)x);
648
}
649
INSTRUCTION (l_extwz) {
650
  uint32_t x;
651
  x = PARAM1;
652
  SET_PARAM0((uorreg_t)x);
653
}
654
INSTRUCTION (l_mtspr) {
655 123 jeremybenn
  uint16_t regno = PARAM0 | PARAM2;
656 19 jeremybenn
  uorreg_t value = PARAM1;
657
 
658
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
659
    mtspr(regno, value);
660
  else {
661
    PRINTF("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
662
    sim_done();
663
  }
664
}
665
INSTRUCTION (l_mfspr) {
666 123 jeremybenn
  uint16_t regno = PARAM1 | PARAM2;
667 19 jeremybenn
  uorreg_t value = mfspr(regno);
668
 
669
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
670
    SET_PARAM0(value);
671
  else {
672
    SET_PARAM0(0);
673
    PRINTF("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
674
    sim_done();
675
  }
676
}
677
INSTRUCTION (l_sys) {
678
  except_handle(EXCEPT_SYSCALL, cpu_state.sprs[SPR_EEAR_BASE]);
679
}
680
INSTRUCTION (l_trap) {
681
  /* TODO: some SR related code here! */
682
  except_handle(EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
683
}
684
INSTRUCTION (l_mac) {
685
  uorreg_t lo, hi;
686
  LONGEST l;
687 116 jeremybenn
  orreg_t x, y, t;
688 19 jeremybenn
 
689
  lo = cpu_state.sprs[SPR_MACLO];
690
  hi = cpu_state.sprs[SPR_MACHI];
691
  x = PARAM0;
692
  y = PARAM1;
693
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
694 116 jeremybenn
 
695
  /* Compute the temporary as (signed) 32-bits, then sign-extend to 64 when
696
     adding in. */
697 19 jeremybenn
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
698 116 jeremybenn
  t = x * y;
699
  l += (LONGEST) t;
700 19 jeremybenn
 
701
  /* This implementation is very fast - it needs only one cycle for mac.  */
702
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
703
  hi = ((LONGEST)l) >> 32;
704
  cpu_state.sprs[SPR_MACLO] = lo;
705
  cpu_state.sprs[SPR_MACHI] = hi;
706
/*   PRINTF ("(%"PRIxREG",%"PRIxREG"\n", hi, lo); */
707
}
708
INSTRUCTION (l_msb) {
709
  uorreg_t lo, hi;
710
  LONGEST l;
711
  orreg_t x, y;
712
 
713
  lo = cpu_state.sprs[SPR_MACLO];
714
  hi = cpu_state.sprs[SPR_MACHI];
715
  x = PARAM0;
716
  y = PARAM1;
717
 
718
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
719
 
720
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
721
  l -= x * y;
722
 
723
  /* This implementation is very fast - it needs only one cycle for msb.  */
724
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
725
  hi = ((LONGEST)l) >> 32;
726
  cpu_state.sprs[SPR_MACLO] = lo;
727
  cpu_state.sprs[SPR_MACHI] = hi;
728
/*   PRINTF ("(%"PRIxREG",%"PRIxREG")\n", hi, lo); */
729
}
730
INSTRUCTION (l_macrc) {
731 116 jeremybenn
  orreg_t lo;
732 19 jeremybenn
  /* No need for synchronization here -- all MAC instructions are 1 cycle long.  */
733
  lo =  cpu_state.sprs[SPR_MACLO];
734
  //PRINTF ("<%08x>\n", (unsigned long)l);
735 116 jeremybenn
  SET_PARAM0(lo);
736 19 jeremybenn
  cpu_state.sprs[SPR_MACLO] = 0;
737
  cpu_state.sprs[SPR_MACHI] = 0;
738
}
739
INSTRUCTION (l_cmov) {
740
  SET_PARAM0(cpu_state.sprs[SPR_SR] & SPR_SR_F ? PARAM1 : PARAM2);
741
}
742
INSTRUCTION (l_ff1) {
743
  SET_PARAM0(ffs(PARAM1));
744
}
745 115 jeremybenn
INSTRUCTION (l_fl1) {
746
  orreg_t t = (orreg_t)PARAM1;
747
 
748
  /* Reverse the word and use ffs */
749
  t = (((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1));
750
  t = (((t & 0xcccccccc) >> 2) | ((t & 0x33333333) << 2));
751
  t = (((t & 0xf0f0f0f0) >> 4) | ((t & 0x0f0f0f0f) << 4));
752
  t = (((t & 0xff00ff00) >> 8) | ((t & 0x00ff00ff) << 8));
753
  t = ffs ((t >> 16) | (t << 16));
754
 
755
  SET_PARAM0 (0 == t ? t : 33 - t);
756
}
757 19 jeremybenn
/******* Floating point instructions *******/
758
/* Single precision */
759
INSTRUCTION (lf_add_s) {
760 100 julius
  if (config.cpu.hardfloat) {
761
  FLOAT param0, param1, param2;
762
  param1.hval = (uorreg_t)PARAM1;
763
  param2.hval = (uorreg_t)PARAM2;
764
  param0.fval = param1.fval + param2.fval;
765
  SET_PARAM0(param0.hval);
766
  } else l_invalid();
767 19 jeremybenn
}
768
INSTRUCTION (lf_div_s) {
769 100 julius
  if (config.cpu.hardfloat) {
770
  FLOAT param0, param1, param2;
771
  param1.hval = (uorreg_t)PARAM1;
772
  param2.hval = (uorreg_t)PARAM2;
773
  param0.fval = param1.fval / param2.fval;
774
  SET_PARAM0(param0.hval);
775
  } else l_invalid();
776 19 jeremybenn
}
777
INSTRUCTION (lf_ftoi_s) {
778 100 julius
  if (config.cpu.hardfloat) {
779
    // no other way appeared to work --jb
780
    float tmp_f; memcpy((void*)&tmp_f, (void*)&PARAM1, sizeof(float));
781
    SET_PARAM0((int)tmp_f);
782
  } else l_invalid();
783 19 jeremybenn
}
784
INSTRUCTION (lf_itof_s) {
785 100 julius
  if (config.cpu.hardfloat) {
786
  FLOAT param0;
787
  param0.fval = (float)((int)PARAM1);
788
  SET_PARAM0(param0.hval);
789
  } else l_invalid();
790 19 jeremybenn
}
791
INSTRUCTION (lf_madd_s) {
792 100 julius
  if (config.cpu.hardfloat) {
793
  FLOAT param0,param1, param2;
794 104 jeremybenn
  param0.hval = (uorreg_t)PARAM0;
795
  param1.hval = (uorreg_t)PARAM1;
796 100 julius
  param2.hval = PARAM2;
797
  param0.fval += param1.fval * param2.fval;
798
  SET_PARAM0(param0.hval);
799
  } else l_invalid();
800 19 jeremybenn
}
801
INSTRUCTION (lf_mul_s) {
802 100 julius
  if (config.cpu.hardfloat) {
803
  FLOAT param0, param1, param2;
804
  param1.hval = (uorreg_t)PARAM1;
805
  param2.hval = (uorreg_t)PARAM2;
806
  param0.fval = param1.fval * param2.fval;
807
  SET_PARAM0(param0.hval);
808
  } else l_invalid();
809 19 jeremybenn
}
810
INSTRUCTION (lf_rem_s) {
811 100 julius
  if (config.cpu.hardfloat) {
812
  FLOAT param0, param1, param2;
813
  param1.hval = PARAM1;
814
  param2.hval = PARAM2;
815 104 jeremybenn
  param0.fval = fmodf (param1.fval, param2.fval);
816 100 julius
  SET_PARAM0(param0.hval);
817
  } else l_invalid();
818 19 jeremybenn
}
819
INSTRUCTION (lf_sfeq_s) {
820 100 julius
  if (config.cpu.hardfloat) {
821
  FLOAT param0, param1;
822
  param0.hval = PARAM0;
823
  param1.hval = PARAM1;
824
  if(param0.fval == param1.fval)
825 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
826
  else
827
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
828 100 julius
  } else l_invalid();
829 19 jeremybenn
}
830
INSTRUCTION (lf_sfge_s) {
831 100 julius
  if (config.cpu.hardfloat) {
832
  FLOAT param0, param1;
833
  param0.hval = PARAM0;
834
  param1.hval = PARAM1;
835
  if(param0.fval >= param1.fval)
836 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
837
  else
838
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
839 100 julius
  } else l_invalid();
840 19 jeremybenn
}
841
INSTRUCTION (lf_sfgt_s) {
842 100 julius
  if (config.cpu.hardfloat) {
843
  FLOAT param0, param1;
844
  param0.hval = PARAM0;
845
  param1.hval = PARAM1;
846
  if(param0.fval > param1.fval)
847 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
848
  else
849
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
850 100 julius
  } else l_invalid();
851 19 jeremybenn
}
852
INSTRUCTION (lf_sfle_s) {
853 100 julius
  if (config.cpu.hardfloat) {
854
  FLOAT param0, param1;
855
  param0.hval = PARAM0;
856
  param1.hval = PARAM1;
857
  if(param0.fval <= param1.fval)
858 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
859
  else
860
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
861 100 julius
  } else l_invalid();
862 19 jeremybenn
}
863
INSTRUCTION (lf_sflt_s) {
864 100 julius
  if (config.cpu.hardfloat) {
865
  FLOAT param0, param1;
866
  param0.hval = PARAM0;
867
  param1.hval = PARAM1;
868
  if(param0.fval < param1.fval)
869 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
870
  else
871
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
872 100 julius
  } else l_invalid();
873 19 jeremybenn
}
874
INSTRUCTION (lf_sfne_s) {
875 100 julius
  if (config.cpu.hardfloat) {
876
  FLOAT param0, param1;
877
  param0.hval = PARAM0;
878
  param1.hval = PARAM1;
879
  if(param0.fval != param1.fval)
880 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
881
  else
882
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
883 100 julius
  } else l_invalid();
884 19 jeremybenn
}
885
INSTRUCTION (lf_sub_s) {
886 100 julius
  if (config.cpu.hardfloat) {
887
  FLOAT param0, param1, param2;
888
  param1.hval = PARAM1;
889
  param2.hval = PARAM2;
890
  param0.fval = param1.fval - param2.fval;
891
  SET_PARAM0(param0.hval);
892
  } else l_invalid();
893 19 jeremybenn
}
894
 
895
/******* Custom instructions *******/
896
INSTRUCTION (l_cust1) {
897
  /*int destr = current->insn >> 21;
898
    int src1r = current->insn >> 15;
899
    int src2r = current->insn >> 9;*/
900
}
901
INSTRUCTION (l_cust2) {
902
}
903
INSTRUCTION (l_cust3) {
904
}
905
INSTRUCTION (l_cust4) {
906
}
907 100 julius
INSTRUCTION (lf_cust1) {
908
}

powered by: WebSVN 2.1.0

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