Author Topic: Is there a way to check current CPU level?  (Read 11152 times)

Offline Serge

  • Jr. Member
  • *
  • Posts: 26
  • Country: ru
Is there a way to check current CPU level?
« on: July 23, 2011, 03:57:58 PM »
Is there a way to check current CPU level?
I need to write a macro that generates different code, depending on current CPU level.
Also the obvious use of this is to "macronize" instructions that are illegal for current CPU level on mixed code.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Is there a way to check current CPU level?
« Reply #1 on: July 23, 2011, 04:44:50 PM »
Well, the "cpuid" instruction (family of instructions) will tell you the cpu level... at run-time. A macro, however, operates at assemble-time and can't know in advance what cpu it's going to be running on. So your options are going to be to write "both kinds of code" and select which to execute at run-time, or inform your macro in advance what the "target" cpu is. I can't think of any possible way to "mix" them.

Best,
Frank


Offline Serge

  • Jr. Member
  • *
  • Posts: 26
  • Country: ru
Re: Is there a way to check current CPU level?
« Reply #2 on: July 23, 2011, 04:55:20 PM »
No-no-no, I did mean "at execution time"!
The idea is to write code that runs on different CPUs. Of course, the processor is CPUIDed before and runs different parts of code. But I need to implement frequently used and highly optimized operation as macro that will generate different code, depending on selected target CPU.
I mean that I need something like __BITS__ variable that can be used in conditional compilation. Let it be __CPU__ variable, for example.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Is there a way to check current CPU level?
« Reply #3 on: July 23, 2011, 05:48:07 PM »
Sure, just define __CPU__ as... whatever you want. Best done on the command line, of course...

Code: [Select]
nasm -f bin -d __CPU__=foo myfile.asm

... and then in your file...

Code: [Select]
%ifidn __CPU__, foo
; some code
%else
; some other code
%endif

This isn't going to be "at execution time", of course. Perhaps I don't understand the question...

Best,
Frank




Offline Serge

  • Jr. Member
  • *
  • Posts: 26
  • Country: ru
Re: Is there a way to check current CPU level?
« Reply #4 on: July 23, 2011, 07:11:37 PM »
Ups... Bad way.
This makes my project compilation dependant, requires different compilation runs for parts of project and, moreover, very unreliable. I can't check in macro, that it used proper way in proper circumstances.
With the same effect I can define __CPU__ every time I fire CPU directive.
So, there is no method, right?
Then please treat is as a "feature request". Like existing pair: "bits" directive <-> __BITS__ built-in macro.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Is there a way to check current CPU level?
« Reply #5 on: July 23, 2011, 07:33:01 PM »
Please suggest implementation details for your "feature request". How in the world would Nasm know what cpu your program would be running on?

As I said, perhaps I don't understand the question...

Best,
Frank


Offline Serge

  • Jr. Member
  • *
  • Posts: 26
  • Country: ru
Re: Is there a way to check current CPU level?
« Reply #6 on: July 23, 2011, 08:38:04 PM »
That's simple example (just to understand)...

Code: [Select]
%macro bswap 1
%if __CPU__<486
; Here comes complicated rotations and exchanges
%else
bswap %1
%endif
%endmacro

cpu 386
call CheckFor486 ; We are checking what kind of system we are running
jc i486
... ; Here is the code for puny CPU
bswap eax ; Easy readable manually optimized code
...
retn

cpu 486
i486: ... ; And here is the code for cool CPU
bswap eax ; And it comes as is
...
retn

Actual code is for real-time signal processing and multimedia.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Is there a way to check current CPU level?
« Reply #7 on: July 23, 2011, 09:12:58 PM »
I fail to see how your "CheckFor486" routine is going to make __CPU__ available to a macro.

Best,
Frank


Offline Serge

  • Jr. Member
  • *
  • Posts: 26
  • Country: ru
Re: Is there a way to check current CPU level?
« Reply #8 on: July 23, 2011, 09:37:58 PM »
The "CheckFor486" routine doesn't handle __CPU__. And it doesn't matter at all how it is implemented. The key is:

Code: [Select]
cpu 386
...
bswap eax ; Expands one way
...

cpu 486
...
bswap eax ; Expands another way

Please have a look at another real code...

Code: [Select]
%macro msg 1
%if __BITS__=16
call near Message16
%elif __BITS__=32
call near Message32
%else
call near Message64
%endif
db %1, 0
%endmacro


bits 16
...
msg `This message will be printed by 16-bit routine\n`
...

bits 32
...
msg `This message will be printed by 32-bit routine\n`
...

Depending on which section the macro is expanded on (16/32/64) it will call the different routine. This is due to built-in macro __BITS__ which can indicate where macro is used. Just EXACTLY like this I suggest to implement the new built-in macro __CPU__ which indicates the section, where the macro is compiled.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Is there a way to check current CPU level?
« Reply #9 on: July 24, 2011, 12:13:17 AM »
I guess I get it. You want your use of the "cpu" directive to set "__CPU__", right? Sort of (but not exactly) like this?

Code: [Select]
bits 32

%macro setcpu 1
cpu %1
%define __CPU__ %1
%endmacro

%macro bswap 1
%ifidn __CPU__, 386
; placeholder - "generic" bswap is hard!
;mov eax, ~(1<<31) ; just to "make a (bogus) noise"
; testing nasm64developer's "fix"
mov eax, 0FFFFFFFFh & ( ~(1<<31)) ; no noise

nop
%elifidn __CPU__, 486
bswap %1
%else
%warning "not implemented for this cpu level"
%endif
%endmacro


setcpu 386

bswap eax

setcpu 486

bswap eax

Ideally, "__CPU__" would be numeric, not text like this humble example, so we could use "<", ">", etc... I guess that could be done... You can make a "feature request" at SF, but don't hold your breath waiting for it. Meantime, perhaps a slightly more sophisticated macro could be worked up. Too hot to chase women today, maybe I'll get to it...

Best,
Frank