#ifndef __CCRXMACHINE_H__ #define __CCRXMACHINE_H__ static __inline__ signed long __max(signed long data1, signed long data2) __attribute__((always_inline)); static __inline__ signed long __min(signed long data1, signed long data2) __attribute__((always_inline)); static __inline__ unsigned long __revl(unsigned long data) __attribute__((always_inline)); static __inline__ unsigned long __revw(unsigned long data) __attribute__((always_inline)); static __inline__ void __xchg(signed long *data1, signed long *data2) __attribute__((always_inline)); static __inline__ long long __rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2) __attribute__((always_inline)); static __inline__ long long __rmpaw(long long init, unsigned long count, short *addr1, short *addr2) __attribute__((always_inline)); static __inline__ long long __rmpal(long long init, unsigned long count, long *addr1, long *addr2) __attribute__((always_inline)); static __inline__ unsigned long __rolc(unsigned long data) __attribute__((always_inline)); static __inline__ unsigned long __rorc(unsigned long data) __attribute__((always_inline)); static __inline__ unsigned long __rotl(unsigned long data, unsigned long num) __attribute__((always_inline)); static __inline__ unsigned long __rotr(unsigned long data, unsigned long num) __attribute__((always_inline)); static __inline__ void __brk(void) __attribute__((always_inline)); static __inline__ void __int_exception(signed long num) __attribute__((always_inline)); static __inline__ void __wait(void) __attribute__((always_inline)); static __inline__ void __nop(void) __attribute__((always_inline)); static __inline__ void __set_ipl(signed long level) __attribute__((always_inline)); static __inline__ unsigned char __get_ipl(void) __attribute__((always_inline)); static __inline__ void __set_psw(unsigned long data) __attribute__((always_inline)); static __inline__ unsigned long __get_psw(void) __attribute__((always_inline)); static __inline__ void __set_fpsw(unsigned long data) __attribute__((always_inline)); static __inline__ unsigned long __get_fpsw(void) __attribute__((always_inline)); static __inline__ void __set_usp(void * data) __attribute__((always_inline)); static __inline__ void * __get_usp(void) __attribute__((always_inline)); static __inline__ void __set_isp(void * data) __attribute__((always_inline)); static __inline__ void * __get_isp(void) __attribute__((always_inline)); static __inline__ void __set_intb(void * data) __attribute__((always_inline)); static __inline__ void * __get_intb(void) __attribute__((always_inline)); static __inline__ void __set_bpsw(unsigned long data) __attribute__((always_inline)); static __inline__ unsigned long __get_bpsw(void) __attribute__((always_inline)); static __inline__ void __set_bpc(void * data) __attribute__((always_inline)); static __inline__ void * __get_bpc(void) __attribute__((always_inline)); static __inline__ void __set_fintv(void * data) __attribute__((always_inline)); static __inline__ void * __get_fintv(void) __attribute__((always_inline)); static __inline__ signed long long __emul(signed long data1, signed long data2) __attribute__((always_inline)); static __inline__ unsigned long long __emulu(unsigned long data1, unsigned long data2) __attribute__((always_inline)); static __inline__ void __chg_pmusr(void) __attribute__((always_inline)); static __inline__ void __set_acc(signed long long data) __attribute__((always_inline)); static __inline__ signed long long __get_acc(void) __attribute__((always_inline)); static __inline__ void __setpsw_i(void) __attribute__((always_inline)); static __inline__ void __clrpsw_i(void) __attribute__((always_inline)); static __inline__ long __macl(short* data1, short* data2, unsigned long count) __attribute__((always_inline)); static __inline__ short __macw1(short* data1, short* data2, unsigned long count) __attribute__((always_inline)); static __inline__ short __macw2(short* data1, short* data2, unsigned long count) __attribute__((always_inline)); static __inline__ void __set_extb(void *data) __attribute__((always_inline)); static __inline__ void * __get_extb(void) __attribute__((always_inline)); static __inline__ void __bclr(unsigned char *data, unsigned long bit) __attribute__((always_inline)); static __inline__ void __bset(unsigned char *data, unsigned long bit) __attribute__((always_inline)); static __inline__ void __bnot(unsigned char *data, unsigned long bit) __attribute__((always_inline)); #define max __max #define min __min #define revl __revl #define revw __revw #define xchg __xchg #define rmpab __rmpab #define rmpaw __rmpaw #define rmpal __rmpal #define rolc __rolc #define rorc __rorc #define rotl __rotl #define rotr __rotr #define brk __brk #define int_exception __int_exception #define wait __wait #define nop __nop #define set_ipl __set_ipl #define get_ipl __get_ipl #define set_psw __set_psw #define get_psw __get_psw #define set_fpsw __set_fpsw #define get_fpsw __get_fpsw #define set_usp __set_usp #define get_usp __get_usp #define set_isp __set_isp #define get_isp __get_isp #define set_intb __set_intb #define get_intb __get_intb #define set_bpsw __set_bpsw #define get_bpsw __get_bpsw #define set_bpc __set_bpc #define get_bpc __get_bpc #define set_fintv __set_fintv #define get_fintv __get_fintv #define emul __emul #define emulu __emulu #define chg_pmusr __chg_pmusr #define set_acc __set_acc #define get_acc __get_acc #define setpsw_i __setpsw_i #define clrpsw_i __clrpsw_i #define macl __macl #define macw1 __macw1 #define macw2 __macw2 #define set_extb __set_extb #define get_extb __get_extb static __inline__ signed long __max(signed long data1, signed long data2) { signed long register result = data1; __asm __volatile("max\t%1, %0 \n" : "+r"(result) : "r"(data2) : ); return result; } static __inline__ signed long __min(signed long data1, signed long data2) { signed long register result = data1; __asm __volatile("min\t%1, %0 \n" : "+r"(result) : "r"(data2) : ); return result; } static __inline__ unsigned long __revl(unsigned long data) { unsigned long register result; __asm __volatile("revl\t%1, %0 \n" : "+r"(result) : "r"(data) : ); return result; } static __inline__ unsigned long __revw(unsigned long data) { unsigned long register result; __asm __volatile("revw\t%1, %0 \n" : "+r"(result) : "r"(data) : ); return result; } static __inline__ void __xchg(signed long *data1, signed long *data2) { signed long register temp = *data1; __asm __volatile("xchg\t%1, %0 \n" : "+&r"(temp) : "m"(*data2) : ); *data1 = temp; } static __inline__ long long __rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2) { unsigned long register r1 asm("r1") = (unsigned long)addr1; unsigned long register r2 asm("r2") = (unsigned long)addr2; unsigned long register r3 asm("r3") = count; long long register r4 asm("r4") = init; unsigned long register r6 asm("r6"); // TODO find a way to store/restore gcc frame pointer r6, because RMPA op WILL trash it __asm __volatile("xor\t%0, %0 \n" : "+r"(r6) : : ); __asm __volatile("rmpa.b \n" : "+r"(r1), "+r"(r2), "+r"(r3), "+r"(r4) : : "cc", "r6" ); return r4; } static __inline__ long long __rmpaw(long long init, unsigned long count, short *addr1, short *addr2) { unsigned long register r1 asm("r1") = (unsigned long)addr1; unsigned long register r2 asm("r2") = (unsigned long)addr2; unsigned long register r3 asm("r3") = count; long long register r4 asm("r4") = init; unsigned long register r6 asm("r6"); // TODO find a way to store/restore gcc frame pointer r6, because RMPA op WILL trash it __asm __volatile("xor\t%0, %0 \n" : "+r"(r6) : : ); __asm __volatile("rmpa.w \n" : "+r"(r1), "+r"(r2), "+r"(r3), "+r"(r4) : : "cc", "r6" ); return r4; } static __inline__ long long __rmpal(long long init, unsigned long count, long *addr1, long *addr2) { unsigned long register r1 asm("r1") = (unsigned long)addr1; unsigned long register r2 asm("r2") = (unsigned long)addr2; unsigned long register r3 asm("r3") = count; long long register r4 asm("r4") = init; unsigned long register r6 asm("r6"); // TODO find a way to store/restore gcc frame pointer r6, because RMPA op WILL trash it __asm __volatile("xor\t%0, %0 \n" : "+r"(r6) : : ); __asm __volatile("rmpa.l \n" : "+r"(r1), "+r"(r2), "+r"(r3), "+r"(r4) : : "cc", "r6" ); return r4; } static __inline__ unsigned long __rolc(unsigned long data) { unsigned long register result = data; __asm __volatile("rolc\t%0 \n" : "+r"(result) : : "cc" ); return result; } static __inline__ unsigned long __rorc(unsigned long data) { unsigned long register result = data; __asm __volatile("rorc\t%0 \n" : "+r"(result) : : "cc" ); return result; } static __inline__ unsigned long __rotl(unsigned long data, unsigned long num) { unsigned long register result = data; __asm __volatile("rotl\t%1, %0 \n" : "+r"(result) : "r"(num) : "cc" ); return result; } static __inline__ unsigned long __rotr(unsigned long data, unsigned long num) { unsigned long register result = data; __asm __volatile("rotr\t%1, %0 \n" : "+r"(result) : "r"(num) : "cc" ); return result; } static __inline__ void __brk(void) { __asm __volatile("brk \n" : : : ); } static __inline__ void __int_exception(signed long num) { __asm __volatile("shll\t#16, %0 \n" : "+r"(num) : : "cc"); /* opcode for int 0x75 0x60 xx then rts 0x02 */ __asm __volatile("add\t#02006075h, %0 \n" : "+r"(num) : : "cc"); /* let's prepare to execute on the stack */ __asm __volatile("push.l\t%0 \n" : : "r"(num) : "r0"); __asm __volatile("mvfc\tpc, %0 \n" : "=r"(num) : : ); /* 3 bytes offset */ /* add total offset in this opcode */ __asm __volatile("add\t#12, %0 \n" : "+r"(num) : : "cc"); /* 2 bytes offset */ __asm __volatile("push.l\t%0 \n" : : "r"(num) : "r0"); /* 2 bytes offset */ __asm __volatile("add\t#4, r0, %0 \n" : "+r"(num) : : "cc"); /* 3 bytes offset */ __asm __volatile("jmp\t%0 \n" : : "r"(num) : ); /* 2 bytes offset */ /* total 12bytes offset from mvfc */ __asm __volatile("add\t#4, r0 \n" : : : "r0"); /* adjust stack after execution */ } static __inline__ void __wait(void) { __asm __volatile("wait \n" : : : ); } static __inline__ void __nop(void) { __asm __volatile("nop \n" : : : ); } static __inline__ void __set_ipl(signed long level) { __asm __volatile("and\t#15, %0 \n" : "+r"(level) : : "cc" ); __asm __volatile("shll\t#24, %0 \n" : "+r"(level) : : "cc" ); __asm __volatile("mvtc\t%0, psw \n" : : "r"(level) : ); } static __inline__ unsigned char __get_ipl(void) { unsigned long register result; __asm __volatile("mvfc\tpsw, %0 \n" : "=r"(result) : : ); __asm __volatile("shlr\t#24, %0 \n" : "+r"(result) : : "cc" ); return result; } static __inline__ void __set_psw(unsigned long data) { __asm __volatile("mvtc\t%0, psw \n" : : "r"(data) : ); } static __inline__ unsigned long __get_psw(void) { unsigned long register result; __asm __volatile("mvfc\tpsw, %0 \n" : "=r"(result) : : ); return result; } static __inline__ void __set_fpsw(unsigned long data) { __asm __volatile("mvtc\t%0, fpsw \n" : : "r"(data) : ); } static __inline__ unsigned long __get_fpsw(void) { unsigned long register result; __asm __volatile("mvfc\tfpsw, %0 \n" : "=r"(result) : : ); return result; } static __inline__ void __set_usp(void * data) { __asm __volatile("mvtc\t%0, usp \n" : : "r"(data) : ); } static __inline__ void * __get_usp(void) { unsigned long register result; __asm __volatile("mvfc\tusp, %0 \n" : "=r"(result) : : ); return (void *)result; } static __inline__ void __set_isp(void * data) { __asm __volatile("mvtc\t%0, isp \n" : : "r"(data) : ); } static __inline__ void * __get_isp(void) { unsigned long register result; __asm __volatile("mvfc\tisp, %0 \n" : "=r"(result) : : ); return (void *)result; } static __inline__ void __set_intb(void * data) { __asm __volatile("mvtc\t%0, intb \n" : : "r"(data) : ); } static __inline__ void * __get_intb(void) { unsigned long register result; __asm __volatile("mvfc\tintb, %0 \n" : "=r"(result) : : ); return (void *)result; } static __inline__ void __set_bpsw(unsigned long data) { __asm __volatile("mvtc\t%0, bpsw \n" : : "r"(data) : ); } static __inline__ unsigned long __get_bpsw(void) { unsigned long register result; __asm __volatile("mvfc\tbpsw, %0 \n" : "=r"(result) : : ); return result; } static __inline__ void __set_bpc(void * data) { __asm __volatile("mvtc\t%0, bpc \n" : : "r"(data) : ); } static __inline__ void * __get_bpc(void) { unsigned long register result; __asm __volatile("mvfc\tbpc, %0 \n" : "=r"(result) : : ); return (void *)result; } static __inline__ void __set_fintv(void * data) { __asm __volatile("mvtc\t%0, fintv \n" : : "r"(data) : ); } static __inline__ void * __get_fintv(void) { unsigned long register result; __asm __volatile("mvfc\tfintv, %0 \n" : "=r"(result) : : ); return (void *)result; } static __inline__ signed long long __emul(signed long data1, signed long data2) { signed long long register result = data1; __asm __volatile("emul\t%1, %0 \n" : "+r"(result) : "r"(data2) : ); return result; } static __inline__ unsigned long long __emulu(unsigned long data1, unsigned long data2) { unsigned long long register result = data1; __asm __volatile("emulu\t%1, %0 \n" : "+r"(result) : "r"(data2) : ); return result; } static __inline__ void __chg_pmusr(void) { unsigned long register result; __asm __volatile("mvfc\tpsw, %0 \n" : "=r"(result) : : ); __asm __volatile("or\t#00100000h, %0 \n" : "+r"(result) : : "cc"); __asm __volatile("push.l\t%0 \n" : : "r"(result) : ); __asm __volatile("mvfc\tpc, %0 \n" : "=r"(result) : : ); /* 3 bytes offset */ __asm __volatile("add\t#9, %0 \n" : "+r"(result) : : "cc"); /* 3 bytes offset */ /* add total offset in this opcode */ __asm __volatile("push.l\t%0 \n" : : "r"(result) : ); /* 2 bytes offset */ __asm __volatile("rte \n" : : : ); /* 2 bytes offset */ } static __inline__ void __set_acc(signed long long data) { signed long register lo asm("r1") = data; signed long register hi asm("r2") = (data>>32); __asm __volatile("mvtaclo\t %0 \n" : : "r"(lo) : ); __asm __volatile("mvtachi\t %0 \n" : : "r"(hi) : ); } static __inline__ signed long long __get_acc(void) { signed long long register r1 asm("r1"); signed long register lo asm("r1"); signed long register hi asm("r2"); __asm __volatile("mvfacmi\t %0 \n" : "=r"(lo) : : ); __asm __volatile("shll\t#16, %0 \n" : "+r"(lo) : : ); __asm __volatile("mvfachi\t %0 \n" : "=r"(hi) : : ); return r1; } static __inline__ void __setpsw_i(void) { __asm __volatile("setpsw\t i \n" : : : ); } static __inline__ void __clrpsw_i(void) { __asm __volatile("clrpsw\t i \n" : : : ); } static __inline__ long __macl(short* data1, short* data2, unsigned long count) { signed long register *ldata1 = (signed long *)data1; signed long register *ldata2 = (signed long *)data2; /* this is much more then an "intrinsic", no inline asm because of loop */ /* will implement this.. interesting function as described in ccrx manual */ __builtin_rx_mullo(0, 0); while (count > 1) { __builtin_rx_maclo(*ldata1, *ldata2); __builtin_rx_machi(*ldata1, *ldata2); ldata1++; ldata2++; count -= 2; } if (count != 0) __builtin_rx_maclo(*ldata1, *ldata2); return __builtin_rx_mvfacmi(); } static __inline__ short __macw1(short* data1, short* data2, unsigned long count) { signed long register *ldata1 = (signed long *)data1; signed long register *ldata2 = (signed long *)data2; /* this is much more then an "intrinsic", no inline asm because of loop */ /* will implement this.. interesting function as described in ccrx manual */ __builtin_rx_mullo(0, 0); while (count > 1) { __builtin_rx_maclo(*ldata1, *ldata2); __builtin_rx_machi(*ldata1, *ldata2); ldata1++; ldata2++; count -= 2; } if (count != 0) __builtin_rx_maclo(*ldata1, *ldata2); __builtin_rx_racw(1); return __builtin_rx_mvfachi(); } static __inline__ short __macw2(short* data1, short* data2, unsigned long count) { signed long register *ldata1 = (signed long *)data1; signed long register *ldata2 = (signed long *)data2; /* this is much more then an "intrinsic", no inline asm because of loop */ /* will implement this.. interesting function as described in ccrx manual */ __builtin_rx_mullo(0, 0); while (count > 1) { __builtin_rx_maclo(*ldata1, *ldata2); __builtin_rx_machi(*ldata1, *ldata2); ldata1++; ldata2++; count -= 2; } if (count != 0) __builtin_rx_maclo(*ldata1, *ldata2); __builtin_rx_racw(2); return __builtin_rx_mvfachi(); } static __inline__ void __set_extb(void *data) { __asm __volatile("mvtc\t%0, extb \n" : : "r"(data) : ); } static __inline__ void * __get_extb(void) { unsigned long register result; __asm __volatile("mvfc\textb, %0 \n" : "=r"(result) : : ); return (void *)result; } static __inline__ void __bclr(unsigned char *data, unsigned long bit) { __asm __volatile("bclr\t%1, %0.B \n" : "+m"(*data) : "r"(bit) : ); } static __inline__ void __bset(unsigned char *data, unsigned long bit) { __asm __volatile("bset\t%1, %0.B \n" : "+m"(*data) : "r"(bit) : ); } static __inline__ void __bnot(unsigned char *data, unsigned long bit) { __asm __volatile("bnot\t%1, %0.B \n" : "+m"(*data) : "r"(bit) : ); } #endif