7481 {
7482 __ Comment(
"EmitParamMoves");
7483
7484
7485 const auto& return_location =
7487 if (return_location.IsPointerToMemory()) {
7488 __ Comment(
"return_location.IsPointerToMemory");
7489 const auto& pointer_location =
7490 return_location.AsPointerToMemory().pointer_location();
7491 const auto& pointer_register =
7492 pointer_location.IsRegisters()
7493 ? pointer_location.AsRegisters().reg_at(0)
7494 : temp0;
7495 __ MoveRegister(pointer_register,
SPREG);
7496 __ AddImmediate(pointer_register, marshaller_.PassByPointerStackOffset(
7498
7499 if (pointer_location.IsStack()) {
7500 const auto& pointer_stack = pointer_location.AsStack();
7501 __ StoreMemoryValue(pointer_register, pointer_stack.base_register(),
7502 pointer_stack.offset_in_bytes());
7503 }
7504 }
7505
7506
7508 saved_fp,
7509 0);
7510 intptr_t def_index = 0;
7511 for (intptr_t arg_index = 0; arg_index < marshaller_.num_args();
7512 arg_index++) {
7513 const intptr_t num_defs = marshaller_.NumDefinitions(arg_index);
7514 const auto& arg_target = marshaller_.Location(arg_index);
7515 __ Comment(
"arg_index %" Pd " arg_target %s", arg_index,
7516 arg_target.ToCString());
7517
7518
7519
7520 for (intptr_t
i = 0;
i < num_defs;
i++) {
7521 if ((arg_target.IsPointerToMemory() ||
7522 marshaller_.IsCompoundPointer(arg_index)) &&
7524
7525
7526
7527 def_index++;
7528 continue;
7529 }
7530 __ Comment(
" def_index %" Pd, def_index);
7531 Location origin = rebase.Rebase(
locs()->in(def_index));
7533
7534
7535
7536 const auto& def_target =
7537 arg_target.payload_type().IsPrimitive() ? arg_target
7538 : arg_target.IsMultiple() ? *arg_target.AsMultiple().locations()[
i]
7539 : arg_target.IsPointerToMemory()
7540 ? arg_target.AsPointerToMemory().pointer_location()
7541 : arg_target.Split(
compiler->zone(),
7543
7544 ConstantTemporaryAllocator temp_alloc(temp0);
7545 if (origin.IsConstant()) {
7546 __ Comment(
"origin.IsConstant()");
7547 ASSERT(!marshaller_.IsHandleCType(arg_index));
7548 ASSERT(!marshaller_.IsTypedDataPointer(arg_index));
7549 ASSERT(!marshaller_.IsCompoundPointer(arg_index));
7550 compiler->EmitMoveConst(def_target, origin, origin_rep, &temp_alloc);
7551 } else if (origin.IsPairLocation() &&
7552 (origin.AsPairLocation()->At(0).IsConstant() ||
7553 origin.AsPairLocation()->At(1).IsConstant())) {
7554
7555 __ Comment(
"origin.IsPairLocation() and constant");
7556 ASSERT(!marshaller_.IsHandleCType(arg_index));
7557 ASSERT(!marshaller_.IsTypedDataPointer(arg_index));
7558 ASSERT(!marshaller_.IsCompoundPointer(arg_index));
7559 compiler->EmitMoveConst(def_target, origin, origin_rep, &temp_alloc);
7560 } else if (marshaller_.IsHandleCType(arg_index)) {
7561 __ Comment(
"marshaller_.IsHandleCType(arg_index)");
7562
7563
7564 ASSERT(origin_rep == kTagged);
7569 ASSERT(origin.IsStackSlot());
7570 if (def_target.IsRegisters()) {
7571 __ AddImmediate(def_target.AsLocation().reg(), origin.base_reg(),
7573 } else {
7574 ASSERT(def_target.IsStack());
7575 const auto& target_stack = def_target.AsStack();
7576 __ AddImmediate(temp0, origin.base_reg(),
7578 __ StoreToOffset(temp0, target_stack.base_register(),
7579 target_stack.offset_in_bytes());
7580 }
7581 } else {
7582 __ Comment(
"def_target %s <- origin %s %s",
7583 def_target.ToCString(
compiler->zone()), origin.ToCString(),
7585#ifdef DEBUG
7586
7587
7588
7589
7590
7591 if (def_target.IsStack()) {
7592 const auto& def_target_stack = def_target.AsStack();
7593 ASSERT(def_target_stack.offset_in_bytes() +
7594 def_target.payload_type().SizeInBytes() <=
7595 marshaller_.RequiredStackSpaceInBytes());
7596 }
7597#endif
7598 if (marshaller_.IsTypedDataPointer(arg_index) ||
7599 marshaller_.IsCompoundPointer(arg_index)) {
7600
7601 __ Comment(
"Load typed data base address");
7602 if (origin.IsStackSlot()) {
7604 &temp_alloc);
7606 }
7607 ASSERT(origin.IsRegister());
7608 __ LoadFromSlot(origin.reg(), origin.reg(), Slot::PointerBase_data());
7609 if (marshaller_.IsCompoundPointer(arg_index)) {
7610 __ Comment(
"Load offset in bytes");
7611 const intptr_t offset_in_bytes_def_index = def_index + 1;
7612 const Location offset_in_bytes_loc =
7613 rebase.Rebase(
locs()->in(offset_in_bytes_def_index));
7615 if (offset_in_bytes_loc.IsRegister()) {
7616 offset_in_bytes_reg = offset_in_bytes_loc.reg();
7617 } else {
7618 offset_in_bytes_reg = temp1;
7619 NoTemporaryAllocator no_temp;
7622 offset_in_bytes_loc, &no_temp);
7623 }
7624 __ AddRegisters(origin.reg(), offset_in_bytes_reg);
7625 }
7626 }
7627 compiler->EmitMoveToNative(def_target, origin, origin_rep, &temp_alloc);
7628 }
7629 def_index++;
7630 }
7631
7632
7633
7634
7635
7636 if (arg_target.IsPointerToMemory()) {
7637 __ Comment(
"arg_target.IsPointerToMemory");
7638 NoTemporaryAllocator temp_alloc;
7639 const auto& pointer_loc =
7640 arg_target.AsPointerToMemory().pointer_location();
7641
7642
7643 const auto&
dst = compiler::ffi::NativeRegistersLocation(
7644 compiler->zone(), pointer_loc.payload_type(),
7645 pointer_loc.container_type(), temp0);
7646 compiler->EmitNativeMove(
dst, pointer_loc, &temp_alloc);
7647 __ LoadFromSlot(temp0, temp0, Slot::PointerBase_data());
7648
7649 __ Comment(
"IsPointerToMemory add offset");
7650 const intptr_t offset_in_bytes_def_index =
7651 def_index - 1;
7652 const Location offset_in_bytes_loc =
7653 rebase.Rebase(
locs()->in(offset_in_bytes_def_index));
7655 if (offset_in_bytes_loc.IsRegister()) {
7656 offset_in_bytes_reg = offset_in_bytes_loc.reg();
7657 } else {
7658 offset_in_bytes_reg = temp1;
7659 NoTemporaryAllocator no_temp;
7661 offset_in_bytes_loc, &no_temp);
7662 }
7663 __ AddRegisters(temp0, offset_in_bytes_reg);
7664
7665
7666
7667
7668
7669 __ Comment(
"IsPointerToMemory copy chunks");
7670 const intptr_t sp_offset =
7671 marshaller_.PassByPointerStackOffset(arg_index);
7672 __ UnrolledMemCopy(
SPREG, sp_offset, temp0, 0,
7673 arg_target.payload_type().SizeInBytes(), temp1);
7674
7675
7676 __ MoveRegister(temp0,
SPREG);
7677 __ AddImmediate(temp0, sp_offset);
7678 const auto&
src = compiler::ffi::NativeRegistersLocation(
7679 compiler->zone(), pointer_loc.payload_type(),
7680 pointer_loc.container_type(), temp0);
7681 __ Comment(
"pointer_loc %s <- src %s", pointer_loc.ToCString(),
7683 compiler->EmitNativeMove(pointer_loc,
src, &temp_alloc);
7684 }
7685 }
7686
7687 __ Comment(
"EmitParamMovesEnd");
7688}
virtual Representation RequiredInputRepresentation(intptr_t idx) const
static Location RegisterLocation(Register reg)
static word InstanceSize()
const intptr_t kResultIndex
static constexpr intptr_t kWordSize
static const char * ToCString(Representation rep)