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 #include "libm_synonyms.h" 33 34 /* 35 * swap exception masks 36 * 37 * Put the complement of bits 5-0 of the argument into FPCW bits 5-0 38 * and MXCSR bits 12-7, return the complement of the previous FPCW 39 * bits 5-0. 40 */ 41 ENTRY(__swapTE) / di <-- NOT(desired xcptn_masks) 42 subq $8,%rsp 43 fstcw (%rsp) / push current_cw on '86 stack 44 movq (%rsp),%rcx / cx <-- current_cw 45 movw %cx,%ax / ax <-- current_cw 46 orw $0x3f,%cx / cx <-- current_cw, but masking all xcptns 47 andw $0x3f,%di / make sure bits > B5 are all zero 48 xorw %di,%cx / cx <-- present_cw, with new xcptn_masks 49 movw %cx,(%rsp) 50 fldcw (%rsp) / load new cw 51 stmxcsr (%rsp) 52 movq (%rsp),%rcx 53 orw $0x1f80,%cx / cx <-- current mxcsr, but masking all xcptns 54 shlw $7,%di 55 xorw %di,%cx / cx <-- present mxcsr, with new xcptn_masks 56 movq %rcx,(%rsp) 57 ldmxcsr (%rsp) 58 andq $0x3f,%rax / al[5..0] <-- former xcptn_masks 59 xorq $0x3f,%rax / al[5..0] <-- NOT(former xcptn_masks) 60 addq $8,%rsp 61 ret 62 .align 16 63 SET_SIZE(__swapTE) 64 65 /* 66 * swap exception flags 67 * 68 * Put bits 5-0 of the argument into FPSW bits 5-0 and MXCSR bits 5-0, 69 * return the "or" of the previous FPSW bits 5-0 and MXCSR bits 5-0. 70 */ 71 ENTRY(__swapEX) 72 fstsw %ax / ax = sw 73 andq $0x3f,%rdi 74 jnz .L1 75 / input ex=0, clear all exception 76 fnclex 77 subq $8,%rsp 78 stmxcsr (%rsp) 79 movq (%rsp),%rcx 80 orw %cx,%ax 81 andw $0xffc0,%cx 82 movq %rcx,(%rsp) 83 ldmxcsr (%rsp) 84 andq $0x3f,%rax 85 addq $8,%rsp 86 ret 87 .L1: 88 / input ex !=0, use fnstenv and fldenv 89 subq $32,%rsp / only needed 28 90 fnstenv (%rsp) 91 movw %ax,%dx 92 andw $0xffc0,%dx 93 orw %cx,%dx 94 movw %dx,4(%rsp) / replace old sw by new one 95 fldenv (%rsp) 96 stmxcsr (%rsp) 97 movq (%rsp),%rdx 98 orw %dx,%ax 99 andw $0xffc0,%dx 100 orw %cx,%dx 101 movq %rdx,(%rsp) 102 ldmxcsr (%rsp) 103 andq $0x3f,%rax 104 addq $32,%rsp 105 ret 106 .align 16 107 SET_SIZE(__swapEX) 108 109 /* 110 * swap rounding precision 111 * 112 * Put bits 1-0 of the argument into FPCW bits 9-8, return the 113 * previous FPCW bits 9-8. 114 */ 115 ENTRY(__swapRP) 116 subq $8,%rsp 117 fstcw (%rsp) 118 movw (%rsp),%ax 119 movw %ax,%cx 120 andw $0xfcff,%cx 121 andq $0x3,%rdi 122 shlw $8,%di 123 orw %di,%cx 124 movq %rcx,(%rsp) 125 fldcw (%rsp) 126 shrw $8,%ax 127 andq $0x3,%rax 128 addq $8,%rsp 129 ret 130 .align 16 131 SET_SIZE(__swapRP) 132 133 /* 134 * swap rounding direction 135 * 136 * Put bits 1-0 of the argument into FPCW bits 11-10 and MXCSR 137 * bits 14-13, return the previous FPCW bits 11-10. 138 */ 139 ENTRY(__swapRD) 140 subq $8,%rsp 141 fstcw (%rsp) 142 movw (%rsp),%ax 143 movw %ax,%cx 144 andw $0xf3ff,%cx 145 andq $0x3,%rdi 146 shlw $10,%di 147 orw %di,%cx 148 movq %rcx,(%rsp) 149 fldcw (%rsp) 150 stmxcsr (%rsp) 151 movq (%rsp),%rcx 152 andw $0x9fff,%cx 153 shlw $3,%di 154 orw %di,%cx 155 movq %rcx,(%rsp) 156 ldmxcsr (%rsp) 157 shrw $10,%ax 158 andq $0x3,%rax 159 addq $8,%rsp 160 ret 161 .align 16 162 SET_SIZE(__swapRD)