/* Architectute dependent code block definitions for i386 family. */ #ifndef __MACHDEP_H__ #define __MACHDEP_H__ #define MACH_i386 /* architecture specific code blocks */ /* Instructions to start a loop of executions. The count is the number of sets to execute the code block. Each of the parameters should be a value on the stack. The next address is stored in AX, the amount to jump is stored in BX. */ #define REP_BLOCK( code, jump, count ) __asm__ __volatile__( "movl %0,%%esi \n\t movl %1,%%ebx \n\t movl %2,%%ecx \n\t movl $1f,%%edx \n\t 0: movl %%esi,%%eax \n\t jmp *%%eax \n\t 1: decl %%ecx \n\t jnz 0b" :/*NO OUT*/: "m"(code),"m"(jump),"m"(count) : "%eax","%ebx","%ecx","%edx","%esi", "cc" ); /* Instructions to start executing generated code on "code", jumping "jump" bytes and returning to "ret". Each of the parameters should be a value on the stack. The next address is stored in AX, the amount to jump is stored in BX, and the return address is stored in DX. */ #define RUN_BLOCK( code, jump, ret ) __asm__ __volatile__( "movl %0,%%eax \n\t movl %1,%%ebx \n\t movl %2,%%edx \n\t jmp *%%eax " :/*NO OUT*/: "m"(code),"m"(jump),"m"(ret) : "%eax","%ebx","%edx" ); /* Instructions to jump within the code block to the next jump instruction or the return block. The jump size is added to the currrent address in AX. Any delay slots must be filled in this block since the compiler will not see it. */ #define JMP_BLOCK startjmp: __asm( "addl %ebx,%eax \n\t jmp *%eax" );\ endjmp: /* Instruction used as filler. */ #define NOP_BLOCK startnop: __asm( "nop" );\ endnop: /* Instruction used to return back to the calling code. The return address is excepted in DX. Any delay slots must be filled in this block since the compiler will not see it. */ #define RET_BLOCK startret: __asm( "jmp *%edx" );\ endret: #endif