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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [m68hc11/] [larith.asm] - Blame information for rev 299

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
/* libgcc routines for M68HC11 & M68HC12.
2
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2008, 2009
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it
8
under the terms of the GNU General Public License as published by the
9
Free Software Foundation; either version 3, or (at your option) any
10
later version.
11
 
12
This file is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
Under Section 7 of GPL version 3, you are granted additional
18
permissions described in the GCC Runtime Library Exception, version
19
3.1, as published by the Free Software Foundation.
20
 
21
You should have received a copy of the GNU General Public License and
22
a copy of the GCC Runtime Library Exception along with this program;
23
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24
.  */
25
 
26
#ifdef __HAVE_SHORT_INT__
27
        .mode mshort
28
#else
29
        .mode mlong
30
#endif
31
 
32
        .macro declare_near name
33
        .globl \name
34
        .type  \name,@function
35
        .size  \name,.Lend-\name
36
\name:
37
        .endm
38
 
39
#if defined(__USE_RTC__)
40
# define ARG(N) N+1
41
 
42
        .macro ret
43
#if defined(mc68hc12)
44
        rtc
45
#else
46
        jmp __return_32
47
#endif
48
        .endm
49
 
50
        .macro declare name
51
        .globl \name
52
        .type  \name,@function
53
        .size  \name,.Lend-\name
54
        .far   \name
55
\name:
56
        .endm
57
 
58
        .macro farsym name
59
        .far NAME
60
        .endm
61
 
62
#else
63
# define ARG(N) N
64
 
65
        .macro ret
66
        rts
67
        .endm
68
 
69
        .macro farsym name
70
        .endm
71
 
72
        .macro declare name
73
        .globl \name
74
        .type  \name,@function
75
        .size  \name,.Lend-\name
76
\name:
77
        .endm
78
 
79
#endif
80
 
81
        .sect .text
82
 
83
 
84
#define REG(NAME)                       \
85
NAME:   .dc.w   1;                      \
86
        .type NAME,@object ;            \
87
        .size NAME,2
88
 
89
#ifdef L_regs_min
90
/* Pseudo hard registers used by gcc.
91
   They should be located in page0.  */
92
 
93
        .sect .softregs
94
        .globl _.tmp
95
        .globl _.z,_.xy
96
REG(_.tmp)
97
REG(_.z)
98
REG(_.xy)
99
 
100
#endif
101
 
102
#ifdef L_regs_frame
103
        .sect .softregs
104
        .globl _.frame
105
REG(_.frame)
106
#endif
107
 
108
#ifdef L_regs_d1_2
109
        .sect .softregs
110
        .globl _.d1,_.d2
111
REG(_.d1)
112
REG(_.d2)
113
#endif
114
 
115
#ifdef L_regs_d3_4
116
        .sect .softregs
117
        .globl _.d3,_.d4
118
REG(_.d3)
119
REG(_.d4)
120
#endif
121
 
122
#ifdef L_regs_d5_6
123
        .sect .softregs
124
        .globl _.d5,_.d6
125
REG(_.d5)
126
REG(_.d6)
127
#endif
128
 
129
#ifdef L_regs_d7_8
130
        .sect .softregs
131
        .globl _.d7,_.d8
132
REG(_.d7)
133
REG(_.d8)
134
#endif
135
 
136
#ifdef L_regs_d9_16
137
/* Pseudo hard registers used by gcc.
138
   They should be located in page0.  */
139
        .sect .softregs
140
        .globl _.d9,_.d10,_.d11,_.d12,_.d13,_.d14
141
        .globl _.d15,_.d16
142
REG(_.d9)
143
REG(_.d10)
144
REG(_.d11)
145
REG(_.d12)
146
REG(_.d13)
147
REG(_.d14)
148
REG(_.d15)
149
REG(_.d16)
150
 
151
#endif
152
 
153
#ifdef L_regs_d17_32
154
/* Pseudo hard registers used by gcc.
155
   They should be located in page0.  */
156
        .sect .softregs
157
        .globl _.d17,_.d18,_.d19,_.d20,_.d21,_.d22
158
        .globl _.d23,_.d24,_.d25,_.d26,_.d27,_.d28
159
        .globl _.d29,_.d30,_.d31,_.d32
160
REG(_.d17)
161
REG(_.d18)
162
REG(_.d19)
163
REG(_.d20)
164
REG(_.d21)
165
REG(_.d22)
166
REG(_.d23)
167
REG(_.d24)
168
REG(_.d25)
169
REG(_.d26)
170
REG(_.d27)
171
REG(_.d28)
172
REG(_.d29)
173
REG(_.d30)
174
REG(_.d31)
175
REG(_.d32)
176
#endif
177
 
