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

Subversion Repositories openrisc

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

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
  orreg_t temp1;
260
 
261
  temp1 = (orreg_t)PARAM1 * (orreg_t)PARAM2;
262
  SET_OV_FLAG_FN (temp1);
263
  SET_PARAM0(temp1);
264
  /*if (!(mcount++ & 1023)) {
265
    PRINTF ("[%i]\n",mcount);
266
    }*/
267
}
268
INSTRUCTION (l_div) {
269
  orreg_t temp3, temp2, temp1;
270
 
271
  temp3 = PARAM2;
272
  temp2 = PARAM1;
273
  if (temp3)
274
    temp1 = temp2 / temp3;
275
  else {
276 112 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_CY;        /* Div by zero sets carry */
277 107 jeremybenn
    except_handle (EXCEPT_RANGE, cpu_state.pc);
278 19 jeremybenn
    return;
279
  }
280
  SET_OV_FLAG_FN (temp1);
281
  SET_PARAM0(temp1);
282
}
283
INSTRUCTION (l_divu) {
284
  uorreg_t temp3, temp2, temp1;
285
 
286
  temp3 = PARAM2;
287
  temp2 = PARAM1;
288
  if (temp3)
289
    temp1 = temp2 / temp3;
290
  else {
291 112 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_CY;        /* Div by zero sets carry */
292 107 jeremybenn
    except_handle(EXCEPT_RANGE, cpu_state.pc);
293 19 jeremybenn
    return;
294
  }
295
  SET_OV_FLAG_FN (temp1);
296
  SET_PARAM0(temp1);
297
  /* runtime.sim.cycles += 16; */
298
}
299
INSTRUCTION (l_sll) {
300
  uorreg_t temp1;
301
 
302
  temp1 = PARAM1 << PARAM2;
303
  SET_OV_FLAG_FN (temp1);
304
  SET_PARAM0(temp1);
305
  /* runtime.sim.cycles += 2; */
306
}
307
INSTRUCTION (l_sra) {
308
  orreg_t temp1;
309
 
310
  temp1 = (orreg_t)PARAM1 >> PARAM2;
311
  SET_OV_FLAG_FN (temp1);
312
  SET_PARAM0(temp1);
313
  /* runtime.sim.cycles += 2; */
314
}
315
INSTRUCTION (l_srl) {
316
  uorreg_t temp1;
317
  temp1 = PARAM1 >> PARAM2;
318
  SET_OV_FLAG_FN (temp1);
319
  SET_PARAM0(temp1);
320
  /* runtime.sim.cycles += 2; */
321
}
322
INSTRUCTION (l_bf) {
323
  if (config.bpb.enabled) {
324
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
325
    or1k_mstats.bf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0][fwd]++;
326
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0);
327
  }
328
  if(cpu_state.sprs[SPR_SR] & SPR_SR_F) {
329
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
330
    btic_update(pcnext);
331
    next_delay_insn = 1;
332
  } else {
333
    btic_update(cpu_state.pc);
334
  }
335
}
336
INSTRUCTION (l_bnf) {
337
  if (config.bpb.enabled) {
338
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
339
    or1k_mstats.bnf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1][fwd]++;
340
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1);
341
  }
342
  if (!(cpu_state.sprs[SPR_SR] & SPR_SR_F)) {
343
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
344
    btic_update(pcnext);
345
    next_delay_insn = 1;
346
  } else {
347
    btic_update(cpu_state.pc);
348
  }
349
}
350
INSTRUCTION (l_j) {
351
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
352
  next_delay_insn = 1;
353
}
354
INSTRUCTION (l_jal) {
355
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
356
 
357
  setsim_reg(LINK_REGNO, cpu_state.pc + 8);
358
  next_delay_insn = 1;
359
  if (config.sim.profile) {
360
    struct label_entry *tmp;
361
    if (verify_memoryarea(cpu_state.pc_delay) && (tmp = get_label (cpu_state.pc_delay)))
362
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" %s\n",
363
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
364
               tmp->name);
365
    else
366
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" @%"PRIxADDR"\n",
367
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
368
               cpu_state.pc_delay);
