- Fix for possible unset uid/gid in toproto - Fix for default mtree style - Update libelf - Importing libexecinfo - Resynchronize GCC, mpc, gmp, mpfr - build.sh: Replace params with show-params. This has been done as the make target has been renamed in the same way, while a new target named params has been added. This new target generates a file containing all the parameters, instead of printing it on the console. - Update test48 with new etc/services (Fix by Ben Gras <ben@minix3.org) get getservbyport() out of the inner loop Change-Id: Ie6ad5226fa2621ff9f0dee8782ea48f9443d2091
381 lines
8 KiB
ArmAsm
381 lines
8 KiB
ArmAsm
/* $NetBSD: divide.S,v 1.4 2013/08/19 03:47:06 matt Exp $ */
|
|
|
|
/*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef __ARM_ARCH_EXT_IDIV__
|
|
|
|
#include <machine/asm.h>
|
|
|
|
/*
|
|
* stack is aligned as there's a possibility of branching to .L_overflow
|
|
* which makes a C call
|
|
*/
|
|
|
|
_ARM_ENTRY(__udivide) /* r0 = r0 / r1; r1 = r0 % r1 */
|
|
eor r0, r1, r0
|
|
eor r1, r0, r1
|
|
eor r0, r1, r0
|
|
/* r0 = r1 / r0; r1 = r1 % r0 */
|
|
cmp r0, #1
|
|
bcc .L_overflow
|
|
beq .L_divide_l0
|
|
mov ip, #0
|
|
movs r1, r1
|
|
bpl .L_divide_l1
|
|
orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
|
|
movs r1, r1, lsr #1
|
|
orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
|
|
b .L_divide_l1
|
|
|
|
.L_divide_l0: /* r0 == 1 */
|
|
mov r0, r1
|
|
mov r1, #0
|
|
RET
|
|
END(__udivide)
|
|
|
|
_ARM_ENTRY(__divide) /* r0 = r0 / r1; r1 = r0 % r1 */
|
|
eor r0, r1, r0
|
|
eor r1, r0, r1
|
|
eor r0, r1, r0
|
|
/* r0 = r1 / r0; r1 = r1 % r0 */
|
|
cmp r0, #1
|
|
bcc .L_overflow
|
|
beq .L_divide_l0
|
|
ands ip, r0, #0x80000000
|
|
rsbmi r0, r0, #0
|
|
ands r2, r1, #0x80000000
|
|
eor ip, ip, r2
|
|
rsbmi r1, r1, #0
|
|
orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
|
|
/* ip bit 0x80000000 = -ve remainder */
|
|
|
|
.L_divide_l1:
|
|
mov r2, #1
|
|
mov r3, #0
|
|
|
|
/*
|
|
* If the highest bit of the dividend is set, we have to be
|
|
* careful when shifting the divisor. Test this.
|
|
*/
|
|
movs r1,r1
|
|
bpl .L_old_code
|
|
|
|
/*
|
|
* At this point, the highest bit of r1 is known to be set.
|
|
* We abuse this below in the tst instructions.
|
|
*/
|
|
tst r1, r0 /*, lsl #0 */
|
|
bmi .L_divide_b1
|
|
tst r1, r0, lsl #1
|
|
bmi .L_divide_b2
|
|
tst r1, r0, lsl #2
|
|
bmi .L_divide_b3
|
|
tst r1, r0, lsl #3
|
|
bmi .L_divide_b4
|
|
tst r1, r0, lsl #4
|
|
bmi .L_divide_b5
|
|
tst r1, r0, lsl #5
|
|
bmi .L_divide_b6
|
|
tst r1, r0, lsl #6
|
|
bmi .L_divide_b7
|
|
tst r1, r0, lsl #7
|
|
bmi .L_divide_b8
|
|
tst r1, r0, lsl #8
|
|
bmi .L_divide_b9
|
|
tst r1, r0, lsl #9
|
|
bmi .L_divide_b10
|
|
tst r1, r0, lsl #10
|
|
bmi .L_divide_b11
|
|
tst r1, r0, lsl #11
|
|
bmi .L_divide_b12
|
|
tst r1, r0, lsl #12
|
|
bmi .L_divide_b13
|
|
tst r1, r0, lsl #13
|
|
bmi .L_divide_b14
|
|
tst r1, r0, lsl #14
|
|
bmi .L_divide_b15
|
|
tst r1, r0, lsl #15
|
|
bmi .L_divide_b16
|
|
tst r1, r0, lsl #16
|
|
bmi .L_divide_b17
|
|
tst r1, r0, lsl #17
|
|
bmi .L_divide_b18
|
|
tst r1, r0, lsl #18
|
|
bmi .L_divide_b19
|
|
tst r1, r0, lsl #19
|
|
bmi .L_divide_b20
|
|
tst r1, r0, lsl #20
|
|
bmi .L_divide_b21
|
|
tst r1, r0, lsl #21
|
|
bmi .L_divide_b22
|
|
tst r1, r0, lsl #22
|
|
bmi .L_divide_b23
|
|
tst r1, r0, lsl #23
|
|
bmi .L_divide_b24
|
|
tst r1, r0, lsl #24
|
|
bmi .L_divide_b25
|
|
tst r1, r0, lsl #25
|
|
bmi .L_divide_b26
|
|
tst r1, r0, lsl #26
|
|
bmi .L_divide_b27
|
|
tst r1, r0, lsl #27
|
|
bmi .L_divide_b28
|
|
tst r1, r0, lsl #28
|
|
bmi .L_divide_b29
|
|
tst r1, r0, lsl #29
|
|
bmi .L_divide_b30
|
|
tst r1, r0, lsl #30
|
|
bmi .L_divide_b31
|
|
/*
|
|
* instead of:
|
|
* tst r1, r0, lsl #31
|
|
* bmi .L_divide_b32
|
|
*/
|
|
b .L_divide_b32
|
|
|
|
.L_old_code:
|
|
cmp r1, r0
|
|
bcc .L_divide_b0
|
|
cmp r1, r0, lsl #1
|
|
bcc .L_divide_b1
|
|
cmp r1, r0, lsl #2
|
|
bcc .L_divide_b2
|
|
cmp r1, r0, lsl #3
|
|
bcc .L_divide_b3
|
|
cmp r1, r0, lsl #4
|
|
bcc .L_divide_b4
|
|
cmp r1, r0, lsl #5
|
|
bcc .L_divide_b5
|
|
cmp r1, r0, lsl #6
|
|
bcc .L_divide_b6
|
|
cmp r1, r0, lsl #7
|
|
bcc .L_divide_b7
|
|
cmp r1, r0, lsl #8
|
|
bcc .L_divide_b8
|
|
cmp r1, r0, lsl #9
|
|
bcc .L_divide_b9
|
|
cmp r1, r0, lsl #10
|
|
bcc .L_divide_b10
|
|
cmp r1, r0, lsl #11
|
|
bcc .L_divide_b11
|
|
cmp r1, r0, lsl #12
|
|
bcc .L_divide_b12
|
|
cmp r1, r0, lsl #13
|
|
bcc .L_divide_b13
|
|
cmp r1, r0, lsl #14
|
|
bcc .L_divide_b14
|
|
cmp r1, r0, lsl #15
|
|
bcc .L_divide_b15
|
|
cmp r1, r0, lsl #16
|
|
bcc .L_divide_b16
|
|
cmp r1, r0, lsl #17
|
|
bcc .L_divide_b17
|
|
cmp r1, r0, lsl #18
|
|
bcc .L_divide_b18
|
|
cmp r1, r0, lsl #19
|
|
bcc .L_divide_b19
|
|
cmp r1, r0, lsl #20
|
|
bcc .L_divide_b20
|
|
cmp r1, r0, lsl #21
|
|
bcc .L_divide_b21
|
|
cmp r1, r0, lsl #22
|
|
bcc .L_divide_b22
|
|
cmp r1, r0, lsl #23
|
|
bcc .L_divide_b23
|
|
cmp r1, r0, lsl #24
|
|
bcc .L_divide_b24
|
|
cmp r1, r0, lsl #25
|
|
bcc .L_divide_b25
|
|
cmp r1, r0, lsl #26
|
|
bcc .L_divide_b26
|
|
cmp r1, r0, lsl #27
|
|
bcc .L_divide_b27
|
|
cmp r1, r0, lsl #28
|
|
bcc .L_divide_b28
|
|
cmp r1, r0, lsl #29
|
|
bcc .L_divide_b29
|
|
cmp r1, r0, lsl #30
|
|
bcc .L_divide_b30
|
|
.L_divide_b32:
|
|
cmp r1, r0, lsl #31
|
|
subhs r1, r1,r0, lsl #31
|
|
addhs r3, r3,r2, lsl #31
|
|
.L_divide_b31:
|
|
cmp r1, r0, lsl #30
|
|
subhs r1, r1,r0, lsl #30
|
|
addhs r3, r3,r2, lsl #30
|
|
.L_divide_b30:
|
|
cmp r1, r0, lsl #29
|
|
subhs r1, r1,r0, lsl #29
|
|
addhs r3, r3,r2, lsl #29
|
|
.L_divide_b29:
|
|
cmp r1, r0, lsl #28
|
|
subhs r1, r1,r0, lsl #28
|
|
addhs r3, r3,r2, lsl #28
|
|
.L_divide_b28:
|
|
cmp r1, r0, lsl #27
|
|
subhs r1, r1,r0, lsl #27
|
|
addhs r3, r3,r2, lsl #27
|
|
.L_divide_b27:
|
|
cmp r1, r0, lsl #26
|
|
subhs r1, r1,r0, lsl #26
|
|
addhs r3, r3,r2, lsl #26
|
|
.L_divide_b26:
|
|
cmp r1, r0, lsl #25
|
|
subhs r1, r1,r0, lsl #25
|
|
addhs r3, r3,r2, lsl #25
|
|
.L_divide_b25:
|
|
cmp r1, r0, lsl #24
|
|
subhs r1, r1,r0, lsl #24
|
|
addhs r3, r3,r2, lsl #24
|
|
.L_divide_b24:
|
|
cmp r1, r0, lsl #23
|
|
subhs r1, r1,r0, lsl #23
|
|
addhs r3, r3,r2, lsl #23
|
|
.L_divide_b23:
|
|
cmp r1, r0, lsl #22
|
|
subhs r1, r1,r0, lsl #22
|
|
addhs r3, r3,r2, lsl #22
|
|
.L_divide_b22:
|
|
cmp r1, r0, lsl #21
|
|
subhs r1, r1,r0, lsl #21
|
|
addhs r3, r3,r2, lsl #21
|
|
.L_divide_b21:
|
|
cmp r1, r0, lsl #20
|
|
subhs r1, r1,r0, lsl #20
|
|
addhs r3, r3,r2, lsl #20
|
|
.L_divide_b20:
|
|
cmp r1, r0, lsl #19
|
|
subhs r1, r1,r0, lsl #19
|
|
addhs r3, r3,r2, lsl #19
|
|
.L_divide_b19:
|
|
cmp r1, r0, lsl #18
|
|
subhs r1, r1,r0, lsl #18
|
|
addhs r3, r3,r2, lsl #18
|
|
.L_divide_b18:
|
|
cmp r1, r0, lsl #17
|
|
subhs r1, r1,r0, lsl #17
|
|
addhs r3, r3,r2, lsl #17
|
|
.L_divide_b17:
|
|
cmp r1, r0, lsl #16
|
|
subhs r1, r1,r0, lsl #16
|
|
addhs r3, r3,r2, lsl #16
|
|
.L_divide_b16:
|
|
cmp r1, r0, lsl #15
|
|
subhs r1, r1,r0, lsl #15
|
|
addhs r3, r3,r2, lsl #15
|
|
.L_divide_b15:
|
|
cmp r1, r0, lsl #14
|
|
subhs r1, r1,r0, lsl #14
|
|
addhs r3, r3,r2, lsl #14
|
|
.L_divide_b14:
|
|
cmp r1, r0, lsl #13
|
|
subhs r1, r1,r0, lsl #13
|
|
addhs r3, r3,r2, lsl #13
|
|
.L_divide_b13:
|
|
cmp r1, r0, lsl #12
|
|
subhs r1, r1,r0, lsl #12
|
|
addhs r3, r3,r2, lsl #12
|
|
.L_divide_b12:
|
|
cmp r1, r0, lsl #11
|
|
subhs r1, r1,r0, lsl #11
|
|
addhs r3, r3,r2, lsl #11
|
|
.L_divide_b11:
|
|
cmp r1, r0, lsl #10
|
|
subhs r1, r1,r0, lsl #10
|
|
addhs r3, r3,r2, lsl #10
|
|
.L_divide_b10:
|
|
cmp r1, r0, lsl #9
|
|
subhs r1, r1,r0, lsl #9
|
|
addhs r3, r3,r2, lsl #9
|
|
.L_divide_b9:
|
|
cmp r1, r0, lsl #8
|
|
subhs r1, r1,r0, lsl #8
|
|
addhs r3, r3,r2, lsl #8
|
|
.L_divide_b8:
|
|
cmp r1, r0, lsl #7
|
|
subhs r1, r1,r0, lsl #7
|
|
addhs r3, r3,r2, lsl #7
|
|
.L_divide_b7:
|
|
cmp r1, r0, lsl #6
|
|
subhs r1, r1,r0, lsl #6
|
|
addhs r3, r3,r2, lsl #6
|
|
.L_divide_b6:
|
|
cmp r1, r0, lsl #5
|
|
subhs r1, r1,r0, lsl #5
|
|
addhs r3, r3,r2, lsl #5
|
|
.L_divide_b5:
|
|
cmp r1, r0, lsl #4
|
|
subhs r1, r1,r0, lsl #4
|
|
addhs r3, r3,r2, lsl #4
|
|
.L_divide_b4:
|
|
cmp r1, r0, lsl #3
|
|
subhs r1, r1,r0, lsl #3
|
|
addhs r3, r3,r2, lsl #3
|
|
.L_divide_b3:
|
|
cmp r1, r0, lsl #2
|
|
subhs r1, r1,r0, lsl #2
|
|
addhs r3, r3,r2, lsl #2
|
|
.L_divide_b2:
|
|
cmp r1, r0, lsl #1
|
|
subhs r1, r1,r0, lsl #1
|
|
addhs r3, r3,r2, lsl #1
|
|
.L_divide_b1:
|
|
cmp r1, r0
|
|
subhs r1, r1, r0
|
|
addhs r3, r3, r2
|
|
.L_divide_b0:
|
|
|
|
tst ip, #0x20000000
|
|
bne .L_udivide_l1
|
|
mov r0, r3
|
|
cmp ip, #0
|
|
rsbmi r1, r1, #0
|
|
movs ip, ip, lsl #1
|
|
bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
|
|
rsbmi r0, r0, #0
|
|
RET
|
|
|
|
.L_udivide_l1:
|
|
tst ip, #0x10000000
|
|
mov r1, r1, lsl #1
|
|
orrne r1, r1, #1
|
|
mov r3, r3, lsl #1
|
|
cmp r1, r0
|
|
subhs r1, r1, r0
|
|
addhs r3, r3, r2
|
|
mov r0, r3
|
|
RET
|
|
|
|
.L_overflow:
|
|
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
|
#ifdef __ARM_EABI__
|
|
mov r0, r1 /* return quotient */
|
|
b PLT_SYM(__aeabi_idiv0)
|
|
#else
|
|
mov r0, #8 /* SIGFPE */
|
|
bl PLT_SYM(_C_LABEL(raise)) /* raise it */
|
|
mov r0, #0
|
|
RET
|
|
#endif
|
|
#else
|
|
/* XXX should cause a fatal error */
|
|
mvn r0, #0
|
|
RET
|
|
#endif
|
|
|
|
END(__divide)
|
|
|
|
#endif /* __ARM_ARCH_EXT_IDIV__ */
|