aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/alpha/reml.S
blob: c4eb426c5a2554c0483f3015cd0571a664179a10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/* Copyright (C) 2004 Free Software Foundation, Inc.
   Contributed by Richard Henderson  <rth@twiddle.net>
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include "div_libc.h"

/* 32-bit signed int remainder.  This is not a normal C function.  Argument
   registers are t10 and t11, the result goes in t12.  Only t12 and AT may
   be clobbered.

   The FPU can handle the division for all input values except zero.
   All we have to do is compute the remainder via multiply-and-subtract.  */

#ifndef EXTEND
#define EXTEND(S,D)	sextl S, D
#endif

	.text
	.align	4
	.globl	__reml
	.type	__reml, @function
	.usepv	__reml, no

	cfi_startproc
	cfi_return_column (RA)
__reml:
	lda	sp, -FRAME(sp)
	cfi_def_cfa_offset (FRAME)
	CALL_MCOUNT
	stt	$f0, 0(sp)
	stt	$f1, 8(sp)
	beq	Y, DIVBYZERO
	cfi_rel_offset ($f0, 0)
	cfi_rel_offset ($f1, 8)

	EXTEND	(X, RV)
	EXTEND	(Y, AT)
	stq	RV, 16(sp)
	stq	AT, 24(sp)

	ldt	$f0, 16(sp)
	ldt	$f1, 24(sp)
	cvtqt	$f0, $f0
	cvtqt	$f1, $f1

	divt/c	$f0, $f1, $f0
	cvttq/c	$f0, $f0
	stt	$f0, 16(sp)
	ldq	RV, 16(sp)

	ldt	$f0, 0(sp)
	mull	RV, Y, RV
	ldt	$f1, 8(sp)
	lda	sp, FRAME(sp)
	cfi_restore ($f0)
	cfi_restore ($f1)
	cfi_def_cfa_offset (0)

	subl	X, RV, RV
	ret	$31, (RA), 1

	cfi_endproc
	.size	__reml, .-__reml

	DO_DIVBYZERO