diff options
Diffstat (limited to 'compiler/dex/quick/mips')
-rw-r--r-- | compiler/dex/quick/mips/call_mips.cc | 4 | ||||
-rw-r--r-- | compiler/dex/quick/mips/codegen_mips.h | 8 | ||||
-rw-r--r-- | compiler/dex/quick/mips/int_mips.cc | 8 | ||||
-rw-r--r-- | compiler/dex/quick/mips/utility_mips.cc | 52 |
4 files changed, 42 insertions, 30 deletions
diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc index e53105fc84..26ea6a8ec7 100644 --- a/compiler/dex/quick/mips/call_mips.cc +++ b/compiler/dex/quick/mips/call_mips.cc @@ -264,9 +264,9 @@ void MipsMir2Lir::GenMoveException(RegLocation rl_dest) { int ex_offset = Thread::ExceptionOffset<4>().Int32Value(); RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true); RegStorage reset_reg = AllocTempRef(); - LoadRefDisp(rs_rMIPS_SELF, ex_offset, rl_result.reg); + LoadRefDisp(rs_rMIPS_SELF, ex_offset, rl_result.reg, kNotVolatile); LoadConstant(reset_reg, 0); - StoreRefDisp(rs_rMIPS_SELF, ex_offset, reset_reg); + StoreRefDisp(rs_rMIPS_SELF, ex_offset, reset_reg, kNotVolatile); FreeTemp(reset_reg); StoreValue(rl_dest, rl_result); } diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h index 571adaccc1..c0ad9161f6 100644 --- a/compiler/dex/quick/mips/codegen_mips.h +++ b/compiler/dex/quick/mips/codegen_mips.h @@ -33,20 +33,16 @@ class MipsMir2Lir FINAL : public Mir2Lir { LIR* CheckSuspendUsingLoad() OVERRIDE; RegStorage LoadHelper(ThreadOffset<4> offset) OVERRIDE; RegStorage LoadHelper(ThreadOffset<8> offset) OVERRIDE; - LIR* LoadBaseDispVolatile(RegStorage r_base, int displacement, RegStorage r_dest, - OpSize size) OVERRIDE; LIR* LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest, - OpSize size) OVERRIDE; + OpSize size, VolatileKind is_volatile) OVERRIDE; LIR* LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale, OpSize size) OVERRIDE; LIR* LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement, RegStorage r_dest, OpSize size) OVERRIDE; LIR* LoadConstantNoClobber(RegStorage r_dest, int value); LIR* LoadConstantWide(RegStorage r_dest, int64_t value); - LIR* StoreBaseDispVolatile(RegStorage r_base, int displacement, RegStorage r_src, - OpSize size) OVERRIDE; LIR* StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src, - OpSize size) OVERRIDE; + OpSize size, VolatileKind is_volatile) OVERRIDE; LIR* StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale, OpSize size) OVERRIDE; LIR* StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, int displacement, diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc index beaf6bb8ea..903a7709ca 100644 --- a/compiler/dex/quick/mips/int_mips.cc +++ b/compiler/dex/quick/mips/int_mips.cc @@ -294,7 +294,7 @@ bool MipsMir2Lir::GenInlinedPeek(CallInfo* info, OpSize size) { RegLocation rl_address = LoadValue(rl_src_address, kCoreReg); RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true); DCHECK(size == kSignedByte); - LoadBaseDisp(rl_address.reg, 0, rl_result.reg, size); + LoadBaseDisp(rl_address.reg, 0, rl_result.reg, size, kNotVolatile); StoreValue(rl_dest, rl_result); return true; } @@ -310,7 +310,7 @@ bool MipsMir2Lir::GenInlinedPoke(CallInfo* info, OpSize size) { RegLocation rl_address = LoadValue(rl_src_address, kCoreReg); DCHECK(size == kSignedByte); RegLocation rl_value = LoadValue(rl_src_value, kCoreReg); - StoreBaseDisp(rl_address.reg, 0, rl_value.reg, size); + StoreBaseDisp(rl_address.reg, 0, rl_value.reg, size, kNotVolatile); return true; } @@ -524,7 +524,7 @@ void MipsMir2Lir::GenArrayGet(int opt_flags, OpSize size, RegLocation rl_array, GenArrayBoundsCheck(rl_index.reg, reg_len); FreeTemp(reg_len); } - LoadBaseDisp(reg_ptr, 0, rl_result.reg, size); + LoadBaseDisp(reg_ptr, 0, rl_result.reg, size, kNotVolatile); FreeTemp(reg_ptr); StoreValueWide(rl_dest, rl_result); @@ -602,7 +602,7 @@ void MipsMir2Lir::GenArrayPut(int opt_flags, OpSize size, RegLocation rl_array, FreeTemp(reg_len); } - StoreBaseDisp(reg_ptr, 0, rl_src.reg, size); + StoreBaseDisp(reg_ptr, 0, rl_src.reg, size, kNotVolatile); } else { rl_src = LoadValue(rl_src, reg_class); if (needs_range_check) { diff --git a/compiler/dex/quick/mips/utility_mips.cc b/compiler/dex/quick/mips/utility_mips.cc index 01b25f9291..b49f43617f 100644 --- a/compiler/dex/quick/mips/utility_mips.cc +++ b/compiler/dex/quick/mips/utility_mips.cc @@ -546,23 +546,31 @@ LIR* MipsMir2Lir::LoadBaseDispBody(RegStorage r_base, int displacement, RegStora return load; } -LIR* MipsMir2Lir::LoadBaseDispVolatile(RegStorage r_base, int displacement, RegStorage r_dest, - OpSize size) { - DCHECK(size != k64 && size != kDouble); - return LoadBaseDisp(r_base, displacement, r_dest, size); -} - LIR* MipsMir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest, - OpSize size) { + OpSize size, VolatileKind is_volatile) { + if (is_volatile == kVolatile) { + DCHECK(size != k64 && size != kDouble); + } + // TODO: base this on target. if (size == kWord) { size = k32; } + LIR* load; if (size == k64 || size == kDouble) { - return LoadBaseDispBody(r_base, displacement, r_dest.GetLow(), r_dest.GetHigh(), size); + load = LoadBaseDispBody(r_base, displacement, r_dest.GetLow(), r_dest.GetHigh(), size); } else { - return LoadBaseDispBody(r_base, displacement, r_dest, RegStorage::InvalidReg(), size); + load = LoadBaseDispBody(r_base, displacement, r_dest, RegStorage::InvalidReg(), size); } + + if (UNLIKELY(is_volatile == kVolatile)) { + // Without context sensitive analysis, we must issue the most conservative barriers. + // In this case, either a load or store may follow so we issue both barriers. + GenMemBarrier(kLoadLoad); + GenMemBarrier(kLoadStore); + } + + return load; } // FIXME: don't split r_dest into 2 containers. @@ -648,23 +656,31 @@ LIR* MipsMir2Lir::StoreBaseDispBody(RegStorage r_base, int displacement, return res; } -LIR* MipsMir2Lir::StoreBaseDispVolatile(RegStorage r_base, int displacement, RegStorage r_src, - OpSize size) { - DCHECK(size != k64 && size != kDouble); - return StoreBaseDisp(r_base, displacement, r_src, size); -} - LIR* MipsMir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src, - OpSize size) { + OpSize size, VolatileKind is_volatile) { + if (is_volatile == kVolatile) { + DCHECK(size != k64 && size != kDouble); + // There might have been a store before this volatile one so insert StoreStore barrier. + GenMemBarrier(kStoreStore); + } + // TODO: base this on target. if (size == kWord) { size = k32; } + LIR* store; if (size == k64 || size == kDouble) { - return StoreBaseDispBody(r_base, displacement, r_src.GetLow(), r_src.GetHigh(), size); + store = StoreBaseDispBody(r_base, displacement, r_src.GetLow(), r_src.GetHigh(), size); } else { - return StoreBaseDispBody(r_base, displacement, r_src, RegStorage::InvalidReg(), size); + store = StoreBaseDispBody(r_base, displacement, r_src, RegStorage::InvalidReg(), size); } + + if (UNLIKELY(is_volatile == kVolatile)) { + // A load might follow the volatile store so insert a StoreLoad barrier. + GenMemBarrier(kStoreLoad); + } + + return store; } LIR* MipsMir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) { |