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

Subversion Repositories openrisc

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

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 115 jeremybenn
INSTRUCTION (l_fl1) {
615
  orreg_t t = (orreg_t)PARAM1;
616
 
617
  /* Reverse the word and use ffs */
618
  t = (((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1));
619
  t = (((t & 0xcccccccc) >> 2) | ((t & 0x33333333) << 2));
620
  t = (((t & 0xf0f0f0f0) >> 4) | ((t & 0x0f0f0f0f) << 4));
621
  t = (((t & 0xff00ff00) >> 8) | ((t & 0x00ff00ff) << 8));
622
  t = ffs ((t >> 16) | (t << 16));
623
 
624
  SET_PARAM0 (0 == t ? t : 33 - t);
625
}
626 19 jeremybenn
/******* Floating point instructions *******/
627
/* Single precision */
628
INSTRUCTION (lf_add_s) {
629 100 julius
  if (config.cpu.hardfloat) {
630
  FLOAT param0, param1, param2;
631
  param1.hval = (uorreg_t)PARAM1;
632
  param2.hval = (uorreg_t)PARAM2;
633
  param0.fval = param1.fval + param2.fval;
634
  SET_PARAM0(param0.hval);
635
  } else l_invalid();
636 19 jeremybenn
}
637
INSTRUCTION (lf_div_s) {
638 100 julius
  if (config.cpu.hardfloat) {
639
  FLOAT param0, param1, param2;
640
  param1.hval = (uorreg_t)PARAM1;
641
  param2.hval = (uorreg_t)PARAM2;
642
  param0.fval = param1.fval / param2.fval;
643
  SET_PARAM0(param0.hval);
644
  } else l_invalid();
645 19 jeremybenn
}
646
INSTRUCTION (lf_ftoi_s) {
647 100 julius
  if (config.cpu.hardfloat) {
648
    // no other way appeared to work --jb
649
    float tmp_f; memcpy((void*)&tmp_f, (void*)&PARAM1, sizeof(float));
650
    SET_PARAM0((int)tmp_f);
651
  } else l_invalid();
652 19 jeremybenn
}
653
INSTRUCTION (lf_itof_s) {
654 100 julius
  if (config.cpu.hardfloat) {
655
  FLOAT param0;
656
  param0.fval = (float)((int)PARAM1);
657
  SET_PARAM0(param0.hval);
658
  } else l_invalid();
659 19 jeremybenn
}
660
INSTRUCTION (lf_madd_s) {
661 100 julius
  if (config.cpu.hardfloat) {
662
  FLOAT param0,param1, param2;
663 104 jeremybenn
  param0.hval = (uorreg_t)PARAM0;
664
  param1.hval = (uorreg_t)PARAM1;
665 100 julius
  param2.hval = PARAM2;
666
  param0.fval += param1.fval * param2.fval;
667
  SET_PARAM0(param0.hval);
668
  } else l_invalid();
669 19 jeremybenn
}
670
INSTRUCTION (lf_mul_s) {
671 100 julius
  if (config.cpu.hardfloat) {
672
  FLOAT param0, param1, param2;
673
  param1.hval = (uorreg_t)PARAM1;
674
  param2.hval = (uorreg_t)PARAM2;
675
  param0.fval = param1.fval * param2.fval;
676
  SET_PARAM0(param0.hval);
677
  } else l_invalid();
678 19 jeremybenn
}
679
INSTRUCTION (lf_rem_s) {
680 100 julius
  if (config.cpu.hardfloat) {
681
  FLOAT param0, param1, param2;
682
  param1.hval = PARAM1;
683
  param2.hval = PARAM2;
684 104 jeremybenn
  param0.fval = fmodf (param1.fval, param2.fval);
685 100 julius
  SET_PARAM0(param0.hval);
686
  } else l_invalid();
687 19 jeremybenn
}
688
INSTRUCTION (lf_sfeq_s) {
689 100 julius
  if (config.cpu.hardfloat) {
690
  FLOAT param0, param1;
691
  param0.hval = PARAM0;
692
  param1.hval = PARAM1;
693
  if(param0.fval == param1.fval)
694 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
695
  else
696
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
697 100 julius
  } else l_invalid();
698 19 jeremybenn
}
699
INSTRUCTION (lf_sfge_s) {
700 100 julius
  if (config.cpu.hardfloat) {
701
  FLOAT param0, param1;
702
  param0.hval = PARAM0;
703
  param1.hval = PARAM1;
704
  if(param0.fval >= param1.fval)
705 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
706
  else
707
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
708 100 julius
  } else l_invalid();
709 19 jeremybenn
}
710
INSTRUCTION (lf_sfgt_s) {
711 100 julius
  if (config.cpu.hardfloat) {
712
  FLOAT param0, param1;
713
  param0.hval = PARAM0;
714
  param1.hval = PARAM1;
715
  if(param0.fval > param1.fval)
716 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
717
  else
718
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
719 100 julius
  } else l_invalid();
720 19 jeremybenn
}
721
INSTRUCTION (lf_sfle_s) {
722 100 julius
  if (config.cpu.hardfloat) {
723
  FLOAT param0, param1;
724
  param0.hval = PARAM0;
725
  param1.hval = PARAM1;
726
  if(param0.fval <= param1.fval)
727 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
728
  else
729
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
730 100 julius
  } else l_invalid();
731 19 jeremybenn
}
732
INSTRUCTION (lf_sflt_s) {
733 100 julius
  if (config.cpu.hardfloat) {
734
  FLOAT param0, param1;
735
  param0.hval = PARAM0;
736
  param1.hval = PARAM1;
737
  if(param0.fval < param1.fval)
738 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
739
  else
740
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
741 100 julius
  } else l_invalid();
742 19 jeremybenn
}
743
INSTRUCTION (lf_sfne_s) {
744 100 julius
  if (config.cpu.hardfloat) {
745
  FLOAT param0, param1;
746
  param0.hval = PARAM0;
747
  param1.hval = PARAM1;
748
  if(param0.fval != param1.fval)
749 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
750
  else
751
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
752 100 julius
  } else l_invalid();
753 19 jeremybenn
}
754
INSTRUCTION (lf_sub_s) {
755 100 julius
  if (config.cpu.hardfloat) {
756
  FLOAT param0, param1, param2;
757
  param1.hval = PARAM1;
758
  param2.hval = PARAM2;
759
  param0.fval = param1.fval - param2.fval;
760
  SET_PARAM0(param0.hval);
761
  } else l_invalid();
762 19 jeremybenn
}
763
 
764
/******* Custom instructions *******/
765
INSTRUCTION (l_cust1) {
766
  /*int destr = current->insn >> 21;
767
    int src1r = current->insn >> 15;
768
    int src2r = current->insn >> 9;*/
769
}
770
INSTRUCTION (l_cust2) {
771
}
772
INSTRUCTION (l_cust3) {
773
}
774
INSTRUCTION (l_cust4) {
775
}
776 100 julius
INSTRUCTION (lf_cust1) {
777
}

powered by: WebSVN 2.1.0

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