cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

divsi3.S (1912B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0 */
      2#include <linux/linkage.h>
      3#include <asm/asmmacro.h>
      4#include <asm/core.h>
      5
      6ENTRY(__divsi3)
      7
      8	abi_entry_default
      9#if XCHAL_HAVE_DIV32
     10	quos	a2, a2, a3
     11#else
     12	xor	a7, a2, a3	/* sign = dividend ^ divisor */
     13	do_abs	a6, a2, a4	/* udividend = abs (dividend) */
     14	do_abs	a3, a3, a4	/* udivisor = abs (divisor) */
     15	bltui	a3, 2, .Lle_one	/* check if udivisor <= 1 */
     16	do_nsau	a5, a6, a2, a8	/* udividend_shift = nsau (udividend) */
     17	do_nsau	a4, a3, a2, a8	/* udivisor_shift = nsau (udivisor) */
     18	bgeu	a5, a4, .Lspecial
     19
     20	sub	a4, a4, a5	/* count = udivisor_shift - udividend_shift */
     21	ssl	a4
     22	sll	a3, a3		/* udivisor <<= count */
     23	movi	a2, 0		/* quotient = 0 */
     24
     25	/* test-subtract-and-shift loop; one quotient bit on each iteration */
     26#if XCHAL_HAVE_LOOPS
     27	loopnez	a4, .Lloopend
     28#endif /* XCHAL_HAVE_LOOPS */
     29.Lloop:
     30	bltu	a6, a3, .Lzerobit
     31	sub	a6, a6, a3
     32	addi	a2, a2, 1
     33.Lzerobit:
     34	slli	a2, a2, 1
     35	srli	a3, a3, 1
     36#if !XCHAL_HAVE_LOOPS
     37	addi	a4, a4, -1
     38	bnez	a4, .Lloop
     39#endif /* !XCHAL_HAVE_LOOPS */
     40.Lloopend:
     41
     42	bltu	a6, a3, .Lreturn
     43	addi	a2, a2, 1	/* increment if udividend >= udivisor */
     44.Lreturn:
     45	neg	a5, a2
     46	movltz	a2, a5, a7	/* return (sign < 0) ? -quotient : quotient */
     47	abi_ret_default
     48
     49.Lle_one:
     50	beqz	a3, .Lerror
     51	neg	a2, a6		/* if udivisor == 1, then return... */
     52	movgez	a2, a6, a7	/* (sign < 0) ? -udividend : udividend */
     53	abi_ret_default
     54
     55.Lspecial:
     56	bltu	a6, a3, .Lreturn0 /* if dividend < divisor, return 0 */
     57	movi	a2, 1
     58	movi	a4, -1
     59	movltz	a2, a4, a7	/* else return (sign < 0) ? -1 : 1 */
     60	abi_ret_default
     61
     62.Lerror:
     63	/* Divide by zero: Use an illegal instruction to force an exception.
     64	   The subsequent "DIV0" string can be recognized by the exception
     65	   handler to identify the real cause of the exception.  */
     66	ill
     67	.ascii	"DIV0"
     68
     69.Lreturn0:
     70	movi	a2, 0
     71#endif /* XCHAL_HAVE_DIV32 */
     72	abi_ret_default
     73
     74ENDPROC(__divsi3)