2014-04-25 17 views
12

Trong khi làm việc về vấn đề này trong Fastest Cortex M0+ Thumb 32x32=64 multiplication function? tôi đã viết chức năng C sau đây để xem làm thế nào nó sẽ biên dịch:ARM Cố tình Bloating Biên dịch Mã?

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; 
} 

Sau khi biên dịch nó với trình biên dịch ARM GCC 4.7.3 qua CodeWarrior (những gì đi kèm với hội đồng quản trị dev Freescale Tôi đang sử dụng) với tối ưu hóa kích thước, nó được chuyển thành:

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} 

Tôi không thể hiểu được trình biên dịch đang làm gì trong 40% cuối cùng của hàm. Nó giống như nó đang chơi các thanh ghi âm không có mục đích nào khác ngoài việc tăng kích thước của hàm. Đây có phải là điều gì đó mà ARM được biết là có hay không, hay có một mục đích lạ nào đó đến mức tôi thiếu chuyên môn lắp ráp ARM để hiểu?

Nếu tôi không thực hiện bất kỳ sai lầm trong thay nửa cuối của hàm có thể được đại diện bởi:

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 và 4.6.3 trên [gcc explorer] (http://gcc.godbolt.org/) dường như không làm điều này. – Jester

+6

LOL +1 chỉ dành cho 'đăng ký âm nhạc' –

+0

Một điều mà là một tiền đề của bài viết của tôi nhưng tôi không hoàn toàn chắc chắn, liệu trình biên dịch có thực sự từ ARM hay chỉ là GCC hỗ trợ ARM. Tôi đã đoán trước đây bởi vì nó được liệt kê là "ARM Ltd GCC Build Tools" trong CodeWarrior, nhưng tôi có thể sai. Như tôi đã hiểu nó, trình biên dịch ARM chính thức sử dụng giao diện người dùng GCC nhưng phụ trợ khác nhau. –

Trả lời

1

tôi đã không sử dụng dây chuyền công cụ CodeWarrior, nhưng tôi đã quyết định thử điều này với uVision bằng cách sử dụng trình biên dịch ARMCC v 5.03.0.76. Tối ưu hóa cho không gian là tùy chọn mặc định (-Ospace) và mã được tạo ra vẫn còn khá xấu xí ... không quá khác với của bạn. Khi tôi biên soạn với -O2 nó trông giống như những gì bạn mong đợi:

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} 

Bạn có thể thử biên dịch với các tùy chọn tối ưu hóa khác nhau nhưng tôi sẽ đề nghị bạn nên đi với một trình biên dịch mới hơn như tiểu bang Marc Glisse trong bình luận của ông.

+0

Vì vậy, tôi đoán câu trả lời cho câu hỏi ban đầu là "không": nó dường như là một lỗi trong cả ARMCC và GCC. –

Các vấn đề liên quan