[aarch64-port-dev ] RFR: aarch64: 8133842: C2 generates illegal instructions with int shifts >=32
Edward Nevill
edward.nevill at gmail.com
Thu Aug 20 13:10:20 UTC 2015
On Thu, 2015-08-20 at 11:56 +0100, Andrew Haley wrote:
> Looks good for C2. OK if you already checked C1!
Yes. For my test case
res += i | (j >> 53);
C1 generates
0x000003ff90eb0d68: lsr w3, w1, #21
0x000003ff90eb0d6c: orr w3, w0, w3
0x000003ff90eb0d70: add w3, w3, w2
IE. It doesn't attempt to merge the shift and the or, and it masks the shift with 0x1f getting 21 instead of 53.
Below is the code in C1 that does it (from c1_LIRGenerator_aarch64.cpp). You can see it ands ints with 0x1f and longs with 0x3f.
All the best,
Ed.
--- cut here ---
if (right.is_constant()) {
right.dont_load_item();
switch (x->op()) {
case Bytecodes::_ishl: {
int c = right.get_jint_constant() & 0x1f;
__ shift_left(left.result(), c, x->operand());
break;
}
case Bytecodes::_ishr: {
int c = right.get_jint_constant() & 0x1f;
__ shift_right(left.result(), c, x->operand());
break;
}
case Bytecodes::_iushr: {
int c = right.get_jint_constant() & 0x1f;
__ unsigned_shift_right(left.result(), c, x->operand());
break;
}
case Bytecodes::_lshl: {
int c = right.get_jint_constant() & 0x3f;
__ shift_left(left.result(), c, x->operand());
break;
}
case Bytecodes::_lshr: {
int c = right.get_jint_constant() & 0x3f;
__ shift_right(left.result(), c, x->operand());
break;
}
case Bytecodes::_lushr: {
int c = right.get_jint_constant() & 0x3f;
__ unsigned_shift_right(left.result(), c, x->operand());
break;
}
default:
ShouldNotReachHere();
}
} else {
--- cut here ---
More information about the aarch64-port-dev
mailing list