aboutsummaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorkvn <none@none>2012-06-14 14:59:52 -0700
committerkvn <none@none>2012-06-14 14:59:52 -0700
commitd62195ef3f73f37d98d1b6dfbe12ed1fa5a51bc0 (patch)
tree33e42763f285bc4c6274e89f241cb391e6b20da6 /src/cpu
parent6224d2e10bd139f71b82460ec553f35ae9115e24 (diff)
parente446e836c7a64207585f58f3e9a0e4524791adca (diff)
Merge
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp32
-rw-r--r--src/cpu/sparc/vm/sparc.ad12
-rw-r--r--src/cpu/x86/vm/assembler_x86.cpp21
-rw-r--r--src/cpu/x86/vm/assembler_x86.hpp2
-rw-r--r--src/cpu/x86/vm/c1_LIRAssembler_x86.cpp2
-rw-r--r--src/cpu/x86/vm/c1_LIRGenerator_x86.cpp37
-rw-r--r--src/cpu/x86/vm/x86_32.ad56
-rw-r--r--src/cpu/x86/vm/x86_64.ad31
8 files changed, 52 insertions, 141 deletions
diff --git a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
index e432fedd6..7b1bf6f1c 100644
--- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
+++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
@@ -644,30 +644,6 @@ void LIRGenerator::do_CompareOp(CompareOp* x) {
}
-void LIRGenerator::do_AttemptUpdate(Intrinsic* x) {
- assert(x->number_of_arguments() == 3, "wrong type");
- LIRItem obj (x->argument_at(0), this); // AtomicLong object
- LIRItem cmp_value (x->argument_at(1), this); // value to compare with field
- LIRItem new_value (x->argument_at(2), this); // replace field with new_value if it matches cmp_value
-
- obj.load_item();
- cmp_value.load_item();
- new_value.load_item();
-
- // generate compare-and-swap and produce zero condition if swap occurs
- int value_offset = sun_misc_AtomicLongCSImpl::value_offset();
- LIR_Opr addr = FrameMap::O7_opr;
- __ add(obj.result(), LIR_OprFact::intConst(value_offset), addr);
- LIR_Opr t1 = FrameMap::G1_opr; // temp for 64-bit value
- LIR_Opr t2 = FrameMap::G3_opr; // temp for 64-bit value
- __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2);
-
- // generate conditional move of boolean result
- LIR_Opr result = rlock_result(x);
- __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result, T_LONG);
-}
-
-
void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
assert(x->number_of_arguments() == 4, "wrong type");
LIRItem obj (x->argument_at(0), this); // object
@@ -989,10 +965,10 @@ void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
if (!x->klass()->is_loaded() || PatchALot) {
patching_info = state_for(x, x->state_before());
- // cannot re-use same xhandlers for multiple CodeEmitInfos, so
- // clone all handlers. This is handled transparently in other
- // places by the CodeEmitInfo cloning logic but is handled
- // specially here because a stub isn't being used.
+ // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
+ // clone all handlers (NOTE: Usually this is handled transparently
+ // by the CodeEmitInfo cloning logic in CodeStub constructors but
+ // is done explicitly here because a stub isn't being used).
x->set_exception_handlers(new XHandlers(x->exception_handlers()));
}
CodeEmitInfo* info = state_for(x, x->state());
diff --git a/src/cpu/sparc/vm/sparc.ad b/src/cpu/sparc/vm/sparc.ad
index e4f868baf..43c9976bb 100644
--- a/src/cpu/sparc/vm/sparc.ad
+++ b/src/cpu/sparc/vm/sparc.ad
@@ -827,7 +827,6 @@ void emit_form3_mem_reg(CodeBuffer &cbuf, const MachNode* n, int primary, int te
// a Load
// inputs are (0:control, 1:memory, 2:address)
if (!(n->ideal_Opcode()==ld_op) && // Following are special cases
- !(n->ideal_Opcode()==Op_LoadLLocked && ld_op==Op_LoadI) &&
!(n->ideal_Opcode()==Op_LoadPLocked && ld_op==Op_LoadP) &&
!(n->ideal_Opcode()==Op_LoadI && ld_op==Op_LoadF) &&
!(n->ideal_Opcode()==Op_LoadF && ld_op==Op_LoadI) &&
@@ -7306,17 +7305,6 @@ instruct loadPLocked(iRegP dst, memory mem) %{
ins_pipe(iload_mem);
%}
-// LoadL-locked. Same as a regular long load when used with a compare-swap
-instruct loadLLocked(iRegL dst, memory mem) %{
- match(Set dst (LoadLLocked mem));
- ins_cost(MEMORY_REF_COST);
- size(4);
- format %{ "LDX $mem,$dst\t! long" %}
- opcode(Assembler::ldx_op3);
- ins_encode(simple_form3_mem_reg( mem, dst ) );
- ins_pipe(iload_mem);
-%}
-
instruct storePConditional( iRegP heap_top_ptr, iRegP oldval, g3RegP newval, flagsRegP pcc ) %{
match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
effect( KILL newval );
diff --git a/src/cpu/x86/vm/assembler_x86.cpp b/src/cpu/x86/vm/assembler_x86.cpp
index 4537a24e0..8409fd73e 100644
--- a/src/cpu/x86/vm/assembler_x86.cpp
+++ b/src/cpu/x86/vm/assembler_x86.cpp
@@ -6927,21 +6927,42 @@ void MacroAssembler::pow_exp_core_encoding() {
addptr(rsp,sizeof(jdouble));
}
+void MacroAssembler::increase_precision() {
+ subptr(rsp, BytesPerWord);
+ fnstcw(Address(rsp, 0));
+ movl(rax, Address(rsp, 0));
+ orl(rax, 0x300);
+ push(rax);
+ fldcw(Address(rsp, 0));
+ pop(rax);
+}
+
+void MacroAssembler::restore_precision() {
+ fldcw(Address(rsp, 0));
+ addptr(rsp, BytesPerWord);
+}
+
void MacroAssembler::fast_pow() {
// computes X^Y = 2^(Y * log2(X))
// if fast computation is not possible, result is NaN. Requires
// fallback from user of this macro.
+ // increase precision for intermediate steps of the computation
+ increase_precision();
fyl2x(); // Stack: (Y*log2(X)) ...
pow_exp_core_encoding(); // Stack: exp(X) ...
+ restore_precision();
}
void MacroAssembler::fast_exp() {
// computes exp(X) = 2^(X * log2(e))
// if fast computation is not possible, result is NaN. Requires
// fallback from user of this macro.
+ // increase precision for intermediate steps of the computation
+ increase_precision();
fldl2e(); // Stack: log2(e) X ...
fmulp(1); // Stack: (X*log2(e)) ...
pow_exp_core_encoding(); // Stack: exp(X) ...
+ restore_precision();
}
void MacroAssembler::pow_or_exp(bool is_exp, int num_fpu_regs_in_use) {
diff --git a/src/cpu/x86/vm/assembler_x86.hpp b/src/cpu/x86/vm/assembler_x86.hpp
index d0f1171f9..2e2fca033 100644
--- a/src/cpu/x86/vm/assembler_x86.hpp
+++ b/src/cpu/x86/vm/assembler_x86.hpp
@@ -2395,6 +2395,8 @@ class MacroAssembler: public Assembler {
// runtime call.
void fast_pow();
void fast_exp();
+ void increase_precision();
+ void restore_precision();
// computes exp(x). Fallback to runtime call included.
void exp_with_fallback(int num_fpu_regs_in_use) { pow_or_exp(true, num_fpu_regs_in_use); }
diff --git a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
index 764c9cff7..dedde0b6e 100644
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
@@ -2673,7 +2673,7 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2,
#endif // _LP64
}
} else {
- ShouldNotReachHere();
+ fatal(err_msg("unexpected type: %s", basictype_to_str(c->type())));
}
// cpu register - address
} else if (opr2->is_address()) {
diff --git a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
index 66d8ed0a8..deca1a0ed 100644
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
+++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
@@ -718,35 +718,6 @@ void LIRGenerator::do_CompareOp(CompareOp* x) {
}
-void LIRGenerator::do_AttemptUpdate(Intrinsic* x) {
- assert(x->number_of_arguments() == 3, "wrong type");
- LIRItem obj (x->argument_at(0), this); // AtomicLong object
- LIRItem cmp_value (x->argument_at(1), this); // value to compare with field
- LIRItem new_value (x->argument_at(2), this); // replace field with new_value if it matches cmp_value
-
- // compare value must be in rdx,eax (hi,lo); may be destroyed by cmpxchg8 instruction
- cmp_value.load_item_force(FrameMap::long0_opr);
-
- // new value must be in rcx,ebx (hi,lo)
- new_value.load_item_force(FrameMap::long1_opr);
-
- // object pointer register is overwritten with field address
- obj.load_item();
-
- // generate compare-and-swap; produces zero condition if swap occurs
- int value_offset = sun_misc_AtomicLongCSImpl::value_offset();
- LIR_Opr addr = new_pointer_register();
- __ leal(LIR_OprFact::address(new LIR_Address(obj.result(), value_offset, T_LONG)), addr);
- LIR_Opr t1 = LIR_OprFact::illegalOpr; // no temp needed
- LIR_Opr t2 = LIR_OprFact::illegalOpr; // no temp needed
- __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2);
-
- // generate conditional move of boolean result
- LIR_Opr result = rlock_result(x);
- __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result, T_LONG);
-}
-
-
void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
assert(x->number_of_arguments() == 4, "wrong type");
LIRItem obj (x->argument_at(0), this); // object
@@ -1116,10 +1087,10 @@ void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
if (!x->klass()->is_loaded() || PatchALot) {
patching_info = state_for(x, x->state_before());
- // cannot re-use same xhandlers for multiple CodeEmitInfos, so
- // clone all handlers. This is handled transparently in other
- // places by the CodeEmitInfo cloning logic but is handled
- // specially here because a stub isn't being used.
+ // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
+ // clone all handlers (NOTE: Usually this is handled transparently
+ // by the CodeEmitInfo cloning logic in CodeStub constructors but
+ // is done explicitly here because a stub isn't being used).
x->set_exception_handlers(new XHandlers(x->exception_handlers()));
}
CodeEmitInfo* info = state_for(x, x->state());
diff --git a/src/cpu/x86/vm/x86_32.ad b/src/cpu/x86/vm/x86_32.ad
index cd4adccd3..300903954 100644
--- a/src/cpu/x86/vm/x86_32.ad
+++ b/src/cpu/x86/vm/x86_32.ad
@@ -5555,8 +5555,9 @@ instruct bytes_reverse_long(eRegL dst) %{
ins_pipe( ialu_reg_reg);
%}
-instruct bytes_reverse_unsigned_short(eRegI dst) %{
+instruct bytes_reverse_unsigned_short(eRegI dst, eFlagsReg cr) %{
match(Set dst (ReverseBytesUS dst));
+ effect(KILL cr);
format %{ "BSWAP $dst\n\t"
"SHR $dst,16\n\t" %}
@@ -5567,8 +5568,9 @@ instruct bytes_reverse_unsigned_short(eRegI dst) %{
ins_pipe( ialu_reg );
%}
-instruct bytes_reverse_short(eRegI dst) %{
+instruct bytes_reverse_short(eRegI dst, eFlagsReg cr) %{
match(Set dst (ReverseBytesS dst));
+ effect(KILL cr);
format %{ "BSWAP $dst\n\t"
"SAR $dst,16\n\t" %}
@@ -5729,9 +5731,10 @@ instruct countTrailingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
//---------- Population Count Instructions -------------------------------------
-instruct popCountI(eRegI dst, eRegI src) %{
+instruct popCountI(eRegI dst, eRegI src, eFlagsReg cr) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountI src));
+ effect(KILL cr);
format %{ "POPCNT $dst, $src" %}
ins_encode %{
@@ -5740,9 +5743,10 @@ instruct popCountI(eRegI dst, eRegI src) %{
ins_pipe(ialu_reg);
%}
-instruct popCountI_mem(eRegI dst, memory mem) %{
+instruct popCountI_mem(eRegI dst, memory mem, eFlagsReg cr) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountI (LoadI mem)));
+ effect(KILL cr);
format %{ "POPCNT $dst, $mem" %}
ins_encode %{
@@ -7796,50 +7800,6 @@ instruct loadPLocked(eRegP dst, memory mem) %{
ins_pipe( ialu_reg_mem );
%}
-// LoadLong-locked - same as a volatile long load when used with compare-swap
-instruct loadLLocked(stackSlotL dst, memory mem) %{
- predicate(UseSSE<=1);
- match(Set dst (LoadLLocked mem));
-
- ins_cost(200);
- format %{ "FILD $mem\t# Atomic volatile long load\n\t"
- "FISTp $dst" %}
- ins_encode(enc_loadL_volatile(mem,dst));
- ins_pipe( fpu_reg_mem );
-%}
-
-instruct loadLX_Locked(stackSlotL dst, memory mem, regD tmp) %{
- predicate(UseSSE>=2);
- match(Set dst (LoadLLocked mem));
- effect(TEMP tmp);
- ins_cost(180);
- format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
- "MOVSD $dst,$tmp" %}
- ins_encode %{
- __ movdbl($tmp$$XMMRegister, $mem$$Address);
- __ movdbl(Address(rsp, $dst$$disp), $tmp$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct loadLX_reg_Locked(eRegL dst, memory mem, regD tmp) %{
- predicate(UseSSE>=2);
- match(Set dst (LoadLLocked mem));
- effect(TEMP tmp);
- ins_cost(160);
- format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
- "MOVD $dst.lo,$tmp\n\t"
- "PSRLQ $tmp,32\n\t"
- "MOVD $dst.hi,$tmp" %}
- ins_encode %{
- __ movdbl($tmp$$XMMRegister, $mem$$Address);
- __ movdl($dst$$Register, $tmp$$XMMRegister);
- __ psrlq($tmp$$XMMRegister, 32);
- __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
diff --git a/src/cpu/x86/vm/x86_64.ad b/src/cpu/x86/vm/x86_64.ad
index 80928c3fa..1a5e1c86c 100644
--- a/src/cpu/x86/vm/x86_64.ad
+++ b/src/cpu/x86/vm/x86_64.ad
@@ -6417,14 +6417,14 @@ instruct bytes_reverse_long(rRegL dst) %{
match(Set dst (ReverseBytesL dst));
format %{ "bswapq $dst" %}
-
opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
ins_pipe( ialu_reg);
%}
-instruct bytes_reverse_unsigned_short(rRegI dst) %{
+instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{
match(Set dst (ReverseBytesUS dst));
+ effect(KILL cr);
format %{ "bswapl $dst\n\t"
"shrl $dst,16\n\t" %}
@@ -6435,8 +6435,9 @@ instruct bytes_reverse_unsigned_short(rRegI dst) %{
ins_pipe( ialu_reg );
%}
-instruct bytes_reverse_short(rRegI dst) %{
+instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{
match(Set dst (ReverseBytesS dst));
+ effect(KILL cr);
format %{ "bswapl $dst\n\t"
"sar $dst,16\n\t" %}
@@ -6564,9 +6565,10 @@ instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
//---------- Population Count Instructions -------------------------------------
-instruct popCountI(rRegI dst, rRegI src) %{
+instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountI src));
+ effect(KILL cr);
format %{ "popcnt $dst, $src" %}
ins_encode %{
@@ -6575,9 +6577,10 @@ instruct popCountI(rRegI dst, rRegI src) %{
ins_pipe(ialu_reg);
%}
-instruct popCountI_mem(rRegI dst, memory mem) %{
+instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountI (LoadI mem)));
+ effect(KILL cr);
format %{ "popcnt $dst, $mem" %}
ins_encode %{
@@ -6587,9 +6590,10 @@ instruct popCountI_mem(rRegI dst, memory mem) %{
%}
// Note: Long.bitCount(long) returns an int.
-instruct popCountL(rRegI dst, rRegL src) %{
+instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountL src));
+ effect(KILL cr);
format %{ "popcnt $dst, $src" %}
ins_encode %{
@@ -6599,9 +6603,10 @@ instruct popCountL(rRegI dst, rRegL src) %{
%}
// Note: Long.bitCount(long) returns an int.
-instruct popCountL_mem(rRegI dst, memory mem) %{
+instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{
predicate(UsePopCountInstruction);
match(Set dst (PopCountL (LoadL mem)));
+ effect(KILL cr);
format %{ "popcnt $dst, $mem" %}
ins_encode %{
@@ -7492,18 +7497,6 @@ instruct loadPLocked(rRegP dst, memory mem)
ins_pipe(ialu_reg_mem); // XXX
%}
-// LoadL-locked - same as a regular LoadL when used with compare-swap
-instruct loadLLocked(rRegL dst, memory mem)
-%{
- match(Set dst (LoadLLocked mem));
-
- ins_cost(125); // XXX
- format %{ "movq $dst, $mem\t# long locked" %}
- opcode(0x8B);
- ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
- ins_pipe(ialu_reg_mem); // XXX
-%}
-
// Conditional-store of the updated heap-top.
// Used during allocation of the shared heap.
// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.