AMD64 Floating point calculation.

Helloguys,

I am working on AMD 64Bits machine and has an Xp32 working driver. Problem
that I face now is that the floating point. In XP32( x86, 32 bits machine)
it was working fine with

KFLOATING_SAVE floatsave;
status = KeSaveFloatingPointState(&floatsave);

KeRestoreFloatingPointState(&floatsave);

But, How can I make a same function in AMD 64 bits machine?

Thank you

You make the same call. WDM.h has a definition (which is FORCEINLINE)
for KeSaveFloatingPointState() for AMD64

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of YoungShin Yoon
Sent: Wednesday, September 27, 2006 7:16 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] AMD64 Floating point calculation.

Helloguys,

I am working on AMD 64Bits machine and has an Xp32 working driver.
Problem
that I face now is that the floating point. In XP32( x86, 32 bits
machine)
it was working fine with

KFLOATING_SAVE floatsave;
status = KeSaveFloatingPointState(&floatsave);

KeRestoreFloatingPointState(&floatsave);

But, How can I make a same function in AMD 64 bits machine?

Thank you


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Thank you for your quick response.
Somehow I used to do some sine/cosine/exp with <math.h> between those Floating fuctions(). But in AMD64, I can’t use it anymore. it brought me some LINK errors. Do I need to some more work to use these functions in Kernel?

Thank you.</math.h>

on your 32 bit driver, where are you getting this functions from? run link /dump /imports .sys and then see where you are resolving the import. on my 32 bit kernel, exp and cosine are not exported from ntoskrnl.exe

C:\Windows\System32>link /dump /exports ntoskrnl.exe | findstr /i cosine

C:\Windows\System32>link /dump /exports ntoskrnl.exe | findstr /i cosin
[nothing]

C:\Windows\System32>link /dump /exports ntoskrnl.exe | findstr /i exp
Section contains the following exports for ntoskrnl.exe
343 128 001880F6 FsRtlIsDbcsInExpression
348 12D 001D5BE5 FsRtlIsNameInExpression
349 12E 0001B645 FsRtlIsNtstatusExpected
709 2AB 000C7D73 KeExpandKernelStackAndCallout
710 2AC 000C7D9A KeExpandKernelStackAndCalloutEx
837 33C 0003F736 KiUnexpectedInterrupt
1558 614 0031A284 SeExports

Thank you so much Doron,

As your advice, I tried your way to check up the export function. In XP32 bits, I can see
C:\WINDOWS\system32>link /dump /exports C:\windows\system32\ntoskrnl.exe | finds
tr /i exp
Section contains the following exports for ntoskrnl.exe
231 C8 00145223 FsRtlIsDbcsInExpression
234 CB 000A8B97 FsRtlIsNameInExpression
235 CC 00033E1A FsRtlIsNtstatusExpected
639 276 00004AE4 KiUnexpectedInterrupt
1226 4C8 001C1D50 SeExports

C:\WINDOWS\system32>link /dump /exports C:\windows\system32\ntoskrnl.exe | finds
tr /i sin
213 B6 0003EDE6 FsRtlFastUnlockSingle
231 C8 00145223 FsRtlIsDbcsInExpression
263 E8 000220B1 FsRtlNumberOfRunsInLargeMcb
264 E9 000595C7 FsRtlNumberOfRunsInMcb
467 1BF 000DD8C8 IoSynchronousInvalidateDeviceRelations
486 1D2 000DC54A IoWMIQuerySingleInstance
487 1D3 0016E1AA IoWMIQuerySingleInstanceMultiple
490 1D6 0016E22D IoWMISetSingleInstance
491 1D7 0016E307 IoWMISetSingleItem
632 26A 000053F0 KeWaitForSingleObject
793 311 00096265 NtWaitForSingleObject
870 360 00029F26 PsGetProcessInheritedFromUniqueProcessId
889 373 00091654 PsInitialSystemProcess
1139 46E 0002B66A RtlSecondsSince1970ToTime
1140 46F 0006D94C RtlSecondsSince1980ToTime
1161 484 0006D98B RtlTimeToSecondsSince1970
1162 485 0006D901 RtlTimeToSecondsSince1980
1248 4DE 000A1FCC SeSinglePrivilegeCheck
1316 523 0000C9CA ZwIsProcessInJob
1391 56E 0000D79E ZwWaitForSingleObject
1395 572 0000E7FC _CIsin

C:\WINDOWS\system32>link /dump /exports C:\windows\system32\ntoskrnl.exe | finds
tr /i cos
1394 571 0000E743 _CIcos

and can’t find in XP 64(AMD64) machine.

