1207151Smarius/*- 2207151Smarius * Copyright (c) 2010 by Peter Jeremy <peterjeremy@acm.org> 3207151Smarius * All rights reserved. 4207151Smarius * 5207151Smarius * Redistribution and use in source and binary forms, with or without 6207151Smarius * modification, are permitted provided that the following conditions 7207151Smarius * are met: 8207151Smarius * 1. Redistributions of source code must retain the above copyright 9207151Smarius * notice, this list of conditions and the following disclaimer. 10207151Smarius * 2. Redistributions in binary form must reproduce the above copyright 11207151Smarius * notice, this list of conditions and the following disclaimer in the 12207151Smarius * documentation and/or other materials provided with the distribution. 13207151Smarius * 14207151Smarius * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15207151Smarius * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16207151Smarius * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17207151Smarius * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18207151Smarius * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19207151Smarius * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20207151Smarius * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21207151Smarius * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22207151Smarius * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 23207151Smarius * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24207151Smarius */ 25207151Smarius 26207151Smarius#include <sys/cdefs.h> 27207151Smarius__FBSDID("$FreeBSD$"); 28207151Smarius 29207151Smarius#include <sys/param.h> 30207151Smarius 31207151Smarius#include <math.h> 32207151Smarius#include <stdio.h> 33207151Smarius#include <stdlib.h> 34207151Smarius 35207151Smarius#include "__sparc_utrap_private.h" 36207151Smarius#include "fpu_extern.h" 37207151Smarius#include "fpu_reg.h" 38207151Smarius 39207151Smariusstatic u_long ireg[32]; 40207151Smarius 41207151Smariusvoid 42207151Smarius__utrap_panic(const char *msg) 43207151Smarius{ 44207151Smarius 45207151Smarius fprintf(stderr, "panic: %s\n", msg); 46207151Smarius exit(1); 47207151Smarius} 48207151Smarius 49207151Smariusvoid __utrap_write(const char *msg) 50207151Smarius{ 51207151Smarius 52207151Smarius fprintf(stderr, "%s", msg); 53207151Smarius} 54207151Smarius 55207151Smariusu_long 56207151Smarius__emul_fetch_reg(struct utrapframe *uf, int reg) 57207151Smarius{ 58207151Smarius 59207151Smarius return (ireg[reg]); 60207151Smarius} 61207151Smarius 62207151Smariustypedef unsigned char int8; 63207151Smariustypedef unsigned int int32; 64207151Smariustypedef unsigned long int64; 65207151Smariustypedef unsigned int float32; 66207151Smariustypedef unsigned long float64; 67207151Smariustypedef struct { 68207151Smarius unsigned long high, low; 69207151Smarius} float128; 70207151Smariustypedef unsigned long flag; 71207151Smarius 72207151Smariusstruct utrapframe utf; 73207151Smarius 74207151Smariusu_int32_t __fpreg[64]; 75207151Smarius 76207151Smariusstatic __inline float128 77207151Smarius__fpu_getreg128(int r) 78207151Smarius{ 79207151Smarius float128 v; 80207151Smarius 81207151Smarius v.high = ((u_int64_t)__fpreg[r] << 32 | (u_int64_t)__fpreg[r + 1]); 82207151Smarius v.low = ((u_int64_t)__fpreg[r + 2] << 32 | (u_int64_t)__fpreg[r + 3]); 83207151Smarius return (v); 84207151Smarius} 85207151Smarius 86207151Smariusstatic __inline void 87207151Smarius__fpu_setreg128(int r, float128 v) 88207151Smarius{ 89207151Smarius 90207151Smarius __fpreg[r] = (u_int32_t)(v.high >> 32); 91207151Smarius __fpreg[r + 1] = (u_int32_t)v.high; 92207151Smarius __fpreg[r + 2] = (u_int32_t)(v.low >> 32); 93207151Smarius __fpreg[r + 3] = (u_int32_t)v.low; 94207151Smarius} 95207151Smarius 96207151Smarius/* 97207151Smarius------------------------------------------------------------------------------- 98207151SmariusClears the system's IEC/IEEE floating-point exception flags. Returns the 99207151Smariusprevious value of the flags. 100207151Smarius------------------------------------------------------------------------------- 101207151Smarius*/ 102207151Smarius#include <fenv.h> 103207151Smarius#include <ieeefp.h> 104207151Smarius 105207151Smariusint8 syst_float_flags_clear(void) 106207151Smarius{ 107207151Smarius int32 flags; 108207151Smarius 109207151Smarius flags = (utf.uf_fsr & FE_ALL_EXCEPT) >> 5; 110207151Smarius utf.uf_fsr &= ~(u_long)FE_ALL_EXCEPT; 111207151Smarius return (flags); 112207151Smarius} 113207151Smarius 114207151Smariusstatic void 115207151Smariusemul_trap(const u_int *insn, u_long mask) 116207151Smarius{ 117207151Smarius u_int32_t savreg[64]; 118207151Smarius int i; 119207151Smarius 120207151Smarius for (i = 0; i < 64; i++) 121207151Smarius savreg[i] = __fpreg[i]; 122207151Smarius 123207151Smarius utf.uf_fsr = (utf.uf_fsr & ~FSR_FTT_MASK) | 124207151Smarius (FSR_FTT_UNFIN << FSR_FTT_SHIFT); 125207151Smarius utf.uf_pc = (u_long)insn; 126207151Smarius if (__fpu_exception(&utf) == 0) 127207151Smarius __asm("stx %%fsr,%0" : "=m" (utf.uf_fsr)); 128207151Smarius 129207151Smarius for (i = 0; i < 64; i++) { 130207151Smarius if (!(mask & (1UL << i)) && savreg[i] != __fpreg[i]) { 131207151Smarius fprintf(stderr, "### %2d %08x != %08x\n", 132207151Smarius i, savreg[i], __fpreg[i]); 133207151Smarius } 134207151Smarius } 135207151Smarius} 136207151Smarius 137207151Smariusextern u_int insn_int32_to_float32; 138207151Smariusextern u_int insn_int32_to_float64; 139207151Smariusextern u_int insn_int32_to_float128; 140207151Smariusextern u_int insn_int64_to_float32; 141207151Smariusextern u_int insn_int64_to_float64; 142207151Smariusextern u_int insn_int64_to_float128; 143207151Smariusextern u_int insn_float32_to_int32_round_to_zero; 144207151Smariusextern u_int insn_float32_to_int64_round_to_zero; 145207151Smariusextern u_int insn_float32_to_float64; 146207151Smariusextern u_int insn_float32_to_float128; 147207151Smariusextern u_int insn_float32_add; 148207151Smariusextern u_int insn_float32_sub; 149207151Smariusextern u_int insn_float32_mul; 150207151Smariusextern u_int insn_float32_div; 151207151Smariusextern u_int insn_float32_sqrt; 152207151Smariusextern u_int insn_float32_cmp; 153207151Smariusextern u_int insn_float32_cmpe; 154207151Smariusextern u_int insn_float64_to_int32_round_to_zero; 155207151Smariusextern u_int insn_float64_to_int64_round_to_zero; 156207151Smariusextern u_int insn_float64_to_float32; 157207151Smariusextern u_int insn_float64_to_float128; 158207151Smariusextern u_int insn_float64_add; 159207151Smariusextern u_int insn_float64_sub; 160207151Smariusextern u_int insn_float64_mul; 161207151Smariusextern u_int insn_float64_div; 162207151Smariusextern u_int insn_float64_sqrt; 163207151Smariusextern u_int insn_float64_cmp; 164207151Smariusextern u_int insn_float64_cmpe; 165207151Smariusextern u_int insn_float128_to_int32_round_to_zero; 166207151Smariusextern u_int insn_float128_to_int64_round_to_zero; 167207151Smariusextern u_int insn_float128_to_float32; 168207151Smariusextern u_int insn_float128_to_float64; 169207151Smariusextern u_int insn_float128_add; 170207151Smariusextern u_int insn_float128_sub; 171207151Smariusextern u_int insn_float128_mul; 172207151Smariusextern u_int insn_float128_div; 173207151Smariusextern u_int insn_float128_sqrt; 174207151Smariusextern u_int insn_float128_cmp; 175207151Smariusextern u_int insn_float128_cmpe; 176207151Smarius 177207151Smariusfloat32 178207151Smariussyst_int32_to_float32(int32 a) 179207151Smarius{ 180207151Smarius 181207151Smarius __fpu_setreg(0, a); 182207151Smarius emul_trap(&insn_int32_to_float32, 0x1UL); 183207151Smarius return (__fpu_getreg(0)); 184207151Smarius} 185207151Smarius 186207151Smariusfloat64 187207151Smariussyst_int32_to_float64(int32 a) 188207151Smarius{ 189207151Smarius 190207151Smarius __fpu_setreg(0, a); 191207151Smarius emul_trap(&insn_int32_to_float64, 0x3UL); 192207151Smarius return (__fpu_getreg64(0)); 193207151Smarius} 194207151Smarius 195207151Smariusfloat128 196207151Smariussyst_int32_to_float128(int32 a) 197207151Smarius{ 198207151Smarius 199207151Smarius __fpu_setreg(0, a); 200207151Smarius emul_trap(&insn_int32_to_float128, 0xfUL); 201207151Smarius return (__fpu_getreg128(0)); 202207151Smarius} 203207151Smarius 204207151Smariusfloat32 205207151Smariussyst_int64_to_float32(int64 a) 206207151Smarius{ 207207151Smarius 208207151Smarius __fpu_setreg64(0, a); 209207151Smarius emul_trap(&insn_int64_to_float32, 0x1UL); 210207151Smarius return (__fpu_getreg(0)); 211207151Smarius} 212207151Smarius 213207151Smariusfloat64 214207151Smariussyst_int64_to_float64(int64 a) 215207151Smarius{ 216207151Smarius 217207151Smarius __fpu_setreg64(0, a); 218207151Smarius emul_trap(&insn_int64_to_float64, 0x3UL); 219207151Smarius return (__fpu_getreg64(0)); 220207151Smarius} 221207151Smarius 222207151Smarius 223207151Smariusfloat128 224207151Smariussyst_int64_to_float128(int64 a) 225207151Smarius{ 226207151Smarius 227207151Smarius __fpu_setreg64(0, a); 228207151Smarius emul_trap(&insn_int64_to_float128, 0xfUL); 229207151Smarius return (__fpu_getreg128(0)); 230207151Smarius} 231207151Smarius 232207151Smariusint32 233207151Smariussyst_float32_to_int32_round_to_zero(float32 a) 234207151Smarius{ 235207151Smarius 236207151Smarius __fpu_setreg(0, a); 237207151Smarius emul_trap(&insn_float32_to_int32_round_to_zero, 0x1UL); 238207151Smarius return (__fpu_getreg(0)); 239207151Smarius} 240207151Smarius 241207151Smariusint64 242207151Smariussyst_float32_to_int64_round_to_zero(float32 a) 243207151Smarius{ 244207151Smarius 245207151Smarius __fpu_setreg(0, a); 246207151Smarius emul_trap(&insn_float32_to_int64_round_to_zero, 0x3UL); 247207151Smarius return (__fpu_getreg64(0)); 248207151Smarius} 249207151Smarius 250207151Smariusfloat64 251207151Smariussyst_float32_to_float64(float32 a) 252207151Smarius{ 253207151Smarius 254207151Smarius __fpu_setreg(0, a); 255207151Smarius emul_trap(&insn_float32_to_float64, 0x3UL); 256207151Smarius return (__fpu_getreg64(0)); 257207151Smarius} 258207151Smarius 259207151Smariusfloat128 260207151Smariussyst_float32_to_float128(float32 a) 261207151Smarius{ 262207151Smarius 263207151Smarius __fpu_setreg(0, a); 264207151Smarius emul_trap(&insn_float32_to_float128, 0xfUL); 265207151Smarius return (__fpu_getreg128(0)); 266207151Smarius} 267207151Smarius 268207151Smariusfloat32 269207151Smariussyst_float32_add(float32 a, float32 b) 270207151Smarius{ 271207151Smarius 272207151Smarius __fpu_setreg(0, a); 273207151Smarius __fpu_setreg(1, b); 274207151Smarius emul_trap(&insn_float32_add, 0x1UL); 275207151Smarius return (__fpu_getreg(0)); 276207151Smarius} 277207151Smarius 278207151Smariusfloat32 279207151Smariussyst_float32_sub(float32 a, float32 b) 280207151Smarius{ 281207151Smarius 282207151Smarius __fpu_setreg(0, a); 283207151Smarius __fpu_setreg(1, b); 284207151Smarius emul_trap(&insn_float32_sub, 0x1UL); 285207151Smarius return (__fpu_getreg(0)); 286207151Smarius} 287207151Smarius 288207151Smariusfloat32 289207151Smariussyst_float32_mul(float32 a, float32 b) 290207151Smarius{ 291207151Smarius 292207151Smarius __fpu_setreg(0, a); 293207151Smarius __fpu_setreg(1, b); 294207151Smarius emul_trap(&insn_float32_mul, 0x1UL); 295207151Smarius return (__fpu_getreg(0)); 296207151Smarius} 297207151Smarius 298207151Smariusfloat32 299207151Smariussyst_float32_div(float32 a, float32 b) 300207151Smarius{ 301207151Smarius 302207151Smarius __fpu_setreg(0, a); 303207151Smarius __fpu_setreg(1, b); 304207151Smarius emul_trap(&insn_float32_div, 0x1UL); 305207151Smarius return (__fpu_getreg(0)); 306207151Smarius} 307207151Smarius 308207151Smariusfloat32 309207151Smariussyst_float32_sqrt(float32 a) 310207151Smarius{ 311207151Smarius 312207151Smarius __fpu_setreg(0, a); 313207151Smarius emul_trap(&insn_float32_sqrt, 0x1UL); 314207151Smarius return (__fpu_getreg(0)); 315207151Smarius} 316207151Smarius 317207151Smariusflag syst_float32_eq(float32 a, float32 b) 318207151Smarius{ 319207151Smarius u_long r; 320207151Smarius 321207151Smarius __fpu_setreg(0, a); 322207151Smarius __fpu_setreg(1, b); 323207151Smarius emul_trap(&insn_float32_cmp, 0x0UL); 324207151Smarius __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r)); 325207151Smarius return (r); 326207151Smarius} 327207151Smarius 328207151Smariusflag syst_float32_le(float32 a, float32 b) 329207151Smarius{ 330207151Smarius u_long r; 331207151Smarius 332207151Smarius __fpu_setreg(0, a); 333207151Smarius __fpu_setreg(1, b); 334207151Smarius emul_trap(&insn_float32_cmpe, 0x0UL); 335207151Smarius __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r)); 336207151Smarius return (r); 337207151Smarius} 338207151Smarius 339207151Smariusflag syst_float32_lt(float32 a, float32 b) 340207151Smarius{ 341207151Smarius u_long r; 342207151Smarius 343207151Smarius __fpu_setreg(0, a); 344207151Smarius __fpu_setreg(1, b); 345207151Smarius emul_trap(&insn_float32_cmpe, 0x0UL); 346207151Smarius __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r)); 347207151Smarius return (r); 348207151Smarius} 349207151Smarius 350207151Smariusflag syst_float32_eq_signaling(float32 a, float32 b) 351207151Smarius{ 352207151Smarius u_long r; 353207151Smarius 354207151Smarius __fpu_setreg(0, a); 355207151Smarius __fpu_setreg(1, b); 356207151Smarius emul_trap(&insn_float32_cmpe, 0x0UL); 357207151Smarius __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r)); 358207151Smarius return (r); 359207151Smarius} 360207151Smarius 361207151Smariusflag syst_float32_le_quiet(float32 a, float32 b) 362207151Smarius{ 363207151Smarius u_long r; 364207151Smarius 365207151Smarius __fpu_setreg(0, a); 366207151Smarius __fpu_setreg(1, b); 367207151Smarius emul_trap(&insn_float32_cmp, 0x0UL); 368207151Smarius __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r)); 369207151Smarius return (r); 370207151Smarius} 371207151Smarius 372207151Smariusflag syst_float32_lt_quiet(float32 a, float32 b) 373207151Smarius{ 374207151Smarius u_long r; 375207151Smarius 376207151Smarius __fpu_setreg(0, a); 377207151Smarius __fpu_setreg(1, b); 378207151Smarius emul_trap(&insn_float32_cmp, 0x0UL); 379207151Smarius __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r)); 380207151Smarius return (r); 381207151Smarius} 382207151Smarius 383207151Smariusint32 384207151Smariussyst_float64_to_int32_round_to_zero(float64 a) 385207151Smarius{ 386207151Smarius 387207151Smarius __fpu_setreg64(0, a); 388207151Smarius emul_trap(&insn_float64_to_int32_round_to_zero, 0x1UL); 389207151Smarius return (__fpu_getreg(0)); 390207151Smarius} 391207151Smarius 392207151Smariusint64 393207151Smariussyst_float64_to_int64_round_to_zero(float64 a) 394207151Smarius{ 395207151Smarius 396207151Smarius __fpu_setreg64(0, a); 397207151Smarius emul_trap(&insn_float64_to_int64_round_to_zero, 0x3UL); 398207151Smarius return (__fpu_getreg64(0)); 399207151Smarius} 400207151Smarius 401207151Smariusfloat32 402207151Smariussyst_float64_to_float32(float64 a) 403207151Smarius{ 404207151Smarius 405207151Smarius __fpu_setreg64(0, a); 406207151Smarius emul_trap(&insn_float64_to_float32, 0x1UL); 407207151Smarius return (__fpu_getreg(0)); 408207151Smarius} 409207151Smarius 410207151Smariusfloat128 411207151Smariussyst_float64_to_float128(float64 a) 412207151Smarius{ 413207151Smarius 414207151Smarius __fpu_setreg64(0, a); 415207151Smarius emul_trap(&insn_float64_to_float128, 0xfUL); 416207151Smarius return (__fpu_getreg128(0)); 417207151Smarius} 418207151Smarius 419207151Smariusfloat64 420207151Smariussyst_float64_add(float64 a, float64 b) 421207151Smarius{ 422207151Smarius 423207151Smarius __fpu_setreg64(0, a); 424207151Smarius __fpu_setreg64(2, b); 425207151Smarius emul_trap(&insn_float64_add, 0x3UL); 426207151Smarius return (__fpu_getreg64(0)); 427207151Smarius} 428207151Smarius 429207151Smariusfloat64 430207151Smariussyst_float64_sub(float64 a, float64 b) 431207151Smarius{ 432207151Smarius 433207151Smarius __fpu_setreg64(0, a); 434207151Smarius __fpu_setreg64(2, b); 435207151Smarius emul_trap(&insn_float64_sub, 0x3UL); 436207151Smarius return (__fpu_getreg64(0)); 437207151Smarius} 438207151Smarius 439207151Smariusfloat64 440207151Smariussyst_float64_mul(float64 a, float64 b) 441207151Smarius{ 442207151Smarius 443207151Smarius __fpu_setreg64(0, a); 444207151Smarius __fpu_setreg64(2, b); 445207151Smarius emul_trap(&insn_float64_mul, 0x3UL); 446207151Smarius return (__fpu_getreg64(0)); 447207151Smarius} 448207151Smarius 449207151Smariusfloat64 450207151Smariussyst_float64_div(float64 a, float64 b) 451207151Smarius{ 452207151Smarius 453207151Smarius __fpu_setreg64(0, a); 454207151Smarius __fpu_setreg64(2, b); 455207151Smarius emul_trap(&insn_float64_div, 0x3UL); 456207151Smarius return (__fpu_getreg64(0)); 457207151Smarius} 458207151Smarius 459207151Smariusfloat64 460207151Smariussyst_float64_sqrt(float64 a) 461207151Smarius{ 462207151Smarius 463207151Smarius __fpu_setreg64(0, a); 464207151Smarius emul_trap(&insn_float64_sqrt, 0x3UL); 465207151Smarius return (__fpu_getreg64(0)); 466207151Smarius} 467207151Smarius 468207151Smariusflag syst_float64_eq(float64 a, float64 b) 469207151Smarius{ 470207151Smarius u_long r; 471207151Smarius 472207151Smarius __fpu_setreg64(0, a); 473207151Smarius __fpu_setreg64(2, b); 474207151Smarius emul_trap(&insn_float64_cmp, 0x0UL); 475207151Smarius __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r)); 476207151Smarius return (r); 477207151Smarius} 478207151Smarius 479207151Smariusflag syst_float64_le(float64 a, float64 b) 480207151Smarius{ 481207151Smarius u_long r; 482207151Smarius 483207151Smarius __fpu_setreg64(0, a); 484207151Smarius __fpu_setreg64(2, b); 485207151Smarius emul_trap(&insn_float64_cmpe, 0x0UL); 486207151Smarius __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r)); 487207151Smarius return (r); 488207151Smarius} 489207151Smarius 490207151Smariusflag syst_float64_lt(float64 a, float64 b) 491207151Smarius{ 492207151Smarius u_long r; 493207151Smarius 494207151Smarius __fpu_setreg64(0, a); 495207151Smarius __fpu_setreg64(2, b); 496207151Smarius emul_trap(&insn_float64_cmpe, 0x0UL); 497207151Smarius __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r)); 498207151Smarius return (r); 499207151Smarius} 500207151Smarius 501207151Smariusflag syst_float64_eq_signaling(float64 a, float64 b) 502207151Smarius{ 503207151Smarius u_long r; 504207151Smarius 505207151Smarius __fpu_setreg64(0, a); 506207151Smarius __fpu_setreg64(2, b); 507207151Smarius emul_trap(&insn_float64_cmpe, 0x0UL); 508207151Smarius __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r)); 509207151Smarius return (r); 510207151Smarius} 511207151Smarius 512207151Smariusflag syst_float64_le_quiet(float64 a, float64 b) 513207151Smarius{ 514207151Smarius u_long r; 515207151Smarius 516207151Smarius __fpu_setreg64(0, a); 517207151Smarius __fpu_setreg64(2, b); 518207151Smarius emul_trap(&insn_float64_cmp, 0x0UL); 519207151Smarius __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r)); 520207151Smarius return (r); 521207151Smarius} 522207151Smarius 523207151Smariusflag syst_float64_lt_quiet(float64 a, float64 b) 524207151Smarius{ 525207151Smarius u_long r; 526207151Smarius 527207151Smarius __fpu_setreg64(0, a); 528207151Smarius __fpu_setreg64(2, b); 529207151Smarius emul_trap(&insn_float64_cmp, 0x0UL); 530207151Smarius __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r)); 531207151Smarius return (r); 532207151Smarius} 533207151Smarius 534207151Smariusint32 535207151Smariussyst_float128_to_int32_round_to_zero(float128 a) 536207151Smarius{ 537207151Smarius 538207151Smarius __fpu_setreg128(0, a); 539207151Smarius emul_trap(&insn_float128_to_int32_round_to_zero, 0x1UL); 540207151Smarius return (__fpu_getreg(0)); 541207151Smarius} 542207151Smarius 543207151Smariusint64 544207151Smariussyst_float128_to_int64_round_to_zero(float128 a) 545207151Smarius{ 546207151Smarius 547207151Smarius __fpu_setreg128(0, a); 548207151Smarius emul_trap(&insn_float128_to_int64_round_to_zero, 0x3UL); 549207151Smarius return (__fpu_getreg64(0)); 550207151Smarius} 551207151Smarius 552207151Smariusfloat32 553207151Smariussyst_float128_to_float32(float128 a) 554207151Smarius{ 555207151Smarius 556207151Smarius __fpu_setreg128(0, a); 557207151Smarius emul_trap(&insn_float128_to_float32, 0x1UL); 558207151Smarius return (__fpu_getreg(0)); 559207151Smarius} 560207151Smarius 561207151Smariusfloat64 562207151Smariussyst_float128_to_float64(float128 a) 563207151Smarius{ 564207151Smarius 565207151Smarius __fpu_setreg128(0, a); 566207151Smarius emul_trap(&insn_float128_to_float64, 0x3UL); 567207151Smarius return (__fpu_getreg64(0)); 568207151Smarius} 569207151Smarius 570207151Smariusfloat128 571207151Smariussyst_float128_add(float128 a, float128 b) 572207151Smarius{ 573207151Smarius 574207151Smarius __fpu_setreg128(0, a); 575207151Smarius __fpu_setreg128(4, b); 576207151Smarius emul_trap(&insn_float128_add, 0xfUL); 577207151Smarius return (__fpu_getreg128(0)); 578207151Smarius} 579207151Smarius 580207151Smariusfloat128 581207151Smariussyst_float128_sub(float128 a, float128 b) 582207151Smarius{ 583207151Smarius 584207151Smarius __fpu_setreg128(0, a); 585207151Smarius __fpu_setreg128(4, b); 586207151Smarius emul_trap(&insn_float128_sub, 0xfUL); 587207151Smarius return (__fpu_getreg128(0)); 588207151Smarius} 589207151Smarius 590207151Smariusfloat128 591207151Smariussyst_float128_mul(float128 a, float128 b) 592207151Smarius{ 593207151Smarius 594207151Smarius __fpu_setreg128(0, a); 595207151Smarius __fpu_setreg128(4, b); 596207151Smarius emul_trap(&insn_float128_mul, 0xfUL); 597207151Smarius return (__fpu_getreg128(0)); 598207151Smarius} 599207151Smarius 600207151Smariusfloat128 601207151Smariussyst_float128_div(float128 a, float128 b) 602207151Smarius{ 603207151Smarius 604207151Smarius __fpu_setreg128(0, a); 605207151Smarius __fpu_setreg128(4, b); 606207151Smarius emul_trap(&insn_float128_div, 0xfUL); 607207151Smarius return (__fpu_getreg128(0)); 608207151Smarius} 609207151Smarius 610207151Smariusfloat128 611207151Smariussyst_float128_sqrt(float128 a) 612207151Smarius{ 613207151Smarius 614207151Smarius __fpu_setreg128(0, a); 615207151Smarius emul_trap(&insn_float128_sqrt, 0xfUL); 616207151Smarius return (__fpu_getreg128(0)); 617207151Smarius} 618207151Smarius 619207151Smariusflag syst_float128_eq(float128 a, float128 b) 620207151Smarius{ 621207151Smarius u_long r; 622207151Smarius 623207151Smarius __fpu_setreg128(0, a); 624207151Smarius __fpu_setreg128(4, b); 625207151Smarius emul_trap(&insn_float128_cmp, 0x0UL); 626207151Smarius __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r)); 627207151Smarius return (r); 628207151Smarius} 629207151Smarius 630207151Smariusflag syst_float128_le(float128 a, float128 b) 631207151Smarius{ 632207151Smarius u_long r; 633207151Smarius 634207151Smarius __fpu_setreg128(0, a); 635207151Smarius __fpu_setreg128(4, b); 636207151Smarius emul_trap(&insn_float128_cmpe, 0x0UL); 637207151Smarius __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r)); 638207151Smarius return (r); 639207151Smarius} 640207151Smarius 641207151Smariusflag syst_float128_lt(float128 a, float128 b) 642207151Smarius{ 643207151Smarius u_long r; 644207151Smarius 645207151Smarius __fpu_setreg128(0, a); 646207151Smarius __fpu_setreg128(4, b); 647207151Smarius emul_trap(&insn_float128_cmpe, 0x0UL); 648207151Smarius __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r)); 649207151Smarius return (r); 650207151Smarius} 651207151Smarius 652207151Smariusflag syst_float128_eq_signaling(float128 a, float128 b) 653207151Smarius{ 654207151Smarius u_long r; 655207151Smarius 656207151Smarius __fpu_setreg128(0, a); 657207151Smarius __fpu_setreg128(4, b); 658207151Smarius emul_trap(&insn_float128_cmpe, 0x0UL); 659207151Smarius __asm __volatile("mov 0,%0; move %%fcc0,1,%0" : "=r" (r)); 660207151Smarius return (r); 661207151Smarius} 662207151Smarius 663207151Smariusflag syst_float128_le_quiet(float128 a, float128 b) 664207151Smarius{ 665207151Smarius u_long r; 666207151Smarius 667207151Smarius __fpu_setreg128(0, a); 668207151Smarius __fpu_setreg128(4, b); 669207151Smarius emul_trap(&insn_float128_cmp, 0x0UL); 670207151Smarius __asm __volatile("mov 0,%0; movle %%fcc0,1,%0" : "=r" (r)); 671207151Smarius return (r); 672207151Smarius} 673207151Smarius 674207151Smariusflag syst_float128_lt_quiet(float128 a, float128 b) 675207151Smarius{ 676207151Smarius u_long r; 677207151Smarius 678207151Smarius __fpu_setreg128(0, a); 679207151Smarius __fpu_setreg128(4, b); 680207151Smarius emul_trap(&insn_float128_cmp, 0x0UL); 681207151Smarius __asm __volatile("mov 0,%0; movl %%fcc0,1,%0" : "=r" (r)); 682207151Smarius return (r); 683207151Smarius} 684207151Smarius 685207151Smarius 686207151Smarius/* 687207151Smarius------------------------------------------------------------------------------- 688207151SmariusSets the system's IEC/IEEE floating-point rounding mode. 689207151Smarius------------------------------------------------------------------------------- 690207151Smarius*/ 691207151Smariusvoid syst_float_set_rounding_mode(int8 roundingMode) 692207151Smarius{ 693207151Smarius 694207151Smarius utf.uf_fsr &= ~FSR_RD_MASK; 695207151Smarius utf.uf_fsr |= FSR_RD((unsigned int)roundingMode & 0x03); 696207151Smarius} 697207151Smarius 698207151Smarius/* 699207151Smarius------------------------------------------------------------------------------- 700207151SmariusDoes nothing. 701207151Smarius------------------------------------------------------------------------------- 702207151Smarius*/ 703207151Smariusvoid syst_float_set_rounding_precision(int8 precision) 704207151Smarius{ 705207151Smarius 706207151Smarius} 707