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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [h8300/] [lib1funcs.S] - Blame information for rev 734

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
;; libgcc routines for the Renesas H8/300 CPU.
2
;; Contributed by Steve Chamberlain 
3
;; Optimizations by Toshiyasu Morita 
4
 
5
/* Copyright (C) 1994, 2000, 2001, 2002, 2003, 2004, 2009
6
   Free Software Foundation, Inc.
7
 
8
This file is free software; you can redistribute it and/or modify it
9
under the terms of the GNU General Public License as published by the
10
Free Software Foundation; either version 3, or (at your option) any
11
later version.
12
 
13
This file is distributed in the hope that it will be useful, but
14
WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
General Public License for more details.
17
 
18
Under Section 7 of GPL version 3, you are granted additional
19
permissions described in the GCC Runtime Library Exception, version
20
3.1, as published by the Free Software Foundation.
21
 
22
You should have received a copy of the GNU General Public License and
23
a copy of the GCC Runtime Library Exception along with this program;
24
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25
.  */
26
 
27
/* Assembler register definitions.  */
28
 
29
#define A0 r0
30
#define A0L r0l
31
#define A0H r0h
32
 
33
#define A1 r1
34
#define A1L r1l
35
#define A1H r1h
36
 
37
#define A2 r2
38
#define A2L r2l
39
#define A2H r2h
40
 
41
#define A3 r3
42
#define A3L r3l
43
#define A3H r3h
44
 
45
#define S0 r4
46
#define S0L r4l
47
#define S0H r4h
48
 
49
#define S1 r5
50
#define S1L r5l
51
#define S1H r5h
52
 
53
#define S2 r6
54
#define S2L r6l
55
#define S2H r6h
56
 
57
#ifdef __H8300__
58
#define PUSHP   push
59
#define POPP    pop
60
 
61
#define A0P     r0
62
#define A1P     r1
63
#define A2P     r2
64
#define A3P     r3
65
#define S0P     r4
66
#define S1P     r5
67
#define S2P     r6
68
#endif
69
 
70
#if defined (__H8300H__) || defined (__H8300S__) || defined (__H8300SX__)
71
#define PUSHP   push.l
72
#define POPP    pop.l
73
 
74
#define A0P     er0
75
#define A1P     er1
76
#define A2P     er2
77
#define A3P     er3
78
#define S0P     er4
79
#define S1P     er5
80
#define S2P     er6
81
 
82
#define A0E     e0
83
#define A1E     e1
84
#define A2E     e2
85
#define A3E     e3
86
#endif
87
 
88
#ifdef __H8300H__
89
#ifdef __NORMAL_MODE__
90
        .h8300hn
91
#else
92
        .h8300h
93
#endif
94
#endif
95
 
96
#ifdef __H8300S__
97
#ifdef __NORMAL_MODE__
98
        .h8300sn
99
#else
100
        .h8300s
101
#endif
102
#endif
103
#ifdef __H8300SX__
104
#ifdef __NORMAL_MODE__
105
        .h8300sxn
106
#else
107
        .h8300sx
108
#endif
109
#endif
110
 
111
#ifdef L_cmpsi2
112
#ifdef __H8300__
113
        .section .text
114
        .align 2
115
        .global ___cmpsi2
116
___cmpsi2:
117
        cmp.w   A0,A2
118
        bne     .L2
119
        cmp.w   A1,A3
120
        bne     .L4
121
        mov.w   #1,A0
122
        rts
123
.L2:
124
        bgt     .L5
125
.L3:
126
        mov.w   #2,A0
127
        rts
128
.L4:
129
        bls     .L3
130
.L5:
131
        sub.w   A0,A0
132
        rts
133
        .end
134
#endif
135
#endif /* L_cmpsi2 */
136
 
137
#ifdef L_ucmpsi2
138
#ifdef __H8300__
139
        .section .text
140
        .align 2
141
        .global ___ucmpsi2
142
___ucmpsi2:
143
        cmp.w   A0,A2
144
        bne     .L2
145
        cmp.w   A1,A3
146
        bne     .L4
147
        mov.w   #1,A0
148
        rts
149
.L2:
150
        bhi     .L5
151
.L3:
152
        mov.w   #2,A0
153
        rts
154
.L4:
155
        bls     .L3
156
.L5:
157
        sub.w   A0,A0
158
        rts
159
        .end
160
#endif
161
#endif /* L_ucmpsi2 */
162
 
