Ensure art::HRor support boolean, byte, short and char inputs.
Also extend tests covering the IntegerRotateLeft,
LongRotateLeft, IntegerRotateRight and LongRotateRight
intrinsics and their translation into an art::HRor
instruction.
Bug: 27682579
Change-Id: I89f6ea6a7315659a172482bf09875cfb7e7422a1
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 34fd9ff..c164f2b 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -3273,7 +3273,8 @@
__ Bind(&end);
}
}
-void LocationsBuilderARM::HandleRotate(HRor* ror) {
+
+void LocationsBuilderARM::VisitRor(HRor* ror) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(ror, LocationSummary::kNoCall);
switch (ror->GetResultType()) {
@@ -3300,7 +3301,7 @@
}
}
-void InstructionCodeGeneratorARM::HandleRotate(HRor* ror) {
+void InstructionCodeGeneratorARM::VisitRor(HRor* ror) {
LocationSummary* locations = ror->GetLocations();
Primitive::Type type = ror->GetResultType();
switch (type) {
@@ -3318,14 +3319,6 @@
}
}
-void LocationsBuilderARM::VisitRor(HRor* op) {
- HandleRotate(op);
-}
-
-void InstructionCodeGeneratorARM::VisitRor(HRor* op) {
- HandleRotate(op);
-}
-
void LocationsBuilderARM::HandleShift(HBinaryOperation* op) {
DCHECK(op->IsShl() || op->IsShr() || op->IsUShr());
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index 5c0f31c..cc4aa14 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -174,7 +174,6 @@
void HandleCondition(HCondition* condition);
void HandleIntegerRotate(LocationSummary* locations);
void HandleLongRotate(LocationSummary* locations);
- void HandleRotate(HRor* ror);
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
@@ -222,7 +221,6 @@
void HandleCondition(HCondition* condition);
void HandleIntegerRotate(LocationSummary* locations);
void HandleLongRotate(LocationSummary* locations);
- void HandleRotate(HRor* ror);
void HandleShift(HBinaryOperation* operation);
void GenerateWideAtomicStore(Register addr, uint32_t offset,
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 9acaa1d..68c10d4 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -3981,8 +3981,7 @@
__ cmovl(kNotEqual, first_reg_hi, first_reg_lo);
__ cmovl(kNotEqual, first_reg_lo, temp_reg);
} else {
- int32_t shift_amt =
- CodeGenerator::GetInt64ValueOf(second.GetConstant()) & kMaxLongShiftValue;
+ int32_t shift_amt = CodeGenerator::GetInt64ValueOf(second.GetConstant()) & kMaxLongShiftValue;
if (shift_amt == 0) {
// Already fine.
return;
diff --git a/compiler/optimizing/common_arm64.h b/compiler/optimizing/common_arm64.h
index 10d8343..6c55194 100644
--- a/compiler/optimizing/common_arm64.h
+++ b/compiler/optimizing/common_arm64.h
@@ -194,7 +194,8 @@
}
static bool CanEncodeConstantAsImmediate(HConstant* constant, HInstruction* instr) {
- DCHECK(constant->IsIntConstant() || constant->IsLongConstant() || constant->IsNullConstant());
+ DCHECK(constant->IsIntConstant() || constant->IsLongConstant() || constant->IsNullConstant())
+ << constant->DebugName();
// For single uses we let VIXL handle the constant generation since it will
// use registers that are not managed by the register allocator (wip0, wip1).
@@ -221,7 +222,8 @@
instr->IsBoundsCheck() ||
instr->IsCompare() ||
instr->IsCondition() ||
- instr->IsSub());
+ instr->IsSub())
+ << instr->DebugName();
// Uses aliases of ADD/SUB instructions.
// If `value` does not fit but `-value` does, VIXL will automatically use
// the 'opposite' instruction.
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 1fbb2d5..11e3689 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -945,7 +945,7 @@
Primitive::PrettyDescriptor(result_type)));
}
} else {
- // Use the first input, so that we can also make this check for shift operations.
+ // Use the first input, so that we can also make this check for shift and rotate operations.
if (Primitive::PrimitiveKind(result_type) != Primitive::PrimitiveKind(lhs_type)) {
AddError(StringPrintf("Binary operation %s %d has a result kind different "
"from its input kind: %s vs %s.",
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index dd2977f..4a8186a 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -96,7 +96,7 @@
bool CanEnsureNotNullAt(HInstruction* instr, HInstruction* at) const;
- void SimplifyRotate(HInvoke* invoke, bool is_left);
+ void SimplifyRotate(HInvoke* invoke, bool is_left, Primitive::Type type);
void SimplifySystemArrayCopy(HInvoke* invoke);
void SimplifyStringEquals(HInvoke* invoke);
void SimplifyCompare(HInvoke* invoke, bool is_signum, Primitive::Type type);
@@ -262,10 +262,8 @@
bool InstructionSimplifierVisitor::ReplaceRotateWithRor(HBinaryOperation* op,
HUShr* ushr,
HShl* shl) {
- DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
- HRor* ror = new (GetGraph()->GetArena()) HRor(ushr->GetType(),
- ushr->GetLeft(),
- ushr->GetRight());
+ DCHECK(op->IsAdd() || op->IsXor() || op->IsOr()) << op->DebugName();
+ HRor* ror = new (GetGraph()->GetArena()) HRor(ushr->GetType(), ushr->GetLeft(), ushr->GetRight());
op->GetBlock()->ReplaceAndRemoveInstructionWith(op, ror);
if (!ushr->HasUses()) {
ushr->GetBlock()->RemoveInstruction(ushr);
@@ -1232,7 +1230,7 @@
// with
// SHL dst, src, log2(pow_of_2)
HIntConstant* shift = GetGraph()->GetIntConstant(WhichPowerOf2(factor));
- HShl* shl = new(allocator) HShl(type, input_other, shift);
+ HShl* shl = new (allocator) HShl(type, input_other, shift);
block->ReplaceAndRemoveInstructionWith(instruction, shl);
RecordSimplification();
} else if (IsPowerOfTwo(factor - 1)) {
@@ -1531,7 +1529,9 @@
}
}
-void InstructionSimplifierVisitor::SimplifyRotate(HInvoke* invoke, bool is_left) {
+void InstructionSimplifierVisitor::SimplifyRotate(HInvoke* invoke,
+ bool is_left,
+ Primitive::Type type) {
DCHECK(invoke->IsInvokeStaticOrDirect());
DCHECK_EQ(invoke->GetOriginalInvokeType(), InvokeType::kStatic);
HInstruction* value = invoke->InputAt(0);
@@ -1541,7 +1541,7 @@
distance = new (GetGraph()->GetArena()) HNeg(distance->GetType(), distance);
invoke->GetBlock()->InsertInstructionBefore(distance, invoke);
}
- HRor* ror = new (GetGraph()->GetArena()) HRor(value->GetType(), value, distance);
+ HRor* ror = new (GetGraph()->GetArena()) HRor(type, value, distance);
invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, ror);
// Remove ClinitCheck and LoadClass, if possible.
HInstruction* clinit = invoke->InputAt(invoke->InputCount() - 1);
@@ -1694,12 +1694,16 @@
SimplifySystemArrayCopy(instruction);
break;
case Intrinsics::kIntegerRotateRight:
+ SimplifyRotate(instruction, /* is_left */ false, Primitive::kPrimInt);
+ break;
case Intrinsics::kLongRotateRight:
- SimplifyRotate(instruction, false);
+ SimplifyRotate(instruction, /* is_left */ false, Primitive::kPrimLong);
break;
case Intrinsics::kIntegerRotateLeft:
+ SimplifyRotate(instruction, /* is_left */ true, Primitive::kPrimInt);
+ break;
case Intrinsics::kLongRotateLeft:
- SimplifyRotate(instruction, true);
+ SimplifyRotate(instruction, /* is_left */ true, Primitive::kPrimLong);
break;
case Intrinsics::kIntegerCompare:
SimplifyCompare(instruction, /* is_signum */ false, Primitive::kPrimInt);
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index e2a54f4..46377ee 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -4689,7 +4689,12 @@
class HRor : public HBinaryOperation {
public:
HRor(Primitive::Type result_type, HInstruction* value, HInstruction* distance)
- : HBinaryOperation(result_type, value, distance) {}
+ : HBinaryOperation(result_type, value, distance) {
+ if (kIsDebugBuild) {
+ DCHECK_EQ(result_type, Primitive::PrimitiveKind(value->GetType()));
+ DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(distance->GetType()));
+ }
+ }
template <typename T, typename U, typename V>
T Compute(T x, U y, V max_shift_value) const {
diff --git a/test/565-checker-rotate/src/Main.java b/test/565-checker-rotate/src/Main.java
index 33bbe02..d7f57d8 100644
--- a/test/565-checker-rotate/src/Main.java
+++ b/test/565-checker-rotate/src/Main.java
@@ -16,112 +16,534 @@
public class Main {
- /// CHECK-START: int Main.rotateLeft32(int, int) intrinsics_recognition (after)
- /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateLeft
- /// CHECK-DAG: Return [<<Result>>]
- private static int rotateLeft32(int x, int y) {
- return Integer.rotateLeft(x, y);
+ /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:z\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<One:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Val:i\d+>> Phi [<<One>>,<<Zero>>]
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Val>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:z\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<One:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Val:i\d+>> Phi [<<One>>,<<Zero>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<Val>>,<<NegDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) select_generator (after)
+ /// CHECK: <<ArgVal:z\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<One:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<SelVal:i\d+>> Select [<<Zero>>,<<One>>,<<ArgVal>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<SelVal>>,<<NegDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) select_generator (after)
+ /// CHECK-NOT: Phi
+
+ /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) instruction_simplifier_after_bce (after)
+ /// CHECK: <<ArgVal:z\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftBoolean(boolean, int) instruction_simplifier_after_bce (after)
+ /// CHECK-NOT: Select
+
+ private static int rotateLeftBoolean(boolean value, int distance) {
+ return Integer.rotateLeft(value ? 1 : 0, distance);
}
- /// CHECK-START: long Main.rotateLeft64(long, int) intrinsics_recognition (after)
- /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateLeft
- /// CHECK-DAG: Return [<<Result>>]
- private static long rotateLeft64(long x, int y) {
- return Long.rotateLeft(x, y);
+ /// CHECK-START: int Main.rotateLeftByte(byte, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:b\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftByte(byte, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:b\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftByte(byte, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static int rotateLeftByte(byte value, int distance) {
+ return Integer.rotateLeft(value, distance);
}
- /// CHECK-START: int Main.rotateRight32(int, int) intrinsics_recognition (after)
- /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:IntegerRotateRight
- /// CHECK-DAG: Return [<<Result>>]
- private static int rotateRight32(int x, int y) {
- return Integer.rotateRight(x, y);
+ /// CHECK-START: int Main.rotateLeftShort(short, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:s\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftShort(short, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:s\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftShort(short, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static int rotateLeftShort(short value, int distance) {
+ return Integer.rotateLeft(value, distance);
}
- /// CHECK-START: long Main.rotateRight64(long, int) intrinsics_recognition (after)
- /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect intrinsic:LongRotateRight
- /// CHECK-DAG: Return [<<Result>>]
- private static long rotateRight64(long x, int y) {
- return Long.rotateRight(x, y);
+ /// CHECK-START: int Main.rotateLeftChar(char, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:c\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftChar(char, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:c\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftChar(char, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static int rotateLeftChar(char value, int distance) {
+ return Integer.rotateLeft(value, distance);
}
+ /// CHECK-START: int Main.rotateLeftInt(int, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:i\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateLeft
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftInt(int, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:i\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateLeftInt(int, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static int rotateLeftInt(int value, int distance) {
+ return Integer.rotateLeft(value, distance);
+ }
+
+ /// CHECK-START: long Main.rotateLeftLong(long, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:j\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:LongRotateLeft
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: long Main.rotateLeftLong(long, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:j\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:j\d+>> Ror [<<ArgVal>>,<<NegDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: long Main.rotateLeftLong(long, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static long rotateLeftLong(long value, int distance) {
+ return Long.rotateLeft(value, distance);
+ }
+
+
+ /// CHECK-START: int Main.rotateRightBoolean(boolean, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:z\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<One:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Val:i\d+>> Phi [<<One>>,<<Zero>>]
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Val>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightBoolean(boolean, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:z\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<One:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Val:i\d+>> Phi [<<One>>,<<Zero>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<Val>>,<<ArgDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightBoolean(boolean, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ /// CHECK-START: int Main.rotateRightBoolean(boolean, int) select_generator (after)
+ /// CHECK: <<ArgVal:z\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<One:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<SelVal:i\d+>> Select [<<Zero>>,<<One>>,<<ArgVal>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<SelVal>>,<<ArgDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightBoolean(boolean, int) select_generator (after)
+ /// CHECK-NOT: Phi
+
+ /// CHECK-START: int Main.rotateRightBoolean(boolean, int) instruction_simplifier_after_bce (after)
+ /// CHECK: <<ArgVal:z\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightBoolean(boolean, int) instruction_simplifier_after_bce (after)
+ /// CHECK-NOT: Select
+
+ private static int rotateRightBoolean(boolean value, int distance) {
+ return Integer.rotateRight(value ? 1 : 0, distance);
+ }
+
+ /// CHECK-START: int Main.rotateRightByte(byte, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:b\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightByte(byte, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:b\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightByte(byte, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static int rotateRightByte(byte value, int distance) {
+ return Integer.rotateRight(value, distance);
+ }
+
+ /// CHECK-START: int Main.rotateRightShort(short, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:s\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightShort(short, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:s\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightShort(short, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static int rotateRightShort(short value, int distance) {
+ return Integer.rotateRight(value, distance);
+ }
+
+ /// CHECK-START: int Main.rotateRightChar(char, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:c\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightChar(char, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:c\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightChar(char, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static int rotateRightChar(char value, int distance) {
+ return Integer.rotateRight(value, distance);
+ }
+
+ /// CHECK-START: int Main.rotateRightInt(int, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:i\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:IntegerRotateRight
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightInt(int, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:i\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: int Main.rotateRightInt(int, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static int rotateRightInt(int value, int distance) {
+ return Integer.rotateRight(value, distance);
+ }
+
+ /// CHECK-START: long Main.rotateRightLong(long, int) intrinsics_recognition (after)
+ /// CHECK-DAG: <<Method:[ij]\d+>> CurrentMethod
+ /// CHECK: <<ArgVal:j\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect [<<ArgVal>>,<<ArgDist>>,<<Method>>] intrinsic:LongRotateRight
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: long Main.rotateRightLong(long, int) instruction_simplifier (after)
+ /// CHECK: <<ArgVal:j\d+>> ParameterValue
+ /// CHECK: <<ArgDist:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:j\d+>> Ror [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: Return [<<Result>>]
+
+ /// CHECK-START: long Main.rotateRightLong(long, int) instruction_simplifier (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ private static long rotateRightLong(long value, int distance) {
+ return Long.rotateRight(value, distance);
+ }
+
+
+ public static void testRotateLeftBoolean() {
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0, rotateLeftBoolean(false, i));
+ expectEqualsInt(1 << i, rotateLeftBoolean(true, i));
+ }
+ }
+
+ public static void testRotateLeftByte() {
+ expectEqualsInt(0x00000001, rotateLeftByte((byte)0x01, 0));
+ expectEqualsInt(0x00000002, rotateLeftByte((byte)0x01, 1));
+ expectEqualsInt(0x80000000, rotateLeftByte((byte)0x01, 31));
+ expectEqualsInt(0x00000001, rotateLeftByte((byte)0x01, 32)); // overshoot
+ expectEqualsInt(0xFFFFFF03, rotateLeftByte((byte)0x81, 1));
+ expectEqualsInt(0xFFFFFE07, rotateLeftByte((byte)0x81, 2));
+ expectEqualsInt(0x00000120, rotateLeftByte((byte)0x12, 4));
+ expectEqualsInt(0xFFFF9AFF, rotateLeftByte((byte)0x9A, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0x00000000, rotateLeftByte((byte)0x0000, i));
+ expectEqualsInt(0xFFFFFFFF, rotateLeftByte((byte)0xFFFF, i));
+ expectEqualsInt((1 << j), rotateLeftByte((byte)0x0001, i));
+ expectEqualsInt((0x12 << j) | (0x12 >>> -j), rotateLeftByte((byte)0x12, i));
+ }
+ }
+
+ public static void testRotateLeftShort() {
+ expectEqualsInt(0x00000001, rotateLeftShort((short)0x0001, 0));
+ expectEqualsInt(0x00000002, rotateLeftShort((short)0x0001, 1));
+ expectEqualsInt(0x80000000, rotateLeftShort((short)0x0001, 31));
+ expectEqualsInt(0x00000001, rotateLeftShort((short)0x0001, 32)); // overshoot
+ expectEqualsInt(0xFFFF0003, rotateLeftShort((short)0x8001, 1));
+ expectEqualsInt(0xFFFE0007, rotateLeftShort((short)0x8001, 2));
+ expectEqualsInt(0x00012340, rotateLeftShort((short)0x1234, 4));
+ expectEqualsInt(0xFF9ABCFF, rotateLeftShort((short)0x9ABC, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0x00000000, rotateLeftShort((short)0x0000, i));
+ expectEqualsInt(0xFFFFFFFF, rotateLeftShort((short)0xFFFF, i));
+ expectEqualsInt((1 << j), rotateLeftShort((short)0x0001, i));
+ expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), rotateLeftShort((short)0x1234, i));
+ }
+ }
+
+ public static void testRotateLeftChar() {
+ expectEqualsInt(0x00000001, rotateLeftChar((char)0x0001, 0));
+ expectEqualsInt(0x00000002, rotateLeftChar((char)0x0001, 1));
+ expectEqualsInt(0x80000000, rotateLeftChar((char)0x0001, 31));
+ expectEqualsInt(0x00000001, rotateLeftChar((char)0x0001, 32)); // overshoot
+ expectEqualsInt(0x00010002, rotateLeftChar((char)0x8001, 1));
+ expectEqualsInt(0x00020004, rotateLeftChar((char)0x8001, 2));
+ expectEqualsInt(0x00012340, rotateLeftChar((char)0x1234, 4));
+ expectEqualsInt(0x009ABC00, rotateLeftChar((char)0x9ABC, 8));
+ expectEqualsInt(0x00FF0000, rotateLeftChar((char)0xFF00, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0x00000000, rotateLeftChar((char)0x0000, i));
+ expectEqualsInt((1 << j), rotateLeftChar((char)0x0001, i));
+ expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), rotateLeftChar((char)0x1234, i));
+ }
+ }
+
+ public static void testRotateLeftInt() {
+ expectEqualsInt(0x00000001, rotateLeftInt(0x00000001, 0));
+ expectEqualsInt(0x00000002, rotateLeftInt(0x00000001, 1));
+ expectEqualsInt(0x80000000, rotateLeftInt(0x00000001, 31));
+ expectEqualsInt(0x00000001, rotateLeftInt(0x00000001, 32)); // overshoot
+ expectEqualsInt(0x00000003, rotateLeftInt(0x80000001, 1));
+ expectEqualsInt(0x00000006, rotateLeftInt(0x80000001, 2));
+ expectEqualsInt(0x23456781, rotateLeftInt(0x12345678, 4));
+ expectEqualsInt(0xBCDEF09A, rotateLeftInt(0x9ABCDEF0, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0x00000000, rotateLeftInt(0x00000000, i));
+ expectEqualsInt(0xFFFFFFFF, rotateLeftInt(0xFFFFFFFF, i));
+ expectEqualsInt(1 << j, rotateLeftInt(0x00000001, i));
+ expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j), rotateLeftInt(0x12345678, i));
+ }
+ }
+
+ public static void testRotateLeftLong() {
+ expectEqualsLong(0x0000000000000001L, rotateLeftLong(0x0000000000000001L, 0));
+ expectEqualsLong(0x0000000000000002L, rotateLeftLong(0x0000000000000001L, 1));
+ expectEqualsLong(0x8000000000000000L, rotateLeftLong(0x0000000000000001L, 63));
+ expectEqualsLong(0x0000000000000001L, rotateLeftLong(0x0000000000000001L, 64)); // overshoot
+ expectEqualsLong(0x0000000000000003L, rotateLeftLong(0x8000000000000001L, 1));
+ expectEqualsLong(0x0000000000000006L, rotateLeftLong(0x8000000000000001L, 2));
+ expectEqualsLong(0x23456789ABCDEF01L, rotateLeftLong(0x123456789ABCDEF0L, 4));
+ expectEqualsLong(0x3456789ABCDEF012L, rotateLeftLong(0x123456789ABCDEF0L, 8));
+ for (int i = 0; i < 70; i++) { // overshoot a bit
+ int j = i & 63;
+ expectEqualsLong(0x0000000000000000L, rotateLeftLong(0x0000000000000000L, i));
+ expectEqualsLong(0xFFFFFFFFFFFFFFFFL, rotateLeftLong(0xFFFFFFFFFFFFFFFFL, i));
+ expectEqualsLong(1L << j, rotateLeftLong(0x0000000000000001, i));
+ expectEqualsLong((0x123456789ABCDEF0L << j) | (0x123456789ABCDEF0L >>> -j),
+ rotateLeftLong(0x123456789ABCDEF0L, i));
+ }
+ }
+
+ public static void testRotateRightBoolean() {
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0, rotateRightBoolean(false, i));
+ expectEqualsInt(1 << (32 - i), rotateRightBoolean(true, i));
+ }
+ }
+
+ public static void testRotateRightByte() {
+ expectEqualsInt(0xFFFFFF80, rotateRightByte((byte)0x80, 0));
+ expectEqualsInt(0x7FFFFFC0, rotateRightByte((byte)0x80, 1));
+ expectEqualsInt(0xFFFFFF01, rotateRightByte((byte)0x80, 31));
+ expectEqualsInt(0xFFFFFF80, rotateRightByte((byte)0x80, 32)); // overshoot
+ expectEqualsInt(0xFFFFFFC0, rotateRightByte((byte)0x81, 1));
+ expectEqualsInt(0x7FFFFFE0, rotateRightByte((byte)0x81, 2));
+ expectEqualsInt(0x20000001, rotateRightByte((byte)0x12, 4));
+ expectEqualsInt(0x9AFFFFFF, rotateRightByte((byte)0x9A, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0x00000000, rotateRightByte((byte)0x00, i));
+ expectEqualsInt(0xFFFFFFFF, rotateRightByte((byte)0xFF, i));
+ expectEqualsInt(1 << (32 - j), rotateRightByte((byte)0x01, i));
+ expectEqualsInt((0x12 >>> j) | (0x12 << -j), rotateRightByte((byte)0x12, i));
+ }
+ }
+
+ public static void testRotateRightShort() {
+ expectEqualsInt(0xFFFF8000, rotateRightShort((short)0x8000, 0));
+ expectEqualsInt(0x7FFFC000, rotateRightShort((short)0x8000, 1));
+ expectEqualsInt(0xFFFF0001, rotateRightShort((short)0x8000, 31));
+ expectEqualsInt(0xFFFF8000, rotateRightShort((short)0x8000, 32)); // overshoot
+ expectEqualsInt(0xFFFFC000, rotateRightShort((short)0x8001, 1));
+ expectEqualsInt(0x7FFFE000, rotateRightShort((short)0x8001, 2));
+ expectEqualsInt(0x40000123, rotateRightShort((short)0x1234, 4));
+ expectEqualsInt(0xBCFFFF9A, rotateRightShort((short)0x9ABC, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0x00000000, rotateRightShort((short)0x0000, i));
+ expectEqualsInt(0xFFFFFFFF, rotateRightShort((short)0xFFFF, i));
+ expectEqualsInt(1 << (32 - j), rotateRightShort((short)0x0001, i));
+ expectEqualsInt((0x1234 >>> j) | (0x1234 << -j), rotateRightShort((short)0x1234, i));
+ }
+ }
+
+ public static void testRotateRightChar() {
+ expectEqualsInt(0x00008000, rotateRightChar((char)0x8000, 0));
+ expectEqualsInt(0x00004000, rotateRightChar((char)0x8000, 1));
+ expectEqualsInt(0x00010000, rotateRightChar((char)0x8000, 31));
+ expectEqualsInt(0x00008000, rotateRightChar((char)0x8000, 32)); // overshoot
+ expectEqualsInt(0x80004000, rotateRightChar((char)0x8001, 1));
+ expectEqualsInt(0x40002000, rotateRightChar((char)0x8001, 2));
+ expectEqualsInt(0x40000123, rotateRightChar((char)0x1234, 4));
+ expectEqualsInt(0xBC00009A, rotateRightChar((char)0x9ABC, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0x00000000, rotateRightChar((char)0x0000, i));
+ expectEqualsInt(1 << (32 - j), rotateRightChar((char)0x0001, i));
+ expectEqualsInt((0x1234 >>> j) | (0x1234 << -j), rotateRightChar((char)0x1234, i));
+ }
+ }
+
+ public static void testRotateRightInt() {
+ expectEqualsInt(0x80000000, rotateRightInt(0x80000000, 0));
+ expectEqualsInt(0x40000000, rotateRightInt(0x80000000, 1));
+ expectEqualsInt(0x00000001, rotateRightInt(0x80000000, 31));
+ expectEqualsInt(0x80000000, rotateRightInt(0x80000000, 32)); // overshoot
+ expectEqualsInt(0xC0000000, rotateRightInt(0x80000001, 1));
+ expectEqualsInt(0x60000000, rotateRightInt(0x80000001, 2));
+ expectEqualsInt(0x81234567, rotateRightInt(0x12345678, 4));
+ expectEqualsInt(0xF09ABCDE, rotateRightInt(0x9ABCDEF0, 8));
+ for (int i = 0; i < 40; i++) { // overshoot a bit
+ int j = i & 31;
+ expectEqualsInt(0x00000000, rotateRightInt(0x00000000, i));
+ expectEqualsInt(0xFFFFFFFF, rotateRightInt(0xFFFFFFFF, i));
+ expectEqualsInt(0x80000000 >>> j, rotateRightInt(0x80000000, i));
+ expectEqualsInt((0x12345678 >>> j) | (0x12345678 << -j), rotateRightInt(0x12345678, i));
+ }
+ }
+
+ public static void testRotateRightLong() {
+ expectEqualsLong(0x8000000000000000L, rotateRightLong(0x8000000000000000L, 0));
+ expectEqualsLong(0x4000000000000000L, rotateRightLong(0x8000000000000000L, 1));
+ expectEqualsLong(0x0000000000000001L, rotateRightLong(0x8000000000000000L, 63));
+ expectEqualsLong(0x8000000000000000L, rotateRightLong(0x8000000000000000L, 64)); // overshoot
+ expectEqualsLong(0xC000000000000000L, rotateRightLong(0x8000000000000001L, 1));
+ expectEqualsLong(0x6000000000000000L, rotateRightLong(0x8000000000000001L, 2));
+ expectEqualsLong(0x0123456789ABCDEFL, rotateRightLong(0x123456789ABCDEF0L, 4));
+ expectEqualsLong(0xF0123456789ABCDEL, rotateRightLong(0x123456789ABCDEF0L, 8));
+ for (int i = 0; i < 70; i++) { // overshoot a bit
+ int j = i & 63;
+ expectEqualsLong(0x0000000000000000L, rotateRightLong(0x0000000000000000L, i));
+ expectEqualsLong(0xFFFFFFFFFFFFFFFFL, rotateRightLong(0xFFFFFFFFFFFFFFFFL, i));
+ expectEqualsLong(0x8000000000000000L >>> j, rotateRightLong(0x8000000000000000L, i));
+ expectEqualsLong((0x123456789ABCDEF0L >>> j) | (0x123456789ABCDEF0L << -j),
+ rotateRightLong(0x123456789ABCDEF0L, i));
+ }
+ }
+
+
public static void main(String args[]) {
- expectEquals32(0x00000001, rotateLeft32(0x00000001, 0));
- expectEquals32(0x00000002, rotateLeft32(0x00000001, 1));
- expectEquals32(0x80000000, rotateLeft32(0x00000001, 31));
- expectEquals32(0x00000001, rotateLeft32(0x00000001, 32)); // overshoot
- expectEquals32(0x00000003, rotateLeft32(0x80000001, 1));
- expectEquals32(0x00000006, rotateLeft32(0x80000001, 2));
- expectEquals32(0x23456781, rotateLeft32(0x12345678, 4));
- expectEquals32(0xBCDEF09A, rotateLeft32(0x9ABCDEF0, 8));
- for (int i = 0; i < 40; i++) { // overshoot a bit
- int j = i & 31;
- expectEquals32(0x00000000, rotateLeft32(0x00000000, i));
- expectEquals32(0xFFFFFFFF, rotateLeft32(0xFFFFFFFF, i));
- expectEquals32(1 << j, rotateLeft32(0x00000001, i));
- expectEquals32((0x12345678 << j) | (0x12345678 >>> -j),
- rotateLeft32(0x12345678, i));
- }
+ testRotateLeftBoolean();
+ testRotateLeftByte();
+ testRotateLeftShort();
+ testRotateLeftChar();
+ testRotateLeftInt();
+ testRotateLeftLong();
- expectEquals64(0x0000000000000001L, rotateLeft64(0x0000000000000001L, 0));
- expectEquals64(0x0000000000000002L, rotateLeft64(0x0000000000000001L, 1));
- expectEquals64(0x8000000000000000L, rotateLeft64(0x0000000000000001L, 63));
- expectEquals64(0x0000000000000001L, rotateLeft64(0x0000000000000001L, 64)); // overshoot
- expectEquals64(0x0000000000000003L, rotateLeft64(0x8000000000000001L, 1));
- expectEquals64(0x0000000000000006L, rotateLeft64(0x8000000000000001L, 2));
- expectEquals64(0x23456789ABCDEF01L, rotateLeft64(0x123456789ABCDEF0L, 4));
- expectEquals64(0x3456789ABCDEF012L, rotateLeft64(0x123456789ABCDEF0L, 8));
- for (int i = 0; i < 70; i++) { // overshoot a bit
- int j = i & 63;
- expectEquals64(0x0000000000000000L, rotateLeft64(0x0000000000000000L, i));
- expectEquals64(0xFFFFFFFFFFFFFFFFL, rotateLeft64(0xFFFFFFFFFFFFFFFFL, i));
- expectEquals64(1L << j, rotateLeft64(0x0000000000000001, i));
- expectEquals64((0x123456789ABCDEF0L << j) | (0x123456789ABCDEF0L >>> -j),
- rotateLeft64(0x123456789ABCDEF0L, i));
- }
-
- expectEquals32(0x80000000, rotateRight32(0x80000000, 0));
- expectEquals32(0x40000000, rotateRight32(0x80000000, 1));
- expectEquals32(0x00000001, rotateRight32(0x80000000, 31));
- expectEquals32(0x80000000, rotateRight32(0x80000000, 32)); // overshoot
- expectEquals32(0xC0000000, rotateRight32(0x80000001, 1));
- expectEquals32(0x60000000, rotateRight32(0x80000001, 2));
- expectEquals32(0x81234567, rotateRight32(0x12345678, 4));
- expectEquals32(0xF09ABCDE, rotateRight32(0x9ABCDEF0, 8));
- for (int i = 0; i < 40; i++) { // overshoot a bit
- int j = i & 31;
- expectEquals32(0x00000000, rotateRight32(0x00000000, i));
- expectEquals32(0xFFFFFFFF, rotateRight32(0xFFFFFFFF, i));
- expectEquals32(0x80000000 >>> j, rotateRight32(0x80000000, i));
- expectEquals32((0x12345678 >>> j) | (0x12345678 << -j),
- rotateRight32(0x12345678, i));
- }
-
- expectEquals64(0x8000000000000000L, rotateRight64(0x8000000000000000L, 0));
- expectEquals64(0x4000000000000000L, rotateRight64(0x8000000000000000L, 1));
- expectEquals64(0x0000000000000001L, rotateRight64(0x8000000000000000L, 63));
- expectEquals64(0x8000000000000000L, rotateRight64(0x8000000000000000L, 64)); // overshoot
- expectEquals64(0xC000000000000000L, rotateRight64(0x8000000000000001L, 1));
- expectEquals64(0x6000000000000000L, rotateRight64(0x8000000000000001L, 2));
- expectEquals64(0x0123456789ABCDEFL, rotateRight64(0x123456789ABCDEF0L, 4));
- expectEquals64(0xF0123456789ABCDEL, rotateRight64(0x123456789ABCDEF0L, 8));
- for (int i = 0; i < 70; i++) { // overshoot a bit
- int j = i & 63;
- expectEquals64(0x0000000000000000L, rotateRight64(0x0000000000000000L, i));
- expectEquals64(0xFFFFFFFFFFFFFFFFL, rotateRight64(0xFFFFFFFFFFFFFFFFL, i));
- expectEquals64(0x8000000000000000L >>> j, rotateRight64(0x8000000000000000L, i));
- expectEquals64((0x123456789ABCDEF0L >>> j) | (0x123456789ABCDEF0L << -j),
- rotateRight64(0x123456789ABCDEF0L, i));
- }
+ testRotateRightBoolean();
+ testRotateRightByte();
+ testRotateRightShort();
+ testRotateRightChar();
+ testRotateRightInt();
+ testRotateRightLong();
System.out.println("passed");
}
- private static void expectEquals32(int expected, int result) {
+
+ private static void expectEqualsInt(int expected, int result) {
if (expected != result) {
throw new Error("Expected: " + expected + ", found: " + result);
}
}
- private static void expectEquals64(long expected, long result) {
+
+ private static void expectEqualsLong(long expected, long result) {
if (expected != result) {
throw new Error("Expected: " + expected + ", found: " + result);
}