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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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