163
#ifdef L_divhi3
164
 
165
;; HImode divides for the H8/300.
166
;; We bunch all of this into one object file since there are several
167
;; "supporting routines".
168
 
169
; general purpose normalize routine
170
;
171
; divisor in A0
172
; dividend in A1
173
; turns both into +ve numbers, and leaves what the answer sign
174
; should be in A2L
175
 
176
#ifdef __H8300__
177
        .section .text
178
        .align 2
179
divnorm:
180
        or      A0H,A0H         ; is divisor > 0
181
        stc     ccr,A2L
182
        bge     _lab1
183
        not     A0H             ; no - then make it +ve
184
        not     A0L
185
        adds    #1,A0
186
_lab1:  or      A1H,A1H ; look at dividend
187
        bge     _lab2
188
        not     A1H             ; it is -ve, make it positive
189
        not     A1L
190
        adds    #1,A1
191
        xor     #0x8,A2L; and toggle sign of result
192
_lab2:  rts
193
;; Basically the same, except that the sign of the divisor determines
194
;; the sign.
195
modnorm:
196
        or      A0H,A0H         ; is divisor > 0
197
        stc     ccr,A2L
198
        bge     _lab7
199
        not     A0H             ; no - then make it +ve
200
        not     A0L
201
        adds    #1,A0
202
_lab7:  or      A1H,A1H ; look at dividend
203
        bge     _lab8
204
        not     A1H             ; it is -ve, make it positive
205
        not     A1L
206
        adds    #1,A1
207
_lab8:  rts
208
 
209
; A0=A0/A1 signed
210
 
211
        .global ___divhi3
212
___divhi3:
213
        bsr     divnorm
214
        bsr     ___udivhi3
215
negans: btst    #3,A2L  ; should answer be negative ?
216
        beq     _lab4
217
        not     A0H     ; yes, so make it so
218
        not     A0L
219
        adds    #1,A0
220
_lab4:  rts
221
 
222
; A0=A0%A1 signed
223
 
224
        .global ___modhi3
225
___modhi3:
226
        bsr     modnorm
227
        bsr     ___udivhi3
228
        mov     A3,A0
229
        bra     negans
230
 
231
; A0=A0%A1 unsigned
232
 
233
        .global ___umodhi3
234
___umodhi3:
235
        bsr     ___udivhi3
236
        mov     A3,A0
237
        rts
238
 
239
; A0=A0/A1 unsigned
240
; A3=A0%A1 unsigned
241
; A2H trashed
242
; D high 8 bits of denom
243
; d low 8 bits of denom
244
; N high 8 bits of num
245
; n low 8 bits of num
246
; M high 8 bits of mod
247
; m low 8 bits of mod
248
; Q high 8 bits of quot
249
; q low 8 bits of quot
250
; P preserve
251
 
252
; The H8/300 only has a 16/8 bit divide, so we look at the incoming and
253
; see how to partition up the expression.
254
 
255
        .global ___udivhi3
256
___udivhi3:
257
                                ; A0 A1 A2 A3
258
                                ; Nn Dd       P
259
        sub.w   A3,A3           ; Nn Dd xP 00
260
        or      A1H,A1H
261
        bne     divlongway
262
        or      A0H,A0H
263
        beq     _lab6
264
 
265
; we know that D == 0 and N is != 0
266
        mov.b   A0H,A3L         ; Nn Dd xP 0N
267
        divxu   A1L,A3          ;          MQ
268
        mov.b   A3L,A0H         ; Q
269
; dealt with N, do n
270
_lab6:  mov.b   A0L,A3L         ;           n
271
        divxu   A1L,A3          ;          mq
272
        mov.b   A3L,A0L         ; Qq
273
        mov.b   A3H,A3L         ;           m
274
        mov.b   #0x0,A3H        ; Qq       0m
275
        rts
276
 
277
; D != 0 - which means the denominator is
278
;          loop around to get the result.
279
 
280
divlongway:
281
        mov.b   A0H,A3L         ; Nn Dd xP 0N
282
        mov.b   #0x0,A0H        ; high byte of answer has to be zero
283
        mov.b   #0x8,A2H        ;       8
284
div8:   add.b   A0L,A0L         ; n*=2
285
        rotxl   A3L             ; Make remainder bigger
286
        rotxl   A3H
287
        sub.w   A1,A3           ; Q-=N
288
        bhs     setbit          ; set a bit ?
