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

Subversion Repositories openrisc

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

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
  cpu_state.pc_delay = PARAM0;
471
  setsim_reg(LINK_REGNO, cpu_state.pc + 8);
472
  next_delay_insn = 1;
473
}
474
INSTRUCTION (l_jr) {
475
  cpu_state.pc_delay = PARAM0;
476
  next_delay_insn = 1;
477
  if (config.sim.profile)
478
    fprintf (runtime.sim.fprof, "-%08llX %"PRIxADDR"\n", runtime.sim.cycles,
479
             cpu_state.pc_delay);
480
}
481
INSTRUCTION (l_rfe) {
482
  pcnext = cpu_state.sprs[SPR_EPCR_BASE];
483
  mtspr(SPR_SR, cpu_state.sprs[SPR_ESR_BASE]);
484
}
485
INSTRUCTION (l_nop) {
486
  uint32_t k = PARAM0;
487
  switch (k) {
488
    case NOP_NOP:
489
      break;
490
    case NOP_EXIT:
491
      PRINTF("exit(%"PRIdREG")\n", evalsim_reg (3));
492
      fprintf(stderr, "@reset : cycles %lld, insn #%lld\n",
493
              runtime.sim.reset_cycles, runtime.cpu.reset_instructions);
494
      fprintf(stderr, "@exit  : cycles %lld, insn #%lld\n", runtime.sim.cycles,
495
              runtime.cpu.instructions);
496
      fprintf(stderr, " diff  : cycles %lld, insn #%lld\n",
497
              runtime.sim.cycles - runtime.sim.reset_cycles,
498
              runtime.cpu.instructions - runtime.cpu.reset_instructions);
499
      if (config.debug.gdb_enabled)
500
        set_stall_state (1);
501
      else
502
        sim_done();
503
      break;
504
    case NOP_CNT_RESET:
505
      PRINTF("****************** counters reset ******************\n");
506
      PRINTF("cycles %lld, insn #%lld\n", runtime.sim.cycles, runtime.cpu.instructions);
507
      PRINTF("****************** counters reset ******************\n");
508
      runtime.sim.reset_cycles = runtime.sim.cycles;
509
      runtime.cpu.reset_instructions = runtime.cpu.instructions;
510
      break;
511
    case NOP_PUTC:              /*JPB */
512
      printf( "%c", (char)(evalsim_reg( 3 ) & 0xff));
513
      fflush( stdout );
514
      break;
515 82 jeremybenn
    case NOP_GET_TICKS:
516
      cpu_state.reg[11] = runtime.sim.cycles & 0xffffffff;
517
      cpu_state.reg[12] = runtime.sim.cycles >> 32;
518
      break;
519
    case NOP_GET_PS:
520
      cpu_state.reg[11] = config.sim.clkcycle_ps;
521
      break;
522 19 jeremybenn
    case NOP_REPORT:
523
      PRINTF("report(0x%"PRIxREG");\n", evalsim_reg(3));
524
    default:
525
      if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
526
      PRINTF("report %" PRIdREG " (0x%"PRIxREG");\n", k - NOP_REPORT_FIRST,
527
             evalsim_reg(3));
528
      break;
529
  }
530
}
531
INSTRUCTION (l_sfeq) {
532
  if(PARAM0 == PARAM1)
533
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
534
  else
535
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
536
}
537
INSTRUCTION (l_sfne) {
538
  if(PARAM0 != PARAM1)
539
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
540
  else
541
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
542
}
543
INSTRUCTION (l_sfgts) {
544
  if((orreg_t)PARAM0 > (orreg_t)PARAM1)
545
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
546
  else
547
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
548
}
549
INSTRUCTION (l_sfges) {
550
  if((orreg_t)PARAM0 >= (orreg_t)PARAM1)
551
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
552
  else
553
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
554
}
555
INSTRUCTION (l_sflts) {
556
  if((orreg_t)PARAM0 < (orreg_t)PARAM1)
557
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
558
  else
559
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
560
}
561
INSTRUCTION (l_sfles) {
562
  if((orreg_t)PARAM0 <= (orreg_t)PARAM1)
563
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
564
  else
565
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
566
}
567
INSTRUCTION (l_sfgtu) {
568
  if(PARAM0 > PARAM1)
569
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
570
  else
571
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
572
}
573
INSTRUCTION (l_sfgeu) {
574
  if(PARAM0 >= PARAM1)
575
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
576
  else
577
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
578
}
579
INSTRUCTION (l_sfltu) {
580
  if(PARAM0 < PARAM1)
581
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
582
  else
583
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
584
}
585
INSTRUCTION (l_sfleu) {
586
  if(PARAM0 <= PARAM1)
587
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
588
  else
589
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
590
}
591
INSTRUCTION (l_extbs) {
592
  int8_t x;
593
  x = PARAM1;
594
  SET_PARAM0((orreg_t)x);
595
}
596
INSTRUCTION (l_extbz) {
597
  uint8_t x;
598
  x = PARAM1;
599
  SET_PARAM0((uorreg_t)x);
600
}
601
INSTRUCTION (l_exths) {
602
  int16_t x;
603
  x = PARAM1;
604
  SET_PARAM0((orreg_t)x);
605
}
606
INSTRUCTION (l_exthz) {
607
  uint16_t x;
608
  x = PARAM1;
609
  SET_PARAM0((uorreg_t)x);
610
}
611
INSTRUCTION (l_extws) {
612
  int32_t x;
613
  x = PARAM1;
614
  SET_PARAM0((orreg_t)x);
615
}
616
INSTRUCTION (l_extwz) {
617
  uint32_t x;
618
  x = PARAM1;
619
  SET_PARAM0((uorreg_t)x);
620
}
621
INSTRUCTION (l_mtspr) {
622
  uint16_t regno = PARAM0 + PARAM2;
623
  uorreg_t value = PARAM1;
624
 
625
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
626
    mtspr(regno, value);
627
  else {
628
    PRINTF("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
629
    sim_done();
630
  }
631
}
632
INSTRUCTION (l_mfspr) {
633
  uint16_t regno = PARAM1 + PARAM2;
634
  uorreg_t value = mfspr(regno);
635
 
636
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
637
    SET_PARAM0(value);
638
  else {
639
    SET_PARAM0(0);
640
    PRINTF("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
641
    sim_done();
642
  }
643
}
644
INSTRUCTION (l_sys) {
645
  except_handle(EXCEPT_SYSCALL, cpu_state.sprs[SPR_EEAR_BASE]);
646
}
647
INSTRUCTION (l_trap) {
648
  /* TODO: some SR related code here! */
649
  except_handle(EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
650
}
651
INSTRUCTION (l_mac) {
652
  uorreg_t lo, hi;
653
  LONGEST l;
654 116 jeremybenn
  orreg_t x, y, t;
655 19 jeremybenn
 
656
  lo = cpu_state.sprs[SPR_MACLO];
657
  hi = cpu_state.sprs[SPR_MACHI];
658
  x = PARAM0;
659
  y = PARAM1;
660
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
661 116 jeremybenn
 
662
  /* Compute the temporary as (signed) 32-bits, then sign-extend to 64 when
663
     adding in. */
664 19 jeremybenn
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
665 116 jeremybenn
  t = x * y;
666
  l += (LONGEST) t;
667 19 jeremybenn
 
668
  /* This implementation is very fast - it needs only one cycle for mac.  */
669
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
670
  hi = ((LONGEST)l) >> 32;
671
  cpu_state.sprs[SPR_MACLO] = lo;
672
  cpu_state.sprs[SPR_MACHI] = hi;
673
/*   PRINTF ("(%"PRIxREG",%"PRIxREG"\n", hi, lo); */
674
}
675
INSTRUCTION (l_msb) {
676
  uorreg_t lo, hi;
677
  LONGEST l;
678
  orreg_t x, y;
679
 
680
  lo = cpu_state.sprs[SPR_MACLO];
681
  hi = cpu_state.sprs[SPR_MACHI];
682
  x = PARAM0;
683
  y = PARAM1;
684
 
685
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
686
 
687
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
688
  l -= x * y;
689
 
690
  /* This implementation is very fast - it needs only one cycle for msb.  */
691
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
692
  hi = ((LONGEST)l) >> 32;
693
  cpu_state.sprs[SPR_MACLO] = lo;
694
  cpu_state.sprs[SPR_MACHI] = hi;
695
/*   PRINTF ("(%"PRIxREG",%"PRIxREG")\n", hi, lo); */
696
}
697
INSTRUCTION (l_macrc) {
698 116 jeremybenn
  orreg_t lo;
699 19 jeremybenn
  /* No need for synchronization here -- all MAC instructions are 1 cycle long.  */
700
  lo =  cpu_state.sprs[SPR_MACLO];
701
  //PRINTF ("<%08x>\n", (unsigned long)l);
702 116 jeremybenn
  SET_PARAM0(lo);
703 19 jeremybenn
  cpu_state.sprs[SPR_MACLO] = 0;
704
  cpu_state.sprs[SPR_MACHI] = 0;
705
}
706
INSTRUCTION (l_cmov) {
707
  SET_PARAM0(cpu_state.sprs[SPR_SR] & SPR_SR_F ? PARAM1 : PARAM2);
708
}
709
INSTRUCTION (l_ff1) {
710
  SET_PARAM0(ffs(PARAM1));
711
}
712 115 jeremybenn
INSTRUCTION (l_fl1) {
713
  orreg_t t = (orreg_t)PARAM1;
714
 
715
  /* Reverse the word and use ffs */
716
  t = (((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1));
717
  t = (((t & 0xcccccccc) >> 2) | ((t & 0x33333333) << 2));
718
  t = (((t & 0xf0f0f0f0) >> 4) | ((t & 0x0f0f0f0f) << 4));
719
  t = (((t & 0xff00ff00) >> 8) | ((t & 0x00ff00ff) << 8));
720
  t = ffs ((t >> 16) | (t << 16));
721
 
722
  SET_PARAM0 (0 == t ? t : 33 - t);
723
}
724 19 jeremybenn
/******* Floating point instructions *******/
725
/* Single precision */
726
INSTRUCTION (lf_add_s) {
727 100 julius
  if (config.cpu.hardfloat) {
728
  FLOAT param0, param1, param2;
729
  param1.hval = (uorreg_t)PARAM1;
730
  param2.hval = (uorreg_t)PARAM2;
731
  param0.fval = param1.fval + param2.fval;
732
  SET_PARAM0(param0.hval);
733
  } else l_invalid();
734 19 jeremybenn
}
735
INSTRUCTION (lf_div_s) {
736 100 julius
  if (config.cpu.hardfloat) {
737
  FLOAT param0, param1, param2;
738
  param1.hval = (uorreg_t)PARAM1;
739
  param2.hval = (uorreg_t)PARAM2;
740
  param0.fval = param1.fval / param2.fval;
741
  SET_PARAM0(param0.hval);
742
  } else l_invalid();
743 19 jeremybenn
}
744
INSTRUCTION (lf_ftoi_s) {
745 100 julius
  if (config.cpu.hardfloat) {
746
    // no other way appeared to work --jb
747
    float tmp_f; memcpy((void*)&tmp_f, (void*)&PARAM1, sizeof(float));
748
    SET_PARAM0((int)tmp_f);
749
  } else l_invalid();
750 19 jeremybenn
}
751
INSTRUCTION (lf_itof_s) {
752 100 julius
  if (config.cpu.hardfloat) {
753
  FLOAT param0;
754
  param0.fval = (float)((int)PARAM1);
755
  SET_PARAM0(param0.hval);
756
  } else l_invalid();
757 19 jeremybenn
}
758
INSTRUCTION (lf_madd_s) {
759 100 julius
  if (config.cpu.hardfloat) {
760
  FLOAT param0,param1, param2;
761 104 jeremybenn
  param0.hval = (uorreg_t)PARAM0;
762
  param1.hval = (uorreg_t)PARAM1;
763 100 julius
  param2.hval = PARAM2;
764
  param0.fval += param1.fval * param2.fval;
765
  SET_PARAM0(param0.hval);
766
  } else l_invalid();
767 19 jeremybenn
}
768
INSTRUCTION (lf_mul_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_rem_s) {
778 100 julius
  if (config.cpu.hardfloat) {
779
  FLOAT param0, param1, param2;
780
  param1.hval = PARAM1;
781
  param2.hval = PARAM2;
782 104 jeremybenn
  param0.fval = fmodf (param1.fval, param2.fval);
783 100 julius
  SET_PARAM0(param0.hval);
784
  } else l_invalid();
785 19 jeremybenn
}
786
INSTRUCTION (lf_sfeq_s) {
787 100 julius
  if (config.cpu.hardfloat) {
788
  FLOAT param0, param1;
789
  param0.hval = PARAM0;
790
  param1.hval = PARAM1;
791
  if(param0.fval == param1.fval)
792 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
793
  else
794
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
795 100 julius
  } else l_invalid();
796 19 jeremybenn
}
797
INSTRUCTION (lf_sfge_s) {
798 100 julius
  if (config.cpu.hardfloat) {
799
  FLOAT param0, param1;
800
  param0.hval = PARAM0;
801
  param1.hval = PARAM1;
802
  if(param0.fval >= param1.fval)
803 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
804
  else
805
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
806 100 julius
  } else l_invalid();
807 19 jeremybenn
}
808
INSTRUCTION (lf_sfgt_s) {
809 100 julius
  if (config.cpu.hardfloat) {
810
  FLOAT param0, param1;
811
  param0.hval = PARAM0;
812
  param1.hval = PARAM1;
813
  if(param0.fval > param1.fval)
814 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
815
  else
816
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
817 100 julius
  } else l_invalid();
818 19 jeremybenn
}
819
INSTRUCTION (lf_sfle_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_sflt_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_sfne_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_sub_s) {
853 100 julius
  if (config.cpu.hardfloat) {
854
  FLOAT param0, param1, param2;
855
  param1.hval = PARAM1;
856
  param2.hval = PARAM2;
857
  param0.fval = param1.fval - param2.fval;
858
  SET_PARAM0(param0.hval);
859
  } else l_invalid();
860 19 jeremybenn
}
861
 
862
/******* Custom instructions *******/
863
INSTRUCTION (l_cust1) {
864
  /*int destr = current->insn >> 21;
865
    int src1r = current->insn >> 15;
866
    int src2r = current->insn >> 9;*/
867
}
868
INSTRUCTION (l_cust2) {
869
}
870
INSTRUCTION (l_cust3) {
871
}
872
INSTRUCTION (l_cust4) {
873
}
874 100 julius
INSTRUCTION (lf_cust1) {
875
}

powered by: WebSVN 2.1.0

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