Page 1 of 1

invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Fri Apr 16, 2021 12:07 pm
by antoni
Hi,
My program (generated by GCC) triggered invalid opcode exception. It was caused by this instruction:

Code: Select all

pxor   %xmm0,%xmm0
Do I need to enable SSE or something to use this instruction?

Re: invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Fri Apr 16, 2021 12:46 pm
by Ethin
Yes, PXOR is an SSE2/MMX instruction. VPXOR is an AVX instruction. The compiler should not be generating these instructions, however, so your configuration is probably broken.

Re: invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Fri Apr 16, 2021 1:33 pm
by nullplan
Some versions ago, both clang and gcc added "-mgeneral-regs-only" as compiler switch for AMD64 (it was already one before that for some other architecture I can't remember right now), which eliminates the need to hunt down all the instruction sets your CPU might support, but you can't use in kernel mode.

Re: invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Fri Apr 16, 2021 2:07 pm
by kzinti
nullplan wrote:Some versions ago, both clang and gcc added "-mgeneral-regs-only" as compiler switch for AMD64 (...) but you can't use in kernel mode.
This works fine for me with GCC 10.2. I am using "-mgeneral-regs-only -mno-red-zone -mcmodel=kernel" and it just works. The gotcha is that you then can't use any float anywhere as the ABI mandates the use of XMM registers for float parameters and return values. But that's fine, one does not usually have floats in their kernel.

Or did you mean something else by "can't use (it) in kernel mode"?

Re: invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Fri Apr 16, 2021 9:24 pm
by klange
kzinti wrote:
nullplan wrote:Some versions ago, both clang and gcc added "-mgeneral-regs-only" as compiler switch for AMD64 (...) but you can't use in kernel mode.
This works fine for me with GCC 10.2. I am using "-mgeneral-regs-only -mno-red-zone -mcmodel=kernel" and it just works. The gotcha is that you then can't use any float anywhere as the ABI mandates the use of XMM registers for float parameters and return values. But that's fine, one does not usually have floats in their kernel.

Or did you mean something else by "can't use (it) in kernel mode"?
I believe nullplan was referring to the registers - they are "registers your CPU has, but can not use in kernel mode". Though whether you can use registers in kernel mode is really up to how you manage them, it's generally considered good practice to avoid the various extended registers in the kernel so they can be more efficiently context switched.

Re: invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Fri Apr 16, 2021 9:34 pm
by Ethin
If you enable SSE and AVX then you can (technically) use those features in kernel mode. The question though is, why would you ever need them? AVX and SSE don't really have many, if any, use cases in kernel mode.

Re: invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Fri Apr 16, 2021 10:00 pm
by kzinti
klange wrote:I believe nullplan was referring to the registers - they are "registers your CPU has, but can not use in kernel mode".
I re-read this and think he meant "instructions that you cannot use in kernel mode" and not the registers. The commas placement confused me.

Re: invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Fri Apr 16, 2021 10:24 pm
by nullplan
kzinti wrote:I re-read this and think he meant "instructions that you cannot use in kernel mode" and not the registers. The commas placement confused me.
This is exactly what I meant. Bloody commas. I often end up using German comma rules in English, and apparently this can cause confusion. I'll strive to better myself on this.
Ethin wrote:If you enable SSE and AVX then you can (technically) use those features in kernel mode. The question though is, why would you ever need them? AVX and SSE don't really have many, if any, use cases in kernel mode.
The compiler will sometimes emit SSE instructions even in integer-only code, usually to optimize some memory copy or to vectorize some loop. Thing is, in order to use extended instruction sets in kernel mode, you must save the extended registers on entry and restore them on exit. Normally, you only have to do this on task switch. But adding XSAVE/XRESTORE to all entry and exit paths likely imposes a bigger cost than the use of SSE/AVX can ever make up. Therefore most kernel authors make the executive decision to not save extended registers on entry and forego the use of them in the kernel.

Re: invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Fri Apr 16, 2021 11:49 pm
by sj95126
You may want to disable SSE register use by the compiler if for no other reason than to avoid clogging up your stack frame with saves of the XMM registers in places like variadic functions where they may not even get used. The SysV amd64 ABI, for example, requires that registers that "might" be used to save arguments be saved in the register save area. You can skip saving XMM0-7 by setting %al to 0, but the code to save them is just jumped over and you still have a larger stack frame. If you tell the compiler to not use SSE, it leaves this out:

Code: Select all

 21d:   84 c0                   test   %al,%al
 21f:   74 20                   je     241 <kdebug+0x59>
 221:   0f 29 45 80             movaps %xmm0,-0x80(%rbp)
 225:   0f 29 4d 90             movaps %xmm1,-0x70(%rbp)
[and so on...]

Re: invalid opcode exception on "pxor %xmm0,%xmm0"

Posted: Sat Apr 17, 2021 12:12 am
by kzinti
nullplan wrote:This is exactly what I meant. Bloody commas. I often end up using German comma rules in English, and apparently this can cause confusion. I'll strive to better myself on this.
No worries, I don't understand comma rules in English either. I gave up a long time ago and decided to simply not use them. It turns out that making many small sentences works better than using commas in English.