0eb6ae938e
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19012 a1c6a512-1295-4272-9138-f99709370657
115 lines
3.2 KiB
ArmAsm
115 lines
3.2 KiB
ArmAsm
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2008 by Jens Arnold
|
|
*
|
|
* Optimised unsigned integer division for ARMv4
|
|
*
|
|
* Based on: libgcc routines for ARM cpu.
|
|
* Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
|
|
* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
|
|
* Free Software Foundation, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "config.h"
|
|
/* Codecs should not normally do this, but we need to check a macro, and
|
|
* codecs.h would confuse the assembler. */
|
|
|
|
.macro ARM_DIV_BODY dividend, divisor, result, curbit
|
|
|
|
mov \result, \dividend
|
|
mov \curbit, #93 @ 3 * 31, (calculating branch dest)
|
|
cmp \divisor, \result, lsr #16
|
|
movls \result,\result, lsr #16
|
|
subls \curbit, \curbit, #48
|
|
cmp \divisor, \result, lsr #8
|
|
movls \result,\result, lsr #8
|
|
subls \curbit, \curbit, #24
|
|
cmp \divisor, \result, lsr #4
|
|
movls \result,\result, lsr #4
|
|
subls \curbit, \curbit, #12
|
|
cmp \divisor, \result, lsr #2
|
|
movls \result,\result, lsr #2
|
|
subls \curbit, \curbit, #6
|
|
cmp \divisor, \result, lsr #1
|
|
subls \curbit, \curbit, #3
|
|
mov \result, #0
|
|
add pc, pc, \curbit, lsl #2
|
|
nop
|
|
.set shift, 32
|
|
.rept 32
|
|
.set shift, shift - 1
|
|
cmp \dividend, \divisor, lsl #shift
|
|
adc \result, \result, \result
|
|
subcs \dividend, \dividend, \divisor, lsl #shift
|
|
.endr
|
|
.endm
|
|
|
|
.macro ARM_DIV2_ORDER divisor, order
|
|
|
|
cmp \divisor, #(1 << 16)
|
|
movhs \divisor, \divisor, lsr #16
|
|
movhs \order, #16
|
|
movlo \order, #0
|
|
|
|
cmp \divisor, #(1 << 8)
|
|
movhs \divisor, \divisor, lsr #8
|
|
addhs \order, \order, #8
|
|
|
|
cmp \divisor, #(1 << 4)
|
|
movhs \divisor, \divisor, lsr #4
|
|
addhs \order, \order, #4
|
|
|
|
cmp \divisor, #(1 << 2)
|
|
addhi \order, \order, #3
|
|
addls \order, \order, \divisor, lsr #1
|
|
.endm
|
|
|
|
|
|
#ifdef USE_IRAM
|
|
.section .icode,"ax",%progbits
|
|
#else
|
|
.text
|
|
#endif
|
|
.align
|
|
.global udiv32_arm
|
|
.type udiv32_arm,%function
|
|
|
|
udiv32_arm:
|
|
subs r2, r1, #1
|
|
bxeq lr
|
|
bcc 20f
|
|
cmp r0, r1
|
|
bls 10f
|
|
tst r1, r2
|
|
beq 30f
|
|
|
|
ARM_DIV_BODY r0, r1, r2, r3
|
|
mov r0, r2
|
|
bx lr
|
|
|
|
10:
|
|
moveq r0, #1
|
|
20:
|
|
movne r0, #0
|
|
bx lr
|
|
|
|
30:
|
|
ARM_DIV2_ORDER r1, r2
|
|
mov r0, r0, lsr r2
|
|
bx lr
|