< prev index next >

src/cpu/sparc/vm/assembler_sparc.inline.hpp

Print this page

        

*** 26,50 **** #define CPU_SPARC_VM_ASSEMBLER_SPARC_INLINE_HPP #include "asm/assembler.hpp" ! inline void Assembler::insert_nop_after_cbcond() { ! if (UseCBCond && cbcond_before()) { nop(); } } inline void Assembler::check_delay() { ! #ifdef CHECK_DELAY ! guarantee(delay_state != at_delay_slot, "must say delayed() when filling delay slot"); ! delay_state = no_delay; #endif } inline void Assembler::emit_int32(int x) { check_delay(); AbstractAssembler::emit_int32(x); } inline void Assembler::emit_data(int x) { emit_int32(x); --- 26,71 ---- #define CPU_SPARC_VM_ASSEMBLER_SPARC_INLINE_HPP #include "asm/assembler.hpp" ! inline void Assembler::avoid_pipeline_stall() { ! #ifdef VALIDATE_PIPELINE ! if (_hazard_state == PcHazard) { ! assert(is_cbcond_before() || is_rdpc_before(), "PC-hazard not preceeded by CBCOND or RDPC."); ! assert_no_delay("Must not have PC-hazard state in delay-slot."); nop(); + _hazard_state = NoHazard; } + #endif + + bool post_cond = is_cbcond_before(); + bool post_rdpc = is_rdpc_before(); + + if (post_cond || post_rdpc) { + nop(); + #ifdef VALIDATE_PIPELINE + if (_hazard_state != PcHazard) { + assert(post_cond, "CBCOND before when no hazard @0x%p\n", pc()); + assert(post_rdpc, "RDPC before when no hazard @0x%p\n", pc()); + } + #endif + } } inline void Assembler::check_delay() { ! #ifdef VALIDATE_PIPELINE ! guarantee(_delay_state != AtDelay, "Use delayed() when filling delay-slot"); ! _delay_state = NoDelay; #endif } inline void Assembler::emit_int32(int x) { check_delay(); + #ifdef VALIDATE_PIPELINE + _hazard_state = NoHazard; + #endif AbstractAssembler::emit_int32(x); } inline void Assembler::emit_data(int x) { emit_int32(x);
*** 134,219 **** aes_only(); emit_int32(op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes3_op3) | fs1(s1, FloatRegisterImpl::D) | opf(aes_kexpand2_opf) | fs2(s2, FloatRegisterImpl::D)); } inline void Assembler::bpr(RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt) { ! insert_nop_after_cbcond(); cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); ! has_delay_slot(); } inline void Assembler::bpr(RCondition c, bool a, Predict p, Register s1, Label &L) { ! insert_nop_after_cbcond(); bpr(c, a, p, s1, target(L)); } inline void Assembler::fb(Condition c, bool a, address d, relocInfo::relocType rt) { v9_dep(); ! insert_nop_after_cbcond(); cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); ! has_delay_slot(); } inline void Assembler::fb(Condition c, bool a, Label &L) { ! insert_nop_after_cbcond(); fb(c, a, target(L)); } inline void Assembler::fbp(Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt) { ! insert_nop_after_cbcond(); cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); ! has_delay_slot(); } inline void Assembler::fbp(Condition c, bool a, CC cc, Predict p, Label &L) { ! insert_nop_after_cbcond(); fbp(c, a, cc, p, target(L)); } inline void Assembler::br(Condition c, bool a, address d, relocInfo::relocType rt) { v9_dep(); ! insert_nop_after_cbcond(); cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); ! has_delay_slot(); } inline void Assembler::br(Condition c, bool a, Label &L) { ! insert_nop_after_cbcond(); br(c, a, target(L)); } inline void Assembler::bp(Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt) { ! insert_nop_after_cbcond(); cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); ! has_delay_slot(); } inline void Assembler::bp(Condition c, bool a, CC cc, Predict p, Label &L) { ! insert_nop_after_cbcond(); bp(c, a, cc, p, target(L)); } // compare and branch inline void Assembler::cbcond(Condition c, CC cc, Register s1, Register s2, Label &L) { ! cti(); no_cbcond_before(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | rs2(s2)); } inline void Assembler::cbcond(Condition c, CC cc, Register s1, int simm5, Label &L) { ! cti(); no_cbcond_before(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | immed(true) | simm(simm5, 5)); } inline void Assembler::call(address d, relocInfo::relocType rt) { ! insert_nop_after_cbcond(); cti(); emit_data(op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); ! has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); } inline void Assembler::call(Label &L, relocInfo::relocType rt) { ! insert_nop_after_cbcond(); call(target(L), rt); } inline void Assembler::call(address d, RelocationHolder const &rspec) { ! insert_nop_after_cbcond(); cti(); emit_data(op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rspec); ! has_delay_slot(); assert(rspec.type() != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); } inline void Assembler::casa(Register s1, Register s2, Register d, int ia) { emit_int32(op(ldst_op) | rd(d) | op3(casa_op3) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); --- 155,258 ---- aes_only(); emit_int32(op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes3_op3) | fs1(s1, FloatRegisterImpl::D) | opf(aes_kexpand2_opf) | fs2(s2, FloatRegisterImpl::D)); } inline void Assembler::bpr(RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt) { ! avoid_pipeline_stall(); ! cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); ! induce_delay_slot(); } inline void Assembler::bpr(RCondition c, bool a, Predict p, Register s1, Label &L) { ! // Note[+]: All assembly emit routines using the 'target()' branch back-patch ! // resolver must call 'avoid_pipeline_stall()' prior to calling 'target()' ! // (we must do so even though the call will be made, as here, in the above ! // implementation of 'bpr()', invoked below). The reason is the assumption ! // made in 'target()', where using the current PC as the address for back- ! // patching prevents any additional code to be emitted _after_ the address ! // has been set (implicitly) in order to refer to the correct instruction. ! avoid_pipeline_stall(); bpr(c, a, p, s1, target(L)); } inline void Assembler::fb(Condition c, bool a, address d, relocInfo::relocType rt) { v9_dep(); ! avoid_pipeline_stall(); ! cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); ! induce_delay_slot(); } inline void Assembler::fb(Condition c, bool a, Label &L) { ! avoid_pipeline_stall(); fb(c, a, target(L)); } inline void Assembler::fbp(Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt) { ! avoid_pipeline_stall(); ! cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); ! induce_delay_slot(); } inline void Assembler::fbp(Condition c, bool a, CC cc, Predict p, Label &L) { ! avoid_pipeline_stall(); fbp(c, a, cc, p, target(L)); } inline void Assembler::br(Condition c, bool a, address d, relocInfo::relocType rt) { v9_dep(); ! avoid_pipeline_stall(); ! cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); ! induce_delay_slot(); } inline void Assembler::br(Condition c, bool a, Label &L) { ! avoid_pipeline_stall(); br(c, a, target(L)); } inline void Assembler::bp(Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt) { ! avoid_pipeline_stall(); ! cti(); emit_data(op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); ! induce_delay_slot(); } inline void Assembler::bp(Condition c, bool a, CC cc, Predict p, Label &L) { ! avoid_pipeline_stall(); bp(c, a, cc, p, target(L)); } // compare and branch inline void Assembler::cbcond(Condition c, CC cc, Register s1, Register s2, Label &L) { ! avoid_pipeline_stall(); ! cti(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | rs2(s2)); + induce_pc_hazard(); } inline void Assembler::cbcond(Condition c, CC cc, Register s1, int simm5, Label &L) { ! avoid_pipeline_stall(); ! cti(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | immed(true) | simm(simm5, 5)); + induce_pc_hazard(); } inline void Assembler::call(address d, relocInfo::relocType rt) { ! avoid_pipeline_stall(); ! cti(); emit_data(op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); ! induce_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); } inline void Assembler::call(Label &L, relocInfo::relocType rt) { ! avoid_pipeline_stall(); call(target(L), rt); } inline void Assembler::call(address d, RelocationHolder const &rspec) { ! avoid_pipeline_stall(); ! cti(); emit_data(op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rspec); ! induce_delay_slot(); assert(rspec.type() != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); } inline void Assembler::casa(Register s1, Register s2, Register d, int ia) { emit_int32(op(ldst_op) | rd(d) | op3(casa_op3) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2));
*** 337,354 **** inline void Assembler::impdep2(int id1, int const19a) { emit_int32(op(arith_op) | fcn(id1) | op3(impdep2_op3) | u_field(const19a, 18, 0)); } inline void Assembler::jmpl(Register s1, Register s2, Register d) { ! insert_nop_after_cbcond(); cti(); emit_int32(op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); ! has_delay_slot(); } inline void Assembler::jmpl(Register s1, int simm13a, Register d, RelocationHolder const &rspec) { ! insert_nop_after_cbcond(); cti(); emit_data(op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); ! has_delay_slot(); } inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_int32(op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2)); } --- 376,395 ---- inline void Assembler::impdep2(int id1, int const19a) { emit_int32(op(arith_op) | fcn(id1) | op3(impdep2_op3) | u_field(const19a, 18, 0)); } inline void Assembler::jmpl(Register s1, Register s2, Register d) { ! avoid_pipeline_stall(); ! cti(); emit_int32(op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); ! induce_delay_slot(); } inline void Assembler::jmpl(Register s1, int simm13a, Register d, RelocationHolder const &rspec) { ! avoid_pipeline_stall(); ! cti(); emit_data(op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); ! induce_delay_slot(); } inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_int32(op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2)); }
*** 652,676 **** } inline void Assembler::rdtick(Register d) { emit_int32(op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(4, 18, 14)); } inline void Assembler::rdpc(Register d) { emit_int32(op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(5, 18, 14)); } inline void Assembler::rdfprs(Register d) { emit_int32(op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(6, 18, 14)); } inline void Assembler::rett(Register s1, Register s2) { cti(); emit_int32(op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); ! has_delay_slot(); } inline void Assembler::rett(Register s1, int simm13a, relocInfo::relocType rt) { cti(); emit_data(op(arith_op) | op3(rett_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rt); ! has_delay_slot(); } inline void Assembler::save(Register s1, Register s2, Register d) { emit_int32(op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | rs2(s2)); } --- 693,720 ---- } inline void Assembler::rdtick(Register d) { emit_int32(op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(4, 18, 14)); } inline void Assembler::rdpc(Register d) { + avoid_pipeline_stall(); + cti(); emit_int32(op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(5, 18, 14)); + induce_pc_hazard(); } inline void Assembler::rdfprs(Register d) { emit_int32(op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(6, 18, 14)); } inline void Assembler::rett(Register s1, Register s2) { cti(); emit_int32(op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); ! induce_delay_slot(); } inline void Assembler::rett(Register s1, int simm13a, relocInfo::relocType rt) { cti(); emit_data(op(arith_op) | op3(rett_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rt); ! induce_delay_slot(); } inline void Assembler::save(Register s1, Register s2, Register d) { emit_int32(op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | rs2(s2)); }
< prev index next >