src/cpu/x86/vm/c1_LIRGenerator_x86.cpp

changeset 4106
7eca5de9e0b6
parent 4051
8a02ca5e5576
child 4159
8e47bac5643a
     1.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Sep 19 16:50:26 2012 -0700
     1.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Thu Sep 20 16:49:17 2012 +0200
     1.3 @@ -753,9 +753,24 @@
     1.4    LIR_Opr addr = new_pointer_register();
     1.5    LIR_Address* a;
     1.6    if(offset.result()->is_constant()) {
     1.7 +#ifdef _LP64
     1.8 +    jlong c = offset.result()->as_jlong();
     1.9 +    if ((jlong)((jint)c) == c) {
    1.10 +      a = new LIR_Address(obj.result(),
    1.11 +                          (jint)c,
    1.12 +                          as_BasicType(type));
    1.13 +    } else {
    1.14 +      LIR_Opr tmp = new_register(T_LONG);
    1.15 +      __ move(offset.result(), tmp);
    1.16 +      a = new LIR_Address(obj.result(),
    1.17 +                          tmp,
    1.18 +                          as_BasicType(type));
    1.19 +    }
    1.20 +#else
    1.21      a = new LIR_Address(obj.result(),
    1.22 -                        NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()),
    1.23 +                        offset.result()->as_jint(),
    1.24                          as_BasicType(type));
    1.25 +#endif
    1.26    } else {
    1.27      a = new LIR_Address(obj.result(),
    1.28                          offset.result(),
    1.29 @@ -1345,3 +1360,57 @@
    1.30      }
    1.31    }
    1.32  }
    1.33 +
    1.34 +void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
    1.35 +  BasicType type = x->basic_type();
    1.36 +  LIRItem src(x->object(), this);
    1.37 +  LIRItem off(x->offset(), this);
    1.38 +  LIRItem value(x->value(), this);
    1.39 +
    1.40 +  src.load_item();
    1.41 +  value.load_item();
    1.42 +  off.load_nonconstant();
    1.43 +
    1.44 +  LIR_Opr dst = rlock_result(x, type);
    1.45 +  LIR_Opr data = value.result();
    1.46 +  bool is_obj = (type == T_ARRAY || type == T_OBJECT);
    1.47 +  LIR_Opr offset = off.result();
    1.48 +
    1.49 +  assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type");
    1.50 +  LIR_Address* addr;
    1.51 +  if (offset->is_constant()) {
    1.52 +#ifdef _LP64
    1.53 +    jlong c = offset->as_jlong();
    1.54 +    if ((jlong)((jint)c) == c) {
    1.55 +      addr = new LIR_Address(src.result(), (jint)c, type);
    1.56 +    } else {
    1.57 +      LIR_Opr tmp = new_register(T_LONG);
    1.58 +      __ move(offset, tmp);
    1.59 +      addr = new LIR_Address(src.result(), tmp, type);
    1.60 +    }
    1.61 +#else
    1.62 +    addr = new LIR_Address(src.result(), offset->as_jint(), type);
    1.63 +#endif
    1.64 +  } else {
    1.65 +    addr = new LIR_Address(src.result(), offset, type);
    1.66 +  }
    1.67 +
    1.68 +  if (data != dst) {
    1.69 +    __ move(data, dst);
    1.70 +    data = dst;
    1.71 +  }
    1.72 +  if (x->is_add()) {
    1.73 +    __ xadd(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr);
    1.74 +  } else {
    1.75 +    if (is_obj) {
    1.76 +      // Do the pre-write barrier, if any.
    1.77 +      pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
    1.78 +                  true /* do_load */, false /* patch */, NULL);
    1.79 +    }
    1.80 +    __ xchg(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr);
    1.81 +    if (is_obj) {
    1.82 +      // Seems to be a precise address
    1.83 +      post_barrier(LIR_OprFact::address(addr), data);
    1.84 +    }
    1.85 +  }
    1.86 +}

mercurial