📄 larith.asm
字号:
clrb tsta bpl Return_zero combReturn_zero: tba rts#endif #ifdef L_ashrqi3 .sect .text .globl ___ashrqi3___ashrqi3: cmpa #8 bge Return_minus_1_or_zero tsta beq ReturnLoop: asrb deca bne LoopReturn: rtsReturn_minus_1_or_zero: clrb tstb bpl Return_zero comaReturn_zero: tab rts#endif#ifdef L_lshlqi3 .sect .text .globl ___lshlqi3___lshlqi3: cmpa #8 bge Return_zero tsta beq ReturnLoop: lslb deca bne LoopReturn: rtsReturn_zero: clrb rts#endif#ifdef L_divmodhi4#ifndef mc68hc12/* 68HC12 signed divisions are generated inline (idivs). */ .sect .text .globl __divmodhi4;;; D = numerator;; X = denominator;;;; Result: D = D / X;; X = D % X;; __divmodhi4: tsta bpl Numerator_pos comb ; D = -D <=> D = (~D) + 1 coma xgdx inx tsta bpl Numerator_neg_denominator_posNumerator_neg_denominator_neg: comb ; X = -X coma addd #1 xgdx idiv coma comb xgdx ; Remainder <= 0 and result >= 0 inx rtsNumerator_pos_denominator_pos: xgdx idiv xgdx ; Both values are >= 0 rts Numerator_pos: xgdx tsta bpl Numerator_pos_denominator_posNumerator_pos_denominator_neg: coma ; X = -X comb xgdx inx idiv xgdx ; Remainder >= 0 but result <= 0 coma comb addd #1 rts Numerator_neg_denominator_pos: xgdx idiv coma ; One value is > 0 and the other < 0 comb ; Change the sign of result and remainder xgdx inx coma comb addd #1 rts#endif /* !mc68hc12 */#endif#ifdef L_mulqi3 .sect .text .globl __mulqi3;; short __mulqi3(signed char a, signed char b);;; signed char a -> register A; signed char b -> register B;; returns the signed result of A * B in register D.;__mulqi3: tsta bmi A_neg tstb bmi B_neg mul rtsB_neg: negb bra A_or_B_negA_neg: nega tstb bmi AB_negA_or_B_neg: mul coma comb addd #1 rtsAB_neg: negb mul rts#endif #ifdef L_mulhi3 .sect .text .globl ___mulhi3;;; unsigned short ___mulhi3(unsigned short a, unsigned short b);; a = register D; b = register X;___mulhi3:#ifdef mc68hc12 pshx ; Preserve X exg x,y emul exg x,y pulx rts#else#ifdef NO_TMP ; ; 16 bit multiplication without temp memory location. ; (smaller but slower) ; pshx ; (4) ins ; (3) pshb ; (3) psha ; (3) pshx ; (4) pula ; (4) pulx ; (5) mul ; (10) B.high * A.low xgdx ; (3) mul ; (10) B.low * A.high abx ; (3) pula ; (4) pulb ; (4) mul ; (10) B.low * A.low pshx ; (4) tsx ; (3) adda 1,x ; (4) pulx ; (5) rts ; (5) 20 bytes ; --- ; 91 cycles#else stx _.tmp ; (4/5) pshb ; (3) ldab _.tmp+1 ; (3/4) mul ; (10) B.high * A.low xgdx ; (3) pulb ; (4) stab _.tmp ; (3/4) mul ; (10) B.low * A.high abx ; (3) ldd _.tmp ; (4/5) mul ; (10) B.low * A.low stx _.tmp ; (4) adda _.tmp+1 ; (4/5) rts ; (5) 20/26 bytes ; --- ; 70/76 cycles#ifdef OLD_MUL stx *_.tmp ; (4) pshb ; (3) ldab *_.tmp+1 ; (3) mul ; (10) A.high * B.low ldaa *_.tmp ; (3) stab *_.tmp ; (3) pulb ; (4) pshb ; (4) mul ; (10) A.low * B.high addb *_.tmp ; (4) stab *_.tmp ; (3) ldaa *_.tmp+1 ; (3) pulb ; (4) mul ; (10) A.low * B.low adda *_.tmp ; (4) rts ; (5) 24/32 bytes ; 77/85 cycles#endif#endif#endif#endif#ifdef L_mulhi32 .sect .text .globl __mulhi32;;; unsigned long __mulhi32(unsigned short a, unsigned short b);; a = register D; b = value on stack;; +---------------+; | B low | <- 7,x; +---------------+; | B high | <- 6,x; +---------------+; | PC low | ; +---------------+; | PC high | ; +---------------+; | Tmp low |; +---------------+; | Tmp high |; +---------------+; | A low |; +---------------+; | A high |; +---------------+ <- 0,x;;; <B-low> 5,x; <B-high> 4,x; <ret> 2,x; <A-low> 1,x; <A-high> 0,x;__mulhi32:#ifdef mc68hc12 ldy 2,sp emul exg x,y rts#else pshx ; Room for temp value pshb psha tsx ldab 6,x mul xgdy ; A.high * B.high ldab 7,x pula mul ; A.high * B.low std 2,x ldaa 1,x ldab 6,x mul ; A.low * B.high addd 2,x stab 2,x tab aby bcc N ldab #0xff aby inyN: ldab 7,x pula mul ; A.low * B.low adda 2,x pulx ; Drop temp location pshy ; Put high part in X pulx bcc Ret inxRet: rts#endif #endif#ifdef L_mulsi3 .sect .text .globl __mulsi3;; <B-low> 8,y; <B-high> 6,y; <ret> 4,y; <tmp> 2,y; <A-low> 0,y;; D,X -> A; Stack -> B;; The result is:;; (((A.low * B.high) + (A.high * B.low)) << 16) + (A.low * B.low);;;__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#elseB_low = 8B_high = 6A_low = 0A_high = 2 pshx pshb psha tsy;; If B.low is 0, optimize into: (A.low * B.high) << 16; ldd B_low,y beq B_low_zero;; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low); cpx #0 beq A_high_zero bsr ___mulhi3 ; A.high * B.low;; If A.low is 0, optimize into: (A.high * B.low) << 16; ldx A_low,y beq A_low_zero ; X = 0, D = A.high * B.low std 2,y;; If B.high is 0, we can avoid the (A.low * B.high) << 16 term.; ldd B_high,y beq B_high_zero bsr ___mulhi3 ; A.low * B.high addd 2,y std 2,y;; Here, we know that A.low and B.low are not 0.;B_high_zero: ldd B_low,y ; A.low is on the stack bsr __mulhi32 ; A.low * B.low xgdx tsy ; Y was clobbered, get it back addd 2,yA_low_zero: ; See A_low_zero_non_optimized below xgdxReturn: ins ins ins ins rts;; ; A_low_zero_non_optimized:;; At this step, X = 0 and D = (A.high * B.low); Optimize into: (A.high * B.low) << 16;; xgdx; clra ; Since X was 0, clearing D is superfuous.; clrb; bra Return; ----------------; B.low == 0, the result is: (A.low * B.high) << 16;; At this step:; D = B.low = 0 ; X = A.high ?; A.low is at A_low,y ?; B.low is at B_low,y ?;B_low_zero: ldd A_low,y beq Zero1 ldx B_high,y beq Zero2 bsr ___mulhi3Zero1: xgdxZero2: clra clrb bra Return; ----------------; A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low);; At this step:; D = B.low != 0 ; X = A.high = 0; A.low is at A_low,y ?; B.low is at B_low,y ?;A_high_zero: ldd A_low,y ; A.low beq Zero1 ldx B_high,y ; B.high beq A_low_B_low bsr ___mulhi3 std 2,y bra B_high_zero ; Do the (A.low * B.low) and the add.; ----------------; A.high and B.high are 0 optimize into: (A.low * B.low);; At this step:; D = B.high = 0 ; X = A.low != 0; A.low is at A_low,y != 0; B.high is at B_high,y = 0;A_low_B_low: ldd B_low,y ; A.low is on the stack bsr __mulhi32 bra Return#endif#endif#ifdef L_map_data .sect .install2,"ax",@progbits .globl __map_data_section .globl __data_image#ifdef mc68hc12 .globl __data_section_size#endif__map_data_section:#ifdef mc68hc12 ldx #__data_image ldy #__data_section_start ldd #__data_section_size beq DoneLoop: movb 1,x+,1,y+ dbne d,Loop#else ldx #__data_image ldy #__data_section_start bra Start_mapLoop: ldaa 0,x staa 0,y inx inyStart_map: cpx #__data_image_end blo Loop#endifDone:#endif#ifdef L_init_bss .sect .install2,"ax",@progbits .globl __init_bss_section__init_bss_section: ldd #__bss_size beq Done ldx #__bss_startLoop:#ifdef mc68hc12 clr 1,x+ dbne d,Loop#else clr 0,x inx subd #1 bne Loop#endifDone:#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__-2ctors_loop: cpx #__CTOR_LIST__ blo ctors_done pshx ldx 0,x jsr 0,x pulx dex dex bra ctors_loopctors_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__ bhs dtors_done pshx ldx 0,x jsr 0,x pulx inx inx bra dtors_loopdtors_done: pula ; Restore exit code pulb#endif;-----------------------------------------; end required gcclib code;-----------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -