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

Subversion Repositories openrisc

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

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 124 jeremybenn
  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_PARAM0(temp1);
231
}
232
INSTRUCTION (l_or) {
233
  uorreg_t temp1;
234
  temp1 = PARAM1 | PARAM2;
235
  SET_PARAM0(temp1);
236
}
237
INSTRUCTION (l_xor) {
238
  uorreg_t temp1;
239
  temp1 = PARAM1 ^ PARAM2;
240
  SET_PARAM0(temp1);
241
}
242
INSTRUCTION (l_sub) {
243 124 jeremybenn
  orreg_t temp1, temp2, temp3;
244
 
245
  temp3 = (orreg_t)PARAM2;
246
  temp2 = (orreg_t)PARAM1;
247
  temp1 = temp2 - temp3;
248
  SET_PARAM0 (temp1);
249
 
250
  /* Set overflow if a negative value minus a positive value gave a positive
251
     sum, or if a positive value minus a negative value gave a negative
252
     sum. Otherwise clear it */
253
  if ((((long int) temp2 <  0) &&
254
       ((long int) temp3 >= 0) &&
255
       ((long int) temp1 >= 0)) ||
256
      (((long int) temp2 >= 0) &&
257
       ((long int) temp3 <  0) &&
258
       ((long int) temp1 <  0)))
259
    {
260
      cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
261
    }
262
  else
263
    {
264
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV;
265
    }
266
 
267
  /* Set the carry flag if (as unsigned values) the second operand is greater
268
     than the first. */
269
  if ((uorreg_t) temp3 > (uorreg_t) temp2)
270
    {
271
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
272
    }
273
  else
274
    {
275
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
276
    }
277
 
278
  /* Trigger a range exception if the overflow flag is set and the SR[OVE] bit
279
     is set. */
280
  if (((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) == SPR_SR_OVE) &&
281
      ((cpu_state.sprs[SPR_SR] & SPR_SR_OV)  == SPR_SR_OV))
282
    {
283
      except_handle (EXCEPT_RANGE, cpu_state.pc);
284
    }
285 19 jeremybenn
}
286
/*int mcount = 0;*/
287
INSTRUCTION (l_mul) {
288 118 jeremybenn
  orreg_t   temp0, temp1, temp2;
289
  LONGEST   ltemp0, ltemp1, ltemp2;
290
  ULONGEST  ultemp0, ultemp1, ultemp2;
291
 
292
  /* Args in 32-bit */
293
  temp2 = (orreg_t) PARAM2;
294
  temp1 = (orreg_t) PARAM1;
295
 
296
  /* Compute initially in 64-bit */
297
  ltemp1 = (LONGEST) temp1;
298
  ltemp2 = (LONGEST) temp2;
299
  ltemp0 = ltemp1 * ltemp2;
300
 
301
  temp0  = (orreg_t) (ltemp0  & 0xffffffffLL);
302
  SET_PARAM0 (temp0);
303
 
304
  /* We have 2's complement overflow, if the result is less than the smallest
305
     possible 32-bit negative number, or greater than the largest possible
306
     32-bit positive number. */
307
  if ((ltemp0 < (LONGEST) INT32_MIN) || (ltemp0 > (LONGEST) INT32_MAX))
308
    {
309
      cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
310
    }
311
  else
312
    {
313
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV;
314
    }
315
 
316
  /* We have 1's complement overflow, if, as an unsigned operation, the result
317
     is greater than the largest possible 32-bit unsigned number. This is
318
     probably quicker than unpicking the bits of the signed result. */
319
  ultemp1 = (ULONGEST) temp1 & 0xffffffffULL;
320
  ultemp2 = (ULONGEST) temp2 & 0xffffffffULL;
321
  ultemp0 = ultemp1 * ultemp2;
322
 
323
  if (ultemp0 > (ULONGEST) UINT32_MAX)
324
    {
325
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
326
    }
327
  else
328
    {
329
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
330
    }
331
 
332
  /* Trigger a range exception if the overflow flag is set and the SR[OVE] bit
333
     is set. */
334
  if (((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) == SPR_SR_OVE) &&
335
      ((cpu_state.sprs[SPR_SR] & SPR_SR_OV)  == SPR_SR_OV))
336
    {
337
      except_handle (EXCEPT_RANGE, cpu_state.pc);
338
    }
339 19 jeremybenn
}
340 118 jeremybenn
INSTRUCTION (l_mulu) {
341
  uorreg_t   temp0, temp1, temp2;
342
  ULONGEST  ultemp0, ultemp1, ultemp2;
343
 
344
  /* Args in 32-bit */
345
  temp2 = (uorreg_t) PARAM2;
346
  temp1 = (uorreg_t) PARAM1;
347
 
348
  /* Compute initially in 64-bit */
349
  ultemp1 = (ULONGEST) temp1 & 0xffffffffULL;
350
  ultemp2 = (ULONGEST) temp2 & 0xffffffffULL;
351
  ultemp0 = ultemp1 * ultemp2;
352
 
353
  temp0  = (uorreg_t) (ultemp0  & 0xffffffffULL);
354
  SET_PARAM0 (temp0);
355
 
356
  /* We never have 2's complement overflow */
357
  cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV;
358
 
359
  /* We have 1's complement overflow, if the result is greater than the
360
     largest possible 32-bit unsigned number. */
361
  if (ultemp0 > (ULONGEST) UINT32_MAX)
362
    {
363
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
364
    }
365
  else
366
    {
367
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
368
    }
369
}
370 19 jeremybenn
INSTRUCTION (l_div) {
371 118 jeremybenn
  orreg_t  temp3, temp2, temp1;
372 19 jeremybenn
 
373 118 jeremybenn
  temp3 = (orreg_t) PARAM2;
374
  temp2 = (orreg_t) PARAM1;
375
 
376
 /* Check for divide by zero (sets carry) */
377
  if (0 == temp3)
378
    {
379
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
380
    }
381
  else
382
    {
383
      temp1 = temp2 / temp3;
384
      SET_PARAM0(temp1);
385
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
386
    }
387
 
388
  cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV; /* Never set */
389
 
390
  /* Trigger a range exception if the overflow flag is set and the SR[OVE] bit
391
     is set. */
392
  if (((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) == SPR_SR_OVE) &&
393
      ((cpu_state.sprs[SPR_SR] & SPR_SR_CY)  == SPR_SR_CY))
394
    {
395
      except_handle (EXCEPT_RANGE, cpu_state.pc);
396
    }
397 19 jeremybenn
}
398
INSTRUCTION (l_divu) {
399
  uorreg_t temp3, temp2, temp1;
400
 
401 118 jeremybenn
  temp3 = (uorreg_t) PARAM2;
402
  temp2 = (uorreg_t) PARAM1;
403
 
404
 /* Check for divide by zero (sets carry) */
405
  if (0 == temp3)
406
    {
407
      cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
408
    }
409
  else
410
    {
411
      temp1 = temp2 / temp3;
412
      SET_PARAM0(temp1);
413
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
414
    }
415
 
416
  cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV; /* Never set */
417
 
418
  /* Trigger a range exception if the overflow flag is set and the SR[OVE] bit
419
     is set. */
420
  if (((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) == SPR_SR_OVE) &&
421
      ((cpu_state.sprs[SPR_SR] & SPR_SR_CY)  == SPR_SR_CY))
422
    {
423
      except_handle (EXCEPT_RANGE, cpu_state.pc);
424
    }
425 19 jeremybenn
}
426
INSTRUCTION (l_sll) {
427
  uorreg_t temp1;
428
 
429
  temp1 = PARAM1 << PARAM2;
430
  SET_PARAM0(temp1);
431
  /* runtime.sim.cycles += 2; */
432
}
433
INSTRUCTION (l_sra) {
434
  orreg_t temp1;
435
 
436
  temp1 = (orreg_t)PARAM1 >> PARAM2;
437
  SET_PARAM0(temp1);
438
  /* runtime.sim.cycles += 2; */
439
}
440
INSTRUCTION (l_srl) {
441
  uorreg_t temp1;
442
  temp1 = PARAM1 >> PARAM2;
443
  SET_PARAM0(temp1);
444
  /* runtime.sim.cycles += 2; */
445
}
446 122 jeremybenn
INSTRUCTION (l_ror) {
447
  uorreg_t temp1;
448
  temp1  = PARAM1 >> (PARAM2 & 0x1f);
449
  temp1 |= PARAM1 << (32 - (PARAM2 & 0x1f));
450
  SET_PARAM0(temp1);
451
}
452 19 jeremybenn
INSTRUCTION (l_bf) {
453
  if (config.bpb.enabled) {
454
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
455
    or1k_mstats.bf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0][fwd]++;
456
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0);
457
  }
