Mercurial > hg > graal-jvmci-8
diff src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @ 2089:037c727f35fb
7009231: C1: Incorrect CAS code for longs on SPARC 32bit
Summary: Fix CAS of longs on SPARC 32bit and cmove on SPARC 64bit.
Reviewed-by: kvn
author | iveresov |
---|---|
date | Mon, 27 Dec 2010 21:51:31 -0800 |
parents | 7601ab0e1e33 |
children | 55f868e91c3b |
line wrap: on
line diff
--- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Dec 22 02:02:53 2010 -0800 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Mon Dec 27 21:51:31 2010 -0800 @@ -1705,8 +1705,7 @@ } -void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) { - +void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) { Assembler::Condition acond; switch (condition) { case lir_cond_equal: acond = Assembler::equal; break; @@ -1737,7 +1736,12 @@ ShouldNotReachHere(); } Label skip; - __ br(acond, false, Assembler::pt, skip); +#ifdef _LP64 + if (type == T_INT) { + __ br(acond, false, Assembler::pt, skip); + } else +#endif + __ brx(acond, false, Assembler::pt, skip); // checks icc on 32bit and xcc on 64bit if (opr1->is_constant() && opr1->type() == T_INT) { Register dest = result->as_register(); if (Assembler::is_simm13(opr1->as_jint())) { @@ -2688,6 +2692,11 @@ #ifdef _LP64 __ mov(cmp_value_lo, t1); __ mov(new_value_lo, t2); + // perform the compare and swap operation + __ casx(addr, t1, t2); + // generate condition code - if the swap succeeded, t2 ("new value" reg) was + // overwritten with the original value in "addr" and will be equal to t1. + __ cmp(t1, t2); #else // move high and low halves of long values into single registers __ sllx(cmp_value_hi, 32, t1); // shift high half into temp reg @@ -2696,13 +2705,15 @@ __ sllx(new_value_hi, 32, t2); __ srl(new_value_lo, 0, new_value_lo); __ or3(t2, new_value_lo, t2); // t2 holds 64-bit value to swap -#endif // perform the compare and swap operation __ casx(addr, t1, t2); // generate condition code - if the swap succeeded, t2 ("new value" reg) was // overwritten with the original value in "addr" and will be equal to t1. - __ cmp(t1, t2); - + // Produce icc flag for 32bit. + __ sub(t1, t2, t2); + __ srlx(t2, 32, t1); + __ orcc(t2, t1, G0); +#endif } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) { Register addr = op->addr()->as_pointer_register(); Register cmp_value = op->cmp_value()->as_register();