1 /* $NetBSD: qp.c,v 1.7 2008/04/28 20:22:57 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 36 void _Qp_add(float128 *c, float128 *a, float128 *b); 37 int _Qp_cmp(float128 *a, float128 *b); 38 int _Qp_cmpe(float128 *a, float128 *b); 39 void _Qp_div(float128 *c, float128 *a, float128 *b); 40 void _Qp_dtoq(float128 *c, double a); 41 int _Qp_feq(float128 *a, float128 *b); 42 int _Qp_fge(float128 *a, float128 *b); 43 int _Qp_fgt(float128 *a, float128 *b); 44 int _Qp_fle(float128 *a, float128 *b); 45 int _Qp_flt(float128 *a, float128 *b); 46 int _Qp_fne(float128 *a, float128 *b); 47 void _Qp_itoq(float128 *c, int a); 48 void _Qp_mul(float128 *c, float128 *a, float128 *b); 49 void _Qp_neg(float128 *c, float128 *a); 50 double _Qp_qtod(float128 *a); 51 int _Qp_qtoi(float128 *a); 52 float _Qp_qtos(float128 *a); 53 unsigned int _Qp_qtoui(float128 *a); 54 unsigned long _Qp_qtoux(float128 *a); 55 long _Qp_qtox(float128 *a); 56 void _Qp_sqrt(float128 *c, float128 *a); 57 void _Qp_stoq(float128 *c, float a); 58 void _Qp_sub(float128 *c, float128 *a, float128 *b); 59 void _Qp_uitoq(float128 *c, unsigned int a); 60 void _Qp_uxtoq(float128 *c, unsigned long a); 61 void _Qp_xtoq(float128 *c, long a); 62 63 64 void 65 _Qp_add(float128 *c, float128 *a, float128 *b) 66 { 67 *c = float128_add(*a, *b); 68 } 69 70 71 int 72 _Qp_cmp(float128 *a, float128 *b) 73 { 74 75 if (float128_eq(*a, *b)) 76 return 0; 77 78 if (float128_le(*a, *b)) 79 return 1; 80 81 return 2; 82 } 83 84 85 /* 86 * XXX 87 */ 88 int 89 _Qp_cmpe(float128 *a, float128 *b) 90 { 91 return _Qp_cmp(a, b); 92 } 93 94 95 void 96 _Qp_div(float128 *c, float128 *a, float128 *b) 97 { 98 *c = float128_div(*a, *b); 99 } 100 101 102 void 103 _Qp_dtoq(float128 *c, double a) 104 { 105 float64 _b; 106 107 memcpy (&_b, &a, sizeof(float64)); 108 *c = float64_to_float128(_b); 109 } 110 111 112 int 113 _Qp_feq(float128 *a, float128 *b) 114 { 115 return float128_eq(*a, *b); 116 } 117 118 119 int 120 _Qp_fge(float128 *a, float128 *b) 121 { 122 return float128_le(*b, *a); 123 } 124 125 126 int 127 _Qp_fgt(float128 *a, float128 *b) 128 { 129 return float128_lt(*b, *a); 130 } 131 132 133 int 134 _Qp_fle(float128 *a, float128 *b) 135 { 136 return float128_le(*a, *b); 137 } 138 139 140 int 141 _Qp_flt(float128 *a, float128 *b) 142 { 143 return float128_lt(*a, *b); 144 } 145 146 147 int 148 _Qp_fne(float128 *a, float128 *b) 149 { 150 return !float128_eq(*a, *b); 151 } 152 153 154 void 155 _Qp_itoq(float128 *c, int a) 156 { 157 *c = int32_to_float128(a); 158 } 159 160 161 void 162 _Qp_mul(float128 *c, float128 *a, float128 *b) 163 { 164 *c = float128_mul(*a, *b); 165 } 166 167 168 /* 169 * XXX need corresponding softfloat function 170 */ 171 static float128 __zero = {0x4034000000000000, 0x00000000}; 172 173 void 174 _Qp_neg(float128 *c, float128 *a) 175 { 176 *c = float128_sub(__zero, *a); 177 } 178 179 180 double 181 _Qp_qtod(float128 *a) 182 { 183 float64 _c; 184 double c; 185 186 _c = float128_to_float64(*a); 187 188 memcpy(&c, &_c, sizeof(double)); 189 190 return c; 191 } 192 193 194 int 195 _Qp_qtoi(float128 *a) 196 { 197 return float128_to_int32(*a); 198 } 199 200 201 float 202 _Qp_qtos(float128 *a) 203 { 204 float c; 205 float32 _c; 206 207 _c = float128_to_float32(*a); 208 209 memcpy(&c, &_c, sizeof(_c)); 210 211 return c; 212 } 213 214 215 unsigned int 216 _Qp_qtoui(float128 *a) 217 { 218 return (unsigned int)float128_to_int64(*a); 219 } 220 221 222 unsigned long 223 _Qp_qtoux(float128 *a) 224 { 225 return (unsigned long)float128_to_uint64_round_to_zero(*a); 226 } 227 228 229 long 230 _Qp_qtox(float128 *a) 231 { 232 return (long)float128_to_int64_round_to_zero(*a); 233 } 234 235 236 void 237 _Qp_sqrt(float128 *c, float128 *a) 238 { 239 *c = float128_sqrt(*a); 240 } 241 242 243 void 244 _Qp_stoq(float128 *c, float a) 245 { 246 float32 _a; 247 248 memcpy(&_a, &a, sizeof(a)); 249 250 *c = float32_to_float128(_a); 251 } 252 253 254 void 255 _Qp_sub(float128 *c, float128 *a, float128 *b) 256 { 257 *c = float128_sub(*a, *b); 258 } 259 260 261 void 262 _Qp_uitoq(float128 *c, unsigned int a) 263 { 264 *c = int64_to_float128(a); 265 } 266 267 268 void 269 _Qp_uxtoq(float128 *c, unsigned long a) 270 { 271 272 if (a & 0x8000000000000000ULL) { 273 a = (a >> 1) | (a & 1); 274 *c = int64_to_float128(a); 275 *c = float128_add(*c, *c); 276 } else 277 *c = int64_to_float128(a); 278 } 279 280 281 void 282 _Qp_xtoq(float128 *c, long a) 283 { 284 *c = int64_to_float128(a); 285 } 286