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@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html
- Prev by Date: Re: AsmIDE update
- Next by Date: How to push PIC reg before seven input operands get loaded?
- Previous by thread: self modyfing code and GDT
- Next by thread: How to push PIC reg before seven input operands get loaded?
- Index(es):