178
#ifdef L_premain
179
;;
180
;; Specific initialization for 68hc11 before the main.
181
;; Nothing special for a generic routine; Just enable interrupts.
182
;;
183
        declare_near    __premain
184
        clra
185
        tap     ; Clear both I and X.
186
        rts
187
#endif
188
 
189
#ifdef L__exit
190
;;
191
;; Exit operation.  Just loop forever and wait for interrupts.
192
;; (no other place to go)
193
;; This operation is split in several pieces collected together by
194
;; the linker script.  This allows to support destructors at the
195
;; exit stage while not impacting program sizes when there is no
196
;; destructors.
197
;;
198
;; _exit:
199
;;    *(.fini0)         /* Beginning of finish code (_exit symbol).  */
200
;;    *(.fini1)         /* Place holder for applications.  */
201
;;    *(.fini2)         /* C++ destructors.  */
202
;;    *(.fini3)         /* Place holder for applications.  */
203
;;    *(.fini4)         /* Runtime exit.  */
204
;;
205
        .sect .fini0,"ax",@progbits
206
        .globl _exit
207
        .globl exit
208
        .weak  exit
209
        farsym  exit
210
        farsym  _exit
211
exit:
212
_exit:
213
 
214
        .sect .fini4,"ax",@progbits
215
fatal:
216
        cli
217
        wai
218
        bra fatal
219
#endif
220
 
221
#ifdef L_abort
222
;;
223
;; Abort operation.  This is defined for the GCC testsuite.
224
;;
225
        declare abort
226
 
227
        ldd     #255            ;
228
#ifdef mc68hc12
229
        trap    #0x30
230
#else
231
        .byte 0xCD              ; Generate an illegal instruction trap
232
        .byte 0x03              ; The simulator catches this and stops.
233
#endif
234
        jmp _exit
235
#endif
236
 
237
#ifdef L_cleanup
238
;;
239
;; Cleanup operation used by exit().
240
;;
241
        declare _cleanup
242
 
243
        ret
244
#endif
245
 
246
;-----------------------------------------
247
; required gcclib code
248
;-----------------------------------------
249
#ifdef L_memcpy
250
       declare  memcpy
251
       declare  __memcpy
252
 
253
        .weak memcpy
254
;;;
255
;;; void* memcpy(void*, const void*, size_t)
256
;;;
257
;;; D    = dst  Pmode
258
;;; 2,sp = src  Pmode
259
;;; 4,sp = size HImode (size_t)
260
;;;
261
#ifdef mc68hc12
262
        ldx     ARG(2),sp
263
        ldy     ARG(4),sp
264
        pshd
265
        xgdy
266
        lsrd
267
        bcc     Start
268
        movb    1,x+,1,y+
269
Start:
270
        beq     Done
271
Loop:
272
        movw    2,x+,2,y+
273
        dbne    d,Loop
274
Done:
275
        puld
276
        ret
277
#else
278
        xgdy
279
        tsx
280
        ldd     ARG(4),x
281
        ldx     ARG(2),x        ; SRC = X, DST = Y
282
        cpd     #0
283
        beq     End
284
        pshy
285
        inca                    ; Correction for the deca below
286
L0:
287
        psha                    ; Save high-counter part
288
L1:
289
        ldaa    0,x             ; Copy up to 256 bytes
290
        staa    0,y
291
        inx
292
        iny
293
        decb
294
        bne     L1
295
        pula
296
        deca
297
        bne     L0
298
        puly                    ; Restore Y to return the DST
299
End:
300
        xgdy
301
        ret
302
#endif
303
#endif
304
 
305
#ifdef L_memset
306
       declare  memset
307
       declare  __memset
308
;;;
309
;;; void* memset(void*, int value, size_t)
310
;;;
311
#ifndef __HAVE_SHORT_INT__
312
;;; D    = dst  Pmode
313
;;; 2,sp = src  SImode
314
;;; 6,sp = size HImode (size_t)
315
        val  = ARG(5)
316
        size = ARG(6)
317
#else
318
;;; D    = dst  Pmode
319
;;; 2,sp = src  SImode
320
;;; 6,sp = size HImode (size_t)
321
        val  = ARG(3)
322
        size = ARG(4)
323
#endif
324
#ifdef mc68hc12
325
        xgdx
326
        ldab    val,sp
327
        ldy     size,sp
328
        pshx
329
        beq     End
330
Loop:
331
        stab    1,x+
332
        dbne    y,Loop
333
End:
334
        puld
