xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/config/mips/vr4120-div.S (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1/* Support file for -mfix-vr4120.
2   Copyright (C) 2002-2020 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23<http://www.gnu.org/licenses/>.  */
24
25/* An executable stack is *not* required for these functions.  */
26#include "gnustack.h"
27
28/* This file contains functions which implement divsi3 and modsi3 for
29   -mfix-vr4120.  div and ddiv do not give the correct result when one
30   of the operands is negative.  */
31
32	.set	nomips16
33
34#define DIV								\
35	xor	$3,$4,$5	/* t = x ^ y */ ;			\
36	li	$2,0x80000000;						\
37	.set	noreorder;						\
38	bgez	$4,1f		/* x >= 0 */; 				\
39	and	$3,$3,$2	/* t = (x ^ y) & 0x80000000 in delay slot */ ;\
40	.set	reorder;						\
41	subu	$4,$0,$4	/* x = -x */ ;				\
421:; 									\
43	.set	noreorder;						\
44	bgez	$5,2f		/* y >= 0 */ ;				\
45	nop;								\
46	subu	$5,$0,$5	/* y = -y */ ;				\
47	.set	reorder;						\
482:;									\
49	divu	$0,$4,$5;	/* we use divu because of INT_MIN */	\
50	.set	noreorder;						\
51	bne	$5,$0,3f;						\
52	nop;								\
53	break	7		/* division on zero y */ ;		\
543:;									\
55	.set	reorder;						\
56	mflo	$2		/* r = x / y */ ;			\
57	.set	noreorder;						\
58	beq	$3,$0,4f	/* t == 0 */ ;				\
59	nop;								\
60	subu	$2,$0,$2	/* r = -r */ ;				\
61	.set	reorder;						\
624:
63
64	.globl	__vr4120_divsi3
65	.ent	__vr4120_divsi3
66__vr4120_divsi3:
67	DIV
68	j	$31
69	.end	__vr4120_divsi3
70
71	.globl	__vr4120_modsi3
72	.ent	__vr4120_modsi3
73__vr4120_modsi3:
74	move	$6,$4		# x1 = x
75	move	$7,$5		# y1 = y
76	DIV
77	mult	$2,$7		# r = r * y1
78	mflo	$2
79	.set	noreorder
80	j	$31
81	subu	$2,$6,$2	# r = x1 - r  in delay slot
82	.end	__vr4120_modsi3
83