@@ -1280,6 +1280,42 @@ inline intx byte_size(void* from, void* to) {
12801280 return (address)to - (address)from;
12811281}
12821282
1283+ #ifdef ASSERT
1284+ #define RHS_MASK_ASSERT (rhs_mask ) \
1285+ if (rhs_mask != 31 && rhs_mask != 63 ) { \
1286+ basic_fatal (" rhs_mask assertion failed." ); \
1287+ }
1288+ #else
1289+ #define RHS_MASK_ASSERT (rhs_mask )
1290+ #endif
1291+
1292+ // Provide integer shift operations with Java semantics. No overflow
1293+ // issues - left shifts simply discard shifted out bits. No undefined
1294+ // behavior for large or negative shift quantities; instead the actual
1295+ // shift distance is the argument modulo the lhs value's size in bits.
1296+ // No undefined or implementation defined behavior for shifting negative
1297+ // values; left shift discards bits, right shift sign extends. We use
1298+ // the same safe conversion technique as above for java_add and friends.
1299+ #define JAVA_INTEGER_SHIFT_OP (OP, NAME, TYPE, XTYPE ) \
1300+ inline TYPE NAME (TYPE lhs, jint rhs) { \
1301+ const uint rhs_mask = (sizeof (TYPE) * 8 ) - 1 ; \
1302+ RHS_MASK_ASSERT (rhs_mask) \
1303+ XTYPE xres = static_cast <XTYPE>(lhs); \
1304+ xres OP ## = (rhs & rhs_mask); \
1305+ return reinterpret_cast <TYPE&>(xres); \
1306+ }
1307+
1308+ JAVA_INTEGER_SHIFT_OP (<<, java_shift_left, jint, juint)
1309+ JAVA_INTEGER_SHIFT_OP(<<, java_shift_left, jlong, julong)
1310+ // For signed shift right, assume C++ implementation >> sign extends.
1311+ JAVA_INTEGER_SHIFT_OP(>>, java_shift_right, jint, jint)
1312+ JAVA_INTEGER_SHIFT_OP(>>, java_shift_right, jlong, jlong)
1313+ // For >>> use C++ unsigned >>.
1314+ JAVA_INTEGER_SHIFT_OP(>>, java_shift_right_unsigned, jint, juint)
1315+ JAVA_INTEGER_SHIFT_OP(>>, java_shift_right_unsigned, jlong, julong)
1316+
1317+ #undef JAVA_INTEGER_SHIFT_OP
1318+
12831319// ----------------------------------------------------------------------------------------------------
12841320// Avoid non-portable casts with these routines (DEPRECATED)
12851321
0 commit comments