1 /* Copyright (C) 2004-2022 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 4 The GNU C Library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 The GNU C Library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with the GNU C Library. If not, see 16 <https://www.gnu.org/licenses/>. */ 17 18 /* Common bits for implementing software divide. */ 19 20 #include <sysdep.h> 21 #ifdef __linux__ 22 # include <asm/gentrap.h> 23 # include <asm/pal.h> 24 #else 25 # include <machine/pal.h> 26 #endif 27 28 /* These are not normal C functions. Argument registers are t10 and t11; 29 the result goes in t12; the return address is in t9. Only t12 and AT 30 may be clobbered. */ 31 #define X t10 32 #define Y t11 33 #define RV t12 34 #define RA t9 35 36 /* The secureplt format does not allow the division routines to be called 37 via plt; there aren't enough registers free to be clobbered. Avoid 38 setting the symbol type to STT_FUNC, so that the linker won't be tempted 39 to create a plt entry. */ 40 #define funcnoplt notype 41 42 /* None of these functions should use implicit anything. */ 43 .set nomacro 44 .set noat 45 46 /* Code fragment to invoke _mcount for profiling. This should be invoked 47 directly after allocation of the stack frame. */ 48 .macro CALL_MCOUNT 49 #ifdef PROF 50 stq ra, 0(sp) 51 stq pv, 8(sp) 52 stq gp, 16(sp) 53 cfi_rel_offset (ra, 0) 54 cfi_rel_offset (pv, 8) 55 cfi_rel_offset (gp, 16) 56 br AT, 1f 57 .set macro 58 1: ldgp gp, 0(AT) 59 mov RA, ra 60 lda AT, _mcount 61 jsr AT, (AT), _mcount 62 .set nomacro 63 ldq ra, 0(sp) 64 ldq pv, 8(sp) 65 ldq gp, 16(sp) 66 cfi_restore (ra) 67 cfi_restore (pv) 68 cfi_restore (gp) 69 /* Realign subsequent code with what we'd have without this 70 macro at all. This means aligned with one arithmetic insn 71 used within the bundle. */ 72 .align 4 73 nop 74 #endif 75 .endm 76 77 /* In order to make the below work, all top-level divide routines must 78 use the same frame size. */ 79 #define FRAME 64 80 81 /* Code fragment to generate an integer divide-by-zero fault. When 82 building libc.so, we arrange for there to be one copy of this code 83 placed late in the dso, such that all branches are forward. When 84 building libc.a, we use multiple copies to avoid having an out of 85 range branch. Users should jump to DIVBYZERO. */ 86 87 .macro DO_DIVBYZERO 88 #ifdef PIC 89 #define DIVBYZERO __divbyzero 90 .section .gnu.linkonce.t.divbyzero, "ax", @progbits 91 .globl __divbyzero 92 .type __divbyzero, @function 93 .usepv __divbyzero, no 94 .hidden __divbyzero 95 #else 96 #define DIVBYZERO $divbyzero 97 #endif 98 99 .align 4 100 DIVBYZERO: 101 cfi_startproc 102 cfi_return_column (RA) 103 cfi_def_cfa_offset (FRAME) 104 105 mov a0, RV 106 unop 107 lda a0, GEN_INTDIV 108 call_pal PAL_gentrap 109 110 mov RV, a0 111 clr RV 112 lda sp, FRAME(sp) 113 cfi_def_cfa_offset (0) 114 ret $31, (RA), 1 115 116 cfi_endproc 117 .size DIVBYZERO, .-DIVBYZERO 118 .endm 119 120 /* Like the ev6 instructions, but fall back to stack use on prior machines. */ 121 122 .arch ev6 123 124 .macro _ITOFS gr, fr, slot 125 #ifdef __alpha_fix__ 126 itofs \gr, \fr 127 #else 128 stl \gr, \slot(sp) 129 lds \fr, \slot(sp) 130 #endif 131 .endm 132 133 .macro _ITOFT gr, fr, slot 134 #ifdef __alpha_fix__ 135 itoft \gr, \fr 136 #else 137 stq \gr, \slot(sp) 138 ldt \fr, \slot(sp) 139 #endif 140 .endm 141 142 .macro _FTOIT fr, gr, slot 143 #ifdef __alpha_fix__ 144 ftoit \fr, \gr 145 #else 146 stt \fr, \slot(sp) 147 ldq \gr, \slot(sp) 148 #endif 149 .endm 150 151 /* Similarly, but move two registers. Schedules better for pre-ev6. */ 152 153 .macro _ITOFT2 gr1, fr1, slot1, gr2, fr2, slot2 154 #ifdef __alpha_fix__ 155 itoft \gr1, \fr1 156 itoft \gr2, \fr2 157 #else 158 stq \gr1, \slot1(sp) 159 stq \gr2, \slot2(sp) 160 ldt \fr1, \slot1(sp) 161 ldt \fr2, \slot2(sp) 162 #endif 163 .endm 164