src/cpu/ppc/vm/ppc.ad
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8054033 Sdiff src/cpu/ppc/vm

src/cpu/ppc/vm/ppc.ad

Print this page




1266 
1267 // Factory for creating loadConL* nodes for large/small constant pool.
1268 
1269 static inline jlong replicate_immF(float con) {
1270   // Replicate float con 2 times and pack into vector.
1271   int val = *((int*)&con);
1272   jlong lval = val;
1273   lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1274   return lval;
1275 }
1276 
1277 //=============================================================================
1278 
1279 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1280 int Compile::ConstantTable::calculate_table_base_offset() const {
1281   return 0;  // absolute addressing, no offset
1282 }
1283 
1284 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1285 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1286   Compile *C = ra_->C;
1287 
1288   iRegPdstOper *op_dst = new iRegPdstOper();
1289   MachNode *m1 = new loadToc_hiNode();
1290   MachNode *m2 = new loadToc_loNode();
1291 
1292   m1->add_req(NULL);
1293   m2->add_req(NULL, m1);
1294   m1->_opnds[0] = op_dst;
1295   m2->_opnds[0] = op_dst;
1296   m2->_opnds[1] = op_dst;
1297   ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1298   ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1299   nodes->push(m1);
1300   nodes->push(m2);
1301 }
1302 
1303 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1304   // Is postalloc expanded.
1305   ShouldNotReachHere();
1306 }
1307 


2212 //
2213 // And `Compile::Shorten_branches' will decide on basis of this
2214 // information whether to replace particular branch sites by short
2215 // ones.
2216 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2217   // Is the offset within the range of a ppc64 pc relative branch?
2218   bool b;
2219 
2220   const int safety_zone = 3 * BytesPerInstWord;
2221   b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2222                          29 - 16 + 1 + 2);
2223   return b;
2224 }
2225 
2226 const bool Matcher::isSimpleConstant64(jlong value) {
2227   // Probably always true, even if a temp register is required.
2228   return true;
2229 }
2230 /* TODO: PPC port
2231 // Make a new machine dependent decode node (with its operands).
2232 MachTypeNode *Matcher::make_decode_node(Compile *C) {
2233   assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0,
2234          "This method is only implemented for unscaled cOops mode so far");
2235   MachTypeNode *decode = new decodeN_unscaledNode();
2236   decode->set_opnd_array(0, new iRegPdstOper());
2237   decode->set_opnd_array(1, new iRegNsrcOper());
2238   return decode;
2239 }
2240 */
2241 // Threshold size for cleararray.
2242 const int Matcher::init_array_short_size = 8 * BytesPerLong;
2243 
2244 // false => size gets scaled to BytesPerLong, ok.
2245 const bool Matcher::init_array_count_is_in_bytes = false;
2246 
2247 // Use conditional move (CMOVL) on Power7.
2248 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves
2249 
2250 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet.
2251 // fsel doesn't accept a condition register as input, so this would be slightly different.
2252 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }


