I'm using Rust 1.13 and I have code similar to the following in a library
pub fn u64_to_u8(number: u64) -> Result<[u8; 8], ()> {
use std::mem::transmute;
let bytes: [u8; 8] = unsafe { transmute(number) };
Ok(bytes)
}
Which results in the following disassembly
0000000000000000 <_ZN9transtest9u64_to_u817hda109e31aa82d40fE>:
0: 48 89 f0 mov rax,rsi
3: 49 89 c0 mov r8,rax
6: 49 89 c1 mov r9,rax
9: 48 89 c1 mov rcx,rax
c: 48 89 c2 mov rdx,rax
f: c6 07 00 mov BYTE PTR [rdi],0x0
12: 88 47 01 mov BYTE PTR [rdi+0x1],al
15: 88 67 02 mov BYTE PTR [rdi+0x2],ah
18: 48 c1 e8 10 shr rax,0x10
1c: 49 c1 e8 18 shr r8,0x18
20: 49 c1 e9 20 shr r9,0x20
24: 48 c1 ee 28 shr rsi,0x28
28: 48 c1 e9 30 shr rcx,0x30
2c: 48 c1 ea 38 shr rdx,0x38
30: 88 47 03 mov BYTE PTR [rdi+0x3],al
33: 44 88 47 04 mov BYTE PTR [rdi+0x4],r8b
37: 44 88 4f 05 mov BYTE PTR [rdi+0x5],r9b
3b: 40 88 77 06 mov BYTE PTR [rdi+0x6],sil
3f: 88 4f 07 mov BYTE PTR [rdi+0x7],cl
42: 88 57 08 mov BYTE PTR [rdi+0x8],dl
45: 48 89 f8 mov rax,rdi
48: c3 ret
When the following code
pub fn u64_to_u8_2(number: u64) -> [u8; 8] {
use std::mem::transmute;
let bytes: [u8; 8] = unsafe { transmute(number) };
bytes
}
Results in the following
0000000000000000 <_ZN9transtest11u64_to_u8_217hc4ea0612fd31159fE>:
0: 48 89 f8 mov rax,rdi
3: c3 ret
Which is much closer to what I expected.
Why does the compiler generate multiple single byte writes instead of a single 8 byte write?