Rewrite read_u32v_be() and write_u32_be() to make sure that all memory access is properly aligned

When I originally wrote the read_u32v_be() and write_u32_be() functions, I didn't consider memory alignment requirements of various architectures. Unfortunately, the current implementations may result in unaligned reads and writes. This doesn't impact x86 / x86_64, but it can cause a compiler crash on ARM. This pull requests rewrites those functions to make sure that all memory access is always correctly aligned.

This fix is a little bit academic - due to the way that LLVM aligns the structures that are passed as arguments to these functions, I believe that the end result is that all memory access happens to be aligned anyway. However, there is nothing in that code that actually enforces that, at least not explicitly. The new implementations are definitely slower than the existing ones. However, I don't believe that these functions are all that significant when looking at the overall performance of the compiler. I think getting rid of some unsafe code and removing a potential portability landmine justifies a very slight decrease in raw performance.