--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Tue Mar 03 18:25:57 2009 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Mar 04 09:58:39 2009 -0800
@@ -153,6 +153,21 @@
times_8 = 3,
times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4)
};
+ static ScaleFactor times(int size) {
+ assert(size >= 1 && size <= 8 && is_power_of_2(size), "bad scale size");
+ if (size == 8) return times_8;
+ if (size == 4) return times_4;
+ if (size == 2) return times_2;
+ return times_1;
+ }
+ static int scale_size(ScaleFactor scale) {
+ assert(scale != no_scale, "");
+ assert(((1 << (int)times_1) == 1 &&
+ (1 << (int)times_2) == 2 &&
+ (1 << (int)times_4) == 4 &&
+ (1 << (int)times_8) == 8), "");
+ return (1 << (int)scale);
+ }
private:
Register _base;
@@ -197,6 +212,22 @@
"inconsistent address");
}
+ Address(Register base, RegisterConstant index, ScaleFactor scale = times_1, int disp = 0)
+ : _base (base),
+ _index(index.register_or_noreg()),
+ _scale(scale),
+ _disp (disp + (index.constant_or_zero() * scale_size(scale))) {
+ if (!index.is_register()) scale = Address::no_scale;
+ assert(!_index->is_valid() == (scale == Address::no_scale),
+ "inconsistent address");
+ }
+
+ Address plus_disp(int disp) const {
+ Address a = (*this);
+ a._disp += disp;
+ return a;
+ }
+
// The following two overloads are used in connection with the
// ByteSize type (see sizes.hpp). They simplify the use of
// ByteSize'd arguments in assembly code. Note that their equivalent
@@ -224,6 +255,17 @@
assert(!index->is_valid() == (scale == Address::no_scale),
"inconsistent address");
}
+
+ Address(Register base, RegisterConstant index, ScaleFactor scale, ByteSize disp)
+ : _base (base),
+ _index(index.register_or_noreg()),
+ _scale(scale),
+ _disp (in_bytes(disp) + (index.constant_or_zero() * scale_size(scale))) {
+ if (!index.is_register()) scale = Address::no_scale;
+ assert(!_index->is_valid() == (scale == Address::no_scale),
+ "inconsistent address");
+ }
+
#endif // ASSERT
// accessors
@@ -240,7 +282,6 @@
static Address make_array(ArrayAddress);
-
private:
bool base_needs_rex() const {
return _base != noreg && _base->encoding() >= 8;
@@ -1393,17 +1434,20 @@
// The following 4 methods return the offset of the appropriate move instruction
- // Support for fast byte/word loading with zero extension (depending on particular CPU)
+ // Support for fast byte/short loading with zero extension (depending on particular CPU)
int load_unsigned_byte(Register dst, Address src);
- int load_unsigned_word(Register dst, Address src);
-
- // Support for fast byte/word loading with sign extension (depending on particular CPU)
+ int load_unsigned_short(Register dst, Address src);
+
+ // Support for fast byte/short loading with sign extension (depending on particular CPU)
int load_signed_byte(Register dst, Address src);
- int load_signed_word(Register dst, Address src);
+ int load_signed_short(Register dst, Address src);
// Support for sign-extension (hi:lo = extend_sign(lo))
void extend_sign(Register hi, Register lo);
+ // Loading values by size and signed-ness
+ void load_sized_value(Register dst, Address src, int size_in_bytes, bool is_signed);
+
// Support for inc/dec with optimal instruction selection depending on value
void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; }
@@ -1763,6 +1807,10 @@
// stack overflow + shadow pages. Also, clobbers tmp
void bang_stack_size(Register size, Register tmp);
+ virtual RegisterConstant delayed_value(intptr_t* delayed_value_addr,
+ Register tmp,
+ int offset);
+
// Support for serializing memory accesses between threads
void serialize_memory(Register thread, Register tmp);