1 /* $NetBSD: qp.c,v 1.5 2003/05/01 21:24:13 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the NetBSD 18 * Foundation, Inc. and its contributors. 19 * 4. Neither the name of The NetBSD Foundation nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 #include <memory.h> 38 39 #include "milieu.h" 40 #include "softfloat.h" 41 42 43 void _Qp_add(float128 *c, float128 *a, float128 *b); 44 int _Qp_cmp(float128 *a, float128 *b); 45 int _Qp_cmpe(float128 *a, float128 *b); 46 void _Qp_div(float128 *c, float128 *a, float128 *b); 47 void _Qp_dtoq(float128 *c, double a); 48 int _Qp_feq(float128 *a, float128 *b); 49 int _Qp_fge(float128 *a, float128 *b); 50 int _Qp_fgt(float128 *a, float128 *b); 51 int _Qp_fle(float128 *a, float128 *b); 52 int _Qp_flt(float128 *a, float128 *b); 53 int _Qp_fne(float128 *a, float128 *b); 54 void _Qp_itoq(float128 *c, int a); 55 void _Qp_mul(float128 *c, float128 *a, float128 *b); 56 void _Qp_neg(float128 *c, float128 *a); 57 double _Qp_qtod(float128 *a); 58 int _Qp_qtoi(float128 *a); 59 float _Qp_qtos(float128 *a); 60 unsigned int _Qp_qtoui(float128 *a); 61 unsigned long _Qp_qtoux(float128 *a); 62 long _Qp_qtox(float128 *a); 63 void _Qp_sqrt(float128 *c, float128 *a); 64 void _Qp_stoq(float128 *c, float a); 65 void _Qp_sub(float128 *c, float128 *a, float128 *b); 66 void _Qp_uitoq(float128 *c, unsigned int a); 67 void _Qp_uxtoq(float128 *c, unsigned long a); 68 void _Qp_xtoq(float128 *c, long a); 69 70 71 void 72 _Qp_add(float128 *c, float128 *a, float128 *b) 73 { 74 *c = float128_add(*a, *b); 75 } 76 77 78 int 79 _Qp_cmp(float128 *a, float128 *b) 80 { 81 82 if (float128_eq(*a, *b)) 83 return 0; 84 85 if (float128_le(*a, *b)) 86 return 1; 87 88 return 2; 89 } 90 91 92 /* 93 * XXX 94 */ 95 int 96 _Qp_cmpe(float128 *a, float128 *b) 97 { 98 return _Qp_cmp(a, b); 99 } 100 101 102 void 103 _Qp_div(float128 *c, float128 *a, float128 *b) 104 { 105 *c = float128_div(*a, *b); 106 } 107 108 109 void 110 _Qp_dtoq(float128 *c, double a) 111 { 112 float64 _b; 113 114 memcpy (&_b, &a, sizeof(float64)); 115 *c = float64_to_float128(_b); 116 } 117 118 119 int 120 _Qp_feq(float128 *a, float128 *b) 121 { 122 return float128_eq(*a, *b); 123 } 124 125 126 int 127 _Qp_fge(float128 *a, float128 *b) 128 { 129 return float128_le(*b, *a); 130 } 131 132 133 int 134 _Qp_fgt(float128 *a, float128 *b) 135 { 136 return float128_lt(*b, *a); 137 } 138 139 140 int 141 _Qp_fle(float128 *a, float128 *b) 142 { 143 return float128_le(*a, *b); 144 } 145 146 147 int 148 _Qp_flt(float128 *a, float128 *b) 149 { 150 return float128_lt(*a, *b); 151 } 152 153 154 int 155 _Qp_fne(float128 *a, float128 *b) 156 { 157 return !float128_eq(*a, *b); 158 } 159 160 161 void 162 _Qp_itoq(float128 *c, int a) 163 { 164 *c = int32_to_float128(a); 165 } 166 167 168 void 169 _Qp_mul(float128 *c, float128 *a, float128 *b) 170 { 171 *c = float128_mul(*a, *b); 172 } 173 174 175 /* 176 * XXX need corresponding softfloat function 177 */ 178 static float128 __zero = {0x4034000000000000, 0x00000000}; 179 180 void 181 _Qp_neg(float128 *c, float128 *a) 182 { 183 *c = float128_sub(__zero, *a); 184 } 185 186 187 double 188 _Qp_qtod(float128 *a) 189 { 190 float64 _c; 191 double c; 192 193 _c = float128_to_float64(*a); 194 195 memcpy(&c, &_c, sizeof(double)); 196 197 return c; 198 } 199 200 201 int 202 _Qp_qtoi(float128 *a) 203 { 204 return float128_to_int32(*a); 205 } 206 207 208 float 209 _Qp_qtos(float128 *a) 210 { 211 float c; 212 float32 _c; 213 214 _c = float128_to_float32(*a); 215 216 memcpy(&c, &_c, sizeof(_c)); 217 218 return c; 219 } 220 221 222 unsigned int 223 _Qp_qtoui(float128 *a) 224 { 225 return (unsigned int)float128_to_int64(*a); 226 } 227 228 229 unsigned long 230 _Qp_qtoux(float128 *a) 231 { 232 return (unsigned long)float128_to_int64(*a); 233 } 234 235 236 long 237 _Qp_qtox(float128 *a) 238 { 239 return (long)float128_to_int64(*a); 240 } 241 242 243 void 244 _Qp_sqrt(float128 *c, float128 *a) 245 { 246 *c = float128_sqrt(*a); 247 } 248 249 250 void 251 _Qp_stoq(float128 *c, float a) 252 { 253 float32 _a; 254 255 memcpy(&_a, &a, sizeof(a)); 256 257 *c = float32_to_float128(_a); 258 } 259 260 261 void 262 _Qp_sub(float128 *c, float128 *a, float128 *b) 263 { 264 *c = float128_sub(*a, *b); 265 } 266 267 268 void 269 _Qp_uitoq(float128 *c, unsigned int a) 270 { 271 *c = int64_to_float128(a); 272 } 273 274 275 void 276 _Qp_uxtoq(float128 *c, unsigned long a) 277 { 278 279 if (a & 0x8000000000000000ULL) { 280 a = (a >> 1) | (a & 1); 281 *c = int64_to_float128(a); 282 *c = float128_add(*c, *c); 283 } else 284 *c = int64_to_float128(a); 285 } 286 287 288 void 289 _Qp_xtoq(float128 *c, long a) 290 { 291 *c = int64_to_float128(a); 292 } 293