7424 {
7425 __ Comment(
"EmitParamMoves");
7426
7427
7428 const auto& return_location =
7430 if (return_location.IsPointerToMemory()) {
7431 __ Comment(
"return_location.IsPointerToMemory");
7432 const auto& pointer_location =
7433 return_location.AsPointerToMemory().pointer_location();
7434 const auto& pointer_register =
7435 pointer_location.IsRegisters()
7436 ? pointer_location.AsRegisters().reg_at(0)
7437 : temp0;
7438 __ MoveRegister(pointer_register,
SPREG);
7439 __ AddImmediate(pointer_register, marshaller_.PassByPointerStackOffset(
7441
7442 if (pointer_location.IsStack()) {
7443 const auto& pointer_stack = pointer_location.AsStack();
7444 __ StoreMemoryValue(pointer_register, pointer_stack.base_register(),
7445 pointer_stack.offset_in_bytes());
7446 }
7447 }
7448
7449
7451 saved_fp,
7452 0);
7453 intptr_t def_index = 0;
7454 for (intptr_t arg_index = 0; arg_index < marshaller_.num_args();
7455 arg_index++) {
7456 const intptr_t num_defs = marshaller_.NumDefinitions(arg_index);
7457 const auto& arg_target = marshaller_.Location(arg_index);
7458 __ Comment(
"arg_index %" Pd " arg_target %s", arg_index,
7459 arg_target.ToCString());
7460
7461
7462
7463 for (intptr_t i = 0; i < num_defs; i++) {
7464 if ((arg_target.IsPointerToMemory() ||
7465 marshaller_.IsCompoundPointer(arg_index)) &&
7466 i == 1) {
7467
7468
7469
7470 def_index++;
7471 continue;
7472 }
7473 __ Comment(
" def_index %" Pd, def_index);
7474 Location origin = rebase.Rebase(
locs()->in(def_index));
7476
7477
7478
7479 const auto& def_target =
7480 arg_target.payload_type().IsPrimitive() ? arg_target
7481 : arg_target.IsMultiple() ? *arg_target.AsMultiple().locations()[i]
7482 : arg_target.IsPointerToMemory()
7483 ? arg_target.AsPointerToMemory().pointer_location()
7484 : arg_target.Split(
compiler->zone(),
7485 num_defs, i);
7486
7487 ConstantTemporaryAllocator temp_alloc(temp0);
7488 if (origin.IsConstant()) {
7489 __ Comment(
"origin.IsConstant()");
7490 ASSERT(!marshaller_.IsHandleCType(arg_index));
7491 ASSERT(!marshaller_.IsTypedDataPointer(arg_index));
7492 ASSERT(!marshaller_.IsCompoundPointer(arg_index));
7493 compiler->EmitMoveConst(def_target, origin, origin_rep, &temp_alloc);
7494 } else if (origin.IsPairLocation() &&
7495 (origin.AsPairLocation()->At(0).IsConstant() ||
7496 origin.AsPairLocation()->At(1).IsConstant())) {
7497
7498 __ Comment(
"origin.IsPairLocation() and constant");
7499 ASSERT(!marshaller_.IsHandleCType(arg_index));
7500 ASSERT(!marshaller_.IsTypedDataPointer(arg_index));
7501 ASSERT(!marshaller_.IsCompoundPointer(arg_index));
7502 compiler->EmitMoveConst(def_target, origin, origin_rep, &temp_alloc);
7503 } else if (marshaller_.IsHandleCType(arg_index)) {
7504 __ Comment(
"marshaller_.IsHandleCType(arg_index)");
7505
7506
7507 ASSERT(origin_rep == kTagged);
7508 ASSERT(compiler::target::LocalHandle::ptr_offset() == 0);
7509 ASSERT(compiler::target::LocalHandle::InstanceSize() ==
7510 compiler::target::kWordSize);
7512 ASSERT(origin.IsStackSlot());
7513 if (def_target.IsRegisters()) {
7514 __ AddImmediate(def_target.AsLocation().reg(), origin.base_reg(),
7515 origin.stack_index() * compiler::target::kWordSize);
7516 } else {
7517 ASSERT(def_target.IsStack());
7518 const auto& target_stack = def_target.AsStack();
7519 __ AddImmediate(temp0, origin.base_reg(),
7520 origin.stack_index() * compiler::target::kWordSize);
7521 __ StoreToOffset(temp0, target_stack.base_register(),
7522 target_stack.offset_in_bytes());
7523 }
7524 } else {
7525 __ Comment(
"def_target %s <- origin %s %s",
7526 def_target.ToCString(
compiler->zone()), origin.ToCString(),
7528#ifdef DEBUG
7529
7530
7531
7532
7533
7534 if (def_target.IsStack()) {
7535 const auto& def_target_stack = def_target.AsStack();
7536 ASSERT(def_target_stack.offset_in_bytes() +
7537 def_target.payload_type().SizeInBytes() <=
7538 marshaller_.RequiredStackSpaceInBytes());
7539 }
7540#endif
7541 if (marshaller_.IsTypedDataPointer(arg_index) ||
7542 marshaller_.IsCompoundPointer(arg_index)) {
7543
7544 __ Comment(
"Load typed data base address");
7545 if (origin.IsStackSlot()) {
7547 &temp_alloc);
7549 }
7550 ASSERT(origin.IsRegister());
7551 __ LoadFromSlot(origin.reg(), origin.reg(), Slot::PointerBase_data());
7552 if (marshaller_.IsCompoundPointer(arg_index)) {
7553 __ Comment(
"Load offset in bytes");
7554 const intptr_t offset_in_bytes_def_index = def_index + 1;
7555 const Location offset_in_bytes_loc =
7556 rebase.Rebase(
locs()->in(offset_in_bytes_def_index));
7558 if (offset_in_bytes_loc.IsRegister()) {
7559 offset_in_bytes_reg = offset_in_bytes_loc.reg();
7560 } else {
7561 offset_in_bytes_reg = temp1;
7562 NoTemporaryAllocator no_temp;
7565 offset_in_bytes_loc, &no_temp);
7566 }
7567 __ AddRegisters(origin.reg(), offset_in_bytes_reg);
7568 }
7569 }
7570 compiler->EmitMoveToNative(def_target, origin, origin_rep, &temp_alloc);
7571 }
7572 def_index++;
7573 }
7574
7575
7576
7577
7578
7579 if (arg_target.IsPointerToMemory()) {
7580 __ Comment(
"arg_target.IsPointerToMemory");
7581 NoTemporaryAllocator temp_alloc;
7582 const auto& pointer_loc =
7583 arg_target.AsPointerToMemory().pointer_location();
7584
7585
7586 const auto&
dst = compiler::ffi::NativeRegistersLocation(
7587 compiler->zone(), pointer_loc.payload_type(),
7588 pointer_loc.container_type(), temp0);
7589 compiler->EmitNativeMove(dst, pointer_loc, &temp_alloc);
7590 __ LoadFromSlot(temp0, temp0, Slot::PointerBase_data());
7591
7592 __ Comment(
"IsPointerToMemory add offset");
7593 const intptr_t offset_in_bytes_def_index =
7594 def_index - 1;
7595 const Location offset_in_bytes_loc =
7596 rebase.Rebase(
locs()->in(offset_in_bytes_def_index));
7598 if (offset_in_bytes_loc.IsRegister()) {
7599 offset_in_bytes_reg = offset_in_bytes_loc.reg();
7600 } else {
7601 offset_in_bytes_reg = temp1;
7602 NoTemporaryAllocator no_temp;
7604 offset_in_bytes_loc, &no_temp);
7605 }
7606 __ AddRegisters(temp0, offset_in_bytes_reg);
7607
7608
7609
7610
7611
7612 __ Comment(
"IsPointerToMemory copy chunks");
7613 const intptr_t sp_offset =
7614 marshaller_.PassByPointerStackOffset(arg_index);
7615 __ UnrolledMemCopy(
SPREG, sp_offset, temp0, 0,
7616 arg_target.payload_type().SizeInBytes(), temp1);
7617
7618
7619 __ MoveRegister(temp0,
SPREG);
7620 __ AddImmediate(temp0, sp_offset);
7621 const auto&
src = compiler::ffi::NativeRegistersLocation(
7622 compiler->zone(), pointer_loc.payload_type(),
7623 pointer_loc.container_type(), temp0);
7624 __ Comment(
"pointer_loc %s <- src %s", pointer_loc.ToCString(),
7626 compiler->EmitNativeMove(pointer_loc, src, &temp_alloc);
7627 }
7628 }
7629
7630 __ Comment(
"EmitParamMovesEnd");
7631}
virtual Representation RequiredInputRepresentation(intptr_t idx) const
static Location RegisterLocation(Register reg)
const intptr_t kResultIndex
static const char * ToCString(Representation rep)