What does it mean and how can I solve this? Do I need to implement or find out the expoted function from Kernel DLLs?

Thank you.

I was not saying that you should check the imports for ntoskrnl.exe on your machine. instead you should check the *imports* for your 32 bit driver which uses these functions and see how you are getting them in the first place in a 32 bit compile. for instance,

link /dump /imports .sys

and then find out where sin/cosin/exp are coming from. With that information, it might be clear how to get them for a 64 bit compile.

d

Thank you Doron Again.

I did as you told me and found that there isn’t any imported sin/cos/sqrt function in an old driver. Also, these are from the standard library from <math.h>. We have used these functions from <math.h> and no problem in XP32 but has some problem in calling these functions. We are doing some floating point processing in the audio driver. I can’t understand why it happened.

Thank you.</math.h></math.h>

I’m slightly confused. You’re talking about trying to use traditional FPP floating point? In 64-bit mode on an x64 processor from kernel mode?

If so, unless something really dramatic has changed that I don’t know about, that’s never been supported. Just one of those changes that’s been making people who write drivers that do signal processing type stuff (soft modems, for example) pull out their hair when porting to x64. Check into the SSE/SSE2 instruction set.

Peter
OSR

Thank you Doron and Peter.

I think I wasn’t ready to ask what to ask first so others also confused by my confusion. Sorry for that.

I had a working XP 32bit audio filter driver and have another request from our customer to supprt XP 64 bits(AMD64). So I started to work with this XP 32 driver with some modification to make it work in 64 bits. What this driver is doing is that getting in/out stream of audio and processing data such for Noise Reduction or Echo cancellation, which requires the math functions for instance Sin/Cos/Sqrt/ … .

As Doron replied, KeSaveFloatingPointState() and KeRestoreFloatingPointState() is working fine in AMD64, but when I added some mathmatic functions such as Sin() and cos() between two functions and it wans’t work as I expeced. Why is that? and How can I use these functions for processing such real time functions?

I have verified with Doron’s help that these are included in the library “msvcrt.lib”, but in the XP32bit model, we didn’t include this library and I thought it should be the default option by the operating system.

Is there anyone who faced this problem and solved it?

Thank you.

xxxxx@hotmail.com wrote:

As Doron replied, KeSaveFloatingPointState() and KeRestoreFloatingPointState() is working fine in AMD64, but when I added some mathmatic functions such as Sin() and cos() between two functions and it wans’t work as I expeced. Why is that? and How can I use these functions for processing such real time functions?

I have verified with Doron’s help that these are included in the library “msvcrt.lib”, but in the XP32bit model, we didn’t include this library and I thought it should be the default option by the operating system.

msvcrt.lib is a USER-MODE library. The kernel-mode equivalent is
libcntpr.lib, and if I dump the strings from the amd64 version of
libcntpr.lib, I certainly see all of the trigonometric functions in there.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Well, I don’t have answer to how to use sin() and cos() directly in
AMD64 kernel mode. However, if you want to compute the value of sin/cos,
you could use approximations. For instance, you could use Maclaurin
variant of Taylor Series:

sin(x) = x-(x^3)/3!+(x^5)/5!-(x^7)/7!+(x^9)/9!-…
cos(x) = 1-(x^2)/2!+(x^4)/4!-(x^6)/6!+(x^8)/8!-…

If you want to generate sin signal, you can implement a second order
Infinite Impulse Response (IIR) filter, and turn it into an oscillator
by properly select the poles and zeros in the Z-plane so that it
oscillates at the frequency you choose. It works great.

Calvin Guan
Sr. Staff Engineer (DDK MVP)
NetXtreme Vista/LH Server Miniport
Broadcom Corporation @ Irvine CA
Connecting Everything(r)

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:bounce-264508-
xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Monday, October 02, 2006 8:57 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] AMD64 Floating point calculation.

Thank you Doron and Peter.

I think I wasn’t ready to ask what to ask first so others also
confused by
my confusion. Sorry for that.

I had a working XP 32bit audio filter driver and have another request
from
our customer to supprt XP 64 bits(AMD64). So I started to work with
this
XP 32 driver with some modification to make it work in 64 bits. What
this
driver is doing is that getting in/out stream of audio and processing
data
such for Noise Reduction or Echo cancellation, which requires the math
functions for instance Sin/Cos/Sqrt/ … .

As Doron replied, KeSaveFloatingPointState() and
KeRestoreFloatingPointState() is working fine in AMD64, but when I
added
some mathmatic functions such as Sin() and cos() between two functions
and
it wans’t work as I expeced. Why is that? and How can I use these
functions for processing such real time functions?

