Index: gcc/gcc/config/arm/bpabi.S |
diff --git a/gcc/gcc/config/arm/bpabi.S b/gcc/gcc/config/arm/bpabi.S |
index 850381e4af6423ad132f6fbb35e23438632489a3..ccc569e982180ea35e61753249856dea450bcdf6 100644 |
--- a/gcc/gcc/config/arm/bpabi.S |
+++ b/gcc/gcc/config/arm/bpabi.S |
@@ -64,9 +64,57 @@ ARM_FUNC_START aeabi_ulcmp |
#endif /* L_aeabi_ulcmp */ |
+.macro test_div_by_zero signed |
+/* Tail-call to divide-by-zero handlers which may be overridden by the user, |
+ so unwinding works properly. */ |
+#if defined(__thumb2__) |
+ cbnz yyh, 1f |
+ cbnz yyl, 1f |
+ cmp xxh, #0 |
+ do_it eq |
+ cmpeq xxl, #0 |
+ .ifc \signed, unsigned |
+ beq 2f |
+ mov xxh, #0xffffffff |
+ mov xxl, xxh |
+2: |
+ .else |
+ do_it lt, t |
+ movlt xxl, #0 |
+ movlt xxh, #0x80000000 |
+ do_it gt, t |
+ movgt xxh, #0x7fffffff |
+ movgt xxl, #0xffffffff |
+ .endif |
+ b SYM (__aeabi_ldiv0) __PLT__ |
+1: |
+#else |
+ /* Note: Thumb-1 code calls via an ARM shim on processors which |
+ support ARM mode. */ |
+ cmp yyh, #0 |
+ cmpeq yyl, #0 |
+ bne 2f |
+ cmp xxh, #0 |
+ cmpeq xxl, #0 |
+ .ifc \signed, unsigned |
+ movne xxh, #0xffffffff |
+ movne xxl, #0xffffffff |
+ .else |
+ movlt xxh, #0x80000000 |
+ movlt xxl, #0 |
+ movgt xxh, #0x7fffffff |
+ movgt xxl, #0xffffffff |
+ .endif |
+ b SYM (__aeabi_ldiv0) __PLT__ |
+2: |
+#endif |
+.endm |
+ |
#ifdef L_aeabi_ldivmod |
ARM_FUNC_START aeabi_ldivmod |
+ test_div_by_zero signed |
+ |
sub sp, sp, #8 |
#if defined(__thumb2__) |
mov ip, sp |
@@ -85,6 +133,8 @@ ARM_FUNC_START aeabi_ldivmod |
#ifdef L_aeabi_uldivmod |
ARM_FUNC_START aeabi_uldivmod |
+ test_div_by_zero unsigned |
+ |
sub sp, sp, #8 |
#if defined(__thumb2__) |
mov ip, sp |