25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER START
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * The contents of this file are subject to the terms of the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Common Development and Distribution License (the "License").
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You may not use this file except in compliance with the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * or http://www.opensolaris.org/os/licensing.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * See the License for the specific language governing permissions
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * and limitations under the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER END
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Use is subject to license terms.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#if defined(__sparc)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <stdio.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <unistd.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <string.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <signal.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <siginfo.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <thread.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <ucontext.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <math.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#if defined(__SUNPRO_C)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <sunmath.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <fenv.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include "fenv_inlines.h"
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include "libm_inlines.h"
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#ifdef __sparcv9
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define FPreg(X) &uap->uc_mcontext.fpregs.fpu_fr.fpu_regs[X]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define FPREG(X) &uap->uc_mcontext.fpregs.fpu_fr.fpu_dregs[(X>>1)| \
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis ((X&1)<<4)]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include <sys/procfs.h>
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define FPxreg(X) &((prxregset_t*)uap->uc_mcontext.xrs.xrs_ptr)->pr_un.pr_v8p.pr_xfr.pr_regs[X]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define FPreg(X) &uap->uc_mcontext.fpregs.fpu_fr.fpu_regs[X]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#define FPREG(X) ((X & 1)? FPxreg(X - 1) : FPreg(X))
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif /* __sparcv9 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#include "fex_handler.h"
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* avoid dependence on libsunmath */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisstatic enum fp_class_type
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtismy_fp_classl(long double *a)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis{
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int msw = *(int*)a & ~0x80000000;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (msw >= 0x7fff0000) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (((msw & 0xffff) | *(1+(int*)a) | *(2+(int*)a) | *(3+(int*)a)) == 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fp_infinity;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else if (msw & 0x8000)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fp_quiet;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fp_signaling;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else if (msw < 0x10000) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((msw | *(1+(int*)a) | *(2+(int*)a) | *(3+(int*)a)) == 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fp_zero;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fp_subnormal;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis } else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fp_normal;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* Determine which type of invalid operation exception occurred
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis*/
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisenum fex_exception
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis__fex_get_invalid_type(siginfo_t *sip, ucontext_t *uap)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis{
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis unsigned instr, opf, rs1, rs2;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis enum fp_class_type t1, t2;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* parse the instruction which caused the exception */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis instr = uap->uc_mcontext.fpregs.fpu_q->FQu.fpq.fpq_instr;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis opf = (instr >> 5) & 0x1ff;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis rs1 = (instr >> 14) & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis rs2 = instr & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* determine the classes of the operands */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf & 3) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 1: /* single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t1 = fp_classf(*(float*)FPreg(rs1));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t2 = fp_classf(*(float*)FPreg(rs2));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 2: /* double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t1 = fp_class(*(double*)FPREG(rs1));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t2 = fp_class(*(double*)FPREG(rs2));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 3: /* quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t1 = my_fp_classl((long double*)FPREG(rs1));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis t2 = my_fp_classl((long double*)FPREG(rs2));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default: /* integer operands never cause an invalid operation */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (enum fex_exception) -1;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* if rs2 is snan, return immediately */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (t2 == fp_signaling)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_snan;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* determine the type of operation */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch ((instr >> 19) & 0x183f) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x1034: /* add, subtract, multiply, divide, square root, convert */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf & 0x1fc) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x40:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x44: /* add or subtract */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (t1 == fp_signaling)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_snan;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_isi;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x48:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x68:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x6c: /* multiply */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (t1 == fp_signaling)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_snan;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_zmi;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4c: /* divide */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (t1 == fp_signaling)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_snan;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else if (t1 == fp_zero)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_zdz;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_idi;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x28: /* square root */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_sqrt;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x80:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xd0: /* convert to integer */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_int;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x1035: /* compare */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (t1 == fp_signaling)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_snan;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return fex_inv_cmp;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return (enum fex_exception) -1;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#ifdef __sparcv9
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisextern void _Qp_sqrt(long double *, const long double *);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisextern long double _Q_sqrt(long double);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* Get the operands, generate the default untrapped result with
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* exceptions, and set a code indicating the type of operation
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis*/
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisvoid
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis__fex_get_op(siginfo_t *sip, ucontext_t *uap, fex_info_t *info)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis{
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis unsigned long fsr;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis unsigned instr, opf, rs1, rs2;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis volatile int c;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* parse the instruction which caused the exception */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis instr = uap->uc_mcontext.fpregs.fpu_q->FQu.fpq.fpq_instr;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis opf = (instr >> 5) & 0x1ff;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis rs1 = (instr >> 14) & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis rs2 = instr & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* get the operands */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf & 3) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0: /* integer */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.type = fex_nodata;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (opf & 0x40) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.type = fex_int;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.val.i = *(int*)FPreg(rs2);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.type = fex_llong;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.val.l = *(long long*)FPREG(rs2);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 1: /* single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.type = info->op2.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.val.f = *(float*)FPreg(rs1);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.val.f = *(float*)FPreg(rs2);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 2: /* double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.type = info->op2.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.val.d = *(double*)FPREG(rs1);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.val.d = *(double*)FPREG(rs2);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 3: /* quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.type = info->op2.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.val.q = *(long double*)FPREG(rs1);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.val.q = *(long double*)FPREG(rs2);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* initialize res to the default untrapped result and ex to the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis corresponding flags (assume trapping is disabled and flags
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis are clear) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_other;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_nodata;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch ((instr >> 19) & 0x183f) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x1035: /* compare */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_cmp;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x51: /* compare single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis c = (info->op1.val.f == info->op2.val.f);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x52: /* compare double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis c = (info->op1.val.d == info->op2.val.d);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x53: /* compare quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis c = (info->op1.val.q == info->op2.val.q);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x55: /* compare single with exception */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis c = (info->op1.val.f < info->op2.val.f);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x56: /* compare double with exception */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis c = (info->op1.val.d < info->op2.val.d);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x57: /* compare quad with exception */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis c = (info->op1.val.q < info->op2.val.q);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x1034: /* add, subtract, multiply, divide, square root, convert */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x41: /* add single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_add;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = info->op1.val.f + info->op2.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x42: /* add double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_add;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = info->op1.val.d + info->op2.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x43: /* add quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_add;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = info->op1.val.q + info->op2.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x45: /* subtract single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_sub;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = info->op1.val.f - info->op2.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x46: /* subtract double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_sub;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = info->op1.val.d - info->op2.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x47: /* subtract quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_sub;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = info->op1.val.q - info->op2.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x49: /* multiply single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_mul;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = info->op1.val.f * info->op2.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4a: /* multiply double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_mul;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = info->op1.val.d * info->op2.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4b: /* multiply quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_mul;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = info->op1.val.q * info->op2.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x69: /* fsmuld */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_mul;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double)info->op1.val.f * (double)info->op2.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x6e: /* fdmulq */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_mul;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double)info->op1.val.d *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (long double)info->op2.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4d: /* divide single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_div;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = info->op1.val.f / info->op2.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4e: /* divide double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_div;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = info->op1.val.d / info->op2.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4f: /* divide quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_div;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = info->op1.val.q / info->op2.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x29: /* square root single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_sqrt;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1 = info->op2;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.type = fex_nodata;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = sqrtf(info->op1.val.f);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x2a: /* square root double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_sqrt;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1 = info->op2;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.type = fex_nodata;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = sqrt(info->op1.val.d);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x2b: /* square root quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_sqrt;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1 = info->op2;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.type = fex_nodata;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#ifdef __sparcv9
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis _Qp_sqrt(&info->res.val.q, &info->op1.val.q);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = _Q_sqrt(info->op1.val.q);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default: /* conversions */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op = fex_cnvt;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1 = info->op2;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.type = fex_nodata;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xd1: /* convert single to int */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_int;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.i = (int) info->op1.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xd2: /* convert double to int */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_int;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.i = (int) info->op1.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xd3: /* convert quad to int */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_int;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.i = (int) info->op1.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x81: /* convert single to long long */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_llong;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.l = (long long) info->op1.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x82: /* convert double to long long */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_llong;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.l = (long long) info->op1.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x83: /* convert quad to long long */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_llong;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.l = (long long) info->op1.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xc4: /* convert int to single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->op1.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x84: /* convert long long to single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->op1.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x88: /* convert long long to double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->op1.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xc6: /* convert double to single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->op1.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xc7: /* convert quad to single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->op1.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xc9: /* convert single to double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->op1.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xcb: /* convert quad to double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->op1.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xcd: /* convert single to quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->op1.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xce: /* convert double to quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->op1.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis __fenv_getfsr(&fsr);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->flags = (int)__fenv_get_ex(fsr);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis __fenv_set_ex(fsr, 0);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis __fenv_setfsr(&fsr);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/*
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* Store the specified result; if no result is given but the exception
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* is underflow or overflow, supply the default trapped result
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis*/
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisvoid
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis__fex_st_result(siginfo_t *sip, ucontext_t *uap, fex_info_t *info)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis{
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis unsigned instr, opf, rs1, rs2, rd;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis long double qscl;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis double dscl;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis float fscl;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* parse the instruction which caused the exception */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis instr = uap->uc_mcontext.fpregs.fpu_q->FQu.fpq.fpq_instr;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis opf = (instr >> 5) & 0x1ff;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis rs1 = (instr >> 14) & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis rs2 = instr & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis rd = (instr >> 25) & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* if the instruction is a compare, just set fcc to unordered */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (((instr >> 19) & 0x183f) == 0x1035) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (rd == 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fpu_fsr |= 0xc00;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis else {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#ifdef __sparcv9
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fpu_fsr |= (3l << ((rd << 1) + 30));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#else
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis ((prxregset_t*)uap->uc_mcontext.xrs.xrs_ptr)->pr_un.pr_v8p.pr_xfsr |= (3 << ((rd - 1) << 1));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* if there is no result available, try to generate the untrapped
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (info->res.type == fex_nodata) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* set scale factors for exponent wrapping */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (sip->si_code) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case FPE_FLTOVF:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fscl = 1.262177448e-29f; /* 2^-96 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dscl = 6.441148769597133308e-232; /* 2^-768 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis qscl = 8.778357852076208839765066529179033145e-3700l;/* 2^-12288 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case FPE_FLTUND:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fscl = 7.922816251e+28f; /* 2^96 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dscl = 1.552518092300708935e+231; /* 2^768 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis qscl = 1.139165225263043370845938579315932009e+3699l;/* 2^12288 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* user may have blown away the default result by mistake,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis so try to regenerate it */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (void) __fex_get_op(sip, uap, info);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (info->res.type != fex_nodata)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis goto stuff;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* couldn't do it */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* get the operands */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf & 3) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 1: /* single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.val.f = *(float*)FPreg(rs1);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.val.f = *(float*)FPreg(rs2);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 2: /* double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.val.d = *(double*)FPREG(rs1);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.val.d = *(double*)FPREG(rs2);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 3: /* quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op1.val.q = *(long double*)FPREG(rs1);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->op2.val.q = *(long double*)FPREG(rs2);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* generate the wrapped result */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x41: /* add single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = fscl * (fscl * info->op1.val.f +
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fscl * info->op2.val.f);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x42: /* add double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = dscl * (dscl * info->op1.val.d +
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dscl * info->op2.val.d);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x43: /* add quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = qscl * (qscl * info->op1.val.q +
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis qscl * info->op2.val.q);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x45: /* subtract single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = fscl * (fscl * info->op1.val.f -
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fscl * info->op2.val.f);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x46: /* subtract double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = dscl * (dscl * info->op1.val.d -
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis dscl * info->op2.val.d);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x47: /* subtract quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = qscl * (qscl * info->op1.val.q -
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis qscl * info->op2.val.q);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x49: /* multiply single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (fscl * info->op1.val.f) *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (fscl * info->op2.val.f);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4a: /* multiply double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (dscl * info->op1.val.d) *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (dscl * info->op2.val.d);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4b: /* multiply quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (qscl * info->op1.val.q) *
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (qscl * info->op2.val.q);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4d: /* divide single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (fscl * info->op1.val.f) /
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (info->op2.val.f / fscl);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4e: /* divide double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (dscl * info->op1.val.d) /
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (info->op2.val.d / dscl);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4f: /* divide quad */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_ldouble;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (qscl * info->op1.val.q) /
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis (info->op2.val.q / qscl);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xc6: /* convert double to single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) (fscl * (fscl * info->op1.val.d));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xc7: /* convert quad to single */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_float;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) (fscl * (fscl * info->op1.val.q));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xcb: /* convert quad to double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.type = fex_double;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) (dscl * (dscl * info->op1.val.q));
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (info->res.type == fex_nodata)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* couldn't do it */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisstuff:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* stick the result in the destination */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (opf & 0x80) { /* conversion */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (opf & 0x10) { /* result is an int */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_llong:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.i = (int) info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_float:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.i = (int) info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_double:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.i = (int) info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_ldouble:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.i = (int) info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(int*)FPreg(rd) = info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf & 0xc) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0: /* result is long long */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_int:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.l = (long long) info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_float:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.l = (long long) info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_double:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.l = (long long) info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_ldouble:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.l = (long long) info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(long long*)FPREG(rd) = info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x4: /* result is float */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_int:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_llong:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_double:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_ldouble:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(float*)FPreg(rd) = info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x8: /* result is double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_int:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_llong:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_float:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_ldouble:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(double*)FPREG(rd) = info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xc: /* result is long double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_int:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_llong:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_float:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_double:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(long double*)FPREG(rd) = info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((opf & 0xf0) == 0x60) { /* fsmuld, fdmulq */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf & 0xc0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0x8: /* result is double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_int:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_llong:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_float:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_ldouble:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(double*)FPREG(rd) = info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 0xc: /* result is long double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_int:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_llong:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_float:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_double:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(long double*)FPREG(rd) = info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis return;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (opf & 3) { /* other arithmetic op */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 1: /* result is float */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_int:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_llong:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_double:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_ldouble:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.f = (float) info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(float*)FPreg(rd) = info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 2: /* result is double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_int:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_llong:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_float:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_ldouble:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.d = (double) info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(double*)FPREG(rd) = info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case 3: /* result is long double */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis switch (info->res.type) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_int:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_llong:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.l;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_float:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case fex_double:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info->res.val.q = (long double) info->res.val.d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis default:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis *(long double*)FPREG(rd) = info->res.val.q;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis break;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis }
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis}
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#endif /* defined(__sparc) */