289
        add.w   A1,A3           ;  no : too far , Q+=N
290
 
291
        dec     A2H
292
        bne     div8            ; next bit
293
        rts
294
 
295
setbit: inc     A0L             ; do insert bit
296
        dec     A2H
297
        bne     div8            ; next bit
298
        rts
299
 
300
#endif /* __H8300__ */
301
#endif /* L_divhi3 */
302
 
303
#ifdef L_divsi3
304
 
305
;; 4 byte integer divides for the H8/300.
306
;;
307
;; We have one routine which does all the work and lots of
308
;; little ones which prepare the args and massage the sign.
309
;; We bunch all of this into one object file since there are several
310
;; "supporting routines".
311
 
312
        .section .text
313
        .align 2
314
 
315
; Put abs SIs into r0/r1 and r2/r3, and leave a 1 in r6l with sign of rest.
316
; This function is here to keep branch displacements small.
317
 
318
#ifdef __H8300__
319
 
320
divnorm:
321
        mov.b   A0H,A0H         ; is the numerator -ve
322
        stc     ccr,S2L         ; keep the sign in bit 3 of S2L
323
        bge     postive
324
 
325
        ; negate arg
326
        not     A0H
327
        not     A1H
328
        not     A0L
329
        not     A1L
330
 
331
        add     #1,A1L
332
        addx    #0,A1H
333
        addx    #0,A0L
334
        addx    #0,A0H
335
postive:
336
        mov.b   A2H,A2H         ; is the denominator -ve
337
        bge     postive2
338
        not     A2L
339
        not     A2H
340
        not     A3L
341
        not     A3H
342
        add.b   #1,A3L
343
        addx    #0,A3H
344
        addx    #0,A2L
345
        addx    #0,A2H
346
        xor.b   #0x08,S2L       ; toggle the result sign
347
postive2:
348
        rts
349
 
350
;; Basically the same, except that the sign of the divisor determines
351
;; the sign.
352
modnorm:
353
        mov.b   A0H,A0H         ; is the numerator -ve
354
        stc     ccr,S2L         ; keep the sign in bit 3 of S2L
355
        bge     mpostive
356
 
357
        ; negate arg
358
        not     A0H
359
        not     A1H
360
        not     A0L
361
        not     A1L
362
 
363
        add     #1,A1L
364
        addx    #0,A1H
365
        addx    #0,A0L
366
        addx    #0,A0H
367
mpostive:
368
        mov.b   A2H,A2H         ; is the denominator -ve
369
        bge     mpostive2
370
        not     A2L
371
        not     A2H
372
        not     A3L
373
        not     A3H
374
        add.b   #1,A3L
375
        addx    #0,A3H
376
        addx    #0,A2L
377
        addx    #0,A2H
378
mpostive2:
379
        rts
380
 
381
#else /* __H8300H__ */
382
 
383
divnorm:
384
        mov.l   A0P,A0P         ; is the numerator -ve
385
        stc     ccr,S2L         ; keep the sign in bit 3 of S2L
386
        bge     postive
387
 
388
        neg.l   A0P             ; negate arg
389
 
390
postive:
391
        mov.l   A1P,A1P         ; is the denominator -ve
392
        bge     postive2
393
 
394
        neg.l   A1P             ; negate arg
395
        xor.b   #0x08,S2L       ; toggle the result sign
396
 
397
postive2:
398
        rts
399
 
400
;; Basically the same, except that the sign of the divisor determines
401
;; the sign.
402
modnorm:
403
        mov.l   A0P,A0P         ; is the numerator -ve
404
        stc     ccr,S2L         ; keep the sign in bit 3 of S2L
405
        bge     mpostive
406
 
407
        neg.l   A0P             ; negate arg
408
 
409
mpostive:
410
        mov.l   A1P,A1P         ; is the denominator -ve
411
        bge     mpostive2
412
 
413
        neg.l   A1P             ; negate arg
414
 
415
mpostive2:
416
        rts
417
 
418
#endif
419
 
420
; numerator in A0/A1
421
; denominator in A2/A3
422
        .global ___modsi3
423
___modsi3:
424
#ifdef __H8300__
425
        PUSHP   S2P
426
        PUSHP   S0P
427
        PUSHP   S1P
428
        bsr     modnorm
429
        bsr     divmodsi4
430
        mov     S0,A0
431
        mov     S1,A1
432
        bra     exitdiv
433
#else
434
        PUSHP   S2P
