Blame sysdeps/alpha/reml.S

Packit 6c4009
/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
Packit 6c4009
   Contributed by Richard Henderson  <rth@twiddle.net>
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library.  If not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include "div_libc.h"
Packit 6c4009
Packit 6c4009
/* 32-bit signed int remainder.  This is not a normal C function.  Argument
Packit 6c4009
   registers are t10 and t11, the result goes in t12.  Only t12 and AT may
Packit 6c4009
   be clobbered.
Packit 6c4009
Packit 6c4009
   The FPU can handle the division for all input values except zero.
Packit 6c4009
   All we have to do is compute the remainder via multiply-and-subtract.
Packit 6c4009
Packit 6c4009
   The FPCR save/restore is due to the fact that the EV6 _will_ set FPCR_INE
Packit 6c4009
   for cvttq/c even without /sui being set.  It will not, however, properly
Packit 6c4009
   raise the exception, so we don't have to worry about FPCR_INED being clear
Packit 6c4009
   and so dying by SIGFPE.  */
Packit 6c4009
Packit 6c4009
#ifndef EXTEND
Packit 6c4009
#define EXTEND(S,D)	sextl S, D
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
	.text
Packit 6c4009
	.align	4
Packit 6c4009
	.globl	__reml
Packit 6c4009
	.type	__reml, @funcnoplt
Packit 6c4009
	.usepv	__reml, no
Packit 6c4009
Packit 6c4009
	cfi_startproc
Packit 6c4009
	cfi_return_column (RA)
Packit 6c4009
__reml:
Packit 6c4009
	lda	sp, -FRAME(sp)
Packit 6c4009
	cfi_def_cfa_offset (FRAME)
Packit 6c4009
	CALL_MCOUNT
Packit 6c4009
	stt	$f0, 0(sp)
Packit 6c4009
	excb
Packit 6c4009
	beq	Y, DIVBYZERO
Packit 6c4009
Packit 6c4009
	stt	$f1, 8(sp)
Packit 6c4009
	stt	$f2, 16(sp)
Packit 6c4009
	cfi_rel_offset ($f0, 0)
Packit 6c4009
	cfi_rel_offset ($f1, 8)
Packit 6c4009
	cfi_rel_offset ($f2, 16)
Packit 6c4009
	mf_fpcr	$f2
Packit 6c4009
Packit 6c4009
	EXTEND	(X, RV)
Packit 6c4009
	EXTEND	(Y, AT)
Packit 6c4009
	_ITOFT2	RV, $f0, 24, AT, $f1, 32
Packit 6c4009
	cvtqt	$f0, $f0
Packit 6c4009
	cvtqt	$f1, $f1
Packit 6c4009
	divt/c	$f0, $f1, $f0
Packit 6c4009
	cvttq/c	$f0, $f0
Packit 6c4009
	excb
Packit 6c4009
	mt_fpcr	$f2
Packit 6c4009
	_FTOIT	$f0, RV, 24
Packit 6c4009
Packit 6c4009
	ldt	$f0, 0(sp)
Packit 6c4009
	mull	RV, Y, RV
Packit 6c4009
	ldt	$f1, 8(sp)
Packit 6c4009
	ldt	$f2, 16(sp)
Packit 6c4009
	lda	sp, FRAME(sp)
Packit 6c4009
	cfi_restore ($f0)
Packit 6c4009
	cfi_restore ($f1)
Packit 6c4009
	cfi_restore ($f2)
Packit 6c4009
	cfi_def_cfa_offset (0)
Packit 6c4009
	subl	X, RV, RV
Packit 6c4009
	ret	$31, (RA), 1
Packit 6c4009
Packit 6c4009
	cfi_endproc
Packit 6c4009
	.size	__reml, .-__reml
Packit 6c4009
Packit 6c4009
	DO_DIVBYZERO