17c478bd9Sstevel@tonic-gate/* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate/* 238238724eSmike_s * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 273e76f9d6SRichard Lowe#include <sys/asm_linkage.h> 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate .file "fsr.s" 305e0a5eb7SRichard Lowe .ident "" 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate .section .data 338238724eSmike_s .align 4 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate/* 367c478bd9Sstevel@tonic-gate * The following table maps trap enable bits in __fsr_init_value 377c478bd9Sstevel@tonic-gate * (after shifting right one bit): 387c478bd9Sstevel@tonic-gate * 397c478bd9Sstevel@tonic-gate * bit 0 - inexact trap 407c478bd9Sstevel@tonic-gate * bit 1 - division trap 417c478bd9Sstevel@tonic-gate * bit 2 - underflow trap 427c478bd9Sstevel@tonic-gate * bit 3 - overflow trap 437c478bd9Sstevel@tonic-gate * bit 4 - invalid trap 447c478bd9Sstevel@tonic-gate * 457c478bd9Sstevel@tonic-gate * to exception masks in the floating point control word 467c478bd9Sstevel@tonic-gate * 477c478bd9Sstevel@tonic-gate * bit 0 - invalid mask 487c478bd9Sstevel@tonic-gate * bit 2 - zero divide mask 497c478bd9Sstevel@tonic-gate * bit 3 - overflow mask 507c478bd9Sstevel@tonic-gate * bit 4 - underflow mask 517c478bd9Sstevel@tonic-gate * bit 5 - inexact mask 527c478bd9Sstevel@tonic-gate */ 537c478bd9Sstevel@tonic-gate .local trap_table 547c478bd9Sstevel@tonic-gate .type trap_table,@object 557c478bd9Sstevel@tonic-gatetrap_table: 567c478bd9Sstevel@tonic-gate .byte 0b11111111 577c478bd9Sstevel@tonic-gate .byte 0b11011111 587c478bd9Sstevel@tonic-gate .byte 0b11111011 597c478bd9Sstevel@tonic-gate .byte 0b11011011 607c478bd9Sstevel@tonic-gate .byte 0b11101111 617c478bd9Sstevel@tonic-gate .byte 0b11001111 627c478bd9Sstevel@tonic-gate .byte 0b11101011 637c478bd9Sstevel@tonic-gate .byte 0b11001011 647c478bd9Sstevel@tonic-gate .byte 0b11110111 657c478bd9Sstevel@tonic-gate .byte 0b11010111 667c478bd9Sstevel@tonic-gate .byte 0b11110011 677c478bd9Sstevel@tonic-gate .byte 0b11010011 687c478bd9Sstevel@tonic-gate .byte 0b11100111 697c478bd9Sstevel@tonic-gate .byte 0b11000111 707c478bd9Sstevel@tonic-gate .byte 0b11100011 717c478bd9Sstevel@tonic-gate .byte 0b11000011 727c478bd9Sstevel@tonic-gate .byte 0b11111110 737c478bd9Sstevel@tonic-gate .byte 0b11011110 747c478bd9Sstevel@tonic-gate .byte 0b11111010 757c478bd9Sstevel@tonic-gate .byte 0b11011010 767c478bd9Sstevel@tonic-gate .byte 0b11101110 777c478bd9Sstevel@tonic-gate .byte 0b11001110 787c478bd9Sstevel@tonic-gate .byte 0b11101010 797c478bd9Sstevel@tonic-gate .byte 0b11001010 807c478bd9Sstevel@tonic-gate .byte 0b11110110 817c478bd9Sstevel@tonic-gate .byte 0b11010110 827c478bd9Sstevel@tonic-gate .byte 0b11110010 837c478bd9Sstevel@tonic-gate .byte 0b11010010 847c478bd9Sstevel@tonic-gate .byte 0b11100110 857c478bd9Sstevel@tonic-gate .byte 0b11000110 867c478bd9Sstevel@tonic-gate .byte 0b11100010 877c478bd9Sstevel@tonic-gate .byte 0b11000010 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate .size trap_table,32 907c478bd9Sstevel@tonic-gate 913e76f9d6SRichard LoweENTRY_NP(__fsr) 927c478bd9Sstevel@tonic-gate pushl %ebp 937c478bd9Sstevel@tonic-gate movl %esp,%ebp 947c478bd9Sstevel@tonic-gate pushl %edx 957c478bd9Sstevel@tonic-gate pushl %ecx 963e76f9d6SRichard Lowe pushl %ebx 977c478bd9Sstevel@tonic-gate subl $4,%esp 987c478bd9Sstevel@tonic-gate 993e76f9d6SRichard Lowe /* Setup PIC */ 1003e76f9d6SRichard Lowe call 9f 1013e76f9d6SRichard Lowe9: popl %ebx 1023e76f9d6SRichard Lowe addl $_GLOBAL_OFFSET_TABLE_ + [. - 9b], %ebx 1033e76f9d6SRichard Lowe 1043e76f9d6SRichard Lowe movl 8(%ebp), %ecx /* the value set by CG is passed in */ 1057c478bd9Sstevel@tonic-gate shrl $1,%ecx /* get rid of fns bit */ 1067c478bd9Sstevel@tonic-gate cmpl $0,%ecx /* if remaining bits are zero */ 1077c478bd9Sstevel@tonic-gate je 3f /* there's nothing to do */ 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate fstcw 0(%esp) /* store the control word */ 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate movl %ecx,%edx 1127c478bd9Sstevel@tonic-gate andl $0x1f,%edx /* get the trap enable bits */ 1133e76f9d6SRichard Lowe movl trap_table@GOT(%ebx), %eax 1143e76f9d6SRichard Lowe addl %eax,%edx 1153e76f9d6SRichard Lowe movb (%edx),%al 1167c478bd9Sstevel@tonic-gate andb %al,0(%esp) /* unmask the corresponding exceptions */ 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate testl $0x200,%ecx /* test denormal trap enable */ 1197c478bd9Sstevel@tonic-gate jz 1f /* skip if zero */ 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate andb $0xfd,0(%esp) /* unmask denormal exception */ 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate1: 1247c478bd9Sstevel@tonic-gate movl %ecx,%edx 1257c478bd9Sstevel@tonic-gate andl $0x60,%edx /* get the rounding direction */ 1267c478bd9Sstevel@tonic-gate jz 1f /* skip if zero */ 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate movl %edx,%eax /* exchange negative<->tozero */ 1297c478bd9Sstevel@tonic-gate andl $0x20,%eax /* leaving nearest and positive */ 1307c478bd9Sstevel@tonic-gate shll $1,%eax /* as is */ 1317c478bd9Sstevel@tonic-gate xorl %eax,%edx 1327c478bd9Sstevel@tonic-gate shll $5,%edx 1337c478bd9Sstevel@tonic-gate andw $0xf3ff,0(%esp) /* update rounding direction */ 1347c478bd9Sstevel@tonic-gate orw %dx,0(%esp) 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate1: 1377c478bd9Sstevel@tonic-gate andl $0x180,%ecx /* get the rounding precision */ 1387c478bd9Sstevel@tonic-gate jz 1f /* skip if zero */ 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate xorl $0x180,%ecx /* reverse bits */ 1417c478bd9Sstevel@tonic-gate shll $1,%ecx 1427c478bd9Sstevel@tonic-gate andw $0xfcff,0(%esp) /* update rounding precision */ 1437c478bd9Sstevel@tonic-gate orw %cx,0(%esp) 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate1: 1467c478bd9Sstevel@tonic-gate fldcw 0(%esp) /* load the modified control word */ 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate3: 1497c478bd9Sstevel@tonic-gate addl $4,%esp 1503e76f9d6SRichard Lowe popl %ebx 1517c478bd9Sstevel@tonic-gate popl %ecx 1527c478bd9Sstevel@tonic-gate popl %edx 1537c478bd9Sstevel@tonic-gate popl %ebp 1547c478bd9Sstevel@tonic-gate ret 1553e76f9d6SRichard LoweSET_SIZE(__fsr) 156