src/cpu/sparc/vm/assembler_sparc.cpp

changeset 1868
df736661d0c8
parent 1844
cff162798819
parent 1861
2338d41fbd81
child 1907
c18cbe5936b8
     1.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp	Mon May 10 14:58:38 2010 -0700
     1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Tue May 11 15:19:19 2010 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * Copyright 1997-2010 Sun Microsystems, Inc.  All Rights Reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -2333,6 +2333,18 @@
    1.11  #endif
    1.12  
    1.13  
    1.14 +void MacroAssembler::load_sized_value(Address src, Register dst,
    1.15 +                                      size_t size_in_bytes, bool is_signed) {
    1.16 +  switch (size_in_bytes) {
    1.17 +  case  8: ldx(src, dst); break;
    1.18 +  case  4: ld( src, dst); break;
    1.19 +  case  2: is_signed ? ldsh(src, dst) : lduh(src, dst); break;
    1.20 +  case  1: is_signed ? ldsb(src, dst) : ldub(src, dst); break;
    1.21 +  default: ShouldNotReachHere();
    1.22 +  }
    1.23 +}
    1.24 +
    1.25 +
    1.26  void MacroAssembler::float_cmp( bool is_float, int unordered_result,
    1.27                                  FloatRegister Fa, FloatRegister Fb,
    1.28                                  Register Rresult) {
    1.29 @@ -2625,40 +2637,103 @@
    1.30  }
    1.31  
    1.32  
    1.33 -void MacroAssembler::regcon_inc_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
    1.34 -  assert(dest.register_or_noreg() != G0, "lost side effect");
    1.35 -  if ((src.is_constant() && src.as_constant() == 0) ||
    1.36 -      (src.is_register() && src.as_register() == G0)) {
    1.37 -    // do nothing
    1.38 -  } else if (dest.is_register()) {
    1.39 -    add(dest.as_register(), ensure_simm13_or_reg(src, temp), dest.as_register());
    1.40 -  } else if (src.is_constant()) {
    1.41 -    intptr_t res = dest.as_constant() + src.as_constant();
    1.42 -    dest = RegisterOrConstant(res); // side effect seen by caller
    1.43 +RegisterOrConstant MacroAssembler::regcon_andn_ptr(RegisterOrConstant s1, RegisterOrConstant s2, RegisterOrConstant d, Register temp) {
    1.44 +  assert(d.register_or_noreg() != G0, "lost side effect");
    1.45 +  if ((s2.is_constant() && s2.as_constant() == 0) ||
    1.46 +      (s2.is_register() && s2.as_register() == G0)) {
    1.47 +    // Do nothing, just move value.
    1.48 +    if (s1.is_register()) {
    1.49 +      if (d.is_constant())  d = temp;
    1.50 +      mov(s1.as_register(), d.as_register());
    1.51 +      return d;
    1.52 +    } else {
    1.53 +      return s1;
    1.54 +    }
    1.55 +  }
    1.56 +
    1.57 +  if (s1.is_register()) {
    1.58 +    assert_different_registers(s1.as_register(), temp);
    1.59 +    if (d.is_constant())  d = temp;
    1.60 +    andn(s1.as_register(), ensure_simm13_or_reg(s2, temp), d.as_register());
    1.61 +    return d;
    1.62    } else {
    1.63 -    assert(temp != noreg, "cannot handle constant += register");
    1.64 -    add(src.as_register(), ensure_simm13_or_reg(dest, temp), temp);
    1.65 -    dest = RegisterOrConstant(temp); // side effect seen by caller
    1.66 +    if (s2.is_register()) {
    1.67 +      assert_different_registers(s2.as_register(), temp);
    1.68 +      if (d.is_constant())  d = temp;
    1.69 +      set(s1.as_constant(), temp);
    1.70 +      andn(temp, s2.as_register(), d.as_register());
    1.71 +      return d;
    1.72 +    } else {
    1.73 +      intptr_t res = s1.as_constant() & ~s2.as_constant();
    1.74 +      return res;
    1.75 +    }
    1.76    }
    1.77  }
    1.78  
    1.79 -void MacroAssembler::regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src, Register temp ) {
    1.80 -  assert(dest.register_or_noreg() != G0, "lost side effect");
    1.81 -  if (!is_simm13(src.constant_or_zero()))
    1.82 -    src = (src.as_constant() & 0xFF);
    1.83 -  if ((src.is_constant() && src.as_constant() == 0) ||
    1.84 -      (src.is_register() && src.as_register() == G0)) {
    1.85 -    // do nothing
    1.86 -  } else if (dest.is_register()) {
    1.87 -    sll_ptr(dest.as_register(), src, dest.as_register());
    1.88 -  } else if (src.is_constant()) {
    1.89 -    intptr_t res = dest.as_constant() << src.as_constant();
    1.90 -    dest = RegisterOrConstant(res); // side effect seen by caller
    1.91 +RegisterOrConstant MacroAssembler::regcon_inc_ptr(RegisterOrConstant s1, RegisterOrConstant s2, RegisterOrConstant d, Register temp) {
    1.92 +  assert(d.register_or_noreg() != G0, "lost side effect");
    1.93 +  if ((s2.is_constant() && s2.as_constant() == 0) ||
    1.94 +      (s2.is_register() && s2.as_register() == G0)) {
    1.95 +    // Do nothing, just move value.
    1.96 +    if (s1.is_register()) {
    1.97 +      if (d.is_constant())  d = temp;
    1.98 +      mov(s1.as_register(), d.as_register());
    1.99 +      return d;
   1.100 +    } else {
   1.101 +      return s1;
   1.102 +    }
   1.103 +  }
   1.104 +
   1.105 +  if (s1.is_register()) {
   1.106 +    assert_different_registers(s1.as_register(), temp);
   1.107 +    if (d.is_constant())  d = temp;
   1.108 +    add(s1.as_register(), ensure_simm13_or_reg(s2, temp), d.as_register());
   1.109 +    return d;
   1.110    } else {
   1.111 -    assert(temp != noreg, "cannot handle constant <<= register");
   1.112 -    set(dest.as_constant(), temp);
   1.113 -    sll_ptr(temp, src, temp);
   1.114 -    dest = RegisterOrConstant(temp); // side effect seen by caller
   1.115 +    if (s2.is_register()) {
   1.116 +      assert_different_registers(s2.as_register(), temp);
   1.117 +      if (d.is_constant())  d = temp;
   1.118 +      add(s2.as_register(), ensure_simm13_or_reg(s1, temp), d.as_register());
   1.119 +      return d;
   1.120 +    } else {
   1.121 +      intptr_t res = s1.as_constant() + s2.as_constant();
   1.122 +      return res;
   1.123 +    }
   1.124 +  }
   1.125 +}
   1.126 +
   1.127 +RegisterOrConstant MacroAssembler::regcon_sll_ptr(RegisterOrConstant s1, RegisterOrConstant s2, RegisterOrConstant d, Register temp) {
   1.128 +  assert(d.register_or_noreg() != G0, "lost side effect");
   1.129 +  if (!is_simm13(s2.constant_or_zero()))
   1.130 +    s2 = (s2.as_constant() & 0xFF);
   1.131 +  if ((s2.is_constant() && s2.as_constant() == 0) ||
   1.132 +      (s2.is_register() && s2.as_register() == G0)) {
   1.133 +    // Do nothing, just move value.
   1.134 +    if (s1.is_register()) {
   1.135 +      if (d.is_constant())  d = temp;
   1.136 +      mov(s1.as_register(), d.as_register());
   1.137 +      return d;
   1.138 +    } else {
   1.139 +      return s1;
   1.140 +    }
   1.141 +  }
   1.142 +
   1.143 +  if (s1.is_register()) {
   1.144 +    assert_different_registers(s1.as_register(), temp);
   1.145 +    if (d.is_constant())  d = temp;
   1.146 +    sll_ptr(s1.as_register(), ensure_simm13_or_reg(s2, temp), d.as_register());
   1.147 +    return d;
   1.148 +  } else {
   1.149 +    if (s2.is_register()) {
   1.150 +      assert_different_registers(s2.as_register(), temp);
   1.151 +      if (d.is_constant())  d = temp;
   1.152 +      set(s1.as_constant(), temp);
   1.153 +      sll_ptr(temp, s2.as_register(), d.as_register());
   1.154 +      return d;
   1.155 +    } else {
   1.156 +      intptr_t res = s1.as_constant() << s2.as_constant();
   1.157 +      return res;
   1.158 +    }
   1.159    }
   1.160  }
   1.161  
   1.162 @@ -2708,8 +2783,8 @@
   1.163  
   1.164    // Adjust recv_klass by scaled itable_index, so we can free itable_index.
   1.165    RegisterOrConstant itable_offset = itable_index;
   1.166 -  regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize));
   1.167 -  regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes());
   1.168 +  itable_offset = regcon_sll_ptr(itable_index, exact_log2(itableMethodEntry::size() * wordSize), itable_offset);
   1.169 +  itable_offset = regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes(), itable_offset);
   1.170    add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass);
   1.171  
   1.172    // for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
   1.173 @@ -2805,7 +2880,7 @@
   1.174  
   1.175    assert_different_registers(sub_klass, super_klass, temp_reg);
   1.176    if (super_check_offset.is_register()) {
   1.177 -    assert_different_registers(sub_klass, super_klass,
   1.178 +    assert_different_registers(sub_klass, super_klass, temp_reg,
   1.179                                 super_check_offset.as_register());
   1.180    } else if (must_load_sco) {
   1.181      assert(temp2_reg != noreg, "supply either a temp or a register offset");
   1.182 @@ -2855,6 +2930,8 @@
   1.183      // The super check offset is always positive...
   1.184      lduw(super_klass, sco_offset, temp2_reg);
   1.185      super_check_offset = RegisterOrConstant(temp2_reg);
   1.186 +    // super_check_offset is register.
   1.187 +    assert_different_registers(sub_klass, super_klass, temp_reg, super_check_offset.as_register());
   1.188    }
   1.189    ld_ptr(sub_klass, super_check_offset, temp_reg);
   1.190    cmp(super_klass, temp_reg);
   1.191 @@ -3014,11 +3091,10 @@
   1.192  }
   1.193  
   1.194  
   1.195 -
   1.196 -
   1.197  void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
   1.198                                                Register temp_reg,
   1.199                                                Label& wrong_method_type) {
   1.200 +  if (UseCompressedOops)  unimplemented("coop");  // field accesses must decode
   1.201    assert_different_registers(mtype_reg, mh_reg, temp_reg);
   1.202    // compare method type against that of the receiver
   1.203    RegisterOrConstant mhtype_offset = delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg);
   1.204 @@ -3029,10 +3105,33 @@
   1.205  }
   1.206  
   1.207  
   1.208 -void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) {
   1.209 +// A method handle has a "vmslots" field which gives the size of its
   1.210 +// argument list in JVM stack slots.  This field is either located directly
   1.211 +// in every method handle, or else is indirectly accessed through the
   1.212 +// method handle's MethodType.  This macro hides the distinction.
   1.213 +void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
   1.214 +                                                Register temp_reg) {
   1.215 +  assert_different_registers(vmslots_reg, mh_reg, temp_reg);
   1.216 +  if (UseCompressedOops)  unimplemented("coop");  // field accesses must decode
   1.217 +  // load mh.type.form.vmslots
   1.218 +  if (java_dyn_MethodHandle::vmslots_offset_in_bytes() != 0) {
   1.219 +    // hoist vmslots into every mh to avoid dependent load chain
   1.220 +    ld(    Address(mh_reg,    delayed_value(java_dyn_MethodHandle::vmslots_offset_in_bytes, temp_reg)),   vmslots_reg);
   1.221 +  } else {
   1.222 +    Register temp2_reg = vmslots_reg;
   1.223 +    ld_ptr(Address(mh_reg,    delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg)),      temp2_reg);
   1.224 +    ld_ptr(Address(temp2_reg, delayed_value(java_dyn_MethodType::form_offset_in_bytes, temp_reg)),        temp2_reg);
   1.225 +    ld(    Address(temp2_reg, delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
   1.226 +  }
   1.227 +}
   1.228 +
   1.229 +
   1.230 +void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg, bool emit_delayed_nop) {
   1.231    assert(mh_reg == G3_method_handle, "caller must put MH object in G3");
   1.232    assert_different_registers(mh_reg, temp_reg);
   1.233  
   1.234 +  if (UseCompressedOops)  unimplemented("coop");  // field accesses must decode
   1.235 +
   1.236    // pick out the interpreted side of the handler
   1.237    ld_ptr(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg);
   1.238  
   1.239 @@ -3043,17 +3142,18 @@
   1.240    // for the various stubs which take control at this point,
   1.241    // see MethodHandles::generate_method_handle_stub
   1.242  
   1.243 -  // (Can any caller use this delay slot?  If so, add an option for supression.)
   1.244 -  delayed()->nop();
   1.245 +  // Some callers can fill the delay slot.
   1.246 +  if (emit_delayed_nop) {
   1.247 +    delayed()->nop();
   1.248 +  }
   1.249  }
   1.250  
   1.251 +
   1.252  RegisterOrConstant MacroAssembler::argument_offset(RegisterOrConstant arg_slot,
   1.253                                                     int extra_slot_offset) {
   1.254    // cf. TemplateTable::prepare_invoke(), if (load_receiver).
   1.255 -  int stackElementSize = Interpreter::stackElementWords() * wordSize;
   1.256 -  int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0);
   1.257 -  int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1);
   1.258 -  assert(offset1 - offset == stackElementSize, "correct arithmetic");
   1.259 +  int stackElementSize = Interpreter::stackElementSize;
   1.260 +  int offset = extra_slot_offset * stackElementSize;
   1.261    if (arg_slot.is_constant()) {
   1.262      offset += arg_slot.as_constant() * stackElementSize;
   1.263      return offset;
   1.264 @@ -3067,6 +3167,11 @@
   1.265  }
   1.266  
   1.267  
   1.268 +Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
   1.269 +                                         int extra_slot_offset) {
   1.270 +  return Address(Gargs, argument_offset(arg_slot, extra_slot_offset));
   1.271 +}
   1.272 +
   1.273  
   1.274  void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
   1.275                                            Register temp_reg,

mercurial