我試圖產生 AXI總線突發訪問與ARM編譯器armcc 5編譯.c文件使用內聯組件STM/LDM指令。如何防止ARM Compiler 5 armcc內嵌彙編程序中的LDM/STM指令擴展?
inline void STMIA2(uint32_t addr, uint32_t w0, uint32_t w1)
{
__asm {
STMIA addr!, { w0, w1 }
}
}
但ARM編譯器armcc用戶指南,第7.18段是說: 「所有的LDM和STM指令被擴展爲等效的LDR和STR指令序列然而,編譯器可能因此重組的單獨的指令在優化過程中轉換爲LDM或STM。「
這就是真正發生的事情在實踐中,LDM/STM被擴展成一組的LDR/STR在某些情況下,這些instuctions的順序是任意的。 這會影響性能,因爲我們使用HW優化了突發處理。此外,這破壞了函數的正確性,因爲我們使用的HW考慮了字的序列並忽略了偏移量(但編譯器認爲改變指令的順序是安全的)。
要解決這一點,是可以使用的,而不是內聯彙編嵌入式彙編程序,但是這會導致額外的函數調用,返回什麼影響性能。
所以我想知道如果有一種方法來生成LDM/STM正確不失的表現?我們能夠在GCC中做到這一點,但沒有找到任何解決方案。
目標CPU:Cortex M0 +(ARMv6-M)。
編輯: 從屬設備都是片上設備,其中大多數是非存儲設備。對於支持地址空間突發訪問區域的每個非存儲器從站寄存器(例如[0x10000..0x10100]),我不完全確定爲什麼,也許CPU或總線不支持固定(非增量)地址。 HW忽略該區域內的偏移量。例如,完整請求可以是16個字節,並且完整請求的第一個字是第一個寫入的字(即使偏移量不爲零)。
如果你很在乎性能,然後寫更多的,你在一個單獨的彙編程序文件所需要的。考慮到編譯器處理代碼的其餘部分有多糟糕,內聯C函數中的單個指令不會讓你感到太多。我的運營主體總是 - 如果您關心時間關鍵的例程的性能,請自己寫(使用匯編程序)。 – BitBank
@ imiron13:我懷疑你是搞砸了。基爾內聯彙編讓優化器無所不能,對「優化」功能缺乏細粒度的控制。如果您使用正常的易失性指針來確保寫入器與64位類型的順序以嘗試組合寫入,那麼代碼生成有多糟糕? – doynax
@BitBank:我的假設是,性能命中並不是孤立於單個重要的內部環路,這可以很容易地手動調整,但寫入內聯生成代碼庫的重要部分。 – doynax