< prev index next >
src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp
Print this page
rev 11926 : 8166140: C1: Possible integer overflow in LIRGenerator::generate_address on several platforms
Reviewed-by:
*** 155,203 ****
LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
int shift, int disp, BasicType type) {
assert(base->is_register(), "must be");
// Accumulate fixed displacements.
if (index->is_constant()) {
! disp += index->as_constant_ptr()->as_jint() << shift;
index = LIR_OprFact::illegalOpr;
}
if (index->is_register()) {
// Apply the shift and accumulate the displacement.
if (shift > 0) {
LIR_Opr tmp = new_pointer_register();
__ shift_left(index, shift, tmp);
index = tmp;
}
! if (disp != 0) {
LIR_Opr tmp = new_pointer_register();
! if (Assembler::is_simm16(disp)) {
! __ add(index, LIR_OprFact::intptrConst(disp), tmp);
index = tmp;
} else {
! __ move(LIR_OprFact::intptrConst(disp), tmp);
__ add(tmp, index, tmp);
index = tmp;
}
! disp = 0;
}
! } else if (!Assembler::is_simm16(disp)) {
// Index is illegal so replace it with the displacement loaded into a register.
index = new_pointer_register();
! __ move(LIR_OprFact::intptrConst(disp), index);
! disp = 0;
}
// At this point we either have base + index or base + displacement.
! if (disp == 0) {
return new LIR_Address(base, index, type);
} else {
! assert(Assembler::is_simm16(disp), "must be");
! return new LIR_Address(base, disp, type);
}
}
LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
--- 155,204 ----
LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
int shift, int disp, BasicType type) {
assert(base->is_register(), "must be");
+ intx large_disp = disp;
// Accumulate fixed displacements.
if (index->is_constant()) {
! large_disp += (intx)(index->as_constant_ptr()->as_jint()) << shift;
index = LIR_OprFact::illegalOpr;
}
if (index->is_register()) {
// Apply the shift and accumulate the displacement.
if (shift > 0) {
LIR_Opr tmp = new_pointer_register();
__ shift_left(index, shift, tmp);
index = tmp;
}
! if (large_disp != 0) {
LIR_Opr tmp = new_pointer_register();
! if (Assembler::is_simm16(large_disp)) {
! __ add(index, LIR_OprFact::intptrConst(large_disp), tmp);
index = tmp;
} else {
! __ move(LIR_OprFact::intptrConst(large_disp), tmp);
__ add(tmp, index, tmp);
index = tmp;
}
! large_disp = 0;
}
! } else if (!Assembler::is_simm16(large_disp)) {
// Index is illegal so replace it with the displacement loaded into a register.
index = new_pointer_register();
! __ move(LIR_OprFact::intptrConst(large_disp), index);
! large_disp = 0;
}
// At this point we either have base + index or base + displacement.
! if (large_disp == 0) {
return new LIR_Address(base, index, type);
} else {
! assert(Assembler::is_simm16(large_disp), "must be");
! return new LIR_Address(base, large_disp, type);
}
}
LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
< prev index next >