2012-03-08 101 views
2

我想要做以下事情: 我有8個值(8 x 1字節)在一個霓虹燈D-Register(= 64位)。現在我需要將每個值3移到左邊,但我不想失去任何比特。 之後,我需要向向量中的每個值添加相同的32位值。ARM Neon Assembler - 處理溢出寄存器

據我瞭解,如果溢出,我可以使用指令VQSHL將結果放入2個D寄存器中?我怎麼知道溢出是否發生,並保證/強制我的所有數據都在新的寄存器中?

你也可以幫我一些代碼換班和添加部分?

例如代碼:

OUT0 = CONSTANT_32BIT +(INPUT0 < < 3)

OUT1 = CONSTANT_32BIT +(輸入1 < < 3)

OUT_N = CONSTANT_32BIT +(input_n < < 3 )

所以理論上我可以使用Neon寄存器並行執行8或16條指令?

目標是ARM Cortex-A9(如果這很重要)。

+0

什麼尺寸爲OUT0? – 2012-03-08 03:26:15

回答

3

你可以做這樣的事情(未測試的代碼,但應該給你如何去做一些想法):

//Assumes signed ints 
//d0: 8 input bytes 
//q3: contains four copies of the 32-bit constant 
//Perform shift and extend to 16-bit elements 
vshll.s8 q0, d0, #3 
//Extend 16-bit elements to 32-bit elements and add the 32-bit constants 
vaddw.s16 q1, q3, d0 
vaddw.s16 q2, q3, d1 
//q1 now contains first four values, q2 the last four 
+0

謝謝。請問vshll強制從8位擴展到16位值?我使用無符號值,所以我可能應該.u8作爲數據類型。數據類型是指源(d0)還是目標寄存器(q0)類型? – HectorLector 2012-03-08 10:26:16

+0

是的,vshll(額外的L表示擴展)會使輸入的位寬加倍,然後進行移位。對於無符號值,vshll.u8和vmovl.u16是正確的數據類型。數據類型在執行擴展操作時引用源寄存器類型。祝你好運! – Leo 2012-03-08 12:19:06

+0

完美。是否有可能在vshll上執行擴展添加操作?(而不是vmovl和vadd - 只有一條指令) – HectorLector 2012-03-08 16:38:46

2

VQSHL是一個飽和的轉變。也就是說,它不會讓車道溢出,如果他們這樣做,他們會飽和到最大可能的價值。如果這是所需的行爲,那麼這將適用於你。如果發生飽和,處理器將設置FPSCR.QC(累積飽和標誌)。

從您的描述來看,這聽起來像你不想要溢出行爲。如果您打算爲每個8位值添加一個32位值,結果通常不適合8位寄存器。 也許你應該考慮將你的8位值加載到更寬的寄存器中。例如。作爲4個32位通道。您可以使用VLD的多元素形式來幫助您將8位值加載到NEON寄存器中,類似於VLD2.8 {d0[0],d1[0],d2[0],d3[0]}, [r0]的東西將加載偶數指數,然後您可以加載奇數指數。另一種選擇是使用VZIP。

+0

謝謝。我使用VTBL來查找字節值,所以我將有一個具有8x1byte值的D-reg。我怎麼能擴展到8x32Bit? – HectorLector 2012-03-08 10:23:44

+0

@Guy Sirton:VZIP是如何作爲另一種選擇。你能否介紹一下它的用法? – 2012-03-15 08:09:16

+1

@AnoopKP:例如如果你有8位數值在d0和0在d1你可以使用VZIP.8 d0,d1將這8位數值擴展爲16位數值(在q0中)。對於這個用例,Leo的方法似乎更好。 – 2012-03-15 21:31:10