435
        bsr     modnorm
436
        bsr     ___udivsi3
437
        mov.l   er3,er0
438
        bra     exitdiv
439
#endif
440
 
441
        ;; H8/300H and H8S version of ___udivsi3 is defined later in
442
        ;; the file.
443
#ifdef __H8300__
444
        .global ___udivsi3
445
___udivsi3:
446
        PUSHP   S2P
447
        PUSHP   S0P
448
        PUSHP   S1P
449
        bsr     divmodsi4
450
        bra     reti
451
#endif
452
 
453
        .global ___umodsi3
454
___umodsi3:
455
#ifdef __H8300__
456
        PUSHP   S2P
457
        PUSHP   S0P
458
        PUSHP   S1P
459
        bsr     divmodsi4
460
        mov     S0,A0
461
        mov     S1,A1
462
        bra     reti
463
#else
464
        bsr     ___udivsi3
465
        mov.l   er3,er0
466
        rts
467
#endif
468
 
469
        .global ___divsi3
470
___divsi3:
471
#ifdef __H8300__
472
        PUSHP   S2P
473
        PUSHP   S0P
474
        PUSHP   S1P
475
        jsr     divnorm
476
        jsr     divmodsi4
477
#else
478
        PUSHP   S2P
479
        jsr     divnorm
480
        bsr     ___udivsi3
481
#endif
482
 
483
        ; examine what the sign should be
484
exitdiv:
485
        btst    #3,S2L
486
        beq     reti
487
 
488
        ; should be -ve
489
#ifdef __H8300__
490
        not     A0H
491
        not     A1H
492
        not     A0L
493
        not     A1L
494
 
495
        add     #1,A1L
496
        addx    #0,A1H
497
        addx    #0,A0L
498
        addx    #0,A0H
499
#else /* __H8300H__ */
500
        neg.l   A0P
501
#endif
502
 
503
reti:
504
#ifdef __H8300__
505
        POPP    S1P
506
        POPP    S0P
507
#endif
508
        POPP    S2P
509
        rts
510
 
511
        ; takes A0/A1 numerator (A0P for H8/300H)
512
        ; A2/A3 denominator (A1P for H8/300H)
513
        ; returns A0/A1 quotient (A0P for H8/300H)
514
        ; S0/S1 remainder (S0P for H8/300H)
515
        ; trashes S2H
516
 
517
#ifdef __H8300__
518
 
519
divmodsi4:
520
        sub.w   S0,S0           ; zero play area
521
        mov.w   S0,S1
522
        mov.b   A2H,S2H
523
        or      A2L,S2H
524
        or      A3H,S2H
525
        bne     DenHighNonZero
526
        mov.b   A0H,A0H
527
        bne     NumByte0Zero
528
        mov.b   A0L,A0L
529
        bne     NumByte1Zero
530
        mov.b   A1H,A1H
531
        bne     NumByte2Zero
532
        bra     NumByte3Zero
533
NumByte0Zero:
534
        mov.b   A0H,S1L
535
        divxu   A3L,S1
536
        mov.b   S1L,A0H
537
NumByte1Zero:
538
        mov.b   A0L,S1L
539
        divxu   A3L,S1
540
        mov.b   S1L,A0L
541
NumByte2Zero:
542
        mov.b   A1H,S1L
543
        divxu   A3L,S1
544
        mov.b   S1L,A1H
545
NumByte3Zero:
546
        mov.b   A1L,S1L
547
        divxu   A3L,S1
548
        mov.b   S1L,A1L
549
 
550
        mov.b   S1H,S1L
551
        mov.b   #0x0,S1H
552
        rts
553
 
554
; have to do the divide by shift and test
555
DenHighNonZero:
556
        mov.b   A0H,S1L
557
        mov.b   A0L,A0H
558
        mov.b   A1H,A0L
559
        mov.b   A1L,A1H
560
 
561
        mov.b   #0,A1L
562
        mov.b   #24,S2H ; only do 24 iterations
563
 
564
nextbit:
565
        add.w   A1,A1   ; double the answer guess
566
        rotxl   A0L
567
        rotxl   A0H
568
 
569
        rotxl   S1L     ; double remainder
570
        rotxl   S1H
571
        rotxl   S0L
572
        rotxl   S0H
573
        sub.w   A3,S1   ; does it all fit
574
        subx    A2L,S0L
575
        subx    A2H,S0H
576
        bhs     setone