369
  }
370
}
371
INSTRUCTION (l_jalr) {
372
  cpu_state.pc_delay = PARAM0;
373
  setsim_reg(LINK_REGNO, cpu_state.pc + 8);
374
  next_delay_insn = 1;
375
}
376
INSTRUCTION (l_jr) {
377
  cpu_state.pc_delay = PARAM0;
378
  next_delay_insn = 1;
379
  if (config.sim.profile)
380
    fprintf (runtime.sim.fprof, "-%08llX %"PRIxADDR"\n", runtime.sim.cycles,
381
             cpu_state.pc_delay);
382
}
383
INSTRUCTION (l_rfe) {
384
  pcnext = cpu_state.sprs[SPR_EPCR_BASE];
385
  mtspr(SPR_SR, cpu_state.sprs[SPR_ESR_BASE]);
386
}
387
INSTRUCTION (l_nop) {
388
  uint32_t k = PARAM0;
389
  switch (k) {
390
    case NOP_NOP:
391
      break;
392
    case NOP_EXIT:
393
      PRINTF("exit(%"PRIdREG")\n", evalsim_reg (3));
394
      fprintf(stderr, "@reset : cycles %lld, insn #%lld\n",
395
              runtime.sim.reset_cycles, runtime.cpu.reset_instructions);
396
      fprintf(stderr, "@exit  : cycles %lld, insn #%lld\n", runtime.sim.cycles,
397
              runtime.cpu.instructions);
398
      fprintf(stderr, " diff  : cycles %lld, insn #%lld\n",
399
              runtime.sim.cycles - runtime.sim.reset_cycles,
400
              runtime.cpu.instructions - runtime.cpu.reset_instructions);
401
      if (config.debug.gdb_enabled)
402
        set_stall_state (1);
403
      else
404
        sim_done();
405
      break;
406
    case NOP_CNT_RESET:
407
      PRINTF("****************** counters reset ******************\n");
408
      PRINTF("cycles %lld, insn #%lld\n", runtime.sim.cycles, runtime.cpu.instructions);
409
      PRINTF("****************** counters reset ******************\n");
410
      runtime.sim.reset_cycles = runtime.sim.cycles;
411
      runtime.cpu.reset_instructions = runtime.cpu.instructions;
412
      break;
413
    case NOP_PUTC:              /*JPB */
414
      printf( "%c", (char)(evalsim_reg( 3 ) & 0xff));
415
      fflush( stdout );
416
      break;
417 82 jeremybenn
    case NOP_GET_TICKS:
418
      cpu_state.reg[11] = runtime.sim.cycles & 0xffffffff;
419
      cpu_state.reg[12] = runtime.sim.cycles >> 32;
420
      break;
421
    case NOP_GET_PS:
422
      cpu_state.reg[11] = config.sim.clkcycle_ps;
423
      break;
424 19 jeremybenn
    case NOP_REPORT:
425
      PRINTF("report(0x%"PRIxREG");\n", evalsim_reg(3));
426
    default:
427
      if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
428
      PRINTF("report %" PRIdREG " (0x%"PRIxREG");\n", k - NOP_REPORT_FIRST,
429
             evalsim_reg(3));
430
      break;
431
  }
432
}
433
INSTRUCTION (l_sfeq) {
434
  if(PARAM0 == PARAM1)
435
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
436
  else
437
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
438
}
439
INSTRUCTION (l_sfne) {
440
  if(PARAM0 != PARAM1)
441
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
442
  else
443
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
444
}
445
INSTRUCTION (l_sfgts) {
446
  if((orreg_t)PARAM0 > (orreg_t)PARAM1)
447
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
448
  else
449
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
450
}
451
INSTRUCTION (l_sfges) {
452
  if((orreg_t)PARAM0 >= (orreg_t)PARAM1)
453
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
454
  else
455
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
456
}
457
INSTRUCTION (l_sflts) {
458
  if((orreg_t)PARAM0 < (orreg_t)PARAM1)
459
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
460
  else
461
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
462
}
463
INSTRUCTION (l_sfles) {
464
  if((orreg_t)PARAM0 <= (orreg_t)PARAM1)
465
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
466
  else
467
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
468
}
469
INSTRUCTION (l_sfgtu) {
470
  if(PARAM0 > PARAM1)
471
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
472
  else
473
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
474
}
475
INSTRUCTION (l_sfgeu) {
476
  if(PARAM0 >= PARAM1)
477
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
478
  else
479
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
480
}
481
INSTRUCTION (l_sfltu) {
482
  if(PARAM0 < PARAM1)
483
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
484
  else
485
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
486
}
487
INSTRUCTION (l_sfleu) {
488
  if(PARAM0 <= PARAM1)
489
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
490
  else
491
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
492
}
493
INSTRUCTION (l_extbs) {
494
  int8_t x;
495
  x = PARAM1;
496
  SET_PARAM0((orreg_t)x);
497
}
498
INSTRUCTION (l_extbz) {
499
  uint8_t x;
500
  x = PARAM1;
501
  SET_PARAM0((uorreg_t)x);
502
}
503
INSTRUCTION (l_exths) {
504
  int16_t x;
505
  x = PARAM1;
506
  SET_PARAM0((orreg_t)x);
507
}
508
INSTRUCTION (l_exthz) {
509
  uint16_t x;
510
  x = PARAM1;
511
  SET_PARAM0((uorreg_t)x);
512
}
513
INSTRUCTION (l_extws) {
514
  int32_t x;
515
  x = PARAM1;
516
  SET_PARAM0((orreg_t)x);
517
}
518
INSTRUCTION (l_extwz) {
519
  uint32_t x;
520
  x = PARAM1;
521
  SET_PARAM0((uorreg_t)x);
522
}
523
INSTRUCTION (l_mtspr) {
524
  uint16_t regno = PARAM0 + PARAM2;
525
  uorreg_t value = PARAM1;
526
 
527
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
528
    mtspr(regno, value);
529
  else {
530
    PRINTF("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
531
    sim_done();
532
  }
533
}
534
INSTRUCTION (l_mfspr) {
535
  uint16_t regno = PARAM1 + PARAM2;
536
  uorreg_t value = mfspr(regno);
537
 
538
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
539
    SET_PARAM0(value);
540
  else {
541
    SET_PARAM0(0);
542
    PRINTF("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
543
    sim_done();
544
  }
545
}
546
INSTRUCTION (l_sys) {
547
  except_handle(EXCEPT_SYSCALL, cpu_state.sprs[SPR_EEAR_BASE]);
548
}
549
INSTRUCTION (l_trap) {
550
  /* TODO: some SR related code here! */
551
  except_handle(EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
552
}
553
INSTRUCTION (l_mac) {
554
  uorreg_t lo, hi;
555
  LONGEST l;
556
  orreg_t x, y;
557
 
558
  lo = cpu_state.sprs[SPR_MACLO];
559
  hi = cpu_state.sprs[SPR_MACHI];
560
  x = PARAM0;
561
  y = PARAM1;
562
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
563
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
564
  l += (LONGEST) x * (LONGEST) y;
565
 
566
  /* This implementation is very fast - it needs only one cycle for mac.  */
567
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
568
  hi = ((LONGEST)l) >> 32;
569
  cpu_state.sprs[SPR_MACLO] = lo;
570
  cpu_state.sprs[SPR_MACHI] = hi;
571
/*   PRINTF ("(%"PRIxREG",%"PRIxREG"\n", hi, lo); */
572
}
573
INSTRUCTION (l_msb) {
574
  uorreg_t lo, hi;
575
  LONGEST l;
576
  orreg_t x, y;
577
 
578
  lo = cpu_state.sprs[SPR_MACLO];
579
  hi = cpu_state.sprs[SPR_MACHI];
580
  x = PARAM0;
581
  y = PARAM1;
582
 
583
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
584
 
585
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
586
  l -= x * y;
587
 
588
  /* This implementation is very fast - it needs only one cycle for msb.  */
589
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
590
  hi = ((LONGEST)l) >> 32;
591
  cpu_state.sprs[SPR_MACLO] = lo;
592
  cpu_state.sprs[SPR_MACHI] = hi;
593
/*   PRINTF ("(%"PRIxREG",%"PRIxREG")\n", hi, lo); */
594
}
595
INSTRUCTION (l_macrc) {
596
  uorreg_t lo, hi;
597
  LONGEST l;
598
  /* No need for synchronization here -- all MAC instructions are 1 cycle long.  */
599
  lo =  cpu_state.sprs[SPR_MACLO];
600
  hi =  cpu_state.sprs[SPR_MACHI];
601
  l = (ULONGEST) lo | ((LONGEST)hi << 32);
602
  l >>= 28;
603
  //PRINTF ("<%08x>\n", (unsigned long)l);
604
  SET_PARAM0((orreg_t)l);
605
  cpu_state.sprs[SPR_MACLO] = 0;
606
  cpu_state.sprs[SPR_MACHI] = 0;
607
}
608
INSTRUCTION (l_cmov) {
609
  SET_PARAM0(cpu_state.sprs[SPR_SR] & SPR_SR_F ? PARAM1 : PARAM2);
610
}
611
INSTRUCTION (l_ff1) {
612
  SET_PARAM0(ffs(PARAM1));
613
}
614
/******* Floating point instructions *******/
615
/* Single precision */
616
INSTRUCTION (lf_add_s) {
617 100 julius
  if (config.cpu.hardfloat) {
618
  FLOAT param0, param1, param2;
619
  param1.hval = (uorreg_t)PARAM1;
620
  param2.hval = (uorreg_t)PARAM2;
621
  param0.fval = param1.fval + param2.fval;
622
  SET_PARAM0(param0.hval);
623
  } else l_invalid();
624 19 jeremybenn
}
625
INSTRUCTION (lf_div_s) {
626 100 julius
  if (config.cpu.hardfloat) {
627
  FLOAT param0, param1, param2;
628
  param1.hval = (uorreg_t)PARAM1;
629
  param2.hval = (uorreg_t)PARAM2;
630
  param0.fval = param1.fval / param2.fval;
631
  SET_PARAM0(param0.hval);
632
  } else l_invalid();
633 19 jeremybenn
}
634
INSTRUCTION (lf_ftoi_s) {
635 100 julius
  if (config.cpu.hardfloat) {
636
    // no other way appeared to work --jb
637
    float tmp_f; memcpy((void*)&tmp_f, (void*)&PARAM1, sizeof(float));
638
    SET_PARAM0((int)tmp_f);
639
  } else l_invalid();
640 19 jeremybenn
}
641
INSTRUCTION (lf_itof_s) {
642 100 julius
  if (config.cpu.hardfloat) {
643
  FLOAT param0;
644
  param0.fval = (float)((int)PARAM1);
645
  SET_PARAM0(param0.hval);
646
  } else l_invalid();
647 19 jeremybenn
}
648
INSTRUCTION (lf_madd_s) {
649 100 julius
  if (config.cpu.hardfloat) {
650
  FLOAT param0,param1, param2;
651 104 jeremybenn
  param0.hval = (uorreg_t)PARAM0;
652
  param1.hval = (uorreg_t)PARAM1;
653 100 julius
  param2.hval = PARAM2;
654
  param0.fval += param1.fval * param2.fval;
655
  SET_PARAM0(param0.hval);
656
  } else l_invalid();
657 19 jeremybenn
}
658
INSTRUCTION (lf_mul_s) {
659 100 julius
  if (config.cpu.hardfloat) {
660
  FLOAT param0, param1, param2;
661
  param1.hval = (uorreg_t)PARAM1;
662
  param2.hval = (uorreg_t)PARAM2;
663
  param0.fval = param1.fval * param2.fval;
664
  SET_PARAM0(param0.hval);
665
  } else l_invalid();
666 19 jeremybenn
}
667
INSTRUCTION (lf_rem_s) {
668 100 julius
  if (config.cpu.hardfloat) {
669
  FLOAT param0, param1, param2;
670
  param1.hval = PARAM1;
671
  param2.hval = PARAM2;
672 104 jeremybenn
  param0.fval = fmodf (param1.fval, param2.fval);
673 100 julius
  SET_PARAM0(param0.hval);
674
  } else l_invalid();
675 19 jeremybenn
}
676
INSTRUCTION (lf_sfeq_s) {
677 100 julius
  if (config.cpu.hardfloat) {
678
  FLOAT param0, param1;
679
  param0.hval = PARAM0;
680
  param1.hval = PARAM1;
681
  if(param0.fval == param1.fval)
682 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
683
  else
684
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
685 100 julius
  } else l_invalid();
686 19 jeremybenn
}
687
INSTRUCTION (lf_sfge_s) {
688 100 julius
  if (config.cpu.hardfloat) {
689
  FLOAT param0, param1;
690
  param0.hval = PARAM0;
691
  param1.hval = PARAM1;
692
  if(param0.fval >= param1.fval)
693 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
694
  else
695
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
696 100 julius
  } else l_invalid();
697 19 jeremybenn
}
698
INSTRUCTION (lf_sfgt_s) {
699 100 julius
  if (config.cpu.hardfloat) {
700
  FLOAT param0, param1;
701
  param0.hval = PARAM0;
702
  param1.hval = PARAM1;
703
  if(param0.fval > param1.fval)
704 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
705
  else
706
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
707 100 julius
  } else l_invalid();
708 19 jeremybenn
}
709
INSTRUCTION (lf_sfle_s) {
710 100 julius
  if (config.cpu.hardfloat) {
711
  FLOAT param0, param1;
712
  param0.hval = PARAM0;
713
  param1.hval = PARAM1;
714
  if(param0.fval <= param1.fval)
715 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
716
  else
717
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
718 100 julius
  } else l_invalid();
719 19 jeremybenn
}
720
INSTRUCTION (lf_sflt_s) {
721 100 julius
  if (config.cpu.hardfloat) {
722
  FLOAT param0, param1;
723
  param0.hval = PARAM0;
724
  param1.hval = PARAM1;
725
  if(param0.fval < param1.fval)
726 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
727
  else
728
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
729 100 julius
  } else l_invalid();
730 19 jeremybenn
}
731
INSTRUCTION (lf_sfne_s) {
732 100 julius
  if (config.cpu.hardfloat) {
733
  FLOAT param0, param1;
734
  param0.hval = PARAM0;
735
  param1.hval = PARAM1;
736
  if(param0.fval != param1.fval)
737 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
738
  else
739
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
740 100 julius
  } else l_invalid();
741 19 jeremybenn
}
742
INSTRUCTION (lf_sub_s) {
743 100 julius
  if (config.cpu.hardfloat) {
744
  FLOAT param0, param1, param2;
745
  param1.hval = PARAM1;
746
  param2.hval = PARAM2;
747
  param0.fval = param1.fval - param2.fval;
748
  SET_PARAM0(param0.hval);
749
  } else l_invalid();
750 19 jeremybenn
}
751
 
752
/******* Custom instructions *******/
753
INSTRUCTION (l_cust1) {
754
  /*int destr = current->insn >> 21;
755
    int src1r = current->insn >> 15;
756
    int src2r = current->insn >> 9;*/
757
}
758
INSTRUCTION (l_cust2) {
759
}
760
INSTRUCTION (l_cust3) {
761
}
762
INSTRUCTION (l_cust4) {
763
}
764 100 julius
INSTRUCTION (lf_cust1) {
765
}

powered by: WebSVN 2.1.0

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