提交 bcaaa7a7 编写于 作者: G goetz

8042309: Some bugfixes for the ppc64 port.

Reviewed-by: kvn
上级 ba6464cf
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012, 2013 SAP AG. All rights reserved. * Copyright 2012, 2013 SAP AG. All rights reserved.
...@@ -403,7 +404,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(Label& stack_ov ...@@ -403,7 +404,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(Label& stack_ov
BLOCK_COMMENT("compute_interpreter_state {"); BLOCK_COMMENT("compute_interpreter_state {");
// access_flags = method->access_flags(); // access_flags = method->access_flags();
// TODO: PPC port: assert(4 == methodOopDesc::sz_access_flags(), "unexpected field size"); // TODO: PPC port: assert(4 == sizeof(AccessFlags), "unexpected field size");
__ lwa(access_flags, method_(access_flags)); __ lwa(access_flags, method_(access_flags));
// parameter_count = method->constMethod->size_of_parameters(); // parameter_count = method->constMethod->size_of_parameters();
...@@ -1055,7 +1056,7 @@ address CppInterpreterGenerator::generate_native_entry(void) { ...@@ -1055,7 +1056,7 @@ address CppInterpreterGenerator::generate_native_entry(void) {
assert(access_flags->is_nonvolatile(), assert(access_flags->is_nonvolatile(),
"access_flags must be in a non-volatile register"); "access_flags must be in a non-volatile register");
// Type check. // Type check.
// TODO: PPC port: assert(4 == methodOopDesc::sz_access_flags(), "unexpected field size"); // TODO: PPC port: assert(4 == sizeof(AccessFlags), "unexpected field size");
__ lwz(access_flags, method_(access_flags)); __ lwz(access_flags, method_(access_flags));
// We don't want to reload R19_method and access_flags after calls // We don't want to reload R19_method and access_flags after calls
...@@ -1838,7 +1839,7 @@ address CppInterpreterGenerator::generate_normal_entry(void) { ...@@ -1838,7 +1839,7 @@ address CppInterpreterGenerator::generate_normal_entry(void) {
// Interpreter state fields. // Interpreter state fields.
const Register msg = R24_tmp4; const Register msg = R24_tmp4;
// MethodOop fields. // Method fields.
const Register parameter_count = R25_tmp5; const Register parameter_count = R25_tmp5;
const Register result_index = R26_tmp6; const Register result_index = R26_tmp6;
...@@ -2023,7 +2024,7 @@ address CppInterpreterGenerator::generate_normal_entry(void) { ...@@ -2023,7 +2024,7 @@ address CppInterpreterGenerator::generate_normal_entry(void) {
__ add(R17_tos, R17_tos, parameter_count); __ add(R17_tos, R17_tos, parameter_count);
// Result stub address array index // Result stub address array index
// TODO: PPC port: assert(4 == methodOopDesc::sz_result_index(), "unexpected field size"); // TODO: PPC port: assert(4 == sizeof(AccessFlags), "unexpected field size");
__ lwa(result_index, method_(result_index)); __ lwa(result_index, method_(result_index));
__ li(msg, BytecodeInterpreter::method_resume); __ li(msg, BytecodeInterpreter::method_resume);
...@@ -2709,7 +2710,7 @@ address CppInterpreterGenerator::generate_normal_entry(void) { ...@@ -2709,7 +2710,7 @@ address CppInterpreterGenerator::generate_normal_entry(void) {
__ ld(R3_ARG1, state_(_result._osr._osr_buf)); __ ld(R3_ARG1, state_(_result._osr._osr_buf));
__ mtctr(R12_scratch2); __ mtctr(R12_scratch2);
// Load method oop, gc may move it during execution of osr'd method. // Load method, gc may move it during execution of osr'd method.
__ ld(R22_tmp2, state_(_method)); __ ld(R22_tmp2, state_(_method));
// Load message 'call_method'. // Load message 'call_method'.
__ li(R23_tmp3, BytecodeInterpreter::call_method); __ li(R23_tmp3, BytecodeInterpreter::call_method);
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#ifndef CPU_PPC_VM_FRAME_PPC_INLINE_HPP #ifndef CPU_PPC_VM_FRAME_PPC_INLINE_HPP
#define CPU_PPC_VM_FRAME_PPC_INLINE_HPP #define CPU_PPC_VM_FRAME_PPC_INLINE_HPP
#include "code/codeCache.hpp"
// Inline functions for ppc64 frames: // Inline functions for ppc64 frames:
// Find codeblob and set deopt_state. // Find codeblob and set deopt_state.
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#ifndef CPU_PPC_VM_INTERP_MASM_PPC_64_HPP #ifndef CPU_PPC_VM_INTERP_MASM_PPC_64_HPP
#define CPU_PPC_VM_INTERP_MASM_PPC_64_HPP #define CPU_PPC_VM_INTERP_MASM_PPC_64_HPP
#include "assembler_ppc.inline.hpp" #include "asm/macroAssembler.hpp"
#include "interpreter/invocationCounter.hpp" #include "interpreter/invocationCounter.hpp"
// This file specializes the assembler with interpreter-specific macros. // This file specializes the assembler with interpreter-specific macros.
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "asm/assembler.inline.hpp"
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp" #include "interpreter/interpreterRuntime.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
......
...@@ -139,32 +139,16 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() { ...@@ -139,32 +139,16 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() {
// Signature is in R3_RET. Signature is callee saved. // Signature is in R3_RET. Signature is callee saved.
__ mr(signature, R3_RET); __ mr(signature, R3_RET);
// Reload method, it may have moved.
#ifdef CC_INTERP
__ ld(R19_method, state_(_method));
#else
__ ld(R19_method, 0, target_sp);
__ ld(R19_method, _ijava_state_neg(method), R19_method);
#endif
// Get the result handler. // Get the result handler.
__ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method); __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method);
// Reload method, it may have moved.
#ifdef CC_INTERP
__ ld(R19_method, state_(_method));
#else
__ ld(R19_method, 0, target_sp);
__ ld(R19_method, _ijava_state_neg(method), R19_method);
#endif
{ {
Label L; Label L;
// test if static // test if static
// _access_flags._flags must be at offset 0. // _access_flags._flags must be at offset 0.
// TODO PPC port: requires change in shared code. // TODO PPC port: requires change in shared code.
//assert(in_bytes(AccessFlags::flags_offset()) == 0, //assert(in_bytes(AccessFlags::flags_offset()) == 0,
// "MethodOopDesc._access_flags == MethodOopDesc._access_flags._flags"); // "MethodDesc._access_flags == MethodDesc._access_flags._flags");
// _access_flags must be a 32 bit value. // _access_flags must be a 32 bit value.
assert(sizeof(AccessFlags) == 4, "wrong size"); assert(sizeof(AccessFlags) == 4, "wrong size");
__ lwa(R11_scratch1/*access_flags*/, method_(access_flags)); __ lwa(R11_scratch1/*access_flags*/, method_(access_flags));
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
// we don't have fast jni accessors. // We don't have fast jni accessors.
return (address) -1; return (address) -1;
} }
...@@ -57,12 +57,12 @@ address JNI_FastGetField::generate_fast_get_int_field() { ...@@ -57,12 +57,12 @@ address JNI_FastGetField::generate_fast_get_int_field() {
} }
address JNI_FastGetField::generate_fast_get_long_field() { address JNI_FastGetField::generate_fast_get_long_field() {
// we don't have fast jni accessors. // We don't have fast jni accessors.
return (address) -1; return (address) -1;
} }
address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
// e don't have fast jni accessors. // We don't have fast jni accessors.
return (address) -1; return (address) -1;
} }
......
...@@ -898,7 +898,7 @@ source_hpp %{ ...@@ -898,7 +898,7 @@ source_hpp %{
// To keep related declarations/definitions/uses close together, // To keep related declarations/definitions/uses close together,
// we switch between source %{ }% and source_hpp %{ }% freely as needed. // we switch between source %{ }% and source_hpp %{ }% freely as needed.
// Returns true if Node n is followed by a MemBar node that // Returns true if Node n is followed by a MemBar node that
// will do an acquire. If so, this node must not do the acquire // will do an acquire. If so, this node must not do the acquire
// operation. // operation.
bool followed_by_acquire(const Node *n); bool followed_by_acquire(const Node *n);
...@@ -908,7 +908,7 @@ source %{ ...@@ -908,7 +908,7 @@ source %{
// Optimize load-acquire. // Optimize load-acquire.
// //
// Check if acquire is unnecessary due to following operation that does // Check if acquire is unnecessary due to following operation that does
// acquire anyways. // acquire anyways.
// Walk the pattern: // Walk the pattern:
// //
...@@ -919,12 +919,12 @@ source %{ ...@@ -919,12 +919,12 @@ source %{
// Proj(ctrl) Proj(mem) // Proj(ctrl) Proj(mem)
// | | // | |
// MemBarRelease/Volatile // MemBarRelease/Volatile
// //
bool followed_by_acquire(const Node *load) { bool followed_by_acquire(const Node *load) {
assert(load->is_Load(), "So far implemented only for loads."); assert(load->is_Load(), "So far implemented only for loads.");
// Find MemBarAcquire. // Find MemBarAcquire.
const Node *mba = NULL; const Node *mba = NULL;
for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) {
const Node *out = load->fast_out(i); const Node *out = load->fast_out(i);
if (out->Opcode() == Op_MemBarAcquire) { if (out->Opcode() == Op_MemBarAcquire) {
...@@ -937,7 +937,7 @@ bool followed_by_acquire(const Node *load) { ...@@ -937,7 +937,7 @@ bool followed_by_acquire(const Node *load) {
// Find following MemBar node. // Find following MemBar node.
// //
// The following node must be reachable by control AND memory // The following node must be reachable by control AND memory
// edge to assure no other operations are in between the two nodes. // edge to assure no other operations are in between the two nodes.
// //
// So first get the Proj node, mem_proj, to use it to iterate forward. // So first get the Proj node, mem_proj, to use it to iterate forward.
...@@ -1135,6 +1135,7 @@ class CallStubImpl { ...@@ -1135,6 +1135,7 @@ class CallStubImpl {
public: public:
// Emit call stub, compiled java to interpreter.
static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset);
// Size of call trampoline stub. // Size of call trampoline stub.
...@@ -2752,7 +2753,7 @@ encode %{ ...@@ -2752,7 +2753,7 @@ encode %{
// inputs for new nodes // inputs for new nodes
m1->add_req(NULL, n_toc); m1->add_req(NULL, n_toc);
m2->add_req(NULL, m1); m2->add_req(NULL, m1);
// operands for new nodes // operands for new nodes
m1->_opnds[0] = new (C) iRegPdstOper(); // dst m1->_opnds[0] = new (C) iRegPdstOper(); // dst
m1->_opnds[1] = op_src; // src m1->_opnds[1] = op_src; // src
...@@ -2760,29 +2761,29 @@ encode %{ ...@@ -2760,29 +2761,29 @@ encode %{
m2->_opnds[0] = new (C) iRegPdstOper(); // dst m2->_opnds[0] = new (C) iRegPdstOper(); // dst
m2->_opnds[1] = op_src; // src m2->_opnds[1] = op_src; // src
m2->_opnds[2] = new (C) iRegLdstOper(); // base m2->_opnds[2] = new (C) iRegLdstOper(); // base
// Initialize ins_attrib TOC fields. // Initialize ins_attrib TOC fields.
m1->_const_toc_offset = -1; m1->_const_toc_offset = -1;
m2->_const_toc_offset_hi_node = m1; m2->_const_toc_offset_hi_node = m1;
// Register allocation for new nodes. // Register allocation for new nodes.
ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
nodes->push(m1); nodes->push(m1);
nodes->push(m2); nodes->push(m2);
assert(m2->bottom_type()->isa_ptr(), "must be ptr"); assert(m2->bottom_type()->isa_ptr(), "must be ptr");
} else { } else {
loadConPNode *m2 = new (C) loadConPNode(); loadConPNode *m2 = new (C) loadConPNode();
// inputs for new nodes // inputs for new nodes
m2->add_req(NULL, n_toc); m2->add_req(NULL, n_toc);
// operands for new nodes // operands for new nodes
m2->_opnds[0] = new (C) iRegPdstOper(); // dst m2->_opnds[0] = new (C) iRegPdstOper(); // dst
m2->_opnds[1] = op_src; // src m2->_opnds[1] = op_src; // src
m2->_opnds[2] = new (C) iRegPdstOper(); // toc m2->_opnds[2] = new (C) iRegPdstOper(); // toc
// Register allocation for new nodes. // Register allocation for new nodes.
ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
...@@ -2974,17 +2975,17 @@ encode %{ ...@@ -2974,17 +2975,17 @@ encode %{
n_sub_base->_opnds[1] = op_crx; n_sub_base->_opnds[1] = op_crx;
n_sub_base->_opnds[2] = op_src; n_sub_base->_opnds[2] = op_src;
n_sub_base->_bottom_type = _bottom_type; n_sub_base->_bottom_type = _bottom_type;
n_shift->add_req(n_region, n_sub_base); n_shift->add_req(n_region, n_sub_base);
n_shift->_opnds[0] = op_dst; n_shift->_opnds[0] = op_dst;
n_shift->_opnds[1] = op_dst; n_shift->_opnds[1] = op_dst;
n_shift->_bottom_type = _bottom_type; n_shift->_bottom_type = _bottom_type;
ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
nodes->push(n_move); nodes->push(n_move);
nodes->push(n_compare); nodes->push(n_compare);
nodes->push(n_sub_base); nodes->push(n_sub_base);
...@@ -3061,20 +3062,20 @@ encode %{ ...@@ -3061,20 +3062,20 @@ encode %{
} else { } else {
// before Power 7 // before Power 7
cond_add_baseNode *n_add_base = new (C) cond_add_baseNode(); cond_add_baseNode *n_add_base = new (C) cond_add_baseNode();
n_add_base->add_req(n_region, n_compare, n_shift); n_add_base->add_req(n_region, n_compare, n_shift);
n_add_base->_opnds[0] = op_dst; n_add_base->_opnds[0] = op_dst;
n_add_base->_opnds[1] = op_crx; n_add_base->_opnds[1] = op_crx;
n_add_base->_opnds[2] = op_dst; n_add_base->_opnds[2] = op_dst;
n_add_base->_bottom_type = _bottom_type; n_add_base->_bottom_type = _bottom_type;
assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!");
ra_->set_oop(n_add_base, true); ra_->set_oop(n_add_base, true);
ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx));
ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this));
nodes->push(n_compare); nodes->push(n_compare);
nodes->push(n_shift); nodes->push(n_shift);
nodes->push(n_add_base); nodes->push(n_add_base);
...@@ -3631,11 +3632,11 @@ encode %{ ...@@ -3631,11 +3632,11 @@ encode %{
// Req... // Req...
for (uint i = 0; i < req(); ++i) { for (uint i = 0; i < req(); ++i) {
// The expanded node does not need toc any more. // The expanded node does not need toc any more.
// Add the inline cache constant here instead. This expresses the // Add the inline cache constant here instead. This expresses the
// register of the inline cache must be live at the call. // register of the inline cache must be live at the call.
// Else we would have to adapt JVMState by -1. // Else we would have to adapt JVMState by -1.
if (i == mach_constant_base_node_input()) { if (i == mach_constant_base_node_input()) {
call->add_req(loadConLNodes_IC._last); call->add_req(loadConLNodes_IC._last);
} else { } else {
call->add_req(in(i)); call->add_req(in(i));
} }
...@@ -3663,6 +3664,8 @@ encode %{ ...@@ -3663,6 +3664,8 @@ encode %{
%} %}
// Compound version of call dynamic // Compound version of call dynamic
// Toc is only passed so that it can be used in ins_encode statement.
// In the code we have to use $constanttablebase.
enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound); // TODO: PPC port $archOpcode(ppc64Opcode_compound);
MacroAssembler _masm(&cbuf); MacroAssembler _masm(&cbuf);
...@@ -3670,14 +3673,17 @@ encode %{ ...@@ -3670,14 +3673,17 @@ encode %{
Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; Register Rtoc = (ra_) ? $constanttablebase : R2_TOC;
#if 0 #if 0
int vtable_index = this->_vtable_index;
if (_vtable_index < 0) { if (_vtable_index < 0) {
// Must be invalid_vtable_index, not nonvirtual_vtable_index. // Must be invalid_vtable_index, not nonvirtual_vtable_index.
assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value");
Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); Register ic_reg = as_Register(Matcher::inline_cache_reg_encode());
AddressLiteral meta = __ allocate_metadata_address((Metadata *)Universe::non_oop_word());
// Virtual call relocation will point to ic load.
address virtual_call_meta_addr = __ pc(); address virtual_call_meta_addr = __ pc();
__ load_const_from_method_toc(ic_reg, meta, Rtoc); // Load a clear inline cache.
AddressLiteral empty_ic((address) Universe::non_oop_word());
__ load_const_from_method_toc(ic_reg, empty_ic, Rtoc);
// CALL to fixup routine. Fixup routine uses ScopeDesc info // CALL to fixup routine. Fixup routine uses ScopeDesc info
// to determine who we intended to call. // to determine who we intended to call.
__ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr));
...@@ -3710,7 +3716,6 @@ encode %{ ...@@ -3710,7 +3716,6 @@ encode %{
"Fix constant in ret_addr_offset()"); "Fix constant in ret_addr_offset()");
} }
#endif #endif
guarantee(0, "Fix handling of toc edge: messes up derived/base pairs.");
Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!).
%} %}
...@@ -5436,7 +5441,7 @@ instruct loadI_ac(iRegIdst dst, memory mem) %{ ...@@ -5436,7 +5441,7 @@ instruct loadI_ac(iRegIdst dst, memory mem) %{
ins_pipe(pipe_class_memory); ins_pipe(pipe_class_memory);
%} %}
// Match loading integer and casting it to unsigned int in // Match loading integer and casting it to unsigned int in
// long register. // long register.
// LoadI + ConvI2L + AndL 0xffffffff. // LoadI + ConvI2L + AndL 0xffffffff.
instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{
...@@ -6078,7 +6083,7 @@ instruct loadConNKlass_hi(iRegNdst dst, immNKlass src) %{ ...@@ -6078,7 +6083,7 @@ instruct loadConNKlass_hi(iRegNdst dst, immNKlass src) %{
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
%} %}
// This needs a match rule so that build_oop_map knows this is // This needs a match rule so that build_oop_map knows this is
// not a narrow oop. // not a narrow oop.
instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
match(Set dst src1); match(Set dst src1);
...@@ -6702,7 +6707,7 @@ instruct cond_set_0_oop(iRegNdst dst, flagsReg crx, iRegPsrc src1) %{ ...@@ -6702,7 +6707,7 @@ instruct cond_set_0_oop(iRegNdst dst, flagsReg crx, iRegPsrc src1) %{
size(4); size(4);
ins_encode %{ ins_encode %{
// This is a Power7 instruction for which no machine description exists. // This is a Power7 instruction for which no machine description exists.
// TODO: PPC port $archOpcode(ppc64Opcode_compound); // TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
%} %}
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
...@@ -6847,7 +6852,7 @@ instruct cond_set_0_ptr(iRegPdst dst, flagsReg crx, iRegPsrc src1) %{ ...@@ -6847,7 +6852,7 @@ instruct cond_set_0_ptr(iRegPdst dst, flagsReg crx, iRegPsrc src1) %{
size(4); size(4);
ins_encode %{ ins_encode %{
// This is a Power7 instruction for which no machine description exists. // This is a Power7 instruction for which no machine description exists.
// TODO: PPC port $archOpcode(ppc64Opcode_compound); // TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
%} %}
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
...@@ -7064,7 +7069,7 @@ instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc s ...@@ -7064,7 +7069,7 @@ instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc s
n1->_bottom_type = _bottom_type; n1->_bottom_type = _bottom_type;
decodeNKlass_shiftNode *n2 = new (C) decodeNKlass_shiftNode(); decodeNKlass_shiftNode *n2 = new (C) decodeNKlass_shiftNode();
n2->add_req(n_region, n2); n2->add_req(n_region, n1);
n2->_opnds[0] = op_dst; n2->_opnds[0] = op_dst;
n2->_opnds[1] = op_dst; n2->_opnds[1] = op_dst;
n2->_bottom_type = _bottom_type; n2->_bottom_type = _bottom_type;
...@@ -7199,7 +7204,7 @@ instruct membar_volatile() %{ ...@@ -7199,7 +7204,7 @@ instruct membar_volatile() %{
// inline_unsafe_load_store). // inline_unsafe_load_store).
// //
// Add this node again if we found a good solution for inline_unsafe_load_store(). // Add this node again if we found a good solution for inline_unsafe_load_store().
// Don't forget to look at the implementation of post_store_load_barrier again, // Don't forget to look at the implementation of post_store_load_barrier again,
// we did other fixes in that method. // we did other fixes in that method.
//instruct unnecessary_membar_volatile() %{ //instruct unnecessary_membar_volatile() %{
// match(MemBarVolatile); // match(MemBarVolatile);
...@@ -7237,7 +7242,7 @@ instruct cmovI_reg_isel(cmpOp cmp, flagsReg crx, iRegIdst dst, iRegIsrc src) %{ ...@@ -7237,7 +7242,7 @@ instruct cmovI_reg_isel(cmpOp cmp, flagsReg crx, iRegIdst dst, iRegIsrc src) %{
// exists. Anyways, the scheduler should be off on Power7. // exists. Anyways, the scheduler should be off on Power7.
// TODO: PPC port $archOpcode(ppc64Opcode_compound); // TODO: PPC port $archOpcode(ppc64Opcode_compound);
int cc = $cmp$$cmpcode; int cc = $cmp$$cmpcode;
__ isel($dst$$Register, $crx$$CondRegister, __ isel($dst$$Register, $crx$$CondRegister,
(Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
%} %}
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
...@@ -7283,7 +7288,7 @@ instruct cmovL_reg_isel(cmpOp cmp, flagsReg crx, iRegLdst dst, iRegLsrc src) %{ ...@@ -7283,7 +7288,7 @@ instruct cmovL_reg_isel(cmpOp cmp, flagsReg crx, iRegLdst dst, iRegLsrc src) %{
// exists. Anyways, the scheduler should be off on Power7. // exists. Anyways, the scheduler should be off on Power7.
// TODO: PPC port $archOpcode(ppc64Opcode_compound); // TODO: PPC port $archOpcode(ppc64Opcode_compound);
int cc = $cmp$$cmpcode; int cc = $cmp$$cmpcode;
__ isel($dst$$Register, $crx$$CondRegister, __ isel($dst$$Register, $crx$$CondRegister,
(Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
%} %}
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
...@@ -7329,7 +7334,7 @@ instruct cmovN_reg_isel(cmpOp cmp, flagsReg crx, iRegNdst dst, iRegNsrc src) %{ ...@@ -7329,7 +7334,7 @@ instruct cmovN_reg_isel(cmpOp cmp, flagsReg crx, iRegNdst dst, iRegNsrc src) %{
// exists. Anyways, the scheduler should be off on Power7. // exists. Anyways, the scheduler should be off on Power7.
// TODO: PPC port $archOpcode(ppc64Opcode_compound); // TODO: PPC port $archOpcode(ppc64Opcode_compound);
int cc = $cmp$$cmpcode; int cc = $cmp$$cmpcode;
__ isel($dst$$Register, $crx$$CondRegister, __ isel($dst$$Register, $crx$$CondRegister,
(Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
%} %}
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
...@@ -7376,7 +7381,7 @@ instruct cmovP_reg_isel(cmpOp cmp, flagsReg crx, iRegPdst dst, iRegPsrc src) %{ ...@@ -7376,7 +7381,7 @@ instruct cmovP_reg_isel(cmpOp cmp, flagsReg crx, iRegPdst dst, iRegPsrc src) %{
// exists. Anyways, the scheduler should be off on Power7. // exists. Anyways, the scheduler should be off on Power7.
// TODO: PPC port $archOpcode(ppc64Opcode_compound); // TODO: PPC port $archOpcode(ppc64Opcode_compound);
int cc = $cmp$$cmpcode; int cc = $cmp$$cmpcode;
__ isel($dst$$Register, $crx$$CondRegister, __ isel($dst$$Register, $crx$$CondRegister,
(Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
%} %}
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
...@@ -7522,8 +7527,8 @@ instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc ...@@ -7522,8 +7527,8 @@ instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc
ins_encode %{ ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound); // TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(), MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, true); $res$$Register, true);
%} %}
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
...@@ -7929,7 +7934,23 @@ instruct subL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ ...@@ -7929,7 +7934,23 @@ instruct subL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
// Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
// positive longs and 0xF...F for negative ones. // positive longs and 0xF...F for negative ones.
instruct signmask64I_regI(iRegIdst dst, iRegIsrc src) %{ instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
// no match-rule, false predicate
effect(DEF dst, USE src);
predicate(false);
format %{ "SRADI $dst, $src, #63" %}
size(4);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_sradi);
__ sradi($dst$$Register, $src$$Register, 0x3f);
%}
ins_pipe(pipe_class_default);
%}
// Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for
// positive longs and 0xF...F for negative ones.
instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
// no match-rule, false predicate // no match-rule, false predicate
effect(DEF dst, USE src); effect(DEF dst, USE src);
predicate(false); predicate(false);
...@@ -8893,7 +8914,7 @@ instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) % ...@@ -8893,7 +8914,7 @@ instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %
size(4); size(4);
ins_encode %{ ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
__ rlwinm($dst$$Register, $src1$$Register, 0, __ rlwinm($dst$$Register, $src1$$Register, 0,
(31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f);
%} %}
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
...@@ -9619,14 +9640,14 @@ instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ ...@@ -9619,14 +9640,14 @@ instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
ins_cost(DEFAULT_COST*4); ins_cost(DEFAULT_COST*4);
expand %{ expand %{
iRegIdst src1s; iRegLdst src1s;
iRegIdst src2s; iRegLdst src2s;
iRegIdst diff; iRegLdst diff;
sxtI_reg(src1s, src1); // ensure proper sign extention convI2L_reg(src1s, src1); // Ensure proper sign extension.
sxtI_reg(src2s, src2); // ensure proper sign extention convI2L_reg(src2s, src2); // Ensure proper sign extension.
subI_reg_reg(diff, src1s, src2s); subL_reg_reg(diff, src1s, src2s);
// Need to consider >=33 bit result, therefore we need signmaskL. // Need to consider >=33 bit result, therefore we need signmaskL.
signmask64I_regI(dst, diff); signmask64I_regL(dst, diff);
%} %}
%} %}
...@@ -10863,7 +10884,7 @@ instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P supe ...@@ -10863,7 +10884,7 @@ instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P supe
format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
ins_encode %{ ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound); // TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
$tmp_klass$$Register, NULL, $result$$Register); $tmp_klass$$Register, NULL, $result$$Register);
%} %}
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
...@@ -11178,18 +11199,18 @@ instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ ...@@ -11178,18 +11199,18 @@ instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
ins_cost(DEFAULT_COST*6); ins_cost(DEFAULT_COST*6);
expand %{ expand %{
iRegIdst src1s; iRegLdst src1s;
iRegIdst src2s; iRegLdst src2s;
iRegIdst diff; iRegLdst diff;
iRegIdst sm; iRegLdst sm;
iRegIdst doz; // difference or zero iRegLdst doz; // difference or zero
sxtI_reg(src1s, src1); // Ensure proper sign extention. convI2L_reg(src1s, src1); // Ensure proper sign extension.
sxtI_reg(src2s, src2); // Ensure proper sign extention. convI2L_reg(src2s, src2); // Ensure proper sign extension.
subI_reg_reg(diff, src2s, src1s); subL_reg_reg(diff, src2s, src1s);
// Need to consider >=33 bit result, therefore we need signmaskL. // Need to consider >=33 bit result, therefore we need signmaskL.
signmask64I_regI(sm, diff); signmask64L_regL(sm, diff);
andI_reg_reg(doz, diff, sm); // <=0 andL_reg_reg(doz, diff, sm); // <=0
addI_reg_reg(dst, doz, src1s); addI_regL_regL(dst, doz, src1s);
%} %}
%} %}
...@@ -11198,19 +11219,18 @@ instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ ...@@ -11198,19 +11219,18 @@ instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
ins_cost(DEFAULT_COST*6); ins_cost(DEFAULT_COST*6);
expand %{ expand %{
immI_minus1 m1 %{ -1 %} iRegLdst src1s;
iRegIdst src1s; iRegLdst src2s;
iRegIdst src2s; iRegLdst diff;
iRegIdst diff; iRegLdst sm;
iRegIdst sm; iRegLdst doz; // difference or zero
iRegIdst doz; // difference or zero convI2L_reg(src1s, src1); // Ensure proper sign extension.
sxtI_reg(src1s, src1); // Ensure proper sign extention. convI2L_reg(src2s, src2); // Ensure proper sign extension.
sxtI_reg(src2s, src2); // Ensure proper sign extention. subL_reg_reg(diff, src2s, src1s);
subI_reg_reg(diff, src2s, src1s);
// Need to consider >=33 bit result, therefore we need signmaskL. // Need to consider >=33 bit result, therefore we need signmaskL.
signmask64I_regI(sm, diff); signmask64L_regL(sm, diff);
andcI_reg_reg(doz, sm, m1, diff); // >=0 andcL_reg_reg(doz, diff, sm); // >=0
addI_reg_reg(dst, doz, src1s); addI_regL_regL(dst, doz, src1s);
%} %}
%} %}
......
...@@ -81,24 +81,18 @@ address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(con ...@@ -81,24 +81,18 @@ address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(con
#if 0 #if 0
// Call special ClassCastException constructor taking object to cast // Call special ClassCastException constructor taking object to cast
// and target class as arguments. // and target class as arguments.
address TemplateInterpreterGenerator::generate_ClassCastException_verbose_handler(const char* name) { address TemplateInterpreterGenerator::generate_ClassCastException_verbose_handler() {
address entry = __ pc(); address entry = __ pc();
// Target class oop is in register R6_ARG4 by convention!
// Expression stack must be empty before entering the VM if an // Expression stack must be empty before entering the VM if an
// exception happened. // exception happened.
__ empty_expression_stack(); __ empty_expression_stack();
// Setup parameters.
// Thread will be loaded to R3_ARG1. // Thread will be loaded to R3_ARG1.
__ load_const_optimized(R4_ARG2, (address) name); // Target class oop is in register R5_ARG3 by convention!
__ mr(R5_ARG3, R17_tos); __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException_verbose, R17_tos, R5_ARG3));
// R6_ARG4 contains specified class.
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException_verbose));
#ifdef ASSERT
// Above call must not return here since exception pending. // Above call must not return here since exception pending.
__ should_not_reach_here(); DEBUG_ONLY(__ should_not_reach_here();)
#endif
return entry; return entry;
} }
#endif #endif
...@@ -1535,14 +1529,32 @@ void TemplateInterpreterGenerator::generate_throw_exception() { ...@@ -1535,14 +1529,32 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
__ stw(R0, in_bytes(JavaThread::popframe_condition_offset()), R16_thread); __ stw(R0, in_bytes(JavaThread::popframe_condition_offset()), R16_thread);
// Get out of the current method and re-execute the call that called us. // Get out of the current method and re-execute the call that called us.
__ merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ return_pc, R11_scratch1, R12_scratch2); __ merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ noreg, R11_scratch1, R12_scratch2);
__ restore_interpreter_state(R11_scratch1); __ restore_interpreter_state(R11_scratch1);
__ ld(R12_scratch2, _ijava_state_neg(top_frame_sp), R11_scratch1); __ ld(R12_scratch2, _ijava_state_neg(top_frame_sp), R11_scratch1);
__ resize_frame_absolute(R12_scratch2, R11_scratch1, R0); __ resize_frame_absolute(R12_scratch2, R11_scratch1, R0);
__ mtlr(return_pc);
if (ProfileInterpreter) { if (ProfileInterpreter) {
__ set_method_data_pointer_for_bcp(); __ set_method_data_pointer_for_bcp();
} }
#if INCLUDE_JVMTI
Label L_done;
__ lbz(R11_scratch1, 0, R14_bcp);
__ cmpwi(CCR0, R11_scratch1, Bytecodes::_invokestatic);
__ bne(CCR0, L_done);
// The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
// Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
__ ld(R4_ARG2, 0, R18_locals);
__ call_VM(R11_scratch1, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null),
R4_ARG2, R19_method, R14_bcp);
__ cmpdi(CCR0, R11_scratch1, 0);
__ beq(CCR0, L_done);
__ std(R11_scratch1, wordSize, R15_esp);
__ bind(L_done);
#endif // INCLUDE_JVMTI
__ dispatch_next(vtos); __ dispatch_next(vtos);
} }
// end of JVMTI PopFrame support // end of JVMTI PopFrame support
......
...@@ -64,7 +64,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm, ...@@ -64,7 +64,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
assert_different_registers(Rtmp1, Rtmp2, Rtmp3, Rval, Rbase); assert_different_registers(Rtmp1, Rtmp2, Rtmp3, Rval, Rbase);
switch (barrier) { switch (barrier) {
#ifndef SERIALGC #if INCLUDE_ALL_GCS
case BarrierSet::G1SATBCT: case BarrierSet::G1SATBCT:
case BarrierSet::G1SATBCTLogging: case BarrierSet::G1SATBCTLogging:
{ {
...@@ -104,7 +104,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm, ...@@ -104,7 +104,7 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
__ bind(Ldone); __ bind(Ldone);
} }
break; break;
#endif // SERIALGC #endif // INCLUDE_ALL_GCS
case BarrierSet::CardTableModRef: case BarrierSet::CardTableModRef:
case BarrierSet::CardTableExtension: case BarrierSet::CardTableExtension:
{ {
...@@ -259,17 +259,17 @@ void TemplateTable::fconst(int value) { ...@@ -259,17 +259,17 @@ void TemplateTable::fconst(int value) {
switch (value) { switch (value) {
default: ShouldNotReachHere(); default: ShouldNotReachHere();
case 0: { case 0: {
int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&zero, R0); int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&zero, R0, true);
__ lfs(F15_ftos, simm16_offset, R11_scratch1); __ lfs(F15_ftos, simm16_offset, R11_scratch1);
break; break;
} }
case 1: { case 1: {
int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&one, R0); int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&one, R0, true);
__ lfs(F15_ftos, simm16_offset, R11_scratch1); __ lfs(F15_ftos, simm16_offset, R11_scratch1);
break; break;
} }
case 2: { case 2: {
int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&two, R0); int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&two, R0, true);
__ lfs(F15_ftos, simm16_offset, R11_scratch1); __ lfs(F15_ftos, simm16_offset, R11_scratch1);
break; break;
} }
...@@ -282,12 +282,12 @@ void TemplateTable::dconst(int value) { ...@@ -282,12 +282,12 @@ void TemplateTable::dconst(int value) {
static double one = 1.0; static double one = 1.0;
switch (value) { switch (value) {
case 0: { case 0: {
int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&zero, R0); int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&zero, R0, true);
__ lfd(F15_ftos, simm16_offset, R11_scratch1); __ lfd(F15_ftos, simm16_offset, R11_scratch1);
break; break;
} }
case 1: { case 1: {
int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&one, R0); int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&one, R0, true);
__ lfd(F15_ftos, simm16_offset, R11_scratch1); __ lfd(F15_ftos, simm16_offset, R11_scratch1);
break; break;
} }
...@@ -3728,9 +3728,9 @@ void TemplateTable::checkcast() { ...@@ -3728,9 +3728,9 @@ void TemplateTable::checkcast() {
transition(atos, atos); transition(atos, atos);
Label Ldone, Lis_null, Lquicked, Lresolved; Label Ldone, Lis_null, Lquicked, Lresolved;
Register Roffset = R5_ARG3, Register Roffset = R6_ARG4,
RobjKlass = R4_ARG2, RobjKlass = R4_ARG2,
RspecifiedKlass = R6_ARG4, // Generate_ClassCastException_verbose_handler will expect this register. RspecifiedKlass = R5_ARG3, // Generate_ClassCastException_verbose_handler will read value from this register.
Rcpool = R11_scratch1, Rcpool = R11_scratch1,
Rtags = R12_scratch2; Rtags = R12_scratch2;
......
...@@ -53,41 +53,41 @@ inline void Atomic::store_ptr(void* store_value, volatile void* dest) { * ...@@ -53,41 +53,41 @@ inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *
inline jlong Atomic::load(volatile jlong* src) { return *src; } inline jlong Atomic::load(volatile jlong* src) { return *src; }
/* //
machine barrier instructions: // machine barrier instructions:
//
- sync two-way memory barrier, aka fence // - sync two-way memory barrier, aka fence
- lwsync orders Store|Store, // - lwsync orders Store|Store,
Load|Store, // Load|Store,
Load|Load, // Load|Load,
but not Store|Load // but not Store|Load
- eieio orders memory accesses for device memory (only) // - eieio orders memory accesses for device memory (only)
- isync invalidates speculatively executed instructions // - isync invalidates speculatively executed instructions
From the POWER ISA 2.06 documentation: // From the POWER ISA 2.06 documentation:
"[...] an isync instruction prevents the execution of // "[...] an isync instruction prevents the execution of
instructions following the isync until instructions // instructions following the isync until instructions
preceding the isync have completed, [...]" // preceding the isync have completed, [...]"
From IBM's AIX assembler reference: // From IBM's AIX assembler reference:
"The isync [...] instructions causes the processor to // "The isync [...] instructions causes the processor to
refetch any instructions that might have been fetched // refetch any instructions that might have been fetched
prior to the isync instruction. The instruction isync // prior to the isync instruction. The instruction isync
causes the processor to wait for all previous instructions // causes the processor to wait for all previous instructions
to complete. Then any instructions already fetched are // to complete. Then any instructions already fetched are
discarded and instruction processing continues in the // discarded and instruction processing continues in the
environment established by the previous instructions." // environment established by the previous instructions."
//
semantic barrier instructions: // semantic barrier instructions:
(as defined in orderAccess.hpp) // (as defined in orderAccess.hpp)
//
- release orders Store|Store, (maps to lwsync) // - release orders Store|Store, (maps to lwsync)
Load|Store // Load|Store
- acquire orders Load|Store, (maps to lwsync) // - acquire orders Load|Store, (maps to lwsync)
Load|Load // Load|Load
- fence orders Store|Store, (maps to sync) // - fence orders Store|Store, (maps to sync)
Load|Store, // Load|Store,
Load|Load, // Load|Load,
Store|Load // Store|Load
*/ //
#define strasm_sync "\n sync \n" #define strasm_sync "\n sync \n"
#define strasm_lwsync "\n lwsync \n" #define strasm_lwsync "\n lwsync \n"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册