1080 //
1081
1082 typedef struct {
1083 int insts_call_instruction_offset;
1084 int ret_addr_offset;
1085 } EmitCallOffsets;
1086
1087 // Emit a branch-and-link instruction that branches to a trampoline.
1088 // - Remember the offset of the branch-and-link instruction.
1089 // - Add a relocation at the branch-and-link instruction.
1090 // - Emit a branch-and-link.
1091 // - Remember the return pc offset.
1092 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) {
1093 EmitCallOffsets offsets = { -1, -1 };
1094 const int start_offset = __ offset();
1095 offsets.insts_call_instruction_offset = __ offset();
1096
1097 // No entry point given, use the current pc.
1098 if (entry_point == NULL) entry_point = __ pc();
1099
1100 if (!Compile::current()->in_scratch_emit_size()) {
1101 // Put the entry point as a constant into the constant pool.
1102 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
1103 if (entry_point_toc_addr == NULL) {
1104 ciEnv::current()->record_out_of_memory_failure();
1105 return offsets;
1106 }
1107 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
1108
1109 // Emit the trampoline stub which will be related to the branch-and-link below.
1110 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
1111 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
1112 __ relocate(rtype);
1113 }
1114
1115 // Note: At this point we do not have the address of the trampoline
1116 // stub, and the entry point might be too far away for bl, so __ pc()
1117 // serves as dummy and the bl will be patched later.
1118 __ bl((address) __ pc());
1119
1120 offsets.ret_addr_offset = __ offset() - start_offset;
1121
1122 return offsets;
1123 }
1124
1125 //=============================================================================
1126
1127 // Factory for creating loadConL* nodes for large/small constant pool.
1128
1129 static inline jlong replicate_immF(float con) {
1130 // Replicate float con 2 times and pack into vector.
1131 int val = *((int*)&con);
1132 jlong lval = val;
1133 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
2407 // Operand 'ds' requires 4-alignment.
2408 assert((Idisp & 0x3) == 0, "unaligned offset");
2409 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2410 __ twi_0($dst$$Register);
2411 __ isync();
2412 %}
2413
2414 enc_class enc_lfd(RegF dst, memory mem) %{
2415 // TODO: PPC port $archOpcode(ppc64Opcode_lfd);
2416 MacroAssembler _masm(&cbuf);
2417 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2418 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2419 %}
2420
2421 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2422 // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2423
2424 MacroAssembler _masm(&cbuf);
2425 int toc_offset = 0;
2426
2427 if (!ra_->C->in_scratch_emit_size()) {
2428 address const_toc_addr;
2429 // Create a non-oop constant, no relocation needed.
2430 // If it is an IC, it has a virtual_call_Relocation.
2431 const_toc_addr = __ long_constant((jlong)$src$$constant);
2432 if (const_toc_addr == NULL) {
2433 ciEnv::current()->record_out_of_memory_failure();
2434 return;
2435 }
2436
2437 // Get the constant's TOC offset.
2438 toc_offset = __ offset_to_method_toc(const_toc_addr);
2439
2440 // Keep the current instruction offset in mind.
2441 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2442 }
2443
2444 __ ld($dst$$Register, toc_offset, $toc$$Register);
2445 %}
2446
2447 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2448 // TODO: PPC port $archOpcode(ppc64Opcode_addis);
2449
2450 MacroAssembler _masm(&cbuf);
2451
2452 if (!ra_->C->in_scratch_emit_size()) {
2453 address const_toc_addr;
2454 // Create a non-oop constant, no relocation needed.
2455 // If it is an IC, it has a virtual_call_Relocation.
2456 const_toc_addr = __ long_constant((jlong)$src$$constant);
2457 if (const_toc_addr == NULL) {
2458 ciEnv::current()->record_out_of_memory_failure();
2459 return;
2460 }
2461
2462 // Get the constant's TOC offset.
2559 // Create new nodes.
2560 loadConLNodesTuple loadConLNodes =
2561 loadConLNodesTuple_create(ra_, n_toc, op_src,
2562 ra_->get_reg_second(this), ra_->get_reg_first(this));
2563
2564 // Push new nodes.
2565 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2566 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2567
2568 // some asserts
2569 assert(nodes->length() >= 1, "must have created at least 1 node");
2570 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2571 %}
2572
2573 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2574 // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2575
2576 MacroAssembler _masm(&cbuf);
2577 int toc_offset = 0;
2578
2579 if (!ra_->C->in_scratch_emit_size()) {
2580 intptr_t val = $src$$constant;
2581 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2582 address const_toc_addr;
2583 if (constant_reloc == relocInfo::oop_type) {
2584 // Create an oop constant and a corresponding relocation.
2585 AddressLiteral a = __ allocate_oop_address((jobject)val);
2586 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2587 __ relocate(a.rspec());
2588 } else if (constant_reloc == relocInfo::metadata_type) {
2589 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2590 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2591 __ relocate(a.rspec());
2592 } else {
2593 // Create a non-oop constant, no relocation needed.
2594 const_toc_addr = __ long_constant((jlong)$src$$constant);
2595 }
2596
2597 if (const_toc_addr == NULL) {
2598 ciEnv::current()->record_out_of_memory_failure();
2599 return;
2600 }
2601 // Get the constant's TOC offset.
2602 toc_offset = __ offset_to_method_toc(const_toc_addr);
2603 }
2604
2605 __ ld($dst$$Register, toc_offset, $toc$$Register);
2606 %}
2607
2608 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2609 // TODO: PPC port $archOpcode(ppc64Opcode_addis);
2610
2611 MacroAssembler _masm(&cbuf);
2612 if (!ra_->C->in_scratch_emit_size()) {
2613 intptr_t val = $src$$constant;
2614 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2615 address const_toc_addr;
2616 if (constant_reloc == relocInfo::oop_type) {
2617 // Create an oop constant and a corresponding relocation.
2618 AddressLiteral a = __ allocate_oop_address((jobject)val);
2619 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2620 __ relocate(a.rspec());
2621 } else if (constant_reloc == relocInfo::metadata_type) {
2622 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2623 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
3255 // - Branches directly to a compiled method if the offset is encodable in instruction.
3256 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3257 // - Branches to the compiled_to_interp stub if the target is interpreted.
3258 //
3259 // Further there are three relocations from the loads to the constants in
3260 // the constant section.
3261 //
3262 // Usage of r1 and r2 in the stubs allows to distinguish them.
3263 enc_class enc_java_static_call(method meth) %{
3264 // TODO: PPC port $archOpcode(ppc64Opcode_bl);
3265
3266 MacroAssembler _masm(&cbuf);
3267 address entry_point = (address)$meth$$method;
3268
3269 if (!_method) {
3270 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3271 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type);
3272 } else {
3273 // Remember the offset not the address.
3274 const int start_offset = __ offset();
3275 // The trampoline stub.
3276 if (!Compile::current()->in_scratch_emit_size()) {
3277 // No entry point given, use the current pc.
3278 // Make sure branch fits into
3279 if (entry_point == 0) entry_point = __ pc();
3280
3281 // Put the entry point as a constant into the constant pool.
3282 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
3283 if (entry_point_toc_addr == NULL) {
3284 ciEnv::current()->record_out_of_memory_failure();
3285 return;
3286 }
3287 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
3288
3289
3290 // Emit the trampoline stub which will be related to the branch-and-link below.
3291 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
3292 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3293 int method_index = resolved_method_index(cbuf);
3294 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3295 : static_call_Relocation::spec(method_index));
3296 }
3297
3298 // The real call.
3299 // Note: At this point we do not have the address of the trampoline
3300 // stub, and the entry point might be too far away for bl, so __ pc()
3301 // serves as dummy and the bl will be patched later.
3302 cbuf.set_insts_mark();
3303 __ bl(__ pc()); // Emits a relocation.
3304
3305 // The stub for call to interpreter.
3306 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
3307 if (stub == NULL) {
3308 ciEnv::current()->record_failure("CodeCache is full");
3309 return;
3310 }
3311 }
3312 %}
3313
3314 // Second node of expanded dynamic call - the call.
3315 enc_class enc_java_dynamic_call_sched(method meth) %{
3316 // TODO: PPC port $archOpcode(ppc64Opcode_bl);
|
1080 //
1081
1082 typedef struct {
1083 int insts_call_instruction_offset;
1084 int ret_addr_offset;
1085 } EmitCallOffsets;
1086
1087 // Emit a branch-and-link instruction that branches to a trampoline.
1088 // - Remember the offset of the branch-and-link instruction.
1089 // - Add a relocation at the branch-and-link instruction.
1090 // - Emit a branch-and-link.
1091 // - Remember the return pc offset.
1092 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) {
1093 EmitCallOffsets offsets = { -1, -1 };
1094 const int start_offset = __ offset();
1095 offsets.insts_call_instruction_offset = __ offset();
1096
1097 // No entry point given, use the current pc.
1098 if (entry_point == NULL) entry_point = __ pc();
1099
1100 // Put the entry point as a constant into the constant pool.
1101 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
1102 if (entry_point_toc_addr == NULL) {
1103 ciEnv::current()->record_out_of_memory_failure();
1104 return offsets;
1105 }
1106 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
1107
1108 // Emit the trampoline stub which will be related to the branch-and-link below.
1109 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
1110 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
1111 __ relocate(rtype);
1112
1113 // Note: At this point we do not have the address of the trampoline
1114 // stub, and the entry point might be too far away for bl, so __ pc()
1115 // serves as dummy and the bl will be patched later.
1116 __ bl((address) __ pc());
1117
1118 offsets.ret_addr_offset = __ offset() - start_offset;
1119
1120 return offsets;
1121 }
1122
1123 //=============================================================================
1124
1125 // Factory for creating loadConL* nodes for large/small constant pool.
1126
1127 static inline jlong replicate_immF(float con) {
1128 // Replicate float con 2 times and pack into vector.
1129 int val = *((int*)&con);
1130 jlong lval = val;
1131 lval = (lval << 32) | (lval & 0xFFFFFFFFl);
2405 // Operand 'ds' requires 4-alignment.
2406 assert((Idisp & 0x3) == 0, "unaligned offset");
2407 __ ld($dst$$Register, Idisp, $mem$$base$$Register);
2408 __ twi_0($dst$$Register);
2409 __ isync();
2410 %}
2411
2412 enc_class enc_lfd(RegF dst, memory mem) %{
2413 // TODO: PPC port $archOpcode(ppc64Opcode_lfd);
2414 MacroAssembler _masm(&cbuf);
2415 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
2416 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
2417 %}
2418
2419 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
2420 // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2421
2422 MacroAssembler _masm(&cbuf);
2423 int toc_offset = 0;
2424
2425 address const_toc_addr;
2426 // Create a non-oop constant, no relocation needed.
2427 // If it is an IC, it has a virtual_call_Relocation.
2428 const_toc_addr = __ long_constant((jlong)$src$$constant);
2429 if (const_toc_addr == NULL) {
2430 ciEnv::current()->record_out_of_memory_failure();
2431 return;
2432 }
2433
2434 // Get the constant's TOC offset.
2435 toc_offset = __ offset_to_method_toc(const_toc_addr);
2436
2437 // Keep the current instruction offset in mind.
2438 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
2439
2440 __ ld($dst$$Register, toc_offset, $toc$$Register);
2441 %}
2442
2443 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
2444 // TODO: PPC port $archOpcode(ppc64Opcode_addis);
2445
2446 MacroAssembler _masm(&cbuf);
2447
2448 if (!ra_->C->in_scratch_emit_size()) {
2449 address const_toc_addr;
2450 // Create a non-oop constant, no relocation needed.
2451 // If it is an IC, it has a virtual_call_Relocation.
2452 const_toc_addr = __ long_constant((jlong)$src$$constant);
2453 if (const_toc_addr == NULL) {
2454 ciEnv::current()->record_out_of_memory_failure();
2455 return;
2456 }
2457
2458 // Get the constant's TOC offset.
2555 // Create new nodes.
2556 loadConLNodesTuple loadConLNodes =
2557 loadConLNodesTuple_create(ra_, n_toc, op_src,
2558 ra_->get_reg_second(this), ra_->get_reg_first(this));
2559
2560 // Push new nodes.
2561 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2562 if (loadConLNodes._last) nodes->push(loadConLNodes._last);
2563
2564 // some asserts
2565 assert(nodes->length() >= 1, "must have created at least 1 node");
2566 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2567 %}
2568
2569 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2570 // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2571
2572 MacroAssembler _masm(&cbuf);
2573 int toc_offset = 0;
2574
2575 intptr_t val = $src$$constant;
2576 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2577 address const_toc_addr;
2578 if (constant_reloc == relocInfo::oop_type) {
2579 // Create an oop constant and a corresponding relocation.
2580 AddressLiteral a = __ allocate_oop_address((jobject)val);
2581 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2582 __ relocate(a.rspec());
2583 } else if (constant_reloc == relocInfo::metadata_type) {
2584 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2585 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2586 __ relocate(a.rspec());
2587 } else {
2588 // Create a non-oop constant, no relocation needed.
2589 const_toc_addr = __ long_constant((jlong)$src$$constant);
2590 }
2591
2592 if (const_toc_addr == NULL) {
2593 ciEnv::current()->record_out_of_memory_failure();
2594 return;
2595 }
2596 // Get the constant's TOC offset.
2597 toc_offset = __ offset_to_method_toc(const_toc_addr);
2598
2599 __ ld($dst$$Register, toc_offset, $toc$$Register);
2600 %}
2601
2602 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
2603 // TODO: PPC port $archOpcode(ppc64Opcode_addis);
2604
2605 MacroAssembler _masm(&cbuf);
2606 if (!ra_->C->in_scratch_emit_size()) {
2607 intptr_t val = $src$$constant;
2608 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src
2609 address const_toc_addr;
2610 if (constant_reloc == relocInfo::oop_type) {
2611 // Create an oop constant and a corresponding relocation.
2612 AddressLiteral a = __ allocate_oop_address((jobject)val);
2613 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
2614 __ relocate(a.rspec());
2615 } else if (constant_reloc == relocInfo::metadata_type) {
2616 AddressLiteral a = __ constant_metadata_address((Metadata *)val);
2617 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
3249 // - Branches directly to a compiled method if the offset is encodable in instruction.
3250 // - Branches to the trampoline stub if the offset to the compiled method is not encodable.
3251 // - Branches to the compiled_to_interp stub if the target is interpreted.
3252 //
3253 // Further there are three relocations from the loads to the constants in
3254 // the constant section.
3255 //
3256 // Usage of r1 and r2 in the stubs allows to distinguish them.
3257 enc_class enc_java_static_call(method meth) %{
3258 // TODO: PPC port $archOpcode(ppc64Opcode_bl);
3259
3260 MacroAssembler _masm(&cbuf);
3261 address entry_point = (address)$meth$$method;
3262
3263 if (!_method) {
3264 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
3265 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type);
3266 } else {
3267 // Remember the offset not the address.
3268 const int start_offset = __ offset();
3269
3270 // The trampoline stub.
3271 // No entry point given, use the current pc.
3272 // Make sure branch fits into
3273 if (entry_point == 0) entry_point = __ pc();
3274
3275 // Put the entry point as a constant into the constant pool.
3276 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
3277 if (entry_point_toc_addr == NULL) {
3278 ciEnv::current()->record_out_of_memory_failure();
3279 return;
3280 }
3281 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
3282
3283 // Emit the trampoline stub which will be related to the branch-and-link below.
3284 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
3285 if (ciEnv::current()->failing()) { return; } // Code cache may be full.
3286 int method_index = resolved_method_index(cbuf);
3287 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
3288 : static_call_Relocation::spec(method_index));
3289
3290 // The real call.
3291 // Note: At this point we do not have the address of the trampoline
3292 // stub, and the entry point might be too far away for bl, so __ pc()
3293 // serves as dummy and the bl will be patched later.
3294 cbuf.set_insts_mark();
3295 __ bl(__ pc()); // Emits a relocation.
3296
3297 // The stub for call to interpreter.
3298 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf);
3299 if (stub == NULL) {
3300 ciEnv::current()->record_failure("CodeCache is full");
3301 return;
3302 }
3303 }
3304 %}
3305
3306 // Second node of expanded dynamic call - the call.
3307 enc_class enc_java_dynamic_call_sched(method meth) %{
3308 // TODO: PPC port $archOpcode(ppc64Opcode_bl);
|