summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/system.h26
1 files changed, 23 insertions, 3 deletions
diff --git a/firmware/export/system.h b/firmware/export/system.h
index 2a8b98c7a5..895b3f7529 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -207,6 +207,16 @@ static inline unsigned short SWAB16(unsigned short value)
207 return (value >> 8) | (value << 8); 207 return (value >> 8) | (value << 8);
208} 208}
209 209
210static inline unsigned long SWAW32(unsigned long value)
211 /*
212 result[31..16] = value[15.. 0];
213 result[15.. 0] = value[31..16];
214 */
215{
216 asm ("swap %%0" : "+r"(value));
217 return value;
218}
219
210static inline unsigned long SWAB32(unsigned long value) 220static inline unsigned long SWAB32(unsigned long value)
211 /* 221 /*
212 result[31..24] = value[ 7.. 0]; 222 result[31..24] = value[ 7.. 0];
@@ -215,9 +225,19 @@ static inline unsigned long SWAB32(unsigned long value)
215 result[ 7.. 0] = value[31..24]; 225 result[ 7.. 0] = value[31..24];
216 */ 226 */
217{ 227{
218 unsigned short hi = SWAB16(value >> 16); 228 unsigned long mask = 0x00FF00FF;
219 unsigned short lo = SWAB16(value & 0xffff); 229 asm ( /* val = ABCD */
220 return (lo << 16) | hi; 230 "and.l %[val],%[mask] \n" /* mask = .B.D */
231 "eor.l %[mask],%[val] \n" /* val = A.C. */
232 "lsl.l #8,%[mask] \n" /* mask = B.D. */
233 "lsr.l #8,%[val] \n" /* val = .A.C */
234 "or.l %[mask],%[val] \n" /* val = BADC */
235 "swap %[val] \n" /* val = DCBA */
236 : /* outputs */
237 [val] "+d"(value),
238 [mask]"+d"(mask)
239 );
240 return value;
221} 241}
222 242
223static inline void invalidate_icache(void) 243static inline void invalidate_icache(void)