aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S')
-rw-r--r--contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S57
1 files changed, 57 insertions, 0 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S b/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S
new file mode 100644
index 000000000000..37171331f4b3
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/builtins/avr/divmodhi4.S
@@ -0,0 +1,57 @@
+//===------------- divmodhi4.S - sint16 div & mod -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// As described at
+// https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention, the
+// prototype is `struct {sint16, sint16} __divmodhi4(sint16, sint16)`.
+// The sint16 quotient is returned via R23:R22, and the sint16 remainder is
+// returned via R25:R24, while registers R21/R26/27/Rtmp and bit T in SREG
+// are clobbered.
+//
+//===----------------------------------------------------------------------===//
+
+ .text
+ .align 2
+
+#ifdef __AVR_TINY__
+ .set __tmp_reg__, 16
+#else
+ .set __tmp_reg__, 0
+#endif
+
+ .globl __divmodhi4
+ .type __divmodhi4, @function
+
+__divmodhi4:
+ bst r25, 7
+ mov __tmp_reg__, r23
+ brtc __divmodhi4_a
+ com __tmp_reg__
+ rcall __divmodhi4_b
+
+__divmodhi4_a:
+ sbrc r23, 7
+ rcall __divmodhi4_c
+ rcall __udivmodhi4 ; Call __udivmodhi4 to do real calculation.
+ sbrc __tmp_reg__, 7
+ rcall __divmodhi4_c
+ brtc __divmodhi4_exit
+
+__divmodhi4_b:
+ com r25
+ neg r24
+ sbci r25, 255
+ ret ; Return quotient via R23:R22 and remainder via R25:R24.
+
+__divmodhi4_c:
+ com r23
+ neg r22
+ sbci r23, 255
+
+__divmodhi4_exit:
+ ret ; Return quotient via R23:R22 and remainder via R25:r24.