2576       ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2577 
2578       // Also keep the current instruction offset in mind.
2579       ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2580     }
2581 
2582     __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2583   %}
2584 
2585 %} // encode
2586 
2587 source %{
2588 
2589 typedef struct {
2590   loadConL_hiNode *_large_hi;
2591   loadConL_loNode *_large_lo;
2592   loadConLNode    *_small;
2593   MachNode        *_last;
2594 } loadConLNodesTuple;
2595 
2596 loadConLNodesTuple loadConLNodesTuple_create(Compile *C, PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2597                                              OptoReg::Name reg_second, OptoReg::Name reg_first) {
2598   loadConLNodesTuple nodes;
2599 
2600   const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2601   if (large_constant_pool) {
2602     // Create new nodes.
2603     loadConL_hiNode *m1 = new loadConL_hiNode();
2604     loadConL_loNode *m2 = new loadConL_loNode();
2605 
2606     // inputs for new nodes
2607     m1->add_req(NULL, toc);
2608     m2->add_req(NULL, m1);
2609 
2610     // operands for new nodes
2611     m1->_opnds[0] = new iRegLdstOper(); // dst
2612     m1->_opnds[1] = immSrc;             // src
2613     m1->_opnds[2] = new iRegPdstOper(); // toc
2614     m2->_opnds[0] = new iRegLdstOper(); // dst
2615     m2->_opnds[1] = immSrc;             // src
2616     m2->_opnds[2] = new iRegLdstOper(); // base


2652     // Create result.
2653     nodes._large_hi = NULL;
2654     nodes._large_lo = NULL;
2655     nodes._small = m2;
2656     nodes._last = nodes._small;
2657     assert(m2->bottom_type()->isa_long(), "must be long");
2658   }
2659 
2660   return nodes;
2661 }
2662 
2663 %} // source
2664 
2665 encode %{
2666   // Postalloc expand emitter for loading a long constant from the method's TOC.
2667   // Enc_class needed as consttanttablebase is not supported by postalloc
2668   // expand.
2669   enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2670     // Create new nodes.
2671     loadConLNodesTuple loadConLNodes =
2672       loadConLNodesTuple_create(C, ra_, n_toc, op_src,
2673                                 ra_->get_reg_second(this), ra_->get_reg_first(this));
2674 
2675     // Push new nodes.
2676     if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2677     if (loadConLNodes._last)     nodes->push(loadConLNodes._last);
2678 
2679     // some asserts
2680     assert(nodes->length() >= 1, "must have created at least 1 node");
2681     assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2682   %}
2683 
2684   enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2685     // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2686 
2687     MacroAssembler _masm(&cbuf);
2688     int toc_offset = 0;
2689 
2690     if (!ra_->C->in_scratch_emit_size()) {
2691       intptr_t val = $src$$constant;
2692       relocInfo::relocType constant_reloc = $src->constant_reloc();  // src


3374     } else {
3375       __ bc    (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3376                     cc_to_biint(cc, flags_reg),
3377                     l);
3378     }
3379 #endif
3380     Unimplemented();
3381   %}
3382 
3383   // Postalloc expand emitter for loading a replicatef float constant from
3384   // the method's TOC.
3385   // Enc_class needed as consttanttablebase is not supported by postalloc
3386   // expand.
3387   enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3388     // Create new nodes.
3389 
3390     // Make an operand with the bit pattern to load as float.
3391     immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3392 
3393     loadConLNodesTuple loadConLNodes =
3394       loadConLNodesTuple_create(C, ra_, n_toc, op_repl,
3395                                 ra_->get_reg_second(this), ra_->get_reg_first(this));
3396 
3397     // Push new nodes.
3398     if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3399     if (loadConLNodes._last)     nodes->push(loadConLNodes._last);
3400 
3401     assert(nodes->length() >= 1, "must have created at least 1 node");
3402     assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3403   %}
3404 
3405   // This enc_class is needed so that scheduler gets proper
3406   // input mapping for latency computation.
3407   enc_class enc_poll(immI dst, iRegLdst poll) %{
3408     // TODO: PPC port $archOpcode(ppc64Opcode_ld);
3409     // Fake operand dst needed for PPC scheduler.
3410     assert($dst$$constant == 0x0, "dst must be 0x0");
3411 
3412     MacroAssembler _masm(&cbuf);
3413     // Mark the code position where the load from the safepoint
3414     // polling page was emitted as relocInfo::poll_type.


3594         ? _load_ic_hi_node->_cbuf_insts_offset
3595         : _load_ic_node->_cbuf_insts_offset;
3596       const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset);
3597       assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr),
3598              "should be load from TOC");
3599 
3600       __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr));
3601     }
3602 
3603     // At this point I do not have the address of the trampoline stub,
3604     // and the entry point might be too far away for bl. Pc() serves
3605     // as dummy and bl will be patched later.
3606     __ bl((address) __ pc());
3607   %}
3608 
3609   // postalloc expand emitter for virtual calls.
3610   enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{
3611 
3612     // Create the nodes for loading the IC from the TOC.
3613     loadConLNodesTuple loadConLNodes_IC =
3614       loadConLNodesTuple_create(C, ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()),
3615                                 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
3616 
3617     // Create the call node.
3618     CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode();
3619     call->_method_handle_invoke = _method_handle_invoke;
3620     call->_vtable_index      = _vtable_index;
3621     call->_method            = _method;
3622     call->_bci               = _bci;
3623     call->_optimized_virtual = _optimized_virtual;
3624     call->_tf                = _tf;
3625     call->_entry_point       = _entry_point;
3626     call->_cnt               = _cnt;
3627     call->_argsize           = _argsize;
3628     call->_oop_map           = _oop_map;
3629     call->_jvms              = _jvms;
3630     call->_jvmadj            = _jvmadj;
3631     call->_in_rms            = _in_rms;
3632     call->_nesting           = _nesting;
3633 
3634     // New call needs all inputs of old call.


3748     // Check the ret_addr_offset.
3749     assert(((MachCallRuntimeNode*)this)->ret_addr_offset() ==  __ last_calls_return_pc() - start_pc,
3750            "Fix constant in ret_addr_offset()");
3751   %}
3752 
3753   // Move to ctr for leaf call.
3754   // This enc_class is needed so that scheduler gets proper
3755   // input mapping for latency computation.
3756   enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3757     // TODO: PPC port $archOpcode(ppc64Opcode_mtctr);
3758     MacroAssembler _masm(&cbuf);
3759     __ mtctr($src$$Register);
3760   %}
3761 
3762   // Postalloc expand emitter for runtime leaf calls.
3763   enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3764     loadConLNodesTuple loadConLNodes_Entry;
3765 #if defined(ABI_ELFv2)
3766     jlong entry_address = (jlong) this->entry_point();
3767     assert(entry_address, "need address here");
3768     loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper(entry_address),
3769                                                     OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3770 #else
3771     // Get the struct that describes the function we are about to call.
3772     FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3773     assert(fd, "need fd here");
3774     jlong entry_address = (jlong) fd->entry();
3775     // new nodes
3776     loadConLNodesTuple loadConLNodes_Env;
3777     loadConLNodesTuple loadConLNodes_Toc;
3778 
3779     // Create nodes and operands for loading the entry point.
3780     loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper(entry_address),
3781                                                     OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3782 
3783 
3784     // Create nodes and operands for loading the env pointer.
3785     if (fd->env() != NULL) {
3786       loadConLNodes_Env = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper((jlong) fd->env()),
3787                                                     OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3788     } else {
3789       loadConLNodes_Env._large_hi = NULL;
3790       loadConLNodes_Env._large_lo = NULL;
3791       loadConLNodes_Env._small    = NULL;
3792       loadConLNodes_Env._last = new loadConL16Node();
3793       loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3794       loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3795       ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3796     }
3797 
3798     // Create nodes and operands for loading the Toc point.
3799     loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new immLOper((jlong) fd->toc()),
3800                                                   OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3801 #endif // ABI_ELFv2
3802     // mtctr node
3803     MachNode *mtctr = new CallLeafDirect_mtctrNode();
3804 
3805     assert(loadConLNodes_Entry._last != NULL, "entry must exist");
3806     mtctr->add_req(0, loadConLNodes_Entry._last);
3807 
3808     mtctr->_opnds[0] = new iRegLdstOper();
3809     mtctr->_opnds[1] = new iRegLdstOper();
3810 
3811     // call node
3812     MachCallLeafNode *call = new CallLeafDirectNode();
3813 
3814     call->_opnds[0] = _opnds[0];
3815     call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3816 
3817     // Make the new call node look like the old one.
3818     call->_name        = _name;
3819     call->_tf          = _tf;




