(&mut self, vmctx: Reg)
| 167 | } |
| 168 | |
| 169 | fn check_stack(&mut self, vmctx: Reg) -> Result<()> { |
| 170 | let ptr_size_u8: u8 = self.ptr_size.bytes().try_into().unwrap(); |
| 171 | |
| 172 | // The PatchableAddToReg construct on aarch64 is not a single |
| 173 | // add-immediate instruction, but a 3-instruction sequence that loads an |
| 174 | // immediate using 2 mov-immediate instructions into _another_ scratch |
| 175 | // register before adding it into the target scratch register. |
| 176 | // |
| 177 | // In other words, to make this work we use _two_ scratch registers, one |
| 178 | // to hold the limit we're calculating and one helper that's just used |
| 179 | // to load the immediate. |
| 180 | // |
| 181 | // Luckily on aarch64 we have 2 available scratch registers, ip0 and |
| 182 | // ip1. |
| 183 | // NB that this in this case, we manually allocate the scratch registers |
| 184 | // as precision when it comes to its usage is |
| 185 | |
| 186 | let ptr_size = self.ptr_size; |
| 187 | self.with_aligned_sp(|masm| { |
| 188 | masm.with_scratch::<IntScratch, _>(|masm, scratch_stk_limit| { |
| 189 | masm.with_scratch::<IntScratch, _>(|masm, scratch_tmp| { |
| 190 | masm.load_ptr( |
| 191 | masm.address_at_reg(vmctx, ptr_size_u8.vmcontext_store_context().into())?, |
| 192 | scratch_stk_limit.writable(), |
| 193 | )?; |
| 194 | |
| 195 | masm.load_ptr( |
| 196 | Address::offset( |
| 197 | scratch_stk_limit.inner(), |
| 198 | ptr_size_u8.vmstore_context_stack_limit().into(), |
| 199 | ), |
| 200 | scratch_stk_limit.writable(), |
| 201 | )?; |
| 202 | |
| 203 | masm.add_stack_max(scratch_stk_limit.writable(), scratch_tmp.writable()); |
| 204 | |
| 205 | // Aarch can only do a cmp with sp in the first operand, which means we |
| 206 | // use a less-than comparison, not a greater-than (stack grows down). |
| 207 | masm.cmp(regs::sp(), scratch_stk_limit.inner().into(), ptr_size)?; |
| 208 | masm.asm |
| 209 | .trapif(IntCmpKind::LtU.into(), TrapCode::STACK_OVERFLOW); |
| 210 | |
| 211 | Ok(()) |
| 212 | }) |
| 213 | }) |
| 214 | }) |
| 215 | } |
| 216 | |
| 217 | fn frame_restore(&mut self) -> Result<()> { |
| 218 | debug_assert_eq!(self.sp_offset, 0); |
nothing calls this directly
no test coverage detected