335
        ret
336
#else
337
        xgdx
338
        tsy
339
        ldab    val,y
340
        ldy     size,y          ; DST = X, CNT = Y
341
        beq     End
342
        pshx
343
L0:
344
        stab    0,x             ; Fill up to 256 bytes
345
        inx
346
        dey
347
        bne     L0
348
        pulx                    ; Restore X to return the DST
349
End:
350
        xgdx
351
        ret
352
#endif
353
#endif
354
 
355
#ifdef L_adddi3
356
        declare ___adddi3
357
 
358
        tsx
359
        xgdy
360
        ldd     ARG(8),x                ; Add LSB
361
        addd    ARG(16),x
362
        std     6,y             ; Save (carry preserved)
363
 
364
        ldd     ARG(6),x
365
        adcb    ARG(15),x
366
        adca    ARG(14),x
367
        std     4,y
368
 
369
        ldd     ARG(4),x
370
        adcb    ARG(13),x
371
        adca    ARG(12),x
372
        std     2,y
373
 
374
        ldd     ARG(2),x
375
        adcb    ARG(11),x               ; Add MSB
376
        adca    ARG(10),x
377
        std     0,y
378
 
379
        xgdy
380
        ret
381
#endif
382
 
383
#ifdef L_subdi3
384
        declare ___subdi3
385
 
386
        tsx
387
        xgdy
388
        ldd     ARG(8),x                ; Subtract LSB
389
        subd    ARG(16),x
390
        std     6,y                     ; Save, borrow preserved
391
 
392
        ldd     ARG(6),x
393
        sbcb    ARG(15),x
394
        sbca    ARG(14),x
395
        std     4,y
396
 
397
        ldd     ARG(4),x
398
        sbcb    ARG(13),x
399
        sbca    ARG(12),x
400
        std     2,y
401
 
402
        ldd     ARG(2),x                ; Subtract MSB
403
        sbcb    ARG(11),x
404
        sbca    ARG(10),x
405
        std     0,y
406
 
407
        xgdy                    ;
408
        ret
409
#endif
410
 
411
#ifdef L_notdi2
412
        declare ___notdi2
413
 
414
        tsy
415
        xgdx
416
        ldd     ARG(8),y
417
        coma
418
        comb
419
        std     6,x
420
 
421
        ldd     ARG(6),y
422
        coma
423
        comb
424
        std     4,x
425
 
426
        ldd     ARG(4),y
427
        coma
428
        comb
429
        std     2,x
430
 
431
        ldd     ARG(2),y
432
        coma
433
        comb
434
        std     0,x
435
        xgdx
436
        ret
437
#endif
438
 
439
#ifdef L_negsi2
440
        declare_near ___negsi2
441
 
442
        comb
443
        coma
444
        xgdx
445
        comb
446
        coma
447
        inx
448
        xgdx
449
        bne     done
450
        inx
451
done:
452
        rts
453
#endif
454
 
455
#ifdef L_one_cmplsi2
456
        declare_near ___one_cmplsi2
457
 
458
        comb
459
        coma
460
        xgdx
461
        comb
462
        coma
463
        xgdx
464
        rts
465
#endif
466
 
467
#ifdef L_ashlsi3
468
        declare_near ___ashlsi3
469
 
470
        xgdy
471
        clra
472
        andb    #0x1f
473
        xgdy
474
        beq     Return
475
Loop:
476
        lsld
477
        xgdx
478
        rolb
479
        rola
480
        xgdx
481
        dey
482
        bne     Loop
483
Return:
484
        rts
485
#endif
486
 
487
#ifdef L_ashrsi3
488
        declare_near ___ashrsi3
489
 
490
        xgdy
491
        clra
492
        andb    #0x1f
493
        xgdy
494
        beq     Return
495
Loop:
496
        xgdx
497
        asra
498
        rorb
499
        xgdx
500
        rora
501
        rorb
502
        dey
503
        bne     Loop
504
Return:
505
        rts
506
#endif
507
 
508
#ifdef L_lshrsi3
509
        declare_near ___lshrsi3
510
 
511
        xgdy
512
        clra
513
        andb    #0x1f
514
        xgdy
515
        beq     Return
516
Loop:
517
        xgdx
518
        lsrd
519
        xgdx
520
        rora
521
        rorb
522
        dey
523
        bne     Loop
524
Return:
525
        rts
526
#endif
527
 
528
#ifdef L_lshrhi3
529
        declare_near ___lshrhi3
530
 
531
        cpx     #16
532
        bge     Return_zero
533
        cpx     #0
534
        beq     Return
535
Loop:
536
        lsrd
