| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
#![cfg(target_arch = "aarch64")] |
| 14 |
|
| 15 |
use crate::crc32::fusion::aarch64::{clmul_hi_and_xor, clmul_lo_and_xor}; |
| 16 |
use core::arch::aarch64::{ |
| 17 |
__crc32cb, __crc32cd, veorq_u64, vgetq_lane_u64, vld1q_u64, vmovq_n_u64, vsetq_lane_u64, |
| 18 |
}; |
| 19 |
|
| 20 |
|
| 21 |
|
| 22 |
|
| 23 |
|
| 24 |
|
| 25 |
|
| 26 |
#[inline] |
| 27 |
#[target_feature(enable = "crc,aes")] |
| 28 |
pub(crate) unsafe fn crc32_iscsi_v12e_v1(mut crc0: u32, mut buf: *const u8, mut len: usize) -> u32 { |
| 29 |
|
| 30 |
while len > 0 && (buf as usize & 7) != 0 { |
| 31 |
crc0 = __crc32cb(crc0, *buf); |
| 32 |
buf = buf.add(1); |
| 33 |
len -= 1; |
| 34 |
} |
| 35 |
|
| 36 |
|
| 37 |
if (buf as usize & 8) != 0 && len >= 8 { |
| 38 |
crc0 = __crc32cd(crc0, *(buf as *const u64)); |
| 39 |
buf = buf.add(8); |
| 40 |
len -= 8; |
| 41 |
} |
| 42 |
|
| 43 |
if len >= 192 { |
| 44 |
let end = buf.add(len); |
| 45 |
let limit = buf.add(len - 192); |
| 46 |
|
| 47 |
|
| 48 |
let mut x0 = vld1q_u64(buf as *const u64); |
| 49 |
let mut x1 = vld1q_u64(buf.add(16) as *const u64); |
| 50 |
let mut x2 = vld1q_u64(buf.add(32) as *const u64); |
| 51 |
let mut x3 = vld1q_u64(buf.add(48) as *const u64); |
| 52 |
let mut x4 = vld1q_u64(buf.add(64) as *const u64); |
| 53 |
let mut x5 = vld1q_u64(buf.add(80) as *const u64); |
| 54 |
let mut x6 = vld1q_u64(buf.add(96) as *const u64); |
| 55 |
let mut x7 = vld1q_u64(buf.add(112) as *const u64); |
| 56 |
let mut x8 = vld1q_u64(buf.add(128) as *const u64); |
| 57 |
let mut x9 = vld1q_u64(buf.add(144) as *const u64); |
| 58 |
let mut x10 = vld1q_u64(buf.add(160) as *const u64); |
| 59 |
let mut x11 = vld1q_u64(buf.add(176) as *const u64); |
| 60 |
|
| 61 |
let k_vals: [u64; 2] = [0xa87ab8a8, 0xab7aff2a]; |
| 62 |
let mut k = vld1q_u64(k_vals.as_ptr()); |
| 63 |
|
| 64 |
|
| 65 |
let crc_vec = vsetq_lane_u64(crc0 as u64, vmovq_n_u64(0), 0); |
| 66 |
x0 = veorq_u64(crc_vec, x0); |
| 67 |
buf = buf.add(192); |
| 68 |
|
| 69 |
|
| 70 |
while buf <= limit { |
| 71 |
let y0 = clmul_lo_and_xor(x0, k, vld1q_u64(buf as *const u64)); |
| 72 |
x0 = clmul_hi_and_xor(x0, k, y0); |
| 73 |
let y1 = clmul_lo_and_xor(x1, k, vld1q_u64(buf.add(16) as *const u64)); |
| 74 |
x1 = clmul_hi_and_xor(x1, k, y1); |
| 75 |
let y2 = clmul_lo_and_xor(x2, k, vld1q_u64(buf.add(32) as *const u64)); |
| 76 |
x2 = clmul_hi_and_xor(x2, k, y2); |
| 77 |
let y3 = clmul_lo_and_xor(x3, k, vld1q_u64(buf.add(48) as *const u64)); |
| 78 |
x3 = clmul_hi_and_xor(x3, k, y3); |
| 79 |
let y4 = clmul_lo_and_xor(x4, k, vld1q_u64(buf.add(64) as *const u64)); |
| 80 |
x4 = clmul_hi_and_xor(x4, k, y4); |
| 81 |
let y5 = clmul_lo_and_xor(x5, k, vld1q_u64(buf.add(80) as *const u64)); |
| 82 |
x5 = clmul_hi_and_xor(x5, k, y5); |
| 83 |
let y6 = clmul_lo_and_xor(x6, k, vld1q_u64(buf.add(96) as *const u64)); |
| 84 |
x6 = clmul_hi_and_xor(x6, k, y6); |
| 85 |
let y7 = clmul_lo_and_xor(x7, k, vld1q_u64(buf.add(112) as *const u64)); |
| 86 |
x7 = clmul_hi_and_xor(x7, k, y7); |
| 87 |
let y8 = clmul_lo_and_xor(x8, k, vld1q_u64(buf.add(128) as *const u64)); |
| 88 |
x8 = clmul_hi_and_xor(x8, k, y8); |
| 89 |
let y9 = clmul_lo_and_xor(x9, k, vld1q_u64(buf.add(144) as *const u64)); |
| 90 |
x9 = clmul_hi_and_xor(x9, k, y9); |
| 91 |
let y10 = clmul_lo_and_xor(x10, k, vld1q_u64(buf.add(160) as *const u64)); |
| 92 |
x10 = clmul_hi_and_xor(x10, k, y10); |
| 93 |
let y11 = clmul_lo_and_xor(x11, k, vld1q_u64(buf.add(176) as *const u64)); |
| 94 |
x11 = clmul_hi_and_xor(x11, k, y11); |
| 95 |
buf = buf.add(192); |
| 96 |
} |
| 97 |
|
| 98 |
|
| 99 |
let k_vals: [u64; 2] = [0xf20c0dfe, 0x493c7d27]; |
| 100 |
k = vld1q_u64(k_vals.as_ptr()); |
| 101 |
|
| 102 |
let y0 = clmul_lo_and_xor(x0, k, x1); |
| 103 |
x0 = clmul_hi_and_xor(x0, k, y0); |
| 104 |
let y2 = clmul_lo_and_xor(x2, k, x3); |
| 105 |
x2 = clmul_hi_and_xor(x2, k, y2); |
| 106 |
let y4 = clmul_lo_and_xor(x4, k, x5); |
| 107 |
x4 = clmul_hi_and_xor(x4, k, y4); |
| 108 |
let y6 = clmul_lo_and_xor(x6, k, x7); |
| 109 |
x6 = clmul_hi_and_xor(x6, k, y6); |
| 110 |
let y8 = clmul_lo_and_xor(x8, k, x9); |
| 111 |
x8 = clmul_hi_and_xor(x8, k, y8); |
| 112 |
let y10 = clmul_lo_and_xor(x10, k, x11); |
| 113 |
x10 = clmul_hi_and_xor(x10, k, y10); |
| 114 |
|
| 115 |
let k_vals: [u64; 2] = [0x3da6d0cb, 0xba4fc28e]; |
| 116 |
k = vld1q_u64(k_vals.as_ptr()); |
| 117 |
|
| 118 |
let y0 = clmul_lo_and_xor(x0, k, x2); |
| 119 |
x0 = clmul_hi_and_xor(x0, k, y0); |
| 120 |
let y4 = clmul_lo_and_xor(x4, k, x6); |
| 121 |
x4 = clmul_hi_and_xor(x4, k, y4); |
| 122 |
let y8 = clmul_lo_and_xor(x8, k, x10); |
| 123 |
x8 = clmul_hi_and_xor(x8, k, y8); |
| 124 |
|
| 125 |
let k_vals: [u64; 2] = [0x740eef02, 0x9e4addf8]; |
| 126 |
k = vld1q_u64(k_vals.as_ptr()); |
| 127 |
|
| 128 |
let y0 = clmul_lo_and_xor(x0, k, x4); |
| 129 |
x0 = clmul_hi_and_xor(x0, k, y0); |
| 130 |
x4 = x8; |
| 131 |
let y0 = clmul_lo_and_xor(x0, k, x4); |
| 132 |
x0 = clmul_hi_and_xor(x0, k, y0); |
| 133 |
|
| 134 |
|
| 135 |
crc0 = __crc32cd(0, vgetq_lane_u64(x0, 0)); |
| 136 |
crc0 = __crc32cd(crc0, vgetq_lane_u64(x0, 1)); |
| 137 |
len = end.offset_from(buf) as usize; |
| 138 |
} |
| 139 |
|
| 140 |
if len >= 16 { |
| 141 |
|
| 142 |
let mut x0 = vld1q_u64(buf as *const u64); |
| 143 |
|
| 144 |
let k_vals: [u64; 2] = [0xf20c0dfe, 0x493c7d27]; |
| 145 |
let k = vld1q_u64(k_vals.as_ptr()); |
| 146 |
|
| 147 |
|
| 148 |
let crc_vec = vsetq_lane_u64(crc0 as u64, vmovq_n_u64(0), 0); |
| 149 |
x0 = veorq_u64(crc_vec, x0); |
| 150 |
buf = buf.add(16); |
| 151 |
len -= 16; |
| 152 |
|
| 153 |
|
| 154 |
while len >= 16 { |
| 155 |
let y0 = clmul_lo_and_xor(x0, k, vld1q_u64(buf as *const u64)); |
| 156 |
x0 = clmul_hi_and_xor(x0, k, y0); |
| 157 |
buf = buf.add(16); |
| 158 |
len -= 16; |
| 159 |
} |
| 160 |
|
| 161 |
|
| 162 |
crc0 = __crc32cd(0, vgetq_lane_u64(x0, 0)); |
| 163 |
crc0 = __crc32cd(crc0, vgetq_lane_u64(x0, 1)); |
| 164 |
} |
| 165 |
|
| 166 |
while len >= 8 { |
| 167 |
crc0 = __crc32cd(crc0, *(buf as *const u64)); |
| 168 |
buf = buf.add(8); |
| 169 |
len -= 8; |
| 170 |
} |
| 171 |
|
| 172 |
while len > 0 { |
| 173 |
crc0 = __crc32cb(crc0, *buf); |
| 174 |
buf = buf.add(1); |
| 175 |
len -= 1; |
| 176 |
} |
| 177 |
|
| 178 |
crc0 |
| 179 |
} |