123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393 |
- /* $NetBSD: divsi3.S,v 1.5 2005/02/26 22:58:56 perry 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.
- */
- /*
- * stack is aligned as there's a possibility of branching to L_overflow
- * which makes a C call
- */
- .text
- .align 0
- .globl __umodsi3
- .type __umodsi3 , function
- __umodsi3:
- stmfd sp!, {lr}
- sub sp, sp, #4 /* align stack */
- bl .L_udivide
- add sp, sp, #4 /* unalign stack */
- mov r0, r1
- ldmfd sp!, {pc}
- .text
- .align 0
- .globl __modsi3
- .type __modsi3 , function
- __modsi3:
- stmfd sp!, {lr}
- sub sp, sp, #4 /* align stack */
- bl .L_divide
- add sp, sp, #4 /* unalign stack */
- mov r0, r1
- ldmfd sp!, {pc}
- .L_overflow:
- /* XXX should cause a fatal error */
- mvn r0, #0
- mov pc, lr
- .text
- .align 0
- .globl __udivsi3
- .type __udivsi3 , function
- __udivsi3:
- .L_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
- mov pc, lr
- .text
- .align 0
- .globl __divsi3
- .type __divsi3 , function
- __divsi3:
- .L_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
- mov pc, lr
- .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
- mov pc, lr
|