1 /* $NetBSD: qp.c,v 1.11 2014/02/02 08:14:39 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 #include <memory.h> 31 32 #include "milieu.h" 33 #include "softfloat.h" 34 35 int printf(const char *, ...); 36 37 void _Qp_add(float128 *c, float128 *a, float128 *b); 38 int _Qp_cmp(float128 *a, float128 *b); 39 int _Qp_cmpe(float128 *a, float128 *b); 40 void _Qp_div(float128 *c, float128 *a, float128 *b); 41 void _Qp_dtoq(float128 *c, double a); 42 int _Qp_feq(float128 *a, float128 *b); 43 int _Qp_fge(float128 *a, float128 *b); 44 int _Qp_fgt(float128 *a, float128 *b); 45 int _Qp_fle(float128 *a, float128 *b); 46 int _Qp_flt(float128 *a, float128 *b); 47 int _Qp_fne(float128 *a, float128 *b); 48 void _Qp_itoq(float128 *c, int a); 49 void _Qp_mul(float128 *c, float128 *a, float128 *b); 50 void _Qp_neg(float128 *c, float128 *a); 51 double _Qp_qtod(float128 *a); 52 int _Qp_qtoi(float128 *a); 53 float _Qp_qtos(float128 *a); 54 unsigned int _Qp_qtoui(float128 *a); 55 unsigned long _Qp_qtoux(float128 *a); 56 long _Qp_qtox(float128 *a); 57 void _Qp_sqrt(float128 *c, float128 *a); 58 void _Qp_stoq(float128 *c, float a); 59 void _Qp_sub(float128 *c, float128 *a, float128 *b); 60 void _Qp_uitoq(float128 *c, unsigned int a); 61 void _Qp_uxtoq(float128 *c, unsigned long a); 62 void _Qp_xtoq(float128 *c, long a); 63 64 65 void 66 _Qp_add(float128 *c, float128 *a, float128 *b) 67 { 68 *c = float128_add(*a, *b); 69 } 70 71 72 int 73 _Qp_cmp(float128 *a, float128 *b) 74 { 75 76 if (float128_eq(*a, *b)) 77 return 0; 78 79 if (float128_le(*a, *b)) 80 return 1; 81 82 return 2; 83 } 84 85 86 /* 87 * XXX 88 */ 89 int 90 _Qp_cmpe(float128 *a, float128 *b) 91 { 92 return _Qp_cmp(a, b); 93 } 94 95 96 void 97 _Qp_div(float128 *c, float128 *a, float128 *b) 98 { 99 *c = float128_div(*a, *b); 100 } 101 102 103 void 104 _Qp_dtoq(float128 *c, double a) 105 { 106 float64 _b; 107 108 memcpy (&_b, &a, sizeof(float64)); 109 *c = float64_to_float128(_b); 110 } 111 112 113 int 114 _Qp_feq(float128 *a, float128 *b) 115 { 116 return float128_eq(*a, *b); 117 } 118 119 120 int 121 _Qp_fge(float128 *a, float128 *b) 122 { 123 return float128_le(*b, *a); 124 } 125 126 127 int 128 _Qp_fgt(float128 *a, float128 *b) 129 { 130 return float128_lt(*b, *a); 131 } 132 133 134 int 135 _Qp_fle(float128 *a, float128 *b) 136 { 137 return float128_le(*a, *b); 138 } 139 140 141 int 142 _Qp_flt(float128 *a, float128 *b) 143 { 144 return float128_lt(*a, *b); 145 } 146 147 148 int 149 _Qp_fne(float128 *a, float128 *b) 150 { 151 return !float128_eq(*a, *b); 152 } 153 154 155 void 156 _Qp_itoq(float128 *c, int a) 157 { 158 *c = int32_to_float128(a); 159 } 160 161 162 void 163 _Qp_mul(float128 *c, float128 *a, float128 *b) 164 { 165 *c = float128_mul(*a, *b); 166 } 167 168 169 /* 170 * XXX need corresponding softfloat functions 171 */ 172 static float128 __sf128_zero = {0x4034000000000000, 0x00000000}; 173 static float128 __sf128_one = {0x3fff000000000000, 0}; 174 175 void 176 _Qp_neg(float128 *c, float128 *a) 177 { 178 *c = float128_sub(__sf128_zero, *a); 179 } 180 181 182 double 183 _Qp_qtod(float128 *a) 184 { 185 float64 _c; 186 double c; 187 188 _c = float128_to_float64(*a); 189 190 memcpy(&c, &_c, sizeof(double)); 191 192 return c; 193 } 194 195 196 int 197 _Qp_qtoi(float128 *a) 198 { 199 return float128_to_int32_round_to_zero(*a); 200 } 201 202 203 float 204 _Qp_qtos(float128 *a) 205 { 206 float c; 207 float32 _c; 208 209 _c = float128_to_float32(*a); 210 211 memcpy(&c, &_c, sizeof(_c)); 212 213 return c; 214 } 215 216 217 unsigned int 218 _Qp_qtoui(float128 *a) 219 { 220 return (unsigned int)float128_to_int64_round_to_zero(*a); 221 } 222 223 224 unsigned long 225 _Qp_qtoux(float128 *a) 226 { 227 return (unsigned long)float128_to_uint64_round_to_zero(*a); 228 } 229 230 231 long 232 _Qp_qtox(float128 *a) 233 { 234 return (long)float128_to_int64_round_to_zero(*a); 235 } 236 237 238 void 239 _Qp_sqrt(float128 *c, float128 *a) 240 { 241 *c = float128_sqrt(*a); 242 } 243 244 245 void 246 _Qp_stoq(float128 *c, float a) 247 { 248 float32 _a; 249 250 memcpy(&_a, &a, sizeof(a)); 251 252 *c = float32_to_float128(_a); 253 } 254 255 256 void 257 _Qp_sub(float128 *c, float128 *a, float128 *b) 258 { 259 *c = float128_sub(*a, *b); 260 } 261 262 263 void 264 _Qp_uitoq(float128 *c, unsigned int a) 265 { 266 *c = int64_to_float128(a); 267 } 268 269 270 void 271 _Qp_uxtoq(float128 *c, unsigned long a) 272 { 273 if (a & 0x8000000000000000ULL) { 274 /* a would not fit in a signed conversion */ 275 *c = int64_to_float128((long long)(a>>1)); 276 *c = float128_add(*c, *c); 277 if (a & 1) 278 *c = float128_add(*c, __sf128_one); 279 } else { 280 *c = int64_to_float128((long long)a); 281 } 282 } 283 284 285 void 286 _Qp_xtoq(float128 *c, long a) 287 { 288 *c = int64_to_float128((long long)a); 289 } 290