(&mut self, addr: u64, data: u64, n: usize)
| 248 | // Aligned 2/4/8-byte writes stay inside one line: resolve once and, when |
| 249 | // write-through, issue one sized store instead of a write_byte per byte. |
| 250 | if n > 1 && addr & (n as u64 - 1) == 0 { |
| 251 | let (set_idx, way_idx, miss) = self.resolve_line(addr)?; |
| 252 | if miss { |
| 253 | self.stats.write_misses += 1; |
| 254 | } else { |
| 255 | self.stats.write_hits += 1; |
| 256 | } |
| 257 | let offset = (addr & ((1u64 << self.block_bits) - 1)) as usize; |
| 258 | let bytes = data.to_le_bytes(); |
| 259 | self.sets[set_idx].ways[way_idx].data[offset..offset + n].copy_from_slice(&bytes[..n]); |
| 260 | |
| 261 | if self.params.write_back { |
| 262 | self.sets[set_idx].ways[way_idx].dirty = true; |
| 263 | } else { |
| 264 | match n { |
| 265 | 2 => self.next.write_halfword(addr, data as u16)?, |
| 266 | 4 => self.next.write_word(addr, data as u32)?, |
| 267 | 8 => self.next.write_doubleword(addr, data)?, |
| 268 | _ => { |
| 269 | for i in 0..n { |
| 270 | self.next.write_byte(addr + i as u64, bytes[i])?; |
| 271 | } |
| 272 | } |
| 273 | } |
| 274 | } |
| 275 | return Ok(()); |
| 276 | } |
| 277 | |
| 278 | let block_mask = !((1u64 << self.block_bits) - 1); |
| 279 | let mut last_block = u64::MAX; |
| 280 | let mut last_set = 0usize; |
| 281 | let mut last_way = 0usize; |
| 282 | |
| 283 | for i in 0..n { |
| 284 | let byte_addr = addr + i as u64; |
| 285 | let block = byte_addr & block_mask; |
| 286 | |
| 287 | let (set_idx, way_idx) = if block != last_block { |
| 288 | let (si, wi, miss) = self.resolve_line(byte_addr)?; |
| 289 | if miss { |
| 290 | self.stats.write_misses += 1; |
| 291 | } else { |
| 292 | self.stats.write_hits += 1; |
| 293 | } |
| 294 | last_block = block; |
| 295 | last_set = si; |
| 296 | last_way = wi; |
| 297 | (si, wi) |
| 298 | } else { |
| 299 | (last_set, last_way) |
| 300 | }; |
| 301 | |
| 302 | let offset = (byte_addr & !block_mask) as usize; |
| 303 | let byte = ((data >> (i * 8)) & 0xFF) as u8; |
| 304 | self.sets[set_idx].ways[way_idx].data[offset] = byte; |
| 305 | |
| 306 | if self.params.write_back { |
| 307 | self.sets[set_idx].ways[way_idx].dirty = true; |
no test coverage detected