Blame sysdeps/alpha/div_libc.h

Packit Service 82fcde
/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library.  If not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
/* Common bits for implementing software divide.  */
Packit Service 82fcde
Packit Service 82fcde
#include <sysdep.h>
Packit Service 82fcde
#ifdef __linux__
Packit Service 82fcde
# include <asm/gentrap.h>
Packit Service 82fcde
# include <asm/pal.h>
Packit Service 82fcde
#else
Packit Service 82fcde
# include <machine/pal.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* These are not normal C functions.  Argument registers are t10 and t11;
Packit Service 82fcde
   the result goes in t12; the return address is in t9.  Only t12 and AT
Packit Service 82fcde
   may be clobbered.  */
Packit Service 82fcde
#define X	t10
Packit Service 82fcde
#define Y	t11
Packit Service 82fcde
#define RV	t12
Packit Service 82fcde
#define RA	t9
Packit Service 82fcde
Packit Service 82fcde
/* The secureplt format does not allow the division routines to be called
Packit Service 82fcde
   via plt; there aren't enough registers free to be clobbered.  Avoid
Packit Service 82fcde
   setting the symbol type to STT_FUNC, so that the linker won't be tempted
Packit Service 82fcde
   to create a plt entry.  */
Packit Service 82fcde
#define funcnoplt notype
Packit Service 82fcde
Packit Service 82fcde
/* None of these functions should use implicit anything.  */
Packit Service 82fcde
	.set	nomacro
Packit Service 82fcde
	.set	noat
Packit Service 82fcde
Packit Service 82fcde
/* Code fragment to invoke _mcount for profiling.  This should be invoked
Packit Service 82fcde
   directly after allocation of the stack frame.  */
Packit Service 82fcde
.macro CALL_MCOUNT
Packit Service 82fcde
#ifdef PROF
Packit Service 82fcde
	stq	ra, 0(sp)
Packit Service 82fcde
	stq	pv, 8(sp)
Packit Service 82fcde
	stq	gp, 16(sp)
Packit Service 82fcde
	cfi_rel_offset (ra, 0)
Packit Service 82fcde
	cfi_rel_offset (pv, 8)
Packit Service 82fcde
	cfi_rel_offset (gp, 16)
Packit Service 82fcde
	br	AT, 1f
Packit Service 82fcde
	.set	macro
Packit Service 82fcde
1:	ldgp	gp, 0(AT)
Packit Service 82fcde
	mov	RA, ra
Packit Service 82fcde
	lda	AT, _mcount
Packit Service 82fcde
	jsr	AT, (AT), _mcount
Packit Service 82fcde
	.set	nomacro
Packit Service 82fcde
	ldq	ra, 0(sp)
Packit Service 82fcde
	ldq	pv, 8(sp)
Packit Service 82fcde
	ldq	gp, 16(sp)
Packit Service 82fcde
	cfi_restore (ra)
Packit Service 82fcde
	cfi_restore (pv)
Packit Service 82fcde
	cfi_restore (gp)
Packit Service 82fcde
	/* Realign subsequent code with what we'd have without this
Packit Service 82fcde
	   macro at all.  This means aligned with one arithmetic insn
Packit Service 82fcde
	   used within the bundle.  */
Packit Service 82fcde
	.align	4
Packit Service 82fcde
	nop
Packit Service 82fcde
#endif
Packit Service 82fcde
.endm
Packit Service 82fcde
Packit Service 82fcde
/* In order to make the below work, all top-level divide routines must
Packit Service 82fcde
   use the same frame size.  */
Packit Service 82fcde
#define FRAME	64
Packit Service 82fcde
Packit Service 82fcde
/* Code fragment to generate an integer divide-by-zero fault.  When
Packit Service 82fcde
   building libc.so, we arrange for there to be one copy of this code
Packit Service 82fcde
   placed late in the dso, such that all branches are forward.  When
Packit Service 82fcde
   building libc.a, we use multiple copies to avoid having an out of
Packit Service 82fcde
   range branch.  Users should jump to DIVBYZERO.  */