537
        dex
538
        bne     Loop
539
Return:
540
        rts
541
Return_zero:
542
        clra
543
        clrb
544
        rts
545
#endif
546
 
547
#ifdef L_lshlhi3
548
        declare_near ___lshlhi3
549
 
550
        cpx     #16
551
        bge     Return_zero
552
        cpx     #0
553
        beq     Return
554
Loop:
555
        lsld
556
        dex
557
        bne     Loop
558
Return:
559
        rts
560
Return_zero:
561
        clra
562
        clrb
563
        rts
564
#endif
565
 
566
#ifdef L_rotrhi3
567
        declare_near ___rotrhi3
568
 
569
___rotrhi3:
570
        xgdx
571
        clra
572
        andb    #0x0f
573
        xgdx
574
        beq     Return
575
Loop:
576
        tap
577
        rorb
578
        rora
579
        dex
580
        bne     Loop
581
Return:
582
        rts
583
#endif
584
 
585
#ifdef L_rotlhi3
586
        declare_near ___rotlhi3
587
 
588
___rotlhi3:
589
        xgdx
590
        clra
591
        andb    #0x0f
592
        xgdx
593
        beq     Return
594
Loop:
595
        asrb
596
        rolb
597
        rola
598
        rolb
599
        dex
600
        bne     Loop
601
Return:
602
        rts
603
#endif
604
 
605
#ifdef L_ashrhi3
606
        declare_near ___ashrhi3
607
 
608
        cpx     #16
609
        bge     Return_minus_1_or_zero
610
        cpx     #0
611
        beq     Return
612
Loop:
613
        asra
614
        rorb
615
        dex
616
        bne     Loop
617
Return:
618
        rts
619
Return_minus_1_or_zero:
620
        clrb
621
        tsta
622
        bpl     Return_zero
623
        comb
624
Return_zero:
625
        tba
626
        rts
627
#endif
628
 
629
#ifdef L_ashrqi3
630
        declare_near ___ashrqi3
631
 
632
        cmpa    #8
633
        bge     Return_minus_1_or_zero
634
        tsta
635
        beq     Return
636
Loop:
637
        asrb
638
        deca
639
        bne     Loop
640
Return:
641
        rts
642
Return_minus_1_or_zero:
643
        clrb
644
        tstb
645
        bpl     Return_zero
646
        coma
647
Return_zero:
648
        tab
649
        rts
650
#endif
651
 
652
#ifdef L_lshlqi3
653
        declare_near ___lshlqi3
654
 
655
        cmpa    #8
656
        bge     Return_zero
657
        tsta
658
        beq     Return
659
Loop:
660
        lslb
661
        deca
662
        bne     Loop
663
Return:
664
        rts
665
Return_zero:
666
        clrb
667
        rts
668
#endif
669
 
670
#ifdef L_divmodhi4
671
#ifndef mc68hc12
672
/* 68HC12 signed divisions are generated inline (idivs).  */
673
 
674
        declare_near __divmodhi4
675
 
676
;
677
;; D = numerator
678
;; X = denominator
679
;;
680
;; Result:      D = D / X
681
;;              X = D % X
682
;;
683
        tsta
684
        bpl     Numerator_pos
685
        comb                    ; D = -D <=> D = (~D) + 1
686
        coma
687
        xgdx
688
        inx
689
        tsta
690
        bpl     Numerator_neg_denominator_pos
691
Numerator_neg_denominator_neg:
692
        comb                    ; X = -X
693
        coma
694
        addd    #1
695
        xgdx
696
        idiv
697
        coma
698
        comb
699
        xgdx                    ; Remainder <= 0 and result >= 0
700
        inx
701
        rts
702
 
703
Numerator_pos_denominator_pos:
704
        xgdx
705
        idiv
706
        xgdx                    ; Both values are >= 0
707
        rts
708
 
709
Numerator_pos:
710
        xgdx
711
        tsta
712
        bpl     Numerator_pos_denominator_pos
713
Numerator_pos_denominator_neg:
714
        coma                    ; X = -X
715
        comb
716
        xgdx
717
        inx
718
        idiv
719
        xgdx                    ; Remainder >= 0 but result <= 0
720
        coma
721
        comb
722
        addd    #1
723
        rts
724
 
725
Numerator_neg_denominator_pos:
726
        xgdx
727
        idiv
728
        coma                    ; One value is > 0 and the other < 0
729
        comb                    ; Change the sign of result and remainder
730
        xgdx
731
        inx
732
        coma
733
        comb
734
        addd    #1
735
        rts
736
#endif /* !mc68hc12 */
737
#endif
738
 
