Replacing memcpy and .divsi3_skip_div0_test with smaller code on ARM MCU

228 views Asked by At

My entry for https://hackaday.com/2016/11/21/step-up-to-the-1-kb-challenge/ includes a couple of huge functions which are not generated from any C code which I have written.

000004e4 <.divsi3_skip_div0_test>:
 4e4:   b410        push    {r4}
 4e6:   1c04        adds    r4, r0, #0
 4e8:   404c        eors    r4, r1
 4ea:   46a4        mov ip, r4
 4ec:   2301        movs    r3, #1
 4ee:   2200        movs    r2, #0
 4f0:   2900        cmp r1, #0
 4f2:   d500        bpl.n   4f6 <.divsi3_skip_div0_test+0x12>
 4f4:   4249        negs    r1, r1
 4f6:   2800        cmp r0, #0
 4f8:   d500        bpl.n   4fc <.divsi3_skip_div0_test+0x18>
 4fa:   4240        negs    r0, r0
 4fc:   4288        cmp r0, r1
 4fe:   d32c        bcc.n   55a <.divsi3_skip_div0_test+0x76>
 500:   2401        movs    r4, #1
 502:   0724        lsls    r4, r4, #28
 504:   42a1        cmp r1, r4
 506:   d204        bcs.n   512 <.divsi3_skip_div0_test+0x2e>
 508:   4281        cmp r1, r0
 50a:   d202        bcs.n   512 <.divsi3_skip_div0_test+0x2e>
 50c:   0109        lsls    r1, r1, #4
 50e:   011b        lsls    r3, r3, #4
 510:   e7f8        b.n 504 <.divsi3_skip_div0_test+0x20>
 512:   00e4        lsls    r4, r4, #3
 514:   42a1        cmp r1, r4
 516:   d204        bcs.n   522 <.divsi3_skip_div0_test+0x3e>
 518:   4281        cmp r1, r0
 51a:   d202        bcs.n   522 <.divsi3_skip_div0_test+0x3e>
 51c:   0049        lsls    r1, r1, #1
 51e:   005b        lsls    r3, r3, #1
 520:   e7f8        b.n 514 <.divsi3_skip_div0_test+0x30>
 522:   4288        cmp r0, r1
 524:   d301        bcc.n   52a <.divsi3_skip_div0_test+0x46>
 526:   1a40        subs    r0, r0, r1
 528:   431a        orrs    r2, r3
 52a:   084c        lsrs    r4, r1, #1
 52c:   42a0        cmp r0, r4
 52e:   d302        bcc.n   536 <.divsi3_skip_div0_test+0x52>
 530:   1b00        subs    r0, r0, r4
 532:   085c        lsrs    r4, r3, #1
 534:   4322        orrs    r2, r4
 536:   088c        lsrs    r4, r1, #2
 538:   42a0        cmp r0, r4
 53a:   d302        bcc.n   542 <.divsi3_skip_div0_test+0x5e>
 53c:   1b00        subs    r0, r0, r4
 53e:   089c        lsrs    r4, r3, #2
 540:   4322        orrs    r2, r4
 542:   08cc        lsrs    r4, r1, #3
 544:   42a0        cmp r0, r4
 546:   d302        bcc.n   54e <.divsi3_skip_div0_test+0x6a>
 548:   1b00        subs    r0, r0, r4
 54a:   08dc        lsrs    r4, r3, #3
 54c:   4322        orrs    r2, r4
 54e:   2800        cmp r0, #0
 550:   d003        beq.n   55a <.divsi3_skip_div0_test+0x76>
 552:   091b        lsrs    r3, r3, #4
 554:   d001        beq.n   55a <.divsi3_skip_div0_test+0x76>
 556:   0909        lsrs    r1, r1, #4
 558:   e7e3        b.n 522 <.divsi3_skip_div0_test+0x3e>
 55a:   1c10        adds    r0, r2, #0
 55c:   4664        mov r4, ip
 55e:   2c00        cmp r4, #0
 560:   d500        bpl.n   564 <.divsi3_skip_div0_test+0x80>
 562:   4240        negs    r0, r0
 564:   bc10        pop {r4}
 566:   4770        bx  lr
 568:   2800        cmp r0, #0
 56a:   d006        beq.n   57a <.divsi3_skip_div0_test+0x96>
 56c:   db03        blt.n   576 <.divsi3_skip_div0_test+0x92>
 56e:   2000        movs    r0, #0
 570:   43c0        mvns    r0, r0
 572:   0840        lsrs    r0, r0, #1
 574:   e001        b.n 57a <.divsi3_skip_div0_test+0x96>
 576:   2080        movs    r0, #128    ; 0x80
 578:   0600        lsls    r0, r0, #24
 57a:   b407        push    {r0, r1, r2}
 57c:   4802        ldr r0, [pc, #8]    ; (588 <.divsi3_skip_div0_test+0xa4>)
 57e:   a102        add r1, pc, #8  ; (adr r1, 588 <.divsi3_skip_div0_test+0xa4>)
 580:   1840        adds    r0, r0, r1
 582:   9002        str r0, [sp, #8]
 584:   bd03        pop {r0, r1, pc}
 586:   46c0        nop         ; (mov r8, r8)
 588:   00000019    .word   0x00000019

and:

000005a4 <memcpy>:
 5a4:   b5f0        push    {r4, r5, r6, r7, lr}
 5a6:   2a0f        cmp r2, #15
 5a8:   d935        bls.n   616 <memcpy+0x72>
 5aa:   1c03        adds    r3, r0, #0
 5ac:   430b        orrs    r3, r1
 5ae:   079c        lsls    r4, r3, #30
 5b0:   d135        bne.n   61e <memcpy+0x7a>
 5b2:   1c16        adds    r6, r2, #0
 5b4:   3e10        subs    r6, #16
 5b6:   0936        lsrs    r6, r6, #4
 5b8:   0135        lsls    r5, r6, #4
 5ba:   1945        adds    r5, r0, r5
 5bc:   3510        adds    r5, #16
 5be:   1c0c        adds    r4, r1, #0
 5c0:   1c03        adds    r3, r0, #0
 5c2:   6827        ldr r7, [r4, #0]
 5c4:   601f        str r7, [r3, #0]
 5c6:   6867        ldr r7, [r4, #4]
 5c8:   605f        str r7, [r3, #4]
 5ca:   68a7        ldr r7, [r4, #8]
 5cc:   609f        str r7, [r3, #8]
 5ce:   68e7        ldr r7, [r4, #12]
 5d0:   3410        adds    r4, #16
 5d2:   60df        str r7, [r3, #12]
 5d4:   3310        adds    r3, #16
 5d6:   42ab        cmp r3, r5
 5d8:   d1f3        bne.n   5c2 <memcpy+0x1e>
 5da:   1c73        adds    r3, r6, #1
 5dc:   011b        lsls    r3, r3, #4
 5de:   18c5        adds    r5, r0, r3
 5e0:   18c9        adds    r1, r1, r3
 5e2:   230f        movs    r3, #15
 5e4:   4013        ands    r3, r2
 5e6:   2b03        cmp r3, #3
 5e8:   d91b        bls.n   622 <memcpy+0x7e>
 5ea:   1f1c        subs    r4, r3, #4
 5ec:   08a4        lsrs    r4, r4, #2
 5ee:   3401        adds    r4, #1
 5f0:   00a4        lsls    r4, r4, #2
 5f2:   2300        movs    r3, #0
 5f4:   58ce        ldr r6, [r1, r3]
 5f6:   50ee        str r6, [r5, r3]
 5f8:   3304        adds    r3, #4
 5fa:   42a3        cmp r3, r4
 5fc:   d1fa        bne.n   5f4 <memcpy+0x50>
 5fe:   18ed        adds    r5, r5, r3
 600:   18c9        adds    r1, r1, r3
 602:   2303        movs    r3, #3
 604:   401a        ands    r2, r3
 606:   d005        beq.n   614 <memcpy+0x70>
 608:   2300        movs    r3, #0
 60a:   5ccc        ldrb    r4, [r1, r3]
 60c:   54ec        strb    r4, [r5, r3]
 60e:   3301        adds    r3, #1
 610:   4293        cmp r3, r2
 612:   d1fa        bne.n   60a <memcpy+0x66>
 614:   bdf0        pop {r4, r5, r6, r7, pc}
 616:   1c05        adds    r5, r0, #0
 618:   2a00        cmp r2, #0
 61a:   d1f5        bne.n   608 <memcpy+0x64>
 61c:   e7fa        b.n 614 <memcpy+0x70>
 61e:   1c05        adds    r5, r0, #0
 620:   e7f2        b.n 608 <memcpy+0x64>
 622:   1c1a        adds    r2, r3, #0
 624:   e7f8        b.n 618 <memcpy+0x74>
 626:   46c0        nop         ; (mov r8, r8)

I am guessing that I could code far smaller, but less time-efficient, replacements myself.

Is this likely?

Where will I find the source which I need to edit - I'm guessing that I should look for the source of a libc under gcc-arm-none-eabi/lib/gcc/arm-none-eabi/4.8.3/. I think that I've found the compiled symbols, but I can't find the source.

~/gcc-arm-none-eabi$ grep -R divsi3_skip_div0_test *
Binary file lib/gcc/arm-none-eabi/4.8.3/libgcc.a matches
Binary file lib/gcc/arm-none-eabi/4.8.3/thumb/libgcc.a matches
Binary file lib/gcc/arm-none-eabi/4.8.3/armv6-m/libgcc.a matches
Binary file lib/gcc/arm-none-eabi/4.8.3/fpu/libgcc.a matches
Binary file lib/gcc/arm-none-eabi/4.8.3/armv7-ar/thumb/libgcc.a matches
Binary file lib/gcc/arm-none-eabi/4.8.3/armv7-ar/thumb/softfp/libgcc.a matches
Binary file lib/gcc/arm-none-eabi/4.8.3/armv7-ar/thumb/fpu/libgcc.a matches

Alternatively, is there a way to tell gcc not to use memcpy when copying structures? (They are 10 bytes, so three thumb instructions should do the job.) I've tried adding -mno-memcpy and -Wa,mno-memcpy but neither are recognised.

Update:

I've solved the memcpy part of this question - adding a partial, but sufficient, memcpy function stops the other from being added.

size_t memcpy(uint8_t *restrict dst, uint8_t *restrict const src, size_t size) {
    int i;
    for (i = 0; i < size; i++) {
        dst[i] = src[i];
    }
    return i;
}

It's much smaller, but less efficient and won't handle dst < src + size overlap.

000003ec <memcpy>:
 3ec:   b510        push    {r4, lr}
 3ee:   2300        movs    r3, #0
 3f0:   4293        cmp r3, r2
 3f2:   d003        beq.n   3fc <memcpy+0x10>
 3f4:   5ccc        ldrb    r4, [r1, r3]
 3f6:   54c4        strb    r4, [r0, r3]
 3f8:   3301        adds    r3, #1
 3fa:   e7f9        b.n 3f0 <memcpy+0x4>
 3fc:   1c18        adds    r0, r3, #0
 3fe:   bd10        pop {r4, pc}

To clarify, I'm now only asking what I might do to replace the .divsi3_skip_div0_test code with a less efficient, but smaller, code.

It is not clear to me where the source of this code is, or how to edit its source. It looks to be more complicated to replace than memcpy as it does not look like a C function, as its name begins with a ..

0

There are 0 answers