2014-04-25 8 views
12

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} 
+0

FYI, gcc 4.5.3 e 4.6.3 su [gcc explorer] (http://gcc.godbolt.org/) non sembrano farlo. – Jester

+6

LOL +1 solo per "registri musicali" –

+0

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. –

risposta

1

Non ho usato il tool chain CodeWarrior, ma ho deciso di provare questo con uVision utilizzando il compilatore ARMCC v 5.03.0.76. L'ottimizzazione dello spazio è l'opzione predefinita (-Ospace) e il codice generato era ancora piuttosto brutto ... non troppo diverso dal tuo. Quando ho compilato con l'-O2 sembrava più simile a quello che ci si aspetta:

0x0000008A B570  PUSH  {r4-r6,lr} 
0x0000008C 0C02  LSRS  r2,r0,#16 
0x0000008E 0C0C  LSRS  r4,r1,#16 
0x00000090 B280  UXTH  r0,r0 
0x00000092 B289  UXTH  r1,r1 
0x00000094 4606  MOV  r6,r0 
0x00000096 4615  MOV  r5,r2 
0x00000098 434D  MULS  r5,r1,r5 
0x0000009A 4360  MULS  r0,r4,r0 
0x0000009C 434E  MULS  r6,r1,r6 
0x0000009E 182B  ADDS  r3,r5,r0 
0x000000A0 4362  MULS  r2,r4,r2 
0x000000A2 42AB  CMP  r3,r5 
0x000000A4 D202  BCS  0x000000AC 
0x000000A6 2001  MOVS  r0,#0x01 
0x000000A8 0400  LSLS  r0,r0,#16 
0x000000AA 1812  ADDS  r2,r2,r0 
0x000000AC 2400  MOVS  r4,#0x00 
0x000000AE 0C19  LSRS  r1,r3,#16 
0x000000B0 0418  LSLS  r0,r3,#16 
0x000000B2 1900  ADDS  r0,r0,r4 
0x000000B4 4151  ADCS  r1,r1,r2 
0x000000B6 1980  ADDS  r0,r0,r6 
0x000000B8 4161  ADCS  r1,r1,r4 
0x000000BA BD70  POP  {r4-r6,pc} 

si può provare la compilazione con diverse opzioni di ottimizzazione, ma vorrei suggerire che si va con un compilatore più recente come Marc Glisse afferma nel suo commento.

+0

Quindi immagino che la risposta alla domanda originale sia "no": sembra essere un bug sia in ARMCC che in GCC. –