aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/m68hc11/larith.asm
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/m68hc11/larith.asm')
-rw-r--r--gcc/config/m68hc11/larith.asm255
1 files changed, 220 insertions, 35 deletions
diff --git a/gcc/config/m68hc11/larith.asm b/gcc/config/m68hc11/larith.asm
index e75772964f1..6ec9ba57f4d 100644
--- a/gcc/config/m68hc11/larith.asm
+++ b/gcc/config/m68hc11/larith.asm
@@ -1,5 +1,5 @@
-/* libgcc1 routines for M68HC11.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* libgcc1 routines for M68HC11 & M68HC12.
+ Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -47,35 +47,74 @@ NAME: .word 0; \
/* Pseudo hard registers used by gcc.
They must be located in page0.
They will normally appear at the end of .page0 section. */
+#ifdef mc68hc12
+ .sect .bss
+#else
.sect .page0
- .globl _.tmp,_.frame
+#endif
+ .globl _.tmp
.globl _.z,_.xy
REG(_.tmp)
REG(_.z)
REG(_.xy)
-REG(_.frame)
#endif
-#ifdef L_regs_d1_8
-/* Pseudo hard registers used by gcc.
- They must be located in page0.
- They will normally appear at the end of .page0 section. */
+#ifdef L_regs_frame
+#ifdef mc68hc12
+ .sect .bss
+#else
.sect .page0
- .globl _.d1,_.d2,_.d3,_.d4,_.d5,_.d6
- .globl _.d7,_.d8
+#endif
+ .globl _.frame
+REG(_.frame)
+#endif
+
+#ifdef L_regs_d1_2
+#ifdef mc68hc12
+ .sect .bss
+#else
+ .sect .page0
+#endif
+ .globl _.d1,_.d2
REG(_.d1)
REG(_.d2)
+#endif
+
+#ifdef L_regs_d3_4
+#ifdef mc68hc12
+ .sect .bss
+#else
+ .sect .page0
+#endif
+ .globl _.d3,_.d4
REG(_.d3)
REG(_.d4)
+#endif
+
+#ifdef L_regs_d5_6
+#ifdef mc68hc12
+ .sect .bss
+#else
+ .sect .page0
+#endif
+ .globl _.d5,_.d6
REG(_.d5)
REG(_.d6)
+#endif
+
+#ifdef L_regs_d7_8
+#ifdef mc68hc12
+ .sect .bss
+#else
+ .sect .page0
+#endif
+ .globl _.d7,_.d8
REG(_.d7)
REG(_.d8)
-
#endif
-#ifdef L_regs_d8_16
+#ifdef L_regs_d9_16
/* Pseudo hard registers used by gcc.
They must be located in page0.
They will normally appear at the end of .page0 section. */
@@ -97,7 +136,11 @@ REG(_.d16)
/* Pseudo hard registers used by gcc.
They must be located in page0.
They will normally appear at the end of .page0 section. */
+#ifdef mc68hc12
+ .sect .bss
+#else
.sect .page0
+#endif
.globl _.d17,_.d18,_.d19,_.d20,_.d21,_.d22
.globl _.d23,_.d24,_.d25,_.d26,_.d27,_.d28
.globl _.d29,_.d30,_.d31,_.d32
@@ -136,13 +179,26 @@ __premain:
;;
;; Exit operation. Just loop forever and wait for interrupts.
;; (no other place to go)
+;; This operation is split in several pieces collected together by
+;; the linker script. This allows to support destructors at the
+;; exit stage while not impacting program sizes when there is no
+;; destructors.
;;
- .sect .text
- .globl _exit
+;; _exit:
+;; *(.fini0) /* Beginning of finish code (_exit symbol). */
+;; *(.fini1) /* Place holder for applications. */
+;; *(.fini2) /* C++ destructors. */
+;; *(.fini3) /* Place holder for applications. */
+;; *(.fini4) /* Runtime exit. */
+;;
+ .sect .fini0,"ax",@progbits
+ .globl _exit
.globl exit
.weak exit
exit:
_exit:
+
+ .sect .fini4,"ax",@progbits
fatal:
cli
wai
@@ -157,8 +213,12 @@ fatal:
.globl abort
abort:
ldd #255 ;
+#ifdef mc68hc12
+ trap #0x30
+#else
.byte 0xCD ; Generate an illegal instruction trap
.byte 0x03 ; The simulator catches this and stops.
+#endif
jmp _exit
#endif
@@ -189,6 +249,23 @@ _cleanup:
;;;
__memcpy:
memcpy:
+#ifdef mc68hc12
+ ldx 2,sp
+ ldy 4,sp
+ pshd
+ xgdy
+ lsrd
+ bcc Start
+ movb 1,x+,1,y+
+Start:
+ beq Done
+Loop:
+ movw 2,x+,2,y+
+ dbne d,Loop
+Done:
+ puld
+ rts
+#else
xgdy
tsx
ldd 4,x
@@ -214,6 +291,7 @@ End:
xgdy
rts
#endif
+#endif
#ifdef L_memset
.sect .text
@@ -237,6 +315,19 @@ End:
#endif
__memset:
memset:
+#ifdef mc68hc12
+ xgdx
+ ldab val,sp
+ ldy size,sp
+ pshx
+ beq End
+Loop:
+ stab 1,x+
+ dbne y,Loop
+End:
+ puld
+ rts
+#else
xgdx
tsy
ldab val,y
@@ -253,6 +344,7 @@ End:
xgdx
rts
#endif
+#endif
#ifdef L_adddi3
.sect .text
@@ -260,29 +352,28 @@ End:
___adddi3:
tsx
- tsy
pshb
psha
ldd 8,x
- addd 16,y
+ addd 16,x
pshb
psha
ldd 6,x
- adcb 15,y
- adca 14,y
+ adcb 15,x
+ adca 14,x
pshb
psha
ldd 4,x
- adcb 13,y
- adca 12,y
+ adcb 13,x
+ adca 12,x
pshb
psha
ldd 2,x
- adcb 11,y
- adca 10,y
+ adcb 11,x
+ adca 10,x
tsx
ldy 6,x
@@ -303,29 +394,28 @@ ___adddi3:
___subdi3:
tsx
- tsy
pshb
psha
ldd 8,x
- subd 16,y
+ subd 16,x
pshb
psha
ldd 6,x
- sbcb 15,y
- sbca 14,y
+ sbcb 15,x
+ sbca 14,x
pshb
psha
ldd 4,x
- sbcb 13,y
- sbca 12,y
+ sbcb 13,x
+ sbca 12,x
pshb
psha
ldd 2,x
- sbcb 11,y
- sbca 10,y
+ sbcb 11,x
+ sbca 10,x
tsx
ldy 6,x
@@ -582,6 +672,9 @@ Return_zero:
#endif
#ifdef L_divmodhi4
+#ifndef mc68hc12
+/* 68HC12 signed divisions are generated inline (idivs). */
+
.sect .text
.globl __divmodhi4
@@ -646,6 +739,7 @@ Numerator_neg_denominator_pos:
comb
addd #1
rts
+#endif /* !mc68hc12 */
#endif
#ifdef L_mulqi3
@@ -681,7 +775,6 @@ A_or_B_neg:
addd #1
rts
AB_neg:
- nega
negb
mul
rts
@@ -699,6 +792,13 @@ AB_neg:
; b = register X
;
___mulhi3:
+#ifdef mc68hc12
+ pshx ; Preserve X
+ exg x,y
+ emul
+ exg x,y
+ pulx
+#else
stx *_.tmp
pshb
ldab *_.tmp+1
@@ -714,6 +814,7 @@ ___mulhi3:
pulb
mul ; A.low * B.low
adda *_.tmp
+#endif
rts
#endif
@@ -750,6 +851,11 @@ ___mulhi3:
; <A-high> 0,x
;
__mulhi32:
+#ifdef mc68hc12
+ ldy 2,sp
+ emul
+ exg x,y
+#else
pshb
psha
tsx
@@ -781,6 +887,7 @@ N:
Ret:
pshy
pulx
+#endif
rts
#endif
@@ -806,11 +913,27 @@ Ret:
;
;
+__mulsi3:
+#ifdef mc68hc12
+ pshd ; Save A.low
+ ldy 4,sp
+ emul ; A.low * B.high
+ ldy 6,sp
+ exg x,d
+ emul ; A.high * B.low
+ leax d,x
+ ldy 6,sp
+ puld
+ emul ; A.low * B.low
+ exg d,y
+ leax d,x
+ exg d,y
+ rts
+#else
B_low = 8
B_high = 6
A_low = 0
A_high = 2
-__mulsi3:
pshx
pshb
psha
@@ -921,10 +1044,11 @@ A_low_B_low:
bsr __mulhi32
bra Return
#endif
+#endif
#ifdef L_map_data
- .sect .install3,"ax",@progbits
+ .sect .install2,"ax",@progbits
.globl __map_data_section
__map_data_section:
@@ -933,6 +1057,10 @@ __map_data_section:
ldx #__data_image
ldy #__data_section_start
Loop:
+#ifdef mc68hc12
+ movb 1,x+,1,y+
+ dbne d,Loop
+#else
psha
ldaa 0,x
staa 0,y
@@ -941,13 +1069,14 @@ Loop:
iny
subd #1
bne Loop
+#endif
Done:
#endif
#ifdef L_init_bss
- .sect .install3,"ax",@progbits
+ .sect .install2,"ax",@progbits
.globl __init_bss_section
__init_bss_section:
@@ -955,14 +1084,70 @@ __init_bss_section:
beq Done
ldx #__bss_start
Loop:
+#ifdef mc68hc12
+ clr 1,x+
+ dbne d,Loop
+#else
clr 0,x
inx
subd #1
bne Loop
+#endif
Done:
#endif
-
+
+#ifdef L_ctor
+
+; End of constructor table
+ .sect .install3,"ax",@progbits
+ .globl __do_global_ctors
+
+__do_global_ctors:
+ ; Start from the end - sizeof(void*)
+ ldx #__CTOR_END__-2
+ctors_loop:
+ cpx #__CTOR_LIST__
+ blt ctors_done
+ pshx
+ ldx 0,x
+ jsr 0,x
+ pulx
+ dex
+ dex
+ bra ctors_loop
+ctors_done:
+
+#endif
+
+#ifdef L_dtor
+
+ .sect .fini3,"ax",@progbits
+ .globl __do_global_dtors
+
+;;
+;; This piece of code is inserted in the _exit() code by the linker.
+;;
+__do_global_dtors:
+ pshb ; Save exit code
+ psha
+ ldx #__DTOR_LIST__
+dtors_loop:
+ cpx #__DTOR_END__
+ bge dtors_done
+ pshx
+ ldx 0,x
+ jsr 0,x
+ pulx
+ inx
+ inx
+ bra dtors_loop
+dtors_done:
+ pula ; Restore exit code
+ pulb
+
+#endif
+
;-----------------------------------------
; end required gcclib code
;-----------------------------------------