458
  if(cpu_state.sprs[SPR_SR] & SPR_SR_F) {
459
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
460
    btic_update(pcnext);
461
    next_delay_insn = 1;
462
  } else {
463
    btic_update(cpu_state.pc);
464
  }
465
}
466
INSTRUCTION (l_bnf) {
467
  if (config.bpb.enabled) {
468
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
469
    or1k_mstats.bnf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1][fwd]++;
470
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1);
471
  }
472
  if (!(cpu_state.sprs[SPR_SR] & SPR_SR_F)) {
473
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
474
    btic_update(pcnext);
475
    next_delay_insn = 1;
476
  } else {
477
    btic_update(cpu_state.pc);
478
  }
479
}
480
INSTRUCTION (l_j) {
481
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
482
  next_delay_insn = 1;
483
}
484
INSTRUCTION (l_jal) {
485
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
486
 
487
  setsim_reg(LINK_REGNO, cpu_state.pc + 8);
488
  next_delay_insn = 1;
489
  if (config.sim.profile) {
490
    struct label_entry *tmp;
491
    if (verify_memoryarea(cpu_state.pc_delay) && (tmp = get_label (cpu_state.pc_delay)))
492
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" %s\n",
493
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
494
               tmp->name);
495
    else
496
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" @%"PRIxADDR"\n",
497
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
498
               cpu_state.pc_delay);
