Index: runtime/vm/intermediate_language_mips.cc |
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc |
index ed03d1d19a80cb81d34d5c7876f904d2a9497478..2b2a971bb4a7642df934e46a0d7b4e249748c49f 100644 |
--- a/runtime/vm/intermediate_language_mips.cc |
+++ b/runtime/vm/intermediate_language_mips.cc |
@@ -3063,6 +3063,30 @@ void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
case Token::kBIT_XOR: |
__ xor_(result, left, right); |
break; |
+ case Token::kSHL: |
+ ASSERT(result != left); |
+ ASSERT(result != right); |
+ __ BranchUnsignedGreater(right, |
+ Immediate(Smi::RawValue(Smi::kBits)), |
+ slow_path->entry_label()); |
+ // Check for overflow by shifting left and shifting back arithmetically. |
+ // If the result is different from the original, there was overflow. |
+ __ SmiUntag(TMP, right); |
+ __ sllv(result, left, TMP); |
+ __ srav(CMPRES1, result, TMP); |
+ __ bne(CMPRES1, left, slow_path->entry_label()); |
+ break; |
+ case Token::kSHR: |
+ __ bltz(right, slow_path->entry_label()); |
+ __ SmiUntag(result, right); |
+ |
+ __ LoadImmediate(TMP, 0x1F); |
+ __ slt(CMPRES1, TMP, result); // CMPRES1 := 0x1F < result ? 1 : 0 |
+ __ movn(result, TMP, CMPRES1); // result := 0x1F < result ? 0x1F : result |
+ __ SmiUntag(TMP, left); |
+ __ srav(result, TMP, result); |
+ __ SmiTag(result); |
+ break; |
default: |
UNIMPLEMENTED(); |
} |