I have verified with Doron’s help that these are included in the
library
“msvcrt.lib”, but in the XP32bit model, we didn’t include this library
and
I thought it should be the default option by the operating system.

Is there anyone who faced this problem and solved it?

Thank you.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

>people who write drivers that do signal processing type stuff (soft modems,
for

example)

The most popular Conexant soft modem is a user-mode service, and the modem
driver just proxies all calls to it. It supports a range of hardware (embedded
to laptops usually), and the hardware is similar to AC97 wave sound - it
listens the phone line and then the user-mode service decodes the modem data
from this wave.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Thank you for all guys especailly Tim. I tried our driver with your opinion and it works fine. It was the library problem. Thank you Doron, Peter, and Calvin. I really appreciate your help and deep knowledge.

Thank you.

You can call KeSaveFloatingPointState… But I’d very strongly recommend that you walk into that function just once in the debugger before you write a driver that relies on this.

Note that in nice, limited, testing on your test box it can LOOK like it works… but Win-64 on the X64 doesn’t save x87/FPP floating point registers.

Standard x87 FPP (NOT SSE/SSE2/SSE3) operations ARE NOT SUPPORTED in kernel mode on Windows 64 on X64. I can tell you from experience that this has cause folks a lot of pain.

Peter
OSR

xxxxx@osr.com wrote:

Note that in nice, limited, testing on your test box it can LOOK like it works… but Win-64 on the X64 doesn’t save x87/FPP floating point registers.

That was the original stated design, but that was changed in
development. The operating system as implemented DOES save and restore
them for a 32-bit task.

Standard x87 FPP (NOT SSE/SSE2/SSE3) operations ARE NOT SUPPORTED in kernel mode on Windows 64 on X64. I can tell you from experience that this has cause folks a lot of pain.

Forgive my ignorance, but I thought that the x64 instruction set simply
does not include any x87 floating point instructions. I suppose that is
ONE definition of “not supported”…


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Correct. 32-bit USER MODE tasks. I didn’t mean to imply anything about user mode, sorry.

The CRTL in user mode for floating point for x64 native 64-bit programs is all done with SSE/SSE2. Interesting, huh?

That’s not the impression I’m under, but I’m not looking at a processor manual either.

To me, whether CPU support is there or not is moot if I can’t use it under any circumstances in kernel mode. Which, as I said, I believe to be the case.

My point is only this: If the OP dude thinks KeSaveFloatingPointState/KeRestoreFloatingPointState are doing something that’ll let him execute FPP on x64 (like it does on x64) he’s mistaken. It’s hard to tell from his question… However, if even for the archive, I didn’t want anybody left with the impression that there’s any reasonable way to use x87/FPP instructions in x64 kernel mode.

Peter
OSR

Hello Peter and Tim,
Thank you so much for your help. But for the current discussion on “Test thourghly on X64 machine using KeSaveFloatingPointState() and KeRestoreFloatingPointState()” from Peter, I don’t understand it fully. Sorry for my ignorance. Could you explain it more plain language?. As you see, I am very very beginner of these world.

If I need to test, how can I test and verify it?
Thank you, again.

xxxxx@hotmail.com wrote:

Hello Peter and Tim,
Thank you so much for your help. But for the current discussion on “Test thourghly on X64 machine using KeSaveFloatingPointState() and KeRestoreFloatingPointState()” from Peter, I don’t understand it fully. Sorry for my ignorance. Could you explain it more plain language?. As you see, I am very very beginner of these world.

Well, as it turns out, I am mistaken. The x64 instruction set DOES
include the x87 instructions, even in 64-bit mode, so you may ignore my
message about that. I’m not sure where I got that impression.

Peter’s point is that the thread scheduler in Win64 does not save and
restore the floating point stack when a task switch occurs. So, if your
driver is doing some calculation, and some other kernel thread gets
scheduled in the middle and uses a floating point instruction, your
calculations will be ruined. That makes it just about impossible to use
the x87 instructions in kernel mode.

The question then becomes, do sin() and cos() in the kernel-mode
run-time library (libcntpr.lib) use those instructions? And the answer
to that is “no”. I just extracted and disassembled those modules from
the amd64 library, and it looks like they are using SSE/SSE2 to do a
polynomial expansion, as Calvin suggested. No x87 instructions.

So, to sum up: yes, you may call sin() and cos() in your kernel driver
(using libcntpr.lib). On x64, you do not need to call
KeSaveFloatingPointState(), because those routines do not alter the
floating point state. In fact, KeSaveFloatingPointState() is useless on
x64, because you can’t safely use the registers it saves anyway.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks Tim again for your plain and easy answer. Now I can understand very clearly. Thank you so much again.