Home | History | Annotate | Line # | Download | only in quad
      1 /*-
      2  * Copyright (c) 2012 The NetBSD Foundation, Inc.
      3  * All rights reserved.
      4  *
      5  * This code is derived from software contributed to The NetBSD Foundation
      6  * by Matt Thomas of 3am Software Foundry.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  * POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include <machine/asm.h>
     31 
     32 RCSID("$NetBSD: __aeabi_uldivmod.S,v 1.9 2014/05/06 16:02:11 joerg Exp $")
     33 
     34 /*
     35  * typedef struct { unsigned long long quo, rem } ulldiv_t;
     36  * __value_in_regs ulldiv_t __aeabi_uldivmod(unsigned long long n,
     37  *	unsigned long long d);
     38  */
     39 
     40 ENTRY(__aeabi_uldivmod)
     41 #ifdef __ARM_EABI__
     42 # if !defined(__ARM_DWARF_EH__)
     43 	.fnstart
     44 #endif
     45 	.cfi_startproc
     46 #endif
     47 #if !defined(_KERNEL) && !defined(_STANDALONE)
     48 #if !defined(__thumb__)
     49 	orrs	ip, r2, r3
     50 	beq	.Ldivbyzero
     51 #elif defined(_ARM_ARCH_T2)
     52 	cbnz	r2, 1f
     53 	cbz	r3, .Ldivbyzero
     54 1:
     55 #else
     56 	cmp	r2, #0
     57 	bne	1f
     58 	cmp	r3, #0
     59 	beq	.Ldivbyzero
     60 1:
     61 #endif
     62 #endif
     63 
     64 	push	{r4,lr}
     65 #ifdef __ARM_EABI__
     66 # if !defined(__ARM_DWARF_EH__)
     67 	.save	{r4,lr}
     68 # endif
     69 	.cfi_def_cfa_offset 8
     70 	.cfi_offset 14, -4
     71 	.cfi_offset 4, -8
     72 #endif
     73 	sub	sp, sp, #16
     74 #ifdef __ARM_EABI__
     75 	.cfi_def_cfa_offset 24
     76 #endif
     77 #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
     78 	add	r4, sp, #8
     79 #else
     80 	mov	r4, sp
     81 	adds	r4, r4, #8
     82 #endif
     83 	str	r4, [sp]
     84 	bl	PLT_SYM(__qdivrem)
     85 	add	sp, sp, #8
     86 #ifdef __ARM_EABI__
     87 	.cfi_def_cfa_offset 16
     88 	.cfi_offset 3, -12
     89 	.cfi_offset 2, -16
     90 #endif
     91 	/*
     92 	 * The remainder is already on the stack just waiting to be popped
     93 	 * into r2/r3.
     94 	 */
     95 	pop	{r2-r4,pc}
     96 
     97 #if !defined(_KERNEL) && !defined(_STANDALONE)
     98 .Ldivbyzero:
     99 	push	{r0-r1,r4,lr}
    100 #ifdef __ARM_EABI__
    101 # if !defined(__ARM_DWARF_EH__)
    102 	.save	{r0-r1,r4,lr}
    103 # endif
    104 	.cfi_def_cfa_offset 16
    105 	.cfi_offset 14, -4
    106 	.cfi_offset 4, -8
    107 #endif
    108 #ifdef __thumb__
    109 	movs	r0, #0
    110 	mvns	r0, r0
    111 #else
    112 	mvn	r0, #0
    113 #endif
    114 	movs	r1, r0
    115 	bl	PLT_SYM(__aeabi_ldiv0)
    116 	pop	{r2-r4,pc}
    117 #endif
    118 #ifdef __ARM_EABI__
    119 	.cfi_endproc
    120 # if !defined(__ARM_DWARF_EH__)
    121 	.fnend
    122 # endif
    123 #endif
    124 END(__aeabi_uldivmod)
    125