Packit Service 82fcde
Packit Service 82fcde
.macro DO_DIVBYZERO
Packit Service 82fcde
#ifdef PIC
Packit Service 82fcde
#define DIVBYZERO	__divbyzero
Packit Service 82fcde
	.section .gnu.linkonce.t.divbyzero, "ax", @progbits
Packit Service 82fcde
	.globl	__divbyzero
Packit Service 82fcde
	.type	__divbyzero, @function
Packit Service 82fcde
	.usepv	__divbyzero, no
Packit Service 82fcde
	.hidden	__divbyzero
Packit Service 82fcde
#else
Packit Service 82fcde
#define DIVBYZERO	$divbyzero
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
	.align	4
Packit Service 82fcde
DIVBYZERO:
Packit Service 82fcde
	cfi_startproc
Packit Service 82fcde
	cfi_return_column (RA)
Packit Service 82fcde
	cfi_def_cfa_offset (FRAME)
Packit Service 82fcde
Packit Service 82fcde
	mov	a0, RV
Packit Service 82fcde
	unop
Packit Service 82fcde
	lda	a0, GEN_INTDIV
Packit Service 82fcde
	call_pal PAL_gentrap
Packit Service 82fcde
Packit Service 82fcde
	mov	RV, a0
Packit Service 82fcde
	clr	RV
Packit Service 82fcde
	lda	sp, FRAME(sp)
Packit Service 82fcde
	cfi_def_cfa_offset (0)
Packit Service 82fcde
	ret	$31, (RA), 1
Packit Service 82fcde
Packit Service 82fcde
	cfi_endproc
Packit Service 82fcde
	.size	DIVBYZERO, .-DIVBYZERO
Packit Service 82fcde
.endm
Packit Service 82fcde
Packit Service 82fcde
/* Like the ev6 instructions, but fall back to stack use on prior machines.  */
Packit Service 82fcde
Packit Service 82fcde
	.arch	ev6
Packit Service 82fcde
Packit Service 82fcde
.macro _ITOFS  gr, fr, slot
Packit Service 82fcde
#ifdef __alpha_fix__
Packit Service 82fcde
	itofs	\gr, \fr
Packit Service 82fcde
#else
Packit Service 82fcde
	stl	\gr, \slot(sp)
Packit Service 82fcde
	lds	\fr, \slot(sp)
Packit Service 82fcde
#endif
Packit Service 82fcde
.endm
Packit Service 82fcde
Packit Service 82fcde
.macro _ITOFT  gr, fr, slot
Packit Service 82fcde
#ifdef __alpha_fix__
Packit Service 82fcde
	itoft	\gr, \fr
Packit Service 82fcde
#else
Packit Service 82fcde
	stq	\gr, \slot(sp)
Packit Service 82fcde
	ldt	\fr, \slot(sp)
Packit Service 82fcde
#endif
Packit Service 82fcde
.endm
Packit Service 82fcde
Packit Service 82fcde
.macro _FTOIT  fr, gr, slot
Packit Service 82fcde
#ifdef __alpha_fix__
Packit Service 82fcde
	ftoit	\fr, \gr
Packit Service 82fcde
#else
Packit Service 82fcde
	stt	\fr, \slot(sp)
Packit Service 82fcde
	ldq	\gr, \slot(sp)
Packit Service 82fcde
#endif
Packit Service 82fcde
.endm
Packit Service 82fcde
Packit Service 82fcde
/* Similarly, but move two registers.  Schedules better for pre-ev6.  */
Packit Service 82fcde
Packit Service 82fcde
.macro _ITOFT2 gr1, fr1, slot1, gr2, fr2, slot2
Packit Service 82fcde
#ifdef __alpha_fix__
Packit Service 82fcde
	itoft	\gr1, \fr1
Packit Service 82fcde
	itoft	\gr2, \fr2
Packit Service 82fcde
#else
Packit Service 82fcde
	stq	\gr1, \slot1(sp)
Packit Service 82fcde
	stq	\gr2, \slot2(sp)
Packit Service 82fcde
	ldt	\fr1, \slot1(sp)
Packit Service 82fcde
	ldt	\fr2, \slot2(sp)
Packit Service 82fcde
#endif
Packit Service 82fcde
.endm