You are reading a single comment by @FManga and its replies. Click here to read the full conversation.
  • I was hoping I could add the following to E.compiledC, but even after accounting for the double-escaping, I'm not having success :

    float __attribute__((naked)) __aeabi_d2f(double d) {__asm__ volatile(
        "lsrs r0, #30\n\t"
        "lsls r2, r1, #12\n\t"
        "lsrs r2, #9\n\t"
        "asrs r1, #22\n\t"
        "lsls r1, #22\n\t"
        "orrs r0, r1\n\t"
        "orrs r0, r2\n\t"
        "bx lr"
    double __attribute__((naked)) __aeabi_f2d(float f) {__asm__ volatile(
        "asrs r1, r0, #3\n\t"
        "movs r2, [#0xf](­/?q=%230xf)\n\t"
        "lsls r2, #27\n\t"
        "orrs r1, r2\n\t"
        "lsls r0, #25\n\t"
        "bx lr"

    If you have any luck, please let me know!

  • 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
     	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
     	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
     	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
     	and.w	r0, r1, 0x80000000
     	orr.w	r0, r0, 0x7f000000
     	orr.w	r0, r0, 0x800000
      vmov s0, r0
     	bx	lr
    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.


Avatar for FManga @FManga started