Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

problems with porting assembly code from MSVC to intel compiler in ubuntu

suanhwee
Beginner
467 Views
hi i trying to port code from msvc to linux. all is fine
except for the below error. pinsrw is a valid assembly instruction why does it not compile?

thank you

this is the error
error: unsupported instruction form -- __asm pinsrw

#define _CALCULATE(number)
{
__asm mov edi, [eax]
__asm mov cx, word ptr [esi+edi]
__asm pinsrw xmm3, cx, shiftNr

__asm add edi, edx
__asm mov cx, word ptr [esi+edi]
__asm add eax, 4
__asm pinsrw xmm5, cx, shiftNr
}
0 Kudos
6 Replies
Dale_S_Intel
Employee
467 Views
It depends on what "shiftNr" is, which is undefined in this snippet (note that "number" is unused). The third parameter to the pinsrw instruction is an immediate so the thing you pass it must be a constant at compile time.

If you believe that shiftNr is a constant, please post a compilable test case and I'll look at it some more.

Thanks!

Dale
0 Kudos
Dale_S_Intel
Employee
467 Views
I must admit to a little confusion. If I take this out of a macro and have a function like this:

void foo()
{
__asm mov edi, [eax]
__asm mov cx, word ptr [esi+edi]
__asm pinsrw xmm3, ecx, 2
__asm add edi, edx
__asm mov cx, word ptr [esi+edi]
__asm add eax, 4
__asm pinsrw xmm5, ecx, 2
}

Then it works on both Linux and Windows. In the original form, assuming that "number" should really be shiftNr and instantiating the macro in a function, it fails on both Linux and Windows with the Intel compiler.

Dale

0 Kudos
Dale_S_Intel
Employee
467 Views
OK, at least some of my confusion arises from a copy/paste problem, wherein spaces are added to the end of the lines which went undetected.

When I fix that, I see a difference in behavior between the MS compiler and the Intel compiler on windows. An issue is being submitted on that.

May I assume that the code you're porting from windows was built with the MS compiler? Is there any chance that using a function as above is a useful workaround (of course you can't pass in a parameter, which complicates things).

We'll update here when the issue as addressed.

Thanks!

Dale

0 Kudos
suanhwee
Beginner
467 Views
Hi Dale, thanks for helping me out, the error is that the "number" should be "shiftNr" in the define statement. sorry about that.

Yes im converting the code from Visual studio 2005 -> intel compiler (ubuntu)
im using icpc -use-masm (to compile it)


#define _CALCULATE(shiftNr)
{
__asm mov edi, [eax]
__asm mov cx, word ptr [esi+edi]
__asm pinsrw xmm3, cx, shiftNr

__asm add edi, edx

__asm mov cx, word ptr [esi+edi]
__asm add eax, 4
__asm pinsrw xmm5, cx, shiftNr
}

what is happening is i will be using this macro in this form in other parts of my code and yr correct that i am passing shiftNr as a constant and by doing it this way it works find in visual studio but gives the error
error: unsupported instruction form -- __asm pinsrw
in linux and im using icpc -use-masm to compile it
__asm _CALCULATE(0x0)

0 Kudos
levicki
Valued Contributor I
467 Views

Stupid question, but have you perhaps tried writing 0h instead of 0x0?

0 Kudos
JenniferJ
Moderator
467 Views

I should have posted some insight info I got earlier.

According to the Intel Software Developer's Manual, passing a 16-bit register to the PINSRW instruction is not valid.

pinsrw xmm3, cx, shiftNr

should be rewritten as
pinsrw xmm3, ecx, shiftNr

In addition, it's strongly recommended that you change the 16-bit load instructions into zero extending loads. As written, this code suffers from a partial register stall. The machine implementation of PINSRW reads the full 32 bits of ECX even though only the lower 16 bits affect the result. This stall will severely affect the performance of this code. So instead of

mov cx, word ptr [esi + edi]

use
movzx ecx, word ptr [esi + edi]

0 Kudos
Reply