From: Georg-Johann Lay Date: Tue, 9 Jun 2026 10:43:34 +0000 (+0200) Subject: AVR: Outsource lib1func.S's macros to asm-defs.h. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef23977dddf8eefa2a2ec6d9ecc5093d9cff36ec;p=thirdparty%2Fgcc.git AVR: Outsource lib1func.S's macros to asm-defs.h. libgcc/ * config/avr/lib1funcs.S: Fix trailing blanks. (mov_h): Remove macro and invocations. (mov_l): Remove macro. Replace invocations with wmov. (__zero_reg__, __tmp_reg__, __SREG__, __SP_H__) (__SP_L__, __RAMPZ__, __EIND__, skip, NEG2, NEG4) (wmov, wsubi, waddi, mov4, XCALL, XJMP, XICALL, XIJMP) (do_prologue_saves, do_epilogue_restores, .branch_plus) (DEFUN, ENDF, FALIAS): Move macros to... * config/avr/asm-defs.h: ...this new file. * config/avr/lib1funcs-fixed.S: Fix trailing blanks. --- diff --git a/libgcc/config/avr/asm-defs.h b/libgcc/config/avr/asm-defs.h new file mode 100644 index 00000000000..1e0add53021 --- /dev/null +++ b/libgcc/config/avr/asm-defs.h @@ -0,0 +1,264 @@ +/* -*- Mode: Asm -*- */ +/* Copyright (C) 1998-2026 Free Software Foundation, Inc. + Contributed by Denis Chertykov + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Definitions for common SFRs and fixed registers. + +#if defined (__AVR_TINY__) +#define __zero_reg__ r17 +#define __tmp_reg__ r16 +#else +#define __zero_reg__ r1 +#define __tmp_reg__ r0 +#endif + +#if defined (__AVR_HAVE_SPH__) +#define __SP_H__ 0x3e +#endif + +#define __SP_L__ 0x3d +#define __RAMPZ__ 0x3B +#define __EIND__ 0x3C +#define __SREG__ 0x3f + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Helper macros. + +;;; REGNO sets symbol SYM to the register number of REG. +;;; Valid REGs are: r0..r31, R0..R31 and XL, yh, ZH etc. +;;; Expressions that evaluate to a number can also be used. +.macro REGNO sym, reg + ..regno.done = 0 + ..regno = 0 + .irp name, \ + r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, \ + r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ + r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \ + r30, r31, \ + R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, \ + R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, \ + R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, \ + R30, R31 + .ifc \name,\reg + \sym = ..regno % 32 + ..regno.done = 1 + .endif + ..regno = ..regno + 1 + .endr + + ..regno = 0 + .irp name, \ + xl, xh, yl, yh, zl, zh, \ + Xl, Xh, Yl, Yh, Zl, Zh, \ + xL, xH, yL, yH, zL, zH, \ + XL, XH, YL, YH, ZL, ZH + .ifc \name,\reg + \sym = 26 + ..regno % 6 + ..regno.done = 1 + .endif + ..regno = ..regno + 1 + .endr + + .if ! ..regno.done + ;; Assume that \reg is some valid numeric expression. + \sym = \reg + .endif +.endm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Definitions to factor out different ISAs. + +#if defined (__AVR_HAVE_JMP_CALL__) +#define XCALL call +#define XJMP jmp +#else +#define XCALL rcall +#define XJMP rjmp +#endif + +#if defined (__AVR_HAVE_EIJMP_EICALL__) +#define XICALL eicall +#define XIJMP eijmp +#else +#define XICALL icall +#define XIJMP ijmp +#endif + + +;;; Like MOVW +#ifdef __AVR_HAVE_MOVW__ +#define wmov movw +#else +.macro wmov dst, src + REGNO ..wmov.dst, \dst + REGNO ..wmov.src, \src + mov ..wmov.dst+0, ..wmov.src+0 + mov ..wmov.dst+1, ..wmov.src+1 +.endm +#endif /* __AVR_HAVE_MOVW__ */ + + +;;; Like SBIW, ADIW +#ifdef __AVR_HAVE_ADIW__ +#define waddi adiw +#define wsubi sbiw +#else +.macro wsubi reg, arg + REGNO ..wsubi.reg, \reg + subi ..wsubi.reg+0, lo8 (\arg) + sbci ..wsubi.reg+1, hi8 (\arg) +.endm + +.macro waddi reg, arg + REGNO ..waddi.reg, \reg + subi ..waddi.reg+0, lo8 (-(\arg)) + sbci ..waddi.reg+1, hi8 (-(\arg)) +.endm +#endif /* __AVR_HAVE_ADIW__ */ + + +;;; [R]JMP to label LABL when REG is positive (REG.7 = 0). +;;; Otherwise, fallthrough. +.macro .branch_plus reg, labl +#ifdef __AVR_ERRATA_SKIP_JMP_CALL__ + ;; Some cores have a problem skipping 2-word instructions. + tst \reg + brmi .L.branch_plus.\@ +#else + sbrs \reg, 7 +#endif /* skip erratum */ + XJMP \labl +.L.branch_plus.\@: +.endm ; .branch_plus + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Macros for convenience. + +;; Skip the next instruction, typically a jump target. +#define skip cpse 16,16 + + +.macro mov4 dst, src + REGNO ..mov4.dst, \dst + REGNO ..mov4.src, \src + .if ..mov4.dst < ..mov4.src + wmov ..mov4.dst+0, ..mov4.src+0 + wmov ..mov4.dst+2, ..mov4.src+2 + .else + wmov ..mov4.dst+2, ..mov4.src+2 + wmov ..mov4.dst+0, ..mov4.src+0 + .endif +.endm + + +;; Negate a 2-byte value held in consecutive registers. +.macro NEG2 reg + com \reg+1 + neg \reg + sbci \reg+1, -1 +.endm + + +;; Negate a 4-byte value held in consecutive registers. +;; Sets the V flag for signed overflow tests if REG >= 16. +.macro NEG4 reg + com \reg+3 + com \reg+2 + com \reg+1 +.if \reg >= 16 + neg \reg + sbci \reg+1, -1 + sbci \reg+2, -1 + sbci \reg+3, -1 +.else + com \reg + adc \reg, __zero_reg__ + adc \reg+1, __zero_reg__ + adc \reg+2, __zero_reg__ + adc \reg+3, __zero_reg__ +.endif +.endm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Function entry and exit. + +.macro DEFUN name + .global \name + .func \name + \name: +.endm + +.macro ENDF name + .size \name, .-\name + .endfunc +.endm + +.macro FALIAS name + .global \name + .func \name + \name: + .size \name, .-\name + .endfunc +.endm + + +#ifndef __AVR_TINY__ + +;;; Prologue stuff +.macro do_prologue_saves n_pushed n_frame=0 + ldi r26, lo8 (\n_frame) + ldi r27, hi8 (\n_frame) + ldi r30, lo8 (gs(.L_prologue_saves.\@)) + ldi r31, hi8 (gs(.L_prologue_saves.\@)) + XJMP __prologue_saves__ + ((18 - (\n_pushed)) * 2) +.L_prologue_saves.\@: +.endm + + +;; Epilogue stuff +.macro do_epilogue_restores n_pushed n_frame=0 + in r28, __SP_L__ +#ifdef __AVR_HAVE_SPH__ + in r29, __SP_H__ +.if \n_frame > 63 + subi r28, lo8 (-(\n_frame)) + sbci r29, hi8 (-(\n_frame)) +.elseif \n_frame > 0 + adiw r28, \n_frame +.endif +#else + clr r29 +.if \n_frame > 0 + subi r28, lo8 (-(\n_frame)) +.endif +#endif /* HAVE SPH */ + ldi r30, \n_pushed + XJMP __epilogue_restores__ + ((18 - (\n_pushed)) * 2) +.endm + +#endif /* AVR_TINY */ diff --git a/libgcc/config/avr/lib1funcs-fixed.S b/libgcc/config/avr/lib1funcs-fixed.S index 577129503cf..4b77ee2dd56 100644 --- a/libgcc/config/avr/lib1funcs-fixed.S +++ b/libgcc/config/avr/lib1funcs-fixed.S @@ -1598,7 +1598,7 @@ DEFUN __rounduha3 ;; [ R25:R24 = 1 << (FBIT-1 - RP) ;; R23:R22 += 1 << (FBIT-1 - RP) ] XCALL __addmask_2 - XJMP __round_u2_const + XJMP __round_u2_const ENDF __rounduha3 #endif /* L_round_u2 */ @@ -1627,7 +1627,7 @@ DEFUN __round_u2_const ;; C[] = 2^{-RP} lsl C0 rol C1 - ;; + ;; NEG2 C0 ;; Clear the bits beyond the rounding point. and C0, A0 @@ -1717,7 +1717,7 @@ DEFUN __roundusa3 ;; [ R25:R22 = 1 << (FBIT-1 - RP) ;; R21:R18 += 1 << (FBIT-1 - RP) ] XCALL __addmask_4 - XJMP __round_u4_const + XJMP __round_u4_const ENDF __roundusa3 #endif /* L_round_u4 */ diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S index f0f06e478e1..4978a2e969c 100644 --- a/libgcc/config/avr/lib1funcs.S +++ b/libgcc/config/avr/lib1funcs.S @@ -21,202 +21,18 @@ a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ -#if defined (__AVR_TINY__) -#define __zero_reg__ r17 -#define __tmp_reg__ r16 -#else -#define __zero_reg__ r1 -#define __tmp_reg__ r0 -#endif -#define __SREG__ 0x3f -#if defined (__AVR_HAVE_SPH__) -#define __SP_H__ 0x3e -#endif -#define __SP_L__ 0x3d -#define __RAMPZ__ 0x3B -#define __EIND__ 0x3C +#include "asm-defs.h" /* Most of the functions here are called directly from avr.md patterns, instead of using the standard libcall mechanisms. This can make better code because GCC knows exactly which - of the call-used registers (not all of them) are clobbered. */ - -/* FIXME: At present, there is no SORT directive in the linker - script so that we must not assume that different modules - in the same input section like .libgcc.text.mul will be - located close together. Therefore, we cannot use - RCALL/RJMP to call a function like __udivmodhi4 from - __divmodhi4 and have to use lengthy XCALL/XJMP even - though they are in the same input section and all same - input sections together are small enough to reach every - location with a RCALL/RJMP instruction. */ + of the call-used registers (not all of them) are clobbered. + Some functions are using a non-ABI interface. */ #if defined (__AVR_HAVE_EIJMP_EICALL__) && !defined (__AVR_HAVE_ELPMX__) #error device not supported #endif - .macro mov_l r_dest, r_src -#if defined (__AVR_HAVE_MOVW__) - movw \r_dest, \r_src -#else - mov \r_dest, \r_src -#endif - .endm - - .macro mov_h r_dest, r_src -#if defined (__AVR_HAVE_MOVW__) - ; empty -#else - mov \r_dest, \r_src -#endif - .endm - -.macro wmov r_dest, r_src -#if defined (__AVR_HAVE_MOVW__) - movw \r_dest, \r_src -#else - mov \r_dest, \r_src - mov \r_dest+1, \r_src+1 -#endif -.endm - -.macro mov4 r_dest, r_src - wmov \r_dest, \r_src - wmov \r_dest+2, \r_src+2 -.endm - -#if defined (__AVR_HAVE_JMP_CALL__) -#define XCALL call -#define XJMP jmp -#else -#define XCALL rcall -#define XJMP rjmp -#endif - -#if defined (__AVR_HAVE_EIJMP_EICALL__) -#define XICALL eicall -#define XIJMP eijmp -#else -#define XICALL icall -#define XIJMP ijmp -#endif - -;;; [R]JMP to label \labl when \reg is positive (\reg.7 = 0). -;;; Otherwise, fallthrough. -.macro .branch_plus reg, labl -#ifdef __AVR_ERRATA_SKIP_JMP_CALL__ - ;; Some cores have a problem skipping 2-word instructions - tst \reg - brmi .L..\@ -#else - sbrs \reg, 7 -#endif /* skip erratum */ - XJMP \labl -.L..\@: -.endm ; .branch_plus - -;; Prologue stuff - -.macro do_prologue_saves n_pushed n_frame=0 - ldi r26, lo8(\n_frame) - ldi r27, hi8(\n_frame) - ldi r30, lo8(gs(.L_prologue_saves.\@)) - ldi r31, hi8(gs(.L_prologue_saves.\@)) - XJMP __prologue_saves__ + ((18 - (\n_pushed)) * 2) -.L_prologue_saves.\@: -.endm - -;; Epilogue stuff - -.macro do_epilogue_restores n_pushed n_frame=0 - in r28, __SP_L__ -#ifdef __AVR_HAVE_SPH__ - in r29, __SP_H__ -.if \n_frame > 63 - subi r28, lo8(-\n_frame) - sbci r29, hi8(-\n_frame) -.elseif \n_frame > 0 - adiw r28, \n_frame -.endif -#else - clr r29 -.if \n_frame > 0 - subi r28, lo8(-\n_frame) -.endif -#endif /* HAVE SPH */ - ldi r30, \n_pushed - XJMP __epilogue_restores__ + ((18 - (\n_pushed)) * 2) -.endm - -;; Support function entry and exit for convenience - -.macro wsubi r_arg1, i_arg2 -#if defined (__AVR_TINY__) - subi \r_arg1, lo8(\i_arg2) - sbci \r_arg1+1, hi8(\i_arg2) -#else - sbiw \r_arg1, \i_arg2 -#endif -.endm - -.macro waddi r_arg1, i_arg2 -#if defined (__AVR_TINY__) - subi \r_arg1, lo8(-\i_arg2) - sbci \r_arg1+1, hi8(-\i_arg2) -#else - adiw \r_arg1, \i_arg2 -#endif -.endm - -.macro DEFUN name -.global \name -.func \name -\name: -.endm - -.macro ENDF name -.size \name, .-\name -.endfunc -.endm - -.macro FALIAS name -.global \name -.func \name -\name: -.size \name, .-\name -.endfunc -.endm - -;; Skip next instruction, typically a jump target -#define skip cpse 16,16 - -;; Negate a 2-byte value held in consecutive registers -.macro NEG2 reg - com \reg+1 - neg \reg - sbci \reg+1, -1 -.endm - -;; Negate a 4-byte value held in consecutive registers -;; Sets the V flag for signed overflow tests if REG >= 16 -.macro NEG4 reg - com \reg+3 - com \reg+2 - com \reg+1 -.if \reg >= 16 - neg \reg - sbci \reg+1, -1 - sbci \reg+2, -1 - sbci \reg+3, -1 -.else - com \reg - adc \reg, __zero_reg__ - adc \reg+1, __zero_reg__ - adc \reg+2, __zero_reg__ - adc \reg+3, __zero_reg__ -.endif -.endm - #define exp_lo(N) hlo8 ((N) << 23) #define exp_hi(N) hhi8 ((N) << 23) @@ -244,7 +60,7 @@ __mulqi3_loop: breq __mulqi3_exit ; while multiplicand != 0 lsr r_arg1 ; brne __mulqi3_loop ; exit if multiplier = 0 -__mulqi3_exit: +__mulqi3_exit: mov r_arg1,r_res ; result to return register ret ENDF __mulqi3 @@ -252,7 +68,7 @@ ENDF __mulqi3 #undef r_arg2 #undef r_arg1 #undef r_res - + #endif /* defined (L_mulqi3) */ @@ -501,7 +317,7 @@ DEFUN __mulsi3_helper wmov C2, CC2 #if defined (__AVR_TINY__) pop B1 ; restore callee saved regs - pop B0 + pop B0 #endif /* defined (__AVR_TINY__) */ ret @@ -615,14 +431,7 @@ ENDF __umulhisi3 ;;; (C3:C0) = (signed long) A1:A0 * B3:B0 ;;; Clobbers: __tmp_reg__ DEFUN __mulshisi3 -#ifdef __AVR_ERRATA_SKIP_JMP_CALL__ - ;; Some cores have problem skipping 2-word instruction - tst A1 - brmi __mulohisi3 -#else - sbrs A1, 7 -#endif /* __AVR_HAVE_JMP_CALL__ */ - XJMP __muluhisi3 + .branch_plus A1, __muluhisi3 ;; FALLTHRU ENDF __mulshisi3 @@ -760,13 +569,13 @@ ENDF __mulpsi3 DEFUN __mulpsi3 #if defined (__AVR_TINY__) - in r26,__SP_L__ + in r26,__SP_L__ in r27,__SP_H__ subi r26, lo8(-3) ; Add 3 to point past return address sbci r27, hi8(-3) push B0 ; save callee saved regs push B1 - ld B0,X+ ; load from caller stack + ld B0,X+ ; load from caller stack ld B1,X+ ld B2,X+ #endif /* defined (__AVR_TINY__) */ @@ -1119,15 +928,15 @@ ENDF __muldi3 #if defined (__AVR_HAVE_MUL__) #define A0 r22 -#define A1 r23 +#define A1 r23 #define A2 r24 #define A3 r25 - + #define B0 r18 #define B1 r19 #define B2 r20 #define B3 r21 - + #define C0 18 #define C1 C0+1 #define C2 20 @@ -1349,7 +1158,7 @@ ENDF __umulsidi3 #endif /* L_mulsidi3 && !HAVE_MUL */ #endif /* if not __AVR_TINY__ */ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - + .section .text.libgcc.div, "ax", @progbits @@ -1405,8 +1214,8 @@ ENDF __divmodqi4 #undef r_arg1 #undef r_arg2 #undef r_cnt - - + + /******************************************************* Division 16 / 16 => (result + remainder) *******************************************************/ @@ -1420,7 +1229,7 @@ ENDF __divmodqi4 /* return: quotient */ #define r_arg2L r22 /* divisor Low */ #define r_arg2H r23 /* divisor High */ - + #define r_cnt r21 /* loop count */ #if defined (L_udivmodhi4) @@ -1445,10 +1254,8 @@ __udivmodhi4_ep: com r_arg1L com r_arg1H ; div/mod results to return registers, as for the div() function - mov_l r_arg2L, r_arg1L ; quotient - mov_h r_arg2H, r_arg1H - mov_l r_arg1L, r_remL ; remainder - mov_h r_arg1H, r_remH + wmov r_arg2L, r_arg1L ; quotient + wmov r_arg1L, r_remL ; remainder ret ENDF __udivmodhi4 #endif /* defined (L_udivmodhi4) */ @@ -1493,8 +1300,8 @@ ENDF __divmodhi4 #undef r_arg2H #undef r_arg2L - -#undef r_cnt + +#undef r_cnt /******************************************************* Division 24 / 24 => (result + remainder) @@ -1650,7 +1457,7 @@ ENDF __divmodpsi4 #define r_arg2HL r20 #define r_arg2H r19 #define r_arg2L r18 /* divisor Low */ - + #define r_cnt __zero_reg__ /* loop count (0 after the loop!) */ #if defined (L_udivmodsi4) @@ -1659,8 +1466,7 @@ DEFUN __udivmodsi4 mov r_cnt, r_remL sub r_remL,r_remL sub r_remH,r_remH ; clear remainder and carry - mov_l r_remHL, r_remL - mov_h r_remHH, r_remH + wmov r_remHL, r_remL rjmp __udivmodsi4_ep ; jump to entry point __udivmodsi4_loop: rol r_remL ; shift dividend into remainder @@ -1689,14 +1495,10 @@ __udivmodsi4_ep: com r_arg1HL com r_arg1HH ; div/mod results to return registers, as for the ldiv() function - mov_l r_arg2L, r_arg1L ; quotient - mov_h r_arg2H, r_arg1H - mov_l r_arg2HL, r_arg1HL - mov_h r_arg2HH, r_arg1HH - mov_l r_arg1L, r_remL ; remainder - mov_h r_arg1H, r_remH - mov_l r_arg1HL, r_remHL - mov_h r_arg1HH, r_remHH + wmov r_arg2L, r_arg1L ; quotient + wmov r_arg2HL, r_arg1HL + wmov r_arg1L, r_remL ; remainder + wmov r_arg1HL, r_remHL ret ENDF __udivmodsi4 #endif /* defined (L_udivmodsi4) */ @@ -2277,8 +2079,7 @@ DEFUN __epilogue_restores__ out __SP_H__,r29 out __SREG__,__tmp_reg__ out __SP_L__,r28 - mov_l r28, r26 - mov_h r29, r27 + wmov r28, r26 #endif /* #SP = 8/16 */ ret ENDF __epilogue_restores__ @@ -2353,7 +2154,7 @@ DEFUN __tablejump2__ wsubi 30, -(__AVR_TINY_PM_BASE_ADDRESS__) ; Add PM offset to Z ld __tmp_reg__, Z+ ld r31, Z ; Use ld instead of lpm to load Z - mov r30, __tmp_reg__ + mov r30, __tmp_reg__ ijmp #else lpm @@ -2496,8 +2297,7 @@ DEFUN __do_global_ctors sbc r16, __zero_reg__ mov r24, r16 #endif /* HAVE_EIJMP */ - mov_h r31, r29 - mov_l r30, r28 + wmov r30, r28 XCALL __tablejump2__ .L__do_global_ctors_start: cpi r28, pm_lo8(__ctors_start) @@ -2524,8 +2324,7 @@ DEFUN __do_global_dtors #ifdef __AVR_HAVE_EIJMP_EICALL__ mov r24, r16 #endif /* HAVE_EIJMP */ - mov_h r31, r29 - mov_l r30, r28 + wmov r30, r28 XCALL __tablejump2__ waddi 28, 1 #ifdef __AVR_HAVE_EIJMP_EICALL__ @@ -2764,14 +2563,8 @@ ENDF __fload_4 #if !defined (__AVR_TINY__) #if defined (L_strlen_memx) DEFUN __strlen_memx -#ifdef __AVR_ERRATA_SKIP_JMP_CALL__ - tst r24 - brmi 1f -#else - sbrs r24, 7 -#endif - XJMP strlen_PF ; AVR-LibC -1: wmov 24, 22 + .branch_plus r24, strlen_PF ; AVR-LibC + wmov 24, 22 XJMP strlen ; AVR-LibC ENDF __strlen_memx #endif /* L_strlen_memx */ @@ -2872,7 +2665,7 @@ ENDF __movmemf_hi #undef LOOP #endif /* L_movmemf */ -#endif /* !defined (__AVR_TINY__) */ +#endif /* !defined (__AVR_TINY__) */ .section .text.libgcc.builtins, "ax", @progbits @@ -2984,10 +2777,8 @@ DEFUN __clzdi2 XCALL __clzsi2 sbrs r24, 5 ret - mov_l r22, r18 - mov_h r23, r19 - mov_l r24, r20 - mov_h r25, r21 + wmov r22, r18 + wmov r24, r20 XCALL __clzsi2 subi r24, -32 ret @@ -3002,8 +2793,7 @@ DEFUN __clzsi2 XCALL __clzhi2 sbrs r24, 4 ret - mov_l r24, r22 - mov_h r25, r23 + wmov r24, r22 XCALL __clzhi2 subi r24, -16 ret @@ -3124,8 +2914,7 @@ ENDF __popcounthi2_tail DEFUN __popcountsi2 XCALL __popcounthi2 push r24 - mov_l r24, r22 - mov_h r25, r23 + wmov r24, r22 XCALL __popcounthi2 XJMP __popcounthi2_tail ENDF __popcountsi2 @@ -3138,10 +2927,8 @@ ENDF __popcountsi2 DEFUN __popcountdi2 XCALL __popcountsi2 push r24 - mov_l r22, r18 - mov_h r23, r19 - mov_l r24, r20 - mov_h r25, r21 + wmov r22, r18 + wmov r24, r20 XCALL __popcountsi2 XJMP __popcounthi2_tail ENDF __popcountdi2 @@ -3433,15 +3220,8 @@ DEFUN __fmulsu_exit ;; A1 = |A1| sbrc A1, 7 neg A1 -#ifdef __AVR_ERRATA_SKIP_JMP_CALL__ - ;; Some cores have problem skipping 2-word instruction - tst A0 - brmi 1f -#else - sbrs A0, 7 -#endif /* __AVR_HAVE_JMP_CALL__ */ - XJMP __fmul -1: XCALL __fmul + .branch_plus A0, __fmul + XCALL __fmul ;; C = -C iff A0.7 = 1 NEG2 C0 ret