1266 
1267 // Factory for creating loadConL* nodes for large/small constant pool.
1268 
1269 static inline jlong replicate_immF(float con) {
1270   // Replicate float con 2 times and pack into vector.
1271   int val = *((int*)&con);
1272   jlong lval = val;
1273   lval = (lval << 32) | (lval & 0xFFFFFFFFl);
1274   return lval;
1275 }
1276 
1277 //=============================================================================
1278 
1279 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask();
1280 int Compile::ConstantTable::calculate_table_base_offset() const {
1281   return 0;  // absolute addressing, no offset
1282 }
1283 
1284 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; }
1285 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {


1286   iRegPdstOper *op_dst = new iRegPdstOper();
1287   MachNode *m1 = new loadToc_hiNode();
1288   MachNode *m2 = new loadToc_loNode();
1289 
1290   m1->add_req(NULL);
1291   m2->add_req(NULL, m1);
1292   m1->_opnds[0] = op_dst;
1293   m2->_opnds[0] = op_dst;
1294   m2->_opnds[1] = op_dst;
1295   ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1296   ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
1297   nodes->push(m1);
1298   nodes->push(m2);
1299 }
1300 
1301 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1302   // Is postalloc expanded.
1303   ShouldNotReachHere();
1304 }
1305 


2210 //
2211 // And `Compile::Shorten_branches' will decide on basis of this
2212 // information whether to replace particular branch sites by short
2213 // ones.
2214 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
2215   // Is the offset within the range of a ppc64 pc relative branch?
2216   bool b;
2217 
2218   const int safety_zone = 3 * BytesPerInstWord;
2219   b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone),
2220                          29 - 16 + 1 + 2);
2221   return b;
2222 }
2223 
2224 const bool Matcher::isSimpleConstant64(jlong value) {
2225   // Probably always true, even if a temp register is required.
2226   return true;
2227 }
2228 /* TODO: PPC port
2229 // Make a new machine dependent decode node (with its operands).
2230 MachTypeNode *Matcher::make_decode_node() {
2231   assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0,
2232          "This method is only implemented for unscaled cOops mode so far");
2233   MachTypeNode *decode = new decodeN_unscaledNode();
2234   decode->set_opnd_array(0, new iRegPdstOper());
2235   decode->set_opnd_array(1, new iRegNsrcOper());
2236   return decode;
2237 }
2238 */
2239 // Threshold size for cleararray.
2240 const int Matcher::init_array_short_size = 8 * BytesPerLong;
2241 
2242 // false => size gets scaled to BytesPerLong, ok.
2243 const bool Matcher::init_array_count_is_in_bytes = false;
2244 
2245 // Use conditional move (CMOVL) on Power7.
2246 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves
2247 
2248 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet.
2249 // fsel doesn't accept a condition register as input, so this would be slightly different.
2250 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }


