Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Unified Diff: gcc/gcc/config/arm/lib1funcs.asm

Issue 3050029: [gcc] GCC 4.5.0=>4.5.1 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/nacl-toolchain.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gcc/gcc/config/arm/elf.h ('k') | gcc/gcc/config/arm/neon.ml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gcc/gcc/config/arm/lib1funcs.asm
diff --git a/gcc/gcc/config/arm/lib1funcs.asm b/gcc/gcc/config/arm/lib1funcs.asm
index b1f2bcc74b97e9041bb1086063d5dde5d5cb921f..cd64da35860e70a2ac920acd2ed9566d4b58afb1 100644
--- a/gcc/gcc/config/arm/lib1funcs.asm
+++ b/gcc/gcc/config/arm/lib1funcs.asm
@@ -2,7 +2,7 @@
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005, 2007, 2008,
- 2009 Free Software Foundation, Inc.
+ 2009, 2010 Free Software Foundation, Inc.
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
@@ -27,8 +27,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined(__ELF__) && defined(__linux__)
.section .note.GNU-stack,"",%progbits
.previous
-#endif
-
+#endif /* __ELF__ and __linux__ */
+
+#ifdef __ARM_EABI__
+/* Some attributes that are common to all routines in this file. */
+ /* Tag_ABI_align8_needed: This code does not require 8-byte
+ alignment from the caller. */
+ /* .eabi_attribute 24, 0 -- default setting. */
+ /* Tag_ABI_align8_preserved: This code preserves 8-byte
+ alignment in any callee. */
+ .eabi_attribute 25, 1
+#endif /* __ARM_EABI__ */
/* ------------------------------------------------------------------------ */
/* We need to know what prefix to add to function names. */
@@ -103,6 +112,18 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#error Unable to determine architecture.
#endif
+/* There are times when we might prefer Thumb1 code even if ARM code is
+ permitted, for example, the code might be smaller, or there might be
+ interworking problems with switching to ARM state if interworking is
+ disabled. */
+#if (defined(__thumb__) \
+ && !defined(__thumb2__) \
+ && (!defined(__THUMB_INTERWORK__) \
+ || defined (__OPTIMIZE_SIZE__) \
+ || defined(__ARM_ARCH_6M__)))
+# define __prefer_thumb__
+#endif
+
/* How to return from a function call depends on the architecture variant. */
#if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
@@ -256,16 +277,91 @@ LSYM(Lend_fde):
.endm
#endif
-.macro ARM_LDIV0 name
+#ifdef __ARM_EABI__
+.macro ARM_LDIV0 name signed
+ cmp r0, #0
+ .ifc \signed, unsigned
+ movne r0, #0xffffffff
+ .else
+ movgt r0, #0x7fffffff
+ movlt r0, #0x80000000
+ .endif
+ b SYM (__aeabi_idiv0) __PLT__
+.endm
+#else
+.macro ARM_LDIV0 name signed
str lr, [sp, #-8]!
98: cfi_push 98b - __\name, 0xe, -0x8, 0x8
bl SYM (__div0) __PLT__
mov r0, #0 @ About as wrong as it could be.
RETLDM unwind=98b
.endm
+#endif
-.macro THUMB_LDIV0 name
+#ifdef __ARM_EABI__
+.macro THUMB_LDIV0 name signed
+#if defined(__ARM_ARCH_6M__)
+ .ifc \signed, unsigned
+ cmp r0, #0
+ beq 1f
+ mov r0, #0
+ mvn r0, r0 @ 0xffffffff
+1:
+ .else
+ cmp r0, #0
+ beq 2f
+ blt 3f
+ mov r0, #0
+ mvn r0, r0
+ lsr r0, r0, #1 @ 0x7fffffff
+ b 2f
+3: mov r0, #0x80
+ lsl r0, r0, #24 @ 0x80000000
+2:
+ .endif
+ push {r0, r1, r2}
+ ldr r0, 4f
+ adr r1, 4f
+ add r0, r1
+ str r0, [sp, #8]
+ @ We know we are not on armv4t, so pop pc is safe.
+ pop {r0, r1, pc}
+ .align 2
+4:
+ .word __aeabi_idiv0 - 4b
+#elif defined(__thumb2__)
+ .syntax unified
+ .ifc \signed, unsigned
+ cbz r0, 1f
+ mov r0, #0xffffffff
+1:
+ .else
+ cmp r0, #0
+ do_it gt
+ movgt r0, #0x7fffffff
+ do_it lt
+ movlt r0, #0x80000000
+ .endif
+ b.w SYM(__aeabi_idiv0) __PLT__
+#else
+ .align 2
+ bx pc
+ nop
+ .arm
+ cmp r0, #0
+ .ifc \signed, unsigned
+ movne r0, #0xffffffff
+ .else
+ movgt r0, #0x7fffffff
+ movlt r0, #0x80000000
+ .endif
+ b SYM(__aeabi_idiv0) __PLT__
+ .thumb
+#endif
+.endm
+#else
+.macro THUMB_LDIV0 name signed
push { r1, lr }
98: cfi_push 98b - __\name, 0xe, -0x4, 0x8
bl SYM (__div0)
@@ -277,18 +373,19 @@ LSYM(Lend_fde):
pop { r1, pc }
#endif
.endm
+#endif
.macro FUNC_END name
SIZE (__\name)
.endm
-.macro DIV_FUNC_END name
+.macro DIV_FUNC_END name signed
cfi_start __\name, LSYM(Lend_div0)
LSYM(Ldiv0):
#ifdef __thumb__
- THUMB_LDIV0 \name
+ THUMB_LDIV0 \name \signed
#else
- ARM_LDIV0 \name
+ ARM_LDIV0 \name \signed
#endif
cfi_end LSYM(Lend_div0)
FUNC_END \name
@@ -413,6 +510,12 @@ SYM (__\name):
#define yyl r2
#endif
+#ifdef __ARM_EABI__
+.macro WEAK name
+ .weak SYM (__\name)
+.endm
+#endif
+
#ifdef __thumb__
/* Register aliases. */
@@ -437,6 +540,27 @@ pc .req r15
#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
+#if defined (__thumb2__)
+ clz \curbit, \dividend
+ clz \result, \divisor
+ sub \curbit, \result, \curbit
+ rsb \curbit, \curbit, #31
+ adr \result, 1f
+ add \curbit, \result, \curbit, lsl #4
+ mov \result, #0
+ mov pc, \curbit
+.p2align 3
+1:
+ .set shift, 32
+ .rept 32
+ .set shift, shift - 1
+ cmp.w \dividend, \divisor, lsl #shift
+ nop.n
+ adc.w \result, \result, \result
+ it cs
+ subcs.w \dividend, \dividend, \divisor, lsl #shift
+ .endr
+#else
clz \curbit, \dividend
clz \result, \divisor
sub \curbit, \result, \curbit
@@ -452,6 +576,7 @@ pc .req r15
adc \result, \result, \result
subcs \dividend, \dividend, \divisor, lsl #shift
.endr
+#endif
#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
#if __ARM_ARCH__ >= 5
@@ -499,18 +624,23 @@ pc .req r15
@ Division loop
1: cmp \dividend, \divisor
+ do_it hs, t
subhs \dividend, \dividend, \divisor
orrhs \result, \result, \curbit
cmp \dividend, \divisor, lsr #1
+ do_it hs, t
subhs \dividend, \dividend, \divisor, lsr #1
orrhs \result, \result, \curbit, lsr #1
cmp \dividend, \divisor, lsr #2
+ do_it hs, t
subhs \dividend, \dividend, \divisor, lsr #2
orrhs \result, \result, \curbit, lsr #2
cmp \dividend, \divisor, lsr #3
+ do_it hs, t
subhs \dividend, \dividend, \divisor, lsr #3
orrhs \result, \result, \curbit, lsr #3
cmp \dividend, #0 @ Early termination?
+ do_it hs, t
movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
movne \divisor, \divisor, lsr #4
bne 1b
@@ -799,13 +929,14 @@ LSYM(Lgot_result):
/* ------------------------------------------------------------------------ */
#ifdef L_udivsi3
+#if defined(__prefer_thumb__)
+
FUNC_START udivsi3
FUNC_ALIAS aeabi_uidiv udivsi3
-#ifdef __thumb__
-
cmp divisor, #0
beq LSYM(Ldiv0)
+LSYM(udivsi3_skip_div0_test):
mov curbit, #1
mov result, #0
@@ -819,9 +950,16 @@ LSYM(Lgot_result):
pop { work }
RET
-#else /* ARM version. */
+#else /* ARM version/Thumb-2. */
+ ARM_FUNC_START udivsi3
+ ARM_FUNC_ALIAS aeabi_uidiv udivsi3
+
+ /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
+ check for division-by-zero a second time. */
+LSYM(udivsi3_skip_div0_test):
subs r2, r1, #1
+ do_it eq
RETc(eq)
bcc LSYM(Ldiv0)
cmp r0, r1
@@ -834,7 +972,8 @@ LSYM(Lgot_result):
mov r0, r2
RET
-11: moveq r0, #1
+11: do_it eq, e
+ moveq r0, #1
movne r0, #0
RET
@@ -845,19 +984,24 @@ LSYM(Lgot_result):
#endif /* ARM version */
- DIV_FUNC_END udivsi3
+ DIV_FUNC_END udivsi3 unsigned
+#if defined(__prefer_thumb__)
FUNC_START aeabi_uidivmod
-#ifdef __thumb__
+ cmp r1, #0
+ beq LSYM(Ldiv0)
push {r0, r1, lr}
- bl SYM(__udivsi3)
+ bl LSYM(udivsi3_skip_div0_test)
POP {r1, r2, r3}
mul r2, r0
sub r1, r1, r2
bx r3
#else
+ARM_FUNC_START aeabi_uidivmod
+ cmp r1, #0
+ beq LSYM(Ldiv0)
stmfd sp!, { r0, r1, lr }
- bl SYM(__udivsi3)
+ bl LSYM(udivsi3_skip_div0_test)
ldmfd sp!, { r1, r2, lr }
mul r3, r2, r0
sub r1, r1, r3
@@ -904,19 +1048,20 @@ LSYM(Lover10):
#endif /* ARM version. */
- DIV_FUNC_END umodsi3
+ DIV_FUNC_END umodsi3 unsigned
#endif /* L_umodsi3 */
/* ------------------------------------------------------------------------ */
#ifdef L_divsi3
+#if defined(__prefer_thumb__)
+
FUNC_START divsi3
FUNC_ALIAS aeabi_idiv divsi3
-#ifdef __thumb__
cmp divisor, #0
beq LSYM(Ldiv0)
-
+LSYM(divsi3_skip_div0_test):
push { work }
mov work, dividend
eor work, divisor @ Save the sign of the result.
@@ -945,15 +1090,21 @@ LSYM(Lover12):
pop { work }
RET
-#else /* ARM version. */
+#else /* ARM/Thumb-2 version. */
+ ARM_FUNC_START divsi3
+ ARM_FUNC_ALIAS aeabi_idiv divsi3
+
cmp r1, #0
- eor ip, r0, r1 @ save the sign of the result.
beq LSYM(Ldiv0)
+LSYM(divsi3_skip_div0_test):
+ eor ip, r0, r1 @ save the sign of the result.
+ do_it mi
rsbmi r1, r1, #0 @ loops below use unsigned.
subs r2, r1, #1 @ division by 1 or -1 ?
beq 10f
movs r3, r0
+ do_it mi
rsbmi r3, r0, #0 @ positive dividend value
cmp r3, r1
bls 11f
@@ -963,14 +1114,18 @@ LSYM(Lover12):
ARM_DIV_BODY r3, r1, r0, r2
cmp ip, #0
+ do_it mi
rsbmi r0, r0, #0
RET
10: teq ip, r0 @ same sign ?
+ do_it mi
rsbmi r0, r0, #0
RET
-11: movlo r0, #0
+11: do_it lo
+ movlo r0, #0
+ do_it eq,t
moveq r0, ip, asr #31
orreq r0, r0, #1
RET
@@ -979,24 +1134,30 @@ LSYM(Lover12):
cmp ip, #0
mov r0, r3, lsr r2
+ do_it mi
rsbmi r0, r0, #0
RET
#endif /* ARM version */
- DIV_FUNC_END divsi3
+ DIV_FUNC_END divsi3 signed
+#if defined(__prefer_thumb__)
FUNC_START aeabi_idivmod
-#ifdef __thumb__
+ cmp r1, #0
+ beq LSYM(Ldiv0)
push {r0, r1, lr}
- bl SYM(__divsi3)
+ bl LSYM(divsi3_skip_div0_test)
POP {r1, r2, r3}
mul r2, r0
sub r1, r1, r2
bx r3
#else
+ARM_FUNC_START aeabi_idivmod
+ cmp r1, #0
+ beq LSYM(Ldiv0)
stmfd sp!, { r0, r1, lr }
- bl SYM(__divsi3)
+ bl LSYM(divsi3_skip_div0_test)
ldmfd sp!, { r1, r2, lr }
mul r3, r2, r0
sub r1, r1, r3
@@ -1062,21 +1223,25 @@ LSYM(Lover12):
#endif /* ARM version */
- DIV_FUNC_END modsi3
+ DIV_FUNC_END modsi3 signed
#endif /* L_modsi3 */
/* ------------------------------------------------------------------------ */
#ifdef L_dvmd_tls
- FUNC_START div0
- FUNC_ALIAS aeabi_idiv0 div0
- FUNC_ALIAS aeabi_ldiv0 div0
-
+#ifdef __ARM_EABI__
+ WEAK aeabi_idiv0
+ WEAK aeabi_ldiv0
+ FUNC_START aeabi_idiv0
+ FUNC_START aeabi_ldiv0
RET
-
FUNC_END aeabi_ldiv0
FUNC_END aeabi_idiv0
+#else
+ FUNC_START div0
+ RET
FUNC_END div0
+#endif
#endif /* L_divmodsi_tools */
/* ------------------------------------------------------------------------ */
@@ -1086,16 +1251,49 @@ LSYM(Lover12):
/* Constant taken from <asm/signal.h>. */
#define SIGFPE 8
+#ifdef __ARM_EABI__
+ WEAK aeabi_idiv0
+ WEAK aeabi_ldiv0
+ ARM_FUNC_START aeabi_idiv0
+ ARM_FUNC_START aeabi_ldiv0
+#else
ARM_FUNC_START div0
+#endif
do_push {r1, lr}
mov r0, #SIGFPE
bl SYM(raise) __PLT__
RETLDM r1
+#ifdef __ARM_EABI__
+ FUNC_END aeabi_ldiv0
+ FUNC_END aeabi_idiv0
+#else
FUNC_END div0
+#endif
#endif /* L_dvmd_lnx */
+#ifdef L_clear_cache
+#if defined __ARM_EABI__ && defined __linux__
+@ EABI GNU/Linux call to cacheflush syscall.
+ ARM_FUNC_START clear_cache
+ do_push {r7}
+#if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
+ movw r7, #2
+ movt r7, #0xf
+#else
+ mov r7, #0xf0000
+ add r7, r7, #2
+#endif
+ mov r2, #0
+ swi 0
+ do_pop {r7}
+ RET
+ FUNC_END clear_cache
+#else
+#error "This is only for ARM EABI GNU/Linux"
+#endif
+#endif /* L_clear_cache */
/* ------------------------------------------------------------------------ */
/* Dword shift operations. */
/* All the following Dword shift variants rely on the fact that
@@ -1512,6 +1710,111 @@ LSYM(Lchange_\register):
#endif /* L_interwork_call_via_rX */
#endif /* !__thumb2__ */
+
+/* Functions to support compact pic switch tables in thumb1 state.
+ All these routines take an index into the table in r0. The
+ table is at LR & ~1 (but this must be rounded up in the case
+ of 32-bit entires). They are only permitted to clobber r12
+ and r14 and r0 must be preserved on exit. */
+#ifdef L_thumb1_case_sqi
+
+ .text
+ .align 0
+ .force_thumb
+ .syntax unified
+ THUMB_FUNC_START __gnu_thumb1_case_sqi
+ push {r1}
+ mov r1, lr
+ lsrs r1, r1, #1
+ lsls r1, r1, #1
+ ldrsb r1, [r1, r0]
+ lsls r1, r1, #1
+ add lr, lr, r1
+ pop {r1}
+ bx lr
+ SIZE (__gnu_thumb1_case_sqi)
+#endif
+
+#ifdef L_thumb1_case_uqi
+
+ .text
+ .align 0
+ .force_thumb
+ .syntax unified
+ THUMB_FUNC_START __gnu_thumb1_case_uqi
+ push {r1}
+ mov r1, lr
+ lsrs r1, r1, #1
+ lsls r1, r1, #1
+ ldrb r1, [r1, r0]
+ lsls r1, r1, #1
+ add lr, lr, r1
+ pop {r1}
+ bx lr
+ SIZE (__gnu_thumb1_case_uqi)
+#endif
+
+#ifdef L_thumb1_case_shi
+
+ .text
+ .align 0
+ .force_thumb
+ .syntax unified
+ THUMB_FUNC_START __gnu_thumb1_case_shi
+ push {r0, r1}
+ mov r1, lr
+ lsrs r1, r1, #1
+ lsls r0, r0, #1
+ lsls r1, r1, #1
+ ldrsh r1, [r1, r0]
+ lsls r1, r1, #1
+ add lr, lr, r1
+ pop {r0, r1}
+ bx lr
+ SIZE (__gnu_thumb1_case_shi)
+#endif
+
+#ifdef L_thumb1_case_uhi
+
+ .text
+ .align 0
+ .force_thumb
+ .syntax unified
+ THUMB_FUNC_START __gnu_thumb1_case_uhi
+ push {r0, r1}
+ mov r1, lr
+ lsrs r1, r1, #1
+ lsls r0, r0, #1
+ lsls r1, r1, #1
+ ldrh r1, [r1, r0]
+ lsls r1, r1, #1
+ add lr, lr, r1
+ pop {r0, r1}
+ bx lr
+ SIZE (__gnu_thumb1_case_uhi)
+#endif
+
+#ifdef L_thumb1_case_si
+
+ .text
+ .align 0
+ .force_thumb
+ .syntax unified
+ THUMB_FUNC_START __gnu_thumb1_case_si
+ push {r0, r1}
+ mov r1, lr
+ adds.n r1, r1, #2 /* Align to word. */
+ lsrs r1, r1, #2
+ lsls r0, r0, #2
+ lsls r1, r1, #2
+ ldr r0, [r1, r0]
+ adds r0, r0, r1
+ mov lr, r0
+ pop {r0, r1}
+ mov pc, lr /* We know we were called from thumb code. */
+ SIZE (__gnu_thumb1_case_si)
+#endif
+
#endif /* Arch supports thumb. */
#ifndef __symbian__
« no previous file with comments | « gcc/gcc/config/arm/elf.h ('k') | gcc/gcc/config/arm/neon.ml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698