739
#ifdef L_mulqi3
740
        declare_near ___mulqi3
741
 
742
;
743
; short __mulqi3(signed char a, signed char b);
744
;
745
;       signed char a   -> register A
746
;       signed char b   -> register B
747
;
748
; returns the signed result of A * B in register D.
749
;
750
        tsta
751
        bmi     A_neg
752
        tstb
753
        bmi     B_neg
754
        mul
755
        rts
756
B_neg:
757
        negb
758
        bra     A_or_B_neg
759
A_neg:
760
        nega
761
        tstb
762
        bmi     AB_neg
763
A_or_B_neg:
764
        mul
765
        coma
766
        comb
767
        addd    #1
768
        rts
769
AB_neg:
770
        negb
771
        mul
772
        rts
773
#endif
774
 
775
#ifdef L_mulhi3
776
        declare_near ___mulhi3
777
 
778
;
779
;
780
;  unsigned short ___mulhi3(unsigned short a, unsigned short b)
781
;
782
;       a = register D
783
;       b = register X
784
;
785
#ifdef mc68hc12
786
        pshx                    ; Preserve X
787
        exg     x,y
788
        emul
789
        exg     x,y
790
        pulx
791
        rts
792
#else
793
#ifdef NO_TMP
794
        ;
795
        ; 16-bit multiplication without temp memory location.
796
        ; (smaller but slower)
797
        ;
798
        pshx                    ; (4)
799
        ins                     ; (3)
800
        pshb                    ; (3)
801
        psha                    ; (3)
802
        pshx                    ; (4)
803
        pula                    ; (4)
804
        pulx                    ; (5)
805
        mul                     ; (10) B.high * A.low
806
        xgdx                    ; (3)
807
        mul                     ; (10) B.low * A.high
808
        abx                     ; (3)
809
        pula                    ; (4)
810
        pulb                    ; (4)
811
        mul                     ; (10) B.low * A.low
812
        pshx                    ; (4)
813
        tsx                     ; (3)
814
        adda    1,x             ; (4)
815
        pulx                    ; (5)
816
        rts                     ; (5) 20 bytes
817
                                ; ---
818
                                ; 91 cycles
819
#else
820
        stx     *_.tmp          ; (4)
821
        pshb                    ; (3)
822
        ldab    *_.tmp+1        ; (3)
823
        mul                     ; (10) A.high * B.low
824
        ldaa    *_.tmp          ; (3)
825
        stab    *_.tmp          ; (3)
826
        pulb                    ; (4)
827
        pshb                    ; (4)
828
        mul                     ; (10) A.low * B.high
829
        addb    *_.tmp          ; (4)
830
        stab    *_.tmp          ; (3)
831
        ldaa    *_.tmp+1        ; (3)
832
        pulb                    ; (4)
833
        mul                     ; (10) A.low * B.low
834
        adda    *_.tmp          ; (4)
835
        rts                     ; (5) 24/32 bytes
836
                                ; 77/85 cycles
837
#endif
838
#endif
839
#endif
840
 
841
#ifdef L_mulhi32
842
 
843
;
844
;
845
;  unsigned long __mulhi32(unsigned short a, unsigned short b)
846
;
847
;       a = register D
848
;       b = value on stack
849
;
850
;       +---------------+
851
;       |  B low        | <- 7,x
852
;       +---------------+
853
;       |  B high       | <- 6,x
854
;       +---------------+
855
;       |  PC low       |
856
;       +---------------+
857
;       |  PC high      |
858
;       +---------------+
859
;       |  Tmp low      |
860
;       +---------------+
861
;       |  Tmp high     |
862
;       +---------------+
863
;       |  A low        |
864
;       +---------------+
865
;       |  A high       |
866
;       +---------------+  <- 0,x
867
;
868
;
869
;          5,x
870
;         4,x
871
;            2,x
872
;          1,x
873
;         0,x
874
;
875
        declare_near    __mulhi32
876
 
877
#ifdef mc68hc12
878
        ldy     2,sp
879
        emul
880
        exg     x,y
881
        rts
882
#else
883
        pshx                    ; Room for temp value
884
        pshb
885
        psha
886
        tsx
887
        ldab    6,x
888
        mul
889
        xgdy                    ; A.high * B.high
890
        ldab    7,x
891
        pula
892
        mul                     ; A.high * B.low
893
        std     2,x
894
        ldaa    1,x
895
        ldab    6,x
896
        mul                     ; A.low * B.high
897
        addd    2,x
898
        stab    2,x
899
        tab
900
        aby
901
        bcc     N