2574       ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
2575 
2576       // Also keep the current instruction offset in mind.
2577       ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset();
2578     }
2579 
2580     __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset));
2581   %}
2582 
2583 %} // encode
2584 
2585 source %{
2586 
2587 typedef struct {
2588   loadConL_hiNode *_large_hi;
2589   loadConL_loNode *_large_lo;
2590   loadConLNode    *_small;
2591   MachNode        *_last;
2592 } loadConLNodesTuple;
2593 
2594 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc,
2595                                              OptoReg::Name reg_second, OptoReg::Name reg_first) {
2596   loadConLNodesTuple nodes;
2597 
2598   const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000;
2599   if (large_constant_pool) {
2600     // Create new nodes.
2601     loadConL_hiNode *m1 = new loadConL_hiNode();
2602     loadConL_loNode *m2 = new loadConL_loNode();
2603 
2604     // inputs for new nodes
2605     m1->add_req(NULL, toc);
2606     m2->add_req(NULL, m1);
2607 
2608     // operands for new nodes
2609     m1->_opnds[0] = new iRegLdstOper(); // dst
2610     m1->_opnds[1] = immSrc;             // src
2611     m1->_opnds[2] = new iRegPdstOper(); // toc
2612     m2->_opnds[0] = new iRegLdstOper(); // dst
2613     m2->_opnds[1] = immSrc;             // src
2614     m2->_opnds[2] = new iRegLdstOper(); // base


2650     // Create result.
2651     nodes._large_hi = NULL;
2652     nodes._large_lo = NULL;
2653     nodes._small = m2;
2654     nodes._last = nodes._small;
2655     assert(m2->bottom_type()->isa_long(), "must be long");
2656   }
2657 
2658   return nodes;
2659 }
2660 
2661 %} // source
2662 
2663 encode %{
2664   // Postalloc expand emitter for loading a long constant from the method's TOC.
2665   // Enc_class needed as consttanttablebase is not supported by postalloc
2666   // expand.
2667   enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{
2668     // Create new nodes.
2669     loadConLNodesTuple loadConLNodes =
2670       loadConLNodesTuple_create(ra_, n_toc, op_src,
2671                                 ra_->get_reg_second(this), ra_->get_reg_first(this));
2672 
2673     // Push new nodes.
2674     if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
2675     if (loadConLNodes._last)     nodes->push(loadConLNodes._last);
2676 
2677     // some asserts
2678     assert(nodes->length() >= 1, "must have created at least 1 node");
2679     assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
2680   %}
2681 
2682   enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
2683     // TODO: PPC port $archOpcode(ppc64Opcode_ld);
2684 
2685     MacroAssembler _masm(&cbuf);
2686     int toc_offset = 0;
2687 
2688     if (!ra_->C->in_scratch_emit_size()) {
2689       intptr_t val = $src$$constant;
2690       relocInfo::relocType constant_reloc = $src->constant_reloc();  // src


3372     } else {
3373       __ bc    (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
3374                     cc_to_biint(cc, flags_reg),
3375                     l);
3376     }
3377 #endif
3378     Unimplemented();
3379   %}
3380 
3381   // Postalloc expand emitter for loading a replicatef float constant from
3382   // the method's TOC.
3383   // Enc_class needed as consttanttablebase is not supported by postalloc
3384   // expand.
3385   enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{
3386     // Create new nodes.
3387 
3388     // Make an operand with the bit pattern to load as float.
3389     immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF()));
3390 
3391     loadConLNodesTuple loadConLNodes =
3392       loadConLNodesTuple_create(ra_, n_toc, op_repl,
3393                                 ra_->get_reg_second(this), ra_->get_reg_first(this));
3394 
3395     // Push new nodes.
3396     if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi);
3397     if (loadConLNodes._last)     nodes->push(loadConLNodes._last);
3398 
3399     assert(nodes->length() >= 1, "must have created at least 1 node");
3400     assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long");
3401   %}
3402 
3403   // This enc_class is needed so that scheduler gets proper
3404   // input mapping for latency computation.
3405   enc_class enc_poll(immI dst, iRegLdst poll) %{
3406     // TODO: PPC port $archOpcode(ppc64Opcode_ld);
3407     // Fake operand dst needed for PPC scheduler.
3408     assert($dst$$constant == 0x0, "dst must be 0x0");
3409 
3410     MacroAssembler _masm(&cbuf);
3411     // Mark the code position where the load from the safepoint
3412     // polling page was emitted as relocInfo::poll_type.


3592         ? _load_ic_hi_node->_cbuf_insts_offset
3593         : _load_ic_node->_cbuf_insts_offset;
3594       const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset);
3595       assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr),
3596              "should be load from TOC");
3597 
3598       __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr));
3599     }
3600 
3601     // At this point I do not have the address of the trampoline stub,
3602     // and the entry point might be too far away for bl. Pc() serves
3603     // as dummy and bl will be patched later.
3604     __ bl((address) __ pc());
3605   %}
3606 
3607   // postalloc expand emitter for virtual calls.
3608   enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{
3609 
3610     // Create the nodes for loading the IC from the TOC.
3611     loadConLNodesTuple loadConLNodes_IC =
3612       loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()),
3613                                 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num));
3614 
3615     // Create the call node.
3616     CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode();
3617     call->_method_handle_invoke = _method_handle_invoke;
3618     call->_vtable_index      = _vtable_index;
3619     call->_method            = _method;
3620     call->_bci               = _bci;
3621     call->_optimized_virtual = _optimized_virtual;
3622     call->_tf                = _tf;
3623     call->_entry_point       = _entry_point;
3624     call->_cnt               = _cnt;
3625     call->_argsize           = _argsize;
3626     call->_oop_map           = _oop_map;
3627     call->_jvms              = _jvms;
3628     call->_jvmadj            = _jvmadj;
3629     call->_in_rms            = _in_rms;
3630     call->_nesting           = _nesting;
3631 
3632     // New call needs all inputs of old call.


