Use little-endian ordering for CLIF vconst immediate
Examining wasm-objdump revealed that it stores SIMD constants in little-endian order, e.g.: 000071 func[2] <test_const>: 000072: fd 02 01 00 00 00 02 00 00 | v128.const 0x00000001 0x00000002 0x00000003 0x00000004 00007b: 00 03 00 00 00 04 00 00 00 | 000084: fd 0d 03 | i32x4.extract_lane 3 000087: 0b | end This change avoids confusion by making the CLIF representation use little-endian order as well.
This commit is contained in:
@@ -275,7 +275,7 @@ impl Display for Uimm128 {
|
|||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
write!(f, "0x")?;
|
write!(f, "0x")?;
|
||||||
let mut anything_written = false;
|
let mut anything_written = false;
|
||||||
for &b in self.0.iter() {
|
for &b in self.0.iter().rev() {
|
||||||
if b == 0 && !anything_written {
|
if b == 0 && !anything_written {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@@ -293,7 +293,7 @@ impl Display for Uimm128 {
|
|||||||
impl From<u64> for Uimm128 {
|
impl From<u64> for Uimm128 {
|
||||||
fn from(x: u64) -> Self {
|
fn from(x: u64) -> Self {
|
||||||
let mut buffer: [u8; 16] = [0; 16]; // zero-fill
|
let mut buffer: [u8; 16] = [0; 16]; // zero-fill
|
||||||
(0..8).for_each(|byte| buffer[15 - byte] = (x >> (byte as u64 * 8) & 0xff) as u8); // insert each byte from the u64 into v after byte position 8
|
(0..8).for_each(|byte| buffer[byte] = (x >> (byte as u64 * 8) & 0xff) as u8); // insert each byte from the u64 into v in little-endian order
|
||||||
Uimm128(buffer)
|
Uimm128(buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -316,15 +316,15 @@ impl FromStr for Uimm128 {
|
|||||||
Err("Expected a hexadecimal string, e.g. 0x1234")
|
Err("Expected a hexadecimal string, e.g. 0x1234")
|
||||||
} else if s.len() % 2 != 0 {
|
} else if s.len() % 2 != 0 {
|
||||||
Err("Hexadecimal string must have an even number of digits")
|
Err("Hexadecimal string must have an even number of digits")
|
||||||
} else if s.len() > 32 {
|
} else if s.len() > 34 {
|
||||||
Err("Hexadecimal string has too many digits to fit in a 128-bit vector")
|
Err("Hexadecimal string has too many digits to fit in a 128-bit vector")
|
||||||
} else {
|
} else {
|
||||||
let mut buffer = [0; 16]; // zero-fill
|
let mut buffer = [0; 16]; // zero-fill
|
||||||
let start_at = 16 - s.len() / 2;
|
let start_at = s.len() / 2 - 1;
|
||||||
for i in (2..s.len()).step_by(2) {
|
for i in (2..s.len()).step_by(2) {
|
||||||
let byte = u8::from_str_radix(&s[i..i + 2], 16)
|
let byte = u8::from_str_radix(&s[i..i + 2], 16)
|
||||||
.or_else(|_| Err("Unable to parse as hexadecimal"))?;
|
.or_else(|_| Err("Unable to parse as hexadecimal"))?;
|
||||||
let position = start_at + (i / 2);
|
let position = start_at - (i / 2);
|
||||||
buffer[position] = byte;
|
buffer[position] = byte;
|
||||||
}
|
}
|
||||||
Ok(Uimm128(buffer))
|
Ok(Uimm128(buffer))
|
||||||
@@ -984,6 +984,22 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn uimm128_endianness() {
|
||||||
|
assert_eq!(
|
||||||
|
"0x42".parse::<Uimm128>().unwrap().0,
|
||||||
|
[0x42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"0x00".parse::<Uimm128>().unwrap().0,
|
||||||
|
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
"0x12345678".parse::<Uimm128>().unwrap().0,
|
||||||
|
[0x78, 0x56, 0x34, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn format_offset32() {
|
fn format_offset32() {
|
||||||
assert_eq!(Offset32(0).to_string(), "");
|
assert_eq!(Offset32(0).to_string(), "");
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ ebb0:
|
|||||||
return v0
|
return v0
|
||||||
}
|
}
|
||||||
|
|
||||||
; sameln: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 34]
|
; sameln: [34, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
|||||||
Reference in New Issue
Block a user