📄 larith.asm
字号:
/* libgcc routines for M68HC11 & M68HC12. Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2, or (at your option) anylater version.In addition to the permissions in the GNU General Public License, theFree Software Foundation gives you unlimited permission to link thecompiled version of this file with other programs, and to distributethose programs without any restriction coming from the use of thisfile. (The General Public License restrictions do apply in otherrespects; for example, they cover modification of the file, anddistribution when not linked into another program.)This file is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. *//* As a special exception, if you link this library with other files, some of which are compiled with GCC, to produce an executable, this library does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ .file "larith.asm" .sect .text #define REG(NAME) \NAME: .word 0; \ .type NAME,@object ; \ .size NAME,2#ifdef L_regs_min/* 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 _.tmp .globl _.z,_.xyREG(_.tmp)REG(_.z)REG(_.xy)#endif#ifdef L_regs_frame#ifdef mc68hc12 .sect .bss#else .sect .page0#endif .globl _.frameREG(_.frame)#endif#ifdef L_regs_d1_2#ifdef mc68hc12 .sect .bss#else .sect .page0#endif .globl _.d1,_.d2REG(_.d1)REG(_.d2)#endif#ifdef L_regs_d3_4#ifdef mc68hc12 .sect .bss#else .sect .page0#endif .globl _.d3,_.d4REG(_.d3)REG(_.d4)#endif#ifdef L_regs_d5_6#ifdef mc68hc12 .sect .bss#else .sect .page0#endif .globl _.d5,_.d6REG(_.d5)REG(_.d6)#endif#ifdef L_regs_d7_8#ifdef mc68hc12 .sect .bss#else .sect .page0#endif .globl _.d7,_.d8REG(_.d7)REG(_.d8)#endif#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. */ .sect .page0 .globl _.d9,_.d10,_.d11,_.d12,_.d13,_.d14 .globl _.d15,_.d16REG(_.d9)REG(_.d10)REG(_.d11)REG(_.d12)REG(_.d13)REG(_.d14)REG(_.d15)REG(_.d16)#endif#ifdef L_regs_d17_32/* 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,_.d32REG(_.d17)REG(_.d18)REG(_.d19)REG(_.d20)REG(_.d21)REG(_.d22)REG(_.d23)REG(_.d24)REG(_.d25)REG(_.d26)REG(_.d27)REG(_.d28)REG(_.d29)REG(_.d30)REG(_.d31)REG(_.d32)#endif#ifdef L_premain;;;; Specific initialization for 68hc11 before the main.;; Nothing special for a generic routine; Just enable interrupts.;; .sect .text .globl __premain__premain: clra tap ; Clear both I and X. rts#endif#ifdef L__exit;;;; 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.;;;; _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 exitexit:_exit: .sect .fini4,"ax",@progbitsfatal: cli wai bra fatal#endif#ifdef L_abort;;;; Abort operation. This is defined for the GCC testsuite.;; .sect .text .globl abortabort: 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 #ifdef L_cleanup;;;; Cleanup operation used by exit().;; .sect .text .globl _cleanup_cleanup: rts#endif;-----------------------------------------; required gcclib code;-----------------------------------------#ifdef L_memcpy .sect .text .weak memcpy .globl memcpy .globl __memcpy;;;;;; void* memcpy(void*, const void*, size_t);;; ;;; D = dst Pmode;;; 2,sp = src Pmode;;; 4,sp = size HImode (size_t);;; __memcpy:memcpy:#ifdef mc68hc12 ldx 2,sp ldy 4,sp pshd xgdy lsrd bcc Start movb 1,x+,1,y+Start: beq DoneLoop: movw 2,x+,2,y+ dbne d,LoopDone: puld rts#else xgdy tsx ldd 4,x ldx 2,x ; SRC = X, DST = Y cpd #0 beq End pshy inca ; Correction for the deca belowL0: psha ; Save high-counter partL1: ldaa 0,x ; Copy up to 256 bytes staa 0,y inx iny decb bne L1 pula deca bne L0 puly ; Restore Y to return the DSTEnd: xgdy rts#endif#endif#ifdef L_memset .sect .text .globl memset .globl __memset;;;;;; void* memset(void*, int value, size_t);;; #ifndef __HAVE_SHORT_INT__;;; D = dst Pmode;;; 2,sp = src SImode;;; 6,sp = size HImode (size_t) val = 5 size = 6#else;;; D = dst Pmode;;; 2,sp = src SImode;;; 6,sp = size HImode (size_t) val = 3 size = 4#endif__memset:memset:#ifdef mc68hc12 xgdx ldab val,sp ldy size,sp pshx beq EndLoop: stab 1,x+ dbne y,LoopEnd: puld rts#else xgdx tsy ldab val,y ldy size,y ; DST = X, CNT = Y beq End pshxL0: stab 0,x ; Fill up to 256 bytes inx dey bne L0 pulx ; Restore X to return the DSTEnd: xgdx rts#endif#endif #ifdef L_adddi3 .sect .text .globl ___adddi3___adddi3: tsx xgdy ldd 8,x ; Add LSB addd 16,x std 6,y ; Save (carry preserved) ldd 6,x adcb 15,x adca 14,x std 4,y ldd 4,x adcb 13,x adca 12,x std 2,y ldd 2,x adcb 11,x ; Add MSB adca 10,x std 0,y xgdy rts#endif#ifdef L_subdi3 .sect .text .globl ___subdi3___subdi3: tsx xgdy ldd 8,x ; Subtract LSB subd 16,x std 6,y ; Save, borrow preserved ldd 6,x sbcb 15,x sbca 14,x std 4,y ldd 4,x sbcb 13,x sbca 12,x std 2,y ldd 2,x ; Subtract MSB sbcb 11,x sbca 10,x std 0,y xgdy ; rts#endif #ifdef L_notdi2 .sect .text .globl ___notdi2___notdi2: tsy xgdx ldd 8,y coma comb std 6,x ldd 6,y coma comb std 4,x ldd 4,y coma comb std 2,x ldd 2,y coma comb std 0,x xgdx rts#endif #ifdef L_negsi2 .sect .text .globl ___negsi2___negsi2: comb coma xgdx comb coma inx xgdx bne done inxdone: rts#endif#ifdef L_one_cmplsi2 .sect .text .globl ___one_cmplsi2___one_cmplsi2: comb coma xgdx comb coma xgdx rts#endif #ifdef L_ashlsi3 .sect .text .globl ___ashlsi3___ashlsi3: xgdy clra andb #0x1f xgdy beq ReturnLoop: lsld xgdx rolb rola xgdx dey bne LoopReturn: rts#endif#ifdef L_ashrsi3 .sect .text .globl ___ashrsi3___ashrsi3: xgdy clra andb #0x1f xgdy beq ReturnLoop: xgdx asra rorb xgdx rora rorb dey bne LoopReturn: rts#endif#ifdef L_lshrsi3 .sect .text .globl ___lshrsi3___lshrsi3: xgdy clra andb #0x1f xgdy beq ReturnLoop: xgdx lsrd xgdx rora rorb dey bne LoopReturn: rts#endif#ifdef L_lshrhi3 .sect .text .globl ___lshrhi3___lshrhi3: cpx #16 bge Return_zero cpx #0 beq ReturnLoop: lsrd dex bne LoopReturn: rtsReturn_zero: clra clrb rts#endif #ifdef L_lshlhi3 .sect .text .globl ___lshlhi3___lshlhi3: cpx #16 bge Return_zero cpx #0 beq ReturnLoop: lsld dex bne LoopReturn: rtsReturn_zero: clra clrb rts#endif#ifdef L_ashrhi3 .sect .text .globl ___ashrhi3___ashrhi3: cpx #16 bge Return_minus_1_or_zero cpx #0 beq ReturnLoop: asra rorb dex bne LoopReturn: rtsReturn_minus_1_or_zero:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -