Assign arguments for the function call.
(
sig: &ABISig,
callee_context: &ContextArgs,
ret_area: Option<&RetArea>,
context: &mut CodeGenContext<Emission>,
masm: &mut M,
)
| 303 | |
| 304 | /// Assign arguments for the function call. |
| 305 | fn assign<M: MacroAssembler>( |
| 306 | sig: &ABISig, |
| 307 | callee_context: &ContextArgs, |
| 308 | ret_area: Option<&RetArea>, |
| 309 | context: &mut CodeGenContext<Emission>, |
| 310 | masm: &mut M, |
| 311 | ) -> Result<()> { |
| 312 | let arg_count = sig.params.len_without_retptr(); |
| 313 | debug_assert!(arg_count >= callee_context.len()); |
| 314 | let stack = &context.stack; |
| 315 | let stack_values = stack.peekn(arg_count - callee_context.len()); |
| 316 | |
| 317 | if callee_context.len() > 0 { |
| 318 | Self::assign_context_args(&sig, &callee_context, masm)?; |
| 319 | } |
| 320 | |
| 321 | for (arg, val) in sig |
| 322 | .params_without_retptr() |
| 323 | .iter() |
| 324 | .skip(callee_context.len()) |
| 325 | .zip(stack_values) |
| 326 | { |
| 327 | match arg { |
| 328 | &ABIOperand::Reg { reg, .. } => { |
| 329 | context.move_val_to_reg(&val, reg, masm)?; |
| 330 | } |
| 331 | &ABIOperand::Stack { ty, offset, .. } => { |
| 332 | let addr = masm.address_at_sp(SPOffset::from_u32(offset))?; |
| 333 | let size: OperandSize = ty.try_into()?; |
| 334 | masm.with_scratch_for(ty, |masm, scratch| { |
| 335 | context.move_val_to_reg(val, scratch.inner(), masm)?; |
| 336 | masm.store(scratch.inner().into(), addr, size) |
| 337 | })?; |
| 338 | } |
| 339 | } |
| 340 | } |
| 341 | |
| 342 | if sig.has_stack_results() { |
| 343 | let operand = sig.params.unwrap_results_area_operand(); |
| 344 | let base = ret_area.unwrap().unwrap_sp(); |
| 345 | let addr = masm.address_from_sp(base)?; |
| 346 | |
| 347 | match operand { |
| 348 | &ABIOperand::Reg { ty, reg, .. } => { |
| 349 | masm.compute_addr(addr, writable!(reg), ty.try_into()?)?; |
| 350 | } |
| 351 | &ABIOperand::Stack { ty, offset, .. } => { |
| 352 | let slot = masm.address_at_sp(SPOffset::from_u32(offset))?; |
| 353 | // Don't rely on `ABI::scratch_for` as we always use |
| 354 | // an int register as the return pointer. |
| 355 | masm.with_scratch::<IntScratch, _>(|masm, scratch| { |
| 356 | masm.compute_addr(addr, scratch.writable(), ty.try_into()?)?; |
| 357 | masm.store(scratch.inner().into(), slot, ty.try_into()?) |
| 358 | })?; |
| 359 | } |
| 360 | } |
| 361 | } |
| 362 | Ok(()) |
no test coverage detected