1 /////////////////////////////////////////////////////////////////////////
2 // $Id: xmm.h,v 1.27 2008/04/06 13:56:22 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2003 Stanislav Shwartsman
6 // Written by Stanislav Shwartsman [sshwarts at sourceforge net]
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /////////////////////////////////////////////////////////////////////////
24 #ifndef BX_SSE_EXTENSIONS_H
25 #define BX_SSE_EXTENSIONS_H
29 typedef union bx_xmm_reg_t
{
38 } BxPackedXmmRegister
;
41 #define xmm64s(i) _s64[1 - (i)]
42 #define xmm32s(i) _s32[3 - (i)]
43 #define xmm16s(i) _s16[7 - (i)]
44 #define xmmsbyte(i) _sbyte[15 - (i)]
45 #define xmmubyte(i) _ubyte[15 - (i)]
46 #define xmm16u(i) _u16[7 - (i)]
47 #define xmm32u(i) _u32[3 - (i)]
48 #define xmm64u(i) _u64[1 - (i)]
50 #define xmm64s(i) _s64[(i)]
51 #define xmm32s(i) _s32[(i)]
52 #define xmm16s(i) _s16[(i)]
53 #define xmmsbyte(i) _sbyte[(i)]
54 #define xmmubyte(i) _ubyte[(i)]
55 #define xmm16u(i) _u16[(i)]
56 #define xmm32u(i) _u32[(i)]
57 #define xmm64u(i) _u64[(i)]
60 #if BX_SUPPORT_SSE >= 1
63 # define BX_XMM_REGISTERS 16
65 # define BX_XMM_REGISTERS 8
68 /* read XMM register */
69 #define BX_READ_XMM_REG(index) (BX_CPU_THIS_PTR xmm[index])
71 /* read only high 64 bit of the register */
72 #define BX_READ_XMM_REG_HI_QWORD(index) \
73 ((BX_CPU_THIS_PTR xmm[index]).xmm64u(1))
75 /* read only low 64 bit of the register */
76 #define BX_READ_XMM_REG_LO_QWORD(index) \
77 ((BX_CPU_THIS_PTR xmm[index]).xmm64u(0))
79 /* read only low 32 bit of the register */
80 #define BX_READ_XMM_REG_LO_DWORD(index) \
81 ((BX_CPU_THIS_PTR xmm[index]).xmm32u(0))
83 /* read only low 16 bit of the register */
84 #define BX_READ_XMM_REG_LO_WORD(index) \
85 ((BX_CPU_THIS_PTR xmm[index]).xmm16u(0))
87 /* short names for above macroses */
88 #define BX_XMM_REG_HI_QWORD BX_READ_XMM_REG_HI_QWORD
89 #define BX_XMM_REG_LO_QWORD BX_READ_XMM_REG_LO_QWORD
90 #define BX_XMM_REG_LO_DWORD BX_READ_XMM_REG_LO_DWORD
92 /* store XMM register */
93 #define BX_WRITE_XMM_REG(index, reg) \
94 { BX_CPU_THIS_PTR xmm[index] = (reg); }
96 /* store only high 64 bit of the register, rest of the register unchanged */
97 #define BX_WRITE_XMM_REG_HI_QWORD(index, reg64) \
98 { (BX_CPU_THIS_PTR xmm[index]).xmm64u(1) = (reg64); }
100 /* store only low 64 bit of the register, rest of the register unchanged */
101 #define BX_WRITE_XMM_REG_LO_QWORD(index, reg64) \
102 { (BX_CPU_THIS_PTR xmm[index]).xmm64u(0) = (reg64); }
104 /* store only low 32 bit of the register, rest of the register unchanged */
105 #define BX_WRITE_XMM_REG_LO_DWORD(index, reg32) \
106 { (BX_CPU_THIS_PTR xmm[index]).xmm32u(0) = (reg32); }
111 /* 31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16
112 * ==|==|=====|==|==|==|==|==|==|==|==|==|==|==|== (reserved)
113 * 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|MM| 0
115 * 15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0
116 * ==|==|=====|==|==|==|==|==|==|==|==|==|==|==|==
117 * FZ| R C |PM|UM|OM|ZM|DM|IM|DZ|PE|UE|OE|ZE|DE|IE
120 /* MXCSR REGISTER FIELDS DESCRIPTION */
123 * IE 0 Invalid-Operation Exception 0
124 * DE 1 Denormalized-Operand Exception 0
125 * ZE 2 Zero-Divide Exception 0
126 * OE 3 Overflow Exception 0
127 * UE 4 Underflow Exception 0
128 * PE 5 Precision Exception 0
129 * DZ 6 Denormals are Zeros 0
130 * IM 7 Invalid-Operation Exception Mask 1
131 * DM 8 Denormalized-Operand Exception Mask 1
132 * ZM 9 Zero-Divide Exception Mask 1
133 * OM 10 Overflow Exception Mask 1
134 * UM 11 Underflow Exception Mask 1
135 * PM 12 Precision Exception Mask 1
136 * RC 13-14 Floating-Point Rounding Control 00
137 * FZ 15 Flush-to-Zero for Masked Underflow 0
139 * MM 17 Misaligned Exceptuion Mask 0
142 #define MXCSR_EXCEPTIONS 0x0000003F
143 #define MXCSR_DAZ 0x00000040
144 #define MXCSR_MASKED_EXCEPTIONS 0x00001F80
145 #define MXCSR_ROUNDING_CONTROL 0x00006000
146 #define MXCSR_FLUSH_MASKED_UNDERFLOW 0x00008000
147 #define MXCSR_MISALIGNED_EXCEPTION_MASK 0x00020000
149 #define MXCSR_IE 0x00000001
150 #define MXCSR_DE 0x00000002
151 #define MXCSR_ZE 0x00000004
152 #define MXCSR_OE 0x00000008
153 #define MXCSR_UE 0x00000010
154 #define MXCSR_PE 0x00000020
156 #define MXCSR_IM 0x00000080
157 #define MXCSR_DM 0x00000100
158 #define MXCSR_ZM 0x00000200
159 #define MXCSR_OM 0x00000400
160 #define MXCSR_UM 0x00000800
161 #define MXCSR_PM 0x00001000
163 #define MXCSR_RESET 0x00001F80 /* reset value of the MXCSR register */
165 struct BOCHSAPI bx_mxcsr_t
169 bx_mxcsr_t (Bit32u val
= MXCSR_RESET
)
172 #define IMPLEMENT_MXCSR_ACCESSOR(name, bitmask, bitnum) \
173 int get_##name () const { \
174 return (mxcsr & (bitmask)) >> (bitnum); \
177 IMPLEMENT_MXCSR_ACCESSOR(exceptions_masks
, MXCSR_MASKED_EXCEPTIONS
, 7);
178 IMPLEMENT_MXCSR_ACCESSOR(DAZ
, MXCSR_DAZ
, 6);
179 IMPLEMENT_MXCSR_ACCESSOR(rounding_mode
, MXCSR_ROUNDING_CONTROL
, 13);
180 IMPLEMENT_MXCSR_ACCESSOR(flush_masked_underflow
, MXCSR_FLUSH_MASKED_UNDERFLOW
, 15);
181 IMPLEMENT_MXCSR_ACCESSOR(misaligned_exception_mask
, MXCSR_MISALIGNED_EXCEPTION_MASK
, 17);
183 IMPLEMENT_MXCSR_ACCESSOR(IE
, MXCSR_IE
, 0);
184 IMPLEMENT_MXCSR_ACCESSOR(DE
, MXCSR_DE
, 1);
185 IMPLEMENT_MXCSR_ACCESSOR(ZE
, MXCSR_ZE
, 2);
186 IMPLEMENT_MXCSR_ACCESSOR(OE
, MXCSR_OE
, 3);
187 IMPLEMENT_MXCSR_ACCESSOR(UE
, MXCSR_UE
, 4);
188 IMPLEMENT_MXCSR_ACCESSOR(PE
, MXCSR_PE
, 5);
190 IMPLEMENT_MXCSR_ACCESSOR(IM
, MXCSR_IM
, 7);
191 IMPLEMENT_MXCSR_ACCESSOR(DM
, MXCSR_DM
, 8);
192 IMPLEMENT_MXCSR_ACCESSOR(ZM
, MXCSR_ZM
, 9);
193 IMPLEMENT_MXCSR_ACCESSOR(OM
, MXCSR_OM
, 10);
194 IMPLEMENT_MXCSR_ACCESSOR(UM
, MXCSR_UM
, 11);
195 IMPLEMENT_MXCSR_ACCESSOR(PM
, MXCSR_PM
, 12);
197 void set_exceptions(int status
) {
198 mxcsr
|= (status
& MXCSR_EXCEPTIONS
);
203 /* reset reserved bits */
204 #define MXCSR_MASK (0x0000FFBF | \
205 (BX_SUPPORT_DAZ ? MXCSR_DAZ : 0) | \
206 (BX_SUPPORT_MISALIGNED_SSE ? MXCSR_MISALIGNED_EXCEPTION_MASK : 0))
208 #if defined(NEED_CPU_REG_SHORTCUTS)
209 #define MXCSR (BX_CPU_THIS_PTR mxcsr)
210 #define BX_MXCSR_REGISTER (BX_CPU_THIS_PTR mxcsr.mxcsr)
213 #endif // BX_SUPPORT_SSE
215 /* INTEGER SATURATION */
218 * SaturateWordSToByteS converts a signed 16-bit value to a signed
219 * 8-bit value. If the signed 16-bit value is less than -128, it is
220 * represented by the saturated value -128 (0x80). If it is greater
221 * than 127, it is represented by the saturated value 127 (0x7F).
223 BX_CPP_INLINE Bit8s
BX_CPP_AttrRegparmN(1) SaturateWordSToByteS(Bit16s value
)
225 if(value
< -128) return -128;
226 if(value
> 127) return 127;
227 return (Bit8s
) value
;
231 * SaturateDwordSToWordS converts a signed 32-bit value to a signed
232 * 16-bit value. If the signed 32-bit value is less than -32768, it is
233 * represented by the saturated value -32768 (0x8000). If it is greater
234 * than 32767, it is represented by the saturated value 32767 (0x7FFF).
236 BX_CPP_INLINE Bit16s
BX_CPP_AttrRegparmN(1) SaturateDwordSToWordS(Bit32s value
)
238 if(value
< -32768) return -32768;
239 if(value
> 32767) return 32767;
240 return (Bit16s
) value
;
244 * SaturateWordSToByteU converts a signed 16-bit value to an unsigned
245 * 8-bit value. If the signed 16-bit value is less than zero it is
246 * represented by the saturated value zero (0x00).If it is greater than
247 * 255 it is represented by the saturated value 255 (0xFF).
249 BX_CPP_INLINE Bit8u
BX_CPP_AttrRegparmN(1) SaturateWordSToByteU(Bit16s value
)
251 if(value
< 0) return 0;
252 if(value
> 255) return 255;
253 return (Bit8u
) value
;
257 * SaturateDwordSToWordU converts a signed 32-bit value to an unsigned
258 * 16-bit value. If the signed 32-bit value is less than zero, it is
259 * represented by the saturated value zero (0x0000). If it is greater
260 * than 65535, it is represented by the saturated value 65535 (0xFFFF).
262 BX_CPP_INLINE Bit16u
BX_CPP_AttrRegparmN(1) SaturateDwordSToWordU(Bit32s value
)
264 if(value
< 0) return 0;
265 if(value
> 65535) return 65535;
266 return (Bit16u
) value
;