1.1 --- a/src/cpu/sparc/vm/assembler_sparc.hpp Thu Jul 21 08:38:25 2011 -0700 1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Thu Jul 21 11:25:07 2011 -0700 1.3 @@ -761,7 +761,7 @@ 1.4 mwtos_opf = 0x119 1.5 }; 1.6 1.7 - enum RCondition { rc_z = 1, rc_lez = 2, rc_lz = 3, rc_nz = 5, rc_gz = 6, rc_gez = 7 }; 1.8 + enum RCondition { rc_z = 1, rc_lez = 2, rc_lz = 3, rc_nz = 5, rc_gz = 6, rc_gez = 7, rc_last = rc_gez }; 1.9 1.10 enum Condition { 1.11 // for FBfcc & FBPfcc instruction 1.12 @@ -866,9 +866,18 @@ 1.13 return is_simm(d, nbits + 2); 1.14 } 1.15 1.16 + address target_distance(Label& L) { 1.17 + // Assembler::target(L) should be called only when 1.18 + // a branch instruction is emitted since non-bound 1.19 + // labels record current pc() as a branch address. 1.20 + if (L.is_bound()) return target(L); 1.21 + // Return current address for non-bound labels. 1.22 + return pc(); 1.23 + } 1.24 + 1.25 // test if label is in simm16 range in words (wdisp16). 1.26 bool is_in_wdisp16_range(Label& L) { 1.27 - return is_in_wdisp_range(target(L), pc(), 16); 1.28 + return is_in_wdisp_range(target_distance(L), pc(), 16); 1.29 } 1.30 // test if the distance between two addresses fits in simm30 range in words 1.31 static bool is_in_wdisp30_range(address a, address b) { 1.32 @@ -975,6 +984,20 @@ 1.33 static int sx( int i) { return u_field(i, 12, 12); } // shift x=1 means 64-bit 1.34 static int opf( int x) { return u_field(x, 13, 5); } 1.35 1.36 + static bool is_cbcond( int x ) { 1.37 + return (VM_Version::has_cbcond() && (inv_cond(x) > rc_last) && 1.38 + inv_op(x) == branch_op && inv_op2(x) == bpr_op2); 1.39 + } 1.40 + static bool is_cxb( int x ) { 1.41 + assert(is_cbcond(x), "wrong instruction"); 1.42 + return (x & (1<<21)) != 0; 1.43 + } 1.44 + static int cond_cbcond( int x) { return u_field((((x & 8)<<1) + 8 + (x & 7)), 29, 25); } 1.45 + static int inv_cond_cbcond(int x) { 1.46 + assert(is_cbcond(x), "wrong instruction"); 1.47 + return inv_u_field(x, 27, 25) | (inv_u_field(x, 29, 29)<<3); 1.48 + } 1.49 + 1.50 static int opf_cc( CC c, bool useFloat ) { return u_field((useFloat ? 0 : 4) + c, 13, 11); } 1.51 static int mov_cc( CC c, bool useFloat ) { return u_field(useFloat ? 0 : 1, 18, 18) | u_field(c, 12, 11); } 1.52 1.53 @@ -1026,6 +1049,26 @@ 1.54 return r; 1.55 } 1.56 1.57 + // compute inverse of wdisp10 1.58 + static intptr_t inv_wdisp10(int x, intptr_t pos) { 1.59 + assert(is_cbcond(x), "wrong instruction"); 1.60 + int lo = inv_u_field(x, 12, 5); 1.61 + int hi = (x >> 19) & 3; 1.62 + if (hi >= 2) hi |= ~1; 1.63 + return (((hi << 8) | lo) << 2) + pos; 1.64 + } 1.65 + 1.66 + // word offset for cbcond, 8 bits at [B12,B5], 2 bits at [B20,B19] 1.67 + static int wdisp10(intptr_t x, intptr_t off) { 1.68 + assert(VM_Version::has_cbcond(), "This CPU does not have CBCOND instruction"); 1.69 + intptr_t xx = x - off; 1.70 + assert_signed_word_disp_range(xx, 10); 1.71 + int r = ( ( (xx >> 2 ) & ((1 << 8) - 1) ) << 5 ) 1.72 + | ( ( (xx >> (2+8)) & 3 ) << 19 ); 1.73 + // Have to fake cbcond instruction to pass assert in inv_wdisp10() 1.74 + assert(inv_wdisp10((r | op(branch_op) | cond_cbcond(rc_last+1) | op2(bpr_op2)), off) == x, "inverse is not inverse"); 1.75 + return r; 1.76 + } 1.77 1.78 // word displacement in low-order nbits bits 1.79 1.80 @@ -1138,6 +1181,24 @@ 1.81 #endif 1.82 } 1.83 1.84 + // cbcond instruction should not be generated one after an other 1.85 + bool cbcond_before() { 1.86 + if (offset() == 0) return false; // it is first instruction 1.87 + int x = *(int*)(intptr_t(pc()) - 4); // previous instruction 1.88 + return is_cbcond(x); 1.89 + } 1.90 + 1.91 + void no_cbcond_before() { 1.92 + assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond"); 1.93 + } 1.94 + 1.95 + bool use_cbcond(Label& L) { 1.96 + if (!UseCBCond || cbcond_before()) return false; 1.97 + intptr_t x = intptr_t(target_distance(L)) - intptr_t(pc()); 1.98 + assert( (x & 3) == 0, "not word aligned"); 1.99 + return is_simm(x, 12); 1.100 + } 1.101 + 1.102 public: 1.103 // Tells assembler you know that next instruction is delayed 1.104 Assembler* delayed() { 1.105 @@ -1181,10 +1242,11 @@ 1.106 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) ); } 1.107 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) ); } 1.108 1.109 + 1.110 // pp 136 1.111 1.112 - inline void bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none ); 1.113 - inline void bpr( RCondition c, bool a, Predict p, Register s1, Label& L); 1.114 + inline void bpr(RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none); 1.115 + inline void bpr(RCondition c, bool a, Predict p, Register s1, Label& L); 1.116 1.117 protected: // use MacroAssembler::br instead 1.118 1.119 @@ -1198,8 +1260,6 @@ 1.120 inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); 1.121 inline void fbp( Condition c, bool a, CC cc, Predict p, Label& L ); 1.122 1.123 - public: 1.124 - 1.125 // pp 144 1.126 1.127 inline void br( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none ); 1.128 @@ -1215,11 +1275,17 @@ 1.129 inline void cb( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none ); 1.130 inline void cb( Condition c, bool a, Label& L ); 1.131 1.132 + // compare and branch 1.133 + inline void cbcond(Condition c, CC cc, Register s1, Register s2, Label& L); 1.134 + inline void cbcond(Condition c, CC cc, Register s1, int simm5, Label& L); 1.135 + 1.136 // pp 149 1.137 1.138 inline void call( address d, relocInfo::relocType rt = relocInfo::runtime_call_type ); 1.139 inline void call( Label& L, relocInfo::relocType rt = relocInfo::runtime_call_type ); 1.140 1.141 + public: 1.142 + 1.143 // pp 150 1.144 1.145 // These instructions compare the contents of s2 with the contents of 1.146 @@ -1862,8 +1928,8 @@ 1.147 inline void fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); 1.148 inline void fb( Condition c, bool a, Predict p, Label& L ); 1.149 1.150 - // compares register with zero and branches (V9 and V8 instructions) 1.151 - void br_zero( Condition c, bool a, Predict p, Register s1, Label& L); 1.152 + // compares register with zero (32 bit) and branches (V9 and V8 instructions) 1.153 + void cmp_zero_and_br( Condition c, Register s1, Label& L, bool a = false, Predict p = pn ); 1.154 // Compares a pointer register with zero and branches on (not)null. 1.155 // Does a test & branch on 32-bit systems and a register-branch on 64-bit. 1.156 void br_null ( Register s1, bool a, Predict p, Label& L ); 1.157 @@ -1875,6 +1941,26 @@ 1.158 void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none ); 1.159 void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, Label& L); 1.160 1.161 + // 1.162 + // Compare registers and branch with nop in delay slot or cbcond without delay slot. 1.163 + // 1.164 + // ATTENTION: use these instructions with caution because cbcond instruction 1.165 + // has very short distance: 512 instructions (2Kbyte). 1.166 + 1.167 + // Compare integer (32 bit) values (icc only). 1.168 + void cmp_and_br_short(Register s1, Register s2, Condition c, Predict p, Label& L); 1.169 + void cmp_and_br_short(Register s1, int simm13a, Condition c, Predict p, Label& L); 1.170 + // Platform depending version for pointer compare (icc on !LP64 and xcc on LP64). 1.171 + void cmp_and_brx_short(Register s1, Register s2, Condition c, Predict p, Label& L); 1.172 + void cmp_and_brx_short(Register s1, int simm13a, Condition c, Predict p, Label& L); 1.173 + 1.174 + // Short branch version for compares a pointer pwith zero. 1.175 + void br_null_short ( Register s1, Predict p, Label& L ); 1.176 + void br_notnull_short( Register s1, Predict p, Label& L ); 1.177 + 1.178 + // unconditional short branch 1.179 + void ba_short(Label& L); 1.180 + 1.181 inline void bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); 1.182 inline void bp( Condition c, bool a, CC cc, Predict p, Label& L ); 1.183 1.184 @@ -1882,8 +1968,8 @@ 1.185 inline void brx( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); 1.186 inline void brx( Condition c, bool a, Predict p, Label& L ); 1.187 1.188 - // unconditional short branch 1.189 - inline void ba( bool a, Label& L ); 1.190 + // unconditional branch 1.191 + inline void ba( Label& L ); 1.192 1.193 // Branch that tests fp condition codes 1.194 inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); 1.195 @@ -2167,7 +2253,6 @@ 1.196 1.197 inline void stbool(Register d, const Address& a) { stb(d, a); } 1.198 inline void ldbool(const Address& a, Register d) { ldsb(a, d); } 1.199 - inline void tstbool( Register s ) { tst(s); } 1.200 inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); } 1.201 1.202 // klass oop manipulations if compressed 1.203 @@ -2469,8 +2554,7 @@ 1.204 Label* L_success, 1.205 Label* L_failure, 1.206 Label* L_slow_path, 1.207 - RegisterOrConstant super_check_offset = RegisterOrConstant(-1), 1.208 - Register instanceof_hack = noreg); 1.209 + RegisterOrConstant super_check_offset = RegisterOrConstant(-1)); 1.210 1.211 // The rest of the type check; must be wired to a corresponding fast path. 1.212 // It does not repeat the fast path logic, so don't use it standalone.