Hallo!
I'm hopelessly lost: I tried to port inline asm from CTP2 code, which is written for MSC.
I think I did quite well but have two problems:
1. One part of asm code uses six references to C-vars and still needs a free register. I don't know how MSC can handel that but gas seems not to be able to. I think, I found a small workaround but when compiling it, gcc complains with:
error: can't find a register in class `BREG' while reloading `asm'
Studying similar questions in the net they never say what this message means or how to prevent it by modifing the code. Using gcc-3.36 instead of 4.1.1 didn't help nor using -fomit-frame-pointer or -O. I tried two variants, one with static registers and one with dynamic registers.
What is it gcc can't do and how can I solve it?
2. What exception would I have to catch if asm part fails? (see below the mmx test)
Thanks for any help.
Lynx
Below two parts of code which both don't compile:
#ifdef _MSC_VER
bool retval = true;
DWORD RegEDX = 0;
__try {
_asm {
mov eax, 1
_emit 0fh
_emit 0a2h
mov RegEDX, edx
}
} __except(EXCEPTION_EXECUTE_HANDLER) { retval = false; }
if(retval == false)
return false;
if (RegEDX & 0x800000)
{
__try { _asm emms }
__except(EXCEPTION_EXECUTE_HANDLER) { retval = false; }
}
#else
bool retval = true;
DWORD RegEDX = 0;
try {
__asm__ (
"movl $1,%%eax \n\t"
"_emit 0fh \n\t"
"_emit 0a2h \n\t"
// "movl %edx, $RegEDX \n\t"
: "=d" (RegEDX)
:
: "%eax", "%edx", "memory"
);
}
catch(...) {
printf("%s L%d: MMX-Test FAILED!\n", __FILE__, __LINE__);
retval = false;
}
if(retval == false)
return false;
if (RegEDX & 0x800000)
{
try { __asm__ (" emms \n\t"); }
catch(...) {
printf("%s L%d: MMX-Test FAILED!\n", __FILE__, __LINE__);
retval = false;
}
}
printf("%s L%d: MMX-Test succeded!\n", __FILE__, __LINE__);
//bool retval = false;
#endif // _MSC_VER
return retval;
}
_____________________________________________________________________________
diffrent file now:
______________________________________________________________________________
dataPtr = data;
uint8 *pSurfBase;
pSurfBase = m_surfBase;
sint32 surfWidth = m_surfWidth;
sint32 surfHeight = m_surfHeight;
sint32 surfPitch = m_surfPitch;
Pixel16 srcPixel, transPixel = 0;
uint16 *pDestPixel = (Pixel16 *)(pSurfBase + (y+ypos) * surfPitch + 2 * (x+xpos));
{
for (y=0; y<k_TILE_PIXEL_HEIGHT; y++) {
if (y<=23) {
startX = (23-y)*2;
endX = k_TILE_PIXEL_WIDTH - startX;
} else {
startX = (y-24)*2;
endX = k_TILE_PIXEL_WIDTH - startX;
}
//#ifdef _MSC_VER //use this if __asm__ is NOT used
if (transDataPtr)
{
#ifdef _MSC_VER //use this if __asm__ is used
//printf("tiledraw.cpp L4141: assambly used!\n");
_asm {
mov edx, endX
mov edi, pDestPixel
mov esi, dataPtr
mov ecx, startX
lea edi, [edi + 2*edx]
sub ecx, edx
mov ebx, transDataPtr
L0:
mov dx, [esi]
add esi, 2
xor eax, eax
mov ax, dx
cmp eax, 4
jge L1
mov edx, tileData[4*eax]
test edx, edx
jz L2
add edx, 2
mov tileData[4*eax], edx
mov dx, [edx-2]
jmp L1
L2:
mov dx, [ebx]
L1:
add ebx, 2
mov [edi + 2*ecx], dx
inc ecx
jnz L0
mov transDataPtr, ebx
mov dataPtr, esi
}
#else //use this if __asm__ is used
//this comes from intel2gas -I tiledraw.cpp
__asm__ __volatile__ (
// "movl $endX, %edx \n\t"
// "movl $pDestPixel, %edi \n\t"
// "movl $dataPtr, %esi \n\t"
// "movl $startX, %ecx \n\t"
"leal (%edi,%edx,2),%edi \n\t"
"subl %edx,%ecx \n\t"
// "movl $transDataPtr, %ebx \n\t"
".L0: \n\t"
"movw (%esi),%dx \n\t"
// "addl $2,%esi \n\t"
"movl %eax, %esi \n\t"
"xorl %eax,%eax \n\t"
"movw %dx,%ax \n\t"
"cmpl $4,%eax \n\t"
"jge .L1 \n\t"
"movl %esi(%eax,4), %edx \n\t"
"testl %edx,%edx \n\t"
"jz .L2 \n\t"
"addl $2,%edx \n\t"
"movl %edx, %esi(%eax,4) \n\t"
"movw -2(%edx),%dx \n\t"
"jmp .L1 \n\t"
".L2: \n\t"
"movw (%ebx),%dx \n\t"
".L1: \n\t"
"addl $2,%ebx \n\t"
"movw %dx,(%edi,%ecx,2) \n\t"
"incl %ecx \n\t"
"jnz .L0 \n\t"
// "movl %ebx, $transDataPtr \n\t"
// "movl %esi, $dataPtr \n\t"
: //"=b" (transDataPtr), "=S" (dataPtr)
: "D" (pDestPixel), "a" (tileData), "d" (endX), "c" (startX), "b" (transDataPtr), "S" (dataPtr)
: "memory" );
// this is adjusted after intel2gas -I tiledraw.cpp
/* __asm__ (
// "movl $endX, %edx \n\t" //done by gcc!
// "movl $pDestPixel, %edi \n\t" //done by gcc!
// "movl $dataPtr, %esi \n\t" //done by gcc!
// "movl $startX, %ecx \n\t" //done by gcc!
"leal (%0,%1,2),%0 \n\t" //load value %0 + %1 * s is pointing to %0
"subl %1,%2 \n\t"
// "movl $transDataPtr, %ebx \n\t" //done by gcc!
".L0: \n\t"
"movw (%4),%%dx \n\t"
"addl $2,%4 \n\t"
"xorl %%eax,%%eax \n\t" //make %eax = 0, see below
"movw %%dx,%%ax \n\t" //because of this eax has to be static
"cmpl $4,%%eax \n\t" //because of above line eax may be != 0
"jge .L1 \n\t"
"movl %5(%%eax,4), %1 \n\t" // %1 = (%5 + %eax * 4)
"testl %1,%1 \n\t" //check if %1 is zero, set Z-bit
"jz .L2 \n\t"
"addl $2,%1 \n\t"
"movl %1, %5(%%eax,4) \n\t" // (%5 + %eax * 4) = %1
"movw -2(%1),%%dx \n\t"
"jmp .L1 \n\t"
".L2: \n\t"
"movw (%3),%%dx \n\t"
".L1: \n\t"
"addl $2,%3 \n\t"
"movw %%dx,(%0,%2,2) \n\t"
"incl %2 \n\t"
"jnz .L0 \n\t"
// "movl %ebx, $transDataPtr \n\t"
// "movl %esi, $dataPtr \n\t"
: // FIXASM: output regs/vars go here, e.g.: "=m" (memory_var)
: "0" (pDestPixel), "1" (endX), "2" (startX), "3" (transDataPtr), "4" (dataPtr), "5" (tileData)
: // FIXASM: clobber list, e.g.: "%eax", "%ecx", "cc"
);
*/
#endif //use this if __asm__ is used
}
else
{
for (x = startX; x<endX; x++)
{
srcPixel = *dataPtr++;
if (srcPixel < 4)
{
Pixel16 *tile = tileData[srcPixel];
if (tile != NULL)
-
To unsubscribe from this list: send the line "unsubscribe linux-assembly" in
the body of a message to
majordomo@vger...
More majordomo info at
http://vger.kernel.org/majordomo-info.html
opensubscriber is not affiliated with the authors of this message nor responsible for its content.