1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 23 */ 24 /* 25 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 .file "__swapFLAGS.s" 30 31 #include "libm.h" 32 33 /* 34 * swap exception masks 35 * 36 * Put the complement of bits 5-0 of the argument into FPCW bits 5-0 37 * and MXCSR bits 12-7, return the complement of the previous FPCW 38 * bits 5-0. 39 */ 40 ENTRY(__swapTE) / di <-- NOT(desired xcptn_masks) 41 subq $8,%rsp 42 fstcw (%rsp) / push current_cw on '86 stack 43 movq (%rsp),%rcx / cx <-- current_cw 44 movw %cx,%ax / ax <-- current_cw 45 orw $0x3f,%cx / cx <-- current_cw, but masking all xcptns 46 andw $0x3f,%di / make sure bits > B5 are all zero 47 xorw %di,%cx / cx <-- present_cw, with new xcptn_masks 48 movw %cx,(%rsp) 49 fldcw (%rsp) / load new cw 50 stmxcsr (%rsp) 51 movq (%rsp),%rcx 52 orw $0x1f80,%cx / cx <-- current mxcsr, but masking all xcptns 53 shlw $7,%di 54 xorw %di,%cx / cx <-- present mxcsr, with new xcptn_masks 55 movq %rcx,(%rsp) 56 ldmxcsr (%rsp) 57 andq $0x3f,%rax / al[5..0] <-- former xcptn_masks 58 xorq $0x3f,%rax / al[5..0] <-- NOT(former xcptn_masks) 59 addq $8,%rsp 60 ret 61 .align 16 62 SET_SIZE(__swapTE) 63 64 /* 65 * swap exception flags 66 * 67 * Put bits 5-0 of the argument into FPSW bits 5-0 and MXCSR bits 5-0, 68 * return the "or" of the previous FPSW bits 5-0 and MXCSR bits 5-0. 69 */ 70 ENTRY(__swapEX) 71 fstsw %ax / ax = sw 72 andq $0x3f,%rdi 73 jnz .L1 74 / input ex=0, clear all exception 75 fnclex 76 subq $8,%rsp 77 stmxcsr (%rsp) 78 movq (%rsp),%rcx 79 orw %cx,%ax 80 andw $0xffc0,%cx 81 movq %rcx,(%rsp) 82 ldmxcsr (%rsp) 83 andq $0x3f,%rax 84 addq $8,%rsp 85 ret 86 .L1: 87 / input ex !=0, use fnstenv and fldenv 88 subq $32,%rsp / only needed 28 89 fnstenv (%rsp) 90 movw %ax,%dx 91 andw $0xffc0,%dx 92 orw %cx,%dx 93 movw %dx,4(%rsp) / replace old sw by new one 94 fldenv (%rsp) 95 stmxcsr (%rsp) 96 movq (%rsp),%rdx 97 orw %dx,%ax 98 andw $0xffc0,%dx 99 orw %cx,%dx 100 movq %rdx,(%rsp) 101 ldmxcsr (%rsp) 102 andq $0x3f,%rax 103 addq $32,%rsp 104 ret 105 .align 16 106 SET_SIZE(__swapEX) 107 108 /* 109 * swap rounding precision 110 * 111 * Put bits 1-0 of the argument into FPCW bits 9-8, return the 112 * previous FPCW bits 9-8. 113 */ 114 ENTRY(__swapRP) 115 subq $8,%rsp 116 fstcw (%rsp) 117 movw (%rsp),%ax 118 movw %ax,%cx 119 andw $0xfcff,%cx 120 andq $0x3,%rdi 121 shlw $8,%di 122 orw %di,%cx 123 movq %rcx,(%rsp) 124 fldcw (%rsp) 125 shrw $8,%ax 126 andq $0x3,%rax 127 addq $8,%rsp 128 ret 129 .align 16 130 SET_SIZE(__swapRP) 131 132 /* 133 * swap rounding direction 134 * 135 * Put bits 1-0 of the argument into FPCW bits 11-10 and MXCSR 136 * bits 14-13, return the previous FPCW bits 11-10. 137 */ 138 ENTRY(__swapRD) 139 subq $8,%rsp 140 fstcw (%rsp) 141 movw (%rsp),%ax 142 movw %ax,%cx 143 andw $0xf3ff,%cx 144 andq $0x3,%rdi 145 shlw $10,%di 146 orw %di,%cx 147 movq %rcx,(%rsp) 148 fldcw (%rsp) 149 stmxcsr (%rsp) 150 movq (%rsp),%rcx 151 andw $0x9fff,%cx 152 shlw $3,%di 153 orw %di,%cx 154 movq %rcx,(%rsp) 155 ldmxcsr (%rsp) 156 shrw $10,%ax 157 andq $0x3,%rax 158 addq $8,%rsp 159 ret 160 .align 16 161 SET_SIZE(__swapRD)