| 1 | /*	$NetBSD: aeabi.h,v 1.6 2021/10/06 05:33:15 skrll Exp $	*/ |
| 2 | |
| 3 | /*- |
| 4 | * Copyright (c) 2012 The NetBSD Foundation, Inc. |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * This code is derived from software contributed to The NetBSD Foundation |
| 8 | * by Matt Thomas of 3am Software Foundry. |
| 9 | * |
| 10 | * Redistribution and use in source and binary forms, with or without |
| 11 | * modification, are permitted provided that the following conditions |
| 12 | * are met: |
| 13 | * 1. Redistributions of source code must retain the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer. |
| 15 | * 2. Redistributions in binary form must reproduce the above copyright |
| 16 | * notice, this list of conditions and the following disclaimer in the |
| 17 | * documentation and/or other materials provided with the distribution. |
| 18 | * |
| 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
| 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
| 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
| 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 29 | * POSSIBILITY OF SUCH DAMAGE. |
| 30 | */ |
| 31 | #ifndef _ARM_AEABI_H_ |
| 32 | #define	_ARM_AEABI_H_ |
| 33 | |
| 34 | #if defined(_KERNEL) || defined(_STANDALONE) |
| 35 | #include <sys/types.h> |
| 36 | #else |
| 37 | #include <stddef.h> |
| 38 | #endif |
| 39 | |
| 40 | #define	__value_in_regs		/* nothing */ |
| 41 | #define	__aapcs			__attribute__((__pcs__("aapcs"))) |
| 42 | |
| 43 | /* |
| 44 | * Standard double precision floating-point arithmetic helper functions |
| 45 | */ |
| 46 | double __aeabi_dadd(double, double) __aapcs;	// double-precision addition |
| 47 | double __aeabi_ddiv(double n, double d) __aapcs;	// double-precision division, n / d |
| 48 | double __aeabi_dmul(double, double) __aapcs;	// double-precision multiplication |
| 49 | double __aeabi_drsub(double x, double y) __aapcs;	// double-precision reverse subtraction, y - x |
| 50 | double __aeabi_dsub(double x, double y) __aapcs;	// double-precision subtraction, x - y |
| 51 | double __aeabi_dneg(double) __aapcs;	// double-precision negation (obsolete, to be removed in r2.09) |
| 52 | |
| 53 | /* |
| 54 | * Double precision floating-point comparison helper functions |
| 55 | */ |
| 56 | void __aeabi_cdcmpeq(double, double) __aapcs; // non-excepting equality comparison [1], result in PSR ZC flags |
| 57 | void __aeabi_cdcmple(double, double) __aapcs; // 3-way (<, =, >) compare [1], result in PSR ZC flags |
| 58 | void __aeabi_cdrcmple(double, double) __aapcs; // reversed 3-way (<, =, >) compare [1], result in PSR ZC flags |
| 59 | int __aeabi_dcmpeq(double, double) __aapcs; // result (1, 0) denotes (=, <>) [2], use for C == and != |
| 60 | int __aeabi_dcmplt(double, double) __aapcs; // result (1, 0) denotes (<, >=) [2], use for C < |
| 61 | int __aeabi_dcmple(double, double) __aapcs; // result (1, 0) denotes (<=, >) [2], use for C <= |
| 62 | int __aeabi_dcmpge(double, double) __aapcs; // result (1, 0) denotes (>=, <) [2], use for C >= |
| 63 | int __aeabi_dcmpgt(double, double) __aapcs; // result (1, 0) denotes (>, <=) [2], use for C > |
| 64 | int __aeabi_dcmpun(double, double) __aapcs; // result (1, 0) denotes (?, <=>) [2], use for C99 isunordered() |
| 65 | |
| 66 | /* |
| 67 | * Standard single precision floating-point arithmetic helper functions |
| 68 | */ |
| 69 | float __aeabi_fadd(float, float) __aapcs; // single-precision addition |
| 70 | float __aeabi_fdiv(float n, float d) __aapcs; // single-precision division, n / d |
| 71 | float __aeabi_fmul(float, float) __aapcs; // single-precision multiplication |
| 72 | float __aeabi_frsub(float x, float y) __aapcs; // single-precision reverse subtraction, y - x |
| 73 | float __aeabi_fsub(float x, float y) __aapcs; // single-precision subtraction, x - y |
| 74 | float __aeabi_fneg(float) __aapcs; // single-precision negation (obsolete, to be removed in r2.09) |
| 75 | |
| 76 | /* |
| 77 | * Standard single precision floating-point comparison helper functions |
| 78 | */ |
| 79 | void __aeabi_cfcmpeq(float, float) __aapcs; // non-excepting equality comparison [1], result in PSR ZC flags |
| 80 | void __aeabi_cfcmple(float, float) __aapcs; // 3-way (<, =, ?>) compare [1], result in PSR ZC flags |
| 81 | void __aeabi_cfrcmple(float, float) __aapcs; // reversed 3-way (<, =, ?>) compare [1], result in PSR ZC flags |
| 82 | int __aeabi_fcmpeq(float, float) __aapcs; // result (1, 0) denotes (=, <>) [2], use for C == and != |
| 83 | int __aeabi_fcmplt(float, float) __aapcs; // result (1, 0) denotes (<, >=) [2], use for C < |
| 84 | int __aeabi_fcmple(float, float) __aapcs; // result (1, 0) denotes (<=, >) [2], use for C <= |
| 85 | int __aeabi_fcmpge(float, float) __aapcs; // result (1, 0) denotes (>=, <) [2], use for C >= |
| 86 | int __aeabi_fcmpgt(float, float) __aapcs; // result (1, 0) denotes (>, <=) [2], use for C > |
| 87 | int __aeabi_fcmpun(float, float) __aapcs; // result (1, 0) denotes (?, <=>) [2], use for C99 isunordered() |
| 88 | |
| 89 | /* |
| 90 | * Standard conversions between floating types |
| 91 | */ |
| 92 | float __aeabi_d2f(double) __aapcs;	// double to float (single precision) conversion |
| 93 | double __aeabi_f2d(float) __aapcs;	// float (single precision) to double conversion |
| 94 | float __aeabi_h2f(short hf) __aapcs;	// IEEE 754 binary16 storage format (VFP half precision) to binary32 (float) conversion [4, 5] |
| 95 | short __aeabi_f2h(float f) __aapcs;	// IEEE 754 binary32 (float) to binary16 storage format (VFP half precision) conversion [4, 6] |
| 96 | float __aeabi_h2f_alt(short hf) __aapcs;	// __aeabi_h2f_alt converts from VFP alternative format [7]. |
| 97 | short __aeabi_f2h_alt(float f) __aapcs;	// __aeabi_f2h_alt converts to VFP alternative format [8]. |
| 98 | |
| 99 | /* |
| 100 | * Standard floating-point to integer conversions |
| 101 | */ |
| 102 | int __aeabi_d2iz(double) __aapcs;	// double to integer C-style conversion [3] |
| 103 | unsigned __aeabi_d2uiz(double) __aapcs;	// double to unsigned C-style conversion [3] |
| 104 | long long __aeabi_d2lz(double) __aapcs;	// double to long long C-style conversion [3] |
| 105 | unsigned long long __aeabi_d2ulz(double) __aapcs;	// double to unsigned long long C-style conversion [3] |
| 106 | int __aeabi_f2iz(float) __aapcs;	// float (single precision) to integer C-style conversion [3] |
| 107 | unsigned __aeabi_f2uiz(float) __aapcs;	// float (single precision) to unsigned C-style conversion [3] |
| 108 | long long __aeabi_f2lz(float) __aapcs;	// float (single precision) to long long C-style conversion [3] |
| 109 | unsigned long long __aeabi_f2ulz(float) __aapcs;	// float to unsigned long long C-style conversion [3] |
| 110 | |
| 111 | /* |
| 112 | * Standard integer to floating-point conversions |
| 113 | */ |
| 114 | double __aeabi_i2d(int) __aapcs;		// integer to double conversion |
| 115 | double __aeabi_ui2d(unsigned) __aapcs;	// unsigned to double conversion |
| 116 | double __aeabi_l2d(long long) __aapcs;	// long long to double conversion |
| 117 | double __aeabi_ul2d(unsigned long long) __aapcs;	// unsigned long long to double conversion |
| 118 | float __aeabi_i2f(int) __aapcs;	// integer to float (single precision) conversion |
| 119 | float __aeabi_ui2f(unsigned) __aapcs;	// unsigned to float (single precision) conversion |
| 120 | float __aeabi_l2f(long long) __aapcs;	// long long to float (single precision) conversion |
| 121 | float __aeabi_ul2f(unsigned long long) __aapcs;	// unsigned long long to float (single precision) conversion |
| 122 | |
| 123 | /* |
| 124 | * Long long functions |
| 125 | */ |
| 126 | long long __aeabi_lmul(long long, long long); // multiplication |
| 127 | |
| 128 | /* |
| 129 | * A pair of (unsigned) long longs is returned in {{r0, r1}, {r2, r3}}, |
| 130 | * the quotient in {r0, r1}, and the remainder in {r2, r3}. |
| 131 | */ |
| 132 | typedef struct { long long quot; long long rem; } lldiv_t; |
| 133 | __value_in_regs lldiv_t __aeabi_ldivmod(long long n, long long d); // signed long long division and remainder, {q, r} = n / d [2] |
| 134 | |
| 135 | typedef struct { unsigned long long quot; unsigned long long rem; } ulldiv_t; |
| 136 | __value_in_regs ulldiv_t __aeabi_uldivmod(unsigned long long n, unsigned long long d); // unsigned signed ll division, remainder, {q, r} = n / d [2] |
| 137 | |
| 138 | /* |
| 139 | * Because of 2's complement number representation, these functions work |
| 140 | * identically with long long replaced uniformly by unsigned long long. |
| 141 | * Each returns its result in {r0, r1}, as specified by the [AAPCS]. |
| 142 | */ |
| 143 | long long __aeabi_llsl(long long, int); // logical shift left [1] |
| 144 | long long __aeabi_llsr(long long, int); // logical shift right [1] |
| 145 | long long __aeabi_lasr(long long, int); // arithmetic shift right [1] |
| 146 | |
| 147 | /* |
| 148 | * The comparison functions return negative, zero, or a positive integer |
| 149 | * according to whether the comparison result is <, ==, or >, respectively |
| 150 | * (like strcmp). |
| 151 | */ |
| 152 | int __aeabi_lcmp(long long, long long); // signed long long comparison |
| 153 | int __aeabi_ulcmp(unsigned long long, unsigned long long); // unsigned long long comparison |
| 154 | |
| 155 | int __aeabi_idiv(int numerator, int denominator); |
| 156 | unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator); |
| 157 | typedef struct { int quot, rem; } idiv_return; |
| 158 | typedef struct { unsigned int quot, rem; } uidiv_return; |
| 159 | __value_in_regs idiv_return __aeabi_idivmod(int, int); |
| 160 | __value_in_regs uidiv_return __aeabi_uidivmod(unsigned int, unsigned int); |
| 161 | |
| 162 | /* |
| 163 | * Division by zero |
| 164 | * |
| 165 | * If an integer or long long division helper function is called upon to |
| 166 | * divide by 0, it should return as quotient the value returned by a call |
| 167 | * to __aeabi_idiv0 or __aeabi_ldiv0, respectively. A *divmod helper should |
| 168 | * return as remainder either 0 or the original numerator. |
| 169 | */ |
| 170 | int __aeabi_idiv0(int); |
| 171 | long long __aeabi_ldiv0(long long); |
| 172 | |
| 173 | /* |
| 174 | * These functions read and write 4-byte and 8-byte values at arbitrarily |
| 175 | * aligned addresses. Write functions return the value written, |
| 176 | * read functions the value read. |
| 177 | */ |
| 178 | int __aeabi_uread4(void *); |
| 179 | int __aeabi_uwrite4(int, void *); |
| 180 | long long __aeabi_uread8(void *); |
| 181 | long long __aeabi_uwrite8(long long, void *); |
| 182 | |
| 183 | /* |
| 184 | * Memory copying, clearing, and setting |
| 185 | */ |
| 186 | void __aeabi_memcpy8(void *, const void *, size_t); |
| 187 | void __aeabi_memcpy4(void *, const void *, size_t); |
| 188 | void __aeabi_memcpy(void *, const void *, size_t); |
| 189 | void __aeabi_memmove8(void *, const void *, size_t); |
| 190 | void __aeabi_memmove4(void *, const void *, size_t); |
| 191 | void __aeabi_memmove(void *, const void *, size_t); |
| 192 | |
| 193 | /* |
| 194 | * Memory clearing and setting |
| 195 | */ |
| 196 | void __aeabi_memset8(void *, size_t, int); |
| 197 | void __aeabi_memset4(void *, size_t, int); |
| 198 | void __aeabi_memset(void *, size_t, int); |
| 199 | void __aeabi_memclr8(void *, size_t); |
| 200 | void __aeabi_memclr4(void *, size_t); |
| 201 | void __aeabi_memclr(void *, size_t); |
| 202 | |
| 203 | void *__aeabi_read_tp(void); // return the value of $tp |
| 204 | |
| 205 | #undef	__aapcs |
| 206 | |
| 207 | #endif /* _ARM_AEABI_H_ */ |