Index: src/hydrogen-instructions.cc |
=================================================================== |
--- src/hydrogen-instructions.cc (revision 10035) |
+++ src/hydrogen-instructions.cc (working copy) |
@@ -1325,6 +1325,13 @@ |
} |
+void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { |
+ stream->Add(Token::Name(token())); |
+ stream->Add(" "); |
+ HControlInstruction::PrintDataTo(stream); |
+} |
+ |
+ |
void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { |
stream->Add(Token::Name(token())); |
stream->Add(" "); |
@@ -1887,6 +1894,167 @@ |
} |
+#define H_CONSTANT_INT32(val) \ |
+new(zone) HConstant(FACTORY->NewNumberFromInt(val, TENURED), \ |
+ Representation::Integer32()) |
+#define H_CONSTANT_DOUBLE(val) \ |
+new(zone) HConstant(FACTORY->NewNumber(val, TENURED), \ |
+ Representation::Double()) |
+ |
+#define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ |
+HInstruction* HInstr::New##HInstr(Zone* zone, \ |
+ HValue* context, \ |
+ HValue* left, \ |
+ HValue* right) { \ |
+ if (left->IsConstant() && right->IsConstant()) { \ |
+ HConstant* c_left = HConstant::cast(left); \ |
+ HConstant* c_right = HConstant::cast(right); \ |
+ if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
+ double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \ |
+ if (TypeInfo::IsInt32Double(double_res)) { \ |
+ return H_CONSTANT_INT32(static_cast<int32_t>(double_res)); \ |
+ } \ |
+ return H_CONSTANT_DOUBLE(double_res); \ |
+ } \ |
+ } \ |
+ return new(zone) HInstr(context, left, right); \ |
+} |
+ |
+ |
+DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +) |
+DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *) |
+DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -) |
+ |
+#undef DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR |
+ |
+ |
+HInstruction* HMod::NewHMod(Zone* zone, |
+ HValue* context, |
+ HValue* left, |
+ HValue* right) { |
+ if (left->IsConstant() && right->IsConstant()) { |
+ HConstant* c_left = HConstant::cast(left); |
+ HConstant* c_right = HConstant::cast(right); |
+ if (c_left->HasInteger32Value() && c_right->HasInteger32Value()) { |
+ int32_t dividend = c_left->Integer32Value(); |
+ int32_t divisor = c_right->Integer32Value(); |
+ if (divisor != 0) { |
+ int32_t res = dividend % divisor; |
+ if ((res == 0) && (dividend < 0)) { |
+ return H_CONSTANT_DOUBLE(-0.0); |
+ } |
+ return H_CONSTANT_INT32(res); |
+ } |
+ } |
+ } |
+ return new(zone) HMod(context, left, right); |
+} |
+ |
+ |
+HInstruction* HDiv::NewHDiv(Zone* zone, |
+ HValue* context, |
+ HValue* left, |
+ HValue* right) { |
+ // If left and right are constant values, try to return a constant value. |
+ if (left->IsConstant() && right->IsConstant()) { |
+ HConstant* c_left = HConstant::cast(left); |
+ HConstant* c_right = HConstant::cast(right); |
+ if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
+ if (c_right->DoubleValue() != 0) { |
+ double double_res = c_left->DoubleValue() / c_right->DoubleValue(); |
+ if (TypeInfo::IsInt32Double(double_res)) { |
+ return H_CONSTANT_INT32(static_cast<int32_t>(double_res)); |
+ } |
+ return H_CONSTANT_DOUBLE(double_res); |
+ } |
+ } |
+ } |
+ return new(zone) HDiv(context, left, right); |
+} |
+ |
+ |
+HInstruction* HBitwise::NewHBitwise(Zone* zone, |
+ Token::Value op, |
+ HValue* context, |
+ HValue* left, |
+ HValue* right) { |
+ if (left->IsConstant() && right->IsConstant()) { |
+ HConstant* c_left = HConstant::cast(left); |
+ HConstant* c_right = HConstant::cast(right); |
+ if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
+ int32_t result; |
+ int32_t v_left = c_left->NumberValueAsInteger32(); |
+ int32_t v_right = c_right->NumberValueAsInteger32(); |
+ switch (op) { |
+ case Token::BIT_XOR: |
+ result = v_left ^ v_right; |
+ break; |
+ case Token::BIT_AND: |
+ result = v_left & v_right; |
+ break; |
+ case Token::BIT_OR: |
+ result = v_left | v_right; |
+ break; |
+ default: |
+ result = 0; // Please the compiler. |
+ UNREACHABLE(); |
+ } |
+ return H_CONSTANT_INT32(result); |
+ } |
+ } |
+ return new(zone) HBitwise(op, context, left, right); |
+} |
+ |
+ |
+#define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \ |
+HInstruction* HInstr::New##HInstr(Zone* zone, \ |
+ HValue* context, \ |
+ HValue* left, \ |
+ HValue* right) { \ |
+ if (left->IsConstant() && right->IsConstant()) { \ |
+ HConstant* c_left = HConstant::cast(left); \ |
+ HConstant* c_right = HConstant::cast(right); \ |
+ if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
+ return H_CONSTANT_INT32(result); \ |
+ } \ |
+ } \ |
+ return new(zone) HInstr(context, left, right); \ |
+} |
+ |
+ |
+DEFINE_NEW_H_BITWISE_INSTR(HSar, |
+c_left->NumberValueAsInteger32() >> (c_right->NumberValueAsInteger32() & 0x1f)) |
+DEFINE_NEW_H_BITWISE_INSTR(HShl, |
+c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f)) |
+ |
+#undef DEFINE_NEW_H_BITWISE_INSTR |
+ |
+ |
+HInstruction* HShr::NewHShr(Zone* zone, |
+ HValue* context, |
+ HValue* left, |
+ HValue* right) { |
+ if (left->IsConstant() && right->IsConstant()) { |
+ HConstant* c_left = HConstant::cast(left); |
+ HConstant* c_right = HConstant::cast(right); |
+ if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
+ int32_t left_val = c_left->NumberValueAsInteger32(); |
+ int32_t right_val = c_right->NumberValueAsInteger32() & 0x1f; |
+ if ((right_val == 0) && (left_val < 0)) { |
+ return H_CONSTANT_DOUBLE( |
+ static_cast<double>(static_cast<uint32_t>(left_val))); |
+ } |
+ return H_CONSTANT_INT32(static_cast<uint32_t>(left_val) >> right_val); |
+ } |
+ } |
+ return new(zone) HShr(context, left, right); |
+} |
+ |
+ |
+#undef H_CONSTANT_INT32 |
+#undef H_CONSTANT_DOUBLE |
+ |
+ |
void HIn::PrintDataTo(StringStream* stream) { |
key()->PrintNameTo(stream); |
stream->Add(" "); |