src/cpu/sparc/vm/assembler_sparc.hpp

changeset 3037
3d42f82cd811
parent 3001
faa472957b38
child 3049
95134e034042
     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.

mercurial