msg_tool\utils/
mmx.rs

1//! MMX Operations in pure Rust
2
3/// Packed Add of Bytes (8-bit integers)
4pub const fn mmx_p_add_b(a: u64, b: u64) -> u64 {
5    let mut mask = 0xFF;
6    let mut r = ((a & mask).wrapping_add(b & mask)) & mask; // First byte
7    mask <<= 8;
8    r |= ((a & mask).wrapping_add(b & mask)) & mask; // Second byte
9    mask <<= 8;
10    r |= ((a & mask).wrapping_add(b & mask)) & mask; // Third byte
11    mask <<= 8;
12    r |= ((a & mask).wrapping_add(b & mask)) & mask; // Fourth byte
13    mask <<= 8;
14    r |= ((a & mask).wrapping_add(b & mask)) & mask; // Fifth byte
15    mask <<= 8;
16    r |= ((a & mask).wrapping_add(b & mask)) & mask; // Sixth byte
17    mask <<= 8;
18    r |= ((a & mask).wrapping_add(b & mask)) & mask; // Seventh byte
19    mask <<= 8;
20    r |= ((a & mask).wrapping_add(b & mask)) & mask; // Eighth byte
21    r
22}
23
24/// Packed Add of Doublewords (32-bit integers)
25pub const fn mmx_p_add_d(a: u64, b: u64) -> u64 {
26    let mut mask = 0xffffffff;
27    let r = ((a & mask).wrapping_add(b & mask)) & mask;
28    mask <<= 32;
29    r | ((a & mask).wrapping_add(b & mask)) & mask
30}
31
32/// Packed Add of Words (16-bit integers)
33pub const fn mmx_p_add_w(a: u64, b: u64) -> u64 {
34    let mut mask = 0xFFFF;
35    let mut r = ((a & mask).wrapping_add(b & mask)) & mask;
36    mask <<= 16;
37    r |= ((a & mask).wrapping_add(b & mask)) & mask;
38    mask <<= 16;
39    r |= ((a & mask).wrapping_add(b & mask)) & mask;
40    mask <<= 16;
41    r |= ((a & mask).wrapping_add(b & mask)) & mask;
42    r
43}
44
45/// Packed Shift Left Logical of Doublewords (32-bit integers)
46pub const fn mmx_p_sll_d(a: u64, mut count: u32) -> u64 {
47    count &= 0x1F;
48    let mut mask = (0xFFFFFFFFu32 << count) as u64;
49    mask |= mask << 32;
50    (a << count) & mask
51}
52
53/// Packed Shift Right Logical of Doublewords (32-bit integers)
54pub const fn mmx_p_srl_d(a: u64, mut count: u32) -> u64 {
55    count &= 0x1F;
56    let mut mask = (0xFFFFFFFFu32 >> count) as u64;
57    mask |= mask << 32;
58    (a >> count) & mask
59}
60
61/// Packed Unpack Low Doubleword
62pub const fn mmx_punpckldq(a: u64, b: u64) -> u64 {
63    (a & 0xFFFFFFFF) | (b & 0xFFFFFFFF) << 32
64}
65
66/// Packed Unpack Low Doubleword with itself
67pub const fn mmx_punpckldq2(a: u64) -> u64 {
68    mmx_punpckldq(a, a)
69}
70
71#[test]
72fn test_mmx() {
73    assert_eq!(mmx_punpckldq(0x1, 0x2), 0x200000001);
74}