1176491Smarcel/* $NetBSD: fpu_implode.c,v 1.6 2005/12/11 12:18:42 christos Exp $ */ 2176491Smarcel 3176491Smarcel/* 4176491Smarcel * Copyright (c) 1992, 1993 5176491Smarcel * The Regents of the University of California. All rights reserved. 6176491Smarcel * 7176491Smarcel * This software was developed by the Computer Systems Engineering group 8176491Smarcel * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9176491Smarcel * contributed to Berkeley. 10176491Smarcel * 11176491Smarcel * All advertising materials mentioning features or use of this software 12176491Smarcel * must display the following acknowledgement: 13176491Smarcel * This product includes software developed by the University of 14176491Smarcel * California, Lawrence Berkeley Laboratory. 15176491Smarcel * 16176491Smarcel * Redistribution and use in source and binary forms, with or without 17176491Smarcel * modification, are permitted provided that the following conditions 18176491Smarcel * are met: 19176491Smarcel * 1. Redistributions of source code must retain the above copyright 20176491Smarcel * notice, this list of conditions and the following disclaimer. 21176491Smarcel * 2. Redistributions in binary form must reproduce the above copyright 22176491Smarcel * notice, this list of conditions and the following disclaimer in the 23176491Smarcel * documentation and/or other materials provided with the distribution. 24176491Smarcel * 3. Neither the name of the University nor the names of its contributors 25176491Smarcel * may be used to endorse or promote products derived from this software 26176491Smarcel * without specific prior written permission. 27176491Smarcel * 28176491Smarcel * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29176491Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30176491Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31176491Smarcel * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32176491Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33176491Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34176491Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35176491Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36176491Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37176491Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38176491Smarcel * SUCH DAMAGE. 39176491Smarcel * 40176491Smarcel * @(#)fpu_implode.c 8.1 (Berkeley) 6/11/93 41176491Smarcel */ 42176491Smarcel 43176491Smarcel/* 44176491Smarcel * FPU subroutines: `implode' internal format numbers into the machine's 45176491Smarcel * `packed binary' format. 46176491Smarcel */ 47176491Smarcel 48176491Smarcel#include <sys/cdefs.h> 49176491Smarcel__FBSDID("$FreeBSD: releng/10.3/sys/powerpc/fpu/fpu_implode.c 178030 2008-04-09 08:50:37Z grehan $"); 50176491Smarcel 51178030Sgrehan#include <sys/types.h> 52176491Smarcel#include <sys/systm.h> 53176491Smarcel 54176491Smarcel#include <machine/fpu.h> 55176491Smarcel#include <machine/ieee.h> 56176491Smarcel#include <machine/ieeefp.h> 57176491Smarcel#include <machine/reg.h> 58176491Smarcel 59176491Smarcel#include <powerpc/fpu/fpu_arith.h> 60176491Smarcel#include <powerpc/fpu/fpu_emu.h> 61176491Smarcel#include <powerpc/fpu/fpu_extern.h> 62176491Smarcel#include <powerpc/fpu/fpu_instr.h> 63176491Smarcel 64176491Smarcelstatic int round(struct fpemu *, struct fpn *); 65176491Smarcelstatic int toinf(struct fpemu *, int); 66176491Smarcel 67176491Smarcel/* 68176491Smarcel * Round a number (algorithm from Motorola MC68882 manual, modified for 69176491Smarcel * our internal format). Set inexact exception if rounding is required. 70176491Smarcel * Return true iff we rounded up. 71176491Smarcel * 72176491Smarcel * After rounding, we discard the guard and round bits by shifting right 73176491Smarcel * 2 bits (a la fpu_shr(), but we do not bother with fp->fp_sticky). 74176491Smarcel * This saves effort later. 75176491Smarcel * 76176491Smarcel * Note that we may leave the value 2.0 in fp->fp_mant; it is the caller's 77176491Smarcel * responsibility to fix this if necessary. 78176491Smarcel */ 79176491Smarcelstatic int 80176491Smarcelround(struct fpemu *fe, struct fpn *fp) 81176491Smarcel{ 82176491Smarcel u_int m0, m1, m2, m3; 83176491Smarcel int gr, s; 84176491Smarcel FPU_DECL_CARRY; 85176491Smarcel 86176491Smarcel m0 = fp->fp_mant[0]; 87176491Smarcel m1 = fp->fp_mant[1]; 88176491Smarcel m2 = fp->fp_mant[2]; 89176491Smarcel m3 = fp->fp_mant[3]; 90176491Smarcel gr = m3 & 3; 91176491Smarcel s = fp->fp_sticky; 92176491Smarcel 93176491Smarcel /* mant >>= FP_NG */ 94176491Smarcel m3 = (m3 >> FP_NG) | (m2 << (32 - FP_NG)); 95176491Smarcel m2 = (m2 >> FP_NG) | (m1 << (32 - FP_NG)); 96176491Smarcel m1 = (m1 >> FP_NG) | (m0 << (32 - FP_NG)); 97176491Smarcel m0 >>= FP_NG; 98176491Smarcel 99176491Smarcel if ((gr | s) == 0) /* result is exact: no rounding needed */ 100176491Smarcel goto rounddown; 101176491Smarcel 102176491Smarcel fe->fe_cx |= FPSCR_XX|FPSCR_FI; /* inexact */ 103176491Smarcel 104176491Smarcel /* Go to rounddown to round down; break to round up. */ 105176491Smarcel switch ((fe->fe_fpscr) & FPSCR_RN) { 106176491Smarcel 107176491Smarcel case FP_RN: 108176491Smarcel default: 109176491Smarcel /* 110176491Smarcel * Round only if guard is set (gr & 2). If guard is set, 111176491Smarcel * but round & sticky both clear, then we want to round 112176491Smarcel * but have a tie, so round to even, i.e., add 1 iff odd. 113176491Smarcel */ 114176491Smarcel if ((gr & 2) == 0) 115176491Smarcel goto rounddown; 116176491Smarcel if ((gr & 1) || fp->fp_sticky || (m3 & 1)) 117176491Smarcel break; 118176491Smarcel goto rounddown; 119176491Smarcel 120176491Smarcel case FP_RZ: 121176491Smarcel /* Round towards zero, i.e., down. */ 122176491Smarcel goto rounddown; 123176491Smarcel 124176491Smarcel case FP_RM: 125176491Smarcel /* Round towards -Inf: up if negative, down if positive. */ 126176491Smarcel if (fp->fp_sign) 127176491Smarcel break; 128176491Smarcel goto rounddown; 129176491Smarcel 130176491Smarcel case FP_RP: 131176491Smarcel /* Round towards +Inf: up if positive, down otherwise. */ 132176491Smarcel if (!fp->fp_sign) 133176491Smarcel break; 134176491Smarcel goto rounddown; 135176491Smarcel } 136176491Smarcel 137176491Smarcel /* Bump low bit of mantissa, with carry. */ 138176491Smarcel fe->fe_cx |= FPSCR_FR; 139176491Smarcel 140176491Smarcel FPU_ADDS(m3, m3, 1); 141176491Smarcel FPU_ADDCS(m2, m2, 0); 142176491Smarcel FPU_ADDCS(m1, m1, 0); 143176491Smarcel FPU_ADDC(m0, m0, 0); 144176491Smarcel fp->fp_mant[0] = m0; 145176491Smarcel fp->fp_mant[1] = m1; 146176491Smarcel fp->fp_mant[2] = m2; 147176491Smarcel fp->fp_mant[3] = m3; 148176491Smarcel return (1); 149176491Smarcel 150176491Smarcelrounddown: 151176491Smarcel fp->fp_mant[0] = m0; 152176491Smarcel fp->fp_mant[1] = m1; 153176491Smarcel fp->fp_mant[2] = m2; 154176491Smarcel fp->fp_mant[3] = m3; 155176491Smarcel return (0); 156176491Smarcel} 157176491Smarcel 158176491Smarcel/* 159176491Smarcel * For overflow: return true if overflow is to go to +/-Inf, according 160176491Smarcel * to the sign of the overflowing result. If false, overflow is to go 161176491Smarcel * to the largest magnitude value instead. 162176491Smarcel */ 163176491Smarcelstatic int 164176491Smarceltoinf(struct fpemu *fe, int sign) 165176491Smarcel{ 166176491Smarcel int inf; 167176491Smarcel 168176491Smarcel /* look at rounding direction */ 169176491Smarcel switch ((fe->fe_fpscr) & FPSCR_RN) { 170176491Smarcel 171176491Smarcel default: 172176491Smarcel case FP_RN: /* the nearest value is always Inf */ 173176491Smarcel inf = 1; 174176491Smarcel break; 175176491Smarcel 176176491Smarcel case FP_RZ: /* toward 0 => never towards Inf */ 177176491Smarcel inf = 0; 178176491Smarcel break; 179176491Smarcel 180176491Smarcel case FP_RP: /* toward +Inf iff positive */ 181176491Smarcel inf = sign == 0; 182176491Smarcel break; 183176491Smarcel 184176491Smarcel case FP_RM: /* toward -Inf iff negative */ 185176491Smarcel inf = sign; 186176491Smarcel break; 187176491Smarcel } 188176491Smarcel if (inf) 189176491Smarcel fe->fe_cx |= FPSCR_OX; 190176491Smarcel return (inf); 191176491Smarcel} 192176491Smarcel 193176491Smarcel/* 194176491Smarcel * fpn -> int (int value returned as return value). 195176491Smarcel * 196176491Smarcel * N.B.: this conversion always rounds towards zero (this is a peculiarity 197176491Smarcel * of the SPARC instruction set). 198176491Smarcel */ 199176491Smarcelu_int 200176491Smarcelfpu_ftoi(struct fpemu *fe, struct fpn *fp) 201176491Smarcel{ 202176491Smarcel u_int i; 203176491Smarcel int sign, exp; 204176491Smarcel 205176491Smarcel sign = fp->fp_sign; 206176491Smarcel switch (fp->fp_class) { 207176491Smarcel 208176491Smarcel case FPC_ZERO: 209176491Smarcel return (0); 210176491Smarcel 211176491Smarcel case FPC_NUM: 212176491Smarcel /* 213176491Smarcel * If exp >= 2^32, overflow. Otherwise shift value right 214176491Smarcel * into last mantissa word (this will not exceed 0xffffffff), 215176491Smarcel * shifting any guard and round bits out into the sticky 216176491Smarcel * bit. Then ``round'' towards zero, i.e., just set an 217176491Smarcel * inexact exception if sticky is set (see round()). 218176491Smarcel * If the result is > 0x80000000, or is positive and equals 219176491Smarcel * 0x80000000, overflow; otherwise the last fraction word 220176491Smarcel * is the result. 221176491Smarcel */ 222176491Smarcel if ((exp = fp->fp_exp) >= 32) 223176491Smarcel break; 224176491Smarcel /* NB: the following includes exp < 0 cases */ 225176491Smarcel if (fpu_shr(fp, FP_NMANT - 1 - exp) != 0) 226176491Smarcel fe->fe_cx |= FPSCR_UX; 227176491Smarcel i = fp->fp_mant[3]; 228176491Smarcel if (i >= ((u_int)0x80000000 + sign)) 229176491Smarcel break; 230176491Smarcel return (sign ? -i : i); 231176491Smarcel 232176491Smarcel default: /* Inf, qNaN, sNaN */ 233176491Smarcel break; 234176491Smarcel } 235176491Smarcel /* overflow: replace any inexact exception with invalid */ 236176491Smarcel fe->fe_cx |= FPSCR_VXCVI; 237176491Smarcel return (0x7fffffff + sign); 238176491Smarcel} 239176491Smarcel 240176491Smarcel/* 241176491Smarcel * fpn -> extended int (high bits of int value returned as return value). 242176491Smarcel * 243176491Smarcel * N.B.: this conversion always rounds towards zero (this is a peculiarity 244176491Smarcel * of the SPARC instruction set). 245176491Smarcel */ 246176491Smarcelu_int 247176491Smarcelfpu_ftox(struct fpemu *fe, struct fpn *fp, u_int *res) 248176491Smarcel{ 249176491Smarcel u_int64_t i; 250176491Smarcel int sign, exp; 251176491Smarcel 252176491Smarcel sign = fp->fp_sign; 253176491Smarcel switch (fp->fp_class) { 254176491Smarcel 255176491Smarcel case FPC_ZERO: 256176491Smarcel res[1] = 0; 257176491Smarcel return (0); 258176491Smarcel 259176491Smarcel case FPC_NUM: 260176491Smarcel /* 261176491Smarcel * If exp >= 2^64, overflow. Otherwise shift value right 262176491Smarcel * into last mantissa word (this will not exceed 0xffffffffffffffff), 263176491Smarcel * shifting any guard and round bits out into the sticky 264176491Smarcel * bit. Then ``round'' towards zero, i.e., just set an 265176491Smarcel * inexact exception if sticky is set (see round()). 266176491Smarcel * If the result is > 0x8000000000000000, or is positive and equals 267176491Smarcel * 0x8000000000000000, overflow; otherwise the last fraction word 268176491Smarcel * is the result. 269176491Smarcel */ 270176491Smarcel if ((exp = fp->fp_exp) >= 64) 271176491Smarcel break; 272176491Smarcel /* NB: the following includes exp < 0 cases */ 273176491Smarcel if (fpu_shr(fp, FP_NMANT - 1 - exp) != 0) 274176491Smarcel fe->fe_cx |= FPSCR_UX; 275176491Smarcel i = ((u_int64_t)fp->fp_mant[2]<<32)|fp->fp_mant[3]; 276176491Smarcel if (i >= ((u_int64_t)0x8000000000000000LL + sign)) 277176491Smarcel break; 278176491Smarcel return (sign ? -i : i); 279176491Smarcel 280176491Smarcel default: /* Inf, qNaN, sNaN */ 281176491Smarcel break; 282176491Smarcel } 283176491Smarcel /* overflow: replace any inexact exception with invalid */ 284176491Smarcel fe->fe_cx |= FPSCR_VXCVI; 285176491Smarcel return (0x7fffffffffffffffLL + sign); 286176491Smarcel} 287176491Smarcel 288176491Smarcel/* 289176491Smarcel * fpn -> single (32 bit single returned as return value). 290176491Smarcel * We assume <= 29 bits in a single-precision fraction (1.f part). 291176491Smarcel */ 292176491Smarcelu_int 293176491Smarcelfpu_ftos(struct fpemu *fe, struct fpn *fp) 294176491Smarcel{ 295176491Smarcel u_int sign = fp->fp_sign << 31; 296176491Smarcel int exp; 297176491Smarcel 298176491Smarcel#define SNG_EXP(e) ((e) << SNG_FRACBITS) /* makes e an exponent */ 299176491Smarcel#define SNG_MASK (SNG_EXP(1) - 1) /* mask for fraction */ 300176491Smarcel 301176491Smarcel /* Take care of non-numbers first. */ 302176491Smarcel if (ISNAN(fp)) { 303176491Smarcel /* 304176491Smarcel * Preserve upper bits of NaN, per SPARC V8 appendix N. 305176491Smarcel * Note that fp->fp_mant[0] has the quiet bit set, 306176491Smarcel * even if it is classified as a signalling NaN. 307176491Smarcel */ 308176491Smarcel (void) fpu_shr(fp, FP_NMANT - 1 - SNG_FRACBITS); 309176491Smarcel exp = SNG_EXP_INFNAN; 310176491Smarcel goto done; 311176491Smarcel } 312176491Smarcel if (ISINF(fp)) 313176491Smarcel return (sign | SNG_EXP(SNG_EXP_INFNAN)); 314176491Smarcel if (ISZERO(fp)) 315176491Smarcel return (sign); 316176491Smarcel 317176491Smarcel /* 318176491Smarcel * Normals (including subnormals). Drop all the fraction bits 319176491Smarcel * (including the explicit ``implied'' 1 bit) down into the 320176491Smarcel * single-precision range. If the number is subnormal, move 321176491Smarcel * the ``implied'' 1 into the explicit range as well, and shift 322176491Smarcel * right to introduce leading zeroes. Rounding then acts 323176491Smarcel * differently for normals and subnormals: the largest subnormal 324176491Smarcel * may round to the smallest normal (1.0 x 2^minexp), or may 325176491Smarcel * remain subnormal. In the latter case, signal an underflow 326176491Smarcel * if the result was inexact or if underflow traps are enabled. 327176491Smarcel * 328176491Smarcel * Rounding a normal, on the other hand, always produces another 329176491Smarcel * normal (although either way the result might be too big for 330176491Smarcel * single precision, and cause an overflow). If rounding a 331176491Smarcel * normal produces 2.0 in the fraction, we need not adjust that 332176491Smarcel * fraction at all, since both 1.0 and 2.0 are zero under the 333176491Smarcel * fraction mask. 334176491Smarcel * 335176491Smarcel * Note that the guard and round bits vanish from the number after 336176491Smarcel * rounding. 337176491Smarcel */ 338176491Smarcel if ((exp = fp->fp_exp + SNG_EXP_BIAS) <= 0) { /* subnormal */ 339176491Smarcel /* -NG for g,r; -SNG_FRACBITS-exp for fraction */ 340176491Smarcel (void) fpu_shr(fp, FP_NMANT - FP_NG - SNG_FRACBITS - exp); 341176491Smarcel if (round(fe, fp) && fp->fp_mant[3] == SNG_EXP(1)) 342176491Smarcel return (sign | SNG_EXP(1) | 0); 343176491Smarcel if ((fe->fe_cx & FPSCR_FI) || 344176491Smarcel (fe->fe_fpscr & FPSCR_UX)) 345176491Smarcel fe->fe_cx |= FPSCR_UX; 346176491Smarcel return (sign | SNG_EXP(0) | fp->fp_mant[3]); 347176491Smarcel } 348176491Smarcel /* -FP_NG for g,r; -1 for implied 1; -SNG_FRACBITS for fraction */ 349176491Smarcel (void) fpu_shr(fp, FP_NMANT - FP_NG - 1 - SNG_FRACBITS); 350176491Smarcel#ifdef DIAGNOSTIC 351176491Smarcel if ((fp->fp_mant[3] & SNG_EXP(1 << FP_NG)) == 0) 352176491Smarcel panic("fpu_ftos"); 353176491Smarcel#endif 354176491Smarcel if (round(fe, fp) && fp->fp_mant[3] == SNG_EXP(2)) 355176491Smarcel exp++; 356176491Smarcel if (exp >= SNG_EXP_INFNAN) { 357176491Smarcel /* overflow to inf or to max single */ 358176491Smarcel if (toinf(fe, sign)) 359176491Smarcel return (sign | SNG_EXP(SNG_EXP_INFNAN)); 360176491Smarcel return (sign | SNG_EXP(SNG_EXP_INFNAN - 1) | SNG_MASK); 361176491Smarcel } 362176491Smarceldone: 363176491Smarcel /* phew, made it */ 364176491Smarcel return (sign | SNG_EXP(exp) | (fp->fp_mant[3] & SNG_MASK)); 365176491Smarcel} 366176491Smarcel 367176491Smarcel/* 368176491Smarcel * fpn -> double (32 bit high-order result returned; 32-bit low order result 369176491Smarcel * left in res[1]). Assumes <= 61 bits in double precision fraction. 370176491Smarcel * 371176491Smarcel * This code mimics fpu_ftos; see it for comments. 372176491Smarcel */ 373176491Smarcelu_int 374176491Smarcelfpu_ftod(struct fpemu *fe, struct fpn *fp, u_int *res) 375176491Smarcel{ 376176491Smarcel u_int sign = fp->fp_sign << 31; 377176491Smarcel int exp; 378176491Smarcel 379176491Smarcel#define DBL_EXP(e) ((e) << (DBL_FRACBITS & 31)) 380176491Smarcel#define DBL_MASK (DBL_EXP(1) - 1) 381176491Smarcel 382176491Smarcel if (ISNAN(fp)) { 383176491Smarcel (void) fpu_shr(fp, FP_NMANT - 1 - DBL_FRACBITS); 384176491Smarcel exp = DBL_EXP_INFNAN; 385176491Smarcel goto done; 386176491Smarcel } 387176491Smarcel if (ISINF(fp)) { 388176491Smarcel sign |= DBL_EXP(DBL_EXP_INFNAN); 389176491Smarcel goto zero; 390176491Smarcel } 391176491Smarcel if (ISZERO(fp)) { 392176491Smarcelzero: res[1] = 0; 393176491Smarcel return (sign); 394176491Smarcel } 395176491Smarcel 396176491Smarcel if ((exp = fp->fp_exp + DBL_EXP_BIAS) <= 0) { 397176491Smarcel (void) fpu_shr(fp, FP_NMANT - FP_NG - DBL_FRACBITS - exp); 398176491Smarcel if (round(fe, fp) && fp->fp_mant[2] == DBL_EXP(1)) { 399176491Smarcel res[1] = 0; 400176491Smarcel return (sign | DBL_EXP(1) | 0); 401176491Smarcel } 402176491Smarcel if ((fe->fe_cx & FPSCR_FI) || 403176491Smarcel (fe->fe_fpscr & FPSCR_UX)) 404176491Smarcel fe->fe_cx |= FPSCR_UX; 405176491Smarcel exp = 0; 406176491Smarcel goto done; 407176491Smarcel } 408176491Smarcel (void) fpu_shr(fp, FP_NMANT - FP_NG - 1 - DBL_FRACBITS); 409176491Smarcel if (round(fe, fp) && fp->fp_mant[2] == DBL_EXP(2)) 410176491Smarcel exp++; 411176491Smarcel if (exp >= DBL_EXP_INFNAN) { 412176491Smarcel fe->fe_cx |= FPSCR_OX | FPSCR_UX; 413176491Smarcel if (toinf(fe, sign)) { 414176491Smarcel res[1] = 0; 415176491Smarcel return (sign | DBL_EXP(DBL_EXP_INFNAN) | 0); 416176491Smarcel } 417176491Smarcel res[1] = ~0; 418176491Smarcel return (sign | DBL_EXP(DBL_EXP_INFNAN) | DBL_MASK); 419176491Smarcel } 420176491Smarceldone: 421176491Smarcel res[1] = fp->fp_mant[3]; 422176491Smarcel return (sign | DBL_EXP(exp) | (fp->fp_mant[2] & DBL_MASK)); 423176491Smarcel} 424176491Smarcel 425176491Smarcel/* 426176491Smarcel * Implode an fpn, writing the result into the given space. 427176491Smarcel */ 428176491Smarcelvoid 429176491Smarcelfpu_implode(struct fpemu *fe, struct fpn *fp, int type, u_int *space) 430176491Smarcel{ 431176491Smarcel 432176491Smarcel switch (type) { 433176491Smarcel 434176491Smarcel case FTYPE_LNG: 435176491Smarcel space[0] = fpu_ftox(fe, fp, space); 436176491Smarcel DPRINTF(FPE_REG, ("fpu_implode: long %x %x\n", 437176491Smarcel space[0], space[1])); 438176491Smarcel break; 439176491Smarcel 440176491Smarcel case FTYPE_INT: 441176491Smarcel space[0] = 0; 442176491Smarcel space[1] = fpu_ftoi(fe, fp); 443176491Smarcel DPRINTF(FPE_REG, ("fpu_implode: int %x\n", 444176491Smarcel space[1])); 445176491Smarcel break; 446176491Smarcel 447176491Smarcel case FTYPE_SNG: 448176491Smarcel space[0] = fpu_ftos(fe, fp); 449176491Smarcel DPRINTF(FPE_REG, ("fpu_implode: single %x\n", 450176491Smarcel space[0])); 451176491Smarcel break; 452176491Smarcel 453176491Smarcel case FTYPE_DBL: 454176491Smarcel space[0] = fpu_ftod(fe, fp, space); 455176491Smarcel DPRINTF(FPE_REG, ("fpu_implode: double %x %x\n", 456176491Smarcel space[0], space[1])); 457176491Smarcel break; break; 458176491Smarcel 459176491Smarcel default: 460176491Smarcel panic("fpu_implode: invalid type %d", type); 461176491Smarcel } 462176491Smarcel} 463