902
        ldab    #0xff
903
        aby
904
        iny
905
N:
906
        ldab    7,x
907
        pula
908
        mul                     ; A.low * B.low
909
        adda    2,x
910
        pulx                    ; Drop temp location
911
        pshy                    ; Put high part in X
912
        pulx
913
        bcc     Ret
914
        inx
915
Ret:
916
        rts
917
#endif
918
#endif
919
 
920
#ifdef L_mulsi3
921
 
922
;
923
;          8,y
924
;         6,y
925
;            4,y
926
;                 2,y
927
;          0,y
928
;
929
; D,X   -> A
930
; Stack -> B
931
;
932
; The result is:
933
;
934
;       (((A.low * B.high) + (A.high * B.low)) << 16) + (A.low * B.low)
935
;
936
;
937
;
938
 
939
        declare __mulsi3
940
 
941
#ifdef mc68hc12
942
        pshd                            ; Save A.low
943
        ldy     ARG(4),sp
944
        emul                            ; A.low * B.high
945
        ldy     ARG(6),sp
946
        exg     x,d
947
        emul                            ; A.high * B.low
948
        leax    d,x
949
        ldy     ARG(6),sp
950
        puld
951
        emul                            ; A.low * B.low
952
        exg     d,y
953
        leax    d,x
954
        exg     d,y
955
        ret
956
#else
957
B_low   =       ARG(8)
958
B_high  =       ARG(6)
959
A_low   =       0
960
A_high  =       2
961
        pshx
962
        pshb
963
        psha
964
        tsy
965
;
966
; If B.low is 0, optimize into: (A.low * B.high) << 16
967
;
968
        ldd     B_low,y
969
        beq     B_low_zero
970
;
971
; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
972
;
973
        cpx     #0
974
        beq     A_high_zero
975
        bsr     ___mulhi3               ; A.high * B.low
976
;
977
; If A.low is 0, optimize into: (A.high * B.low) << 16
978
;
979
        ldx     A_low,y
980
        beq     A_low_zero              ; X = 0, D = A.high * B.low
981
        std     2,y
982
;
983
; If B.high is 0, we can avoid the (A.low * B.high) << 16 term.
984
;
985
        ldd     B_high,y
986
        beq     B_high_zero
987
        bsr     ___mulhi3               ; A.low * B.high
988
        addd    2,y
989
        std     2,y
990
;
991
; Here, we know that A.low and B.low are not 0.
992
;
993
B_high_zero:
994
        ldd     B_low,y                 ; A.low is on the stack
995
        bsr     __mulhi32               ; A.low * B.low
996
        xgdx
997
        tsy                             ; Y was clobbered, get it back
998
        addd    2,y
999
A_low_zero:                             ; See A_low_zero_non_optimized below
1000
        xgdx
1001
Return:
1002
        ins
1003
        ins
1004
        ins
1005
        ins
1006
        ret
1007
;
1008
;
1009
; A_low_zero_non_optimized:
1010
;
1011
; At this step, X = 0 and D = (A.high * B.low)
1012
; Optimize into: (A.high * B.low) << 16
1013
;
1014
;       xgdx
1015
;       clra                    ; Since X was 0, clearing D is superfuous.
1016
;       clrb
1017
;       bra     Return
1018
; ----------------
1019
; B.low == 0, the result is:    (A.low * B.high) << 16
1020
;
1021
; At this step:
1022
;   D = B.low                           = 0
1023
;   X = A.high                          ?
1024
;       A.low is at A_low,y             ?
1025
;       B.low is at B_low,y             ?
1026
;
1027
B_low_zero:
1028
        ldd     A_low,y
1029
        beq     Zero1
1030
        ldx     B_high,y
1031
        beq     Zero2
1032
        bsr     ___mulhi3
1033
Zero1:
1034
        xgdx
1035
Zero2:
1036
        clra
1037
        clrb
1038
        bra     Return
1039
; ----------------
1040
; A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
1041
;
1042
; At this step:
1043
;   D = B.low                           != 0
1044
;   X = A.high                          = 0
1045
;       A.low is at A_low,y             ?
1046
;       B.low is at B_low,y             ?
1047
;
1048
A_high_zero:
1049
        ldd     A_low,y         ; A.low
1050
        beq     Zero1
1051
        ldx     B_high,y        ; B.high
1052
        beq     A_low_B_low
1053
        bsr     ___mulhi3
1054
        std     2,y
1055
        bra     B_high_zero     ; Do the (A.low * B.low) and the add.
1056
 