577
 
578
        add.w   A3,S1   ; no, restore mistake
579
        addx    A2L,S0L
580
        addx    A2H,S0H
581
 
582
        dec     S2H
583
        bne     nextbit
584
        rts
585
 
586
setone:
587
        inc     A1L
588
        dec     S2H
589
        bne     nextbit
590
        rts
591
 
592
#else /* __H8300H__ */
593
 
594
        ;; This function also computes the remainder and stores it in er3.
595
        .global ___udivsi3
596
___udivsi3:
597
        mov.w   A1E,A1E         ; denominator top word 0?
598
        bne     DenHighNonZero
599
 
600
        ; do it the easy way, see page 107 in manual
601
        mov.w   A0E,A2
602
        extu.l  A2P
603
        divxu.w A1,A2P
604
        mov.w   A2E,A0E
605
        divxu.w A1,A0P
606
        mov.w   A0E,A3
607
        mov.w   A2,A0E
608
        extu.l  A3P
609
        rts
610
 
611
        ; er0 = er0 / er1
612
        ; er3 = er0 % er1
613
        ; trashes er1 er2
614
        ; expects er1 >= 2^16
615
DenHighNonZero:
616
        mov.l   er0,er3
617
        mov.l   er1,er2
618
#ifdef __H8300H__
619
divmod_L21:
620
        shlr.l  er0
621
        shlr.l  er2             ; make divisor < 2^16
622
        mov.w   e2,e2
623
        bne     divmod_L21
624
#else
625
        shlr.l  #2,er2          ; make divisor < 2^16
626
        mov.w   e2,e2
627
        beq     divmod_L22A
628
divmod_L21:
629
        shlr.l  #2,er0
630
divmod_L22:
631
        shlr.l  #2,er2          ; make divisor < 2^16
632
        mov.w   e2,e2
633
        bne     divmod_L21
634
divmod_L22A:
635
        rotxl.w r2
636
        bcs     divmod_L23
637
        shlr.l  er0
638
        bra     divmod_L24
639
divmod_L23:
640
        rotxr.w r2
641
        shlr.l  #2,er0
642
divmod_L24:
643
#endif
644
        ;; At this point,
645
        ;;  er0 contains shifted dividend
646
        ;;  er1 contains divisor
647
        ;;  er2 contains shifted divisor
648
        ;;  er3 contains dividend, later remainder
649
        divxu.w r2,er0          ; r0 now contains the approximate quotient (AQ)
650
        extu.l  er0
651
        beq     divmod_L25
652
        subs    #1,er0          ; er0 = AQ - 1
653
        mov.w   e1,r2
654
        mulxu.w r0,er2          ; er2 = upper (AQ - 1) * divisor
655
        sub.w   r2,e3           ; dividend - 65536 * er2
656
        mov.w   r1,r2
657
        mulxu.w r0,er2          ; compute er3 = remainder (tentative)
658
        sub.l   er2,er3         ; er3 = dividend - (AQ - 1) * divisor
659
divmod_L25:
660
        cmp.l   er1,er3         ; is divisor < remainder?
661
        blo     divmod_L26
662
        adds    #1,er0
663
        sub.l   er1,er3         ; correct the remainder
664
divmod_L26:
665
        rts
666
 
667
#endif
668
#endif /* L_divsi3 */
669
 
670
#ifdef L_mulhi3
671
 
672
;; HImode multiply.
673
; The H8/300 only has an 8*8->16 multiply.
674
; The answer is the same as:
675
;
676
; product = (srca.l * srcb.l) + ((srca.h * srcb.l) + (srcb.h * srca.l)) * 256
677
; (we can ignore A1.h * A0.h cause that will all off the top)
678
; A0 in
679
; A1 in
680
; A0 answer
681
 
682
#ifdef __H8300__
683
        .section .text
684
        .align 2
685
        .global ___mulhi3
686
___mulhi3:
687
        mov.b   A1L,A2L         ; A2l gets srcb.l
688
        mulxu   A0L,A2          ; A2 gets first sub product
689
 
690
        mov.b   A0H,A3L         ; prepare for
691
        mulxu   A1L,A3          ; second sub product
692
 
693
        add.b   A3L,A2H         ; sum first two terms
694
 
695
        mov.b   A1H,A3L         ; third sub product
696
        mulxu   A0L,A3
697
 
698
        add.b   A3L,A2H         ; almost there
699
        mov.w   A2,A0           ; that is
