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}
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
LOL +1 chỉ dành cho 'đăng ký âm nhạc' –
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. –