499
  }
500
}
501
INSTRUCTION (l_jalr) {
502 121 jeremybenn
  /* Badly aligned destination or use of link register triggers an exception */
503
  uorreg_t  temp1 = PARAM0;
504
 
505
  if (REG_PARAM0 == LINK_REGNO)
506
    {
507
      except_handle (EXCEPT_ILLEGAL, cpu_state.pc);
508
    }
509
  else if ((temp1 & 0x3) != 0)
510
    {
511
      except_handle (EXCEPT_ALIGN, cpu_state.pc);
512
    }
513
  else
514
    {
515
      cpu_state.pc_delay = temp1;
516
      setsim_reg(LINK_REGNO, cpu_state.pc + 8);
517
      next_delay_insn = 1;
518
    }
519 19 jeremybenn
}
520
INSTRUCTION (l_jr) {
521 121 jeremybenn
  /* Badly aligned destination triggers an exception */
522
  uorreg_t  temp1 = PARAM0;
523
 
524
  if ((temp1 & 0x3) != 0)
525
    {
526
      except_handle (EXCEPT_ALIGN, cpu_state.pc);
527
    }
528
  else
529
    {
530
      cpu_state.pc_delay = temp1;
531
      next_delay_insn = 1;
532
 
533
      if (config.sim.profile)
534
        {
535
          fprintf (runtime.sim.fprof, "-%08llX %"PRIxADDR"\n",
536
                   runtime.sim.cycles, cpu_state.pc_delay);
537
        }
538
    }
539 19 jeremybenn
}
540
INSTRUCTION (l_rfe) {
541
  pcnext = cpu_state.sprs[SPR_EPCR_BASE];
542
  mtspr(SPR_SR, cpu_state.sprs[SPR_ESR_BASE]);
543
}
544
INSTRUCTION (l_nop) {
545
  uint32_t k = PARAM0;
546
  switch (k) {
547
    case NOP_NOP:
548
      break;
549
    case NOP_EXIT:
550
      PRINTF("exit(%"PRIdREG")\n", evalsim_reg (3));
551
      fprintf(stderr, "@reset : cycles %lld, insn #%lld\n",
552
              runtime.sim.reset_cycles, runtime.cpu.reset_instructions);
553
      fprintf(stderr, "@exit  : cycles %lld, insn #%lld\n", runtime.sim.cycles,
554
              runtime.cpu.instructions);
555
      fprintf(stderr, " diff  : cycles %lld, insn #%lld\n",
556
              runtime.sim.cycles - runtime.sim.reset_cycles,
557
              runtime.cpu.instructions - runtime.cpu.reset_instructions);
558
      if (config.debug.gdb_enabled)
559
        set_stall_state (1);
560
      else
561
        sim_done();
562
      break;
563
    case NOP_CNT_RESET:
564
      PRINTF("****************** counters reset ******************\n");
565
      PRINTF("cycles %lld, insn #%lld\n", runtime.sim.cycles, runtime.cpu.instructions);
566
      PRINTF("****************** counters reset ******************\n");
567
      runtime.sim.reset_cycles = runtime.sim.cycles;
568
      runtime.cpu.reset_instructions = runtime.cpu.instructions;
569
      break;
570
    case NOP_PUTC:              /*JPB */
571
      printf( "%c", (char)(evalsim_reg( 3 ) & 0xff));
572
      fflush( stdout );
573
      break;
574 82 jeremybenn
    case NOP_GET_TICKS:
575
      cpu_state.reg[11] = runtime.sim.cycles & 0xffffffff;
576
      cpu_state.reg[12] = runtime.sim.cycles >> 32;
577
      break;
578
    case NOP_GET_PS:
579
      cpu_state.reg[11] = config.sim.clkcycle_ps;
580
      break;
581 19 jeremybenn
    case NOP_REPORT:
582
      PRINTF("report(0x%"PRIxREG");\n", evalsim_reg(3));
583
    default:
584
      if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
585
      PRINTF("report %" PRIdREG " (0x%"PRIxREG");\n", k - NOP_REPORT_FIRST,
586
             evalsim_reg(3));
587
      break;
588
  }
589
}
590
INSTRUCTION (l_sfeq) {
591
  if(PARAM0 == PARAM1)
592
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
593
  else
594
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
595
}
596
INSTRUCTION (l_sfne) {
597
  if(PARAM0 != PARAM1)
598
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
599
  else
600
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
601
}
602
INSTRUCTION (l_sfgts) {
603
  if((orreg_t)PARAM0 > (orreg_t)PARAM1)
604
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
605
  else
606
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
607
}
608
INSTRUCTION (l_sfges) {
609
  if((orreg_t)PARAM0 >= (orreg_t)PARAM1)
610
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
611
  else
612
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
613
}
614
INSTRUCTION (l_sflts) {
615
  if((orreg_t)PARAM0 < (orreg_t)PARAM1)
616
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
617
  else
618
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
619
}
620
INSTRUCTION (l_sfles) {
621
  if((orreg_t)PARAM0 <= (orreg_t)PARAM1)
622
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
623
  else
624
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
625
}
626
INSTRUCTION (l_sfgtu) {
627
  if(PARAM0 > PARAM1)
628
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
629
  else
630
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
631
}
632
INSTRUCTION (l_sfgeu) {
633
  if(PARAM0 >= PARAM1)
634
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
635
  else
636
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
637
}
638
INSTRUCTION (l_sfltu) {
639
  if(PARAM0 < PARAM1)
640
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
641
  else
642
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
643
}
644
INSTRUCTION (l_sfleu) {
645
  if(PARAM0 <= PARAM1)
646
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
647
  else
648
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
649
}
650
INSTRUCTION (l_extbs) {
651
  int8_t x;
652
  x = PARAM1;
653
  SET_PARAM0((orreg_t)x);
654
}
655
INSTRUCTION (l_extbz) {
656
  uint8_t x;
657
  x = PARAM1;
658
  SET_PARAM0((uorreg_t)x);
659
}
660
INSTRUCTION (l_exths) {
661
  int16_t x;
662
  x = PARAM1;
663
  SET_PARAM0((orreg_t)x);
664
}
665
INSTRUCTION (l_exthz) {
666
  uint16_t x;
667
  x = PARAM1;
668
  SET_PARAM0((uorreg_t)x);
669
}
670
INSTRUCTION (l_extws) {
671
  int32_t x;
672
  x = PARAM1;
673
  SET_PARAM0((orreg_t)x);
674
}
675
INSTRUCTION (l_extwz) {
676
  uint32_t x;
677
  x = PARAM1;
678
  SET_PARAM0((uorreg_t)x);
679
}
680
INSTRUCTION (l_mtspr) {
681 123 jeremybenn
  uint16_t regno = PARAM0 | PARAM2;
682 19 jeremybenn
  uorreg_t value = PARAM1;
683
 
684
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
685
    mtspr(regno, value);
686
  else {
687
    PRINTF("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
688
    sim_done();
689
  }
690
}
691
INSTRUCTION (l_mfspr) {
692 123 jeremybenn
  uint16_t regno = PARAM1 | PARAM2;
693 19 jeremybenn
  uorreg_t value = mfspr(regno);
694
 
695
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
696
    SET_PARAM0(value);
697
  else {
698
    SET_PARAM0(0);
699
    PRINTF("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
700
    sim_done();
701
  }
702
}
703
INSTRUCTION (l_sys) {
704
  except_handle(EXCEPT_SYSCALL, cpu_state.sprs[SPR_EEAR_BASE]);
705
}
706
INSTRUCTION (l_trap) {
707
  /* TODO: some SR related code here! */
708
  except_handle(EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
709
}
710
INSTRUCTION (l_mac) {
711
  uorreg_t lo, hi;
712
  LONGEST l;
713 116 jeremybenn
  orreg_t x, y, t;
714 19 jeremybenn
 
715
  lo = cpu_state.sprs[SPR_MACLO];
716
  hi = cpu_state.sprs[SPR_MACHI];
717
  x = PARAM0;
718
  y = PARAM1;
719
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
720 116 jeremybenn
 
721
  /* Compute the temporary as (signed) 32-bits, then sign-extend to 64 when
722
     adding in. */
723 19 jeremybenn
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
724 116 jeremybenn
  t = x * y;
725
  l += (LONGEST) t;
726 19 jeremybenn
 
727
  /* This implementation is very fast - it needs only one cycle for mac.  */
728
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
729
  hi = ((LONGEST)l) >> 32;
730
  cpu_state.sprs[SPR_MACLO] = lo;
731
  cpu_state.sprs[SPR_MACHI] = hi;
732
/*   PRINTF ("(%"PRIxREG",%"PRIxREG"\n", hi, lo); */
733
}
734
INSTRUCTION (l_msb) {
735
  uorreg_t lo, hi;
736
  LONGEST l;
737
  orreg_t x, y;
738
 
739
  lo = cpu_state.sprs[SPR_MACLO];
740
  hi = cpu_state.sprs[SPR_MACHI];
741
  x = PARAM0;
742
  y = PARAM1;
743
 
744
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
745
 
746
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
747
  l -= x * y;
748
 
749
  /* This implementation is very fast - it needs only one cycle for msb.  */
750
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
751
  hi = ((LONGEST)l) >> 32;
752
  cpu_state.sprs[SPR_MACLO] = lo;
753
  cpu_state.sprs[SPR_MACHI] = hi;
754
/*   PRINTF ("(%"PRIxREG",%"PRIxREG")\n", hi, lo); */
755
}
756
INSTRUCTION (l_macrc) {
757 116 jeremybenn
  orreg_t lo;
758 19 jeremybenn
  /* No need for synchronization here -- all MAC instructions are 1 cycle long.  */
759
  lo =  cpu_state.sprs[SPR_MACLO];
760
  //PRINTF ("<%08x>\n", (unsigned long)l);
761 116 jeremybenn
  SET_PARAM0(lo);
762 19 jeremybenn
  cpu_state.sprs[SPR_MACLO] = 0;
763
  cpu_state.sprs[SPR_MACHI] = 0;
764
}
765
INSTRUCTION (l_cmov) {
766
  SET_PARAM0(cpu_state.sprs[SPR_SR] & SPR_SR_F ? PARAM1 : PARAM2);
767
}
768
INSTRUCTION (l_ff1) {
769
  SET_PARAM0(ffs(PARAM1));
770
}
771 115 jeremybenn
INSTRUCTION (l_fl1) {
772
  orreg_t t = (orreg_t)PARAM1;
773
 
774
  /* Reverse the word and use ffs */
775
  t = (((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1));
776
  t = (((t & 0xcccccccc) >> 2) | ((t & 0x33333333) << 2));
777
  t = (((t & 0xf0f0f0f0) >> 4) | ((t & 0x0f0f0f0f) << 4));
778
  t = (((t & 0xff00ff00) >> 8) | ((t & 0x00ff00ff) << 8));
779
  t = ffs ((t >> 16) | (t << 16));
780
 
781
  SET_PARAM0 (0 == t ? t : 33 - t);
782
}
783 19 jeremybenn
/******* Floating point instructions *******/
784
/* Single precision */
785
INSTRUCTION (lf_add_s) {
786 100 julius
  if (config.cpu.hardfloat) {
787
  FLOAT param0, param1, param2;
788
  param1.hval = (uorreg_t)PARAM1;
789
  param2.hval = (uorreg_t)PARAM2;
790
  param0.fval = param1.fval + param2.fval;
791
  SET_PARAM0(param0.hval);
792
  } else l_invalid();
793 19 jeremybenn
}
794
INSTRUCTION (lf_div_s) {
795 100 julius
  if (config.cpu.hardfloat) {
796
  FLOAT param0, param1, param2;
797
  param1.hval = (uorreg_t)PARAM1;
798
  param2.hval = (uorreg_t)PARAM2;
799
  param0.fval = param1.fval / param2.fval;
800
  SET_PARAM0(param0.hval);
801
  } else l_invalid();
802 19 jeremybenn
}
803
INSTRUCTION (lf_ftoi_s) {
804 100 julius
  if (config.cpu.hardfloat) {
805
    // no other way appeared to work --jb
806
    float tmp_f; memcpy((void*)&tmp_f, (void*)&PARAM1, sizeof(float));
807
    SET_PARAM0((int)tmp_f);
808
  } else l_invalid();
809 19 jeremybenn
}
810
INSTRUCTION (lf_itof_s) {
811 100 julius
  if (config.cpu.hardfloat) {
812
  FLOAT param0;
813
  param0.fval = (float)((int)PARAM1);
814
  SET_PARAM0(param0.hval);
815
  } else l_invalid();
816 19 jeremybenn
}
817
INSTRUCTION (lf_madd_s) {
818 100 julius
  if (config.cpu.hardfloat) {
819
  FLOAT param0,param1, param2;
820 104 jeremybenn
  param0.hval = (uorreg_t)PARAM0;
821
  param1.hval = (uorreg_t)PARAM1;
822 100 julius
  param2.hval = PARAM2;
823
  param0.fval += param1.fval * param2.fval;
824
  SET_PARAM0(param0.hval);
825
  } else l_invalid();
826 19 jeremybenn
}
827
INSTRUCTION (lf_mul_s) {
828 100 julius
  if (config.cpu.hardfloat) {
829
  FLOAT param0, param1, param2;
830
  param1.hval = (uorreg_t)PARAM1;
831
  param2.hval = (uorreg_t)PARAM2;
832
  param0.fval = param1.fval * param2.fval;
833
  SET_PARAM0(param0.hval);
834
  } else l_invalid();
835 19 jeremybenn
}
836
INSTRUCTION (lf_rem_s) {
837 100 julius
  if (config.cpu.hardfloat) {
838
  FLOAT param0, param1, param2;
839
  param1.hval = PARAM1;
840
  param2.hval = PARAM2;
841 104 jeremybenn
  param0.fval = fmodf (param1.fval, param2.fval);
842 100 julius
  SET_PARAM0(param0.hval);
843
  } else l_invalid();
844 19 jeremybenn
}
845
INSTRUCTION (lf_sfeq_s) {
846 100 julius
  if (config.cpu.hardfloat) {
847
  FLOAT param0, param1;
848
  param0.hval = PARAM0;
849
  param1.hval = PARAM1;
850
  if(param0.fval == param1.fval)
851 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
852
  else
853
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
854 100 julius
  } else l_invalid();
855 19 jeremybenn
}
856
INSTRUCTION (lf_sfge_s) {
857 100 julius
  if (config.cpu.hardfloat) {
858
  FLOAT param0, param1;
859
  param0.hval = PARAM0;
860
  param1.hval = PARAM1;
861
  if(param0.fval >= param1.fval)
862 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
863
  else
864
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
865 100 julius
  } else l_invalid();
866 19 jeremybenn
}
867
INSTRUCTION (lf_sfgt_s) {
868 100 julius
  if (config.cpu.hardfloat) {
869
  FLOAT param0, param1;
870
  param0.hval = PARAM0;
871
  param1.hval = PARAM1;
872
  if(param0.fval > param1.fval)
873 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
874
  else
875
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
876 100 julius
  } else l_invalid();
877 19 jeremybenn
}
878
INSTRUCTION (lf_sfle_s) {
879 100 julius
  if (config.cpu.hardfloat) {
880
  FLOAT param0, param1;
881
  param0.hval = PARAM0;
882
  param1.hval = PARAM1;
883
  if(param0.fval <= param1.fval)
884 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
885
  else
886
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
887 100 julius
  } else l_invalid();
888 19 jeremybenn
}
889
INSTRUCTION (lf_sflt_s) {
890 100 julius
  if (config.cpu.hardfloat) {
891
  FLOAT param0, param1;
892
  param0.hval = PARAM0;
893
  param1.hval = PARAM1;
894
  if(param0.fval < param1.fval)
895 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
896
  else
897
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
898 100 julius
  } else l_invalid();
899 19 jeremybenn
}
900
INSTRUCTION (lf_sfne_s) {
901 100 julius
  if (config.cpu.hardfloat) {
902
  FLOAT param0, param1;
903
  param0.hval = PARAM0;
904
  param1.hval = PARAM1;
905
  if(param0.fval != param1.fval)
906 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
907
  else
908
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
909 100 julius
  } else l_invalid();
910 19 jeremybenn
}
911
INSTRUCTION (lf_sub_s) {
912 100 julius
  if (config.cpu.hardfloat) {
913
  FLOAT param0, param1, param2;
914
  param1.hval = PARAM1;
915
  param2.hval = PARAM2;
916
  param0.fval = param1.fval - param2.fval;
917
  SET_PARAM0(param0.hval);
918
  } else l_invalid();
919 19 jeremybenn
}
920
 
921
/******* Custom instructions *******/
922
INSTRUCTION (l_cust1) {
923
  /*int destr = current->insn >> 21;
924
    int src1r = current->insn >> 15;
925
    int src2r = current->insn >> 9;*/
926
}
927
INSTRUCTION (l_cust2) {
928
}
929
INSTRUCTION (l_cust3) {
930
}
931
INSTRUCTION (l_cust4) {
932
}
933 100 julius
INSTRUCTION (lf_cust1) {
934
}

powered by: WebSVN 2.1.0

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