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

Subversion Repositories openrisc

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

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
 
83
  temp2 = (orreg_t)PARAM2;
84
  temp3 = (orreg_t)PARAM1;
85
  temp1 = temp2 + temp3;
86
  if(cpu_state.sprs[SPR_SR] & SPR_SR_CY)
87
    temp1++;
88
  SET_PARAM0(temp1);
89
  SET_OV_FLAG_FN (temp1);
90
  if (ARITH_SET_FLAG) {
91
    if(!temp1)
92
      cpu_state.sprs[SPR_SR] |= SPR_SR_F;
93
    else
94
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
95
  }
96
  if ((uorreg_t) temp1 < (uorreg_t) temp2)
97
    cpu_state.sprs[SPR_SR] |= SPR_SR_CY;
98
  else
99
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_CY;
100
 
101
  temp4 = temp1;
102
  if (temp4 == temp1)
103
    or1k_mstats.byteadd++;
104
}
105
INSTRUCTION (l_sw) {
106
  int old_cyc = 0;
107
  if (config.cpu.sbuf_len) old_cyc = runtime.sim.mem_cycles;
108
  set_mem32(PARAM0, PARAM1, &breakpoint);
109
  if (config.cpu.sbuf_len) {
110
    int t = runtime.sim.mem_cycles;
111
    runtime.sim.mem_cycles = old_cyc;
112
    sbuf_store (t - old_cyc);
113
  }
114
}
115
INSTRUCTION (l_sb) {
116
  int old_cyc = 0;
117
  if (config.cpu.sbuf_len) old_cyc = runtime.sim.mem_cycles;
118
  set_mem8(PARAM0, PARAM1, &breakpoint);
119
  if (config.cpu.sbuf_len) {
120
    int t = runtime.sim.mem_cycles;
121
    runtime.sim.mem_cycles = old_cyc;
122
    sbuf_store (t- old_cyc);
123
  }
124
}
125
INSTRUCTION (l_sh) {
126
  int old_cyc = 0;
127
  if (config.cpu.sbuf_len) old_cyc = runtime.sim.mem_cycles;
128
  set_mem16(PARAM0, PARAM1, &breakpoint);
129
  if (config.cpu.sbuf_len) {
130
    int t = runtime.sim.mem_cycles;
131
    runtime.sim.mem_cycles = old_cyc;
132
    sbuf_store (t - old_cyc);
133
  }
134
}
135 104 jeremybenn
INSTRUCTION (l_lws) {
136
  uint32_t val;
137
  if (config.cpu.sbuf_len) sbuf_load ();
138
  val = eval_mem32(PARAM1, &breakpoint);
139
  /* If eval operand produced exception don't set anything. JPB changed to
140
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
141
  if (!(except_pending || breakpoint))
142
    SET_PARAM0(val);
143
}
144 19 jeremybenn
INSTRUCTION (l_lwz) {
145
  uint32_t val;
146
  if (config.cpu.sbuf_len) sbuf_load ();
147
  val = eval_mem32(PARAM1, &breakpoint);
148
  /* If eval operand produced exception don't set anything. JPB changed to
149
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
150
  if (!(except_pending || breakpoint))
151
    SET_PARAM0(val);
152
}
153
INSTRUCTION (l_lbs) {
154
  int8_t val;
155
  if (config.cpu.sbuf_len) sbuf_load ();
156
  val = eval_mem8(PARAM1, &breakpoint);
157
  /* If eval operand produced exception don't set anything. JPB changed to
158
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
159
  if (!(except_pending || breakpoint))
160
    SET_PARAM0(val);
161
}
162
INSTRUCTION (l_lbz) {
163
  uint8_t val;
164
  if (config.cpu.sbuf_len) sbuf_load ();
165
  val = eval_mem8(PARAM1, &breakpoint);
166
  /* If eval operand produced exception don't set anything. JPB changed to
167
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
168
  if (!(except_pending || breakpoint))
169
    SET_PARAM0(val);
170
}
171
INSTRUCTION (l_lhs) {
172
  int16_t val;
173
  if (config.cpu.sbuf_len) sbuf_load ();
174
  val = eval_mem16(PARAM1, &breakpoint);
175
  /* If eval operand produced exception don't set anything. JPB changed to
176
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
177
  if (!(except_pending || breakpoint))
178
    SET_PARAM0(val);
179
}
180
INSTRUCTION (l_lhz) {
181
  uint16_t val;
182
  if (config.cpu.sbuf_len) sbuf_load ();
183
  val = eval_mem16(PARAM1, &breakpoint);
184
  /* If eval operand produced exception don't set anything. JPB changed to
185
     trigger on breakpoint, as well as except_pending (seemed to be a bug). */
186
  if (!(except_pending || breakpoint))
187
    SET_PARAM0(val);
188
}
189
INSTRUCTION (l_movhi) {
190
  SET_PARAM0(PARAM1 << 16);
191
}
192
INSTRUCTION (l_and) {
193
  uorreg_t temp1;
194
  temp1 = PARAM1 & PARAM2;
195
  SET_OV_FLAG_FN (temp1);
196
  SET_PARAM0(temp1);
197
  if (ARITH_SET_FLAG) {
198
    if(!temp1)
199
      cpu_state.sprs[SPR_SR] |= SPR_SR_F;
200
    else
201
      cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
202
  }
203
}
204
INSTRUCTION (l_or) {
205
  uorreg_t temp1;
206
  temp1 = PARAM1 | PARAM2;
207
  SET_OV_FLAG_FN (temp1);
208
  SET_PARAM0(temp1);
209
}
210
INSTRUCTION (l_xor) {
211
  uorreg_t temp1;
212
  temp1 = PARAM1 ^ PARAM2;
213
  SET_OV_FLAG_FN (temp1);
214
  SET_PARAM0(temp1);
215
}
216
INSTRUCTION (l_sub) {
217
  orreg_t temp1;
218
  temp1 = (orreg_t)PARAM1 - (orreg_t)PARAM2;
219
  SET_OV_FLAG_FN (temp1);
220
  SET_PARAM0(temp1);
221
}
222
/*int mcount = 0;*/
223
INSTRUCTION (l_mul) {
224
  orreg_t temp1;
225
 
226
  temp1 = (orreg_t)PARAM1 * (orreg_t)PARAM2;
227
  SET_OV_FLAG_FN (temp1);
228
  SET_PARAM0(temp1);
229
  /*if (!(mcount++ & 1023)) {
230
    PRINTF ("[%i]\n",mcount);
231
    }*/
232
}
233
INSTRUCTION (l_div) {
234
  orreg_t temp3, temp2, temp1;
235
 
236
  temp3 = PARAM2;
237
  temp2 = PARAM1;
238
  if (temp3)
239
    temp1 = temp2 / temp3;
240
  else {
241 112 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_CY;        /* Div by zero sets carry */
242 107 jeremybenn
    except_handle (EXCEPT_RANGE, cpu_state.pc);
243 19 jeremybenn
    return;
244
  }
245
  SET_OV_FLAG_FN (temp1);
246
  SET_PARAM0(temp1);
247
}
248
INSTRUCTION (l_divu) {
249
  uorreg_t temp3, temp2, temp1;
250
 
251
  temp3 = PARAM2;
252
  temp2 = PARAM1;
253
  if (temp3)
254
    temp1 = temp2 / temp3;
255
  else {
256 112 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_CY;        /* Div by zero sets carry */
257 107 jeremybenn
    except_handle(EXCEPT_RANGE, cpu_state.pc);
258 19 jeremybenn
    return;
259
  }
260
  SET_OV_FLAG_FN (temp1);
261
  SET_PARAM0(temp1);
262
  /* runtime.sim.cycles += 16; */
263
}
264
INSTRUCTION (l_sll) {
265
  uorreg_t temp1;
266
 
267
  temp1 = PARAM1 << PARAM2;
268
  SET_OV_FLAG_FN (temp1);
269
  SET_PARAM0(temp1);
270
  /* runtime.sim.cycles += 2; */
271
}
272
INSTRUCTION (l_sra) {
273
  orreg_t temp1;
274
 
275
  temp1 = (orreg_t)PARAM1 >> PARAM2;
276
  SET_OV_FLAG_FN (temp1);
277
  SET_PARAM0(temp1);
278
  /* runtime.sim.cycles += 2; */
279
}
280
INSTRUCTION (l_srl) {
281
  uorreg_t temp1;
282
  temp1 = PARAM1 >> PARAM2;
283
  SET_OV_FLAG_FN (temp1);
284
  SET_PARAM0(temp1);
285
  /* runtime.sim.cycles += 2; */
286
}
287
INSTRUCTION (l_bf) {
288
  if (config.bpb.enabled) {
289
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
290
    or1k_mstats.bf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0][fwd]++;
291
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0);
292
  }
