1 /* -*- Mode: Asm -*- */
2 /* Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009
3 Free Software Foundation, Inc.
4 Contributed by Denis Chertykov <chertykov@gmail.com>
6 This file is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 This file is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
25 #define __zero_reg__ r1
26 #define __tmp_reg__ r0
30 #define __RAMPZ__ 0x3B
33 /* Most of the functions here are called directly from avr.md
34 patterns, instead of using the standard libcall mechanisms.
35 This can make better code because GCC knows exactly which
36 of the call-used registers (not all of them) are clobbered. */
38 /* FIXME: At present, there is no SORT directive in the linker
39 script so that we must not assume that different modules
40 in the same input section like .libgcc.text.mul will be
41 located close together. Therefore, we cannot use
42 RCALL/RJMP to call a function like __udivmodhi4 from
43 __divmodhi4 and have to use lengthy XCALL/XJMP even
44 though they are in the same input section and all same
45 input sections together are small enough to reach every
46 location with a RCALL/RJMP instruction. */
48 .macro mov_l r_dest, r_src
49 #if defined (__AVR_HAVE_MOVW__)
56 .macro mov_h r_dest, r_src
57 #if defined (__AVR_HAVE_MOVW__)
64 .macro wmov r_dest, r_src
65 #if defined (__AVR_HAVE_MOVW__)
69 mov \r_dest+1, \r_src+1
73 #if defined (__AVR_HAVE_JMP_CALL__)
93 .section .text.libgcc.mul, "ax", @progbits
95 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
96 /* Note: mulqi3, mulhi3 are open-coded on the enhanced core. */
97 #if !defined (__AVR_HAVE_MUL__)
98 /*******************************************************
99 Multiplication 8 x 8 without MUL
100 *******************************************************/
101 #if defined (L_mulqi3)
103 #define r_arg2 r22 /* multiplicand */
104 #define r_arg1 r24 /* multiplier */
105 #define r_res __tmp_reg__ /* result */
108 clr r_res ; clear result
112 add r_arg2,r_arg2 ; shift multiplicand
113 breq __mulqi3_exit ; while multiplicand != 0
115 brne __mulqi3_loop ; exit if multiplier = 0
117 mov r_arg1,r_res ; result to return register
125 #endif /* defined (L_mulqi3) */
127 #if defined (L_mulqihi3)
137 #endif /* defined (L_mulqihi3) */
139 #if defined (L_umulqihi3)
145 #endif /* defined (L_umulqihi3) */
147 /*******************************************************
148 Multiplication 16 x 16 without MUL
149 *******************************************************/
150 #if defined (L_mulhi3)
151 #define r_arg1L r24 /* multiplier Low */
152 #define r_arg1H r25 /* multiplier High */
153 #define r_arg2L r22 /* multiplicand Low */
154 #define r_arg2H r23 /* multiplicand High */
155 #define r_resL __tmp_reg__ /* result Low */
156 #define r_resH r21 /* result High */
159 clr r_resH ; clear result
160 clr r_resL ; clear result
164 add r_resL,r_arg2L ; result + multiplicand
167 add r_arg2L,r_arg2L ; shift multiplicand
170 cp r_arg2L,__zero_reg__
171 cpc r_arg2H,__zero_reg__
172 breq __mulhi3_exit ; while multiplicand != 0
174 lsr r_arg1H ; gets LSB of multiplier
177 brne __mulhi3_loop ; exit if multiplier = 0
179 mov r_arg1H,r_resH ; result to return register
191 #endif /* defined (L_mulhi3) */
193 /*******************************************************
194 Widening Multiplication 32 = 16 x 16 without MUL
195 *******************************************************/
197 #if defined (L_mulhisi3)
199 ;;; FIXME: This is dead code (noone calls it)
212 #endif /* defined (L_mulhisi3) */
214 #if defined (L_umulhisi3)
216 ;;; FIXME: This is dead code (noone calls it)
225 #endif /* defined (L_umulhisi3) */
227 #if defined (L_mulsi3)
228 /*******************************************************
229 Multiplication 32 x 32 without MUL
230 *******************************************************/
231 #define r_arg1L r22 /* multiplier Low */
234 #define r_arg1HH r25 /* multiplier High */
236 #define r_arg2L r18 /* multiplicand Low */
239 #define r_arg2HH r21 /* multiplicand High */
241 #define r_resL r26 /* result Low */
244 #define r_resHH r31 /* result High */
247 clr r_resHH ; clear result
248 clr r_resHL ; clear result
249 clr r_resH ; clear result
250 clr r_resL ; clear result
254 add r_resL,r_arg2L ; result + multiplicand
259 add r_arg2L,r_arg2L ; shift multiplicand
261 adc r_arg2HL,r_arg2HL
262 adc r_arg2HH,r_arg2HH
264 lsr r_arg1HH ; gets LSB of multiplier
271 brne __mulsi3_loop ; exit if multiplier = 0
273 mov_h r_arg1HH,r_resHH ; result to return register
274 mov_l r_arg1HL,r_resHL
295 #endif /* defined (L_mulsi3) */
297 #endif /* !defined (__AVR_HAVE_MUL__) */
298 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
300 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
301 #if defined (__AVR_HAVE_MUL__)
316 /*******************************************************
317 Widening Multiplication 32 = 16 x 16
318 *******************************************************/
320 #if defined (L_mulhisi3)
321 ;;; R25:R22 = (signed long) R27:R26 * (signed long) R19:R18
322 ;;; C3:C0 = (signed long) A1:A0 * (signed long) B1:B0
323 ;;; Clobbers: __tmp_reg__
332 XJMP __usmulhisi3_tail
334 #endif /* L_mulhisi3 */
336 #if defined (L_usmulhisi3)
337 ;;; R25:R22 = (signed long) R27:R26 * (unsigned long) R19:R18
338 ;;; C3:C0 = (signed long) A1:A0 * (unsigned long) B1:B0
339 ;;; Clobbers: __tmp_reg__
345 DEFUN __usmulhisi3_tail
352 ENDF __usmulhisi3_tail
353 #endif /* L_usmulhisi3 */
355 #if defined (L_umulhisi3)
356 ;;; R25:R22 = (unsigned long) R27:R26 * (unsigned long) R19:R18
357 ;;; C3:C0 = (unsigned long) A1:A0 * (unsigned long) B1:B0
358 ;;; Clobbers: __tmp_reg__
373 #endif /* L_umulhisi3 */
375 /*******************************************************
376 Widening Multiplication 32 = 16 x 32
377 *******************************************************/
379 #if defined (L_mulshisi3)
380 ;;; R25:R22 = (signed long) R27:R26 * R21:R18
381 ;;; (C3:C0) = (signed long) A1:A0 * B3:B0
382 ;;; Clobbers: __tmp_reg__
384 #ifdef __AVR_ERRATA_SKIP_JMP_CALL__
385 ;; Some cores have problem skipping 2-word instruction
390 #endif /* __AVR_HAVE_JMP_CALL__ */
395 ;;; R25:R22 = (one-extended long) R27:R26 * R21:R18
396 ;;; (C3:C0) = (one-extended long) A1:A0 * B3:B0
397 ;;; Clobbers: __tmp_reg__
400 ;; One-extend R27:R26 (A1:A0)
405 #endif /* L_mulshisi3 */
407 #if defined (L_muluhisi3)
408 ;;; R25:R22 = (unsigned long) R27:R26 * R21:R18
409 ;;; (C3:C0) = (unsigned long) A1:A0 * B3:B0
410 ;;; Clobbers: __tmp_reg__
423 #endif /* L_muluhisi3 */
425 /*******************************************************
426 Multiplication 32 x 32
427 *******************************************************/
429 #if defined (L_mulsi3)
430 ;;; R25:R22 = R25:R22 * R21:R18
431 ;;; (C3:C0) = C3:C0 * B3:B0
432 ;;; Clobbers: R26, R27, __tmp_reg__
440 ;; A1:A0 now contains the high word of A
451 #endif /* L_mulsi3 */
466 #endif /* __AVR_HAVE_MUL__ */
468 /*******************************************************
469 Multiplication 24 x 24
470 *******************************************************/
472 #if defined (L_mulpsi3)
474 ;; A[0..2]: In: Multiplicand; Out: Product
479 ;; B[0..2]: In: Multiplier
484 #if defined (__AVR_HAVE_MUL__)
486 ;; C[0..2]: Expand Result
491 ;; R24:R22 *= R20:R18
492 ;; Clobbers: r21, r25, r26, r27, __tmp_reg__
501 mul AA2, B0 $ add C2, r0
502 mul AA0, B2 $ add C2, r0
514 #else /* !HAVE_MUL */
516 ;; C[0..2]: Expand Result
521 ;; R24:R22 *= R20:R18
522 ;; Clobbers: __tmp_reg__, R18, R19, R20, R21
530 0: ;; Shift N-th Bit of B[] into Carry. N = 24 - Loop
531 LSR B2 $ ror B1 $ ror B0
533 ;; If the N-th Bit of B[] was set...
536 ;; ...then add A[] * 2^N to the Result C[]
537 ADD C0,A0 $ adc C1,A1 $ adc C2,A2
539 1: ;; Multiply A[] by 2
540 LSL A0 $ rol A1 $ rol A2
542 ;; Loop until B[] is 0
543 subi B0,0 $ sbci B1,0 $ sbci B2,0
546 ;; Copy C[] to the return Register A[]
558 #endif /* HAVE_MUL */
568 #endif /* L_mulpsi3 */
570 #if defined (L_mulsqipsi3) && defined (__AVR_HAVE_MUL__)
572 ;; A[0..2]: In: Multiplicand
577 ;; BB: In: Multiplier
585 ;; C[] = A[] * sign_extend (BB)
613 #endif /* L_mulsqipsi3 && HAVE_MUL */
615 /*******************************************************
616 Multiplication 64 x 64
617 *******************************************************/
619 #if defined (L_muldi3)
623 ;; A[0..7]: In: Multiplicand
634 ;; B[0..7]: In: Multiplier
644 #if defined (__AVR_HAVE_MUL__)
646 ;; Define C[] for convenience
647 ;; Notice that parts of C[] overlap A[] respective B[]
658 ;; R25:R18 *= R17:R10
659 ;; Ordinary ABI-Function
667 ;; Counting in Words, we have to perform a 4 * 4 Multiplication
670 mul A7,B0 $ $ mov C7,r0
671 mul A0,B7 $ $ add C7,r0
672 mul A6,B1 $ $ add C7,r0
673 mul A6,B0 $ mov C6,r0 $ add C7,r1
674 mul B6,A1 $ $ add C7,r0
675 mul B6,A0 $ add C6,r0 $ adc C7,r1
678 mul A2,B4 $ add C6,r0 $ adc C7,r1
679 mul A3,B4 $ $ add C7,r0
680 mul A2,B5 $ $ add C7,r0
697 XCALL __umulhisi3 $ wmov C4,22 $ add C6,24 $ adc C7,25
707 XCALL __umulhisi3 $ add C4,22 $ adc C5,23 $ adc C6,24 $ adc C7,25
717 XCALL __umulhisi3 $ add C4,22 $ adc C5,23 $ adc C6,24 $ adc C7,25
721 XCALL __umulhisi3 $ $ $ add C6,22 $ adc C7,23
756 #else /* !HAVE_MUL */
770 ;; R25:R18 *= R17:R10
771 ;; Ordinary ABI-Function
787 0: ;; Rotate B[] right by 1 and set Carry to the N-th Bit of B[]
788 ;; where N = 64 - Loop.
789 ;; Notice that B[] = B[] >>> 64 so after this Routine has finished,
790 ;; B[] will have its initial Value again.
791 LSR B7 $ ror B6 $ ror B5 $ ror B4
792 ror B3 $ ror B2 $ ror B1 $ ror B0
794 ;; If the N-th Bit of B[] was set then...
796 ;; ...finish Rotation...
799 ;; ...and add A[] * 2^N to the Result C[]
800 ADD C0,A0 $ adc C1,A1 $ adc C2,A2 $ adc C3,A3
801 adc C4,A4 $ adc C5,A5 $ adc C6,A6 $ adc C7,A7
803 1: ;; Multiply A[] by 2
804 LSL A0 $ rol A1 $ rol A2 $ rol A3
805 rol A4 $ rol A5 $ rol A6 $ rol A7
810 ;; We expanded the Result in C[]
811 ;; Copy Result to the Return Register A[]
835 #endif /* HAVE_MUL */
855 #endif /* L_muldi3 */
857 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
860 .section .text.libgcc.div, "ax", @progbits
862 /*******************************************************
863 Division 8 / 8 => (result + remainder)
864 *******************************************************/
865 #define r_rem r25 /* remainder */
866 #define r_arg1 r24 /* dividend, quotient */
867 #define r_arg2 r22 /* divisor */
868 #define r_cnt r23 /* loop count */
870 #if defined (L_udivmodqi4)
872 sub r_rem,r_rem ; clear remainder and carry
873 ldi r_cnt,9 ; init loop counter
874 rjmp __udivmodqi4_ep ; jump to entry point
876 rol r_rem ; shift dividend into remainder
877 cp r_rem,r_arg2 ; compare remainder & divisor
878 brcs __udivmodqi4_ep ; remainder <= divisor
879 sub r_rem,r_arg2 ; restore remainder
881 rol r_arg1 ; shift dividend (with CARRY)
882 dec r_cnt ; decrement loop counter
883 brne __udivmodqi4_loop
884 com r_arg1 ; complement result
885 ; because C flag was complemented in loop
888 #endif /* defined (L_udivmodqi4) */
890 #if defined (L_divmodqi4)
892 bst r_arg1,7 ; store sign of dividend
893 mov __tmp_reg__,r_arg1
894 eor __tmp_reg__,r_arg2; r0.7 is sign of result
896 neg r_arg1 ; dividend negative : negate
898 neg r_arg2 ; divisor negative : negate
899 XCALL __udivmodqi4 ; do the unsigned div/mod
901 neg r_rem ; correct remainder sign
904 neg r_arg1 ; correct result sign
908 #endif /* defined (L_divmodqi4) */
916 /*******************************************************
917 Division 16 / 16 => (result + remainder)
918 *******************************************************/
919 #define r_remL r26 /* remainder Low */
920 #define r_remH r27 /* remainder High */
922 /* return: remainder */
923 #define r_arg1L r24 /* dividend Low */
924 #define r_arg1H r25 /* dividend High */
926 /* return: quotient */
927 #define r_arg2L r22 /* divisor Low */
928 #define r_arg2H r23 /* divisor High */
930 #define r_cnt r21 /* loop count */
932 #if defined (L_udivmodhi4)
935 sub r_remH,r_remH ; clear remainder and carry
936 ldi r_cnt,17 ; init loop counter
937 rjmp __udivmodhi4_ep ; jump to entry point
939 rol r_remL ; shift dividend into remainder
941 cp r_remL,r_arg2L ; compare remainder & divisor
943 brcs __udivmodhi4_ep ; remainder < divisor
944 sub r_remL,r_arg2L ; restore remainder
947 rol r_arg1L ; shift dividend (with CARRY)
949 dec r_cnt ; decrement loop counter
950 brne __udivmodhi4_loop
953 ; div/mod results to return registers, as for the div() function
954 mov_l r_arg2L, r_arg1L ; quotient
955 mov_h r_arg2H, r_arg1H
956 mov_l r_arg1L, r_remL ; remainder
957 mov_h r_arg1H, r_remH
960 #endif /* defined (L_udivmodhi4) */
962 #if defined (L_divmodhi4)
966 bst r_arg1H,7 ; store sign of dividend
967 mov __tmp_reg__,r_arg2H
969 com __tmp_reg__ ; r0.7 is sign of result
970 rcall __divmodhi4_neg1 ; dividend negative: negate
973 rcall __divmodhi4_neg2 ; divisor negative: negate
974 XCALL __udivmodhi4 ; do the unsigned div/mod
976 rcall __divmodhi4_neg2 ; correct remainder sign
977 brtc __divmodhi4_exit
979 ;; correct dividend/remainder sign
985 ;; correct divisor/result sign
992 #endif /* defined (L_divmodhi4) */
1005 /*******************************************************
1006 Division 24 / 24 => (result + remainder)
1007 *******************************************************/
1009 ;; A[0..2]: In: Dividend; Out: Quotient
1014 ;; B[0..2]: In: Divisor; Out: Remainder
1019 ;; C[0..2]: Expand remainder
1020 #define C0 __zero_reg__
1027 #if defined (L_udivmodpsi4)
1028 ;; R24:R22 = R24:R22 udiv R20:R18
1029 ;; R20:R18 = R24:R22 umod R20:R18
1030 ;; Clobbers: R21, R25, R26
1035 ; Clear remainder and carry. C0 is already 0
1038 ; jump to entry point
1039 rjmp __udivmodpsi4_start
1041 ; shift dividend into remainder
1045 ; compare remainder & divisor
1049 brcs __udivmodpsi4_start ; remainder <= divisor
1050 sub C0, B0 ; restore remainder
1053 __udivmodpsi4_start:
1054 ; shift dividend (with CARRY)
1058 ; decrement loop counter
1060 brne __udivmodpsi4_loop
1064 ; div/mod results to return registers
1069 clr __zero_reg__ ; C0
1072 #endif /* defined (L_udivmodpsi4) */
1074 #if defined (L_divmodpsi4)
1075 ;; R24:R22 = R24:R22 div R20:R18
1076 ;; R20:R18 = R24:R22 mod R20:R18
1077 ;; Clobbers: T, __tmp_reg__, R21, R25, R26
1080 ; R0.7 will contain the sign of the result:
1081 ; R0.7 = A.sign ^ B.sign
1083 ; T-flag = sign of dividend
1087 ; Adjust dividend's sign
1088 rcall __divmodpsi4_negA
1090 ; Adjust divisor's sign
1092 rcall __divmodpsi4_negB
1094 ; Do the unsigned div/mod
1097 ; Adjust quotient's sign
1099 rcall __divmodpsi4_negA
1101 ; Adjust remainder's sign
1102 brtc __divmodpsi4_end
1105 ; Correct divisor/remainder sign
1113 ; Correct dividend/quotient sign
1124 #endif /* defined (L_divmodpsi4) */
1140 /*******************************************************
1141 Division 32 / 32 => (result + remainder)
1142 *******************************************************/
1143 #define r_remHH r31 /* remainder High */
1146 #define r_remL r26 /* remainder Low */
1148 /* return: remainder */
1149 #define r_arg1HH r25 /* dividend High */
1150 #define r_arg1HL r24
1152 #define r_arg1L r22 /* dividend Low */
1154 /* return: quotient */
1155 #define r_arg2HH r21 /* divisor High */
1156 #define r_arg2HL r20
1158 #define r_arg2L r18 /* divisor Low */
1160 #define r_cnt __zero_reg__ /* loop count (0 after the loop!) */
1162 #if defined (L_udivmodsi4)
1164 ldi r_remL, 33 ; init loop counter
1167 sub r_remH,r_remH ; clear remainder and carry
1168 mov_l r_remHL, r_remL
1169 mov_h r_remHH, r_remH
1170 rjmp __udivmodsi4_ep ; jump to entry point
1172 rol r_remL ; shift dividend into remainder
1176 cp r_remL,r_arg2L ; compare remainder & divisor
1178 cpc r_remHL,r_arg2HL
1179 cpc r_remHH,r_arg2HH
1180 brcs __udivmodsi4_ep ; remainder <= divisor
1181 sub r_remL,r_arg2L ; restore remainder
1183 sbc r_remHL,r_arg2HL
1184 sbc r_remHH,r_arg2HH
1186 rol r_arg1L ; shift dividend (with CARRY)
1190 dec r_cnt ; decrement loop counter
1191 brne __udivmodsi4_loop
1192 ; __zero_reg__ now restored (r_cnt == 0)
1197 ; div/mod results to return registers, as for the ldiv() function
1198 mov_l r_arg2L, r_arg1L ; quotient
1199 mov_h r_arg2H, r_arg1H
1200 mov_l r_arg2HL, r_arg1HL
1201 mov_h r_arg2HH, r_arg1HH
1202 mov_l r_arg1L, r_remL ; remainder
1203 mov_h r_arg1H, r_remH
1204 mov_l r_arg1HL, r_remHL
1205 mov_h r_arg1HH, r_remHH
1208 #endif /* defined (L_udivmodsi4) */
1210 #if defined (L_divmodsi4)
1212 mov __tmp_reg__,r_arg2HH
1213 bst r_arg1HH,7 ; store sign of dividend
1215 com __tmp_reg__ ; r0.7 is sign of result
1216 rcall __divmodsi4_neg1 ; dividend negative: negate
1219 rcall __divmodsi4_neg2 ; divisor negative: negate
1220 XCALL __udivmodsi4 ; do the unsigned div/mod
1221 sbrc __tmp_reg__, 7 ; correct quotient sign
1222 rcall __divmodsi4_neg2
1223 brtc __divmodsi4_exit ; correct remainder sign
1225 ;; correct dividend/remainder sign
1235 ;; correct divisor/quotient sign
1246 #endif /* defined (L_divmodsi4) */
1249 /*******************************************************
1252 *******************************************************/
1254 ;; Use Speed-optimized Version on "big" Devices, i.e. Devices with
1255 ;; at least 16k of Program Memory. For smaller Devices, depend
1258 #if defined (__AVR_HAVE_JMP_CALL__)
1259 # define SPEED_DIV 8
1260 #elif defined (__AVR_HAVE_MOVW__)
1261 # define SPEED_DIV 16
1263 # define SPEED_DIV 0
1266 ;; A[0..7]: In: Dividend;
1267 ;; Out: Quotient (T = 0)
1268 ;; Out: Remainder (T = 1)
1278 ;; B[0..7]: In: Divisor; Out: Clobber
1288 ;; C[0..7]: Expand remainder; Out: Remainder (unused)
1298 ;; Holds Signs during Division Routine
1299 #define SS __tmp_reg__
1301 ;; Bit-Counter in Division Routine
1302 #define R_cnt __zero_reg__
1304 ;; Scratch Register for Negation
1307 #if defined (L_udivdi3)
1309 ;; R25:R18 = R24:R18 umod R17:R10
1310 ;; Ordinary ABI-Function
1314 rjmp __udivdi3_umoddi3
1317 ;; R25:R18 = R24:R18 udiv R17:R10
1318 ;; Ordinary ABI-Function
1324 DEFUN __udivdi3_umoddi3
1335 ENDF __udivdi3_umoddi3
1336 #endif /* L_udivdi3 */
1338 #if defined (L_udivmod64)
1340 ;; Worker Routine for 64-Bit unsigned Quotient and Remainder Computation
1341 ;; No Registers saved/restored; the Callers will take Care.
1342 ;; Preserves B[] and T-flag
1343 ;; T = 0: Compute Quotient in A[]
1344 ;; T = 1: Compute Remainder in A[] and shift SS one Bit left
1348 ;; Clear Remainder (C6, C7 will follow)
1355 #if SPEED_DIV == 0 || SPEED_DIV == 16
1356 ;; Initialize Loop-Counter
1359 #endif /* SPEED_DIV */
1366 1: ;; Compare shifted Devidend against Divisor
1367 ;; If -- even after Shifting -- it is smaller...
1368 CP A7,B0 $ cpc C0,B1 $ cpc C1,B2 $ cpc C2,B3
1369 cpc C3,B4 $ cpc C4,B5 $ cpc C5,B6 $ cpc C6,B7
1372 ;; ...then we can subtract it. Thus, it is legal to shift left
1373 $ mov C6,C5 $ mov C5,C4 $ mov C4,C3
1374 mov C3,C2 $ mov C2,C1 $ mov C1,C0 $ mov C0,A7
1375 mov A7,A6 $ mov A6,A5 $ mov A5,A4 $ mov A4,A3
1376 mov A3,A2 $ mov A2,A1 $ mov A1,A0 $ clr A0
1382 ;; Shifted 64 Bits: A7 has traveled to C7
1384 ;; Divisor is greater than Dividend. We have:
1387 ;; Thus, we can return immediately
1390 2: ;; Initialze Bit-Counter with Number of Bits still to be performed
1393 ;; Push of A7 is not needed because C7 is still 0
1397 #elif SPEED_DIV == 16
1399 ;; Compare shifted Dividend against Divisor
1407 ;; Divisor is greater than shifted Dividen: We can shift the Dividend
1408 ;; and it is still smaller than the Divisor --> Shift one 32-Bit Chunk
1409 wmov C2,A6 $ wmov C0,A4
1410 wmov A6,A2 $ wmov A4,A0
1411 wmov A2,C6 $ wmov A0,C4
1413 ;; Set Bit Counter to 32
1417 #error SPEED_DIV = ?
1418 #endif /* SPEED_DIV */
1420 ;; The very Division + Remainder Routine
1422 3: ;; Left-shift Dividend...
1423 lsl A0 $ rol A1 $ rol A2 $ rol A3
1424 rol A4 $ rol A5 $ rol A6 $ rol A7
1426 ;; ...into Remainder
1427 rol C0 $ rol C1 $ rol C2 $ rol C3
1428 rol C4 $ rol C5 $ rol C6 $ rol C7
1430 ;; Compare Remainder and Divisor
1431 CP C0,B0 $ cpc C1,B1 $ cpc C2,B2 $ cpc C3,B3
1432 cpc C4,B4 $ cpc C5,B5 $ cpc C6,B6 $ cpc C7,B7
1436 ;; Divisor fits into Remainder: Subtract it from Remainder...
1437 SUB C0,B0 $ sbc C1,B1 $ sbc C2,B2 $ sbc C3,B3
1438 sbc C4,B4 $ sbc C5,B5 $ sbc C6,B6 $ sbc C7,B7
1440 ;; ...and set according Bit in the upcoming Quotient
1441 ;; The Bit will travel to its final Position
1444 4: ;; This Bit is done
1447 ;; __zero_reg__ is 0 again
1449 ;; T = 0: We are fine with the Quotient in A[]
1450 ;; T = 1: Copy Remainder to A[]
1456 ;; Move the Sign of the Result to SS.7
1462 #endif /* L_udivmod64 */
1465 #if defined (L_divdi3)
1467 ;; R25:R18 = R24:R18 mod R17:R10
1468 ;; Ordinary ABI-Function
1472 rjmp __divdi3_moddi3
1475 ;; R25:R18 = R24:R18 div R17:R10
1476 ;; Ordinary ABI-Function
1482 DEFUN __divdi3_moddi3
1487 ;; Both Signs are 0: the following Complexitiy is not needed
1488 XJMP __udivdi3_umoddi3
1489 #endif /* SPEED_DIV */
1492 ;; Save 12 Registers: Y, 17...8
1493 ;; No Frame needed (X = 0)
1496 ldi r30, lo8(gs(1f))
1497 ldi r31, hi8(gs(1f))
1498 XJMP __prologue_saves__ + ((18 - 12) * 2)
1500 1: ;; SS.7 will contain the Sign of the Quotient (A.sign * B.sign)
1501 ;; SS.6 will contain the Sign of the Remainder (A.sign)
1504 ;; Adjust Dividend's Sign as needed
1506 ;; Compiling for Speed we know that at least one Sign must be < 0
1507 ;; Thus, if A[] >= 0 then we know B[] < 0
1511 #endif /* SPEED_DIV */
1515 ;; Adjust Divisor's Sign and SS.7 as needed
1522 com B4 $ com B5 $ com B6 $ com B7
1523 $ com B1 $ com B2 $ com B3
1525 $ sbc B1,NN $ sbc B2,NN $ sbc B3,NN
1526 sbc B4,NN $ sbc B5,NN $ sbc B6,NN $ sbc B7,NN
1528 3: ;; Do the unsigned 64-Bit Division/Modulo (depending on T-flag)
1531 ;; Adjust Result's Sign
1532 #ifdef __AVR_ERRATA_SKIP_JMP_CALL__
1537 #endif /* __AVR_HAVE_JMP_CALL__ */
1540 4: ;; Epilogue: Restore the Z = 12 Registers and return
1542 #if defined (__AVR_HAVE_8BIT_SP__)
1543 ;; FIXME: __AVR_HAVE_8BIT_SP__ is set on device level, not on core level
1544 ;; so this lines are dead code. To make it work, devices without
1545 ;; SP_H must get their own multilib(s).
1549 #endif /* #SP = 8/16 */
1551 XJMP __epilogue_restores__ + ((18 - 12) * 2)
1553 ENDF __divdi3_moddi3
1559 #endif /* L_divdi3 */
1561 .section .text.libgcc, "ax", @progbits
1563 #define TT __tmp_reg__
1565 #if defined (L_adddi3)
1567 ;; (plus:DI (reg:DI 18)
1570 ADD A0,B0 $ adc A1,B1 $ adc A2,B2 $ adc A3,B3
1571 adc A4,B4 $ adc A5,B5 $ adc A6,B6 $ adc A7,B7
1574 #endif /* L_adddi3 */
1576 #if defined (L_adddi3_s8)
1578 ;; (plus:DI (reg:DI 18)
1579 ;; (sign_extend:SI (reg:QI 26))))
1584 ADD A0,r26 $ adc A1,TT $ adc A2,TT $ adc A3,TT
1585 adc A4,TT $ adc A5,TT $ adc A6,TT $ adc A7,TT
1588 #endif /* L_adddi3_s8 */
1590 #if defined (L_subdi3)
1592 ;; (minus:DI (reg:DI 18)
1595 SUB A0,B0 $ sbc A1,B1 $ sbc A2,B2 $ sbc A3,B3
1596 sbc A4,B4 $ sbc A5,B5 $ sbc A6,B6 $ sbc A7,B7
1599 #endif /* L_subdi3 */
1601 #if defined (L_cmpdi2)
1603 ;; (compare (reg:DI 18)
1606 CP A0,B0 $ cpc A1,B1 $ cpc A2,B2 $ cpc A3,B3
1607 cpc A4,B4 $ cpc A5,B5 $ cpc A6,B6 $ cpc A7,B7
1610 #endif /* L_cmpdi2 */
1612 #if defined (L_cmpdi2_s8)
1614 ;; (compare (reg:DI 18)
1615 ;; (sign_extend:SI (reg:QI 26))))
1620 CP A0,r26 $ cpc A1,TT $ cpc A2,TT $ cpc A3,TT
1621 cpc A4,TT $ cpc A5,TT $ cpc A6,TT $ cpc A7,TT
1624 #endif /* L_cmpdi2_s8 */
1626 #if defined (L_negdi2)
1629 com A4 $ com A5 $ com A6 $ com A7
1630 $ com A1 $ com A2 $ com A3
1632 $ sbci A1,-1 $ sbci A2,-1 $ sbci A3,-1
1633 sbci A4,-1 $ sbci A5,-1 $ sbci A6,-1 $ sbci A7,-1
1637 #endif /* L_negdi2 */
1669 .section .text.libgcc.prologue, "ax", @progbits
1671 /**********************************
1672 * This is a prologue subroutine
1673 **********************************/
1674 #if defined (L_prologue)
1676 ;; This function does not clobber T-flag; 64-bit division relies on it
1677 DEFUN __prologue_saves__
1696 #if defined (__AVR_HAVE_8BIT_SP__)
1697 ;; FIXME: __AVR_HAVE_8BIT_SP__ is set on device level, not on core level
1698 ;; so this lines are dead code. To make it work, devices without
1699 ;; SP_H must get their own multilib(s).
1709 in __tmp_reg__,__SREG__
1712 out __SREG__,__tmp_reg__
1714 #endif /* #SP = 8/16 */
1716 #if defined (__AVR_HAVE_EIJMP_EICALL__)
1722 ENDF __prologue_saves__
1723 #endif /* defined (L_prologue) */
1726 * This is an epilogue subroutine
1728 #if defined (L_epilogue)
1730 DEFUN __epilogue_restores__
1748 #if defined (__AVR_HAVE_8BIT_SP__)
1749 ;; FIXME: __AVR_HAVE_8BIT_SP__ is set on device level, not on core level
1750 ;; so this lines are dead code. To make it work, devices without
1751 ;; SP_H must get their own multilib(s).
1759 adc r29,__zero_reg__
1760 in __tmp_reg__,__SREG__
1763 out __SREG__,__tmp_reg__
1767 #endif /* #SP = 8/16 */
1769 ENDF __epilogue_restores__
1770 #endif /* defined (L_epilogue) */
1773 .section .fini9,"ax",@progbits
1779 /* Code from .fini8 ... .fini1 sections inserted by ld script. */
1781 .section .fini0,"ax",@progbits
1785 #endif /* defined (L_exit) */
1793 #endif /* defined (L_cleanup) */
1796 .section .text.libgcc, "ax", @progbits
1799 DEFUN __tablejump2__
1806 #if defined (__AVR_HAVE_LPMX__)
1809 mov r30, __tmp_reg__
1810 #if defined (__AVR_HAVE_EIJMP_EICALL__)
1816 #else /* !HAVE_LPMX */
1822 #if defined (__AVR_HAVE_EIJMP_EICALL__)
1823 in __tmp_reg__, __EIND__
1827 #endif /* !HAVE_LPMX */
1829 #endif /* defined (L_tablejump) */
1832 .section .init4,"ax",@progbits
1833 DEFUN __do_copy_data
1834 #if defined(__AVR_HAVE_ELPMX__)
1835 ldi r17, hi8(__data_end)
1836 ldi r26, lo8(__data_start)
1837 ldi r27, hi8(__data_start)
1838 ldi r30, lo8(__data_load_start)
1839 ldi r31, hi8(__data_load_start)
1840 ldi r16, hh8(__data_load_start)
1842 rjmp .L__do_copy_data_start
1843 .L__do_copy_data_loop:
1846 .L__do_copy_data_start:
1847 cpi r26, lo8(__data_end)
1849 brne .L__do_copy_data_loop
1850 #elif !defined(__AVR_HAVE_ELPMX__) && defined(__AVR_HAVE_ELPM__)
1851 ldi r17, hi8(__data_end)
1852 ldi r26, lo8(__data_start)
1853 ldi r27, hi8(__data_start)
1854 ldi r30, lo8(__data_load_start)
1855 ldi r31, hi8(__data_load_start)
1856 ldi r16, hh8(__data_load_start - 0x10000)
1857 .L__do_copy_data_carry:
1860 rjmp .L__do_copy_data_start
1861 .L__do_copy_data_loop:
1865 brcs .L__do_copy_data_carry
1866 .L__do_copy_data_start:
1867 cpi r26, lo8(__data_end)
1869 brne .L__do_copy_data_loop
1870 #elif !defined(__AVR_HAVE_ELPMX__) && !defined(__AVR_HAVE_ELPM__)
1871 ldi r17, hi8(__data_end)
1872 ldi r26, lo8(__data_start)
1873 ldi r27, hi8(__data_start)
1874 ldi r30, lo8(__data_load_start)
1875 ldi r31, hi8(__data_load_start)
1876 rjmp .L__do_copy_data_start
1877 .L__do_copy_data_loop:
1878 #if defined (__AVR_HAVE_LPMX__)
1885 .L__do_copy_data_start:
1886 cpi r26, lo8(__data_end)
1888 brne .L__do_copy_data_loop
1889 #endif /* !defined(__AVR_HAVE_ELPMX__) && !defined(__AVR_HAVE_ELPM__) */
1891 #endif /* L_copy_data */
1893 /* __do_clear_bss is only necessary if there is anything in .bss section. */
1896 .section .init4,"ax",@progbits
1897 DEFUN __do_clear_bss
1898 ldi r17, hi8(__bss_end)
1899 ldi r26, lo8(__bss_start)
1900 ldi r27, hi8(__bss_start)
1901 rjmp .do_clear_bss_start
1904 .do_clear_bss_start:
1905 cpi r26, lo8(__bss_end)
1907 brne .do_clear_bss_loop
1909 #endif /* L_clear_bss */
1911 /* __do_global_ctors and __do_global_dtors are only necessary
1912 if there are any constructors/destructors. */
1915 .section .init6,"ax",@progbits
1916 DEFUN __do_global_ctors
1917 #if defined(__AVR_HAVE_RAMPZ__)
1918 ldi r17, hi8(__ctors_start)
1919 ldi r28, lo8(__ctors_end)
1920 ldi r29, hi8(__ctors_end)
1921 ldi r16, hh8(__ctors_end)
1922 rjmp .L__do_global_ctors_start
1923 .L__do_global_ctors_loop:
1925 sbc r16, __zero_reg__
1929 XCALL __tablejump_elpm__
1930 .L__do_global_ctors_start:
1931 cpi r28, lo8(__ctors_start)
1933 ldi r24, hh8(__ctors_start)
1935 brne .L__do_global_ctors_loop
1937 ldi r17, hi8(__ctors_start)
1938 ldi r28, lo8(__ctors_end)
1939 ldi r29, hi8(__ctors_end)
1940 rjmp .L__do_global_ctors_start
1941 .L__do_global_ctors_loop:
1946 .L__do_global_ctors_start:
1947 cpi r28, lo8(__ctors_start)
1949 brne .L__do_global_ctors_loop
1950 #endif /* defined(__AVR_HAVE_RAMPZ__) */
1951 ENDF __do_global_ctors
1952 #endif /* L_ctors */
1955 .section .fini6,"ax",@progbits
1956 DEFUN __do_global_dtors
1957 #if defined(__AVR_HAVE_RAMPZ__)
1958 ldi r17, hi8(__dtors_end)
1959 ldi r28, lo8(__dtors_start)
1960 ldi r29, hi8(__dtors_start)
1961 ldi r16, hh8(__dtors_start)
1962 rjmp .L__do_global_dtors_start
1963 .L__do_global_dtors_loop:
1965 sbc r16, __zero_reg__
1969 XCALL __tablejump_elpm__
1970 .L__do_global_dtors_start:
1971 cpi r28, lo8(__dtors_end)
1973 ldi r24, hh8(__dtors_end)
1975 brne .L__do_global_dtors_loop
1977 ldi r17, hi8(__dtors_end)
1978 ldi r28, lo8(__dtors_start)
1979 ldi r29, hi8(__dtors_start)
1980 rjmp .L__do_global_dtors_start
1981 .L__do_global_dtors_loop:
1986 .L__do_global_dtors_start:
1987 cpi r28, lo8(__dtors_end)
1989 brne .L__do_global_dtors_loop
1990 #endif /* defined(__AVR_HAVE_RAMPZ__) */
1991 ENDF __do_global_dtors
1992 #endif /* L_dtors */
1994 .section .text.libgcc, "ax", @progbits
1996 #ifdef L_tablejump_elpm
1997 DEFUN __tablejump_elpm__
1998 #if defined (__AVR_HAVE_ELPM__)
1999 #if defined (__AVR_HAVE_LPMX__)
2000 elpm __tmp_reg__, Z+
2002 mov r30, __tmp_reg__
2003 #if defined (__AVR_HAVE_EIJMP_EICALL__)
2015 #if defined (__AVR_HAVE_EIJMP_EICALL__)
2016 in __tmp_reg__, __EIND__
2021 #endif /* defined (__AVR_HAVE_ELPM__) */
2022 ENDF __tablejump_elpm__
2023 #endif /* defined (L_tablejump_elpm) */
2025 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2026 ;; Loading n bytes from Flash; n = 3,4
2027 ;; R22... = Flash[Z]
2028 ;; Clobbers: __tmp_reg__
2030 #if (defined (L_load_3) \
2031 || defined (L_load_4)) \
2032 && !defined (__AVR_HAVE_LPMX__)
2040 .macro .load dest, n
2043 .if \dest != D0+\n-1
2050 #if defined (L_load_3)
2057 #endif /* L_load_3 */
2059 #if defined (L_load_4)
2067 #endif /* L_load_4 */
2069 #endif /* L_load_3 || L_load_3 */
2071 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2072 ;; Loading n bytes from Flash; n = 2,3,4
2073 ;; R22... = Flash[R21:Z]
2074 ;; Clobbers: __tmp_reg__, R21, R30, R31
2076 #if (defined (L_xload_2) \
2077 || defined (L_xload_3) \
2078 || defined (L_xload_4)) \
2079 && defined (__AVR_HAVE_ELPM__) \
2080 && !defined (__AVR_HAVE_ELPMX__)
2082 #if !defined (__AVR_HAVE_RAMPZ__)
2084 #endif /* have RAMPZ */
2092 ;; Register containing bits 16+ of the address
2096 .macro .xload dest, n
2099 .if \dest != D0+\n-1
2101 adc HHI8, __zero_reg__
2106 #if defined (L_xload_2)
2113 #endif /* L_xload_2 */
2115 #if defined (L_xload_3)
2123 #endif /* L_xload_3 */
2125 #if defined (L_xload_4)
2134 #endif /* L_xload_4 */
2136 #endif /* L_xload_{2|3|4} && ELPM */
2139 .section .text.libgcc.builtins, "ax", @progbits
2141 /**********************************
2142 * Find first set Bit (ffs)
2143 **********************************/
2145 #if defined (L_ffssi2)
2146 ;; find first set bit
2147 ;; r25:r24 = ffs32 (r25:r22)
2148 ;; clobbers: r22, r26
2166 #endif /* defined (L_ffssi2) */
2168 #if defined (L_ffshi2)
2169 ;; find first set bit
2170 ;; r25:r24 = ffs16 (r25:r24)
2174 #ifdef __AVR_ERRATA_SKIP_JMP_CALL__
2175 ;; Some cores have problem skipping 2-word instruction
2179 cpse r24, __zero_reg__
2180 #endif /* __AVR_HAVE_JMP_CALL__ */
2181 1: XJMP __loop_ffsqi2
2187 #endif /* defined (L_ffshi2) */
2189 #if defined (L_loop_ffsqi2)
2190 ;; Helper for ffshi2, ffssi2
2191 ;; r25:r24 = r26 + zero_extend16 (ffs8(r24))
2202 #endif /* defined (L_loop_ffsqi2) */
2205 /**********************************
2206 * Count trailing Zeros (ctz)
2207 **********************************/
2209 #if defined (L_ctzsi2)
2210 ;; count trailing zeros
2211 ;; r25:r24 = ctz32 (r25:r22)
2212 ;; clobbers: r26, r22
2214 ;; Note that ctz(0) in undefined for GCC
2220 #endif /* defined (L_ctzsi2) */
2222 #if defined (L_ctzhi2)
2223 ;; count trailing zeros
2224 ;; r25:r24 = ctz16 (r25:r24)
2227 ;; Note that ctz(0) in undefined for GCC
2233 #endif /* defined (L_ctzhi2) */
2236 /**********************************
2237 * Count leading Zeros (clz)
2238 **********************************/
2240 #if defined (L_clzdi2)
2241 ;; count leading zeros
2242 ;; r25:r24 = clz64 (r25:r18)
2243 ;; clobbers: r22, r23, r26
2256 #endif /* defined (L_clzdi2) */
2258 #if defined (L_clzsi2)
2259 ;; count leading zeros
2260 ;; r25:r24 = clz32 (r25:r22)
2272 #endif /* defined (L_clzsi2) */
2274 #if defined (L_clzhi2)
2275 ;; count leading zeros
2276 ;; r25:r24 = clz16 (r25:r24)
2298 #endif /* defined (L_clzhi2) */
2301 /**********************************
2303 **********************************/
2305 #if defined (L_paritydi2)
2306 ;; r25:r24 = parity64 (r25:r18)
2307 ;; clobbers: __tmp_reg__
2315 #endif /* defined (L_paritydi2) */
2317 #if defined (L_paritysi2)
2318 ;; r25:r24 = parity32 (r25:r22)
2319 ;; clobbers: __tmp_reg__
2325 #endif /* defined (L_paritysi2) */
2327 #if defined (L_parityhi2)
2328 ;; r25:r24 = parity16 (r25:r24)
2329 ;; clobbers: __tmp_reg__
2335 ;; r25:r24 = parity8 (r24)
2336 ;; clobbers: __tmp_reg__
2338 ;; parity is in r24[0..7]
2339 mov __tmp_reg__, r24
2341 eor r24, __tmp_reg__
2342 ;; parity is in r24[0..3]
2346 ;; parity is in r24[0,3]
2349 ;; parity is in r24[0]
2354 #endif /* defined (L_parityhi2) */
2357 /**********************************
2359 **********************************/
2361 #if defined (L_popcounthi2)
2363 ;; r25:r24 = popcount16 (r25:r24)
2364 ;; clobbers: __tmp_reg__
2374 DEFUN __popcounthi2_tail
2376 add r24, __tmp_reg__
2378 ENDF __popcounthi2_tail
2379 #endif /* defined (L_popcounthi2) */
2381 #if defined (L_popcountsi2)
2383 ;; r25:r24 = popcount32 (r25:r22)
2384 ;; clobbers: __tmp_reg__
2391 XJMP __popcounthi2_tail
2393 #endif /* defined (L_popcountsi2) */
2395 #if defined (L_popcountdi2)
2397 ;; r25:r24 = popcount64 (r25:r18)
2398 ;; clobbers: r22, r23, __tmp_reg__
2407 XJMP __popcounthi2_tail
2409 #endif /* defined (L_popcountdi2) */
2411 #if defined (L_popcountqi2)
2413 ;; r24 = popcount8 (r24)
2414 ;; clobbers: __tmp_reg__
2416 mov __tmp_reg__, r24
2420 adc r24, __zero_reg__
2422 adc r24, __zero_reg__
2424 adc r24, __zero_reg__
2426 adc r24, __zero_reg__
2428 adc r24, __zero_reg__
2430 adc r24, __tmp_reg__
2433 #endif /* defined (L_popcountqi2) */
2436 /**********************************
2438 **********************************/
2440 ;; swap two registers with different register number
2447 #if defined (L_bswapsi2)
2449 ;; r25:r22 = bswap32 (r25:r22)
2455 #endif /* defined (L_bswapsi2) */
2457 #if defined (L_bswapdi2)
2459 ;; r25:r18 = bswap64 (r25:r18)
2467 #endif /* defined (L_bswapdi2) */
2470 /**********************************
2472 **********************************/
2474 #if defined (L_ashrdi3)
2475 ;; Arithmetic shift right
2476 ;; r25:r18 = ashr64 (r25:r18, r17:r16)
2494 #endif /* defined (L_ashrdi3) */
2496 #if defined (L_lshrdi3)
2497 ;; Logic shift right
2498 ;; r25:r18 = lshr64 (r25:r18, r17:r16)
2516 #endif /* defined (L_lshrdi3) */
2518 #if defined (L_ashldi3)
2520 ;; r25:r18 = ashl64 (r25:r18, r17:r16)
2538 #endif /* defined (L_ashldi3) */
2540 #if defined (L_rotldi3)
2542 ;; r25:r18 = rotl64 (r25:r18, r17:r16)
2555 adc r18, __zero_reg__
2561 #endif /* defined (L_rotldi3) */
2564 .section .text.libgcc.fmul, "ax", @progbits
2566 /***********************************************************/
2567 ;;; Softmul versions of FMUL, FMULS and FMULSU to implement
2568 ;;; __builtin_avr_fmul* if !AVR_HAVE_MUL
2569 /***********************************************************/
2575 #define A0 __tmp_reg__
2578 ;;; r23:r22 = fmuls (r24, r25) like in FMULS instruction
2579 ;;; Clobbers: r24, r25, __tmp_reg__
2581 ;; A0.7 = negate result?
2589 #endif /* L_fmuls */
2592 ;;; r23:r22 = fmulsu (r24, r25) like in FMULSU instruction
2593 ;;; Clobbers: r24, r25, __tmp_reg__
2595 ;; A0.7 = negate result?
2600 ;; Helper for __fmuls and __fmulsu
2605 #ifdef __AVR_ERRATA_SKIP_JMP_CALL__
2606 ;; Some cores have problem skipping 2-word instruction
2611 #endif /* __AVR_HAVE_JMP_CALL__ */
2614 ;; C = -C iff A0.7 = 1
2620 #endif /* L_fmulsu */
2624 ;;; r22:r23 = fmul (r24, r25) like in FMUL instruction
2625 ;;; Clobbers: r24, r25, __tmp_reg__
2632 ;; 1.0 = 0x80, so test for bit 7 of B to see if A must to be added to C.