3746     // Check the ret_addr_offset.
3747     assert(((MachCallRuntimeNode*)this)->ret_addr_offset() ==  __ last_calls_return_pc() - start_pc,
3748            "Fix constant in ret_addr_offset()");
3749   %}
3750 
3751   // Move to ctr for leaf call.
3752   // This enc_class is needed so that scheduler gets proper
3753   // input mapping for latency computation.
3754   enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
3755     // TODO: PPC port $archOpcode(ppc64Opcode_mtctr);
3756     MacroAssembler _masm(&cbuf);
3757     __ mtctr($src$$Register);
3758   %}
3759 
3760   // Postalloc expand emitter for runtime leaf calls.
3761   enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
3762     loadConLNodesTuple loadConLNodes_Entry;
3763 #if defined(ABI_ELFv2)
3764     jlong entry_address = (jlong) this->entry_point();
3765     assert(entry_address, "need address here");
3766     loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3767                                                     OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3768 #else
3769     // Get the struct that describes the function we are about to call.
3770     FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
3771     assert(fd, "need fd here");
3772     jlong entry_address = (jlong) fd->entry();
3773     // new nodes
3774     loadConLNodesTuple loadConLNodes_Env;
3775     loadConLNodesTuple loadConLNodes_Toc;
3776 
3777     // Create nodes and operands for loading the entry point.
3778     loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address),
3779                                                     OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
3780 
3781 
3782     // Create nodes and operands for loading the env pointer.
3783     if (fd->env() != NULL) {
3784       loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()),
3785                                                     OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3786     } else {
3787       loadConLNodes_Env._large_hi = NULL;
3788       loadConLNodes_Env._large_lo = NULL;
3789       loadConLNodes_Env._small    = NULL;
3790       loadConLNodes_Env._last = new loadConL16Node();
3791       loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper();
3792       loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0);
3793       ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num));
3794     }
3795 
3796     // Create nodes and operands for loading the Toc point.
3797     loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()),
3798                                                   OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
3799 #endif // ABI_ELFv2
3800     // mtctr node
3801     MachNode *mtctr = new CallLeafDirect_mtctrNode();
3802 
3803     assert(loadConLNodes_Entry._last != NULL, "entry must exist");
3804     mtctr->add_req(0, loadConLNodes_Entry._last);
3805 
3806     mtctr->_opnds[0] = new iRegLdstOper();
3807     mtctr->_opnds[1] = new iRegLdstOper();
3808 
3809     // call node
3810     MachCallLeafNode *call = new CallLeafDirectNode();
3811 
3812     call->_opnds[0] = _opnds[0];
3813     call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later.
3814 
3815     // Make the new call node look like the old one.
3816     call->_name        = _name;
3817     call->_tf          = _tf;


src/cpu/ppc/vm/ppc.ad
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File