293
  if(cpu_state.sprs[SPR_SR] & SPR_SR_F) {
294
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
295
    btic_update(pcnext);
296
    next_delay_insn = 1;
297
  } else {
298
    btic_update(cpu_state.pc);
299
  }
300
}
301
INSTRUCTION (l_bnf) {
302
  if (config.bpb.enabled) {
303
    int fwd = (PARAM0 >= cpu_state.pc) ? 1 : 0;
304
    or1k_mstats.bnf[cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1][fwd]++;
305
    bpb_update(current->insn_addr, cpu_state.sprs[SPR_SR] & SPR_SR_F ? 0 : 1);
306
  }
307
  if (!(cpu_state.sprs[SPR_SR] & SPR_SR_F)) {
308
    cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
309
    btic_update(pcnext);
310
    next_delay_insn = 1;
311
  } else {
312
    btic_update(cpu_state.pc);
313
  }
314
}
315
INSTRUCTION (l_j) {
316
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
317
  next_delay_insn = 1;
318
}
319
INSTRUCTION (l_jal) {
320
  cpu_state.pc_delay = cpu_state.pc + (orreg_t)PARAM0 * 4;
321
 
322
  setsim_reg(LINK_REGNO, cpu_state.pc + 8);
323
  next_delay_insn = 1;
324
  if (config.sim.profile) {
325
    struct label_entry *tmp;
326
    if (verify_memoryarea(cpu_state.pc_delay) && (tmp = get_label (cpu_state.pc_delay)))
327
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" %s\n",
328
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
329
               tmp->name);
330
    else
331
      fprintf (runtime.sim.fprof, "+%08llX %"PRIxADDR" %"PRIxADDR" @%"PRIxADDR"\n",
332
               runtime.sim.cycles, cpu_state.pc + 8, cpu_state.pc_delay,
333
               cpu_state.pc_delay);
334
  }
