Mercurial > hg > graal-jvmci-8
comparison src/cpu/ppc/vm/ppc.ad @ 20508:f6bde7889409
8059592: Recent bugfixes in ppc64 port.
Reviewed-by: kvn
author | goetz |
---|---|
date | Thu, 02 Oct 2014 09:32:53 +0200 |
parents | 0bf37f737702 |
children | 327e7269f90d |
comparison
equal
deleted
inserted
replaced
20507:43ce58b4717b | 20508:f6bde7889409 |
---|---|
1247 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); | 1247 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); |
1248 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); | 1248 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); |
1249 | 1249 |
1250 // Emit the trampoline stub which will be related to the branch-and-link below. | 1250 // Emit the trampoline stub which will be related to the branch-and-link below. |
1251 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); | 1251 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); |
1252 if (Compile::current()->env()->failing()) { return offsets; } // Code cache may be full. | |
1252 __ relocate(rtype); | 1253 __ relocate(rtype); |
1253 } | 1254 } |
1254 | 1255 |
1255 // Note: At this point we do not have the address of the trampoline | 1256 // Note: At this point we do not have the address of the trampoline |
1256 // stub, and the entry point might be too far away for bl, so __ pc() | 1257 // stub, and the entry point might be too far away for bl, so __ pc() |
1410 int bang_offset = bang_end_safe; | 1411 int bang_offset = bang_end_safe; |
1411 | 1412 |
1412 while (bang_offset <= bang_end) { | 1413 while (bang_offset <= bang_end) { |
1413 // Need at least one stack bang at end of shadow zone. | 1414 // Need at least one stack bang at end of shadow zone. |
1414 | 1415 |
1415 // Again I had to copy code, this time from assembler_ppc64.cpp, | 1416 // Again I had to copy code, this time from assembler_ppc.cpp, |
1416 // bang_stack_with_offset - see there for comments. | 1417 // bang_stack_with_offset - see there for comments. |
1417 | 1418 |
1418 // Stack grows down, caller passes positive offset. | 1419 // Stack grows down, caller passes positive offset. |
1419 assert(bang_offset > 0, "must bang with positive offset"); | 1420 assert(bang_offset > 0, "must bang with positive offset"); |
1420 | 1421 |
2000 // This is the unverified entry point. | 2001 // This is the unverified entry point. |
2001 MacroAssembler _masm(&cbuf); | 2002 MacroAssembler _masm(&cbuf); |
2002 | 2003 |
2003 // Inline_cache contains a klass. | 2004 // Inline_cache contains a klass. |
2004 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); | 2005 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); |
2005 Register receiver_klass = R0; // tmp | 2006 Register receiver_klass = R12_scratch2; // tmp |
2006 | 2007 |
2007 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); | 2008 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); |
2008 assert(R11_scratch1 == R11, "need prologue scratch register"); | 2009 assert(R11_scratch1 == R11, "need prologue scratch register"); |
2009 | 2010 |
2010 // Check for NULL argument if we don't have implicit null checks. | 2011 // Check for NULL argument if we don't have implicit null checks. |
3484 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); | 3485 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); |
3485 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); | 3486 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); |
3486 | 3487 |
3487 // Emit the trampoline stub which will be related to the branch-and-link below. | 3488 // Emit the trampoline stub which will be related to the branch-and-link below. |
3488 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); | 3489 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); |
3490 if (Compile::current()->env()->failing()) { return; } // Code cache may be full. | |
3489 __ relocate(_optimized_virtual ? | 3491 __ relocate(_optimized_virtual ? |
3490 relocInfo::opt_virtual_call_type : relocInfo::static_call_type); | 3492 relocInfo::opt_virtual_call_type : relocInfo::static_call_type); |
3491 } | 3493 } |
3492 | 3494 |
3493 // The real call. | 3495 // The real call. |
3527 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); | 3529 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); |
3528 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); | 3530 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); |
3529 | 3531 |
3530 // Emit the trampoline stub which will be related to the branch-and-link below. | 3532 // Emit the trampoline stub which will be related to the branch-and-link below. |
3531 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); | 3533 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); |
3534 if (ra_->C->env()->failing()) { return; } // Code cache may be full. | |
3532 assert(_optimized_virtual, "methodHandle call should be a virtual call"); | 3535 assert(_optimized_virtual, "methodHandle call should be a virtual call"); |
3533 __ relocate(relocInfo::opt_virtual_call_type); | 3536 __ relocate(relocInfo::opt_virtual_call_type); |
3534 } | 3537 } |
3535 | 3538 |
3536 // The real call. | 3539 // The real call. |
3577 // Create a call trampoline stub for the given method. | 3580 // Create a call trampoline stub for the given method. |
3578 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; | 3581 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; |
3579 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); | 3582 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); |
3580 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); | 3583 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); |
3581 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); | 3584 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); |
3582 | 3585 if (ra_->C->env()->failing()) { return; } // Code cache may be full. |
3583 if (ra_->C->env()->failing()) | |
3584 return; | |
3585 | 3586 |
3586 // Build relocation at call site with ic position as data. | 3587 // Build relocation at call site with ic position as data. |
3587 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || | 3588 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || |
3588 (_load_ic_hi_node == NULL && _load_ic_node != NULL), | 3589 (_load_ic_hi_node == NULL && _load_ic_node != NULL), |
3589 "must have one, but can't have both"); | 3590 "must have one, but can't have both"); |
5638 size(4); | 5639 size(4); |
5639 ins_encode( enc_lwz(dst, mem) ); | 5640 ins_encode( enc_lwz(dst, mem) ); |
5640 ins_pipe(pipe_class_memory); | 5641 ins_pipe(pipe_class_memory); |
5641 %} | 5642 %} |
5642 | 5643 |
5643 //// Load compressed klass and decode it if narrow_klass_shift == 0. | |
5644 //// TODO: will narrow_klass_shift ever be 0? | |
5645 //instruct decodeNKlass2Klass(iRegPdst dst, memory mem) %{ | |
5646 // match(Set dst (DecodeNKlass (LoadNKlass mem))); | |
5647 // predicate(false /* TODO: PPC port Universe::narrow_klass_shift() == 0*); | |
5648 // ins_cost(MEMORY_REF_COST); | |
5649 // | |
5650 // format %{ "LWZ $dst, $mem \t// DecodeNKlass (unscaled)" %} | |
5651 // size(4); | |
5652 // ins_encode( enc_lwz(dst, mem) ); | |
5653 // ins_pipe(pipe_class_memory); | |
5654 //%} | |
5655 | |
5656 // Load Klass Pointer | 5644 // Load Klass Pointer |
5657 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ | 5645 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ |
5658 match(Set dst (LoadKlass mem)); | 5646 match(Set dst (LoadKlass mem)); |
5659 ins_cost(MEMORY_REF_COST); | 5647 ins_cost(MEMORY_REF_COST); |
5660 | 5648 |
6070 nodes->push(m2); | 6058 nodes->push(m2); |
6071 nodes->push(m3); | 6059 nodes->push(m3); |
6072 %} | 6060 %} |
6073 %} | 6061 %} |
6074 | 6062 |
6075 instruct loadConNKlass_hi(iRegNdst dst, immNKlass src) %{ | 6063 // We have seen a safepoint between the hi and lo parts, and this node was handled |
6064 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is | |
6065 // not a narrow oop. | |
6066 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ | |
6067 match(Set dst src); | |
6076 effect(DEF dst, USE src); | 6068 effect(DEF dst, USE src); |
6077 ins_cost(DEFAULT_COST); | 6069 ins_cost(DEFAULT_COST); |
6078 | 6070 |
6079 format %{ "LIS $dst, $src \t// narrow oop hi" %} | 6071 format %{ "LIS $dst, $src \t// narrow klass hi" %} |
6080 size(4); | 6072 size(4); |
6081 ins_encode %{ | 6073 ins_encode %{ |
6082 // TODO: PPC port $archOpcode(ppc64Opcode_addis); | 6074 // TODO: PPC port $archOpcode(ppc64Opcode_addis); |
6083 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); | 6075 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); |
6084 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); | 6076 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); |
6077 %} | |
6078 ins_pipe(pipe_class_default); | |
6079 %} | |
6080 | |
6081 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! | |
6082 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ | |
6083 match(Set dst src1); | |
6084 effect(TEMP src2); | |
6085 ins_cost(DEFAULT_COST); | |
6086 | |
6087 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask | |
6088 size(4); | |
6089 ins_encode %{ | |
6090 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); | |
6091 __ clrldi($dst$$Register, $src2$$Register, 0x20); | |
6085 %} | 6092 %} |
6086 ins_pipe(pipe_class_default); | 6093 ins_pipe(pipe_class_default); |
6087 %} | 6094 %} |
6088 | 6095 |
6089 // This needs a match rule so that build_oop_map knows this is | 6096 // This needs a match rule so that build_oop_map knows this is |
6091 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ | 6098 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ |
6092 match(Set dst src1); | 6099 match(Set dst src1); |
6093 effect(TEMP src2); | 6100 effect(TEMP src2); |
6094 ins_cost(DEFAULT_COST); | 6101 ins_cost(DEFAULT_COST); |
6095 | 6102 |
6096 format %{ "ADDI $dst, $src1, $src2 \t// narrow oop lo" %} | 6103 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} |
6097 size(4); | 6104 size(4); |
6098 ins_encode %{ | 6105 ins_encode %{ |
6099 // TODO: PPC port $archOpcode(ppc64Opcode_addi); | 6106 // TODO: PPC port $archOpcode(ppc64Opcode_ori); |
6100 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); | 6107 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); |
6101 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); | 6108 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); |
6102 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); | 6109 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); |
6103 RelocationHolder rspec = metadata_Relocation::spec(klass_index); | 6110 RelocationHolder rspec = metadata_Relocation::spec(klass_index); |
6104 | 6111 |
6125 nodes->push(m1); | 6132 nodes->push(m1); |
6126 | 6133 |
6127 MachNode *m2 = m1; | 6134 MachNode *m2 = m1; |
6128 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { | 6135 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { |
6129 // Value might be 1-extended. Mask out these bits. | 6136 // Value might be 1-extended. Mask out these bits. |
6130 m2 = new (C) clearMs32bNode(); | 6137 m2 = new (C) loadConNKlass_maskNode(); |
6131 m2->add_req(NULL, m1); | 6138 m2->add_req(NULL, m1); |
6132 m2->_opnds[0] = op_dst; | 6139 m2->_opnds[0] = op_dst; |
6133 m2->_opnds[1] = op_dst; | 6140 m2->_opnds[1] = op_src; |
6141 m2->_opnds[2] = op_dst; | |
6134 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); | 6142 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); |
6135 nodes->push(m2); | 6143 nodes->push(m2); |
6136 } | 6144 } |
6137 | 6145 |
6138 MachNode *m3 = new (C) loadConNKlass_loNode(); | 6146 MachNode *m3 = new (C) loadConNKlass_loNode(); |
6973 | 6981 |
6974 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with 32G aligned base" %} | 6982 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with 32G aligned base" %} |
6975 size(4); | 6983 size(4); |
6976 ins_encode %{ | 6984 ins_encode %{ |
6977 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); | 6985 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); |
6978 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); | 6986 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); |
6979 %} | 6987 %} |
6980 ins_pipe(pipe_class_default); | 6988 ins_pipe(pipe_class_default); |
6981 %} | 6989 %} |
6982 | 6990 |
6983 // shift != 0, base != 0 | 6991 // shift != 0, base != 0 |