1169689Skan/* Support file for -mfix-vr4120.
2169689Skan   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
3169689Skan
4169689SkanThis file is part of GCC.
5169689Skan
6169689SkanGCC is free software; you can redistribute it and/or modify
7169689Skanit under the terms of the GNU General Public License as published by
8169689Skanthe Free Software Foundation; either version 2, or (at your option)
9169689Skanany later version.
10169689Skan
11169689SkanGCC is distributed in the hope that it will be useful,
12169689Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
13169689SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169689SkanGNU General Public License for more details.
15169689Skan
16169689SkanYou should have received a copy of the GNU General Public License
17169689Skanalong with GCC; see the file COPYING.  If not, write to
18169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
19169689SkanBoston, MA 02110-1301, USA.  */
20169689Skan
21169689Skan/* This file contains functions which implement divsi3 and modsi3 for
22169689Skan   -mfix-vr4120.  div and ddiv do not give the correct result when one
23169689Skan   of the operands is negative.  */
24169689Skan
25169689Skan	.set	nomips16
26169689Skan
27169689Skan#define DIV								\
28169689Skan	xor	$3,$4,$5	/* t = x ^ y */ ;			\
29169689Skan	li	$2,0x80000000;						\
30169689Skan	.set	noreorder;						\
31169689Skan	bgez	$4,1f		/* x >= 0 */; 				\
32169689Skan	and	$3,$3,$2	/* t = (x ^ y) & 0x80000000 in delay slot */ ;\
33169689Skan	.set	reorder;						\
34169689Skan	subu	$4,$0,$4	/* x = -x */ ;				\
35169689Skan1:; 									\
36169689Skan	.set	noreorder;						\
37169689Skan	bgez	$5,2f		/* y >= 0 */ ;				\
38169689Skan	nop;								\
39169689Skan	subu	$5,$0,$5	/* y = -y */ ;				\
40169689Skan	.set	reorder;						\
41169689Skan2:;									\
42169689Skan	divu	$0,$4,$5;	/* we use divu because of INT_MIN */	\
43169689Skan	.set	noreorder;						\
44169689Skan	bne	$5,$0,3f;						\
45169689Skan	nop;								\
46169689Skan	break	7		/* division on zero y */ ;		\
47169689Skan3:;									\
48169689Skan	.set	reorder;						\
49169689Skan	mflo	$2		/* r = x / y */ ;			\
50169689Skan	.set	noreorder;						\
51169689Skan	beq	$3,$0,4f	/* t == 0 */ ;				\
52169689Skan	nop;								\
53169689Skan	subu	$2,$0,$2	/* r = -r */ ;				\
54169689Skan	.set	reorder;						\
55169689Skan4:
56169689Skan
57169689Skan	.globl	__vr4120_divsi3
58169689Skan	.ent	__vr4120_divsi3
59169689Skan__vr4120_divsi3:
60169689Skan	DIV
61169689Skan	j	$31
62169689Skan	.end	__vr4120_divsi3
63169689Skan
64169689Skan	.globl	__vr4120_modsi3
65169689Skan	.ent	__vr4120_modsi3
66169689Skan__vr4120_modsi3:
67169689Skan	move	$6,$4		# x1 = x
68169689Skan	move	$7,$5		# y1 = y
69169689Skan	DIV
70169689Skan	mult	$2,$7		# r = r * y1
71169689Skan	mflo	$2
72169689Skan	.set	noreorder
73169689Skan	j	$31
74169689Skan	subu	$2,$6,$2	# r = x1 - r  in delay slot
75169689Skan	.end	__vr4120_modsi3
76