/* Architectute dependent code block definitions for sparc family. */ #ifndef __MACHDEP_H__ #define __MACHDEP_H__ #define MACH_SPARC /* 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 R0, the amount to jump is stored in R1. */ #define REP_BLOCK( code, jump, count ) __asm__ __volatile__( "ld %0,%%o4 \n\t ld %1,%%o1 \n\t ld %2,%%o3 \n\t sethi %%hi(1f),%%o2 \n\t or %%o2,%%lo(1f),%%o2 \n\t 0: mov %%o4,%%o0 \n\t jmp %%o0 \n\t nop \n\t 1: addcc %%o3,-1,%%o3 \n\t bne 0b \n\t nop" :/*NO OUT*/: "m"(code),"m"(jump),"m"(count) : "%o0","%o1","%o2","%o3","%o4","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 R0, the amount to jump is stored in R1, and the return address is stored in R2. */ #define RUN_BLOCK( code, jump, ret ) __asm__ __volatile__( "ld %0,%%o0 \n\t ld %1,%%o1 \n\t ld %2,%%o2 \n\t jmp %%o0 \n\t nop" :/*NO OUT*/: "m"(code),"m"(jump),"m"(ret) : "%o0","%o1","%o2" ); /* 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 R0. Any delay slots must be filled in this block since the compiler will not see it. */ #define JMP_BLOCK startjmp: __asm( "add %o0,%o1,%o0 \n\t jmp %o0 \n\t nop" );\ 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 R2. Any delay slots must be filled in this block since the compiler will not see it. */ #define RET_BLOCK startret: __asm( "jmp %o2 \n\t nop" );\ endret: #endif