#define FUNCTION_MARKER "mov r0, r0\n" \ "mov r1, r1\n" \ "mov r2, r2\n" #if EEL_F_SIZE == 8 __attribute__((naked)) void nseel_asm_1pdd(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "str lr, [sp, #-8]!\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_2pdd(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "fcpyd d2, d0\n" "fcpyd d0, d1\n" "fcpyd d1, d2\n" "str lr, [sp, #-8]!\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); }; __attribute__((naked)) void nseel_asm_2pdds(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "push {r1, lr}\n" "fcpyd d1, d0\n" "fldd d0, [r1]\n" "blx r3\n" "pop {r0, lr}\n" "fstd d0, [r0]\n" FUNCTION_MARKER :: ); } #else // 32 bit floating point calls #error no 32 bit float support #endif //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_invsqrt(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r0, 0x59df\n" "movt r0, 0x5f37\n" "fcvtsd s2, d0\n" "fldd d3, [r6, #32]\n" "fmrs r1, s2\n" "fmuld d0, d0, d3\n" "mov r1, r1, asr #1\n" "sub r0, r0, r1\n" "fmsr s4, r0\n" "fcvtds d1, s4\n" "fldd d2, [r6, #40]\n" "fmuld d0, d0, d1\n" "fmuld d0, d0, d1\n" "faddd d0, d0, d2\n" "fmuld d0, d0, d1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_dbg_getstackptr(void) { __asm__ __volatile__( FUNCTION_MARKER "fmsr s0, sp\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_sqr(void) { __asm__ __volatile__( FUNCTION_MARKER "fmuld d0, d0, d0\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_abs(void) { __asm__ __volatile__( FUNCTION_MARKER "fabsd d0, d0\n" FUNCTION_MARKER ); } #define FLUSH_TO_ZERO \ "ldr r1, [r0, #4]\n" \ "movs r2, #0\n" \ "movt r2, #0x7ff0\n" \ "add r1, r1, #0x00100000\n" \ "ands r1, r1, r2\n" \ "cmp r1, #0x00200000\n" \ "bgt 0f\n" \ "movs r2, #0\n" \ "movs r3, #0\n" \ "strd r2, [r0]\n" \ "0:\n" //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_assign(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "mov r0, r1\n" "fstd d0, [r1]\n" FLUSH_TO_ZERO FUNCTION_MARKER ); } // //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_assign_fromfp(void) { __asm__ __volatile__( FUNCTION_MARKER "mov r0, r1\n" "fstd d0, [r1]\n" FLUSH_TO_ZERO FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_assign_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } // //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_assign_fast_fromfp(void) { __asm__ __volatile__( FUNCTION_MARKER "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_add(void) { __asm__ __volatile__( FUNCTION_MARKER "faddd d0, d1, d0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_add_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "faddd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FLUSH_TO_ZERO FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_add_op_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "faddd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_sub(void) { __asm__ __volatile__( FUNCTION_MARKER "fsubd d0, d1, d0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_sub_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fsubd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FLUSH_TO_ZERO FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_sub_op_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fsubd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_mul(void) { __asm__ __volatile__( FUNCTION_MARKER "fmuld d0, d0, d1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_mul_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fmuld d0, d0, d1\n" "mov r0, r1\n" "fstd d0, [r1]\n" FLUSH_TO_ZERO FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_mul_op_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fmuld d0, d0, d1\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_div(void) { __asm__ __volatile__( FUNCTION_MARKER "fdivd d0, d1, d0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_div_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fdivd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FLUSH_TO_ZERO FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_div_op_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "fdivd d0, d1, d0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_mod(void) { __asm__ __volatile__( FUNCTION_MARKER "ftouizd s0, d0\n" // round to unsigned integers "fmrs r3, s0\n" "fuitod d0, s0\n" // divisor "ftouizd s2, d1\n" "cmp r3, #0\n" "beq 0f\n" "fuitod d1, s2\n" // value "fdivd d2, d1, d0\n" "ftouizd s4, d2\n" "fuitod d2, s4\n" "fmuld d2, d2, d0\n" "fsubd d0, d1, d2\n" "0:\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_shl(void) { __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "mov r3, r2, asl r3\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_shr(void) { __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "mov r3, r2, asr r3\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_mod_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftouizd s0, d0\n" // round to unsigned integers "fmrs r3, s0\n" "fuitod d0, s0\n" // divisor "ftouizd s2, d1\n" "cmp r3, #0\n" "beq 0f\n" "fuitod d1, s2\n" // value "fdivd d2, d1, d0\n" "ftouizd s4, d2\n" "fuitod d2, s4\n" "fmuld d2, d2, d0\n" "fsubd d0, d1, d2\n" "0:\n" "mov r0, r1\n" "fstd d0, [r1]\n" FLUSH_TO_ZERO FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_or(void) { __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "orr r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_or0(void) { __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_or_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "orr r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_xor(void) { __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "eor r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_xor_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "eor r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_and(void) { __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "and r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" FUNCTION_MARKER );} __attribute__((naked)) void nseel_asm_and_op(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r1]\n" "ftosizd s0, d0\n" "ftosizd s1, d1\n" "fmrs r3, s0\n" "fmrs r2, s1\n" "and r3, r3, r2\n" "fmsr s0, r3\n" "fsitod d0, s0\n" "mov r0, r1\n" "fstd d0, [r1]\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_uminus(void) { __asm__ __volatile__( FUNCTION_MARKER "fnegd d0, d0\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_sign(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpzd d0\n" "fmstat\n" "flddgt d0, [r6, #16]\n" "flddlt d0, [r6, #24]\n" FUNCTION_MARKER :: ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_bnot(void) { __asm__ __volatile__( FUNCTION_MARKER "cmp r0, #0\n" "movne r0, #0\n" "moveq r0, #1\n" FUNCTION_MARKER ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_if(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "movw r1, 0xdead\n" "movt r1, 0xbeef\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "cmp r0, #0\n" "moveq r1, r2\n" "blx r1\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_repeat(void) { #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "fmrs r3, s0\n" "cmp r3, #0\n" "ble 0f\n" "movw r2, %0\n" "movt r2, %1\n" "cmp r3, r2\n" "movgt r3, r2\n" "push {r10,lr}\n" "movw r10, 0xdead\n" "movt r10, 0xbeef\n" "1:\n" "push {r3,r5}\n" // save counter + worktable "blx r10\n" "pop {r3,r5}\n" "sub r3, r3, #1\n" "cmp r3, #0\n" "bgt 1b\n" "pop {r10,lr}\n" "0:\n" FUNCTION_MARKER ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN&65535), "g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN>>16) ); #else __asm__ __volatile__( FUNCTION_MARKER "ftosizd s0, d0\n" "fmrs r3, s0\n" "cmp r3, #0\n" "ble 0f\n" "push {r10,lr}\n" "movw r10, 0xdead\n" "movt r10, 0xbeef\n" "1:\n" "push {r3,r5}\n" // save counter + worktable "blx r10\n" "pop {r3,r5}\n" "sub r3, r3, #1\n" "cmp r3, #0\n" "bgt 1b\n" "pop {r10,lr}\n" "0:\n" FUNCTION_MARKER ); #endif } __attribute__((naked)) void nseel_asm_repeatwhile(void) { #if NSEEL_LOOPFUNC_SUPPORT_MAXLEN > 0 __asm__ __volatile__( FUNCTION_MARKER "movw r3, %0\n" "movt r3, %1\n" "push {r10,lr}\n" "movw r10, 0xdead\n" "movt r10, 0xbeef\n" "0:\n" "push {r3,r5}\n" // save counter + worktable "blx r10\n" "pop {r3,r5}\n" "sub r3, r3, #1\n" "cmp r0, #0\n" "cmpne r3, #0\n" "bne 0b\n" "pop {r10,lr}\n" FUNCTION_MARKER ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN&65535), "g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN>>16) ); #else __asm__ __volatile__( FUNCTION_MARKER "push {r10,lr}\n" "movw r10, 0xdead\n" "movt r10, 0xbeef\n" "0:\n" "push {r3,r5}\n" // save worktable (r3 just for alignment) "blx r10\n" "pop {r3,r5}\n" "cmp r0, #0\n" "bne 0b\n" "pop {r10,lr}\n" "0:\n" FUNCTION_MARKER ); #endif } __attribute__((naked)) void nseel_asm_band(void) { __asm__ __volatile__( FUNCTION_MARKER "cmp r0, #0\n" "beq 0f\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "push {r3, lr}\n" "blx r3\n" "pop {r3, lr}\n" "0:\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_bor(void) { __asm__ __volatile__( FUNCTION_MARKER "cmp r0, #0\n" "bne 0f\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "push {r3, lr}\n" "blx r3\n" "pop {r3, lr}\n" "0:\n" FUNCTION_MARKER :: ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_equal(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d2, [r6]\n" "fsubd d0, d0, d1\n" "fabsd d0, d0\n" "fcmpd d2, d0\n" "fmstat\n" "movlt r0, #0\n" "movge r0, #1\n" FUNCTION_MARKER :: ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_equal_exact(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpd d0, d1\n" "fmstat\n" "movne r0, #0\n" "moveq r0, #1\n" FUNCTION_MARKER :: ); } // //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_notequal_exact(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpd d0, d1\n" "fmstat\n" "moveq r0, #0\n" "movne r0, #1\n" FUNCTION_MARKER :: ); } // // // //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_notequal(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d2, [r6]\n" "fsubd d0, d0, d1\n" "fabsd d0, d0\n" "fcmpd d2, d0\n" "fmstat\n" "movlt r0, #1\n" "movge r0, #0\n" FUNCTION_MARKER :: ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_below(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpd d1, d0\n" "fmstat\n" "movlt r0, #1\n" "movge r0, #0\n" FUNCTION_MARKER :: ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_beloweq(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpd d1, d0\n" "fmstat\n" "movle r0, #1\n" "movgt r0, #0\n" FUNCTION_MARKER :: ); } //--------------------------------------------------------------------------------------------------------------- __attribute__((naked)) void nseel_asm_above(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpd d1, d0\n" "fmstat\n" "movgt r0, #1\n" "movle r0, #0\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_aboveeq(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpd d1, d0\n" "fmstat\n" "movge r0, #1\n" "movlt r0, #0\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_min(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "movlt r0, r1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_max(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "fldd d1, [r1]\n" "fcmpd d1, d0\n" "fmstat\n" "movge r0, r1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_min_fp(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpd d1, d0\n" "fmstat\n" "fcpydlt d0, d1\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_max_fp(void) { __asm__ __volatile__( FUNCTION_MARKER "fcmpd d1, d0\n" "fmstat\n" "fcpydge d0, d1\n" FUNCTION_MARKER ); } __attribute__((naked)) void _asm_generic3parm(void) { __asm__ __volatile__( FUNCTION_MARKER "push {r4, lr}\n" // input: r0 last, r1=second to last, r2=third to last // output: r0=context, r1=r2, r2=r1, r3=r0 "mov r3, r0\n" // r0 (last parameter) -> r3 "mov r4, r1\n" // r1 (second to last parameter) r1->r4->r2 "movw r0, 0xdead\n" // r0 is first parm (context) "movt r0, 0xbeef\n" "mov r1, r2\n" // r2->r1 "mov r2, r4\n" // r1->r2 "movw r4, 0xdead\n" "movt r4, 0xbeef\n" "blx r4\n" "pop {r4, lr}\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic3parm_retd(void) { __asm__ __volatile__( FUNCTION_MARKER "push {r4, lr}\n" // input: r0 last, r1=second to last, r2=third to last // output: r0=context, r1=r2, r2=r1, r3=r0 "mov r3, r0\n" // r0 (last parameter) -> r3 "mov r4, r1\n" // r1 (second to last parameter) r1->r4->r2 "movw r0, 0xdead\n" // r0 is first parm (context) "movt r0, 0xbeef\n" "mov r1, r2\n" // r2->r1 "mov r2, r4\n" // r1->r2 "movw r4, 0xdead\n" "movt r4, 0xbeef\n" "blx r4\n" "pop {r4, lr}\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic2parm(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "mov r2, r0\n" // r0 -> r2, r1-r1, "movw r0, 0xdead\n" // r0 is first parm "movt r0, 0xbeef\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic2parm_retd(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "mov r2, r0\n" // r0 -> r2, r1-r1, "movw r0, 0xdead\n" // r0 is first parm "movt r0, 0xbeef\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic2xparm_retd(void) { __asm__ __volatile__( FUNCTION_MARKER "push {r4, lr}\n" "mov r3, r0\n" // r0 is last parameter "mov r2, r1\n" // "movw r0, 0xdead\n" // r0 is ctx "movt r0, 0xbeef\n" "movw r1, 0xdead\n" // r1 is second ctx "movt r1, 0xbeef\n" "movw r4, 0xdead\n" "movt r4, 0xbeef\n" "blx r4\n" "pop {r4, lr}\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic1parm(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "mov r1, r0\n" // r0 -> r1 "movw r0, 0xdead\n" // r0 is first parm "movt r0, 0xbeef\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_generic1parm_retd(void) { __asm__ __volatile__( FUNCTION_MARKER "str lr, [sp, #-8]!\n" "mov r1, r0\n" // r0 -> r1 "movw r0, 0xdead\n" // r0 is first parm "movt r0, 0xbeef\n" "movw r3, 0xdead\n" "movt r3, 0xbeef\n" "blx r3\n" "ldr lr, [sp], #8\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void _asm_megabuf(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r7, #-8]\n" "faddd d0, d0, d1\n" "ftouizd s0, d0\n" "fmrs r3, s0\n" // r3 is slot index "mov r2, r3, asr %0\n" "bic r2, r2, #3\n" // r2 is page index*4 "cmp r2, %1\n" "bhs 0f\n" "add r2, r2, r7\n" "ldr r2, [r2]\n" "cmp r2, #0\n" "beq 0f\n" "movw r0, %2\n" "and r3, r3, r0\n" // r3 mask item in slot "add r0, r2, r3, asl #3\n" // set result "b 1f\n" "0:\n" // failed, call stub function "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "str lr, [sp, #-8]!\n" "mov r0, r7\n" // first parameter: blocks "mov r1, r3\n" // second parameter: slot index "blx r2\n" "ldr lr, [sp], #8\n" "1:\n" FUNCTION_MARKER :: "i" (NSEEL_RAM_ITEMSPERBLOCK_LOG2 - 2/*log2(sizeof(void*))*/), "i" (NSEEL_RAM_BLOCKS*4 /*(sizeof(void*))*/), "i" (NSEEL_RAM_ITEMSPERBLOCK-1) ); } __attribute__((naked)) void _asm_gmegabuf(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r0, 0xdead\n" "movt r0, 0xbeef\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "fldd d1, [r7, #-8]\n" "faddd d0, d0, d1\n" "ftouizd s0, d0\n" "fmrs r1, s0\n" // r1 is slot index "push {r4, lr}\n" "blx r2\n" "pop {r4, lr}\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_fcall(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r0, 0xdead\n" "movt r0, 0xbeef\n" "push {r4, lr}\n" "blx r0\n" "pop {r4, lr}\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_push(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d0, [r0]\n" "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r0, [r3]\n" "add r0, r0, #8\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "and r0, r0, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r0, r0, r2\n" "str r0, [r3]\n" "fstd d0, [r0]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_pop(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r1, [r3]\n" "fldd d0, [r1]\n" "sub r1, r1, #8\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "fstd d0, [r0]\n" "and r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r1, r1, r2\n" "str r1, [r3]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_pop_fast(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r1, [r3]\n" "mov r0, r1\n" "sub r1, r1, #8\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "and r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r1, r1, r2\n" "str r1, [r3]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_peek(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ftosizd s0, d0\n" "fmrs r2, s0\n" // r2 is index in stack "ldr r1, [r3]\n" "sub r1, r1, r2, asl #3\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "and r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r0, r1, r2\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_peek_top(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r0, [r3]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_peek_int(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "movw r2, 0xdead\n" // r3 is stack "movt r2, 0xbeef\n" "ldr r1, [r3]\n" "sub r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "and r1, r1, r2\n" "movw r2, 0xdead\n" "movt r2, 0xbeef\n" "orr r0, r1, r2\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_stack_exch(void) { __asm__ __volatile__( FUNCTION_MARKER "movw r3, 0xdead\n" // r3 is stack "movt r3, 0xbeef\n" "ldr r1, [r3]\n" "fldd d0, [r0]\n" "fldd d1, [r1]\n" "fstd d0, [r1]\n" "fstd d1, [r0]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_booltofp(void) { __asm__ __volatile__( FUNCTION_MARKER "cmp r0, #0\n" "flddne d0, [r6, #16]\n" "flddeq d0, [r6, #8]\n" FUNCTION_MARKER ); } __attribute__((naked)) void nseel_asm_fptobool(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r6]\n" "fabsd d0, d0\n" "fcmpd d0, d1\n" "fmstat\n" "movgt r0, #1\n" "movlt r0, #0\n" FUNCTION_MARKER :: ); } __attribute__((naked)) void nseel_asm_fptobool_rev(void) { __asm__ __volatile__( FUNCTION_MARKER "fldd d1, [r6]\n" "fabsd d0, d0\n" "fcmpd d0, d1\n" "fmstat\n" "movgt r0, #0\n" "movlt r0, #1\n" FUNCTION_MARKER :: ); }