1 /// -*- mode: asm; asm-comment-char: ?/ -*-
3 /// CPU dispatch support for x86
5 /// (c) 2019 Straylight/Edgeware
8 ///----- Licensing notice ---------------------------------------------------
10 /// This file is part of Catacomb.
12 /// Catacomb is free software: you can redistribute it and/or modify it
13 /// under the terms of the GNU Library General Public License as published
14 /// by the Free Software Foundation; either version 2 of the License, or
15 /// (at your option) any later version.
17 /// Catacomb is distributed in the hope that it will be useful, but
18 /// WITHOUT ANY WARRANTY; without even the implied warranty of
19 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 /// Library General Public License for more details.
22 /// You should have received a copy of the GNU Library General Public
23 /// License along with Catacomb. If not, write to the Free Software
24 /// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 ///--------------------------------------------------------------------------
31 #include "asm-common.h"
37 ///--------------------------------------------------------------------------
38 /// Probing for CPUID.
40 FUNC(dispatch_x86ish_cpuid)
41 // Enter with a pointer to 16 bytes of storage for the output A, B,
42 // C, D values in the first argument, and input A and C values in the
43 // second and third. Fill the output buffer with `cpuid' results and
44 // return zero if we can; otherwise fill with zero and return -1.
54 #if CPUFAM_AMD64 && ABI_SYSV
60 #if CPUFAM_AMD64 && ABI_WIN
69 // First, check that this is even a thing, using the complicated
70 // dance with the flags register.
72 pop DX // current flags in d
74 or DX, EFLAGS_ID // force the id bit on and check it
82 and DX, ~EFLAGS_ID // force the id bit off and check it
90 // OK, that seemed to work.
120 ///--------------------------------------------------------------------------
121 /// Probing for XMM register availability.
123 FUNC(dispatch_x86ish_xmmregisters_p)
124 // Enter with no arguments. Return nonzero if the XMM registers are
133 // Save the floating point and SIMD registers, and try to clobber
138 xor dword ptr [DX], 0xaaaa5555
141 // Save them again, and read back the low word of xmm0. Undo the
142 // clobbering and restore.
148 // The register are live if we read different things.
157 ///--------------------------------------------------------------------------
158 /// Checking `rdrand'.
160 FUNC(dispatch_x86ish_rdrand)
161 // Enter with two arguments: a code OP requesting either `rdrand' (0)
162 // or `rdseed' (1), and a pointer X_OUT to a 32-bit word. Try to
163 // generate a random word using the requested instruction'. If
164 // successful, set *X_OUT to the generated word, and return zero;
165 // otherwise, return -1.
174 #if CPUFAM_AMD64 && ABI_SYSV
179 #if CPUFAM_AMD64 && ABI_WIN
187 mov COUNT, 16 // fairly persistent
202 // Failed to come up with a random value.
216 ///----- That's all, folks --------------------------------------------------