5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald/*
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * This file and its contents are supplied under the terms of the
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * Common Development and Distribution License ("CDDL"), version 1.0.
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * You may only use this file in accordance with the terms of version
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * 1.0 of the CDDL.
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald *
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * A full copy of the text of the CDDL should have accompanied this
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * source. A copy of the CDDL is also available via the Internet at
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * http://www.illumos.org/license/CDDL.
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald/*
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald .file "_base_il.s"
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald/*
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * These files are in assembly because some compilers will mistakenly reorder
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * multiplications or divisions wrapped in _putsw() and _getsw(). They are
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * proper subroutines for now, but should be considered candidates for
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * inlining eventually.
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald *
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * The original C sources are included for readability in the pre-function
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * comment blocks.
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald#include <SYS.h>
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald/*
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * Multiplies two normal or subnormal doubles, returns result and exceptions.
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald *
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonalddouble
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald__mul_set(double x, double y, int *pe) {
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald extern void _putsw(), _getsw();
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald int sw;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald double z;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald _putsw(0);
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald z = x * y;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald _getsw(&sw);
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald if ((sw & 0x3f) == 0) {
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald *pe = 0;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald } else {
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald *pe = 1;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald }
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald return (z);
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald}
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald ENTRY(__mul_set)
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald subl $0x8, %esp /* Give us an extra 8 bytes to play with. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald /* Clear the floating point exception register. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fnclex /* Equivalent of _putsw(0); */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fldl 0xc(%esp) /* Load up x */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fmull 0x14(%esp) /* And multiply! */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald /* Check to see if the multiply caused any exceptions. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fstsw (%esp) /* Equivalent of... */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald xorl %edx, %edx
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald andl $0x3f, (%esp) /* If the status word (low bits) are zero... */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald setne %dl /* ... set *pe (aka. (%eax)) accordingly. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald movl 0x1c(%esp), %eax/* Get pe. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald movl %edx, (%eax) /* And set it. (True == FP exception). */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald addl $0x8, %esp /* Release the 8 play bytes. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald ret
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald SET_SIZE(__mul_set)
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald/*
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald * Divides two normal or subnormal doubles x/y, returns result and exceptions.
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald *
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonalddouble
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald__div_set(double x, double y, int *pe) {
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald extern void _putsw(), _getsw();
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald int sw;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald double z;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald _putsw(0);
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald z = x / y;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald _getsw(&sw);
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald if ((sw & 0x3f) == 0) {
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald *pe = 0;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald } else {
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald *pe = 1;
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald }
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald return (z);
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald}
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald ENTRY(__div_set)
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald subl $0x8, %esp /* Give us an extra 8 bytes to play with. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald /* Clear the floating point exception register. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fnclex /* Equivalent of _putsw(0); */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fldl 0xc(%esp) /* Load up x */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fdivl 0x14(%esp) /* And divide! */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald /* Check to see if the divide caused any exceptions. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fstsw (%esp) /* Equivalent of... */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald xorl %edx, %edx
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald andl $0x3f, (%esp) /* If the status word (low bits) are zero... */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald setne %dl /* ... set *pe (aka. (%eax)) accordingly. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald movl 0x1c(%esp), %eax/* Get pe. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald movl %edx, (%eax) /* And set it. (True == FP exception). */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald addl $0x8, %esp /* Release the 8 play bytes. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald ret
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald SET_SIZE(__div_set)
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald/* double __dabs(double *d) - Get the abs. value of *d. Straightforward. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald ENTRY(__dabs)
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald movl 0x4(%esp), %eax
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fldl (%eax)
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald fabs /* Just let the FPU do its thing. */
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald ret
5a172a1e0f9068ec8db35fa123baecf7bd540eb5Dan McDonald SET_SIZE(__dabs)