Porting MSC-asm to gcc/gas -> error: can't find a register in class...

[email protected]
Newsgroups gmane.linux.assembly
Message-ID <[email protected]>
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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.