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)

Reply via email to