https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106635
--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Xiaoguang from comment #6) > (In reply to Richard Earnshaw from comment #5) > > Your original code contains (after stripping out the volatile): > > u32 temp_32 = (u32)status_data_base_addr; > > *dst++ = temp_32; > > data_length++; > > > > if(sizeof(addr_t) == 8) { > > *dst++ = (u32)(((u64)status_data_base_addr)>>32); > > data_length++; > > } > > > > Which of course on a 64-bit machine simplifies to > > > > u32 temp_32 = (u32)status_data_base_addr; > > *dst++ = temp_32; > > data_length++; > > > > *dst++ = (u32)(((u64)status_data_base_addr)>>32); > > data_length++; > > > > And which the compiler then further simplifies to > > > > *([unaligned]u64*)dst = status_data_base_addr; > > data_length += 2; > > dst += 2; > > > > If the location that dst points to is in normal, cachable, memory, then this > > will be fine. But if you're writing to non-cachable memory, then you might > > get a trap. > Thanks Very much for the explaination, Can you tell me why unaligned access > only works in normal cachable memory? where does this constraint come from? The architect (armv8) explains this. Basically the hardware does not know what to do when there is a unaligned access as it has to two reads and two writes to get the data correct. It in the arm armv8 document. > > > > > the correct fix is to mark dst as volatile in this case. > > > > void CWLCollectReadRegData(volatile u32* dst,u16 reg_start, u32 > > reg_length,u32* > > total_length, addr_t status_data_base_addr)