aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG2
-rw-r--r--src/long_mode/vex.rs30
-rw-r--r--src/protected_mode/vex.rs34
-rw-r--r--src/real_mode/vex.rs34
-rw-r--r--test/long_mode/mod.rs2
-rw-r--r--test/long_mode/operand.rs4
-rw-r--r--test/protected_mode/mod.rs2
-rw-r--r--test/protected_mode/operand.rs4
-rw-r--r--test/real_mode/mod.rs4
-rw-r--r--test/real_mode/operand.rs4
10 files changed, 88 insertions, 32 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 2a6102b..a2410ee 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,8 @@
vcvtph2ps, vbroadcastf128, vmaskmovps, vmaskmovpd, vpermd, vpbroadcast{b,w,d,q}, among others
* vpbroadcastb and vpbroadcastw should respect the L bit to select xmm/ymm vector width, but
always decoded as ymm.
+* vmaskmovqdu now reports a memory access size for the implied write to ds:[rdi/edi/di].
+* correct swapped operand order of 0xD6-opcode movq. in 32/16-bit, fix this opcode being decoded as vmovd.
## 2.0.0
diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs
index b43b0fe..ba39ba1 100644
--- a/src/long_mode/vex.rs
+++ b/src/long_mode/vex.rs
@@ -46,7 +46,7 @@ enum VEXOperandCode {
VMOVHPS_16,
M_G_xmm,
G_M_xmm,
- G_U_xmm,
+ G_U_xmm_vmaskmovdqu,
Gd_U_xmm,
E_G_xmm_imm8,
Ud_G_xmm_imm8,
@@ -857,17 +857,12 @@ fn read_vex_operands<
}
op @ VEXOperandCode::G_M_xmm |
- op @ VEXOperandCode::G_U_xmm |
op @ VEXOperandCode::G_E_xmm => {
if instruction.regs[3].num != 0 {
return Err(DecodeError::InvalidOperand);
}
let modrm = read_modrm(words)?;
match (op, modrm & 0xc0) {
- (VEXOperandCode::G_U_xmm, 0xc0) => {
- /* this is the only accepted operand */
- }
- (VEXOperandCode::G_U_xmm, _) |
(VEXOperandCode::G_M_xmm, 0xc0) => {
return Err(DecodeError::InvalidOperand);
}
@@ -893,6 +888,23 @@ fn read_vex_operands<
instruction.operand_count = 2;
Ok(())
}
+ VEXOperandCode::G_U_xmm_vmaskmovdqu => {
+ if instruction.regs[3].num != 0 {
+ return Err(DecodeError::InvalidOperand);
+ }
+ let modrm = read_modrm(words)?;
+ if modrm & 0xc0 != 0xc0 {
+ return Err(DecodeError::InvalidOperand);
+ }
+ instruction.regs[0] =
+ RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), RegisterBank::X);
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
+ instruction.operands[0] = OperandSpec::RegRRR;
+ instruction.operands[1] = mem_oper;
+ instruction.mem_size = 16;
+ instruction.operand_count = 2;
+ Ok(())
+ }
VEXOperandCode::G_xmm_E_xmm => {
if instruction.regs[3].num != 0 {
return Err(DecodeError::InvalidOperand);
@@ -1113,7 +1125,7 @@ fn read_vex_operands<
RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.vex_unchecked().r(), bank);
let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
if mem_oper != OperandSpec::RegMMM {
- if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS {
+ if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS || instruction.opcode == Opcode::VMOVQ {
instruction.mem_size = 8;
} else {
if L {
@@ -1889,7 +1901,7 @@ fn read_vex_instruction<
0xD6 => (Opcode::VMOVQ, if L {
return Err(DecodeError::InvalidOpcode);
} else {
- VEXOperandCode::G_E_xmm
+ VEXOperandCode::E_G_xyLmm
}),
0xD7 => (Opcode::VPMOVMSKB, VEXOperandCode::Ud_G_xyLmm),
0xD8 => (Opcode::VPSUBUSB, VEXOperandCode::G_V_E_xyLmm),
@@ -1949,7 +1961,7 @@ fn read_vex_instruction<
0xF7 => (Opcode::VMASKMOVDQU, if L {
return Err(DecodeError::InvalidOpcode);
} else {
- VEXOperandCode::G_U_xmm
+ VEXOperandCode::G_U_xmm_vmaskmovdqu
}),
0xF8 => (Opcode::VPSUBB, VEXOperandCode::G_V_E_xyLmm),
0xF9 => (Opcode::VPSUBW, VEXOperandCode::G_V_E_xyLmm),
diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs
index 1ba9c66..1b5c9d9 100644
--- a/src/protected_mode/vex.rs
+++ b/src/protected_mode/vex.rs
@@ -46,7 +46,7 @@ enum VEXOperandCode {
VMOVHPS_16,
M_G_xmm,
G_M_xmm,
- G_U_xmm,
+ G_U_xmm_vmaskmovdqu,
Gd_U_xmm,
E_G_xmm_imm8,
Ud_G_xmm_imm8,
@@ -784,17 +784,12 @@ fn read_vex_operands<
}
op @ VEXOperandCode::G_M_xmm |
- op @ VEXOperandCode::G_U_xmm |
op @ VEXOperandCode::G_E_xmm => {
if instruction.regs[3].num != 0 {
return Err(DecodeError::InvalidOperand);
}
let modrm = read_modrm(words)?;
match (op, modrm & 0xc0) {
- (VEXOperandCode::G_U_xmm, 0xc0) => {
- /* this is the only accepted operand */
- }
- (VEXOperandCode::G_U_xmm, _) |
(VEXOperandCode::G_M_xmm, 0xc0) => {
return Err(DecodeError::InvalidOperand);
}
@@ -820,6 +815,23 @@ fn read_vex_operands<
instruction.operand_count = 2;
Ok(())
}
+ VEXOperandCode::G_U_xmm_vmaskmovdqu => {
+ if instruction.regs[3].num != 0 {
+ return Err(DecodeError::InvalidOperand);
+ }
+ let modrm = read_modrm(words)?;
+ if modrm & 0xc0 != 0xc0 {
+ return Err(DecodeError::InvalidOperand);
+ }
+ instruction.regs[0] =
+ RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
+ instruction.operands[0] = OperandSpec::RegRRR;
+ instruction.operands[1] = mem_oper;
+ instruction.mem_size = 16;
+ instruction.operand_count = 2;
+ Ok(())
+ }
VEXOperandCode::G_xmm_E_xmm => {
if instruction.regs[3].num != 0 {
return Err(DecodeError::InvalidOperand);
@@ -1040,7 +1052,7 @@ fn read_vex_operands<
RegSpec::from_parts((modrm >> 3) & 7, bank);
let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
if mem_oper != OperandSpec::RegMMM {
- if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS {
+ if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS || instruction.opcode == Opcode::VMOVQ {
instruction.mem_size = 8;
} else {
if L {
@@ -1769,10 +1781,10 @@ fn read_vex_instruction<
}),
0xD4 => (Opcode::VPADDQ, VEXOperandCode::G_V_E_xyLmm),
0xD5 => (Opcode::VPMULLW, VEXOperandCode::G_V_E_xyLmm),
- 0xD6 => (Opcode::VMOVD, if L {
+ 0xD6 => (Opcode::VMOVQ, if L {
return Err(DecodeError::InvalidOpcode);
} else {
- VEXOperandCode::G_E_xmm
+ VEXOperandCode::E_G_xyLmm
}),
0xD7 => (Opcode::VPMOVMSKB, VEXOperandCode::Ud_G_xyLmm),
0xD8 => (Opcode::VPSUBUSB, VEXOperandCode::G_V_E_xyLmm),
@@ -1832,7 +1844,7 @@ fn read_vex_instruction<
0xF7 => (Opcode::VMASKMOVDQU, if L {
return Err(DecodeError::InvalidOpcode);
} else {
- VEXOperandCode::G_U_xmm
+ VEXOperandCode::G_U_xmm_vmaskmovdqu
}),
0xF8 => (Opcode::VPSUBB, VEXOperandCode::G_V_E_xyLmm),
0xF9 => (Opcode::VPSUBW, VEXOperandCode::G_V_E_xyLmm),
@@ -1916,7 +1928,7 @@ fn read_vex_instruction<
0x5f => (Opcode::VMAXSS, VEXOperandCode::G_V_E_xmm),
0x6f => (Opcode::VMOVDQU, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }),
0x70 => (Opcode::VPSHUFHW, VEXOperandCode::G_E_xyLmm_imm8),
- 0x7e => (Opcode::VMOVD, if L { return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }),
+ 0x7e => (Opcode::VMOVQ, if L { return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }),
0x7f => (Opcode::VMOVDQU, VEXOperandCode::E_G_xyLmm),
0xc2 => (Opcode::VCMPSS, VEXOperandCode::G_V_E_xmm_imm8),
0xe6 => (Opcode::VCVTDQ2PD, if L { VEXOperandCode::G_ymm_E_xmm } else { VEXOperandCode::G_xmm_E_xmm }),
diff --git a/src/real_mode/vex.rs b/src/real_mode/vex.rs
index bb41165..9e24ee8 100644
--- a/src/real_mode/vex.rs
+++ b/src/real_mode/vex.rs
@@ -46,7 +46,7 @@ enum VEXOperandCode {
VMOVHPS_16,
M_G_xmm,
G_M_xmm,
- G_U_xmm,
+ G_U_xmm_vmaskmovdqu,
Gd_U_xmm,
E_G_xmm_imm8,
Ud_G_xmm_imm8,
@@ -784,17 +784,12 @@ fn read_vex_operands<
}
op @ VEXOperandCode::G_M_xmm |
- op @ VEXOperandCode::G_U_xmm |
op @ VEXOperandCode::G_E_xmm => {
if instruction.regs[3].num != 0 {
return Err(DecodeError::InvalidOperand);
}
let modrm = read_modrm(words)?;
match (op, modrm & 0xc0) {
- (VEXOperandCode::G_U_xmm, 0xc0) => {
- /* this is the only accepted operand */
- }
- (VEXOperandCode::G_U_xmm, _) |
(VEXOperandCode::G_M_xmm, 0xc0) => {
return Err(DecodeError::InvalidOperand);
}
@@ -820,6 +815,23 @@ fn read_vex_operands<
instruction.operand_count = 2;
Ok(())
}
+ VEXOperandCode::G_U_xmm_vmaskmovdqu => {
+ if instruction.regs[3].num != 0 {
+ return Err(DecodeError::InvalidOperand);
+ }
+ let modrm = read_modrm(words)?;
+ if modrm & 0xc0 != 0xc0 {
+ return Err(DecodeError::InvalidOperand);
+ }
+ instruction.regs[0] =
+ RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
+ let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
+ instruction.operands[0] = OperandSpec::RegRRR;
+ instruction.operands[1] = mem_oper;
+ instruction.mem_size = 16;
+ instruction.operand_count = 2;
+ Ok(())
+ }
VEXOperandCode::G_xmm_E_xmm => {
if instruction.regs[3].num != 0 {
return Err(DecodeError::InvalidOperand);
@@ -1040,7 +1052,7 @@ fn read_vex_operands<
RegSpec::from_parts((modrm >> 3) & 7, bank);
let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
if mem_oper != OperandSpec::RegMMM {
- if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS {
+ if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS || instruction.opcode == Opcode::VMOVQ {
instruction.mem_size = 8;
} else {
if L {
@@ -1769,10 +1781,10 @@ fn read_vex_instruction<
}),
0xD4 => (Opcode::VPADDQ, VEXOperandCode::G_V_E_xyLmm),
0xD5 => (Opcode::VPMULLW, VEXOperandCode::G_V_E_xyLmm),
- 0xD6 => (Opcode::VMOVD, if L {
+ 0xD6 => (Opcode::VMOVQ, if L {
return Err(DecodeError::InvalidOpcode);
} else {
- VEXOperandCode::G_E_xmm
+ VEXOperandCode::E_G_xyLmm
}),
0xD7 => (Opcode::VPMOVMSKB, VEXOperandCode::Ud_G_xyLmm),
0xD8 => (Opcode::VPSUBUSB, VEXOperandCode::G_V_E_xyLmm),
@@ -1832,7 +1844,7 @@ fn read_vex_instruction<
0xF7 => (Opcode::VMASKMOVDQU, if L {
return Err(DecodeError::InvalidOpcode);
} else {
- VEXOperandCode::G_U_xmm
+ VEXOperandCode::G_U_xmm_vmaskmovdqu
}),
0xF8 => (Opcode::VPSUBB, VEXOperandCode::G_V_E_xyLmm),
0xF9 => (Opcode::VPSUBW, VEXOperandCode::G_V_E_xyLmm),
@@ -1916,7 +1928,7 @@ fn read_vex_instruction<
0x5f => (Opcode::VMAXSS, VEXOperandCode::G_V_E_xmm),
0x6f => (Opcode::VMOVDQU, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }),
0x70 => (Opcode::VPSHUFHW, VEXOperandCode::G_E_xyLmm_imm8),
- 0x7e => (Opcode::VMOVD, if L { return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }),
+ 0x7e => (Opcode::VMOVQ, if L { return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }),
0x7f => (Opcode::VMOVDQU, VEXOperandCode::E_G_xyLmm),
0xc2 => (Opcode::VCMPSS, VEXOperandCode::G_V_E_xmm_imm8),
0xe6 => (Opcode::VCVTDQ2PD, if L { VEXOperandCode::G_ymm_E_xmm } else { VEXOperandCode::G_xmm_E_xmm }),
diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs
index 066d8c0..3f7d9e0 100644
--- a/test/long_mode/mod.rs
+++ b/test/long_mode/mod.rs
@@ -2337,6 +2337,8 @@ fn test_vex() {
test_avx2(&[0xc4, 0b000_00001, 0b1_1111_101, 0x6d, 0b11_001_010], "vpunpckhqdq ymm9, ymm0, ymm10");
test_instr(&[0xc4, 0b000_00001, 0b1_1111_001, 0x6e, 0b11_001_010], "vmovq xmm9, r10");
test_instr(&[0xc4, 0b000_00001, 0b1_1111_001, 0x6e, 0b00_001_010], "vmovq xmm9, qword [r10]");
+ test_instr(&[0xc4, 0b000_00001, 0b1_1111_001, 0xd6, 0b00_001_010], "vmovq qword [r10], xmm9");
+ test_instr(&[0xc4, 0b000_00001, 0b1_1111_001, 0xd6, 0b11_001_010], "vmovq xmm10, xmm9");
test_invalid(&[0xc4, 0b000_00001, 0b1_1111_101, 0x6e, 0b11_001_010]);
test_instr(&[0xc4, 0b000_00001, 0b0_1111_001, 0x6f, 0b11_001_010], "vmovdqa xmm9, xmm10");
test_instr(&[0xc4, 0b000_00001, 0b0_1111_101, 0x6f, 0b11_001_010], "vmovdqa ymm9, ymm10");
diff --git a/test/long_mode/operand.rs b/test/long_mode/operand.rs
index 379cc7b..bd47cfd 100644
--- a/test/long_mode/operand.rs
+++ b/test/long_mode/operand.rs
@@ -37,6 +37,10 @@ fn memory_widths() {
// "maskmovdqu xmm0, xmm1"
assert_eq!(mem_size_of(&[0x66, 0x4f, 0x0f, 0xf7, 0xc1]).size_name(), "xmmword");
assert_eq!(mem_size_of(&[0x67, 0x66, 0x0f, 0xf7, 0xc1]).size_name(), "xmmword");
+
+ // "vmaskmovdqu xmm0, xmm1"
+ assert_eq!(mem_size_of(&[0xc4, 0xe1, 0x79, 0xf7, 0xc1]).size_name(), "xmmword");
+ assert_eq!(mem_size_of(&[0x67, 0xc4, 0xe1, 0x79, 0xf7, 0xc1]).size_name(), "xmmword");
}
#[test]
diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs
index 4bd5fc5..f152bbe 100644
--- a/test/protected_mode/mod.rs
+++ b/test/protected_mode/mod.rs
@@ -2138,6 +2138,8 @@ fn test_vex() {
test_avx2(&[0xc4, 0b110_00001, 0b1_1111_101, 0x6d, 0b11_001_010], "vpunpckhqdq ymm1, ymm0, ymm2");
test_instr(&[0xc4, 0b110_00001, 0b1_1111_001, 0x6e, 0b11_001_010], "vmovd xmm1, edx");
test_instr(&[0xc4, 0b110_00001, 0b1_1111_001, 0x6e, 0b00_001_010], "vmovd xmm1, dword [edx]");
+ test_instr(&[0xc4, 0b110_00001, 0b1_1111_001, 0xd6, 0b00_001_010], "vmovq qword [edx], xmm1");
+ test_instr(&[0xc4, 0b110_00001, 0b1_1111_001, 0xd6, 0b11_001_010], "vmovq xmm2, xmm1");
test_invalid(&[0xc4, 0b110_00001, 0b1_1111_101, 0x6e, 0b11_001_010]);
test_instr(&[0xc4, 0b110_00001, 0b0_1111_001, 0x6f, 0b11_001_010], "vmovdqa xmm1, xmm2");
test_instr(&[0xc4, 0b110_00001, 0b0_1111_101, 0x6f, 0b11_001_010], "vmovdqa ymm1, ymm2");
diff --git a/test/protected_mode/operand.rs b/test/protected_mode/operand.rs
index cfda896..d90e6ba 100644
--- a/test/protected_mode/operand.rs
+++ b/test/protected_mode/operand.rs
@@ -33,6 +33,10 @@ fn memory_widths() {
// "maskmovdqu xmm0, xmm1"
assert_eq!(mem_size_of(&[0x66, 0x0f, 0xf7, 0xc1]).size_name(), "xmmword");
assert_eq!(mem_size_of(&[0x67, 0x66, 0x0f, 0xf7, 0xc1]).size_name(), "xmmword");
+
+ // "vmaskmovdqu xmm0, xmm1"
+ assert_eq!(mem_size_of(&[0xc4, 0xe1, 0x79, 0xf7, 0xc1]).size_name(), "xmmword");
+ assert_eq!(mem_size_of(&[0x67, 0xc4, 0xe1, 0x79, 0xf7, 0xc1]).size_name(), "xmmword");
}
#[test]
diff --git a/test/real_mode/mod.rs b/test/real_mode/mod.rs
index 90a6c60..f6ace8b 100644
--- a/test/real_mode/mod.rs
+++ b/test/real_mode/mod.rs
@@ -18244,6 +18244,7 @@ fn test_invalid_sequences() {
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_001, 0x14, 0b00_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_001, 0x15, 0b00_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_001, 0x16, 0b00_001_010, 0x77]);
+ test_invalid(&[0xc4, 0b110_00011, 0b0_0111_001, 0x38, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_001, 0x60, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_001, 0x61, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_001, 0x62, 0b11_001_010, 0x77]);
@@ -18254,6 +18255,7 @@ fn test_invalid_sequences() {
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x20, 0b00_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x21, 0b00_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x22, 0b00_001_010, 0x77]);
+ test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x39, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x41, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x60, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_0111_101, 0x61, 0b11_001_010, 0x77]);
@@ -18273,7 +18275,7 @@ fn test_invalid_sequences() {
test_invalid(&[0xc4, 0b110_00011, 0b0_1111_101, 0x62, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b0_1111_101, 0x63, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b1_0111_001, 0x16, 0b00_001_010, 0x77]);
- test_invalid(&[0xc4, 0b110_00011, 0b1_0111_001, 0x18, 0b11_001_010, 0x77]);
+ test_invalid(&[0xc4, 0b110_00011, 0b1_0111_001, 0x38, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b1_0111_001, 0x4c, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b1_0111_001, 0xdf, 0b11_001_010, 0x77]);
test_invalid(&[0xc4, 0b110_00011, 0b1_0111_101, 0x18, 0b11_001_010, 0x77]);
diff --git a/test/real_mode/operand.rs b/test/real_mode/operand.rs
index 68eea48..9b37f36 100644
--- a/test/real_mode/operand.rs
+++ b/test/real_mode/operand.rs
@@ -44,4 +44,8 @@ fn test_implied_memory_width() {
// "maskmovdqu xmm0, xmm1"
assert_eq!(mem_size_of(&[0x66, 0x0f, 0xf7, 0xc1]), Some(16));
assert_eq!(mem_size_of(&[0x67, 0x66, 0x0f, 0xf7, 0xc1]), Some(16));
+
+ // "vmaskmovdqu xmm0, xmm1"
+ assert_eq!(mem_size_of(&[0xc4, 0xe1, 0x79, 0xf7, 0xc1]), Some(16));
+ assert_eq!(mem_size_of(&[0x67, 0xc4, 0xe1, 0x79, 0xf7, 0xc1]), Some(16));
}