10Sduke/* $NetBSD: qp.c,v 1.10 2013/02/15 09:24:05 martin Exp $ */ 22105Ssla 30Sduke/*- 40Sduke * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc. 50Sduke * All rights reserved. 60Sduke * 70Sduke * Redistribution and use in source and binary forms, with or without 80Sduke * modification, are permitted provided that the following conditions 90Sduke * are met: 100Sduke * 1. Redistributions of source code must retain the above copyright 110Sduke * notice, this list of conditions and the following disclaimer. 120Sduke * 2. Redistributions in binary form must reproduce the above copyright 130Sduke * notice, this list of conditions and the following disclaimer in the 140Sduke * documentation and/or other materials provided with the distribution. 150Sduke * 160Sduke * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 170Sduke * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 180Sduke * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191472Strims * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201472Strims * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211472Strims * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 220Sduke * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 230Sduke * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 240Sduke * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251879Sstefank * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261879Sstefank * POSSIBILITY OF SUCH DAMAGE. 271879Sstefank */ 280Sduke 290Sduke#include <sys/cdefs.h> 300Sduke#include <memory.h> 310Sduke 320Sduke#include "milieu.h" 330Sduke#include "softfloat.h" 346413Szgu 356413Szguint printf(const char *, ...); 366413Szgu 376413Szguvoid _Qp_add(float128 *c, float128 *a, float128 *b); 386413Szguint _Qp_cmp(float128 *a, float128 *b); 396413Szguint _Qp_cmpe(float128 *a, float128 *b); 400Sdukevoid _Qp_div(float128 *c, float128 *a, float128 *b); 410Sdukevoid _Qp_dtoq(float128 *c, double a); 425777Stwistiint _Qp_feq(float128 *a, float128 *b); 435777Stwistiint _Qp_fge(float128 *a, float128 *b); 445777Stwistiint _Qp_fgt(float128 *a, float128 *b); 450Sdukeint _Qp_fle(float128 *a, float128 *b); 460Sdukeint _Qp_flt(float128 *a, float128 *b); 470Sdukeint _Qp_fne(float128 *a, float128 *b); 480Sdukevoid _Qp_itoq(float128 *c, int a); 49645Skvnvoid _Qp_mul(float128 *c, float128 *a, float128 *b); 500Sdukevoid _Qp_neg(float128 *c, float128 *a); 510Sdukedouble _Qp_qtod(float128 *a); 520Sdukeint _Qp_qtoi(float128 *a); 530Sdukefloat _Qp_qtos(float128 *a); 540Sdukeunsigned int _Qp_qtoui(float128 *a); 550Sdukeunsigned long _Qp_qtoux(float128 *a); 560Sdukelong _Qp_qtox(float128 *a); 570Sdukevoid _Qp_sqrt(float128 *c, float128 *a); 580Sdukevoid _Qp_stoq(float128 *c, float a); 590Sdukevoid _Qp_sub(float128 *c, float128 *a, float128 *b); 600Sdukevoid _Qp_uitoq(float128 *c, unsigned int a); 610Sdukevoid _Qp_uxtoq(float128 *c, unsigned long a); 620Sdukevoid _Qp_xtoq(float128 *c, long a); 630Sduke 640Sduke 650Sdukevoid 660Sduke_Qp_add(float128 *c, float128 *a, float128 *b) 670Sduke{ 680Sduke *c = float128_add(*a, *b); 690Sduke} 705777Stwisti 710Sduke 720Sdukeint 732721Snever_Qp_cmp(float128 *a, float128 *b) 740Sduke{ 752721Snever 760Sduke if (float128_eq(*a, *b)) 770Sduke return 0; 780Sduke 790Sduke if (float128_le(*a, *b)) 800Sduke return 1; 811879Sstefank 821879Sstefank return 2; 831879Sstefank} 840Sduke 850Sduke 86603Stwisti/* 870Sduke * XXX 881879Sstefank */ 890Sdukeint 900Sduke_Qp_cmpe(float128 *a, float128 *b) 910Sduke{ 920Sduke return _Qp_cmp(a, b); 931879Sstefank} 940Sduke 950Sduke 960Sdukevoid 970Sduke_Qp_div(float128 *c, float128 *a, float128 *b) 980Sduke{ 990Sduke *c = float128_div(*a, *b); 1000Sduke} 1010Sduke 1020Sduke 1030Sdukevoid 1040Sduke_Qp_dtoq(float128 *c, double a) 1050Sduke{ 1061879Sstefank float64 _b; 1071879Sstefank 108 memcpy (&_b, &a, sizeof(float64)); 109 *c = float64_to_float128(_b); 110} 111 112 113int 114_Qp_feq(float128 *a, float128 *b) 115{ 116 return float128_eq(*a, *b); 117} 118 119 120int 121_Qp_fge(float128 *a, float128 *b) 122{ 123 return float128_le(*b, *a); 124} 125 126 127int 128_Qp_fgt(float128 *a, float128 *b) 129{ 130 return float128_lt(*b, *a); 131} 132 133 134int 135_Qp_fle(float128 *a, float128 *b) 136{ 137 return float128_le(*a, *b); 138} 139 140 141int 142_Qp_flt(float128 *a, float128 *b) 143{ 144 return float128_lt(*a, *b); 145} 146 147 148int 149_Qp_fne(float128 *a, float128 *b) 150{ 151 return !float128_eq(*a, *b); 152} 153 154 155void 156_Qp_itoq(float128 *c, int a) 157{ 158 *c = int32_to_float128(a); 159} 160 161 162void 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 */ 172static float128 __sf128_zero = {0x4034000000000000, 0x00000000}; 173static float128 __sf128_one = {0x3fff000000000000, 0}; 174 175void 176_Qp_neg(float128 *c, float128 *a) 177{ 178 *c = float128_sub(__sf128_zero, *a); 179} 180 181 182double 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 196int 197_Qp_qtoi(float128 *a) 198{ 199 return float128_to_int32_round_to_zero(*a); 200} 201 202 203float 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 217unsigned int 218_Qp_qtoui(float128 *a) 219{ 220 return (unsigned int)float128_to_int64_round_to_zero(*a); 221} 222 223 224unsigned long 225_Qp_qtoux(float128 *a) 226{ 227 return (unsigned long)float128_to_uint64_round_to_zero(*a); 228} 229 230 231long 232_Qp_qtox(float128 *a) 233{ 234 return (long)float128_to_int64_round_to_zero(*a); 235} 236 237 238void 239_Qp_sqrt(float128 *c, float128 *a) 240{ 241 *c = float128_sqrt(*a); 242} 243 244 245void 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 256void 257_Qp_sub(float128 *c, float128 *a, float128 *b) 258{ 259 *c = float128_sub(*a, *b); 260} 261 262 263void 264_Qp_uitoq(float128 *c, unsigned int a) 265{ 266 *c = int64_to_float128(a); 267} 268 269 270void 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 285void 286_Qp_xtoq(float128 *c, long a) 287{ 288 *c = int64_to_float128((long long)a); 289} 290