Skip to content

Commit 0dff8c6

Browse files
committed
Change bytes_in_context to use arrays of larger intigers where possible.
1 parent 6ba33f5 commit 0dff8c6

File tree

1 file changed

+70
-6
lines changed

1 file changed

+70
-6
lines changed

src/common.rs

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,76 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
4646
}
4747

4848
pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> RValue<'gcc> {
49-
let context = &cx.context;
50-
let byte_type = context.new_type::<u8>();
51-
let typ = context.new_array_type(None, byte_type, bytes.len() as u64);
52-
let elements: Vec<_> =
53-
bytes.iter().map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32)).collect();
54-
context.new_array_constructor(None, typ, &elements)
49+
//if cx.sess().target.options.endian == Endian::Little {}
50+
match bytes.len() % 8 {
51+
0 => {
52+
let context = &cx.context;
53+
let byte_type = context.new_type::<u64>();
54+
let typ = context.new_array_type(None, byte_type, bytes.len() as u64 / 8);
55+
let elements: Vec<_> = bytes
56+
.chunks_exact(8)
57+
.map(|arr| {
58+
let arr: [u8; 8] = arr.try_into().unwrap();
59+
context.new_rvalue_from_long(
60+
byte_type,
61+
match cx.sess().target.options.endian {
62+
rustc_abi::Endian::Little => u64::from_le_bytes(arr) as i64,
63+
rustc_abi::Endian::Big => u64::from_be_bytes(arr) as i64,
64+
},
65+
)
66+
})
67+
.collect();
68+
context.new_array_constructor(None, typ, &elements)
69+
}
70+
4 => {
71+
let context = &cx.context;
72+
let byte_type = context.new_type::<u32>();
73+
let typ = context.new_array_type(None, byte_type, bytes.len() as u64 / 4);
74+
let elements: Vec<_> = bytes
75+
.chunks_exact(4)
76+
.map(|arr| {
77+
let arr: [u8; 4] = arr.try_into().unwrap();
78+
context.new_rvalue_from_int(
79+
byte_type,
80+
match cx.sess().target.options.endian {
81+
rustc_abi::Endian::Little => u32::from_le_bytes(arr) as i32,
82+
rustc_abi::Endian::Big => u32::from_be_bytes(arr) as i32,
83+
},
84+
)
85+
})
86+
.collect();
87+
context.new_array_constructor(None, typ, &elements)
88+
}
89+
2..6 => {
90+
let context = &cx.context;
91+
let byte_type = context.new_type::<u16>();
92+
let typ = context.new_array_type(None, byte_type, bytes.len() as u64 / 2);
93+
let elements: Vec<_> = bytes
94+
.chunks_exact(2)
95+
.map(|arr| {
96+
let arr: [u8; 2] = arr.try_into().unwrap();
97+
context.new_rvalue_from_int(
98+
byte_type,
99+
match cx.sess().target.options.endian {
100+
rustc_abi::Endian::Little => u16::from_le_bytes(arr) as u32 as i32,
101+
rustc_abi::Endian::Big => u16::from_be_bytes(arr) as u32 as i32,
102+
},
103+
)
104+
})
105+
.collect();
106+
context.new_array_constructor(None, typ, &elements)
107+
}
108+
_ => {
109+
let context = &cx.context;
110+
let byte_type = context.new_type::<u8>();
111+
let typ = context.new_array_type(None, byte_type, bytes.len() as u64);
112+
let elements: Vec<_> = bytes
113+
.iter()
114+
.map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32))
115+
.collect();
116+
context.new_array_constructor(None, typ, &elements)
117+
}
118+
}
55119
}
56120

57121
pub fn type_is_pointer(typ: Type<'_>) -> bool {

0 commit comments

Comments
 (0)