--- old/src/cpu/sparc/vm/assembler_sparc.hpp Fri Jul 15 19:09:41 2011 +++ new/src/cpu/sparc/vm/assembler_sparc.hpp Fri Jul 15 19:09:41 2011 @@ -984,17 +984,17 @@ 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_cbc( int x ) { + 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_cbc(x), "wrong instruction"); + assert(is_cbcond(x), "wrong instruction"); return (x & (1<<21)) != 0; } - static int cond_cbc( int x) { return u_field((((x & 8)<<1) + 8 + (x & 7)), 29, 25); } - static int inv_cond_cbc(int x) { - assert(is_cbc(x), "wrong instruction"); + 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); } @@ -1051,7 +1051,7 @@ // compute inverse of wdisp10 static intptr_t inv_wdisp10(int x, intptr_t pos) { - assert(is_cbc(x), "wrong instruction"); + assert(is_cbcond(x), "wrong instruction"); int lo = inv_u_field(x, 12, 5); int hi = (x >> 19) & 3; if (hi >= 2) hi |= ~1; @@ -1065,8 +1065,8 @@ assert_signed_word_disp_range(xx, 10); int r = ( ( (xx >> 2 ) & ((1 << 8) - 1) ) << 5 ) | ( ( (xx >> (2+8)) & 3 ) << 19 ); - // Have to fake cbc instruction to pass assert in inv_wdisp10() - assert(inv_wdisp10((r | op(branch_op) | cond_cbc(rc_last+1) | op2(bpr_op2)), off) == x, "inverse is not inverse"); + // 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; } @@ -1182,18 +1182,18 @@ } // cbcond instruction should not be generated one after an other - bool cbc_before() { + bool cbcond_before() { if (offset() == 0) return false; // it is first instruction int x = *(int*)(intptr_t(pc()) - 4); // previous instruction - return is_cbc(x); + return is_cbcond(x); } - void no_cbc_before() { - assert(offset() == 0 || !cbc_before(), "cbcond should not follow an other cbcond"); + void no_cbcond_before() { + assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond"); } - bool use_cbc(Label& L) { - if (!UseCBCond || cbc_before()) return false; + 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); @@ -1276,8 +1276,8 @@ inline void cb( Condition c, bool a, Label& L ); // compare and branch - inline void cbc(Condition c, CC cc, Register s1, Register s2, Label& L); - inline void cbc(Condition c, CC cc, Register s1, int simm5, Label& L); + 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 @@ -1929,7 +1929,7 @@ inline void fb( Condition c, bool a, Predict p, Label& L ); // compares register with zero (32 bit) and branches (V9 and V8 instructions) - void br_zero ( Register s1, Label& L ); + 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, bool emit_delayed_nop = true ); @@ -1941,13 +1941,26 @@ 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, bool emit_delayed_nop = true ); + // // Compare registers and branch with nop in delay slot or cbcond without delay slot. - void cmp_and_br(Register s1, Register s2, Condition c, bool a, Predict p, Label& L); - void cmp_and_br(Register s1, int simm13a, Condition c, bool a, Predict p, Label& L); - // Platform depending version - void cmp_and_brx(Register s1, Register s2, Condition c, bool a, Predict p, Label& L); - void cmp_and_brx(Register s1, int simm13a, Condition c, bool a, Predict p, Label& L); + // + // 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 ); @@ -1955,8 +1968,8 @@ 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( Label& L, bool emit_delayed_nop = true ); + // 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 );