1057
; ----------------
1058
; A.high and B.high are 0 optimize into: (A.low * B.low)
1059
;
1060
; At this step:
1061
;   D = B.high                          = 0
1062
;   X = A.low                           != 0
1063
;       A.low is at A_low,y             != 0
1064
;       B.high is at B_high,y           = 0
1065
;
1066
A_low_B_low:
1067
        ldd     B_low,y                 ; A.low is on the stack
1068
        bsr     __mulhi32
1069
        bra     Return
1070
#endif
1071
#endif
1072
 
1073
#ifdef L_map_data
1074
 
1075
        .sect   .install2,"ax",@progbits
1076
        .globl  __map_data_section
1077
        .globl __data_image
1078
#ifdef mc68hc12
1079
        .globl __data_section_size
1080
#endif
1081
__map_data_section:
1082
#ifdef mc68hc12
1083
        ldx     #__data_image
1084
        ldy     #__data_section_start
1085
        ldd     #__data_section_size
1086
        beq     Done
1087
Loop:
1088
        movb    1,x+,1,y+
1089
        dbne    d,Loop
1090
#else
1091
        ldx     #__data_image
1092
        ldy     #__data_section_start
1093
        bra     Start_map
1094
Loop:
1095
        ldaa    0,x
1096
        staa    0,y
1097
        inx
1098
        iny
1099
Start_map:
1100
        cpx     #__data_image_end
1101
        blo     Loop
1102
#endif
1103
Done:
1104
 
1105
#endif
1106
 
1107
#ifdef L_init_bss
1108
 
1109
        .sect   .install2,"ax",@progbits
1110
        .globl  __init_bss_section
1111
 
1112
__init_bss_section:
1113
        ldd     #__bss_size
1114
        beq     Done
1115
        ldx     #__bss_start
1116
Loop:
1117
#ifdef mc68hc12
1118
        clr     1,x+
1119
        dbne    d,Loop
1120
#else
1121
        clr     0,x
1122
        inx
1123
        subd    #1
1124
        bne     Loop
1125
#endif
1126
Done:
1127
 
1128
#endif
1129
 
1130
#ifdef L_ctor
1131
 
1132
; End of constructor table
1133
        .sect   .install3,"ax",@progbits
1134
        .globl  __do_global_ctors
1135
 
1136
__do_global_ctors:
1137
        ; Start from the end - sizeof(void*)
1138
        ldx     #__CTOR_END__-2
1139
ctors_loop:
1140
        cpx     #__CTOR_LIST__
1141
        blo     ctors_done
1142
        pshx
1143
        ldx     0,x
1144
        jsr     0,x
1145
        pulx
1146
        dex
1147
        dex
1148
        bra     ctors_loop
1149
ctors_done:
1150
 
1151
#endif
1152
 
1153
#ifdef L_dtor
1154
 
1155
        .sect   .fini3,"ax",@progbits
1156
        .globl  __do_global_dtors
1157
 
1158
;;
1159
;; This piece of code is inserted in the _exit() code by the linker.
1160
;;
1161
__do_global_dtors:
1162
        pshb    ; Save exit code
1163
        psha
1164
        ldx     #__DTOR_LIST__
1165
dtors_loop:
1166
        cpx     #__DTOR_END__
1167
        bhs     dtors_done
1168
        pshx
1169
        ldx     0,x
1170
        jsr     0,x
1171
        pulx
1172
        inx
1173
        inx
1174
        bra     dtors_loop
1175
dtors_done:
1176
        pula    ; Restore exit code
1177
        pulb
1178
 
1179
#endif
1180
 
1181
#ifdef L_far_tramp
1182
#ifdef mc68hc12
1183
        .sect   .tramp,"ax",@progbits
1184
        .globl  __far_trampoline
1185
 
1186
;; This is a trampoline used by the linker to invoke a function
1187
;; using rtc to return and being called with jsr/bsr.
1188
;; The trampoline generated is:
1189
;;
1190
;;      foo_tramp:
1191
;;              ldy     #foo
1192
;;              call    __far_trampoline,page(foo)
1193
;;
1194
;; The linker transforms:
1195
;;
1196
;;              jsr     foo
1197
;;
1198
;; into
1199
;;              jsr     foo_tramp
1200
;;
1201
;; The linker generated trampoline and _far_trampoline must be in
1202
;; non-banked memory.
1203
;;
1204
__far_trampoline:
1205
        movb    0,sp, 2,sp      ; Copy page register below the caller's return
1206
        leas    2,sp            ; address.
1207
        jmp     0,y             ; We have a 'call/rtc' stack layout now
1208
                                ; and can jump to the far handler
1209
                                ; (whose memory bank is mapped due to the
1210
                                ; call to the trampoline).
