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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [sim/] [common/] [cgen-accfp.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* Accurate fp support for CGEN-based simulators.
2
   Copyright (C) 1999 Cygnus Solutions.
3
 
4
   This implemention assumes:
5
   typedef USI SF;
6
   typedef UDI DF;
7
 
8
   TODO:
9
   - lazy encoding/decoding
10
   - checking return code (say by callback)
11
   - proper rounding
12
*/
13
 
14
#include "sim-main.h"
15
#include "sim-fpu.h"
16
 
17
/* SF mode support */
18
 
19
static SF
20
addsf (CGEN_FPU* fpu, SF x, SF y)
21
{
22
  sim_fpu op1;
23
  sim_fpu op2;
24
  sim_fpu ans;
25
  unsigned32 res;
26
  sim_fpu_status status;
27
 
28
  sim_fpu_32to (&op1, x);
29
  sim_fpu_32to (&op2, y);
30
  status = sim_fpu_add (&ans, &op1, &op2);
31
  if (status != 0)
32
    (*fpu->ops->error) (fpu, status);
33
  sim_fpu_to32 (&res, &ans);
34
 
35
  return res;
36
}
37
 
38
static SF
39
subsf (CGEN_FPU* fpu, SF x, SF y)
40
{
41
  sim_fpu op1;
42
  sim_fpu op2;
43
  sim_fpu ans;
44
  unsigned32 res;
45
  sim_fpu_status status;
46
 
47
  sim_fpu_32to (&op1, x);
48
  sim_fpu_32to (&op2, y);
49
  status = sim_fpu_sub (&ans, &op1, &op2);
50
  if (status != 0)
51
    (*fpu->ops->error) (fpu, status);
52
  sim_fpu_to32 (&res, &ans);
53
 
54
  return res;
55
}
56
 
57
static SF
58
mulsf (CGEN_FPU* fpu, SF x, SF y)
59
{
60
  sim_fpu op1;
61
  sim_fpu op2;
62
  sim_fpu ans;
63
  unsigned32 res;
64
  sim_fpu_status status;
65
 
66
  sim_fpu_32to (&op1, x);
67
  sim_fpu_32to (&op2, y);
68
  status = sim_fpu_mul (&ans, &op1, &op2);
69
  if (status != 0)
70
    (*fpu->ops->error) (fpu, status);
71
  sim_fpu_to32 (&res, &ans);
72
 
73
  return res;
74
}
75
 
76
static SF
77
divsf (CGEN_FPU* fpu, SF x, SF y)
78
{
79
  sim_fpu op1;
80
  sim_fpu op2;
81
  sim_fpu ans;
82
  unsigned32 res;
83
  sim_fpu_status status;
84
 
85
  sim_fpu_32to (&op1, x);
86
  sim_fpu_32to (&op2, y);
87
  status = sim_fpu_div (&ans, &op1, &op2);
88
  if (status != 0)
89
    (*fpu->ops->error) (fpu, status);
90
  sim_fpu_to32 (&res, &ans);
91
 
92
  return res;
93
}
94
 
95
static SF
96
negsf (CGEN_FPU* fpu, SF x)
97
{
98
  sim_fpu op1;
99
  sim_fpu ans;
100
  unsigned32 res;
101
  sim_fpu_status status;
102
 
103
  sim_fpu_32to (&op1, x);
104
  status = sim_fpu_neg (&ans, &op1);
105
  if (status != 0)
106
    (*fpu->ops->error) (fpu, status);
107
  sim_fpu_to32 (&res, &ans);
108
 
109
  return res;
110
}
111
 
112
static SF
113
abssf (CGEN_FPU* fpu, SF x)
114
{
115
  sim_fpu op1;
116
  sim_fpu ans;
117
  unsigned32 res;
118
  sim_fpu_status status;
119
 
120
  sim_fpu_32to (&op1, x);
121
  status = sim_fpu_abs (&ans, &op1);
122
  if (status != 0)
123
    (*fpu->ops->error) (fpu, status);
124
  sim_fpu_to32 (&res, &ans);
125
 
126
  return res;
127
}
128
 
129
static SF
130
sqrtsf (CGEN_FPU* fpu, SF x)
131
{
132
  sim_fpu op1;
133
  sim_fpu ans;
134
  unsigned32 res;
135
  sim_fpu_status status;
136
 
137
  sim_fpu_32to (&op1, x);
138
  status = sim_fpu_sqrt (&ans, &op1);
139
  if (status != 0)
140
    (*fpu->ops->error) (fpu, status);
141
  sim_fpu_to32 (&res, &ans);
142
 
143
  return res;
144
}
145
 
146
static SF
147
invsf (CGEN_FPU* fpu, SF x)
148
{
149
  sim_fpu op1;
150
  sim_fpu ans;
151
  unsigned32 res;
152
  sim_fpu_status status;
153
 
154
  sim_fpu_32to (&op1, x);
155
  status = sim_fpu_inv (&ans, &op1);
156
  if (status != 0)
157
    (*fpu->ops->error) (fpu, status);
158
  sim_fpu_to32 (&res, &ans);
159
 
160
  return res;
161
}
162
 
163
static SF
164
minsf (CGEN_FPU* fpu, SF x, SF y)
165
{
166
  sim_fpu op1;
167
  sim_fpu op2;
168
  sim_fpu ans;
169
  unsigned32 res;
170
  sim_fpu_status status;
171
 
172
  sim_fpu_32to (&op1, x);
173
  sim_fpu_32to (&op2, y);
174
  status = sim_fpu_min (&ans, &op1, &op2);
175
  if (status != 0)
176
    (*fpu->ops->error) (fpu, status);
177
  sim_fpu_to32 (&res, &ans);
178
 
179
  return res;
180
}
181
 
182
static SF
183
maxsf (CGEN_FPU* fpu, SF x, SF y)
184
{
185
  sim_fpu op1;
186
  sim_fpu op2;
187
  sim_fpu ans;
188
  unsigned32 res;
189
  sim_fpu_status status;
190
 
191
  sim_fpu_32to (&op1, x);
192
  sim_fpu_32to (&op2, y);
193
  status = sim_fpu_max (&ans, &op1, &op2);
194
  if (status != 0)
195
    (*fpu->ops->error) (fpu, status);
196
  sim_fpu_to32 (&res, &ans);
197
 
198
  return res;
199
}
200
 
201
static CGEN_FP_CMP
202
cmpsf (CGEN_FPU* fpu, SF x, SF y)
203
{
204
  sim_fpu op1;
205
  sim_fpu op2;
206
 
207
  sim_fpu_32to (&op1, x);
208
  sim_fpu_32to (&op2, y);
209
 
210
  if (sim_fpu_is_nan (&op1)
211
      || sim_fpu_is_nan (&op2))
212
    return FP_CMP_NAN;
213
 
214
  if (x < y)
215
    return FP_CMP_LT;
216
  if (x > y)
217
    return FP_CMP_GT;
218
  return FP_CMP_EQ;
219
}
220
 
221
static int
222
eqsf (CGEN_FPU* fpu, SF x, SF y)
223
{
224
  sim_fpu op1;
225
  sim_fpu op2;
226
 
227
  sim_fpu_32to (&op1, x);
228
  sim_fpu_32to (&op2, y);
229
  return sim_fpu_is_eq (&op1, &op2);
230
}
231
 
232
static int
233
nesf (CGEN_FPU* fpu, SF x, SF y)
234
{
235
  sim_fpu op1;
236
  sim_fpu op2;
237
 
238
  sim_fpu_32to (&op1, x);
239
  sim_fpu_32to (&op2, y);
240
  return sim_fpu_is_ne (&op1, &op2);
241
}
242
 
243
static int
244
ltsf (CGEN_FPU* fpu, SF x, SF y)
245
{
246
  sim_fpu op1;
247
  sim_fpu op2;
248
 
249
  sim_fpu_32to (&op1, x);
250
  sim_fpu_32to (&op2, y);
251
  return sim_fpu_is_lt (&op1, &op2);
252
}
253
 
254
static int
255
lesf (CGEN_FPU* fpu, SF x, SF y)
256
{
257
  sim_fpu op1;
258
  sim_fpu op2;
259
 
260
  sim_fpu_32to (&op1, x);
261
  sim_fpu_32to (&op2, y);
262
  return sim_fpu_is_le (&op1, &op2);
263
}
264
 
265
static int
266
gtsf (CGEN_FPU* fpu, SF x, SF y)
267
{
268
  sim_fpu op1;
269
  sim_fpu op2;
270
 
271
  sim_fpu_32to (&op1, x);
272
  sim_fpu_32to (&op2, y);
273
  return sim_fpu_is_gt (&op1, &op2);
274
}
275
 
276
static int
277
gesf (CGEN_FPU* fpu, SF x, SF y)
278
{
279
  sim_fpu op1;
280
  sim_fpu op2;
281
 
282
  sim_fpu_32to (&op1, x);
283
  sim_fpu_32to (&op2, y);
284
  return sim_fpu_is_ge (&op1, &op2);
285
}
286
 
287
static DF
288
fextsfdf (CGEN_FPU* fpu, SF x)
289
{
290
  sim_fpu op1;
291
  unsigned64 res;
292
 
293
  sim_fpu_32to (&op1, x);
294
  sim_fpu_to64 (&res, &op1);
295
 
296
  return res;
297
}
298
 
299
static SF
300
ftruncdfsf (CGEN_FPU* fpu, DF x)
301
{
302
  sim_fpu op1;
303
  unsigned32 res;
304
 
305
  sim_fpu_64to (&op1, x);
306
  sim_fpu_to32 (&res, &op1);
307
 
308
  return res;
309
}
310
 
311
static SF
312
floatsisf (CGEN_FPU* fpu, SI x)
313
{
314
  sim_fpu ans;
315
  unsigned32 res;
316
 
317
  sim_fpu_i32to (&ans, x, sim_fpu_round_near);
318
  sim_fpu_to32 (&res, &ans);
319
  return res;
320
}
321
 
322
static DF
323
floatsidf (CGEN_FPU* fpu, SI x)
324
{
325
  sim_fpu ans;
326
  unsigned64 res;
327
 
328
  sim_fpu_i32to (&ans, x, sim_fpu_round_near);
329
  sim_fpu_to64 (&res, &ans);
330
  return res;
331
}
332
 
333
static SF
334
ufloatsisf (CGEN_FPU* fpu, USI x)
335
{
336
  sim_fpu ans;
337
  unsigned32 res;
338
 
339
  sim_fpu_u32to (&ans, x, sim_fpu_round_near);
340
  sim_fpu_to32 (&res, &ans);
341
  return res;
342
}
343
 
344
static SI
345
fixsfsi (CGEN_FPU* fpu, SF x)
346
{
347
  sim_fpu op1;
348
  unsigned32 res;
349
 
350
  sim_fpu_32to (&op1, x);
351
  sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
352
  return res;
353
}
354
 
355
static SI
356
fixdfsi (CGEN_FPU* fpu, DF x)
357
{
358
  sim_fpu op1;
359
  unsigned32 res;
360
 
361
  sim_fpu_64to (&op1, x);
362
  sim_fpu_to32i (&res, &op1, sim_fpu_round_near);
363
  return res;
364
}
365
 
366
static USI
367
ufixsfsi (CGEN_FPU* fpu, SF x)
368
{
369
  sim_fpu op1;
370
  unsigned32 res;
371
 
372
  sim_fpu_32to (&op1, x);
373
  sim_fpu_to32u (&res, &op1, sim_fpu_round_near);
374
  return res;
375
}
376
 
377
/* DF mode support */
378
 
379
static DF
380
adddf (CGEN_FPU* fpu, DF x, DF y)
381
{
382
  sim_fpu op1;
383
  sim_fpu op2;
384
  sim_fpu ans;
385
  unsigned64 res;
386
  sim_fpu_status status;
387
 
388
  sim_fpu_64to (&op1, x);
389
  sim_fpu_64to (&op2, y);
390
  status = sim_fpu_add (&ans, &op1, &op2);
391
  if (status != 0)
392
    (*fpu->ops->error) (fpu, status);
393
  sim_fpu_to64 (&res, &ans);
394
 
395
  return res;
396
}
397
 
398
static DF
399
subdf (CGEN_FPU* fpu, DF x, DF y)
400
{
401
  sim_fpu op1;
402
  sim_fpu op2;
403
  sim_fpu ans;
404
  unsigned64 res;
405
  sim_fpu_status status;
406
 
407
  sim_fpu_64to (&op1, x);
408
  sim_fpu_64to (&op2, y);
409
  status = sim_fpu_sub (&ans, &op1, &op2);
410
  if (status != 0)
411
    (*fpu->ops->error) (fpu, status);
412
  sim_fpu_to64 (&res, &ans);
413
 
414
  return res;
415
}
416
 
417
static DF
418
muldf (CGEN_FPU* fpu, DF x, DF y)
419
{
420
  sim_fpu op1;
421
  sim_fpu op2;
422
  sim_fpu ans;
423
  unsigned64 res;
424
  sim_fpu_status status;
425
 
426
  sim_fpu_64to (&op1, x);
427
  sim_fpu_64to (&op2, y);
428
  status = sim_fpu_mul (&ans, &op1, &op2);
429
  if (status != 0)
430
    (*fpu->ops->error) (fpu, status);
431
  sim_fpu_to64 (&res, &ans);
432
 
433
  return res;
434
}
435
 
436
static DF
437
divdf (CGEN_FPU* fpu, DF x, DF y)
438
{
439
  sim_fpu op1;
440
  sim_fpu op2;
441
  sim_fpu ans;
442
  unsigned64 res;
443
  sim_fpu_status status;
444
 
445
  sim_fpu_64to (&op1, x);
446
  sim_fpu_64to (&op2, y);
447
  status = sim_fpu_div (&ans, &op1, &op2);
448
  if (status != 0)
449
    (*fpu->ops->error) (fpu, status);
450
  sim_fpu_to64 (&res, &ans);
451
 
452
  return res;
453
}
454
 
455
static DF
456
negdf (CGEN_FPU* fpu, DF x)
457
{
458
  sim_fpu op1;
459
  sim_fpu ans;
460
  unsigned64 res;
461
  sim_fpu_status status;
462
 
463
  sim_fpu_64to (&op1, x);
464
  status = sim_fpu_neg (&ans, &op1);
465
  if (status != 0)
466
    (*fpu->ops->error) (fpu, status);
467
  sim_fpu_to64 (&res, &ans);
468
 
469
  return res;
470
}
471
 
472
static DF
473
absdf (CGEN_FPU* fpu, DF x)
474
{
475
  sim_fpu op1;
476
  sim_fpu ans;
477
  unsigned64 res;
478
  sim_fpu_status status;
479
 
480
  sim_fpu_64to (&op1, x);
481
  status = sim_fpu_abs (&ans, &op1);
482
  if (status != 0)
483
    (*fpu->ops->error) (fpu, status);
484
  sim_fpu_to64 (&res, &ans);
485
 
486
  return res;
487
}
488
 
489
static DF
490
sqrtdf (CGEN_FPU* fpu, DF x)
491
{
492
  sim_fpu op1;
493
  sim_fpu ans;
494
  unsigned64 res;
495
  sim_fpu_status status;
496
 
497
  sim_fpu_64to (&op1, x);
498
  status = sim_fpu_sqrt (&ans, &op1);
499
  if (status != 0)
500
    (*fpu->ops->error) (fpu, status);
501
  sim_fpu_to64 (&res, &ans);
502
 
503
  return res;
504
}
505
 
506
static DF
507
invdf (CGEN_FPU* fpu, DF x)
508
{
509
  sim_fpu op1;
510
  sim_fpu ans;
511
  unsigned64 res;
512
  sim_fpu_status status;
513
 
514
  sim_fpu_64to (&op1, x);
515
  status = sim_fpu_inv (&ans, &op1);
516
  if (status != 0)
517
    (*fpu->ops->error) (fpu, status);
518
  sim_fpu_to64 (&res, &ans);
519
 
520
  return res;
521
}
522
 
523
static DF
524
mindf (CGEN_FPU* fpu, DF x, DF y)
525
{
526
  sim_fpu op1;
527
  sim_fpu op2;
528
  sim_fpu ans;
529
  unsigned64 res;
530
  sim_fpu_status status;
531
 
532
  sim_fpu_64to (&op1, x);
533
  sim_fpu_64to (&op2, y);
534
  status = sim_fpu_min (&ans, &op1, &op2);
535
  if (status != 0)
536
    (*fpu->ops->error) (fpu, status);
537
  sim_fpu_to64 (&res, &ans);
538
 
539
  return res;
540
}
541
 
542
static DF
543
maxdf (CGEN_FPU* fpu, DF x, DF y)
544
{
545
  sim_fpu op1;
546
  sim_fpu op2;
547
  sim_fpu ans;
548
  unsigned64 res;
549
  sim_fpu_status status;
550
 
551
  sim_fpu_64to (&op1, x);
552
  sim_fpu_64to (&op2, y);
553
  status = sim_fpu_max (&ans, &op1, &op2);
554
  if (status != 0)
555
    (*fpu->ops->error) (fpu, status);
556
  sim_fpu_to64 (&res, &ans);
557
 
558
  return res;
559
}
560
 
561
static CGEN_FP_CMP
562
cmpdf (CGEN_FPU* fpu, DF x, DF y)
563
{
564
  sim_fpu op1;
565
  sim_fpu op2;
566
 
567
  sim_fpu_64to (&op1, x);
568
  sim_fpu_64to (&op2, y);
569
 
570
  if (sim_fpu_is_nan (&op1)
571
      || sim_fpu_is_nan (&op2))
572
    return FP_CMP_NAN;
573
 
574
  if (x < y)
575
    return FP_CMP_LT;
576
  if (x > y)
577
    return FP_CMP_GT;
578
  return FP_CMP_EQ;
579
}
580
 
581
static int
582
eqdf (CGEN_FPU* fpu, DF x, DF y)
583
{
584
  sim_fpu op1;
585
  sim_fpu op2;
586
 
587
  sim_fpu_64to (&op1, x);
588
  sim_fpu_64to (&op2, y);
589
  return sim_fpu_is_eq (&op1, &op2);
590
}
591
 
592
static int
593
nedf (CGEN_FPU* fpu, DF x, DF y)
594
{
595
  sim_fpu op1;
596
  sim_fpu op2;
597
 
598
  sim_fpu_64to (&op1, x);
599
  sim_fpu_64to (&op2, y);
600
  return sim_fpu_is_ne (&op1, &op2);
601
}
602
 
603
static int
604
ltdf (CGEN_FPU* fpu, DF x, DF y)
605
{
606
  sim_fpu op1;
607
  sim_fpu op2;
608
 
609
  sim_fpu_64to (&op1, x);
610
  sim_fpu_64to (&op2, y);
611
  return sim_fpu_is_lt (&op1, &op2);
612
}
613
 
614
static int
615
ledf (CGEN_FPU* fpu, DF x, DF y)
616
{
617
  sim_fpu op1;
618
  sim_fpu op2;
619
 
620
  sim_fpu_64to (&op1, x);
621
  sim_fpu_64to (&op2, y);
622
  return sim_fpu_is_le (&op1, &op2);
623
}
624
 
625
static int
626
gtdf (CGEN_FPU* fpu, DF x, DF y)
627
{
628
  sim_fpu op1;
629
  sim_fpu op2;
630
 
631
  sim_fpu_64to (&op1, x);
632
  sim_fpu_64to (&op2, y);
633
  return sim_fpu_is_gt (&op1, &op2);
634
}
635
 
636
static int
637
gedf (CGEN_FPU* fpu, DF x, DF y)
638
{
639
  sim_fpu op1;
640
  sim_fpu op2;
641
 
642
  sim_fpu_64to (&op1, x);
643
  sim_fpu_64to (&op2, y);
644
  return sim_fpu_is_ge (&op1, &op2);
645
}
646
 
647
/* Initialize FP_OPS to use accurate library.  */
648
 
649
void
650
cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error)
651
{
652
  CGEN_FP_OPS* o;
653
 
654
  fpu->owner = cpu;
655
  /* ??? small memory leak, not freed by sim_close */
656
  fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS));
