/* License: The MIT License will be used. https://opensource.org/licenses/MIT */ /* Docments: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html and https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html (https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html) https://gcc.gnu.org/onlinedocs/gcc/Constraints.html https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html https://gcc.gnu.org/onlinedocs/gcc/Explicit-Register-Variables.html https://gcc.gnu.org/onlinedocs/gcc/Size-of-an-asm.html and https://gcc.gnu.org/onlinedocs/gcc/Alternate-Keywords.html */ /* Use switch case function instead of RX INT instruction execution on stack. #define DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK */ #ifndef CCRXMACHINE2_H #define CCRXMACHINE2_H static __inline__ signed long max(signed long data1, signed long data2) __attribute__((always_inline)); static __inline__ signed long max(signed long data1, signed long data2) { /* CC-RX V2.03 MAX R2, R1 RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MAX %[R2], %[R1]" : /* OutputOperands */ [R1] "+r" (data1) : /* InputOperands */ [R2] "r" (data2) ); return data1; /* GNURX 2018q1 16 0000 FC 13 21 MAX r2, r1 22 0003 02 rts */ } static __inline__ signed long min(signed long data1, signed long data2) __attribute__((always_inline)); static __inline__ signed long min(signed long data1, signed long data2) { /* CC-RX V2.03 MIN R2, R1 RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MIN %[R2], %[R1]" : /* OutputOperands */ [R1] "+r" (data1) : /* InputOperands */ [R2] "r" (data2) ); return data1; /* GNURX 2018q1 35 0004 FC 17 21 MIN r2, r1 41 0007 02 rts */ } static __inline__ signed long revl(signed long data) __attribute__((always_inline)); static __inline__ signed long revl(signed long data) { /* CC-RX V2.03 REVL R1, R1 RTS */ __asm__ volatile ( /* AssemblerTemplate */ "REVL %[R1], %[R1]" : /* OutputOperands */ [R1] "+r" (data) ); return data; /* GNURX 2018q1 54 0008 FD 67 11 REVL r1, r1 60 000b 02 rts */ } static __inline__ signed long revw(signed long data) __attribute__((always_inline)); static __inline__ signed long revw(signed long data) { /* CC-RX V2.03 REVW R1, R1 RTS */ __asm__ volatile ( /* AssemblerTemplate */ "REVW %[R1], %[R1]" : /* OutputOperands */ [R1] "+r" (data) ); return data; /* GNURX 2018q1 73 000c FD 65 11 REVW r1, r1 79 000f 02 rts */ } static __inline__ void xchg(signed long *data1, signed long *data2) __attribute__((always_inline)); static __inline__ void xchg(signed long *data1, signed long *data2) { /* CC-RX V2.03 MOV.L [R1], R14 XCHG [R2].L, R14 MOV.L R14, [R1] RTS */ signed long temp = *data1; __asm__ volatile ( /* AssemblerTemplate */ "XCHG [%[R2]].L, %[R14]" : /* OutputOperands */ [R14] "+r" (temp) : /* InputOperands */ [R2] "r" (data2) ); *data1 = temp; return; /* GNURX 2018q1 91 0010 EC 15 mov.L [r1], r5 95 0012 06 A0 10 25 XCHG [r2].L, r5 99 0016 E3 15 mov.L r5, [r1] 100 0018 02 rts */ } static __inline__ long long rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2) __attribute__((always_inline)); static __inline__ long long rmpab(long long init, unsigned long count, signed char *addr1, signed char *addr2) { /* CC-RX V2.03 ARG init = R2:R1 ARG count = R3 ARG addr1 = R4 ARG addr2 = 04H[R0](08H[R0] after PUSH R6) RET R2:R1 PUSH.L R6 MOV.L R1, R14 MOV.L R2, R5 MOV.L 08H[R0], R2 SHAR #1FH, R5, R6 MOV.L R4, R1 MOV.L R14, R4 RMPA.B MOV.L R5, R2 MOV.L R4, R1 RTSD #04H, R6-R6 */ register signed char *r1 __asm("r1") = addr1; register signed char *r2 __asm("r2") = addr2; register unsigned long r3 __asm("r3") = count; register long long r5r4 __asm("r4") = init; register signed long r6 __asm("r6") = (signed long)(init >> 63); __asm__ volatile ( /* AssemblerTemplate */ "RMPA.B" : /* OutputOperands */ "+r" (r5r4), "+r" (r6) : /* InputOperands */ "X" (r1), "X" (r2), "X" (r3) ); return r5r4; /* GNURX 2018q1 111 0019 7E A6 push.l r6 113 001b 60 40 sub #4, r0 116 001d EF 25 mov.L r2, r5 117 001f EF 1E mov.L r1, r14 122 0021 EF 41 mov.L r4, r1 125 0023 A8 8A mov.L 12[r0], r2 128 0025 EF E4 mov.L r14, r4 131 0027 FD BF 56 shar #31, r5, r6 134 002a 7F 8C rmpa.b 139 002c EF 41 mov.L r4, r1 141 002e EF 52 mov.L r5, r2 142 0030 3F 66 02 rtsd #8, r6-r6 */ } static __inline__ long long rmpaw(long long init, unsigned long count, short *addr1, short *addr2) __attribute__((always_inline)); static __inline__ long long rmpaw(long long init, unsigned long count, short *addr1, short *addr2) { /* CC-RX V2.03 ARG init = R2:R1 ARG count = R3 ARG addr1 = R4 ARG addr2 = 04H[R0](08H[R0] after PUSH R6) RET R2:R1 PUSH.L R6 MOV.L R1, R14 MOV.L R2, R5 MOV.L 08H[R0], R2 SHAR #1FH, R5, R6 MOV.L R4, R1 MOV.L R14, R4 RMPA.W MOV.L R5, R2 MOV.L R4, R1 RTSD #04H, R6-R6 */ register short *r1 __asm("r1") = addr1; register short *r2 __asm("r2") = addr2; register unsigned long r3 __asm("r3") = count; register long long r5r4 __asm("r4") = init; register signed long r6 __asm("r6") = (signed long)(init >> 63); __asm__ volatile ( /* AssemblerTemplate */ "RMPA.W" : /* OutputOperands */ "+r" (r5r4), "+r" (r6) : /* InputOperands */ "X" (r1), "X" (r2), "X" (r3) ); return r5r4; /* GNURX 2018q1 151 0033 7E A6 push.l r6 153 0035 60 40 sub #4, r0 156 0037 EF 25 mov.L r2, r5 157 0039 EF 1E mov.L r1, r14 162 003b EF 41 mov.L r4, r1 165 003d A8 8A mov.L 12[r0], r2 168 003f EF E4 mov.L r14, r4 171 0041 FD BF 56 shar #31, r5, r6 174 0044 7F 8D RMPA.W 179 0046 EF 41 mov.L r4, r1 181 0048 EF 52 mov.L r5, r2 182 004a 3F 66 02 rtsd #8, r6-r6 */ } static __inline__ long long rmpal(long long init, unsigned long count, long *addr1, long *addr2) __attribute__((always_inline)); static __inline__ long long rmpal(long long init, unsigned long count, long *addr1, long *addr2) { /* CC-RX V2.03 ARG init = R2:R1 ARG count = R3 ARG addr1 = R4 ARG addr2 = 04H[R0](08H[R0] after PUSH R6) RET R2:R1 PUSH.L R6 MOV.L R1, R14 MOV.L R2, R5 MOV.L 08H[R0], R2 SHAR #1FH, R5, R6 MOV.L R4, R1 MOV.L R14, R4 RMPA.L MOV.L R5, R2 MOV.L R4, R1 RTSD #04H, R6-R6 */ register long *r1 __asm("r1") = addr1; register long *r2 __asm("r2") = addr2; register unsigned long r3 __asm("r3") = count; register long long r5r4 __asm("r4") = init; register signed long r6 __asm("r6") = (signed long)(init >> 63); __asm__ volatile ( /* AssemblerTemplate */ "RMPA.L" : /* OutputOperands */ "+r" (r5r4), "+r" (r6) : /* InputOperands */ "X" (r1), "X" (r2), "X" (r3) ); return r5r4; /* GNURX 2018q1 191 004d 7E A6 push.l r6 193 004f 60 40 sub #4, r0 196 0051 EF 25 mov.L r2, r5 197 0053 EF 1E mov.L r1, r14 202 0055 EF 41 mov.L r4, r1 205 0057 A8 8A mov.L 12[r0], r2 208 0059 EF E4 mov.L r14, r4 211 005b FD BF 56 shar #31, r5, r6 214 005e 7F 8E RMPA.L 219 0060 EF 41 mov.L r4, r1 221 0062 EF 52 mov.L r5, r2 222 0064 3F 66 02 rtsd #8, r6-r6 */ } static __inline__ long rolc(unsigned long data) __attribute__((always_inline)); static __inline__ long rolc(unsigned long data) { /* CC-RX V2.03 ROLC R1 RTS */ __asm__ volatile ( /* AssemblerTemplate */ "ROLC %[R1]" : /* OutputOperands */ [R1] "+r" (data) ); return data; /* GNURX 2018q1 235 0067 7E 51 ROLC r1 241 0069 02 rts */ } static __inline__ long rorc(unsigned long data) __attribute__((always_inline)); static __inline__ long rorc(unsigned long data) { /* CC-RX V2.03 RORC R1 RTS */ __asm__ volatile ( /* AssemblerTemplate */ "RORC %[R1]" : /* OutputOperands */ [R1] "+r" (data) ); return data; /* GNURX 2018q1 254 006a 7E 41 RORC r1 260 006c 02 rts */ } static __inline__ long rotl(unsigned long data, unsigned long num) __attribute__((always_inline)); static __inline__ long rotl(unsigned long data, unsigned long num) { /* CC-RX V2.03 ROTL R2, R1 RTS */ __asm__ volatile ( /* AssemblerTemplate */ "ROTL %[R2], %[R1]" : /* OutputOperands */ [R1] "+r" (data) : /* InputOperands */ [R2] "r" (num) ); return data; /* GNURX 2018q1 292 0071 FD 64 21 ROTR r2, r1 298 0074 02 rts */ } static __inline__ long rotr(unsigned long data, unsigned long num) __attribute__((always_inline)); static __inline__ long rotr(unsigned long data, unsigned long num) { /* CC-RX V2.03 ROTR R2, R1 RTS */ __asm__ volatile ( /* AssemblerTemplate */ "ROTR %[R2], %[R1]" : /* OutputOperands */ [R1] "+r" (data) : /* InputOperands */ [R2] "r" (num) ); return data; /* GNURX 2018q1 292 0071 FD 64 21 ROTR r2, r1 298 0074 02 rts */ } #ifndef brk static __inline__ void brk(void) __attribute__((always_inline)); static __inline__ void brk(void) { /* CC-RX V2.03 BRK RTS */ __asm__ volatile ( /* AssemblerTemplate */ "BRK" : /* OutputOperands */ /* No outputs. */ ); return; /* GNURX 2018q1 310 0075 00 BRK 312 0076 02 rts */ } #endif /* #ifndef brk */ #ifdef DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK void int_exception_switch_case_function(signed long num); #if 1 #define int_exception(num) \ do { \ if (__builtin_constant_p(num)) { \ __builtin_rx_int(num); \ } else { \ int_exception_switch_case_function(num); \ } \ } while (0) #else #define int_exception(num) \ do { \ if (__builtin_constant_p(num)) { \ __asm__ volatile \ ( \ /* AssemblerTemplate */ \ "INT %[NUM]" \ : /* OutputOperands */ \ /* No outputs. */ \ : /* InputOperands */ \ [NUM] "i" (num) \ ); \ } else { \ int_exception_switch_case_function(num); \ } \ } while (0) #endif #else /* DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK */ #if 1 #define int_exception(num) \ do { \ if (__builtin_constant_p(num)) { \ __builtin_rx_int(num); \ } else { \ unsigned char int_rts[] = {0x75, 0x60, num, 0x02}; \ ((void (*)(void*))int_rts)(int_rts); \ } \ } while (0) #else #define int_exception(num) \ do { \ if (__builtin_constant_p(num)) { \ __asm__ volatile \ ( \ /* AssemblerTemplate */ \ "INT %[NUM]" \ : /* OutputOperands */ \ /* No outputs. */ \ : /* InputOperands */ \ [NUM] "i" (num) \ ); \ } else { \ unsigned char int_rts[] = {0x75, 0x60, num, 0x02}; \ ((void (*)(void*))int_rts)(int_rts); \ } \ } while (0) #endif #endif /* DONT_EXECUTE_RX_INT_INSTRUCTION_ON_STACK */ #ifndef wait static __inline__ void wait(void) __attribute__((always_inline)); static __inline__ void wait(void) { /* CC-RX V2.03 WAIT RTS */ __asm__ volatile ( /* AssemblerTemplate */ "WAIT" : /* OutputOperands */ /* No outputs. */ ); return; /* GNURX 2018q1 372 0092 7F 96 WAIT 374 0094 02 rts */ } #endif /* #ifndef wait */ #ifndef nop static __inline__ void nop(void) __attribute__((always_inline)); static __inline__ void nop(void) { /* CC-RX V2.03 NOP RTS */ __asm__ volatile ( /* AssemblerTemplate */ "NOP" : /* OutputOperands */ /* No outputs. */ ); return; /* GNURX 2018q1 388 0095 03 NOP 390 0096 02 rts */ } #endif /* #ifndef nop */ static __inline__ void set_ipl(signed long level) __attribute__((always_inline)); static __inline__ void set_ipl(signed long level) { /* CC-RX V2.03 MVFC PSW, R14 SHLL #1CH, R1 SHLR #04H, R1 AND #0F0FFFFFFH, R14 OR R14, R1 MVTC R1, PSW RTS */ signed long temp; __asm__ volatile ( /* AssemblerTemplate */ "MVFC PSW, %[R14]\n\t" "SHLL #0x1C, %[R1]\n\t" "SHLR #0x04, %[R1]\n\t" "AND #0xF0FFFFFF, %[R14]\n\t" "OR %[R14], %[R1]\n\t" "MVTC %[R1], PSW" : /* OutputOperands */ [R1] "+r" (level), [R14] "=r" (temp) ); return; /* GNURX 2018q1 405 0097 FD 6A 05 MVFC PSW, r5 406 009a 6D C1 SHLL #0x1C, r1 407 009c 68 41 SHLR #0x04, r1 408 009e 74 25 FF FF FF F0 AND #0xF0FFFFFF, r5 409 00a4 57 51 OR r5, r1 410 00a6 FD 68 10 MVTC r1, PSW 413 00a9 02 rts */ } static __inline__ unsigned char get_ipl(void) __attribute__((always_inline)); static __inline__ unsigned char get_ipl(void) { /* CC-RX V2.03 MVFC PSW, R14 REVL R14, R1 AND #0FH, R1 RTS */ signed long temp; unsigned char level; __asm__ volatile ( /* AssemblerTemplate */ "MVFC PSW, %[R14]\n\t" "REVL %[R14], %[R1]\n\t" "AND #0x0F, %[R1]" : /* OutputOperands */ [R14] "=r" (temp), [R1] "=r" (level) ); return level; /* GNURX 2018q1 427 00aa FD 6A 05 MVFC PSW, r5 428 00ad FD 67 51 REVL r5, r1 429 00b0 64 F1 AND #0x0F, r1 435 00b2 5B 11 movu.B r1, r1 436 00b4 02 rts */ } static __inline__ void set_psw(unsigned long data) __attribute__((always_inline)); static __inline__ void set_psw(unsigned long data) { /* CC-RX V2.03 MVTC R1, PSW RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MVTC %[R1], PSW" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (data) ); return; /* GNURX 2018q1 449 00b5 FD 68 10 MVTC r1, PSW 451 00b8 02 rts */ } static __inline__ unsigned long get_psw(void) __attribute__((always_inline)); static __inline__ unsigned long get_psw(void) { /* CC-RX V2.03 MVFC PSW, R1 RTS */ unsigned long data; __asm__ volatile ( /* AssemblerTemplate */ "MVFC PSW, %[R1]" : /* OutputOperands */ [R1] "=r" (data) ); return data; /* GNURX 2018q1 465 00b9 FD 6A 01 MVFC PSW, r1 471 00bc 02 rts */ } static __inline__ void set_fpsw(unsigned long data) __attribute__((always_inline)); static __inline__ void set_fpsw(unsigned long data) { /* CC-RX V2.03 MVTC R1, FPSW RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MVTC %[R1], FPSW" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (data) ); return; /* GNURX 2018q1 484 00bd FD 68 13 MVTC r1, FPSW 486 00c0 02 rts */ } static __inline__ unsigned long get_fpsw(void) __attribute__((always_inline)); static __inline__ unsigned long get_fpsw(void) { /* CC-RX V2.03 MVFC FPSW, R1 RTS */ unsigned long data; __asm__ volatile ( /* AssemblerTemplate */ "MVFC FPSW, %[R1]" : /* OutputOperands */ [R1] "=r" (data) ); return data; /* GNURX 2018q1 500 00c1 FD 6A 31 MVFC FPSW, r1 506 00c4 02 rts */ } static __inline__ void set_usp(void *data) __attribute__((always_inline)); static __inline__ void set_usp(void *data) { /* CC-RX V2.03 MVTC R1, USP RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MVTC %[R1], USP" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (data) ); return; /* GNURX 2018q1 519 00c5 FD 68 12 MVTC r1, USP 521 00c8 02 rts */ } static __inline__ void *get_usp(void) __attribute__((always_inline)); static __inline__ void *get_usp(void) { /* CC-RX V2.03 MVFC USP, R1 RTS */ void *data; __asm__ volatile ( /* AssemblerTemplate */ "MVFC USP, %[R1]" : /* OutputOperands */ [R1] "=r" (data) ); return data; /* GNURX 2018q1 535 00c9 FD 6A 21 MVFC USP, r1 541 00cc 02 rts */ } static __inline__ void set_isp(void *data) __attribute__((always_inline)); static __inline__ void set_isp(void *data) { /* CC-RX V2.03 MVTC R1, ISP RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MVTC %[R1], ISP" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (data) ); return; /* GNURX 2018q1 554 00cd FD 68 1A MVTC r1, ISP 556 00d0 02 rts */ } static __inline__ void *get_isp(void) __attribute__((always_inline)); static __inline__ void *get_isp(void) { /* CC-RX V2.03 MVFC ISP, R1 RTS */ void *data; __asm__ volatile ( /* AssemblerTemplate */ "MVFC ISP, %[R1]" : /* OutputOperands */ [R1] "=r" (data) ); return data; /* GNURX 2018q1 570 00d1 FD 6A A1 MVFC ISP, r1 576 00d4 02 rts */ } static __inline__ void set_intb(void *data) __attribute__((always_inline)); static __inline__ void set_intb(void *data) { /* CC-RX V2.03 MVTC R1, INTB RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MVTC %[R1], INTB" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (data) ); return; /* GNURX 2018q1 589 00d5 FD 68 1C MVTC r1, INTB 591 00d8 02 rts */ } static __inline__ void *get_intb(void) __attribute__((always_inline)); static __inline__ void *get_intb(void) { /* CC-RX V2.03 MVFC INTB, R1 RTS */ void *data; __asm__ volatile ( /* AssemblerTemplate */ "MVFC INTB, %[R1]" : /* OutputOperands */ [R1] "=r" (data) ); return data; /* GNURX 2018q1 605 00d9 FD 6A C1 MVFC INTB, r1 611 00dc 02 rts */ } static __inline__ void set_bpsw(unsigned long data) __attribute__((always_inline)); static __inline__ void set_bpsw(unsigned long data) { /* CC-RX V2.03 MVTC R1, BPSW RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MVTC %[R1], BPSW" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (data) ); return; /* GNURX 2018q1 624 00dd FD 68 18 MVTC r1, BPSW 626 00e0 02 rts */ } static __inline__ unsigned long get_bpsw(void) __attribute__((always_inline)); static __inline__ unsigned long get_bpsw(void) { /* CC-RX V2.03 MVFC BPSW, R1 RTS */ unsigned long data; __asm__ volatile ( /* AssemblerTemplate */ "MVFC BPSW, %[R1]" : /* OutputOperands */ [R1] "=r" (data) ); return data; /* GNURX 2018q1 640 00e1 FD 6A 81 MVFC BPSW, r1 646 00e4 02 rts */ } static __inline__ void set_bpc(void *data) __attribute__((always_inline)); static __inline__ void set_bpc(void *data) { /* CC-RX V2.03 MVTC R1, BPC RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MVTC %[R1], BPC" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (data) ); return; /* GNURX 2018q1 659 00e5 FD 68 19 MVTC r1, BPC 661 00e8 02 rts */ } static __inline__ void *get_bpc(void) __attribute__((always_inline)); static __inline__ void *get_bpc(void) { /* CC-RX V2.03 MVFC BPC, R1 RTS */ void *data; __asm__ volatile ( /* AssemblerTemplate */ "MVFC BPC, %[R1]" : /* OutputOperands */ [R1] "=r" (data) ); return data; /* GNURX 2018q1 675 00e9 FD 6A 91 MVFC BPC, r1 681 00ec 02 rts */ } static __inline__ void set_fintv(void *data) __attribute__((always_inline)); static __inline__ void set_fintv(void *data) { /* CC-RX V2.03 MVTC R1, FINTV RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MVTC %[R1], FINTV" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (data) ); return; /* GNURX 2018q1 694 00ed FD 68 1B MVTC r1, FINTV 696 00f0 02 rts */ } static __inline__ void *get_fintv(void) __attribute__((always_inline)); static __inline__ void *get_fintv(void) { /* CC-RX V2.03 MVFC FINTV, R1 RTS */ void *data; __asm__ volatile ( /* AssemblerTemplate */ "MVFC FINTV, %[R1]" : /* OutputOperands */ [R1] "=r" (data) ); return data; /* GNURX 2018q1 710 00f1 FD 6A B1 MVFC FINTV, r1 716 00f4 02 rts */ } static __inline__ signed long long emul(signed long data1, signed long data2) __attribute__((always_inline)); static __inline__ signed long long emul(signed long data1, signed long data2) { /* CC-RX V2.03 MOV.L R1, R4 EMUL R2, R4 MOV.L R5, R2 MOV.L R4, R1 RTS */ return (signed long long)data1 * data2; /* GNURX 2018q1 728 00f5 FC 1B 12 emul r1, r2 733 00f8 EF 21 mov.L r2, r1 735 00fa EF 32 mov.L r3, r2 736 00fc 02 rts */ } static __inline__ unsigned long long emulu(unsigned long data1, unsigned long data2) __attribute__((always_inline)); static __inline__ unsigned long long emulu(unsigned long data1, unsigned long data2) { /* CC-RX V2.03 MOV.L R1, R4 EMULU R2, R4 MOV.L R5, R2 MOV.L R4, R1 RTS */ return (unsigned long long)data1 * data2; /* GNURX 2018q1 748 00fd FC 1F 12 emulu r1, r2 753 0100 EF 21 mov.L r2, r1 755 0102 EF 32 mov.L r3, r2 756 0104 02 rts */ } static __inline__ void chg_pmusr(void) __attribute__((always_inline)); static __inline__ void chg_pmusr(void) { /* CC-RX V2.03 MVFC PSW, R14 BTST #14H, R14 BNE L48 L47: ; entry OR #00100000H, R14 PUSH.L R14 L49: MVFC PC, R14 ADD #L48-L49, R14 PUSH.L R14 RTE L48: ; entry RTS */ signed long temp; __asm__ volatile ( /* AssemblerTemplate */ "MVFC PSW, %[R14]\n\t" "BTST #0x14, %[R14]\n\t" "BNE 3f\n" "1:\n\t" "OR #0x00100000, %[R14]\n\t" "PUSH.L %[R14]\n" "2:\n\t" "MVFC PC, %[R14]\n\t" "ADD #3f-2b, %[R14]\n\t" "PUSH.L %[R14]\n\t" "RTE\n" "3:" : /* OutputOperands */ [R14] "=r" (temp) ); return; /* GNURX 2018q1 768 0105 FD 6A 05 MVFC PSW, r5 769 0108 7D 45 BTST #0x14, r5 770 010a 21 13 BNE 3f 771 1: 772 010c 77 35 00 00 10 OR #0x00100000, r5 773 0111 7E A5 PUSH.L r5 774 2: 775 0113 FD 6A 15 MVFC PC, r5 776 0116 71 55 0A ADD #3f-2b, r5 777 0119 7E A5 PUSH.L r5 778 011b 7F 95 RTE 779 3: 783 011d 02 rts */ } static __inline__ void set_acc(signed long long data) __attribute__((always_inline)); static __inline__ void set_acc(signed long long data) { /* CC-RX V2.03 MVTACLO R1 MVTACHI R2 RTS */ signed long temp1 = (signed long)data; signed long temp2 = (signed long)(data >> 32); __asm__ volatile ( /* AssemblerTemplate */ "MVTACLO R1\n\t" "MVTACHI R2" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (temp1), [R2] "r" (temp2) ); return; /* GNURX 2018q1 797 011e FD 17 11 MVTACLO R1 798 0121 FD 17 02 MVTACHI R2 800 0124 02 rts */ } static __inline__ signed long long get_acc(void) __attribute__((always_inline)); static __inline__ signed long long get_acc(void) { /* CC-RX V2.03 MVFACMI R1 SHLL #10H, R1 MVFACHI R2 RTS */ unsigned long temp1; unsigned long temp2; __asm__ volatile ( /* AssemblerTemplate */ "MVFACMI R1\n\t" "SHLL #0x10, R1\n\t" "MVFACHI R2" : /* OutputOperands */ [R1] "=r" (temp1), [R2] "=r" (temp2) ); return (unsigned long long)((((unsigned long long)temp2) << 32) | temp1); /* GNURX 2018q1 813 0125 FD 1F 21 MVFACMI R1 814 0128 6D 01 SHLL #0x10, R1 815 012a FD 1F 02 MVFACHI R2 817 012d 02 rts */ } static __inline__ void setpsw_i(void) __attribute__((always_inline)); static __inline__ void setpsw_i(void) { /* CC-RX V2.03 SETPSW I RTS */ __asm__ volatile ( /* AssemblerTemplate */ "SETPSW I" : /* OutputOperands */ /* No outputs. */ ); return; /* GNURX 2018q1 829 012e 7F A8 SETPSW I 831 0130 02 rts */ } static __inline__ void clrpsw_i(void) __attribute__((always_inline)); static __inline__ void clrpsw_i(void) { /* CC-RX V2.03 CLRPSW I RTS */ __asm__ volatile ( /* AssemblerTemplate */ "CLRPSW I" : /* OutputOperands */ /* No outputs. */ ); return; /* GNURX 2018q1 845 0131 7F B8 CLRPSW I 847 0133 02 rts */ } static __inline__ long macl(short *data1, short *data2, unsigned long count) __attribute__((always_inline)); static __inline__ long macl(short *data1, short *data2, unsigned long count) { /* CC-RX V2.03 CMP #00H, R3 MOV.L #00000000H, R14 MULLO R14, R14 BEQ L60 L55: ; entry BTST #00H, R3 BGEU L57 L56: ; entry SUB #02H, R3 MOV.L [R1+], R14 MOV.L [R2+], R5 MACLO R14, R5 MACHI R14, R5 BNE L56 BRA L60 L57: ; entry SUB #01H, R3 BEQ L59 L58: ; entry SUB #02H, R3 MOV.L [R1+], R14 MOV.L [R2+], R5 MACLO R14, R5 MACHI R14, R5 BNE L58 L59: ; entry MOV.W [R1], R14 MOV.W [R2], R5 MACLO R14, R5 L60: ; entry MVFACMI R1 RTS */ long temp1; long temp2; long result; __asm__ volatile ( /* AssemblerTemplate */ "CMP #0x00, %[R3]\n\t" "MOV.L #0x00000000, %[R14]\n\t" "MULLO %[R14], %[R14]\n\t" "BEQ 6f\n\t" "1:\n\t" "BTST #0x00, %[R3]\n\t" "BGEU 3f\n\t" "2:\n\t" "SUB #0x02, %[R3]\n\t" "MOV.L [%[R1]+], %[R14]\n\t" "MOV.L [%[R2]+], %[R5]\n\t" "MACLO %[R14], %[R5]\n\t" "MACHI %[R14], %[R5]\n\t" "BNE 2b\n\t" "BRA 6f\n\t" "3:\n\t" "SUB #0x01, %[R3]\n\t" "BEQ 5f\n\t" "4:\n\t" "SUB #0x02, %[R3]\n\t" "MOV.L [%[R1]+], %[R14]\n\t" "MOV.L [%[R2]+], %[R5]\n\t" "MACLO %[R14], %[R5]\n\t" "MACHI %[R14], %[R5]\n\t" "BNE 4b\n\t" "5:\n\t" "MOV.W [%[R1]], %[R14]\n\t" "MOV.W [%[R2]], %[R5]\n\t" "MACLO %[R14], %[R5]\n\t" "6:\n\t" "MVFACMI %[R99]" : /* OutputOperands */ [R5] "+r" (temp1), [R14] "+r" (temp2), [R99] "=r" (result) : /* InputOperands */ [R1] "r" (data1), [R2] "r" (data2), [R3] "r" (count) ); return result; /* GNURX 2018q1 859 0134 66 05 mov.L #0, r5 860 0136 EF 54 mov.L r5, r4 862 0138 61 03 CMP #0x00, r3 863 013a 66 04 MOV.L #0x00000000, r4 864 013c FD 01 44 MULLO r4, r4 865 013f 20 33 BEQ 6f 866 1: 867 0141 7C 03 BTST #0x00, r3 868 0143 22 14 BGEU 3f 869 2: 870 0145 60 23 SUB #0x02, r3 871 0147 FD 2A 14 MOV.L [r1+], r4 872 014a FD 2A 25 MOV.L [r2+], r5 873 014d FD 05 45 MACLO r4, r5 874 0150 FD 04 45 MACHI r4, r5 875 0153 21 F2 BNE 2b 876 0155 2E 1D BRA 6f 877 3: 878 0157 60 13 SUB #0x01, r3 879 0159 20 12 BEQ 5f 880 4: 881 015b 60 23 SUB #0x02, r3 882 015d FD 2A 14 MOV.L [r1+], r4 883 0160 FD 2A 25 MOV.L [r2+], r5 884 0163 FD 05 45 MACLO r4, r5 885 0166 FD 04 45 MACHI r4, r5 886 0169 21 F2 BNE 4b 887 5: 888 016b DC 14 MOV.W [r1], r4 889 016d DC 25 MOV.W [r2], r5 890 016f FD 05 45 MACLO r4, r5 891 6: 892 0172 FD 1F 21 MVFACMI r1 895 0175 02 rts */ } static __inline__ short macw1(short *data1, short *data2, unsigned long count) __attribute__((always_inline)); static __inline__ short macw1(short *data1, short *data2, unsigned long count) { /* CC-RX V2.03 CMP #00H, R3 MOV.L #00000000H, R14 MULLO R14, R14 BEQ L67 L62: ; entry BTST #00H, R3 BGEU L64 L63: ; entry SUB #02H, R3 MOV.L [R1+], R14 MOV.L [R2+], R5 MACLO R14, R5 MACHI R14, R5 BNE L63 BRA L67 L64: ; entry SUB #01H, R3 BEQ L66 L65: ; entry SUB #02H, R3 MOV.L [R1+], R14 MOV.L [R2+], R5 MACLO R14, R5 MACHI R14, R5 BNE L65 L66: ; entry MOV.W [R1], R14 MOV.W [R2], R5 MACLO R14, R5 L67: ; entry RACW #01H MVFACHI R1 RTS */ long temp1; long temp2; short result; __asm__ volatile ( /* AssemblerTemplate */ "CMP #0x00, %[R3]\n\t" "MOV.L #0x00000000, %[R14]\n\t" "MULLO %[R14], %[R14]\n\t" "BEQ 6f\n\t" "1:\n\t" "BTST #0x00, %[R3]\n\t" "BGEU 3f\n\t" "2:\n\t" "SUB #0x02, %[R3]\n\t" "MOV.L [%[R1]+], %[R14]\n\t" "MOV.L [%[R2]+], %[R5]\n\t" "MACLO %[R14], %[R5]\n\t" "MACHI %[R14], %[R5]\n\t" "BNE 2b\n\t" "BRA 6f\n\t" "3:\n\t" "SUB #0x01, %[R3]\n\t" "BEQ 5f\n\t" "4:\n\t" "SUB #0x02, %[R3]\n\t" "MOV.L [%[R1]+], %[R14]\n\t" "MOV.L [%[R2]+], %[R5]\n\t" "MACLO %[R14], %[R5]\n\t" "MACHI %[R14], %[R5]\n\t" "BNE 4b\n\t" "5:\n\t" "MOV.W [%[R1]], %[R14]\n\t" "MOV.W [%[R2]], %[R5]\n\t" "MACLO %[R14], %[R5]\n\t" "6:\n\t" "RACW #0x01\n\t" "MVFACMI %[R99]" : /* OutputOperands */ [R5] "+r" (temp1), [R14] "+r" (temp2), [R99] "=r" (result) : /* InputOperands */ [R1] "r" (data1), [R2] "r" (data2), [R3] "r" (count) ); return result; /* GNURX 2018q1 907 0176 66 05 mov.L #0, r5 908 0178 EF 54 mov.L r5, r4 910 017a 61 03 CMP #0x00, r3 911 017c 66 04 MOV.L #0x00000000, r4 912 017e FD 01 44 MULLO r4, r4 913 0181 20 33 BEQ 6f 914 1: 915 0183 7C 03 BTST #0x00, r3 916 0185 22 14 BGEU 3f 917 2: 918 0187 60 23 SUB #0x02, r3 919 0189 FD 2A 14 MOV.L [r1+], r4 920 018c FD 2A 25 MOV.L [r2+], r5 921 018f FD 05 45 MACLO r4, r5 922 0192 FD 04 45 MACHI r4, r5 923 0195 21 F2 BNE 2b 924 0197 2E 1D BRA 6f 925 3: 926 0199 60 13 SUB #0x01, r3 927 019b 20 12 BEQ 5f 928 4: 929 019d 60 23 SUB #0x02, r3 930 019f FD 2A 14 MOV.L [r1+], r4 931 01a2 FD 2A 25 MOV.L [r2+], r5 932 01a5 FD 05 45 MACLO r4, r5 933 01a8 FD 04 45 MACHI r4, r5 934 01ab 21 F2 BNE 4b 935 5: 936 01ad DC 14 MOV.W [r1], r4 937 01af DC 25 MOV.W [r2], r5 938 01b1 FD 05 45 MACLO r4, r5 939 6: 940 01b4 FD 18 00 RACW #0x01 941 01b7 FD 1F 21 MVFACMI r1 947 01ba DF 11 mov.W r1, r1 948 01bc 02 rts */ } static __inline__ short macw2(short *data1, short *data2, unsigned long count) __attribute__((always_inline)); static __inline__ short macw2(short *data1, short *data2, unsigned long count) { /* CC-RX V2.03 CMP #00H, R3 MOV.L #00000000H, R14 MULLO R14, R14 BEQ L74 L69: ; entry BTST #00H, R3 BGEU L71 L70: ; entry SUB #02H, R3 MOV.L [R1+], R14 MOV.L [R2+], R5 MACLO R14, R5 MACHI R14, R5 BNE L70 BRA L74 L71: ; entry SUB #01H, R3 BEQ L73 L72: ; entry SUB #02H, R3 MOV.L [R1+], R14 MOV.L [R2+], R5 MACLO R14, R5 MACHI R14, R5 BNE L72 L73: ; entry MOV.W [R1], R14 MOV.W [R2], R5 MACLO R14, R5 L74: ; entry RACW #02H MVFACHI R1 RTS */ long temp1; long temp2; short result; __asm__ volatile ( /* AssemblerTemplate */ "CMP #0x00, %[R3]\n\t" "MOV.L #0x00000000, %[R14]\n\t" "MULLO %[R14], %[R14]\n\t" "BEQ 6f\n\t" "1:\n\t" "BTST #0x00, %[R3]\n\t" "BGEU 3f\n\t" "2:\n\t" "SUB #0x02, %[R3]\n\t" "MOV.L [%[R1]+], %[R14]\n\t" "MOV.L [%[R2]+], %[R5]\n\t" "MACLO %[R14], %[R5]\n\t" "MACHI %[R14], %[R5]\n\t" "BNE 2b\n\t" "BRA 6f\n\t" "3:\n\t" "SUB #0x01, %[R3]\n\t" "BEQ 5f\n\t" "4:\n\t" "SUB #0x02, %[R3]\n\t" "MOV.L [%[R1]+], %[R14]\n\t" "MOV.L [%[R2]+], %[R5]\n\t" "MACLO %[R14], %[R5]\n\t" "MACHI %[R14], %[R5]\n\t" "BNE 4b\n\t" "5:\n\t" "MOV.W [%[R1]], %[R14]\n\t" "MOV.W [%[R2]], %[R5]\n\t" "MACLO %[R14], %[R5]\n\t" "6:\n\t" "RACW #02H\n\t" "MVFACMI %[R99]" : /* OutputOperands */ [R5] "+r" (temp1), [R14] "+r" (temp2), [R99] "=r" (result) : /* InputOperands */ [R1] "r" (data1), [R2] "r" (data2), [R3] "r" (count) ); return result; /* GNURX 2018q1 960 01bd 66 05 mov.L #0, r5 961 01bf EF 54 mov.L r5, r4 963 01c1 61 03 CMP #0x00, r3 964 01c3 66 04 MOV.L #0x00000000, r4 965 01c5 FD 01 44 MULLO r4, r4 966 01c8 20 33 BEQ 6f 967 1: 968 01ca 7C 03 BTST #0x00, r3 969 01cc 22 14 BGEU 3f 970 2: 971 01ce 60 23 SUB #0x02, r3 972 01d0 FD 2A 14 MOV.L [r1+], r4 973 01d3 FD 2A 25 MOV.L [r2+], r5 974 01d6 FD 05 45 MACLO r4, r5 975 01d9 FD 04 45 MACHI r4, r5 976 01dc 21 F2 BNE 2b 977 01de 2E 1D BRA 6f 978 3: 979 01e0 60 13 SUB #0x01, r3 980 01e2 20 12 BEQ 5f 981 4: 982 01e4 60 23 SUB #0x02, r3 983 01e6 FD 2A 14 MOV.L [r1+], r4 984 01e9 FD 2A 25 MOV.L [r2+], r5 985 01ec FD 05 45 MACLO r4, r5 986 01ef FD 04 45 MACHI r4, r5 987 01f2 21 F2 BNE 4b 988 5: 989 01f4 DC 14 MOV.W [r1], r4 990 01f6 DC 25 MOV.W [r2], r5 991 01f8 FD 05 45 MACLO r4, r5 992 6: 993 01fb FD 18 10 RACW #02H 994 01fe FD 1F 21 MVFACMI r1 1000 0201 DF 11 mov.W r1, r1 1001 0203 02 rts */ } static __inline__ void set_extb(void *data) __attribute__((always_inline)); static __inline__ void set_extb(void *data) { /* CC-RX V2.03 MVTC R1, EXTB RTS */ __asm__ volatile ( /* AssemblerTemplate */ "MVTC %[R1], EXTB" : /* OutputOperands */ /* No outputs. */ : /* InputOperands */ [R1] "r" (data) ); return; /* GNURX 2018q1 1014 0204 FD 68 1D MVTC r1, EXTB 1016 0207 02 rts */ } static __inline__ void *get_extb(void) __attribute__((always_inline)); static __inline__ void *get_extb(void) { /* CC-RX V2.03 MVFC EXTB, R1 RTS */ void *data; __asm__ volatile ( /* AssemblerTemplate */ "MVFC EXTB, %[R1]" : /* OutputOperands */ [R1] "=r" (data) ); return data; /* GNURX 2018q1 1030 0208 FD 6A D1 MVFC EXTB, r1 1036 020b 02 rts */ } #endif /* CCRXMACHINE2_H */