diff options
| -rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 14 | ||||
| -rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 10 | ||||
| -rw-r--r-- | compiler/utils/arm/assembler_thumb2.cc | 2 | ||||
| -rw-r--r-- | compiler/utils/assembler_thumb_test.cc | 32 | ||||
| -rw-r--r-- | compiler/utils/assembler_thumb_test_expected.cc.inc | 19 | ||||
| -rw-r--r-- | test/458-checker-instruction-simplification/src/Main.java | 19 | ||||
| -rw-r--r-- | test/538-checker-embed-constants/src/Main.java | 137 |
7 files changed, 156 insertions, 77 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 12ab68e8cd..c7e412c8e3 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -3361,7 +3361,19 @@ void InstructionCodeGeneratorARM::HandleShift(HBinaryOperation* op) { __ mov(o_l, ShifterOperand(high)); __ LoadImmediate(o_h, 0); } - } else { // shift_value < 32 + } else if (shift_value == 1) { + if (op->IsShl()) { + __ Lsls(o_l, low, 1); + __ adc(o_h, high, ShifterOperand(high)); + } else if (op->IsShr()) { + __ Asrs(o_h, high, 1); + __ Rrx(o_l, low); + } else { + __ Lsrs(o_h, high, 1); + __ Rrx(o_l, low); + } + } else { + DCHECK(2 <= shift_value && shift_value < 32) << shift_value; if (op->IsShl()) { __ Lsl(o_h, high, shift_value); __ orr(o_h, o_h, ShifterOperand(low, LSR, 32 - shift_value)); diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index b97dc1a511..b36870cf59 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -169,16 +169,6 @@ void InstructionSimplifierVisitor::VisitShift(HBinaryOperation* instruction) { // src instruction->ReplaceWith(input_other); instruction->GetBlock()->RemoveInstruction(instruction); - } else if (instruction->IsShl() && input_cst->IsOne()) { - // Replace Shl looking like - // SHL dst, src, 1 - // with - // ADD dst, src, src - HAdd *add = new(GetGraph()->GetArena()) HAdd(instruction->GetType(), - input_other, - input_other); - instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, add); - RecordSimplification(); } } } diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc index 297cc54e29..584a597701 100644 --- a/compiler/utils/arm/assembler_thumb2.cc +++ b/compiler/utils/arm/assembler_thumb2.cc @@ -3220,7 +3220,7 @@ void Thumb2Assembler::Ror(Register rd, Register rm, uint32_t shift_imm, void Thumb2Assembler::Rrx(Register rd, Register rm, Condition cond, SetCc set_cc) { CheckCondition(cond); - EmitShift(rd, rm, RRX, rm, cond, set_cc); + EmitShift(rd, rm, RRX, 0, cond, set_cc); } diff --git a/compiler/utils/assembler_thumb_test.cc b/compiler/utils/assembler_thumb_test.cc index 2ae88413e7..2e7021df17 100644 --- a/compiler/utils/assembler_thumb_test.cc +++ b/compiler/utils/assembler_thumb_test.cc @@ -466,6 +466,38 @@ TEST(Thumb2AssemblerTest, DataProcessingShiftedRegister) { EmitAndCheck(&assembler, "DataProcessingShiftedRegister"); } +TEST(Thumb2AssemblerTest, ShiftImmediate) { + // Note: This test produces the same results as DataProcessingShiftedRegister + // but it does so using shift functions instead of mov(). + arm::Thumb2Assembler assembler; + + // 16-bit variants. + __ Lsl(R3, R4, 4); + __ Lsr(R3, R4, 5); + __ Asr(R3, R4, 6); + + // 32-bit ROR because ROR immediate doesn't have the same 16-bit version as other shifts. + __ Ror(R3, R4, 7); + + // 32-bit RRX because RRX has no 16-bit version. + __ Rrx(R3, R4); + + // 32 bit variants (not setting condition codes). + __ Lsl(R3, R4, 4, AL, kCcKeep); + __ Lsr(R3, R4, 5, AL, kCcKeep); + __ Asr(R3, R4, 6, AL, kCcKeep); + __ Ror(R3, R4, 7, AL, kCcKeep); + __ Rrx(R3, R4, AL, kCcKeep); + + // 32 bit variants (high registers). + __ Lsls(R8, R4, 4); + __ Lsrs(R8, R4, 5); + __ Asrs(R8, R4, 6); + __ Rors(R8, R4, 7); + __ Rrxs(R8, R4); + + EmitAndCheck(&assembler, "ShiftImmediate"); +} TEST(Thumb2AssemblerTest, BasicLoad) { arm::Thumb2Assembler assembler; diff --git a/compiler/utils/assembler_thumb_test_expected.cc.inc b/compiler/utils/assembler_thumb_test_expected.cc.inc index b79c2e46f0..3fda09f3e8 100644 --- a/compiler/utils/assembler_thumb_test_expected.cc.inc +++ b/compiler/utils/assembler_thumb_test_expected.cc.inc @@ -201,6 +201,24 @@ const char* DataProcessingShiftedRegisterResults[] = { " 32: ea5f 0834 movs.w r8, r4, rrx\n", nullptr }; +const char* ShiftImmediateResults[] = { + " 0: 0123 lsls r3, r4, #4\n", + " 2: 0963 lsrs r3, r4, #5\n", + " 4: 11a3 asrs r3, r4, #6\n", + " 6: ea4f 13f4 mov.w r3, r4, ror #7\n", + " a: ea4f 0334 mov.w r3, r4, rrx\n", + " e: ea4f 1304 mov.w r3, r4, lsl #4\n", + " 12: ea4f 1354 mov.w r3, r4, lsr #5\n", + " 16: ea4f 13a4 mov.w r3, r4, asr #6\n", + " 1a: ea4f 13f4 mov.w r3, r4, ror #7\n", + " 1e: ea4f 0334 mov.w r3, r4, rrx\n", + " 22: ea5f 1804 movs.w r8, r4, lsl #4\n", + " 26: ea5f 1854 movs.w r8, r4, lsr #5\n", + " 2a: ea5f 18a4 movs.w r8, r4, asr #6\n", + " 2e: ea5f 18f4 movs.w r8, r4, ror #7\n", + " 32: ea5f 0834 movs.w r8, r4, rrx\n", + nullptr +}; const char* BasicLoadResults[] = { " 0: 69a3 ldr r3, [r4, #24]\n", " 2: 7e23 ldrb r3, [r4, #24]\n", @@ -4952,6 +4970,7 @@ void setup_results() { test_results["DataProcessingModifiedImmediate"] = DataProcessingModifiedImmediateResults; test_results["DataProcessingModifiedImmediates"] = DataProcessingModifiedImmediatesResults; test_results["DataProcessingShiftedRegister"] = DataProcessingShiftedRegisterResults; + test_results["ShiftImmediate"] = ShiftImmediateResults; test_results["BasicLoad"] = BasicLoadResults; test_results["BasicStore"] = BasicStoreResults; test_results["ComplexLoad"] = ComplexLoadResults; diff --git a/test/458-checker-instruction-simplification/src/Main.java b/test/458-checker-instruction-simplification/src/Main.java index c32d34aa6f..bad857c438 100644 --- a/test/458-checker-instruction-simplification/src/Main.java +++ b/test/458-checker-instruction-simplification/src/Main.java @@ -389,24 +389,6 @@ public class Main { return arg << 0; } - /// CHECK-START: int Main.Shl1(int) instruction_simplifier (before) - /// CHECK-DAG: <<Arg:i\d+>> ParameterValue - /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 - /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Arg>>,<<Const1>>] - /// CHECK-DAG: Return [<<Shl>>] - - /// CHECK-START: int Main.Shl1(int) instruction_simplifier (after) - /// CHECK-DAG: <<Arg:i\d+>> ParameterValue - /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg>>,<<Arg>>] - /// CHECK-DAG: Return [<<Add>>] - - /// CHECK-START: int Main.Shl1(int) instruction_simplifier (after) - /// CHECK-NOT: Shl - - public static int Shl1(int arg) { - return arg << 1; - } - /// CHECK-START: long Main.Shr0(long) instruction_simplifier (before) /// CHECK-DAG: <<Arg:j\d+>> ParameterValue /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 @@ -1274,7 +1256,6 @@ public class Main { assertDoubleEquals(Div2(150.0), 75.0); assertFloatEquals(DivMP25(100.0f), -400.0f); assertDoubleEquals(DivMP25(150.0), -600.0); - assertLongEquals(Shl1(100), 200); assertIntEquals(UShr28And15(0xc1234567), 0xc); assertLongEquals(UShr60And15(0xc123456787654321L), 0xcL); assertIntEquals(UShr28And7(0xc1234567), 0x4); diff --git a/test/538-checker-embed-constants/src/Main.java b/test/538-checker-embed-constants/src/Main.java index 12f0380df0..f791adfd9a 100644 --- a/test/538-checker-embed-constants/src/Main.java +++ b/test/538-checker-embed-constants/src/Main.java @@ -260,26 +260,43 @@ public class Main { return arg ^ 0xf00000000000000fL; } + /// CHECK-START-ARM: long Main.shl1(long) disassembly (after) + /// CHECK: lsls{{(\.w)?}} {{r\d+}}, {{r\d+}}, #1 + /// CHECK: adc{{(\.w)?}} {{r\d+}}, {{r\d+}}, {{r\d+}} + + /// CHECK-START-ARM: long Main.shl1(long) disassembly (after) + /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + + /// CHECK-START-X86: long Main.shl1(long) disassembly (after) + /// CHECK: add + /// CHECK: adc + + /// CHECK-START-X86: long Main.shl1(long) disassembly (after) + /// CHECK-NOT: shl + + public static long shl1(long arg) { + return arg << 1; + } + /// CHECK-START-ARM: long Main.shl2(long) disassembly (after) - /// CHECK: lsl{{s?|.w}} <<oh:r\d+>>, {{r\d+}}, #2 + /// CHECK: lsl{{s?|\.w}} <<oh:r\d+>>, {{r\d+}}, #2 /// CHECK: orr.w <<oh>>, <<oh>>, <<low:r\d+>>, lsr #30 - /// CHECK-DAG: lsl{{s?|.w}} {{r\d+}}, <<low>>, #2 + /// CHECK: lsl{{s?|\.w}} {{r\d+}}, <<low>>, #2 /// CHECK-START-ARM: long Main.shl2(long) disassembly (after) - /// CHECK-NOT: lsl{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long shl2(long arg) { - // Note: Shl(x, 1) is transformed to Add(x, x), so test Shl(x, 2). return arg << 2; } /// CHECK-START-ARM: long Main.shl31(long) disassembly (after) - /// CHECK: lsl{{s?|.w}} <<oh:r\d+>>, {{r\d+}}, #31 + /// CHECK: lsl{{s?|\.w}} <<oh:r\d+>>, {{r\d+}}, #31 /// CHECK: orr.w <<oh>>, <<oh>>, <<low:r\d+>>, lsr #1 - /// CHECK: lsl{{s?|.w}} {{r\d+}}, <<low>>, #31 + /// CHECK: lsl{{s?|\.w}} {{r\d+}}, <<low>>, #31 /// CHECK-START-ARM: long Main.shl31(long) disassembly (after) - /// CHECK-NOT: lsl{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long shl31(long arg) { return arg << 31; @@ -287,114 +304,136 @@ public class Main { /// CHECK-START-ARM: long Main.shl32(long) disassembly (after) /// CHECK-DAG: mov {{r\d+}}, {{r\d+}} - /// CHECK-DAG: mov{{s?|.w}} {{r\d+}}, #0 + /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 /// CHECK-START-ARM: long Main.shl32(long) disassembly (after) - /// CHECK-NOT: lsl{{s?|.w}} + /// CHECK-NOT: lsl{{s?|\.w}} public static long shl32(long arg) { return arg << 32; } /// CHECK-START-ARM: long Main.shl33(long) disassembly (after) - /// CHECK-DAG: lsl{{s?|.w}} {{r\d+}}, <<high:r\d+>>, #1 - /// CHECK-DAG: mov{{s?|.w}} {{r\d+}}, #0 + /// CHECK-DAG: lsl{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #1 + /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 /// CHECK-START-ARM: long Main.shl33(long) disassembly (after) - /// CHECK-NOT: lsl{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long shl33(long arg) { return arg << 33; } /// CHECK-START-ARM: long Main.shl63(long) disassembly (after) - /// CHECK-DAG: lsl{{s?|.w}} {{r\d+}}, <<high:r\d+>>, #31 - /// CHECK-DAG: mov{{s?|.w}} {{r\d+}}, #0 + /// CHECK-DAG: lsl{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #31 + /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 /// CHECK-START-ARM: long Main.shl63(long) disassembly (after) - /// CHECK-NOT: lsl{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: lsl{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long shl63(long arg) { return arg << 63; } /// CHECK-START-ARM: long Main.shr1(long) disassembly (after) - /// CHECK: lsr{{s?|.w}} <<ol:r\d+>>, {{r\d+}}, #1 - /// CHECK: orr.w <<ol>>, <<ol>>, <<high:r\d+>>, lsl #31 - /// CHECK-DAG: asr{{s?|.w}} {{r\d+}}, <<high>>, #1 + /// CHECK: asrs{{(\.w)?}} {{r\d+}}, {{r\d+}}, #1 + /// CHECK: mov.w {{r\d+}}, {{r\d+}}, rrx /// CHECK-START-ARM: long Main.shr1(long) disassembly (after) - /// CHECK-NOT: asr{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long shr1(long arg) { return arg >> 1; } + /// CHECK-START-ARM: long Main.shr2(long) disassembly (after) + /// CHECK: lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #2 + /// CHECK: orr.w <<ol>>, <<ol>>, <<high:r\d+>>, lsl #30 + /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high>>, #2 + + /// CHECK-START-ARM: long Main.shr2(long) disassembly (after) + /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + + public static long shr2(long arg) { + return arg >> 2; + } + /// CHECK-START-ARM: long Main.shr31(long) disassembly (after) - /// CHECK: lsr{{s?|.w}} <<ol:r\d+>>, {{r\d+}}, #31 + /// CHECK: lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #31 /// CHECK: orr.w <<ol>>, <<ol>>, <<high:r\d+>>, lsl #1 - /// CHECK: asr{{s?|.w}} {{r\d+}}, <<high>>, #31 + /// CHECK: asr{{s?|\.w}} {{r\d+}}, <<high>>, #31 /// CHECK-START-ARM: long Main.shr31(long) disassembly (after) - /// CHECK-NOT: asr{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long shr31(long arg) { return arg >> 31; } /// CHECK-START-ARM: long Main.shr32(long) disassembly (after) - /// CHECK-DAG: asr{{s?|.w}} {{r\d+}}, <<high:r\d+>>, #31 + /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #31 /// CHECK-DAG: mov {{r\d+}}, <<high>> /// CHECK-START-ARM: long Main.shr32(long) disassembly (after) - /// CHECK-NOT: asr{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} - /// CHECK-NOT: lsr{{s?|.w}} + /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: lsr{{s?|\.w}} public static long shr32(long arg) { return arg >> 32; } /// CHECK-START-ARM: long Main.shr33(long) disassembly (after) - /// CHECK-DAG: asr{{s?|.w}} {{r\d+}}, <<high:r\d+>>, #1 - /// CHECK-DAG: asr{{s?|.w}} {{r\d+}}, <<high>>, #31 + /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #1 + /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high>>, #31 /// CHECK-START-ARM: long Main.shr33(long) disassembly (after) - /// CHECK-NOT: asr{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long shr33(long arg) { return arg >> 33; } /// CHECK-START-ARM: long Main.shr63(long) disassembly (after) - /// CHECK-DAG: asr{{s?|.w}} {{r\d+}}, <<high:r\d+>>, #31 - /// CHECK-DAG: asr{{s?|.w}} {{r\d+}}, <<high>>, #31 + /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high:r\d+>>, #31 + /// CHECK-DAG: asr{{s?|\.w}} {{r\d+}}, <<high>>, #31 /// CHECK-START-ARM: long Main.shr63(long) disassembly (after) - /// CHECK-NOT: asr{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: asr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long shr63(long arg) { return arg >> 63; } /// CHECK-START-ARM: long Main.ushr1(long) disassembly (after) - /// CHECK: lsr{{s?|.w}} <<ol:r\d+>>, {{r\d+}}, #1 - /// CHECK: orr.w <<ol>>, <<ol>>, <<high:r\d+>>, lsl #31 - /// CHECK-DAG: lsr{{s?|.w}} {{r\d+}}, <<high>>, #1 + /// CHECK: lsrs{{|.w}} {{r\d+}}, {{r\d+}}, #1 + /// CHECK: mov.w {{r\d+}}, {{r\d+}}, rrx /// CHECK-START-ARM: long Main.ushr1(long) disassembly (after) - /// CHECK-NOT: lsr{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long ushr1(long arg) { return arg >>> 1; } + /// CHECK-START-ARM: long Main.ushr2(long) disassembly (after) + /// CHECK: lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #2 + /// CHECK: orr.w <<ol>>, <<ol>>, <<high:r\d+>>, lsl #30 + /// CHECK-DAG: lsr{{s?|\.w}} {{r\d+}}, <<high>>, #2 + + /// CHECK-START-ARM: long Main.ushr2(long) disassembly (after) + /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + + public static long ushr2(long arg) { + return arg >>> 2; + } + /// CHECK-START-ARM: long Main.ushr31(long) disassembly (after) - /// CHECK: lsr{{s?|.w}} <<ol:r\d+>>, {{r\d+}}, #31 + /// CHECK: lsr{{s?|\.w}} <<ol:r\d+>>, {{r\d+}}, #31 /// CHECK: orr.w <<ol>>, <<ol>>, <<high:r\d+>>, lsl #1 - /// CHECK: lsr{{s?|.w}} {{r\d+}}, <<high>>, #31 + /// CHECK: lsr{{s?|\.w}} {{r\d+}}, <<high>>, #31 /// CHECK-START-ARM: long Main.ushr31(long) disassembly (after) - /// CHECK-NOT: lsr{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long ushr31(long arg) { return arg >>> 31; @@ -402,32 +441,32 @@ public class Main { /// CHECK-START-ARM: long Main.ushr32(long) disassembly (after) /// CHECK-DAG: mov {{r\d+}}, {{r\d+}} - /// CHECK-DAG: mov{{s?|.w}} {{r\d+}}, #0 + /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 /// CHECK-START-ARM: long Main.ushr32(long) disassembly (after) - /// CHECK-NOT: lsr{{s?|.w}} + /// CHECK-NOT: lsr{{s?|\.w}} public static long ushr32(long arg) { return arg >>> 32; } /// CHECK-START-ARM: long Main.ushr33(long) disassembly (after) - /// CHECK-DAG: lsr{{s?|.w}} {{r\d+}}, {{r\d+}}, #1 - /// CHECK-DAG: mov{{s?|.w}} {{r\d+}}, #0 + /// CHECK-DAG: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, #1 + /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 /// CHECK-START-ARM: long Main.ushr33(long) disassembly (after) - /// CHECK-NOT: lsr{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long ushr33(long arg) { return arg >>> 33; } /// CHECK-START-ARM: long Main.ushr63(long) disassembly (after) - /// CHECK-DAG: lsr{{s?|.w}} {{r\d+}}, {{r\d+}}, #31 - /// CHECK-DAG: mov{{s?|.w}} {{r\d+}}, #0 + /// CHECK-DAG: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, #31 + /// CHECK-DAG: mov{{s?|\.w}} {{r\d+}}, #0 /// CHECK-START-ARM: long Main.ushr63(long) disassembly (after) - /// CHECK-NOT: lsr{{s?|.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} + /// CHECK-NOT: lsr{{s?|\.w}} {{r\d+}}, {{r\d+}}, {{r\d+}} public static long ushr63(long arg) { return arg >>> 63; @@ -485,11 +524,13 @@ public class Main { assertLongEquals(14, addM1(7)); + assertLongEquals(shl1(longArg), 0x2468acf10eca8642L); assertLongEquals(shl2(longArg), 0x48d159e21d950c84L); assertLongEquals(shl31(longArg), 0x43b2a19080000000L); assertLongEquals(shl32(longArg), 0x8765432100000000L); assertLongEquals(shl33(longArg), 0x0eca864200000000L); assertLongEquals(shl63(longArg), 0x8000000000000000L); + assertLongEquals(shl1(~longArg), 0xdb97530ef13579bcL); assertLongEquals(shl2(~longArg), 0xb72ea61de26af378L); assertLongEquals(shl31(~longArg), 0xbc4d5e6f00000000L); assertLongEquals(shl32(~longArg), 0x789abcde00000000L); @@ -497,22 +538,26 @@ public class Main { assertLongEquals(shl63(~longArg), 0x0000000000000000L); assertLongEquals(shr1(longArg), 0x091a2b3c43b2a190L); + assertLongEquals(shr2(longArg), 0x048d159e21d950c8L); assertLongEquals(shr31(longArg), 0x000000002468acf1L); assertLongEquals(shr32(longArg), 0x0000000012345678L); assertLongEquals(shr33(longArg), 0x00000000091a2b3cL); assertLongEquals(shr63(longArg), 0x0000000000000000L); assertLongEquals(shr1(~longArg), 0xf6e5d4c3bc4d5e6fL); + assertLongEquals(shr2(~longArg), 0xfb72ea61de26af37L); assertLongEquals(shr31(~longArg), 0xffffffffdb97530eL); assertLongEquals(shr32(~longArg), 0xffffffffedcba987L); assertLongEquals(shr33(~longArg), 0xfffffffff6e5d4c3L); assertLongEquals(shr63(~longArg), 0xffffffffffffffffL); assertLongEquals(ushr1(longArg), 0x091a2b3c43b2a190L); + assertLongEquals(ushr2(longArg), 0x048d159e21d950c8L); assertLongEquals(ushr31(longArg), 0x000000002468acf1L); assertLongEquals(ushr32(longArg), 0x0000000012345678L); assertLongEquals(ushr33(longArg), 0x00000000091a2b3cL); assertLongEquals(ushr63(longArg), 0x0000000000000000L); assertLongEquals(ushr1(~longArg), 0x76e5d4c3bc4d5e6fL); + assertLongEquals(ushr2(~longArg), 0x3b72ea61de26af37L); assertLongEquals(ushr31(~longArg), 0x00000001db97530eL); assertLongEquals(ushr32(~longArg), 0x00000000edcba987L); assertLongEquals(ushr33(~longArg), 0x0000000076e5d4c3L); |