1211
#endif
1212
 
1213
#ifdef mc68hc11
1214
        .sect   .tramp,"ax",@progbits
1215
        .globl __far_trampoline
1216
 
1217
;; Trampoline generated by gcc for 68HC11:
1218
;;
1219
;;      pshb
1220
;;      ldab    #%page(func)
1221
;;      ldy     #%addr(func)
1222
;;      jmp     __far_trampoline
1223
;;
1224
__far_trampoline:
1225
        psha                            ; (2) Save function parameter (high)
1226
        ;; 
1227
        psha                            ; (2)
1228
        ;; 
1229
        pshx                            ; (4)
1230
        tsx                             ; (3)
1231
        ldab    4,x                     ; (4) Restore function parameter (low)
1232
        ldaa    2,x                     ; (4) Get saved page number
1233
        staa    4,x                     ; (4) Save it below return PC
1234
        pulx                            ; (5)
1235
        pula                            ; (3)
1236
        pula                            ; (3) Restore function parameter (high)
1237
        jmp     0,y                     ; (4)
1238
#endif
1239
#endif
1240
 
1241
#ifdef L_call_far
1242
#ifdef mc68hc11
1243
        .sect   .tramp,"ax",@progbits
1244
        .globl __call_a16
1245
        .globl __call_a32
1246
;;
1247
;; The call methods are used for 68HC11 to support memory bank switching.
1248
;; Every far call is redirected to these call methods.  Its purpose is to:
1249
;;
1250
;;  1/ Save the current page on the stack (1 byte to follow 68HC12 call frame)
1251
;;  2/ Install the new page
1252
;;  3/ Jump to the real function
1253
;;
1254
;; The page switching (get/save) is board dependent.  The default provided
1255
;; here does nothing (just create the appropriate call frame).
1256
;;
1257
;; Call sequence (10 bytes, 13 cycles):
1258
;;
1259
;;      ldx #page                       ; (3)
1260
;;      ldy #func                       ; (4)
1261
;;      jsr __call_a16                  ; (6)
1262
;;
1263
;; Call trampoline (11 bytes, 19 cycles):
1264
;;
1265
__call_a16:
1266
        ;; xgdx                         ; (3)
1267
        ;;      ; (3) ldaa _current_page
1268
        psha                            ; (2)
1269
        ;;      ; (4) staa _current_page
1270
        ;; xgdx                         ; (3)
1271
        jmp 0,y                         ; (4)
1272
 
1273
;;
1274
;; Call sequence (10 bytes, 14 cycles):
1275
;;
1276
;;      pshb                            ; (2)
1277
;;      ldab #page                      ; (2)
1278
;;      ldy  #func                      ; (4)
1279
;;      jsr __call_a32                  ; (6)
1280
;;
1281
;; Call trampoline (87 bytes, 57 cycles):
1282
;;
1283
__call_a32:
1284
        pshx                            ; (4)
1285
        psha                            ; (2)
1286
        ;;      ; (3) ldaa _current_page
1287
        psha                            ; (2)
1288
        ;;      ; (4) staa _current_page
1289
        tsx                             ; (3)
1290
        ldab    6,x                     ; (4) Restore function parameter
1291
        ldaa    5,x                     ; (4) Move PC return at good place
1292
        staa    6,x                     ; (4)
1293
        ldaa    4,x                     ; (4)
1294
        staa    5,x                     ; (4)
1295
        pula                            ; (3)
1296
        staa    4,x                     ; (4)
1297
        pula                            ; (3)
1298
        pulx                            ; (5)
1299
        jmp     0,y                     ; (4)
1300
#endif
1301
#endif
1302
 
1303
#ifdef L_return_far
1304
#ifdef mc68hc11
1305
        .sect   .tramp,"ax",@progbits
1306
       .globl __return_void
1307
       .globl __return_16
1308
       .globl __return_32
1309
 
1310
__return_void:
1311
        ;; pulb
1312
        ;;  (Board specific)
1313
        ;; rts
1314
__return_16:
1315
        ;; xgdx
1316
        ;; pulb
1317
        ;;  (Board specific)
1318
        ;; xgdx
1319
        ;; rts
1320
__return_32:
1321
        ;; xgdy
1322
        ;; pulb
1323
        ;;  (Board specific)
1324
        ;; xgdy
1325
        ;; rts
1326
        ins
1327
        rts
1328
#endif
1329
#endif
1330
.Lend:
1331
;-----------------------------------------
1332
; end required gcclib code
1333
;-----------------------------------------

powered by: WebSVN 2.1.0

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