-
The Pico code is for a Cortex M0+ and what you have in your snippet is incomplete.
The correct code for a Cortex M4 is this (from assembled+disassembled libgcc, corrected to return the result in S0 instead of R0, since the compiler ignores the softfp ABI for functions in the same compilation unit, apparently):let c = E.compiledC(` // int boop(double) extern "C" float __attribute__((naked)) d2f(double) {__asm__ volatile(R"( mov.w r2, r1, lsl 1 subs.w r3, r2, 0x70000000 itt cs subscs.w ip, r3, 0x200000 rsbscs ip, ip, 0x1fc00000 bls.n 2f 1: and.w ip, r1, 0x80000000 mov.w r2, r0, lsl 3 orr.w r0, ip, r0, lsr 29 cmp.w r2, 0x80000000 adc.w r0, r0, r3, lsl 2 it eq biceq.w r0, r0, 1 b 6f 2: tst.w r1, 0x40000000 bne.n 3f adds.w r2, r3, 0x2e00000 itt lt andlt.w r0, r1, 0x80000000 blt 6f orr.w r1, r1, 0x100000 mov.w r2, r2, lsr 21 rsb r2, r2, 24 rsb ip, r2, 32 lsls.w r3, r0, ip lsr.w r0, r0, r2 it ne orrne.w r0, r0, 1 mov.w r3, r1, lsl 11 mov.w r3, r3, lsr 11 lsl.w ip, r3, ip orr.w r0, r0, ip lsr.w r3, r3, r2 mov.w r3, r3, lsl 1 b.n 1b 3: mvns.w r3, r2, asr 21 bne.n 5f orrs.w r3, r0, r1, lsl 12 ittt ne movne.w r0, 0x7f000000 orrne.w r0, r0, 0xc00000 bne 6f 5: and.w r0, r1, 0x80000000 orr.w r0, r0, 0x7f000000 orr.w r0, r0, 0x800000 6: vmov s0, r0 bx lr nop )");} int boop(double d) { return d2f(d) * 3; } `); print('boop:', c.boop(3.5)); // 3.5 * 3 = 10.5 cast to int = 10
Note that you have to call the function explicitly, I couldn't use a float cast and get it to link as __aeabi_d2f. It might work if we compile the assembly into a library and then link to that. If one were to go that far, might as well link to libgcc and let the linker throw away all the stuff that isn't used.
-
since the compiler ignores the softfp ABI for functions in the same compilation unit, apparently
why do you think so?
and btw it is possible to set calling convention per method via attributes and when calling one from another it works https://gist.github.com/fanoush/85ebe50c5c4a54ca15bf2867e27f7cd3 (EDIT: or for cortex m4 here https://gist.github.com/fanoush/0da3e47aee9e20fb11b010cc3aa4e16e )
But anyway, why to use doubles? Cortex M4F can do only floats in hardware, isn't this enough for most stuff discussed here?
I was hoping I could add the following to E.compiledC, but even after accounting for the double-escaping, I'm not having success :
If you have any luck, please let me know!