335
}
336
INSTRUCTION (l_jalr) {
337
  cpu_state.pc_delay = PARAM0;
338
  setsim_reg(LINK_REGNO, cpu_state.pc + 8);
339
  next_delay_insn = 1;
340
}
341
INSTRUCTION (l_jr) {
342
  cpu_state.pc_delay = PARAM0;
343
  next_delay_insn = 1;
344
  if (config.sim.profile)
345
    fprintf (runtime.sim.fprof, "-%08llX %"PRIxADDR"\n", runtime.sim.cycles,
346
             cpu_state.pc_delay);
347
}
348
INSTRUCTION (l_rfe) {
349
  pcnext = cpu_state.sprs[SPR_EPCR_BASE];
350
  mtspr(SPR_SR, cpu_state.sprs[SPR_ESR_BASE]);
351
}
352
INSTRUCTION (l_nop) {
353
  uint32_t k = PARAM0;
354
  switch (k) {
355
    case NOP_NOP:
356
      break;
357
    case NOP_EXIT:
358
      PRINTF("exit(%"PRIdREG")\n", evalsim_reg (3));
359
      fprintf(stderr, "@reset : cycles %lld, insn #%lld\n",
360
              runtime.sim.reset_cycles, runtime.cpu.reset_instructions);
361
      fprintf(stderr, "@exit  : cycles %lld, insn #%lld\n", runtime.sim.cycles,
362
              runtime.cpu.instructions);
363
      fprintf(stderr, " diff  : cycles %lld, insn #%lld\n",
364
              runtime.sim.cycles - runtime.sim.reset_cycles,
365
              runtime.cpu.instructions - runtime.cpu.reset_instructions);
366
      if (config.debug.gdb_enabled)
367
        set_stall_state (1);
368
      else
369
        sim_done();
370
      break;
371
    case NOP_CNT_RESET:
372
      PRINTF("****************** counters reset ******************\n");
373
      PRINTF("cycles %lld, insn #%lld\n", runtime.sim.cycles, runtime.cpu.instructions);
374
      PRINTF("****************** counters reset ******************\n");
375
      runtime.sim.reset_cycles = runtime.sim.cycles;
376
      runtime.cpu.reset_instructions = runtime.cpu.instructions;
377
      break;
378
    case NOP_PUTC:              /*JPB */
379
      printf( "%c", (char)(evalsim_reg( 3 ) & 0xff));
380
      fflush( stdout );
381
      break;
382 82 jeremybenn
    case NOP_GET_TICKS:
383
      cpu_state.reg[11] = runtime.sim.cycles & 0xffffffff;
384
      cpu_state.reg[12] = runtime.sim.cycles >> 32;
385
      break;
386
    case NOP_GET_PS:
387
      cpu_state.reg[11] = config.sim.clkcycle_ps;
388
      break;
389 19 jeremybenn
    case NOP_REPORT:
390
      PRINTF("report(0x%"PRIxREG");\n", evalsim_reg(3));
391
    default:
392
      if (k >= NOP_REPORT_FIRST && k <= NOP_REPORT_LAST)
393
      PRINTF("report %" PRIdREG " (0x%"PRIxREG");\n", k - NOP_REPORT_FIRST,
394
             evalsim_reg(3));
395
      break;
396
  }
397
}
398
INSTRUCTION (l_sfeq) {
399
  if(PARAM0 == PARAM1)
400
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
401
  else
402
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
403
}
404
INSTRUCTION (l_sfne) {
405
  if(PARAM0 != PARAM1)
406
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
407
  else
408
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
409
}
410
INSTRUCTION (l_sfgts) {
411
  if((orreg_t)PARAM0 > (orreg_t)PARAM1)
412
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
413
  else
414
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
415
}
416
INSTRUCTION (l_sfges) {
417
  if((orreg_t)PARAM0 >= (orreg_t)PARAM1)
418
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
419
  else
420
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
421
}
422
INSTRUCTION (l_sflts) {
423
  if((orreg_t)PARAM0 < (orreg_t)PARAM1)
424
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
425
  else
426
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
427
}
428
INSTRUCTION (l_sfles) {
429
  if((orreg_t)PARAM0 <= (orreg_t)PARAM1)
430
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
431
  else
432
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
433
}
434
INSTRUCTION (l_sfgtu) {
435
  if(PARAM0 > PARAM1)
436
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
437
  else
438
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
439
}
440
INSTRUCTION (l_sfgeu) {
441
  if(PARAM0 >= PARAM1)
442
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
443
  else
444
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
445
}
446
INSTRUCTION (l_sfltu) {
447
  if(PARAM0 < PARAM1)
448
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
449
  else
450
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
451
}
452
INSTRUCTION (l_sfleu) {
453
  if(PARAM0 <= PARAM1)
454
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
455
  else
456
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
457
}
458
INSTRUCTION (l_extbs) {
459
  int8_t x;
460
  x = PARAM1;
461
  SET_PARAM0((orreg_t)x);
462
}
463
INSTRUCTION (l_extbz) {
464
  uint8_t x;
465
  x = PARAM1;
466
  SET_PARAM0((uorreg_t)x);
467
}
468
INSTRUCTION (l_exths) {
469
  int16_t x;
470
  x = PARAM1;
471
  SET_PARAM0((orreg_t)x);
472
}
473
INSTRUCTION (l_exthz) {
474
  uint16_t x;
475
  x = PARAM1;
476
  SET_PARAM0((uorreg_t)x);
477
}
478
INSTRUCTION (l_extws) {
479
  int32_t x;
480
  x = PARAM1;
481
  SET_PARAM0((orreg_t)x);
482
}
483
INSTRUCTION (l_extwz) {
484
  uint32_t x;
485
  x = PARAM1;
486
  SET_PARAM0((uorreg_t)x);
487
}
488
INSTRUCTION (l_mtspr) {
489
  uint16_t regno = PARAM0 + PARAM2;
490
  uorreg_t value = PARAM1;
491
 
492
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
493
    mtspr(regno, value);
494
  else {
495
    PRINTF("WARNING: trying to write SPR while SR[SUPV] is cleared.\n");
496
    sim_done();
497
  }
498
}
499
INSTRUCTION (l_mfspr) {
500
  uint16_t regno = PARAM1 + PARAM2;
501
  uorreg_t value = mfspr(regno);
502
 
503
  if (cpu_state.sprs[SPR_SR] & SPR_SR_SM)
504
    SET_PARAM0(value);
505
  else {
506
    SET_PARAM0(0);
507
    PRINTF("WARNING: trying to read SPR while SR[SUPV] is cleared.\n");
508
    sim_done();
509
  }
510
}
511
INSTRUCTION (l_sys) {
512
  except_handle(EXCEPT_SYSCALL, cpu_state.sprs[SPR_EEAR_BASE]);
513
}
514
INSTRUCTION (l_trap) {
515
  /* TODO: some SR related code here! */
516
  except_handle(EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
517
}
518
INSTRUCTION (l_mac) {
519
  uorreg_t lo, hi;
520
  LONGEST l;
521
  orreg_t x, y;
522
 
523
  lo = cpu_state.sprs[SPR_MACLO];
524
  hi = cpu_state.sprs[SPR_MACHI];
525
  x = PARAM0;
526
  y = PARAM1;
527
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
528
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
529
  l += (LONGEST) x * (LONGEST) y;
530
 
531
  /* This implementation is very fast - it needs only one cycle for mac.  */
532
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
533
  hi = ((LONGEST)l) >> 32;
534
  cpu_state.sprs[SPR_MACLO] = lo;
535
  cpu_state.sprs[SPR_MACHI] = hi;
536
/*   PRINTF ("(%"PRIxREG",%"PRIxREG"\n", hi, lo); */
537
}
538
INSTRUCTION (l_msb) {
539
  uorreg_t lo, hi;
540
  LONGEST l;
541
  orreg_t x, y;
542
 
543
  lo = cpu_state.sprs[SPR_MACLO];
544
  hi = cpu_state.sprs[SPR_MACHI];
545
  x = PARAM0;
546
  y = PARAM1;
547
 
548
/*   PRINTF ("[%"PRIxREG",%"PRIxREG"]\t", x, y); */
549
 
550
  l = (ULONGEST)lo | ((LONGEST)hi << 32);
551
  l -= x * y;
552
 
553
  /* This implementation is very fast - it needs only one cycle for msb.  */
554
  lo = ((ULONGEST)l) & 0xFFFFFFFF;
555
  hi = ((LONGEST)l) >> 32;
556
  cpu_state.sprs[SPR_MACLO] = lo;
557
  cpu_state.sprs[SPR_MACHI] = hi;
558
/*   PRINTF ("(%"PRIxREG",%"PRIxREG")\n", hi, lo); */
559
}
560
INSTRUCTION (l_macrc) {
561
  uorreg_t lo, hi;
562
  LONGEST l;
563
  /* No need for synchronization here -- all MAC instructions are 1 cycle long.  */
564
  lo =  cpu_state.sprs[SPR_MACLO];
565
  hi =  cpu_state.sprs[SPR_MACHI];
566
  l = (ULONGEST) lo | ((LONGEST)hi << 32);
567
  l >>= 28;
568
  //PRINTF ("<%08x>\n", (unsigned long)l);
569
  SET_PARAM0((orreg_t)l);
570
  cpu_state.sprs[SPR_MACLO] = 0;
571
  cpu_state.sprs[SPR_MACHI] = 0;
572
}
573
INSTRUCTION (l_cmov) {
574
  SET_PARAM0(cpu_state.sprs[SPR_SR] & SPR_SR_F ? PARAM1 : PARAM2);
575
}
576
INSTRUCTION (l_ff1) {
577
  SET_PARAM0(ffs(PARAM1));
578
}
579
/******* Floating point instructions *******/
580
/* Single precision */
581
INSTRUCTION (lf_add_s) {
582 100 julius
  if (config.cpu.hardfloat) {
583
  FLOAT param0, param1, param2;
584
  param1.hval = (uorreg_t)PARAM1;
585
  param2.hval = (uorreg_t)PARAM2;
586
  param0.fval = param1.fval + param2.fval;
587
  SET_PARAM0(param0.hval);
588
  } else l_invalid();
589 19 jeremybenn
}
590
INSTRUCTION (lf_div_s) {
591 100 julius
  if (config.cpu.hardfloat) {
592
  FLOAT param0, param1, param2;
593
  param1.hval = (uorreg_t)PARAM1;
594
  param2.hval = (uorreg_t)PARAM2;
595
  param0.fval = param1.fval / param2.fval;
596
  SET_PARAM0(param0.hval);
597
  } else l_invalid();
598 19 jeremybenn
}
599
INSTRUCTION (lf_ftoi_s) {
600 100 julius
  if (config.cpu.hardfloat) {
601
    // no other way appeared to work --jb
602
    float tmp_f; memcpy((void*)&tmp_f, (void*)&PARAM1, sizeof(float));
603
    SET_PARAM0((int)tmp_f);
604
  } else l_invalid();
605 19 jeremybenn
}
606
INSTRUCTION (lf_itof_s) {
607 100 julius
  if (config.cpu.hardfloat) {
608
  FLOAT param0;
609
  param0.fval = (float)((int)PARAM1);
610
  SET_PARAM0(param0.hval);
611
  } else l_invalid();
612 19 jeremybenn
}
613
INSTRUCTION (lf_madd_s) {
614 100 julius
  if (config.cpu.hardfloat) {
615
  FLOAT param0,param1, param2;
616 104 jeremybenn
  param0.hval = (uorreg_t)PARAM0;
617
  param1.hval = (uorreg_t)PARAM1;
618 100 julius
  param2.hval = PARAM2;
619
  param0.fval += param1.fval * param2.fval;
620
  SET_PARAM0(param0.hval);
621
  } else l_invalid();
622 19 jeremybenn
}
623
INSTRUCTION (lf_mul_s) {
624 100 julius
  if (config.cpu.hardfloat) {
625
  FLOAT param0, param1, param2;
626
  param1.hval = (uorreg_t)PARAM1;
627
  param2.hval = (uorreg_t)PARAM2;
628
  param0.fval = param1.fval * param2.fval;
629
  SET_PARAM0(param0.hval);
630
  } else l_invalid();
631 19 jeremybenn
}
632
INSTRUCTION (lf_rem_s) {
633 100 julius
  if (config.cpu.hardfloat) {
634
  FLOAT param0, param1, param2;
635
  param1.hval = PARAM1;
636
  param2.hval = PARAM2;
637 104 jeremybenn
  param0.fval = fmodf (param1.fval, param2.fval);
638 100 julius
  SET_PARAM0(param0.hval);
639
  } else l_invalid();
640 19 jeremybenn
}
641
INSTRUCTION (lf_sfeq_s) {
642 100 julius
  if (config.cpu.hardfloat) {
643
  FLOAT param0, param1;
644
  param0.hval = PARAM0;
645
  param1.hval = PARAM1;
646
  if(param0.fval == param1.fval)
647 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
648
  else
649
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
650 100 julius
  } else l_invalid();
651 19 jeremybenn
}
652
INSTRUCTION (lf_sfge_s) {
653 100 julius
  if (config.cpu.hardfloat) {
654
  FLOAT param0, param1;
655
  param0.hval = PARAM0;
656
  param1.hval = PARAM1;
657
  if(param0.fval >= param1.fval)
658 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
659
  else
660
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
661 100 julius
  } else l_invalid();
662 19 jeremybenn
}
663
INSTRUCTION (lf_sfgt_s) {
664 100 julius
  if (config.cpu.hardfloat) {
665
  FLOAT param0, param1;
666
  param0.hval = PARAM0;
667
  param1.hval = PARAM1;
668
  if(param0.fval > param1.fval)
669 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
670
  else
671
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
672 100 julius
  } else l_invalid();
673 19 jeremybenn
}
674
INSTRUCTION (lf_sfle_s) {
675 100 julius
  if (config.cpu.hardfloat) {
676
  FLOAT param0, param1;
677
  param0.hval = PARAM0;
678
  param1.hval = PARAM1;
679
  if(param0.fval <= param1.fval)
680 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
681
  else
682
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
683 100 julius
  } else l_invalid();
684 19 jeremybenn
}
685
INSTRUCTION (lf_sflt_s) {
686 100 julius
  if (config.cpu.hardfloat) {
687
  FLOAT param0, param1;
688
  param0.hval = PARAM0;
689
  param1.hval = PARAM1;
690
  if(param0.fval < param1.fval)
691 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
692
  else
693
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
694 100 julius
  } else l_invalid();
695 19 jeremybenn
}
696
INSTRUCTION (lf_sfne_s) {
697 100 julius
  if (config.cpu.hardfloat) {
698
  FLOAT param0, param1;
699
  param0.hval = PARAM0;
700
  param1.hval = PARAM1;
701
  if(param0.fval != param1.fval)
702 19 jeremybenn
    cpu_state.sprs[SPR_SR] |= SPR_SR_F;
703
  else
704
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_F;
705 100 julius
  } else l_invalid();
706 19 jeremybenn
}
707
INSTRUCTION (lf_sub_s) {
708 100 julius
  if (config.cpu.hardfloat) {
709
  FLOAT param0, param1, param2;
710
  param1.hval = PARAM1;
711
  param2.hval = PARAM2;
712
  param0.fval = param1.fval - param2.fval;
713
  SET_PARAM0(param0.hval);
714
  } else l_invalid();
715 19 jeremybenn
}
716
 
717
/******* Custom instructions *******/
718
INSTRUCTION (l_cust1) {
719
  /*int destr = current->insn >> 21;
720
    int src1r = current->insn >> 15;
721
    int src2r = current->insn >> 9;*/
722
}
723
INSTRUCTION (l_cust2) {
724
}
725
INSTRUCTION (l_cust3) {
726
}
727
INSTRUCTION (l_cust4) {
728
}
729 100 julius
INSTRUCTION (lf_cust1) {
730
}

powered by: WebSVN 2.1.0

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