提交 6ed3c318 编写于 作者: K kvn

7063628: Use cbcond on T4

Summary: Add new short branch instruction to Hotspot sparc assembler.
Reviewed-by: never, twisti, jrose
上级 85eeb43c
......@@ -761,7 +761,7 @@ class Assembler : public AbstractAssembler {
mwtos_opf = 0x119
};
enum RCondition { rc_z = 1, rc_lez = 2, rc_lz = 3, rc_nz = 5, rc_gz = 6, rc_gez = 7 };
enum RCondition { rc_z = 1, rc_lez = 2, rc_lz = 3, rc_nz = 5, rc_gz = 6, rc_gez = 7, rc_last = rc_gez };
enum Condition {
// for FBfcc & FBPfcc instruction
......@@ -866,9 +866,18 @@ class Assembler : public AbstractAssembler {
return is_simm(d, nbits + 2);
}
address target_distance(Label& L) {
// Assembler::target(L) should be called only when
// a branch instruction is emitted since non-bound
// labels record current pc() as a branch address.
if (L.is_bound()) return target(L);
// Return current address for non-bound labels.
return pc();
}
// test if label is in simm16 range in words (wdisp16).
bool is_in_wdisp16_range(Label& L) {
return is_in_wdisp_range(target(L), pc(), 16);
return is_in_wdisp_range(target_distance(L), pc(), 16);
}
// test if the distance between two addresses fits in simm30 range in words
static bool is_in_wdisp30_range(address a, address b) {
......@@ -975,6 +984,20 @@ class Assembler : public AbstractAssembler {
static int sx( int i) { return u_field(i, 12, 12); } // shift x=1 means 64-bit
static int opf( int x) { return u_field(x, 13, 5); }
static bool is_cbcond( int x ) {
return (VM_Version::has_cbcond() && (inv_cond(x) > rc_last) &&
inv_op(x) == branch_op && inv_op2(x) == bpr_op2);
}
static bool is_cxb( int x ) {
assert(is_cbcond(x), "wrong instruction");
return (x & (1<<21)) != 0;
}
static int cond_cbcond( int x) { return u_field((((x & 8)<<1) + 8 + (x & 7)), 29, 25); }
static int inv_cond_cbcond(int x) {
assert(is_cbcond(x), "wrong instruction");
return inv_u_field(x, 27, 25) | (inv_u_field(x, 29, 29)<<3);
}
static int opf_cc( CC c, bool useFloat ) { return u_field((useFloat ? 0 : 4) + c, 13, 11); }
static int mov_cc( CC c, bool useFloat ) { return u_field(useFloat ? 0 : 1, 18, 18) | u_field(c, 12, 11); }
......@@ -1026,6 +1049,26 @@ class Assembler : public AbstractAssembler {
return r;
}
// compute inverse of wdisp10
static intptr_t inv_wdisp10(int x, intptr_t pos) {
assert(is_cbcond(x), "wrong instruction");
int lo = inv_u_field(x, 12, 5);
int hi = (x >> 19) & 3;
if (hi >= 2) hi |= ~1;
return (((hi << 8) | lo) << 2) + pos;
}
// word offset for cbcond, 8 bits at [B12,B5], 2 bits at [B20,B19]
static int wdisp10(intptr_t x, intptr_t off) {
assert(VM_Version::has_cbcond(), "This CPU does not have CBCOND instruction");
intptr_t xx = x - off;
assert_signed_word_disp_range(xx, 10);
int r = ( ( (xx >> 2 ) & ((1 << 8) - 1) ) << 5 )
| ( ( (xx >> (2+8)) & 3 ) << 19 );
// Have to fake cbcond instruction to pass assert in inv_wdisp10()
assert(inv_wdisp10((r | op(branch_op) | cond_cbcond(rc_last+1) | op2(bpr_op2)), off) == x, "inverse is not inverse");
return r;
}
// word displacement in low-order nbits bits
......@@ -1138,6 +1181,24 @@ class Assembler : public AbstractAssembler {
#endif
}
// cbcond instruction should not be generated one after an other
bool cbcond_before() {
if (offset() == 0) return false; // it is first instruction
int x = *(int*)(intptr_t(pc()) - 4); // previous instruction
return is_cbcond(x);
}
void no_cbcond_before() {
assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond");
}
bool use_cbcond(Label& L) {
if (!UseCBCond || cbcond_before()) return false;
intptr_t x = intptr_t(target_distance(L)) - intptr_t(pc());
assert( (x & 3) == 0, "not word aligned");
return is_simm(x, 12);
}
public:
// Tells assembler you know that next instruction is delayed
Assembler* delayed() {
......@@ -1181,10 +1242,11 @@ public:
void addccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
void addccc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
// pp 136
inline void bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none );
inline void bpr( RCondition c, bool a, Predict p, Register s1, Label& L);
inline void bpr(RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none);
inline void bpr(RCondition c, bool a, Predict p, Register s1, Label& L);
protected: // use MacroAssembler::br instead
......@@ -1198,8 +1260,6 @@ public:
inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
inline void fbp( Condition c, bool a, CC cc, Predict p, Label& L );
public:
// pp 144
inline void br( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none );
......@@ -1215,11 +1275,17 @@ public:
inline void cb( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none );
inline void cb( Condition c, bool a, Label& L );
// compare and branch
inline void cbcond(Condition c, CC cc, Register s1, Register s2, Label& L);
inline void cbcond(Condition c, CC cc, Register s1, int simm5, Label& L);
// pp 149
inline void call( address d, relocInfo::relocType rt = relocInfo::runtime_call_type );
inline void call( Label& L, relocInfo::relocType rt = relocInfo::runtime_call_type );
public:
// pp 150
// These instructions compare the contents of s2 with the contents of
......@@ -1862,8 +1928,8 @@ class MacroAssembler: public Assembler {
inline void fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
inline void fb( Condition c, bool a, Predict p, Label& L );
// compares register with zero and branches (V9 and V8 instructions)
void br_zero( Condition c, bool a, Predict p, Register s1, Label& L);
// compares register with zero (32 bit) and branches (V9 and V8 instructions)
void cmp_zero_and_br( Condition c, Register s1, Label& L, bool a = false, Predict p = pn );
// Compares a pointer register with zero and branches on (not)null.
// Does a test & branch on 32-bit systems and a register-branch on 64-bit.
void br_null ( Register s1, bool a, Predict p, Label& L );
......@@ -1875,6 +1941,26 @@ class MacroAssembler: public Assembler {
void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none );
void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, Label& L);
//
// Compare registers and branch with nop in delay slot or cbcond without delay slot.
//
// ATTENTION: use these instructions with caution because cbcond instruction
// has very short distance: 512 instructions (2Kbyte).
// Compare integer (32 bit) values (icc only).
void cmp_and_br_short(Register s1, Register s2, Condition c, Predict p, Label& L);
void cmp_and_br_short(Register s1, int simm13a, Condition c, Predict p, Label& L);
// Platform depending version for pointer compare (icc on !LP64 and xcc on LP64).
void cmp_and_brx_short(Register s1, Register s2, Condition c, Predict p, Label& L);
void cmp_and_brx_short(Register s1, int simm13a, Condition c, Predict p, Label& L);
// Short branch version for compares a pointer pwith zero.
void br_null_short ( Register s1, Predict p, Label& L );
void br_notnull_short( Register s1, Predict p, Label& L );
// unconditional short branch
void ba_short(Label& L);
inline void bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
inline void bp( Condition c, bool a, CC cc, Predict p, Label& L );
......@@ -1882,8 +1968,8 @@ class MacroAssembler: public Assembler {
inline void brx( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
inline void brx( Condition c, bool a, Predict p, Label& L );
// unconditional short branch
inline void ba( bool a, Label& L );
// unconditional branch
inline void ba( Label& L );
// Branch that tests fp condition codes
inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
......@@ -2167,7 +2253,6 @@ public:
inline void stbool(Register d, const Address& a) { stb(d, a); }
inline void ldbool(const Address& a, Register d) { ldsb(a, d); }
inline void tstbool( Register s ) { tst(s); }
inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); }
// klass oop manipulations if compressed
......@@ -2469,8 +2554,7 @@ public:
Label* L_success,
Label* L_failure,
Label* L_slow_path,
RegisterOrConstant super_check_offset = RegisterOrConstant(-1),
Register instanceof_hack = noreg);
RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
// The rest of the type check; must be wired to a corresponding fast path.
// It does not repeat the fast path logic, so don't use it standalone.
......
......@@ -80,32 +80,36 @@ inline void Assembler::add(Register s1, Register s2, Register d )
inline void Assembler::add(Register s1, int simm13a, Register d, relocInfo::relocType rtype ) { emit_data( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rtype ); }
inline void Assembler::add(Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { emit_data( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec ); }
inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); 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, address d, relocInfo::relocType rt ) { v9_only(); 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) { bpr( c, a, p, s1, target(L)); }
inline void Assembler::fb( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); 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, address d, relocInfo::relocType rt ) { v9_dep(); 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 ) { fb(c, a, target(L)); }
inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); 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, address d, relocInfo::relocType rt ) { v9_only(); 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 ) { fbp(c, a, cc, p, target(L)); }
inline void Assembler::cb( Condition c, bool a, address d, relocInfo::relocType rt ) { v8_only(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(cb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
inline void Assembler::cb( Condition c, bool a, address d, relocInfo::relocType rt ) { v8_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(cb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
inline void Assembler::cb( Condition c, bool a, Label& L ) { cb(c, a, target(L)); }
inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); 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, address d, relocInfo::relocType rt ) { v9_dep(); 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 ) { br(c, a, target(L)); }
inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); 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, address d, relocInfo::relocType rt ) { v9_only(); 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 ) { bp(c, a, cc, p, target(L)); }
inline void Assembler::call( address d, relocInfo::relocType rt ) { 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"); }
// 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 ) { 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 ) { call( target(L), rt); }
inline void Assembler::flush( Register s1, Register s2) { emit_long( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); }
inline void Assembler::flush( Register s1, int simm13a) { emit_data( op(arith_op) | op3(flush_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
inline void Assembler::jmpl( Register s1, Register s2, Register d ) { emit_long( 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 ) { emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); }
inline void Assembler::jmpl( Register s1, Register s2, Register d ) { cti(); emit_long( 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 ) { 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, RegisterOrConstant s2, FloatRegister d) {
if (s2.is_register()) ldf(w, s1, s2.as_register(), d);
......@@ -240,8 +244,8 @@ inline void Assembler::prefetch(Register s1, int simm13a, PrefetchFcn f) { v9_on
inline void Assembler::prefetch(const Address& a, PrefetchFcn f, int offset) { v9_only(); relocate(a.rspec(offset)); prefetch(a.base(), a.disp() + offset, f); }
inline void Assembler::rett( Register s1, Register s2 ) { emit_long( op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); }
inline void Assembler::rett( Register s1, int simm13a, relocInfo::relocType rt) { emit_data( op(arith_op) | op3(rett_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rt); has_delay_slot(); }
inline void Assembler::rett( Register s1, Register s2 ) { cti(); emit_long( 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::sethi( int imm22a, Register d, RelocationHolder const& rspec ) { emit_data( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(imm22a), rspec); }
......@@ -557,8 +561,8 @@ inline void MacroAssembler::brx( Condition c, bool a, Predict p, Label& L ) {
brx(c, a, p, target(L));
}
inline void MacroAssembler::ba( bool a, Label& L ) {
br(always, a, pt, L);
inline void MacroAssembler::ba( Label& L ) {
br(always, false, pt, L);
}
// Warning: V9 only functions
......
......@@ -303,9 +303,7 @@ void PatchingStub::emit_code(LIR_Assembler* ce) {
assert(_oop_index >= 0, "must have oop index");
__ load_heap_oop(_obj, java_lang_Class::klass_offset_in_bytes(), G3);
__ ld_ptr(G3, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
__ cmp(G2_thread, G3);
__ br(Assembler::notEqual, false, Assembler::pn, call_patch);
__ delayed()->nop();
__ cmp_and_brx_short(G2_thread, G3, Assembler::notEqual, Assembler::pn, call_patch);
// load_klass patches may execute the patched code before it's
// copied back into place so we need to jump back into the main
......
......@@ -217,9 +217,7 @@ void LIR_Assembler::osr_entry() {
{
Label L;
__ ld_ptr(OSR_buf, slot_offset + 1*BytesPerWord, O7);
__ cmp(G0, O7);
__ br(Assembler::notEqual, false, Assembler::pt, L);
__ delayed()->nop();
__ cmp_and_br_short(O7, G0, Assembler::notEqual, Assembler::pt, L);
__ stop("locked object is NULL");
__ bind(L);
}
......@@ -2096,10 +2094,10 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ xor3(O0, -1, tmp);
__ sub(length, tmp, length);
__ add(src_pos, tmp, src_pos);
__ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry());
__ cmp_zero_and_br(Assembler::less, O0, *stub->entry());
__ delayed()->add(dst_pos, tmp, dst_pos);
} else {
__ br_zero(Assembler::less, false, Assembler::pn, O0, *stub->entry());
__ cmp_zero_and_br(Assembler::less, O0, *stub->entry());
__ delayed()->nop();
}
__ bind(*stub->continuation());
......@@ -2123,22 +2121,19 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
// test src_pos register
__ tst(src_pos);
__ br(Assembler::less, false, Assembler::pn, *stub->entry());
__ cmp_zero_and_br(Assembler::less, src_pos, *stub->entry());
__ delayed()->nop();
}
if (flags & LIR_OpArrayCopy::dst_pos_positive_check) {
// test dst_pos register
__ tst(dst_pos);
__ br(Assembler::less, false, Assembler::pn, *stub->entry());
__ cmp_zero_and_br(Assembler::less, dst_pos, *stub->entry());
__ delayed()->nop();
}
if (flags & LIR_OpArrayCopy::length_positive_check) {
// make sure length isn't negative
__ tst(length);
__ br(Assembler::less, false, Assembler::pn, *stub->entry());
__ cmp_zero_and_br(Assembler::less, length, *stub->entry());
__ delayed()->nop();
}
......@@ -2261,8 +2256,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
#ifndef PRODUCT
if (PrintC1Statistics) {
Label failed;
__ br_notnull(O0, false, Assembler::pn, failed);
__ delayed()->nop();
__ br_notnull_short(O0, Assembler::pn, failed);
__ inc_counter((address)&Runtime1::_arraycopy_checkcast_cnt, G1, G3);
__ bind(failed);
}
......@@ -2314,9 +2308,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ br(Assembler::notEqual, false, Assembler::pn, halt);
// load the raw value of the src klass.
__ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2);
__ cmp(tmp, tmp2);
__ br(Assembler::equal, false, Assembler::pn, known_ok);
__ delayed()->nop();
__ cmp_and_br_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok);
} else {
__ cmp(tmp, tmp2);
__ br(Assembler::equal, false, Assembler::pn, known_ok);
......@@ -2330,9 +2322,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
__ cmp(tmp, tmp2);
__ brx(Assembler::notEqual, false, Assembler::pn, halt);
__ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), tmp2);
__ cmp(tmp, tmp2);
__ brx(Assembler::equal, false, Assembler::pn, known_ok);
__ delayed()->nop();
__ cmp_and_brx_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok);
} else {
__ cmp(tmp, tmp2);
__ brx(Assembler::equal, false, Assembler::pn, known_ok);
......@@ -2530,15 +2520,13 @@ void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias,
mdo_offset_bias);
__ ld_ptr(receiver_addr, tmp1);
__ verify_oop(tmp1);
__ cmp(recv, tmp1);
__ brx(Assembler::notEqual, false, Assembler::pt, next_test);
__ delayed()->nop();
__ cmp_and_brx_short(recv, tmp1, Assembler::notEqual, Assembler::pt, next_test);
Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -
mdo_offset_bias);
__ ld_ptr(data_addr, tmp1);
__ add(tmp1, DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, data_addr);
__ ba(false, *update_done);
__ ba(*update_done);
__ delayed()->nop();
__ bind(next_test);
}
......@@ -2549,13 +2537,12 @@ void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias,
Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) -
mdo_offset_bias);
__ ld_ptr(recv_addr, tmp1);
__ br_notnull(tmp1, false, Assembler::pt, next_test);
__ delayed()->nop();
__ br_notnull_short(tmp1, Assembler::pt, next_test);
__ st_ptr(recv, recv_addr);
__ set(DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -
mdo_offset_bias);
__ ba(false, *update_done);
__ ba(*update_done);
__ delayed()->nop();
__ bind(next_test);
}
......@@ -2601,8 +2588,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias);
Label not_null;
__ br_notnull(obj, false, Assembler::pn, not_null);
__ delayed()->nop();
__ br_notnull_short(obj, Assembler::pn, not_null);
Register mdo = k_RInfo;
Register data_val = Rtmp1;
jobject2reg(md->constant_encoding(), mdo);
......@@ -2614,7 +2600,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
__ ldub(flags_addr, data_val);
__ or3(data_val, BitData::null_seen_byte_constant(), data_val);
__ stb(data_val, flags_addr);
__ ba(false, *obj_is_null);
__ ba(*obj_is_null);
__ delayed()->nop();
__ bind(not_null);
} else {
......@@ -2682,7 +2668,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
__ load_klass(obj, recv);
type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success);
// Jump over the failure case
__ ba(false, *success);
__ ba(*success);
__ delayed()->nop();
// Cast failure case
__ bind(profile_cast_failure);
......@@ -2695,10 +2681,10 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
__ ld_ptr(data_addr, tmp1);
__ sub(tmp1, DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, data_addr);
__ ba(false, *failure);
__ ba(*failure);
__ delayed()->nop();
}
__ ba(false, *success);
__ ba(*success);
__ delayed()->nop();
}
......@@ -2728,8 +2714,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
if (op->should_profile()) {
Label not_null;
__ br_notnull(value, false, Assembler::pn, not_null);
__ delayed()->nop();
__ br_notnull_short(value, Assembler::pn, not_null);
Register mdo = k_RInfo;
Register data_val = Rtmp1;
jobject2reg(md->constant_encoding(), mdo);
......@@ -2741,12 +2726,10 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
__ ldub(flags_addr, data_val);
__ or3(data_val, BitData::null_seen_byte_constant(), data_val);
__ stb(data_val, flags_addr);
__ ba(false, done);
__ delayed()->nop();
__ ba_short(done);
__ bind(not_null);
} else {
__ br_null(value, false, Assembler::pn, done);
__ delayed()->nop();
__ br_null_short(value, Assembler::pn, done);
}
add_debug_info_for_null_check_here(op->info_for_exception());
__ load_klass(array, k_RInfo);
......@@ -2777,8 +2760,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
}
__ load_klass(value, recv);
type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done);
__ ba(false, done);
__ delayed()->nop();
__ ba_short(done);
// Cast failure case
__ bind(profile_cast_failure);
jobject2reg(md->constant_encoding(), mdo);
......@@ -2790,7 +2772,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
__ ld_ptr(data_addr, tmp1);
__ sub(tmp1, DataLayout::counter_increment, tmp1);
__ st_ptr(tmp1, data_addr);
__ ba(false, *stub->entry());
__ ba(*stub->entry());
__ delayed()->nop();
}
__ bind(done);
......@@ -2808,8 +2790,7 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
emit_typecheck_helper(op, &success, &failure, &failure);
__ bind(failure);
__ set(0, dst);
__ ba(false, done);
__ delayed()->nop();
__ ba_short(done);
__ bind(success);
__ set(1, dst);
__ bind(done);
......
......@@ -41,9 +41,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
// Note: needs more testing of out-of-line vs. inline slow case
verify_oop(receiver);
load_klass(receiver, temp_reg);
cmp(temp_reg, iCache);
brx(Assembler::equal, true, Assembler::pt, L);
delayed()->nop();
cmp_and_brx_short(temp_reg, iCache, Assembler::equal, Assembler::pt, L);
AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
jump_to(ic_miss, temp_reg);
delayed()->nop();
......@@ -142,8 +140,7 @@ void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rb
}
// Test first it it is a fast recursive unlock
ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark);
br_null(Rmark, false, Assembler::pt, done);
delayed()->nop();
br_null_short(Rmark, Assembler::pt, done);
if (!UseBiasedLocking) {
// load object
ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop);
......@@ -231,7 +228,7 @@ void C1_MacroAssembler::allocate_object(
if (!is_simm13(obj_size * wordSize)) {
// would need to use extra register to load
// object size => go the slow case for now
br(Assembler::always, false, Assembler::pt, slow_case);
ba(slow_case);
delayed()->nop();
return;
}
......@@ -257,12 +254,10 @@ void C1_MacroAssembler::initialize_object(
Label ok;
ld(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), t1);
if (var_size_in_bytes != noreg) {
cmp(t1, var_size_in_bytes);
cmp_and_brx_short(t1, var_size_in_bytes, Assembler::equal, Assembler::pt, ok);
} else {
cmp(t1, con_size_in_bytes);
cmp_and_brx_short(t1, con_size_in_bytes, Assembler::equal, Assembler::pt, ok);
}
brx(Assembler::equal, false, Assembler::pt, ok);
delayed()->nop();
stop("bad size in initialize_object");
should_not_reach_here();
......@@ -387,8 +382,7 @@ void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
void C1_MacroAssembler::verify_not_null_oop(Register r) {
Label not_null;
br_notnull(r, false, Assembler::pt, not_null);
delayed()->nop();
br_notnull_short(r, Assembler::pt, not_null);
stop("non-null oop required");
bind(not_null);
if (!VerifyOops) return;
......
......@@ -71,8 +71,7 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e
{ Label L;
Address exception_addr(G2_thread, Thread::pending_exception_offset());
ld_ptr(exception_addr, Gtemp);
br_null(Gtemp, false, pt, L);
delayed()->nop();
br_null_short(Gtemp, pt, L);
Address vm_result_addr(G2_thread, JavaThread::vm_result_offset());
st_ptr(G0, vm_result_addr);
Address vm_result_addr_2(G2_thread, JavaThread::vm_result_2_offset());
......@@ -333,9 +332,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
assert(deopt_blob != NULL, "deoptimization blob must have been created");
Label no_deopt;
__ tst(O0);
__ brx(Assembler::equal, false, Assembler::pt, no_deopt);
__ delayed()->nop();
__ br_null_short(O0, Assembler::pt, no_deopt);
// return to the deoptimization handler entry for unpacking and rexecute
// if we simply returned the we'd deopt as if any call we patched had just
......@@ -402,18 +399,15 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
if (id == fast_new_instance_init_check_id) {
// make sure the klass is initialized
__ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1);
__ cmp(G3_t1, instanceKlass::fully_initialized);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
__ cmp_and_br_short(G3_t1, instanceKlass::fully_initialized, Assembler::notEqual, Assembler::pn, slow_path);
}
#ifdef ASSERT
// assert object can be fast path allocated
{
Label ok, not_ok;
__ ld(G5_klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), G1_obj_size);
__ cmp(G1_obj_size, 0); // make sure it's an instance (LH > 0)
__ br(Assembler::lessEqual, false, Assembler::pn, not_ok);
__ delayed()->nop();
// make sure it's an instance (LH > 0)
__ cmp_and_br_short(G1_obj_size, 0, Assembler::lessEqual, Assembler::pn, not_ok);
__ btst(Klass::_lh_instance_slow_path_bit, G1_obj_size);
__ br(Assembler::zero, false, Assembler::pn, ok);
__ delayed()->nop();
......@@ -501,9 +495,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
int tag = ((id == new_type_array_id)
? Klass::_lh_array_tag_type_value
: Klass::_lh_array_tag_obj_value);
__ cmp(G3_t1, tag);
__ brx(Assembler::equal, false, Assembler::pt, ok);
__ delayed()->nop();
__ cmp_and_brx_short(G3_t1, tag, Assembler::equal, Assembler::pt, ok);
__ stop("assert(is an array klass)");
__ should_not_reach_here();
__ bind(ok);
......@@ -519,9 +511,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
// check that array length is small enough for fast path
__ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
__ cmp(G4_length, G3_t1);
__ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
__ delayed()->nop();
__ cmp_and_br_short(G4_length, G3_t1, Assembler::greaterUnsigned, Assembler::pn, slow_path);
// if we got here then the TLAB allocation failed, so try
// refilling the TLAB or allocating directly from eden.
......
......@@ -544,7 +544,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
// Generate regular method entry
__ bind(slow_path);
__ ba(false, fast_accessor_slow_entry_path);
__ ba(fast_accessor_slow_entry_path);
__ delayed()->nop();
return entry;
}
......@@ -719,8 +719,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
Address exception_addr(G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
__ ld_ptr(exception_addr, G3_scratch);
__ br_notnull(G3_scratch, false, Assembler::pn, pending_exception_present);
__ delayed()->nop();
__ br_notnull_short(G3_scratch, Assembler::pn, pending_exception_present);
__ ld_ptr(Address(G5_method, 0, in_bytes(methodOopDesc::signature_handler_offset())), G3_scratch);
__ bind(L);
}
......@@ -1292,7 +1291,7 @@ void CppInterpreterGenerator::generate_deopt_handling() {
deopt_frame_manager_return_atos = __ pc();
// O0/O1 live
__ ba(false, return_from_deopt_common);
__ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_OBJECT), L3_scratch); // Result stub address array index
......@@ -1300,14 +1299,14 @@ void CppInterpreterGenerator::generate_deopt_handling() {
deopt_frame_manager_return_btos = __ pc();
// O0/O1 live
__ ba(false, return_from_deopt_common);
__ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_BOOLEAN), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result)
deopt_frame_manager_return_itos = __ pc();
// O0/O1 live
__ ba(false, return_from_deopt_common);
__ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_INT), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result)
......@@ -1327,21 +1326,21 @@ void CppInterpreterGenerator::generate_deopt_handling() {
__ srlx(G1,32,O0);
#endif /* !_LP64 && COMPILER2 */
// O0/O1 live
__ ba(false, return_from_deopt_common);
__ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_LONG), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result)
deopt_frame_manager_return_ftos = __ pc();
// O0/O1 live
__ ba(false, return_from_deopt_common);
__ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_FLOAT), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result)
deopt_frame_manager_return_dtos = __ pc();
// O0/O1 live
__ ba(false, return_from_deopt_common);
__ ba(return_from_deopt_common);
__ delayed()->set(AbstractInterpreter::BasicType_as_index(T_DOUBLE), L3_scratch); // Result stub address array index
// deopt needs to jump to here to enter the interpreter (return a result)
......@@ -1398,7 +1397,7 @@ void CppInterpreterGenerator::generate_more_monitors() {
__ ld_ptr(STATE(_stack), L1_scratch); // Get current stack top
__ sub(L1_scratch, entry_size, L1_scratch);
__ st_ptr(L1_scratch, STATE(_stack));
__ ba(false, entry);
__ ba(entry);
__ delayed()->add(L1_scratch, wordSize, L1_scratch); // first real entry (undo prepush)
// 2. move expression stack
......@@ -1651,7 +1650,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ set((int)BytecodeInterpreter::got_monitors, L1_scratch);
VALIDATE_STATE(G3_scratch, 5);
__ ba(false, call_interpreter);
__ ba(call_interpreter);
__ delayed()->st(L1_scratch, STATE(_msg));
// uncommon trap needs to jump to here to enter the interpreter (re-execute current bytecode)
......@@ -1659,7 +1658,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
// QQQ what message do we send
__ ba(false, call_interpreter);
__ ba(call_interpreter);
__ delayed()->ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame
//=============================================================================
......@@ -1675,7 +1674,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
// ready to resume the interpreter
__ set((int)BytecodeInterpreter::deopt_resume, L1_scratch);
__ ba(false, call_interpreter);
__ ba(call_interpreter);
__ delayed()->st(L1_scratch, STATE(_msg));
// Current frame has caught an exception we need to dispatch to the
......@@ -1763,7 +1762,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
// L1_scratch points to top of stack (prepushed)
__ ba(false, resume_interpreter);
__ ba(resume_interpreter);
__ delayed()->mov(L1_scratch, O1);
// An exception is being caught on return to a vanilla interpreter frame.
......@@ -1773,7 +1772,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ ld_ptr(STATE(_frame_bottom), SP); // restore to full stack frame
__ ld_ptr(STATE(_stack_base), O1); // empty java expression stack
__ ba(false, resume_interpreter);
__ ba(resume_interpreter);
__ delayed()->sub(O1, wordSize, O1); // account for prepush
// Return from interpreted method we return result appropriate to the caller (i.e. "recursive"
......@@ -1852,7 +1851,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ set((int)BytecodeInterpreter::method_resume, L1_scratch);
__ st(L1_scratch, STATE(_msg));
__ ba(false, call_interpreter_2);
__ ba(call_interpreter_2);
__ delayed()->st_ptr(O1, STATE(_stack));
......@@ -1867,8 +1866,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ cmp(Gtmp1, O7); // returning to interpreter?
__ brx(Assembler::equal, true, Assembler::pt, re_dispatch); // yep
__ delayed()->nop();
__ ba(false, re_dispatch);
__ delayed()->mov(G0, prevState); // initial entry
__ ba(re_dispatch);
__ delayed()->mov(G0, prevState); // initial entry
}
......@@ -2031,8 +2030,8 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ brx(Assembler::zero, false, Assembler::pt, unwind_and_forward);
__ delayed()->nop();
__ ld_ptr(STATE(_locals), O1); // get result of popping callee's args
__ ba(false, unwind_recursive_activation);
__ ld_ptr(STATE(_locals), O1); // get result of popping callee's args
__ ba(unwind_recursive_activation);
__ delayed()->nop();
interpreter_frame_manager = entry_point;
......
......@@ -236,17 +236,13 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register scratch_reg)
Label L;
Register thr_state = G3_scratch;
ld_ptr(G2_thread, JavaThread::jvmti_thread_state_offset(), thr_state);
tst(thr_state);
br(zero, false, pt, L); // if (thread->jvmti_thread_state() == NULL) exit;
delayed()->nop();
br_null_short(thr_state, pt, L); // if (thread->jvmti_thread_state() == NULL) exit;
// Initiate earlyret handling only if it is not already being processed.
// If the flag has the earlyret_processing bit set, it means that this code
// is called *during* earlyret handling - we don't want to reenter.
ld(thr_state, JvmtiThreadState::earlyret_state_offset(), G4_scratch);
cmp(G4_scratch, JvmtiThreadState::earlyret_pending);
br(Assembler::notEqual, false, pt, L);
delayed()->nop();
cmp_and_br_short(G4_scratch, JvmtiThreadState::earlyret_pending, Assembler::notEqual, pt, L);
// Call Interpreter::remove_activation_early_entry() to get the address of the
// same-named entrypoint in the generated interpreter code
......@@ -566,9 +562,7 @@ void InterpreterMacroAssembler::verify_sp(Register Rsp, Register Rtemp) {
#ifdef _LP64
sub(Rtemp, STACK_BIAS, Rtemp); // Bias Rtemp before cmp to FP
#endif
cmp(Rtemp, FP);
brx(Assembler::greaterUnsigned, false, Assembler::pn, Bad);
delayed()->nop();
cmp_and_brx_short(Rtemp, FP, Assembler::greaterUnsigned, Assembler::pn, Bad);
// Saved SP must not be ridiculously below current SP.
size_t maxstack = MAX2(JavaThread::stack_size_at_create(), (size_t) 4*K*K);
......@@ -577,12 +571,9 @@ void InterpreterMacroAssembler::verify_sp(Register Rsp, Register Rtemp) {
#ifdef _LP64
add(Rtemp, STACK_BIAS, Rtemp); // Unbias Rtemp before cmp to Rsp
#endif
cmp(Rsp, Rtemp);
brx(Assembler::lessUnsigned, false, Assembler::pn, Bad);
delayed()->nop();
cmp_and_brx_short(Rsp, Rtemp, Assembler::lessUnsigned, Assembler::pn, Bad);
br(Assembler::always, false, Assembler::pn, OK);
delayed()->nop();
ba_short(OK);
bind(Bad);
stop("on return to interpreted call, restored SP is corrupted");
......@@ -630,8 +621,7 @@ void InterpreterMacroAssembler::call_from_interpreter(Register target, Register
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
ld(interp_only, scratch);
tst(scratch);
br(Assembler::notZero, true, Assembler::pn, skip_compiled_code);
cmp_zero_and_br(Assembler::notZero, scratch, skip_compiled_code, true, Assembler::pn);
delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target);
bind(skip_compiled_code);
}
......@@ -641,8 +631,7 @@ void InterpreterMacroAssembler::call_from_interpreter(Register target, Register
#ifdef ASSERT
{
Label ok;
br_notnull(target, false, Assembler::pt, ok);
delayed()->nop();
br_notnull_short(target, Assembler::pt, ok);
stop("null entry point");
bind(ok);
}
......@@ -982,8 +971,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
// Don't unlock anything if the _do_not_unlock_if_synchronized flag
// is set.
tstbool(G1_scratch);
br(Assembler::notZero, false, pn, no_unlock);
cmp_zero_and_br(Assembler::notZero, G1_scratch, no_unlock);
delayed()->nop();
// BasicObjectLock will be first in list, since this is a synchronized method. However, need
......@@ -997,8 +985,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
add( top_most_monitor(), O1 );
ld_ptr(O1, BasicObjectLock::obj_offset_in_bytes(), G3_scratch);
br_notnull(G3_scratch, false, pt, unlock);
delayed()->nop();
br_notnull_short(G3_scratch, pt, unlock);
if (throw_monitor_exception) {
// Entry already unlocked need to throw an exception
......@@ -1011,8 +998,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
if (install_monitor_exception) {
MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
}
ba(false, unlocked);
delayed()->nop();
ba_short(unlocked);
}
bind(unlock);
......@@ -1037,15 +1023,13 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
add(top_most_monitor(), Rmptr, delta);
{ Label L;
// ensure that Rmptr starts out above (or at) Rlimit
cmp(Rmptr, Rlimit);
brx(Assembler::greaterEqualUnsigned, false, pn, L);
delayed()->nop();
cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L);
stop("monitor stack has negative size");
bind(L);
}
#endif
bind(restart);
ba(false, entry);
ba(entry);
delayed()->
add(top_most_monitor(), Rmptr, delta); // points to current entry, starting with bottom-most entry
......@@ -1061,8 +1045,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
if (install_monitor_exception) {
MacroAssembler::call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
}
ba(false, restart);
delayed()->nop();
ba_short(restart);
}
bind(loop);
......@@ -1073,9 +1056,7 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
#ifdef ASSERT
{ Label L;
// ensure that Rmptr has not somehow stepped below Rlimit
cmp(Rmptr, Rlimit);
brx(Assembler::greaterEqualUnsigned, false, pn, L);
delayed()->nop();
cmp_and_brx_short(Rmptr, Rlimit, Assembler::greaterEqualUnsigned, pn, L);
stop("ran off the end of the monitor stack");
bind(L);
}
......@@ -1196,9 +1177,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg, Register Object)
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
// if the compare and exchange succeeded we are done (we saw an unlocked object)
cmp(mark_reg, temp_reg);
brx(Assembler::equal, true, Assembler::pt, done);
delayed()->nop();
cmp_and_brx_short(mark_reg, temp_reg, Assembler::equal, Assembler::pt, done);
// We did not see an unlocked object so try the fast recursive case
......@@ -1324,13 +1303,7 @@ void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
void InterpreterMacroAssembler::test_method_data_pointer(Label& zero_continue) {
assert(ProfileInterpreter, "must be profiling interpreter");
#ifdef _LP64
bpr(Assembler::rc_z, false, Assembler::pn, ImethodDataPtr, zero_continue);
#else
tst(ImethodDataPtr);
br(Assembler::zero, false, Assembler::pn, zero_continue);
#endif
delayed()->nop();
br_null_short(ImethodDataPtr, Assembler::pn, zero_continue);
}
void InterpreterMacroAssembler::verify_method_data_pointer() {
......@@ -1376,31 +1349,18 @@ void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocat
Label done;
// if no method data exists, and the counter is high enough, make one
#ifdef _LP64
bpr(Assembler::rc_nz, false, Assembler::pn, ImethodDataPtr, done);
#else
tst(ImethodDataPtr);
br(Assembler::notZero, false, Assembler::pn, done);
#endif
br_notnull_short(ImethodDataPtr, Assembler::pn, done);
// Test to see if we should create a method data oop
AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit);
#ifdef _LP64
delayed()->nop();
sethi(profile_limit, Rtmp);
#else
delayed()->sethi(profile_limit, Rtmp);
#endif
ld(Rtmp, profile_limit.low10(), Rtmp);
cmp(invocation_count, Rtmp);
br(Assembler::lessUnsigned, false, Assembler::pn, profile_continue);
delayed()->nop();
cmp_and_br_short(invocation_count, Rtmp, Assembler::lessUnsigned, Assembler::pn, profile_continue);
// Build it now.
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
set_method_data_pointer_for_bcp();
ba(false, profile_continue);
delayed()->nop();
ba_short(profile_continue);
bind(done);
}
......@@ -1632,13 +1592,10 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
Label skip_receiver_profile;
if (receiver_can_be_null) {
Label not_null;
tst(receiver);
brx(Assembler::notZero, false, Assembler::pt, not_null);
delayed()->nop();
br_notnull_short(receiver, Assembler::pt, not_null);
// We are making a call. Increment the count for null receiver.
increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
ba(false, skip_receiver_profile);
delayed()->nop();
ba_short(skip_receiver_profile);
bind(not_null);
}
......@@ -1682,8 +1639,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
// The receiver is receiver[n]. Increment count[n].
int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
increment_mdp_data_at(count_offset, scratch);
ba(false, done);
delayed()->nop();
ba_short(done);
bind(next_test);
if (test_for_null_also) {
......@@ -1697,8 +1653,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
// Receiver did not match any saved receiver and there is no empty row for it.
// Increment total counter to indicate polymorphic case.
increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
ba(false, done);
delayed()->nop();
ba_short(done);
bind(found_null);
} else {
brx(Assembler::notZero, false, Assembler::pt, done);
......@@ -1729,8 +1684,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper(
mov(DataLayout::counter_increment, scratch);
set_mdp_data_at(count_offset, scratch);
if (start_row > 0) {
ba(false, done);
delayed()->nop();
ba_short(done);
}
}
......@@ -1772,8 +1726,7 @@ void InterpreterMacroAssembler::profile_ret(TosState state,
// The method data pointer needs to be updated to reflect the new target.
update_mdp_by_offset(in_bytes(RetData::bci_displacement_offset(row)), scratch);
ba(false, profile_continue);
delayed()->nop();
ba_short(profile_continue);
bind(next_test);
}
......@@ -1922,8 +1875,8 @@ void InterpreterMacroAssembler::add_monitor_to_stack( bool stack_is_empty,
// untested("monitor stack expansion");
compute_stack_base(Rtemp);
ba( false, start_copying );
delayed()->cmp( Rtemp, Rlimit); // done? duplicated below
ba(start_copying);
delayed()->cmp(Rtemp, Rlimit); // done? duplicated below
// note: must copy from low memory upwards
// On entry to loop,
......@@ -2010,9 +1963,7 @@ void InterpreterMacroAssembler::check_for_regarea_stomp(Register Rindex, int off
// untested("reg area corruption");
add(Rindex, offset, Rscratch);
add(Rlimit, 64 + STACK_BIAS, Rscratch1);
cmp(Rscratch, Rscratch1);
brx(Assembler::greaterEqualUnsigned, false, pn, L);
delayed()->nop();
cmp_and_brx_short(Rscratch, Rscratch1, Assembler::greaterEqualUnsigned, pn, L);
stop("regsave area is being clobbered");
bind(L);
}
......@@ -2174,9 +2125,7 @@ void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_c
AddressLiteral limit(&InvocationCounter::InterpreterBackwardBranchLimit);
load_contents(limit, Rtmp);
cmp(backedge_count, Rtmp);
br(Assembler::lessUnsigned, false, Assembler::pt, did_not_overflow);
delayed()->nop();
cmp_and_br_short(backedge_count, Rtmp, Assembler::lessUnsigned, Assembler::pt, did_not_overflow);
// When ProfileInterpreter is on, the backedge_count comes from the
// methodDataOop, which value does not get reset on the call to
......@@ -2196,15 +2145,11 @@ void InterpreterMacroAssembler::test_backedge_count_for_osr( Register backedge_c
// Was an OSR adapter generated?
// O0 = osr nmethod
tst(O0);
brx(Assembler::zero, false, Assembler::pn, overflow_with_error);
delayed()->nop();
br_null_short(O0, Assembler::pn, overflow_with_error);
// Has the nmethod been invalidated already?
ld(O0, nmethod::entry_bci_offset(), O2);
cmp(O2, InvalidOSREntryBci);
br(Assembler::equal, false, Assembler::pn, overflow_with_error);
delayed()->nop();
cmp_and_br_short(O2, InvalidOSREntryBci, Assembler::equal, Assembler::pn, overflow_with_error);
// migrate the interpreter frame off of the stack
......@@ -2270,8 +2215,7 @@ void InterpreterMacroAssembler::verify_oop_or_return_address(Register reg, Regis
mov(reg, Rtmp);
const int log2_bytecode_size_limit = 16;
srl(Rtmp, log2_bytecode_size_limit, Rtmp);
br_notnull( Rtmp, false, pt, test );
delayed()->nop();
br_notnull_short( Rtmp, pt, test );
// %%% should use call_VM_leaf here?
save_frame_and_mov(0, Lmethod, O0, reg, O1);
......@@ -2320,9 +2264,7 @@ void InterpreterMacroAssembler::notify_method_entry() {
Register temp_reg = O5;
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
ld(interp_only, temp_reg);
tst(temp_reg);
br(zero, false, pt, L);
delayed()->nop();
cmp_and_br_short(temp_reg, 0, equal, pt, L);
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry));
bind(L);
}
......@@ -2372,9 +2314,7 @@ void InterpreterMacroAssembler::notify_method_exit(bool is_native_method,
Register temp_reg = O5;
const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
ld(interp_only, temp_reg);
tst(temp_reg);
br(zero, false, pt, L);
delayed()->nop();
cmp_and_br_short(temp_reg, 0, equal, pt, L);
// Note: frame::interpreter_frame_result has a dependency on how the
// method result is saved across the call to post_method_exit. For
......
......@@ -191,22 +191,19 @@ address AbstractInterpreterGenerator::generate_slow_signature_handler() {
// Optimization, see if there are any more args and get out prior to checking
// all 16 float registers. My guess is that this is rare.
// If is_register is false, then we are done the first six integer args.
__ tst(G4_scratch);
__ brx(Assembler::zero, false, Assembler::pt, done);
__ delayed()->nop();
__ br_null_short(G4_scratch, Assembler::pt, done);
}
__ ba(false, NextArg);
__ ba(NextArg);
__ delayed()->srl( G4_scratch, 2, G4_scratch );
__ bind(LoadFloatArg);
__ ldf( FloatRegisterImpl::S, a, ldarg.as_float_register(), 4);
__ ba(false, NextArg);
__ ba(NextArg);
__ delayed()->srl( G4_scratch, 2, G4_scratch );
__ bind(LoadDoubleArg);
__ ldf( FloatRegisterImpl::D, a, ldarg.as_double_register() );
__ ba(false, NextArg);
__ ba(NextArg);
__ delayed()->srl( G4_scratch, 2, G4_scratch );
__ bind(NextArg);
......@@ -234,8 +231,7 @@ void InterpreterGenerator::generate_counter_overflow(Label& Lcontinue) {
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), O2, O2, true);
// returns verified_entry_point or NULL
// we ignore it in any case
__ ba(false, Lcontinue);
__ delayed()->nop();
__ ba_short(Lcontinue);
}
......
......@@ -287,9 +287,7 @@ void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
BLOCK_COMMENT("verify_clean {");
// Magic numbers must check out:
__ set((int32_t) MAGIC_NUMBER_1, O7_temp);
__ cmp(O7_temp, L0_magic_number_1);
__ br(Assembler::equal, false, Assembler::pt, L_ok_1);
__ delayed()->nop();
__ cmp_and_br_short(O7_temp, L0_magic_number_1, Assembler::equal, Assembler::pt, L_ok_1);
__ stop("damaged ricochet frame: MAGIC_NUMBER_1 not found");
__ BIND(L_ok_1);
......@@ -301,9 +299,7 @@ void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
#else
Register FP_temp = FP;
#endif
__ cmp(L4_saved_args_base, FP_temp);
__ br(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_ok_2);
__ delayed()->nop();
__ cmp_and_brx_short(L4_saved_args_base, FP_temp, Assembler::greaterEqualUnsigned, Assembler::pt, L_ok_2);
__ stop("damaged ricochet frame: L4 < FP");
__ BIND(L_ok_2);
......@@ -316,15 +312,11 @@ void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
__ BIND(L_ok_3);
extract_conversion_dest_type(_masm, L5_conversion, O7_temp);
__ cmp(O7_temp, T_VOID);
__ br(Assembler::equal, false, Assembler::pt, L_ok_4);
__ delayed()->nop();
__ cmp_and_br_short(O7_temp, T_VOID, Assembler::equal, Assembler::pt, L_ok_4);
extract_conversion_vminfo(_masm, L5_conversion, O5_temp);
__ ld_ptr(L4_saved_args_base, __ argument_offset(O5_temp, O5_temp), O7_temp);
assert(__ is_simm13(RETURN_VALUE_PLACEHOLDER), "must be simm13");
__ cmp(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER);
__ brx(Assembler::equal, false, Assembler::pt, L_ok_4);
__ delayed()->nop();
__ cmp_and_brx_short(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER, Assembler::equal, Assembler::pt, L_ok_4);
__ stop("damaged ricochet frame: RETURN_VALUE_PLACEHOLDER not found");
__ BIND(L_ok_4);
BLOCK_COMMENT("} verify_clean");
......@@ -363,9 +355,7 @@ void MethodHandles::load_stack_move(MacroAssembler* _masm,
if (VerifyMethodHandles) {
Label L_ok, L_bad;
int32_t stack_move_limit = 0x0800; // extra-large
__ cmp(stack_move_reg, stack_move_limit);
__ br(Assembler::greaterEqual, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ cmp_and_br_short(stack_move_reg, stack_move_limit, Assembler::greaterEqual, Assembler::pn, L_bad);
__ cmp(stack_move_reg, -stack_move_limit);
__ br(Assembler::greater, false, Assembler::pt, L_ok);
__ delayed()->nop();
......@@ -401,13 +391,9 @@ void MethodHandles::verify_argslot(MacroAssembler* _masm, Register argslot_reg,
// Verify that argslot lies within (Gargs, FP].
Label L_ok, L_bad;
BLOCK_COMMENT("verify_argslot {");
__ cmp_and_brx_short(Gargs, argslot_reg, Assembler::greaterUnsigned, Assembler::pn, L_bad);
__ add(FP, STACK_BIAS, temp_reg); // STACK_BIAS is zero on !_LP64
__ cmp(argslot_reg, temp_reg);
__ brx(Assembler::greaterUnsigned, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ cmp(Gargs, argslot_reg);
__ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(argslot_reg, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop(error_message);
__ BIND(L_ok);
......@@ -434,14 +420,10 @@ void MethodHandles::verify_argslots(MacroAssembler* _masm,
}
__ add(arg_slot_base_reg, __ argument_offset(arg_slots, temp_reg), temp_reg);
__ add(FP, STACK_BIAS, temp2_reg); // STACK_BIAS is zero on !_LP64
__ cmp(temp_reg, temp2_reg);
__ brx(Assembler::greaterUnsigned, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::greaterUnsigned, Assembler::pn, L_bad);
// Gargs points to the first word so adjust by BytesPerWord
__ add(arg_slot_base_reg, BytesPerWord, temp_reg);
__ cmp(Gargs, temp_reg);
__ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(Gargs, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop(error_message);
__ BIND(L_ok);
......@@ -502,21 +484,16 @@ void MethodHandles::verify_klass(MacroAssembler* _masm,
Label L_ok, L_bad;
BLOCK_COMMENT("verify_klass {");
__ verify_oop(obj_reg);
__ br_null(obj_reg, false, Assembler::pn, L_bad);
__ delayed()->nop();
__ br_null_short(obj_reg, Assembler::pn, L_bad);
__ load_klass(obj_reg, temp_reg);
__ set(ExternalAddress(klass_addr), temp2_reg);
__ ld_ptr(Address(temp2_reg, 0), temp2_reg);
__ cmp(temp_reg, temp2_reg);
__ brx(Assembler::equal, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok);
intptr_t super_check_offset = klass->super_check_offset();
__ ld_ptr(Address(temp_reg, super_check_offset), temp_reg);
__ set(ExternalAddress(klass_addr), temp2_reg);
__ ld_ptr(Address(temp2_reg, 0), temp2_reg);
__ cmp(temp_reg, temp2_reg);
__ brx(Assembler::equal, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop(error_message);
__ BIND(L_ok);
......@@ -671,9 +648,7 @@ static RegisterOrConstant adjust_SP_and_Gargs_down_by_slots(MacroAssembler* _mas
#ifdef ASSERT
{
Label L_ok;
__ cmp(arg_slots.as_register(), 0);
__ br(Assembler::greaterEqual, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_br_short(arg_slots.as_register(), 0, Assembler::greaterEqual, Assembler::pt, L_ok);
__ stop("negative arg_slots");
__ bind(L_ok);
}
......@@ -748,9 +723,7 @@ void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
__ ld_ptr( Address(temp_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(temp_reg, offset) );
__ add(temp_reg, wordSize, temp_reg);
__ cmp(temp_reg, argslot_reg);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(temp_reg, argslot_reg, Assembler::lessUnsigned, Assembler::pt, loop);
}
// Now move the argslot down, to point to the opened-up space.
......@@ -797,9 +770,7 @@ void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
__ ld_ptr( Address(temp_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(temp_reg, offset) );
__ sub(temp_reg, wordSize, temp_reg);
__ cmp(temp_reg, Gargs);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(temp_reg, Gargs, Assembler::greaterEqualUnsigned, Assembler::pt, L_loop);
}
// And adjust the argslot address to point at the deletion point.
......@@ -848,8 +819,7 @@ void MethodHandles::push_arg_slots(MacroAssembler* _masm,
__ delayed()->nop();
__ ld_ptr( Address(argslot_reg, 0), temp_reg);
__ st_ptr(temp_reg, Address(Gargs, 0));
__ ba(false, L_break);
__ delayed()->nop(); // FILLME
__ ba_short(L_break);
__ BIND(L_plural);
// Loop for 2 or more:
......@@ -863,9 +833,7 @@ void MethodHandles::push_arg_slots(MacroAssembler* _masm,
__ sub(Gargs, wordSize, Gargs );
__ ld_ptr( Address(top_reg, 0), temp2_reg);
__ st_ptr(temp2_reg, Address(Gargs, 0));
__ cmp(top_reg, argslot_reg);
__ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(top_reg, argslot_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop);
__ BIND(L_break);
}
BLOCK_COMMENT("} push_arg_slots");
......@@ -897,17 +865,13 @@ void MethodHandles::move_arg_slots_up(MacroAssembler* _masm,
__ br(Assembler::lessEqual, false, Assembler::pn, L_bad);
__ delayed()->nop();
}
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop("valid bounds (copy up)");
__ BIND(L_ok);
}
#endif
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pn, L_break);
__ delayed()->nop();
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break);
// work top down to bottom, copying contiguous data upwards
// In pseudo-code:
// while (--top >= bottom) *(top + distance) = *(top + 0);
......@@ -916,9 +880,7 @@ void MethodHandles::move_arg_slots_up(MacroAssembler* _masm,
__ sub(top_reg, wordSize, top_reg);
__ ld_ptr( Address(top_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(top_reg, offset) );
__ cmp(top_reg, bottom_reg);
__ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(top_reg, bottom_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop);
assert(Interpreter::stackElementSize == wordSize, "else change loop");
__ BIND(L_break);
BLOCK_COMMENT("} move_arg_slots_up");
......@@ -951,17 +913,13 @@ void MethodHandles::move_arg_slots_down(MacroAssembler* _masm,
__ br(Assembler::greaterEqual, false, Assembler::pn, L_bad);
__ delayed()->nop();
}
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
__ BIND(L_bad);
__ stop("valid bounds (copy down)");
__ BIND(L_ok);
}
#endif
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pn, L_break);
__ delayed()->nop();
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break);
// work bottom up to top, copying contiguous data downwards
// In pseudo-code:
// while (bottom < top) *(bottom - distance) = *(bottom + 0), bottom++;
......@@ -970,9 +928,7 @@ void MethodHandles::move_arg_slots_down(MacroAssembler* _masm,
__ ld_ptr( Address(bottom_reg, 0 ), temp2_reg);
__ st_ptr(temp2_reg, Address(bottom_reg, offset) );
__ add(bottom_reg, wordSize, bottom_reg);
__ cmp(bottom_reg, top_reg);
__ brx(Assembler::lessUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_loop);
assert(Interpreter::stackElementSize == wordSize, "else change loop");
__ BIND(L_break);
BLOCK_COMMENT("} move_arg_slots_down");
......@@ -1329,9 +1285,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
Label L_done;
__ ld_ptr(vmarg, O2_scratch);
__ tst(O2_scratch);
__ brx(Assembler::zero, false, Assembler::pn, L_done); // No cast if null.
__ delayed()->nop();
__ br_null_short(O2_scratch, Assembler::pn, L_done); // No cast if null.
__ load_klass(O2_scratch, O2_scratch);
// Live at this point:
......@@ -1436,8 +1390,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
// this path is taken for int->byte, int->short
__ sra(O1_scratch, G5_vminfo, O1_scratch);
__ ba(false, done);
__ delayed()->nop();
__ ba_short(done);
__ bind(zero_extend);
// this is taken for int->char
......@@ -1860,9 +1813,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
BLOCK_COMMENT("verify collect_count_constant {");
__ load_method_handle_vmslots(O3_scratch, G3_method_handle, O2_scratch);
Label L_count_ok;
__ cmp(O3_scratch, collect_count_constant);
__ br(Assembler::equal, false, Assembler::pt, L_count_ok);
__ delayed()->nop();
__ cmp_and_br_short(O3_scratch, collect_count_constant, Assembler::equal, Assembler::pt, L_count_ok);
__ stop("bad vminfo in AMH.conv");
__ BIND(L_count_ok);
BLOCK_COMMENT("} verify collect_count_constant");
......@@ -1909,9 +1860,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
BLOCK_COMMENT("verify dest_slot_constant {");
extract_conversion_vminfo(_masm, RicochetFrame::L5_conversion, O3_scratch);
Label L_vminfo_ok;
__ cmp(O3_scratch, dest_slot_constant);
__ br(Assembler::equal, false, Assembler::pt, L_vminfo_ok);
__ delayed()->nop();
__ cmp_and_br_short(O3_scratch, dest_slot_constant, Assembler::equal, Assembler::pt, L_vminfo_ok);
__ stop("bad vminfo in AMH.conv");
__ BIND(L_vminfo_ok);
BLOCK_COMMENT("} verify dest_slot_constant");
......@@ -1951,14 +1900,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
// If there are variable parameters, use dynamic checks to skip around the whole mess.
Label L_done;
if (keep3_count.is_register()) {
__ tst(keep3_count.as_register());
__ br(Assembler::zero, false, Assembler::pn, L_done);
__ delayed()->nop();
__ cmp_and_br_short(keep3_count.as_register(), 0, Assembler::equal, Assembler::pn, L_done);
}
if (close_count.is_register()) {
__ cmp(close_count.as_register(), open_count);
__ br(Assembler::equal, false, Assembler::pn, L_done);
__ delayed()->nop();
__ cmp_and_br_short(close_count.as_register(), open_count, Assembler::equal, Assembler::pn, L_done);
}
if (move_keep3 && fix_arg_base) {
......@@ -1999,8 +1944,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
}
if (emit_guard) {
__ ba(false, L_done); // assumes emit_move_up is true also
__ delayed()->nop();
__ ba_short(L_done); // assumes emit_move_up is true also
__ BIND(L_move_up);
}
......@@ -2133,8 +2077,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
#ifdef ASSERT
{ Label L_ok;
__ br_notnull(O7_temp, false, Assembler::pt, L_ok);
__ delayed()->nop();
__ br_notnull_short(O7_temp, Assembler::pt, L_ok);
__ stop("bad method handle return");
__ BIND(L_ok);
}
......@@ -2192,11 +2135,10 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
Label L_skip;
if (length_constant < 0) {
load_conversion_vminfo(_masm, G3_amh_conversion, O3_scratch);
__ br_zero(Assembler::notZero, false, Assembler::pn, O3_scratch, L_skip);
__ delayed()->nop();
__ cmp_zero_and_br(Assembler::notZero, O3_scratch, L_skip);
__ delayed()->nop(); // to avoid back-to-back cbcond instructions
}
__ br_null(O1_array, false, Assembler::pn, L_array_is_empty);
__ delayed()->nop();
__ br_null_short(O1_array, Assembler::pn, L_array_is_empty);
__ BIND(L_skip);
}
__ null_check(O1_array, oopDesc::klass_offset_in_bytes());
......@@ -2210,8 +2152,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
Label L_ok_array_klass, L_bad_array_klass, L_bad_array_length;
__ check_klass_subtype(O2_array_klass, O3_klass, O4_scratch, G5_scratch, L_ok_array_klass);
// If we get here, the type check failed!
__ ba(false, L_bad_array_klass);
__ delayed()->nop();
__ ba_short(L_bad_array_klass);
__ BIND(L_ok_array_klass);
// Check length.
......@@ -2247,8 +2188,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
__ BIND(L_array_is_empty);
remove_arg_slots(_masm, -stack_move_unit() * array_slots,
O0_argslot, O1_scratch, O2_scratch, O3_scratch);
__ ba(false, L_args_done); // no spreading to do
__ delayed()->nop();
__ ba_short(L_args_done); // no spreading to do
__ BIND(L_insert_arg_space);
// come here in the usual case, stack_move < 0 (2 or more spread arguments)
// Live: O1_array, O2_argslot_limit, O3_stack_move
......@@ -2289,9 +2229,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan
Address(O1_source, 0), Address(O4_fill_ptr, 0),
O2_scratch); // must be an even register for !_LP64 long moves (uses O2/O3)
__ add(O1_source, type2aelembytes(elem_type), O1_source);
__ cmp(O4_fill_ptr, O0_argslot);
__ brx(Assembler::greaterUnsigned, false, Assembler::pt, L_loop);
__ delayed()->nop(); // FILLME
__ cmp_and_brx_short(O4_fill_ptr, O0_argslot, Assembler::greaterUnsigned, Assembler::pt, L_loop);
} else if (length_constant == 0) {
// nothing to copy
} else {
......
......@@ -600,7 +600,7 @@ class AdapterGenerator {
void AdapterGenerator::patch_callers_callsite() {
Label L;
__ ld_ptr(G5_method, in_bytes(methodOopDesc::code_offset()), G3_scratch);
__ br_null(G3_scratch, false, __ pt, L);
__ br_null(G3_scratch, false, Assembler::pt, L);
// Schedule the branch target address early.
__ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch);
// Call into the VM to patch the caller, then jump to compiled callee
......@@ -1127,8 +1127,7 @@ void AdapterGenerator::gen_i2c_adapter(
Label loop;
__ bind(loop);
__ sub(L0, 1, L0);
__ br_null(L0, false, Assembler::pt, loop);
__ delayed()->nop();
__ br_null_short(L0, Assembler::pt, loop);
__ restore();
}
......@@ -1202,7 +1201,7 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
// the call site corrected.
__ ld_ptr(G5_method, in_bytes(methodOopDesc::code_offset()), G3_scratch);
__ bind(ok2);
__ br_null(G3_scratch, false, __ pt, skip_fixup);
__ br_null(G3_scratch, false, Assembler::pt, skip_fixup);
__ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch);
__ jump_to(ic_miss, G3_scratch);
__ delayed()->nop();
......@@ -1779,9 +1778,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
__ verify_oop(O0);
__ load_klass(O0, temp_reg);
__ cmp(temp_reg, G5_inline_cache_reg);
__ brx(Assembler::equal, true, Assembler::pt, L);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, G5_inline_cache_reg, Assembler::equal, Assembler::pt, L);
__ jump_to(ic_miss, temp_reg);
__ delayed()->nop();
......@@ -2182,8 +2179,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
#ifdef ASSERT
{ Label L;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0);
__ br_null(O0, false, Assembler::pt, L);
__ delayed()->nop();
__ br_null_short(O0, Assembler::pt, L);
__ stop("no pending exception allowed on exit from IR::monitorenter");
__ bind(L);
}
......@@ -2298,9 +2294,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
Address suspend_state(G2_thread, JavaThread::suspend_flags_offset());
__ br(Assembler::notEqual, false, Assembler::pn, L);
__ delayed()->ld(suspend_state, G3_scratch);
__ cmp(G3_scratch, 0);
__ br(Assembler::equal, false, Assembler::pt, no_block);
__ delayed()->nop();
__ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block);
__ bind(L);
// Block. Save any potential method result value before the operation and
......@@ -2328,9 +2322,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
Label no_reguard;
__ ld(G2_thread, JavaThread::stack_guard_state_offset(), G3_scratch);
__ cmp(G3_scratch, JavaThread::stack_guard_yellow_disabled);
__ br(Assembler::notEqual, false, Assembler::pt, no_reguard);
__ delayed()->nop();
__ cmp_and_br_short(G3_scratch, JavaThread::stack_guard_yellow_disabled, Assembler::notEqual, Assembler::pt, no_reguard);
save_native_result(masm, ret_type, stack_slots);
__ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages));
......@@ -2382,8 +2374,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
#ifdef ASSERT
{ Label L;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0);
__ br_null(O0, false, Assembler::pt, L);
__ delayed()->nop();
__ br_null_short(O0, Assembler::pt, L);
__ stop("no pending exception allowed on exit from IR::monitorexit");
__ bind(L);
}
......@@ -2639,9 +2630,7 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
__ verify_oop(O0);
__ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
__ cmp(temp_reg, G5_inline_cache_reg);
__ brx(Assembler::equal, true, Assembler::pt, L);
__ delayed()->nop();
__ cmp_and_brx_short(temp_reg, G5_inline_cache_reg, Assembler::equal, Assembler::pt, L);
__ jump_to(ic_miss, temp_reg);
__ delayed()->nop();
......@@ -3143,8 +3132,7 @@ static void make_new_frames(MacroAssembler* masm, bool deopt) {
gen_new_frame(masm, deopt); // allocate an interpreter frame
__ tst(O4array_size);
__ br(Assembler::notZero, false, Assembler::pn, loop);
__ cmp_zero_and_br(Assembler::notZero, O4array_size, loop);
__ delayed()->add(O3array, wordSize, O3array);
__ ld_ptr(G3pcs, 0, O7); // load final frame new pc
......@@ -3221,7 +3209,7 @@ void SharedRuntime::generate_deopt_blob() {
// pc is now in O7. Return values are still in the expected places
map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
__ ba(false, cont);
__ ba(cont);
__ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode);
int exception_offset = __ offset() - start;
......@@ -3256,8 +3244,7 @@ void SharedRuntime::generate_deopt_blob() {
// verify that there is really an exception oop in exception_oop
Label has_exception;
__ ld_ptr(G2_thread, JavaThread::exception_oop_offset(), Oexception);
__ br_notnull(Oexception, false, Assembler::pt, has_exception);
__ delayed()-> nop();
__ br_notnull_short(Oexception, Assembler::pt, has_exception);
__ stop("no exception in thread");
__ bind(has_exception);
......@@ -3265,14 +3252,13 @@ void SharedRuntime::generate_deopt_blob() {
Label no_pending_exception;
Address exception_addr(G2_thread, Thread::pending_exception_offset());
__ ld_ptr(exception_addr, Oexception);
__ br_null(Oexception, false, Assembler::pt, no_pending_exception);
__ delayed()->nop();
__ br_null_short(Oexception, Assembler::pt, no_pending_exception);
__ stop("must not have pending exception here");
__ bind(no_pending_exception);
}
#endif
__ ba(false, cont);
__ ba(cont);
__ delayed()->mov(Deoptimization::Unpack_exception, L0deopt_mode);;
//
......@@ -3313,9 +3299,7 @@ void SharedRuntime::generate_deopt_blob() {
RegisterSaver::restore_result_registers(masm);
Label noException;
__ cmp(G4deopt_mode, Deoptimization::Unpack_exception); // Was exception pending?
__ br(Assembler::notEqual, false, Assembler::pt, noException);
__ delayed()->nop();
__ cmp_and_br_short(G4deopt_mode, Deoptimization::Unpack_exception, Assembler::notEqual, Assembler::pt, noException);
// Move the pending exception from exception_oop to Oexception so
// the pending exception will be picked up the interpreter.
......@@ -3359,9 +3343,7 @@ void SharedRuntime::generate_deopt_blob() {
// In 32 bit, C2 returns longs in G1 so restore the saved G1 into
// I0/I1 if the return value is long.
Label not_long;
__ cmp(O0,T_LONG);
__ br(Assembler::notEqual, false, Assembler::pt, not_long);
__ delayed()->nop();
__ cmp_and_br_short(O0,T_LONG, Assembler::notEqual, Assembler::pt, not_long);
__ ldd(saved_Greturn1_addr,I0);
__ bind(not_long);
#endif
......@@ -3534,9 +3516,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause
Label pending;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
__ tst(O1);
__ brx(Assembler::notEqual, true, Assembler::pn, pending);
__ delayed()->nop();
__ br_notnull_short(O1, Assembler::pn, pending);
RegisterSaver::restore_live_registers(masm);
......@@ -3623,9 +3603,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha
Label pending;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
__ tst(O1);
__ brx(Assembler::notEqual, true, Assembler::pn, pending);
__ delayed()->nop();
__ br_notnull_short(O1, Assembler::pn, pending);
// get the returned methodOop
......
......@@ -1693,7 +1693,6 @@ void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
MacroAssembler _masm(&cbuf);
Label L;
Register G5_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
Register temp_reg = G3;
assert( G5_ic_reg != temp_reg, "conflicting registers" );
......@@ -2315,60 +2314,23 @@ encode %{
__ delayed()->nop();
%}
enc_class enc_bp( Label labl, cmpOp cmp, flagsReg cc ) %{
enc_class enc_bp( label labl, cmpOp cmp, flagsReg cc ) %{
MacroAssembler _masm(&cbuf);
Label &L = *($labl$$label);
Label* L = $labl$$label;
Assembler::Predict predict_taken =
cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn;
cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
__ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, L);
__ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::icc, predict_taken, *L);
__ delayed()->nop();
%}
enc_class enc_bpl( Label labl, cmpOp cmp, flagsRegL cc ) %{
enc_class enc_bpr( label labl, cmpOp_reg cmp, iRegI op1 ) %{
MacroAssembler _masm(&cbuf);
Label &L = *($labl$$label);
Label* L = $labl$$label;
Assembler::Predict predict_taken =
cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn;
cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
__ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, L);
__ delayed()->nop();
%}
enc_class enc_bpx( Label labl, cmpOp cmp, flagsRegP cc ) %{
MacroAssembler _masm(&cbuf);
Label &L = *($labl$$label);
Assembler::Predict predict_taken =
cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn;
__ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, L);
__ delayed()->nop();
%}
enc_class enc_fbp( Label labl, cmpOpF cmp, flagsRegF cc ) %{
MacroAssembler _masm(&cbuf);
Label &L = *($labl$$label);
Assembler::Predict predict_taken =
cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn;
__ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($cc$$reg), predict_taken, L);
__ delayed()->nop();
%}
enc_class enc_ba( Label labl ) %{
MacroAssembler _masm(&cbuf);
Label &L = *($labl$$label);
__ ba(false, L);
__ delayed()->nop();
%}
enc_class enc_bpr( Label labl, cmpOp_reg cmp, iRegI op1 ) %{
MacroAssembler _masm(&cbuf);
Label &L = *$labl$$label;
Assembler::Predict predict_taken =
cbuf.is_backward_branch(L) ? Assembler::pt : Assembler::pn;
__ bpr( (Assembler::RCondition)($cmp$$cmpcode), false, predict_taken, as_Register($op1$$reg), L);
__ bpr( (Assembler::RCondition)($cmp$$cmpcode), false, predict_taken, as_Register($op1$$reg), *L);
__ delayed()->nop();
%}
......@@ -2986,7 +2948,7 @@ enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI r
__ brx(Assembler::equal, true, Assembler::pn, Ldone);
__ delayed()->add(G0, 1, result_reg);
__ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, cnt_reg, Ldone);
__ cmp_zero_and_br(Assembler::zero, cnt_reg, Ldone, true, Assembler::pn);
__ delayed()->add(G0, 1, result_reg); // count == 0
//rename registers
......@@ -3006,7 +2968,7 @@ enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI r
// Compare char[] arrays aligned to 4 bytes.
__ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
chr1_reg, chr2_reg, Ldone);
__ ba(false,Ldone);
__ ba(Ldone);
__ delayed()->add(G0, 1, result_reg);
// char by char compare
......@@ -3065,7 +3027,7 @@ enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI r
__ br(Assembler::notEqual, true, Assembler::pn, Ldone);
__ delayed()->mov(G0, result_reg); // not equal
__ br_on_reg_cond(Assembler::rc_z, true, Assembler::pn, tmp1_reg, Ldone);
__ cmp_zero_and_br(Assembler::zero, tmp1_reg, Ldone, true, Assembler::pn);
__ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
// load array addresses
......@@ -9232,9 +9194,11 @@ instruct branch(label labl) %{
size(8);
ins_cost(BRANCH_COST);
format %{ "BA $labl" %}
// Prim = bits 24-22, Secnd = bits 31-30, Tert = cond
opcode(Assembler::br_op2, Assembler::branch_op, Assembler::always);
ins_encode( enc_ba( labl ) );
ins_encode %{
Label* L = $labl$$label;
__ ba(*L);
__ delayed()->nop();
%}
ins_pc_relative(1);
ins_pipe(br);
%}
......@@ -9314,8 +9278,14 @@ instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
size(8);
ins_cost(BRANCH_COST);
format %{ "BP$cmp $pcc,$labl" %}
// Prim = bits 24-22, Secnd = bits 31-30
ins_encode( enc_bpx( labl, cmp, pcc ) );
ins_encode %{
Label* L = $labl$$label;
Assembler::Predict predict_taken =
cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
__ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L);
__ delayed()->nop();
%}
ins_pc_relative(1);
ins_pipe(br_cc);
%}
......@@ -9327,8 +9297,14 @@ instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{
size(8);
ins_cost(BRANCH_COST);
format %{ "FBP$cmp $fcc,$labl" %}
// Prim = bits 24-22, Secnd = bits 31-30
ins_encode( enc_fbp( labl, cmp, fcc ) );
ins_encode %{
Label* L = $labl$$label;
Assembler::Predict predict_taken =
cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
__ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L);
__ delayed()->nop();
%}
ins_pc_relative(1);
ins_pipe(br_fcc);
%}
......@@ -9387,8 +9363,14 @@ instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
size(8);
ins_cost(BRANCH_COST);
format %{ "BP$cmp $xcc,$labl" %}
// Prim = bits 24-22, Secnd = bits 31-30
ins_encode( enc_bpl( labl, cmp, xcc ) );
ins_encode %{
Label* L = $labl$$label;
Assembler::Predict predict_taken =
cbuf.is_backward_branch(*L) ? Assembler::pt : Assembler::pn;
__ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
__ delayed()->nop();
%}
ins_pc_relative(1);
ins_pipe(br_cc);
%}
......@@ -9707,7 +9689,6 @@ instruct cmpFastLock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o7R
effect(KILL scratch, TEMP scratch2);
ins_cost(100);
size(4*112); // conservative overestimation ...
format %{ "FASTLOCK $object, $box; KILL $scratch, $scratch2, $box" %}
ins_encode( Fast_Lock(object, box, scratch, scratch2) );
ins_pipe(long_memory_op);
......@@ -9719,7 +9700,6 @@ instruct cmpFastUnlock(flagsRegP pcc, iRegP object, iRegP box, iRegP scratch2, o
effect(KILL scratch, TEMP scratch2);
ins_cost(100);
size(4*120); // conservative overestimation ...
format %{ "FASTUNLOCK $object, $box; KILL $scratch, $scratch2, $box" %}
ins_encode( Fast_Unlock(object, box, scratch, scratch2) );
ins_pipe(long_memory_op);
......
......@@ -150,8 +150,7 @@ class StubGenerator: public StubCodeGenerator {
{ const Register t = G3_scratch;
Label L;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), t);
__ br_null(t, false, Assembler::pt, L);
__ delayed()->nop();
__ br_null_short(t, Assembler::pt, L);
__ stop("StubRoutines::call_stub: entered with pending exception");
__ bind(L);
}
......@@ -207,8 +206,7 @@ class StubGenerator: public StubCodeGenerator {
Label exit;
__ ld_ptr(parameter_size.as_in().as_address(), cnt); // parameter counter
__ add( FP, STACK_BIAS, dst );
__ tst(cnt);
__ br(Assembler::zero, false, Assembler::pn, exit);
__ cmp_zero_and_br(Assembler::zero, cnt, exit);
__ delayed()->sub(dst, BytesPerWord, dst); // setup Lentry_args
// copy parameters if any
......@@ -282,20 +280,20 @@ class StubGenerator: public StubCodeGenerator {
__ delayed()->restore();
__ BIND(is_object);
__ ba(false, exit);
__ ba(exit);
__ delayed()->st_ptr(O0, addr, G0);
__ BIND(is_float);
__ ba(false, exit);
__ ba(exit);
__ delayed()->stf(FloatRegisterImpl::S, F0, addr, G0);
__ BIND(is_double);
__ ba(false, exit);
__ ba(exit);
__ delayed()->stf(FloatRegisterImpl::D, F0, addr, G0);
__ BIND(is_long);
#ifdef _LP64
__ ba(false, exit);
__ ba(exit);
__ delayed()->st_long(O0, addr, G0); // store entire long
#else
#if defined(COMPILER2)
......@@ -307,11 +305,11 @@ class StubGenerator: public StubCodeGenerator {
// do this here. Unfortunately if we did a rethrow we'd see an machepilog node
// first which would move g1 -> O0/O1 and destroy the exception we were throwing.
__ ba(false, exit);
__ ba(exit);
__ delayed()->stx(G1, addr, G0); // store entire long
#else
__ st(O1, addr, BytesPerInt);
__ ba(false, exit);
__ ba(exit);
__ delayed()->st(O0, addr, G0);
#endif /* COMPILER2 */
#endif /* _LP64 */
......@@ -382,8 +380,7 @@ class StubGenerator: public StubCodeGenerator {
// make sure that this code is only executed if there is a pending exception
{ Label L;
__ ld_ptr(exception_addr, Gtemp);
__ br_notnull(Gtemp, false, Assembler::pt, L);
__ delayed()->nop();
__ br_notnull_short(Gtemp, Assembler::pt, L);
__ stop("StubRoutines::forward exception: no pending exception (1)");
__ bind(L);
}
......@@ -406,8 +403,7 @@ class StubGenerator: public StubCodeGenerator {
#ifdef ASSERT
// make sure exception is set
{ Label L;
__ br_notnull(Oexception, false, Assembler::pt, L);
__ delayed()->nop();
__ br_notnull_short(Oexception, Assembler::pt, L);
__ stop("StubRoutines::forward exception: no pending exception (2)");
__ bind(L);
}
......@@ -501,8 +497,7 @@ class StubGenerator: public StubCodeGenerator {
Address exception_addr(G2_thread, Thread::pending_exception_offset());
Register scratch_reg = Gtemp;
__ ld_ptr(exception_addr, scratch_reg);
__ br_notnull(scratch_reg, false, Assembler::pt, L);
__ delayed()->nop();
__ br_notnull_short(scratch_reg, Assembler::pt, L);
__ should_not_reach_here();
__ bind(L);
#endif // ASSERT
......@@ -614,9 +609,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(G0,yield_reg);
__ BIND(retry);
__ cmp(yield_reg, V8AtomicOperationUnderLockSpinCount);
__ br(Assembler::less, false, Assembler::pt, dontyield);
__ delayed()->nop();
__ cmp_and_br_short(yield_reg, V8AtomicOperationUnderLockSpinCount, Assembler::less, Assembler::pt, dontyield);
// This code can only be called from inside the VM, this
// stub is only invoked from Atomic::add(). We do not
......@@ -676,9 +669,7 @@ class StubGenerator: public StubCodeGenerator {
// try to replace O2 with O3
__ cas_under_lock(O1, O2, O3,
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr(),false);
__ cmp(O2, O3);
__ br(Assembler::notEqual, false, Assembler::pn, retry);
__ delayed()->nop();
__ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
__ retl(false);
__ delayed()->mov(O2, O0); // report previous value to caller
......@@ -798,11 +789,9 @@ class StubGenerator: public StubCodeGenerator {
__ BIND(retry);
__ lduw(O1, 0, O2);
__ add(O0, O2, O3);
__ cas(O1, O2, O3);
__ cmp( O2, O3);
__ br(Assembler::notEqual, false, Assembler::pn, retry);
__ delayed()->nop();
__ add(O0, O2, O3);
__ cas(O1, O2, O3);
__ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
__ retl(false);
__ delayed()->add(O0, O2, O0); // note that cas made O2==O3
} else {
......@@ -1370,8 +1359,7 @@ class StubGenerator: public StubCodeGenerator {
// copy tailing bytes
__ BIND(L_copy_byte);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit);
__ delayed()->nop();
__ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ align(OptoLoopAlignment);
__ BIND(L_copy_byte_loop);
__ ldub(from, offset, O3);
......@@ -1482,8 +1470,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element (2 bytes) at a time
__ BIND(L_copy_byte);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit);
__ delayed()->nop();
__ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ align(OptoLoopAlignment);
__ BIND(L_copy_byte_loop);
__ dec(end_from);
......@@ -1600,8 +1587,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element at a time
__ BIND(L_copy_2_bytes);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit);
__ delayed()->nop();
__ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ align(OptoLoopAlignment);
__ BIND(L_copy_2_bytes_loop);
__ lduh(from, offset, O3);
......@@ -1946,8 +1932,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element (2 bytes) at a time
__ BIND(L_copy_2_bytes);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit);
__ delayed()->nop();
__ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ BIND(L_copy_2_bytes_loop);
__ dec(end_from, 2);
__ dec(end_to, 2);
......@@ -2060,8 +2045,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element at a time
__ BIND(L_copy_4_bytes);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit);
__ delayed()->nop();
__ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ BIND(L_copy_4_bytes_loop);
__ ld(from, offset, O3);
__ deccc(count);
......@@ -2193,8 +2177,7 @@ class StubGenerator: public StubCodeGenerator {
// copy 1 element (4 bytes) at a time
__ BIND(L_copy_4_bytes);
__ br_zero(Assembler::zero, false, Assembler::pt, count, L_exit);
__ delayed()->nop();
__ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
__ BIND(L_copy_4_bytes_loop);
__ dec(end_from, 4);
__ dec(end_to, 4);
......@@ -2576,7 +2559,7 @@ class StubGenerator: public StubCodeGenerator {
super_klass->after_save(),
L0, L1, L2, L4,
NULL, &L_pop_to_miss);
__ ba(false, L_success);
__ ba(L_success);
__ delayed()->restore();
__ bind(L_pop_to_miss);
......@@ -2673,8 +2656,7 @@ class StubGenerator: public StubCodeGenerator {
// ======== loop entry is here ========
__ BIND(load_element);
__ load_heap_oop(O0_from, O5_offset, G3_oop); // load the oop
__ br_null(G3_oop, true, Assembler::pt, store_element);
__ delayed()->nop();
__ br_null_short(G3_oop, Assembler::pt, store_element);
__ load_klass(G3_oop, G4_klass); // query the object klass
......@@ -2896,8 +2878,7 @@ class StubGenerator: public StubCodeGenerator {
// assert(src->klass() != NULL);
BLOCK_COMMENT("assert klasses not null");
{ Label L_a, L_b;
__ br_notnull(G3_src_klass, false, Assembler::pt, L_b); // it is broken if klass is NULL
__ delayed()->nop();
__ br_notnull_short(G3_src_klass, Assembler::pt, L_b); // it is broken if klass is NULL
__ bind(L_a);
__ stop("broken null klass");
__ bind(L_b);
......@@ -2937,9 +2918,7 @@ class StubGenerator: public StubCodeGenerator {
}
// if (src->klass() != dst->klass()) return -1;
__ cmp(G3_src_klass, G4_dst_klass);
__ brx(Assembler::notEqual, false, Assembler::pn, L_failed);
__ delayed()->nop();
__ cmp_and_brx_short(G3_src_klass, G4_dst_klass, Assembler::notEqual, Assembler::pn, L_failed);
// if (!src->is_Array()) return -1;
__ cmp(G5_lh, Klass::_lh_neutral_value); // < 0
......@@ -3007,9 +2986,7 @@ class StubGenerator: public StubCodeGenerator {
__ delayed()->signx(length, count); // length
#ifdef ASSERT
{ Label L;
__ cmp(G3_elsize, LogBytesPerLong);
__ br(Assembler::equal, false, Assembler::pt, L);
__ delayed()->nop();
__ cmp_and_br_short(G3_elsize, LogBytesPerLong, Assembler::equal, Assembler::pt, L);
__ stop("must be long copy, but elsize is wrong");
__ bind(L);
}
......
......@@ -190,9 +190,7 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
const Register size = G1_scratch;
if (EnableInvokeDynamic) {
__ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode.
__ cmp(G1_scratch, Bytecodes::_invokedynamic);
__ br(Assembler::equal, false, Assembler::pn, L_giant_index);
__ delayed()->nop();
__ cmp_and_br_short(G1_scratch, Bytecodes::_invokedynamic, Assembler::equal, Assembler::pn, L_giant_index);
}
__ get_cache_and_index_at_bcp(cache, G1_scratch, 1);
__ bind(L_got_cache);
......@@ -207,8 +205,7 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
if (EnableInvokeDynamic) {
__ bind(L_giant_index);
__ get_cache_and_index_at_bcp(cache, G1_scratch, 1, sizeof(u4));
__ ba(false, L_got_cache);
__ delayed()->nop();
__ ba_short(L_got_cache);
}
return entry;
......@@ -221,9 +218,7 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, i
{ Label L;
Address exception_addr(G2_thread, Thread::pending_exception_offset());
__ ld_ptr(exception_addr, Gtemp); // Load pending exception.
__ tst(Gtemp);
__ brx(Assembler::equal, false, Assembler::pt, L);
__ delayed()->nop();
__ br_null_short(Gtemp, Assembler::pt, L);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
__ should_not_reach_here();
__ bind(L);
......@@ -304,8 +299,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile
if (ProfileInterpreter) {
// If no method data exists, go to profile_continue.
__ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch);
__ br_null(G4_scratch, false, Assembler::pn, no_mdo);
__ delayed()->nop();
__ br_null_short(G4_scratch, Assembler::pn, no_mdo);
// Increment counter
Address mdo_invocation_counter(G4_scratch,
in_bytes(methodDataOopDesc::invocation_counter_offset()) +
......@@ -313,8 +307,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile
__ increment_mask_and_jump(mdo_invocation_counter, increment, mask,
G3_scratch, Lscratch,
Assembler::zero, overflow);
__ ba(false, done);
__ delayed()->nop();
__ ba_short(done);
}
// Increment counter in methodOop
......@@ -340,9 +333,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile
// Test to see if we should create a method data oop
AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit);
__ load_contents(profile_limit, G3_scratch);
__ cmp(O0, G3_scratch);
__ br(Assembler::lessUnsigned, false, Assembler::pn, *profile_method_continue);
__ delayed()->nop();
__ cmp_and_br_short(O0, G3_scratch, Assembler::lessUnsigned, Assembler::pn, *profile_method_continue);
// if no method data exists, go to profile_method
__ test_method_data_pointer(*profile_method);
......@@ -351,7 +342,7 @@ void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile
AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit);
__ load_contents(invocation_limit, G3_scratch);
__ cmp(O0, G3_scratch);
__ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow);
__ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); // Far distance
__ delayed()->nop();
}
......@@ -410,19 +401,14 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
assert_different_registers(Rframe_size, Rscratch, Rscratch2);
__ set( page_size, Rscratch );
__ cmp( Rframe_size, Rscratch );
__ br( Assembler::lessEqual, false, Assembler::pt, after_frame_check );
__ delayed()->nop();
__ set(page_size, Rscratch);
__ cmp_and_br_short(Rframe_size, Rscratch, Assembler::lessEqual, Assembler::pt, after_frame_check);
// get the stack base, and in debug, verify it is non-zero
__ ld_ptr( G2_thread, Thread::stack_base_offset(), Rscratch );
#ifdef ASSERT
Label base_not_zero;
__ cmp( Rscratch, G0 );
__ brx( Assembler::notEqual, false, Assembler::pn, base_not_zero );
__ delayed()->nop();
__ br_notnull_short(Rscratch, Assembler::pn, base_not_zero);
__ stop("stack base is zero in generate_stack_overflow_check");
__ bind(base_not_zero);
#endif
......@@ -432,9 +418,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
__ ld_ptr( G2_thread, Thread::stack_size_offset(), Rscratch2 );
#ifdef ASSERT
Label size_not_zero;
__ cmp( Rscratch2, G0 );
__ brx( Assembler::notEqual, false, Assembler::pn, size_not_zero );
__ delayed()->nop();
__ br_notnull_short(Rscratch2, Assembler::pn, size_not_zero);
__ stop("stack size is zero in generate_stack_overflow_check");
__ bind(size_not_zero);
#endif
......@@ -450,9 +434,7 @@ void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rframe
// the frame is greater than one page in size, so check against
// the bottom of the stack
__ cmp( SP, Rscratch );
__ brx( Assembler::greater, false, Assembler::pt, after_frame_check );
__ delayed()->nop();
__ cmp_and_brx_short(SP, Rscratch, Assembler::greater, Assembler::pt, after_frame_check);
// Save the return address as the exception pc
__ st_ptr(O7, saved_exception_pc);
......@@ -624,9 +606,7 @@ address InterpreterGenerator::generate_empty_entry(void) {
// If we need a safepoint check, generate full interpreter entry.
AddressLiteral sync_state(SafepointSynchronize::address_of_state());
__ set(sync_state, G3_scratch);
__ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
__ cmp_and_br_short(G3_scratch, SafepointSynchronize::_not_synchronized, Assembler::notEqual, Assembler::pn, slow_path);
// Code: _return
__ retl();
......@@ -664,14 +644,12 @@ address InterpreterGenerator::generate_accessor_entry(void) {
AddressLiteral sync_state(SafepointSynchronize::address_of_state());
__ load_contents(sync_state, G3_scratch);
__ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
__ cmp_and_br_short(G3_scratch, SafepointSynchronize::_not_synchronized, Assembler::notEqual, Assembler::pn, slow_path);
// Check if local 0 != NULL
__ ld_ptr(Gargs, G0, Otos_i ); // get local 0
__ tst(Otos_i); // check if local 0 == NULL and go the slow path
__ brx(Assembler::zero, false, Assembler::pn, slow_path);
__ delayed()->nop();
// check if local 0 == NULL and go the slow path
__ br_null_short(Otos_i, Assembler::pn, slow_path);
// read first instruction word and extract bytecode @ 1 and index @ 2
......@@ -697,9 +675,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
__ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::indices_offset(), G1_scratch);
__ srl(G1_scratch, 2*BitsPerByte, G1_scratch);
__ and3(G1_scratch, 0xFF, G1_scratch);
__ cmp(G1_scratch, Bytecodes::_getfield);
__ br(Assembler::notEqual, false, Assembler::pn, slow_path);
__ delayed()->nop();
__ cmp_and_br_short(G1_scratch, Bytecodes::_getfield, Assembler::notEqual, Assembler::pn, slow_path);
// Get the type and return field offset from the constant pool cache
__ ld_ptr(G3_scratch, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), G1_scratch);
......@@ -787,9 +763,8 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
// Check if local 0 != NULL
// If the receiver is null then it is OK to jump to the slow path.
__ ld_ptr(Gargs, G0, Otos_i ); // get local 0
__ tst(Otos_i); // check if local 0 == NULL and go the slow path
__ brx(Assembler::zero, false, Assembler::pn, slow_path);
__ delayed()->nop();
// check if local 0 == NULL and go the slow path
__ cmp_and_brx_short(Otos_i, 0, Assembler::equal, Assembler::pn, slow_path);
// Load the value of the referent field.
......@@ -952,9 +927,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
{ Label L;
Address signature_handler(Lmethod, methodOopDesc::signature_handler_offset());
__ ld_ptr(signature_handler, G3_scratch);
__ tst(G3_scratch);
__ brx(Assembler::notZero, false, Assembler::pt, L);
__ delayed()->nop();
__ br_notnull_short(G3_scratch, Assembler::pt, L);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), Lmethod);
__ ld_ptr(signature_handler, G3_scratch);
__ bind(L);
......@@ -1019,9 +992,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
#ifdef ASSERT
if (!PrintSignatureHandlers) // do not dirty the output with this
{ Label L;
__ tst(O1);
__ brx(Assembler::notZero, false, Assembler::pt, L);
__ delayed()->nop();
__ br_notnull_short(O1, Assembler::pt, L);
__ stop("mirror is missing");
__ bind(L);
}
......@@ -1038,9 +1009,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
#ifdef ASSERT
{ Label L;
__ tst(O0);
__ brx(Assembler::notZero, false, Assembler::pt, L);
__ delayed()->nop();
__ br_notnull_short(O0, Assembler::pt, L);
__ stop("native entry point is missing");
__ bind(L);
}
......@@ -1079,9 +1048,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
#ifdef ASSERT
{ Label L;
__ ld(thread_state, G3_scratch);
__ cmp(G3_scratch, _thread_in_Java);
__ br(Assembler::equal, false, Assembler::pt, L);
__ delayed()->nop();
__ cmp_and_br_short(G3_scratch, _thread_in_Java, Assembler::equal, Assembler::pt, L);
__ stop("Wrong thread state in native stub");
__ bind(L);
}
......@@ -1134,9 +1101,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
Label L;
__ br(Assembler::notEqual, false, Assembler::pn, L);
__ delayed()->ld(G2_thread, JavaThread::suspend_flags_offset(), G3_scratch);
__ cmp(G3_scratch, 0);
__ br(Assembler::equal, false, Assembler::pt, no_block);
__ delayed()->nop();
__ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block);
__ bind(L);
// Block. Save any potential method result value before the operation and
......@@ -1185,9 +1150,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
Label no_oop, store_result;
__ set((intptr_t)AbstractInterpreter::result_handler(T_OBJECT), G3_scratch);
__ cmp(G3_scratch, Lscratch);
__ brx(Assembler::notEqual, false, Assembler::pt, no_oop);
__ delayed()->nop();
__ cmp_and_brx_short(G3_scratch, Lscratch, Assembler::notEqual, Assembler::pt, no_oop);
__ addcc(G0, O0, O0);
__ brx(Assembler::notZero, true, Assembler::pt, store_result); // if result is not NULL:
__ delayed()->ld_ptr(O0, 0, O0); // unbox it
......@@ -1206,9 +1169,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
{ Label L;
Address exception_addr(G2_thread, Thread::pending_exception_offset());
__ ld_ptr(exception_addr, Gtemp);
__ tst(Gtemp);
__ brx(Assembler::equal, false, Assembler::pt, L);
__ delayed()->nop();
__ br_null_short(Gtemp, Assembler::pt, L);
// Note: This could be handled more efficiently since we know that the native
// method doesn't have an exception handler. We could directly return
// to the exception handler for the caller.
......@@ -1245,9 +1206,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
#ifdef ASSERT
{
Label ok;
__ cmp(I5_savedSP, FP);
__ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, ok);
__ delayed()->nop();
__ cmp_and_brx_short(I5_savedSP, FP, Assembler::greaterEqualUnsigned, Assembler::pt, ok);
__ stop("bad I5_savedSP value");
__ should_not_reach_here();
__ bind(ok);
......@@ -1429,8 +1388,7 @@ address InterpreterGenerator::generate_normal_entry(bool synchronized) {
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
__ set_method_data_pointer_for_bcp();
__ ba(false, profile_method_continue);
__ delayed()->nop();
__ ba_short(profile_method_continue);
}
// handle invocation counter overflow
......@@ -1856,9 +1814,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
// adapter frames in C2.
Label caller_not_deoptimized;
__ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), I7);
__ tst(O0);
__ brx(Assembler::notEqual, false, Assembler::pt, caller_not_deoptimized);
__ delayed()->nop();
__ br_notnull_short(O0, Assembler::pt, caller_not_deoptimized);
const Register Gtmp1 = G3_scratch;
const Register Gtmp2 = G1_scratch;
......@@ -1992,10 +1948,10 @@ address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state
void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
Label L;
aep = __ pc(); __ push_ptr(); __ ba(false, L); __ delayed()->nop();
fep = __ pc(); __ push_f(); __ ba(false, L); __ delayed()->nop();
dep = __ pc(); __ push_d(); __ ba(false, L); __ delayed()->nop();
lep = __ pc(); __ push_l(); __ ba(false, L); __ delayed()->nop();
aep = __ pc(); __ push_ptr(); __ ba_short(L);
fep = __ pc(); __ push_f(); __ ba_short(L);
dep = __ pc(); __ push_d(); __ ba_short(L);
lep = __ pc(); __ push_l(); __ ba_short(L);
iep = __ pc(); __ push_i();
bep = cep = sep = iep; // there aren't any
vep = __ pc(); __ bind(L); // fall through
......
......@@ -59,6 +59,11 @@ void VM_Version::initialize() {
assert(AllocatePrefetchDistance % AllocatePrefetchStepSize == 0, "invalid value");
if (AllocatePrefetchStyle == 3 && !has_blk_init()) {
warning("BIS instructions are not available on this CPU");
FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1);
}
UseSSE = 0; // Only on x86 and x64
_supports_cx8 = has_v9();
......@@ -116,27 +121,44 @@ void VM_Version::initialize() {
if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
FLAG_SET_DEFAULT(UsePopCountInstruction, true);
}
} else if (UsePopCountInstruction) {
warning("POPC instruction is not available on this CPU");
FLAG_SET_DEFAULT(UsePopCountInstruction, false);
}
// T4 and newer Sparc cpus have new compare and branch instruction.
if (has_cbcond()) {
if (FLAG_IS_DEFAULT(UseCBCond)) {
FLAG_SET_DEFAULT(UseCBCond, true);
}
} else if (UseCBCond) {
warning("CBCOND instruction is not available on this CPU");
FLAG_SET_DEFAULT(UseCBCond, false);
}
#ifdef COMPILER2
// T4 and newer Sparc cpus have fast RDPC.
if (has_fast_rdpc() && FLAG_IS_DEFAULT(UseRDPCForConstantTableBase)) {
// FLAG_SET_DEFAULT(UseRDPCForConstantTableBase, true);
}
// Currently not supported anywhere.
FLAG_SET_DEFAULT(UseFPUForSpilling, false);
#endif
char buf[512];
jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
(has_v8() ? ", has_v8" : ""),
(has_v9() ? ", has_v9" : ""),
jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
(has_v9() ? ", v9" : (has_v8() ? ", v8" : "")),
(has_hardware_popc() ? ", popc" : ""),
(has_vis1() ? ", has_vis1" : ""),
(has_vis2() ? ", has_vis2" : ""),
(has_vis3() ? ", has_vis3" : ""),
(has_blk_init() ? ", has_blk_init" : ""),
(is_ultra3() ? ", is_ultra3" : ""),
(is_sun4v() ? ", is_sun4v" : ""),
(is_niagara() ? ", is_niagara" : ""),
(is_niagara_plus() ? ", is_niagara_plus" : ""),
(is_sparc64() ? ", is_sparc64" : ""),
(has_vis1() ? ", vis1" : ""),
(has_vis2() ? ", vis2" : ""),
(has_vis3() ? ", vis3" : ""),
(has_blk_init() ? ", blk_init" : ""),
(has_cbcond() ? ", cbcond" : ""),
(is_ultra3() ? ", ultra3" : ""),
(is_sun4v() ? ", sun4v" : ""),
(is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")),
(is_sparc64() ? ", sparc64" : ""),
(!has_hardware_mul32() ? ", no-mul32" : ""),
(!has_hardware_div32() ? ", no-div32" : ""),
(!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
......
......@@ -31,44 +31,46 @@
class VM_Version: public Abstract_VM_Version {
protected:
enum Feature_Flag {
v8_instructions = 0,
hardware_mul32 = 1,
hardware_div32 = 2,
hardware_fsmuld = 3,
hardware_popc = 4,
v9_instructions = 5,
vis1_instructions = 6,
vis2_instructions = 7,
sun4v_instructions = 8,
v8_instructions = 0,
hardware_mul32 = 1,
hardware_div32 = 2,
hardware_fsmuld = 3,
hardware_popc = 4,
v9_instructions = 5,
vis1_instructions = 6,
vis2_instructions = 7,
sun4v_instructions = 8,
blk_init_instructions = 9,
fmaf_instructions = 10,
fmau_instructions = 11,
vis3_instructions = 12,
sparc64_family = 13,
T_family = 14,
T1_model = 15
fmaf_instructions = 10,
fmau_instructions = 11,
vis3_instructions = 12,
sparc64_family = 13,
T_family = 14,
T1_model = 15,
cbcond_instructions = 16
};
enum Feature_Flag_Set {
unknown_m = 0,
all_features_m = -1,
v8_instructions_m = 1 << v8_instructions,
hardware_mul32_m = 1 << hardware_mul32,
hardware_div32_m = 1 << hardware_div32,
hardware_fsmuld_m = 1 << hardware_fsmuld,
hardware_popc_m = 1 << hardware_popc,
v9_instructions_m = 1 << v9_instructions,
vis1_instructions_m = 1 << vis1_instructions,
vis2_instructions_m = 1 << vis2_instructions,
sun4v_m = 1 << sun4v_instructions,
v8_instructions_m = 1 << v8_instructions,
hardware_mul32_m = 1 << hardware_mul32,
hardware_div32_m = 1 << hardware_div32,
hardware_fsmuld_m = 1 << hardware_fsmuld,
hardware_popc_m = 1 << hardware_popc,
v9_instructions_m = 1 << v9_instructions,
vis1_instructions_m = 1 << vis1_instructions,
vis2_instructions_m = 1 << vis2_instructions,
sun4v_m = 1 << sun4v_instructions,
blk_init_instructions_m = 1 << blk_init_instructions,
fmaf_instructions_m = 1 << fmaf_instructions,
fmau_instructions_m = 1 << fmau_instructions,
vis3_instructions_m = 1 << vis3_instructions,
sparc64_family_m = 1 << sparc64_family,
T_family_m = 1 << T_family,
T1_model_m = 1 << T1_model,
fmaf_instructions_m = 1 << fmaf_instructions,
fmau_instructions_m = 1 << fmau_instructions,
vis3_instructions_m = 1 << vis3_instructions,
sparc64_family_m = 1 << sparc64_family,
T_family_m = 1 << T_family,
T1_model_m = 1 << T1_model,
cbcond_instructions_m = 1 << cbcond_instructions,
generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
generic_v9_m = generic_v8_m | v9_instructions_m,
......@@ -111,20 +113,25 @@ public:
static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
static bool has_vis3() { return (_features & vis3_instructions_m) != 0; }
static bool has_blk_init() { return (_features & blk_init_instructions_m) != 0; }
static bool has_cbcond() { return (_features & cbcond_instructions_m) != 0; }
static bool supports_compare_and_exchange()
{ return has_v9(); }
static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m; }
static bool is_sun4v() { return (_features & sun4v_m) != 0; }
// Returns true if the platform is in the niagara line (T series)
// and newer than the niagara1.
static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); }
// Fujitsu SPARC64
static bool is_sparc64() { return (_features & sparc64_family_m) != 0; }
static bool is_sun4v() { return (_features & sun4v_m) != 0; }
static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m && !is_sun4v() && !is_sparc64(); }
static bool has_fast_fxtof() { return is_niagara() || is_sparc64() || has_v9() && !is_ultra3(); }
static bool has_fast_idiv() { return is_niagara_plus() || is_sparc64(); }
// T4 and newer Sparc have fast RDPC instruction.
static bool has_fast_rdpc() { return is_niagara_plus() && has_cbcond(); }
static const char* cpu_features() { return _features_str; }
......
......@@ -76,9 +76,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
Label L;
// check offset vs vtable length
__ ld(G3_scratch, instanceKlass::vtable_length_offset()*wordSize, G5);
__ cmp(G5, vtable_index*vtableEntry::size());
__ br(Assembler::greaterUnsigned, false, Assembler::pt, L);
__ delayed()->nop();
__ cmp_and_br_short(G5, vtable_index*vtableEntry::size(), Assembler::greaterUnsigned, Assembler::pt, L);
__ set(vtable_index, O2);
__ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2);
__ bind(L);
......@@ -95,8 +93,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
#ifndef PRODUCT
if (DebugVtables) {
Label L;
__ br_notnull(G5_method, false, Assembler::pt, L);
__ delayed()->nop();
__ br_notnull_short(G5_method, Assembler::pt, L);
__ stop("Vtable entry is ZERO");
__ bind(L);
}
......@@ -177,8 +174,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
#ifndef PRODUCT
if (DebugVtables) {
Label L01;
__ bpr(Assembler::rc_nz, false, Assembler::pt, L5_method, L01);
__ delayed()->nop();
__ br_notnull_short(L5_method, Assembler::pt, L01);
__ stop("methodOop is null");
__ bind(L01);
__ verify_oop(L5_method);
......
......@@ -1713,14 +1713,14 @@ encode %{
else emit_d32(cbuf,con);
%}
enc_class Lbl (label labl) %{ // JMP, CALL
enc_class Lbl (label labl) %{ // GOTO
Label *l = $labl$$label;
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0);
emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size()+4)));
%}
enc_class LblShort (label labl) %{ // JMP, CALL
enc_class LblShort (label labl) %{ // GOTO
Label *l = $labl$$label;
int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0;
int disp = l->loc_pos() - (cbuf.insts_size()+1);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
emit_d8(cbuf, disp);
%}
......@@ -1751,13 +1751,13 @@ encode %{
Label *l = $labl$$label;
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size()+4)) : 0);
emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size()+4)));
%}
enc_class JccShort (cmpOp cop, label labl) %{ // JCC
Label *l = $labl$$label;
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size()+1)) : 0;
int disp = l->loc_pos() - (cbuf.insts_size()+1);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
emit_d8(cbuf, disp);
%}
......@@ -13172,7 +13172,7 @@ instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
bool ok = false;
if ($cop$$cmpcode == Assembler::notEqual) {
// the two jumps 6 bytes apart so the jump distances are too
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
parity_disp = l->loc_pos() - (cbuf.insts_size() + 4);
} else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 6;
ok = true;
......@@ -13182,7 +13182,7 @@ instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
emit_d32(cbuf, parity_disp);
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
int disp = l->loc_pos() - (cbuf.insts_size() + 4);
emit_d32(cbuf, disp);
%}
ins_pipe(pipe_jcc);
......@@ -13368,7 +13368,7 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
emit_cc(cbuf, $primary, Assembler::parity);
int parity_disp = -1;
if ($cop$$cmpcode == Assembler::notEqual) {
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
parity_disp = l->loc_pos() - (cbuf.insts_size() + 1);
} else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 2;
} else {
......@@ -13376,7 +13376,7 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
}
emit_d8(cbuf, parity_disp);
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
int disp = l->loc_pos() - (cbuf.insts_size() + 1);
emit_d8(cbuf, disp);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
......
......@@ -2428,16 +2428,16 @@ encode %{
enc_class Lbl(label labl)
%{
// JMP, CALL
// GOTO
Label* l = $labl$$label;
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size() + 4)));
%}
enc_class LblShort(label labl)
%{
// JMP, CALL
// GOTO
Label* l = $labl$$label;
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
int disp = l->loc_pos() - (cbuf.insts_size() + 1);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
emit_d8(cbuf, disp);
%}
......@@ -2466,7 +2466,7 @@ encode %{
Label* l = $labl$$label;
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0);
emit_d32(cbuf, (l->loc_pos() - (cbuf.insts_size() + 4)));
%}
enc_class JccShort (cmpOp cop, label labl)
......@@ -2474,7 +2474,7 @@ encode %{
// JCC
Label *l = $labl$$label;
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
int disp = l->loc_pos() - (cbuf.insts_size() + 1);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
emit_d8(cbuf, disp);
%}
......@@ -12131,7 +12131,7 @@ instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
int parity_disp = -1;
if ($cop$$cmpcode == Assembler::notEqual) {
// the two jumps 6 bytes apart so the jump distances are too
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
parity_disp = l->loc_pos() - (cbuf.insts_size() + 4);
} else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 6;
} else {
......@@ -12140,7 +12140,7 @@ instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
emit_d32(cbuf, parity_disp);
$$$emit8$primary;
emit_cc(cbuf, $secondary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 4)) : 0;
int disp = l->loc_pos() - (cbuf.insts_size() + 4);
emit_d32(cbuf, disp);
%}
ins_pipe(pipe_jcc);
......@@ -12335,7 +12335,7 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
emit_cc(cbuf, $primary, Assembler::parity);
int parity_disp = -1;
if ($cop$$cmpcode == Assembler::notEqual) {
parity_disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
parity_disp = l->loc_pos() - (cbuf.insts_size() + 1);
} else if ($cop$$cmpcode == Assembler::equal) {
parity_disp = 2;
} else {
......@@ -12343,7 +12343,7 @@ instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
}
emit_d8(cbuf, parity_disp);
emit_cc(cbuf, $primary, $cop$$cmpcode);
int disp = l ? (l->loc_pos() - (cbuf.insts_size() + 1)) : 0;
int disp = l->loc_pos() - (cbuf.insts_size() + 1);
emit_d8(cbuf, disp);
assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
......
......@@ -114,6 +114,11 @@ int VM_Version::platform_features(int features) {
#endif
if (av & AV_SPARC_VIS3) features |= vis3_instructions_m;
#ifndef AV_SPARC_CBCOND
#define AV_SPARC_CBCOND 0x10000000 /* compare and branch instrs supported */
#endif
if (av & AV_SPARC_CBCOND) features |= cbcond_instructions_m;
} else {
// getisax(2) failed, use the old legacy code.
#ifndef PRODUCT
......
......@@ -3623,7 +3623,27 @@ bool MatchNode::equivalent(FormDict &globals, MatchNode *mNode2) {
assert( mNode2->_opType, "Must have _opType");
const Form *form = globals[_opType];
const Form *form2 = globals[mNode2->_opType];
return (form == form2);
if( form != form2 ) {
return false;
}
// Check that their children also match
if (_lChild ) {
if( !_lChild->equivalent(globals, mNode2->_lChild) )
return false;
} else if (mNode2->_lChild) {
return false; // I have NULL left child, mNode2 has non-NULL left child.
}
if (_rChild ) {
if( !_rChild->equivalent(globals, mNode2->_rChild) )
return false;
} else if (mNode2->_rChild) {
return false; // I have NULL right child, mNode2 has non-NULL right child.
}
// We've made it through the gauntlet.
return true;
}
//-------------------------- has_commutative_op -------------------------------
......
......@@ -3088,10 +3088,10 @@ void ArchDesc::defineClasses(FILE *fp) {
int label_position = instr->label_position();
if( label_position != -1 ) {
// Set the label
fprintf(fp,"void %sNode::label_set( Label& label, uint block_num ) {\n", instr->_ident);
fprintf(fp,"void %sNode::label_set( Label* label, uint block_num ) {\n", instr->_ident);
fprintf(fp," labelOper* oper = (labelOper*)(opnd_array(%d));\n",
label_position );
fprintf(fp," oper->_label = &label;\n");
fprintf(fp," oper->_label = label;\n");
fprintf(fp," oper->_block_num = block_num;\n");
fprintf(fp,"}\n");
}
......
......@@ -1520,7 +1520,7 @@ void ArchDesc::declareClasses(FILE *fp) {
int label_position = instr->label_position();
if( label_position != -1 ) {
// Set the label, stored in labelOper::_branch_label
fprintf(fp," virtual void label_set( Label& label, uint block_num );\n");
fprintf(fp," virtual void label_set( Label* label, uint block_num );\n");
}
// If this instruction contains a methodOper
......
......@@ -517,7 +517,17 @@ uint Compile::scratch_emit_size(const Node* n) {
buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize);
// Do the emission.
Label fakeL; // Fake label for branch instructions.
bool is_branch = n->is_Branch() && n->as_Mach()->ideal_Opcode() != Op_Jump;
if (is_branch) {
MacroAssembler masm(&buf);
masm.bind(fakeL);
n->as_Mach()->label_set(&fakeL, 0);
}
n->emit(buf, this->regalloc());
if (is_branch) // Clear the reference to fake label.
n->as_Mach()->label_set(NULL, 0);
// End scratch_emit_size section.
set_in_scratch_emit_size(false);
......
......@@ -409,7 +409,7 @@ void MachNode::add_case_label( int index_num, Label* blockLabel) {
//------------------------------label_set--------------------------------------
// Set the Label for a LabelOper, if an operand for this instruction
void MachNode::label_set( Label& label, uint block_num ) {
void MachNode::label_set( Label* label, uint block_num ) {
ShouldNotCallThis();
}
......@@ -514,6 +514,9 @@ void MachNullCheckNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
void MachNullCheckNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
// only emits entries in the null-pointer exception handler table
}
void MachNullCheckNode::label_set(Label* label, uint block_num) {
// Nothing to emit
}
const RegMask &MachNullCheckNode::in_RegMask( uint idx ) const {
if( idx == 0 ) return RegMask::Empty;
......
......@@ -282,7 +282,7 @@ public:
virtual int ideal_Opcode() const { return Op_Node; }
// Set the branch inside jump MachNodes. Error for non-branch Nodes.
virtual void label_set( Label& label, uint block_num );
virtual void label_set( Label* label, uint block_num );
// Adds the label for the case
virtual void add_case_label( int switch_val, Label* blockLabel);
......@@ -531,6 +531,7 @@ public:
}
virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
virtual void label_set(Label* label, uint block_num);
virtual bool pinned() const { return true; };
virtual void negate() { }
virtual const class Type *bottom_type() const { return TypeTuple::IFBOTH; }
......@@ -853,7 +854,7 @@ public:
virtual MachOper *clone(Compile* C) const;
virtual Label *label() const { return _label; }
virtual Label *label() const { assert(_label != NULL, "need Label"); return _label; }
virtual uint opcode() const;
......
......@@ -1346,7 +1346,7 @@ void Compile::Fill_buffer() {
// For Branchs
// This requires the TRUE branch target be in succs[0]
uint block_num = b->non_connector_successor(0)->_pre_order;
mach->label_set( blk_labels[block_num], block_num );
mach->label_set( &blk_labels[block_num], block_num );
}
}
......
......@@ -1205,6 +1205,9 @@ class CommandLineFlags {
product(bool, UseUnalignedLoadStores, false, \
"Use SSE2 MOVDQU instruction for Arraycopy") \
\
product(bool, UseCBCond, false, \
"Use compare and branch instruction on SPARC") \
\
product(intx, FieldsAllocationStyle, 1, \
"0 - type based with oops first, 1 - with oops last, " \
"2 - oops in super and sub classes are together") \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册