vr4120-div.S revision 169689
1194246Smarius/* Support file for -mfix-vr4120.
2194246Smarius   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
3194246Smarius
4194246SmariusThis file is part of GCC.
5194246Smarius
6194246SmariusGCC is free software; you can redistribute it and/or modify
7194246Smariusit under the terms of the GNU General Public License as published by
8194246Smariusthe Free Software Foundation; either version 2, or (at your option)
9194246Smariusany later version.
10194246Smarius
11194246SmariusGCC is distributed in the hope that it will be useful,
12194246Smariusbut WITHOUT ANY WARRANTY; without even the implied warranty of
13194246SmariusMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14194246SmariusGNU General Public License for more details.
15194246Smarius
16194246SmariusYou should have received a copy of the GNU General Public License
17194246Smariusalong with GCC; see the file COPYING.  If not, write to
18194246Smariusthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
19194246SmariusBoston, MA 02110-1301, USA.  */
20194246Smarius
21194246Smarius/* This file contains functions which implement divsi3 and modsi3 for
22194246Smarius   -mfix-vr4120.  div and ddiv do not give the correct result when one
23194246Smarius   of the operands is negative.  */
24194246Smarius
25194246Smarius	.set	nomips16
26194246Smarius
27194246Smarius#define DIV								\
28194246Smarius	xor	$3,$4,$5	/* t = x ^ y */ ;			\
29194246Smarius	li	$2,0x80000000;						\
30194246Smarius	.set	noreorder;						\
31194246Smarius	bgez	$4,1f		/* x >= 0 */; 				\
32194246Smarius	and	$3,$3,$2	/* t = (x ^ y) & 0x80000000 in delay slot */ ;\
33194246Smarius	.set	reorder;						\
34194246Smarius	subu	$4,$0,$4	/* x = -x */ ;				\
35194246Smarius1:; 									\
36194246Smarius	.set	noreorder;						\
37194246Smarius	bgez	$5,2f		/* y >= 0 */ ;				\
38194246Smarius	nop;								\
39194246Smarius	subu	$5,$0,$5	/* y = -y */ ;				\
40194246Smarius	.set	reorder;						\
41194246Smarius2:;									\
42194246Smarius	divu	$0,$4,$5;	/* we use divu because of INT_MIN */	\
43194246Smarius	.set	noreorder;						\
44194246Smarius	bne	$5,$0,3f;						\
45194246Smarius	nop;								\
46194246Smarius	break	7		/* division on zero y */ ;		\
47194246Smarius3:;									\
48194246Smarius	.set	reorder;						\
49194246Smarius	mflo	$2		/* r = x / y */ ;			\
50194246Smarius	.set	noreorder;						\
51194246Smarius	beq	$3,$0,4f	/* t == 0 */ ;				\
52194246Smarius	nop;								\
53194246Smarius	subu	$2,$0,$2	/* r = -r */ ;				\
54194246Smarius	.set	reorder;						\
55194246Smarius4:
56194246Smarius
57194246Smarius	.globl	__vr4120_divsi3
58194246Smarius	.ent	__vr4120_divsi3
59194246Smarius__vr4120_divsi3:
60194904Smarius	DIV
61194246Smarius	j	$31
62194246Smarius	.end	__vr4120_divsi3
63194246Smarius
64194246Smarius	.globl	__vr4120_modsi3
65194246Smarius	.ent	__vr4120_modsi3
66194246Smarius__vr4120_modsi3:
67194246Smarius	move	$6,$4		# x1 = x
68194246Smarius	move	$7,$5		# y1 = y
69194246Smarius	DIV
70194246Smarius	mult	$2,$7		# r = r * y1
71194246Smarius	mflo	$2
72194246Smarius	.set	noreorder
73194246Smarius	j	$31
74194246Smarius	subu	$2,$6,$2	# r = x1 - r  in delay slot
75194246Smarius	.end	__vr4120_modsi3
76194246Smarius