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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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