Mentre si lavora sul tema in Fastest Cortex M0+ Thumb 32x32=64 multiplication function? ho scritto la seguente funzione C per vedere come sarebbe la compilazione:ARM Compilato deliberatamente codice compilato?
uint64_t lmul(uint32_t a, uint32_t b){
uint32_t hia = a >> 16,
hib = b >> 16,
loa = (uint32_t)(uint16_t)a,
lob = (uint32_t)(uint16_t)b,
low = loa * lob,
mid1 = hia * lob,
mid2 = loa * hib,
mid = mid1 + mid2,
high = hia * hib;
if (mid < mid1)
high += 0x10000;
return ((uint64_t)high << 32) + ((uint64_t)mid << 16) + low;
}
Dopo aver compilato con il compilatore GCC 4.7.3 ARM attraverso CodeWarrior (quello che è venuto con la scheda dev Freescale sto usando) con l'ottimizzazione dimensioni, si è trasformato in questo:
00000eac <lmul>:
eac: b570 push {r4, r5, r6, lr}
eae: 0c06 lsrs r6, r0, #16
eb0: b280 uxth r0, r0
eb2: 0c0a lsrs r2, r1, #16
eb4: 1c04 adds r4, r0, #0
eb6: b289 uxth r1, r1
eb8: 434c muls r4, r1
eba: 4350 muls r0, r2
ebc: 4371 muls r1, r6
ebe: 1843 adds r3, r0, r1
ec0: 4356 muls r6, r2
ec2: 428b cmp r3, r1
ec4: d202 bcs.n ecc <lmul+0x20>
ec6: 2580 movs r5, #128 ; 0x80
ec8: 026a lsls r2, r5, #9
eca: 18b6 adds r6, r6, r2
ecc: 0c19 lsrs r1, r3, #16
ece: 0418 lsls r0, r3, #16
ed0: 1c22 adds r2, r4, #0
ed2: 2300 movs r3, #0
ed4: 1c04 adds r4, r0, #0
ed6: 1c0d adds r5, r1, #0
ed8: 18a4 adds r4, r4, r2
eda: 415d adcs r5, r3
edc: 1c31 adds r1, r6, #0
ede: 1c18 adds r0, r3, #0
ee0: 1c22 adds r2, r4, #0
ee2: 1c2b adds r3, r5, #0
ee4: 1812 adds r2, r2, r0
ee6: 414b adcs r3, r1
ee8: 1c10 adds r0, r2, #0
eea: 1c19 adds r1, r3, #0
eec: bd70 pop {r4, r5, r6, pc}
non riesco a capire quello che il compilatore sta facendo negli ultimi 40% della funzione. È come se stesse suonando i registri musicali per nessun altro scopo che aumentare le dimensioni della funzione. È qualcosa che ARM è noto a fare, o c'è uno strano scopo a questo che mi manca l'esperienza dell'assemblaggio ARM per comprendere?
Se non avessi commesso errori in sostituzione l'ultima metà della funzione potrebbe essere rappresentata da:
ecc: 0c19 lsrs r1, r3, #16
ece: 0418 lsls r0, r3, #16
ed2: 2300 movs r3, #0
ed8: 18a4 adds r0, r0, r4
eda: 415d adcs r1, r3
ee6: 414b adds r1, r1, r6
eec: bd70 pop {r4, r5, r6, pc}
FYI, gcc 4.5.3 e 4.6.3 su [gcc explorer] (http://gcc.godbolt.org/) non sembrano farlo. – Jester
LOL +1 solo per "registri musicali" –
Una cosa che era una specie di premessa del mio post ma non ne sono del tutto sicuro, è se il compilatore è in realtà da ARM o è solo GCC che supporta ARM. Ho indovinato il primo perché è elencato come "ARM Ltd. GCC Build Tools" in CodeWarrior, ma potrei sbagliarmi. A quanto ho capito, il compilatore ufficiale ARM usa il front-end GCC ma un back-end diverso. –