Compute static type information for remaining expression types on x64 platform.
authorwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 23 Apr 2010 08:05:13 +0000 (08:05 +0000)
committerwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 23 Apr 2010 08:05:13 +0000 (08:05 +0000)
Review URL: http://codereview.chromium.org/1751008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4481 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/ia32/codegen-ia32.cc
src/x64/codegen-x64.cc

index 95dbcd4..66a1774 100644 (file)
@@ -7047,6 +7047,12 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
           (node->expression()->AsBinaryOperation() != NULL &&
            node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
       switch (op) {
+        case Token::NOT:
+        case Token::DELETE:
+        case Token::TYPEOF:
+          UNREACHABLE();  // handled above
+          break;
+
         case Token::SUB: {
           GenericUnaryOpStub stub(Token::SUB, overwrite);
           Result operand = frame_->Pop();
@@ -7087,11 +7093,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
             __ not_(answer.reg());
 
             continue_label.Bind(&answer);
-            if (operand_info.IsInteger32()) {
-              answer.set_type_info(TypeInfo::Integer32());
-            } else {
-              answer.set_type_info(TypeInfo::Number());
-            }
+            answer.set_type_info(TypeInfo::Integer32());
             frame_->Push(&answer);
           }
           break;
@@ -7121,8 +7123,6 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
           break;
         }
         default:
-          // NOT, DELETE, TYPEOF, and VOID are handled outside the
-          // switch.
           UNREACHABLE();
       }
     }
@@ -7333,7 +7333,7 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
         __ setcc(overflow, tmp.reg());
         __ or_(Operand(tmp.reg()), new_value.reg());
         __ test(tmp.reg(), Immediate(kSmiTagMask));
-        tmp.Unuse();
+        tmp.Unusec();
         deferred->Branch(not_zero);
       } else {
         // Otherwise we test separately for overflow and smi tag.
index 4fac89a..9ce5821 100644 (file)
@@ -3117,6 +3117,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
         GenericUnaryOpStub stub(Token::SUB, overwrite);
         Result operand = frame_->Pop();
         Result answer = frame_->CallStub(&stub, &operand);
+        answer.set_type_info(TypeInfo::Number());
         frame_->Push(&answer);
         break;
       }
@@ -3140,6 +3141,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
         frame_->Spill(answer.reg());
         __ SmiNot(answer.reg(), answer.reg());
         continue_label.Bind(&answer);
+        answer.set_type_info(TypeInfo::Smi());
         frame_->Push(&answer);
         break;
       }
@@ -3148,6 +3150,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
         // Smi check.
         JumpTarget continue_label;
         Result operand = frame_->Pop();
+        TypeInfo operand_info = operand.type_info();
         operand.ToRegister();
         Condition is_smi = masm_->CheckSmi(operand.reg());
         continue_label.Branch(is_smi, &operand);
@@ -3156,10 +3159,16 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
                                               CALL_FUNCTION, 1);
 
         continue_label.Bind(&answer);
+        if (operand_info.IsSmi()) {
+          answer.set_type_info(TypeInfo::Smi());
+        } else if (operand_info.IsInteger32()) {
+          answer.set_type_info(TypeInfo::Integer32());
+        } else {
+          answer.set_type_info(TypeInfo::Number());
+        }
         frame_->Push(&answer);
         break;
       }
-
       default:
         UNREACHABLE();
     }
@@ -5720,6 +5729,57 @@ void DeferredInlineBinaryOperation::Generate() {
 }
 
 
+static TypeInfo CalculateTypeInfo(TypeInfo operands_type,
+                                  Token::Value op,
+                                  const Result& right,
+                                  const Result& left) {
+  // Set TypeInfo of result according to the operation performed.
+  // We rely on the fact that smis have a 32 bit payload on x64.
+  STATIC_ASSERT(kSmiValueSize == 32);
+  switch (op) {
+    case Token::COMMA:
+      return right.type_info();
+    case Token::OR:
+    case Token::AND:
+      // Result type can be either of the two input types.
+      return operands_type;
+    case Token::BIT_OR:
+    case Token::BIT_XOR:
+    case Token::BIT_AND:
+      // Result is always a smi.
+      return TypeInfo::Smi();
+    case Token::SAR:
+    case Token::SHL:
+      // Result is always a smi.
+      return TypeInfo::Smi();
+    case Token::SHR:
+      // Result of x >>> y is always a smi if masked y >= 1, otherwise a number.
+      return (right.is_constant() && right.handle()->IsSmi()
+                     && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
+          ? TypeInfo::Smi()
+          : TypeInfo::Number();
+    case Token::ADD:
+      if (operands_type.IsNumber()) {
+        return TypeInfo::Number();
+      } else if (left.type_info().IsString() || right.type_info().IsString()) {
+        return TypeInfo::String();
+      } else {
+        return TypeInfo::Unknown();
+      }
+    case Token::SUB:
+    case Token::MUL:
+    case Token::DIV:
+    case Token::MOD:
+      // Result is always a number.
+      return TypeInfo::Number();
+    default:
+      UNREACHABLE();
+  }
+  UNREACHABLE();
+  return TypeInfo::Unknown();
+}
+
+
 void CodeGenerator::GenericBinaryOperation(Token::Value op,
                                            StaticType* type,
                                            OverwriteMode overwrite_mode) {
@@ -5785,6 +5845,8 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
   TypeInfo operands_type =
       TypeInfo::Combine(left.type_info(), right.type_info());
 
+  TypeInfo result_type = CalculateTypeInfo(operands_type, op, right, left);
+
   Result answer;
   if (left_is_non_smi_constant || right_is_non_smi_constant) {
     GenericBinaryOpStub stub(op,
@@ -5815,56 +5877,6 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
     }
   }
 
-  // Set TypeInfo of result according to the operation performed.
-  // We rely on the fact that smis have a 32 bit payload on x64.
-  ASSERT(kSmiValueSize == 32);
-  TypeInfo result_type = TypeInfo::Unknown();
-  switch (op) {
-    case Token::COMMA:
-      result_type = right.type_info();
-      break;
-    case Token::OR:
-    case Token::AND:
-      // Result type can be either of the two input types.
-      result_type = operands_type;
-      break;
-    case Token::BIT_OR:
-    case Token::BIT_XOR:
-    case Token::BIT_AND:
-      // Result is always a smi.
-      result_type = TypeInfo::Smi();
-      break;
-    case Token::SAR:
-    case Token::SHL:
-      // Result is always a smi.
-      result_type = TypeInfo::Smi();
-      break;
-    case Token::SHR:
-      // Result of x >>> y is always a smi if masked y >= 1, otherwise a number.
-      result_type = (right.is_constant() && right.handle()->IsSmi()
-                     && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
-          ? TypeInfo::Smi()
-          : TypeInfo::Number();
-      break;
-    case Token::ADD:
-      if (operands_type.IsNumber()) {
-        result_type = TypeInfo::Number();
-      } else if (operands_type.IsString()) {
-        result_type = TypeInfo::String();
-      } else {
-        result_type = TypeInfo::Unknown();
-      }
-      break;
-    case Token::SUB:
-    case Token::MUL:
-    case Token::DIV:
-    case Token::MOD:
-      // Result is always a number.
-      result_type = TypeInfo::Number();
-      break;
-    default:
-      UNREACHABLE();
-  }
   answer.set_type_info(result_type);
   frame_->Push(&answer);
 }