657
 
658
  o = fpu->ops;
659
  memset (o, 0, sizeof (*o));
660
 
661
  o->error = error;
662
 
663
  o->addsf = addsf;
664
  o->subsf = subsf;
665
  o->mulsf = mulsf;
666
  o->divsf = divsf;
667
  o->negsf = negsf;
668
  o->abssf = abssf;
669
  o->sqrtsf = sqrtsf;
670
  o->invsf = invsf;
671
  o->minsf = minsf;
672
  o->maxsf = maxsf;
673
  o->cmpsf = cmpsf;
674
  o->eqsf = eqsf;
675
  o->nesf = nesf;
676
  o->ltsf = ltsf;
677
  o->lesf = lesf;
678
  o->gtsf = gtsf;
679
  o->gesf = gesf;
680
 
681
  o->adddf = adddf;
682
  o->subdf = subdf;
683
  o->muldf = muldf;
684
  o->divdf = divdf;
685
  o->negdf = negdf;
686
  o->absdf = absdf;
687
  o->sqrtdf = sqrtdf;
688
  o->invdf = invdf;
689
  o->mindf = mindf;
690
  o->maxdf = maxdf;
691
  o->cmpdf = cmpdf;
692
  o->eqdf = eqdf;
693
  o->nedf = nedf;
694
  o->ltdf = ltdf;
695
  o->ledf = ledf;
696
  o->gtdf = gtdf;
697
  o->gedf = gedf;
698
  o->fextsfdf = fextsfdf;
699
  o->ftruncdfsf = ftruncdfsf;
700
  o->floatsisf = floatsisf;
701
  o->floatsidf = floatsidf;
702
  o->ufloatsisf = ufloatsisf;
703
  o->fixsfsi = fixsfsi;
704
  o->fixdfsi = fixdfsi;
705
  o->ufixsfsi = ufixsfsi;
706
}

powered by: WebSVN 2.1.0

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