Performs a memory move of bytes from src to dest. Bytes are moved in blocks of 8 bytes, where possible.
(
&mut self,
src: SPOffset,
dst: SPOffset,
bytes: u32,
direction: MemMoveDirection,
)
| 1550 | /// Performs a memory move of bytes from src to dest. |
| 1551 | /// Bytes are moved in blocks of 8 bytes, where possible. |
| 1552 | fn memmove( |
| 1553 | &mut self, |
| 1554 | src: SPOffset, |
| 1555 | dst: SPOffset, |
| 1556 | bytes: u32, |
| 1557 | direction: MemMoveDirection, |
| 1558 | ) -> Result<()> { |
| 1559 | match direction { |
| 1560 | MemMoveDirection::LowToHigh => debug_assert!(dst.as_u32() < src.as_u32()), |
| 1561 | MemMoveDirection::HighToLow => debug_assert!(dst.as_u32() > src.as_u32()), |
| 1562 | } |
| 1563 | // At least 4 byte aligned. |
| 1564 | debug_assert!(bytes % 4 == 0); |
| 1565 | let mut remaining = bytes; |
| 1566 | let word_bytes = <Self::ABI as abi::ABI>::word_bytes(); |
| 1567 | |
| 1568 | let word_bytes = word_bytes as u32; |
| 1569 | |
| 1570 | let mut dst_offs; |
| 1571 | let mut src_offs; |
| 1572 | match direction { |
| 1573 | MemMoveDirection::LowToHigh => { |
| 1574 | dst_offs = dst.as_u32() - bytes; |
| 1575 | src_offs = src.as_u32() - bytes; |
| 1576 | self.with_scratch::<IntScratch, _>(|masm, scratch| { |
| 1577 | while remaining >= word_bytes { |
| 1578 | remaining -= word_bytes; |
| 1579 | dst_offs += word_bytes; |
| 1580 | src_offs += word_bytes; |
| 1581 | |
| 1582 | masm.load_ptr( |
| 1583 | masm.address_from_sp(SPOffset::from_u32(src_offs))?, |
| 1584 | scratch.writable(), |
| 1585 | )?; |
| 1586 | masm.store_ptr( |
| 1587 | scratch.inner(), |
| 1588 | masm.address_from_sp(SPOffset::from_u32(dst_offs))?, |
| 1589 | )?; |
| 1590 | } |
| 1591 | wasmtime_environ::error::Ok(()) |
| 1592 | })?; |
| 1593 | } |
| 1594 | MemMoveDirection::HighToLow => { |
| 1595 | // Go from the end to the beginning to handle overlapping addresses. |
| 1596 | src_offs = src.as_u32(); |
| 1597 | dst_offs = dst.as_u32(); |
| 1598 | self.with_scratch::<IntScratch, _>(|masm, scratch| { |
| 1599 | while remaining >= word_bytes { |
| 1600 | masm.load_ptr( |
| 1601 | masm.address_from_sp(SPOffset::from_u32(src_offs))?, |
| 1602 | scratch.writable(), |
| 1603 | )?; |
| 1604 | masm.store_ptr( |
| 1605 | scratch.inner(), |
| 1606 | masm.address_from_sp(SPOffset::from_u32(dst_offs))?, |
| 1607 | )?; |
| 1608 | |
| 1609 | remaining -= word_bytes; |