700
        rts
701
 
702
#endif
703
#endif /* L_mulhi3 */
704
 
705
#ifdef L_mulsi3
706
 
707
;; SImode multiply.
708
;;
709
;; I think that shift and add may be sufficient for this.  Using the
710
;; supplied 8x8->16 would need 10 ops of 14 cycles each + overhead.  This way
711
;; the inner loop uses maybe 20 cycles + overhead, but terminates
712
;; quickly on small args.
713
;;
714
;; A0/A1 src_a
715
;; A2/A3 src_b
716
;;
717
;;  while (a)
718
;;    {
719
;;      if (a & 1)
720
;;        r += b;
721
;;      a >>= 1;
722
;;      b <<= 1;
723
;;    }
724
 
725
        .section .text
726
        .align 2
727
 
728
#ifdef __H8300__
729
 
730
        .global ___mulsi3
731
___mulsi3:
732
        PUSHP   S0P
733
        PUSHP   S1P
734
 
735
        sub.w   S0,S0
736
        sub.w   S1,S1
737
 
738
        ; while (a)
739
_top:   mov.w   A0,A0
740
        bne     _more
741
        mov.w   A1,A1
742
        beq     _done
743
_more:  ; if (a & 1)
744
        bld     #0,A1L
745
        bcc     _nobit
746
        ; r += b
747
        add.w   A3,S1
748
        addx    A2L,S0L
749
        addx    A2H,S0H
750
_nobit:
751
        ; a >>= 1
752
        shlr    A0H
753
        rotxr   A0L
754
        rotxr   A1H
755
        rotxr   A1L
756
 
757
        ; b <<= 1
758
        add.w   A3,A3
759
        addx    A2L,A2L
760
        addx    A2H,A2H
761
        bra     _top
762
 
763
_done:
764
        mov.w   S0,A0
765
        mov.w   S1,A1
766
        POPP    S1P
767
        POPP    S0P
768
        rts
769
 
770
#else /* __H8300H__ */
771
 
772
;
773
; mulsi3 for H8/300H - based on Renesas SH implementation
774
;
775
; by Toshiyasu Morita
776
;
777
; Old code:
778
;
779
; 16b * 16b = 372 states (worst case)
780
; 32b * 32b = 724 states (worst case)
781
;
782
; New code:
783
;
784
; 16b * 16b =  48 states
785
; 16b * 32b =  72 states
786
; 32b * 32b =  92 states
787
;
788
 
789
        .global ___mulsi3
790
___mulsi3:
791
        mov.w   r1,r2   ; ( 2 states) b * d
792
        mulxu   r0,er2  ; (22 states)
793
 
794
        mov.w   e0,r3   ; ( 2 states) a * d
795
        beq     L_skip1 ; ( 4 states)
796
        mulxu   r1,er3  ; (22 states)
797
        add.w   r3,e2   ; ( 2 states)
798
 
799
L_skip1:
800
        mov.w   e1,r3   ; ( 2 states) c * b
801
        beq     L_skip2 ; ( 4 states)
802
        mulxu   r0,er3  ; (22 states)
803
        add.w   r3,e2   ; ( 2 states)
804
 
805
L_skip2:
806
        mov.l   er2,er0 ; ( 2 states)
807
        rts             ; (10 states)
808
 
809
#endif
810
#endif /* L_mulsi3 */
811
#ifdef L_fixunssfsi_asm
812
/* For the h8300 we use asm to save some bytes, to
813
   allow more programs to fit into the tiny address
814
   space.  For the H8/300H and H8S, the C version is good enough.  */
815
#ifdef __H8300__
816
/* We still treat NANs different than libgcc2.c, but then, the
817
   behavior is undefined anyways.  */
818
        .global ___fixunssfsi
819
___fixunssfsi:
820
        cmp.b #0x4f,r0h
821
        bge Large_num
822
        jmp     @___fixsfsi
823
Large_num:
824
        bhi L_huge_num
825
        xor.b #0x80,A0L
826
        bmi L_shift8
827
L_huge_num:
828
        mov.w #65535,A0
829
        mov.w A0,A1
830
        rts
831
L_shift8:
832
        mov.b A0L,A0H
833
        mov.b A1H,A0L
834
        mov.b A1L,A1H
835
        mov.b #0,A1L
836
        rts
837
#endif
838
#endif /* L_fixunssfsi_asm */

powered by: WebSVN 2.1.0

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