Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: src/x64/codegen-x64.cc

Issue 2754004: Use static type information in ConstantIntBinaryOperation on x64. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/codegen-x64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 6876 matching lines...) Expand 10 before | Expand all | Expand 10 after
6887 DeferredCode* deferred = NULL; 6887 DeferredCode* deferred = NULL;
6888 if (reversed) { 6888 if (reversed) {
6889 deferred = new DeferredInlineSmiAddReversed(operand->reg(), 6889 deferred = new DeferredInlineSmiAddReversed(operand->reg(),
6890 smi_value, 6890 smi_value,
6891 overwrite_mode); 6891 overwrite_mode);
6892 } else { 6892 } else {
6893 deferred = new DeferredInlineSmiAdd(operand->reg(), 6893 deferred = new DeferredInlineSmiAdd(operand->reg(),
6894 smi_value, 6894 smi_value,
6895 overwrite_mode); 6895 overwrite_mode);
6896 } 6896 }
6897 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 6897 JumpIfNotSmiUsingTypeInfo(operand->reg(), operand->type_info(),
6898 deferred);
6898 __ SmiAddConstant(operand->reg(), 6899 __ SmiAddConstant(operand->reg(),
6899 operand->reg(), 6900 operand->reg(),
6900 smi_value, 6901 smi_value,
6901 deferred->entry_label()); 6902 deferred->entry_label());
6902 deferred->BindExit(); 6903 deferred->BindExit();
6903 answer = *operand; 6904 answer = *operand;
6904 break; 6905 break;
6905 } 6906 }
6906 6907
6907 case Token::SUB: { 6908 case Token::SUB: {
6908 if (reversed) { 6909 if (reversed) {
6909 Result constant_operand(value); 6910 Result constant_operand(value);
6910 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand, 6911 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
6911 overwrite_mode); 6912 overwrite_mode);
6912 } else { 6913 } else {
6913 operand->ToRegister(); 6914 operand->ToRegister();
6914 frame_->Spill(operand->reg()); 6915 frame_->Spill(operand->reg());
6915 DeferredCode* deferred = new DeferredInlineSmiSub(operand->reg(), 6916 DeferredCode* deferred = new DeferredInlineSmiSub(operand->reg(),
6916 smi_value, 6917 smi_value,
6917 overwrite_mode); 6918 overwrite_mode);
6918 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 6919 JumpIfNotSmiUsingTypeInfo(operand->reg(), operand->type_info(),
6920 deferred);
6919 // A smi currently fits in a 32-bit Immediate. 6921 // A smi currently fits in a 32-bit Immediate.
6920 __ SmiSubConstant(operand->reg(), 6922 __ SmiSubConstant(operand->reg(),
6921 operand->reg(), 6923 operand->reg(),
6922 smi_value, 6924 smi_value,
6923 deferred->entry_label()); 6925 deferred->entry_label());
6924 deferred->BindExit(); 6926 deferred->BindExit();
6925 answer = *operand; 6927 answer = *operand;
6926 } 6928 }
6927 break; 6929 break;
6928 } 6930 }
6929 6931
6930 case Token::SAR: 6932 case Token::SAR:
6931 if (reversed) { 6933 if (reversed) {
6932 Result constant_operand(value); 6934 Result constant_operand(value);
6933 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand, 6935 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
6934 overwrite_mode); 6936 overwrite_mode);
6935 } else { 6937 } else {
6936 // Only the least significant 5 bits of the shift value are used. 6938 // Only the least significant 5 bits of the shift value are used.
6937 // In the slow case, this masking is done inside the runtime call. 6939 // In the slow case, this masking is done inside the runtime call.
6938 int shift_value = int_value & 0x1f; 6940 int shift_value = int_value & 0x1f;
6939 operand->ToRegister(); 6941 operand->ToRegister();
6940 frame_->Spill(operand->reg()); 6942 frame_->Spill(operand->reg());
6941 DeferredInlineSmiOperation* deferred = 6943 DeferredInlineSmiOperation* deferred =
6942 new DeferredInlineSmiOperation(op, 6944 new DeferredInlineSmiOperation(op,
6943 operand->reg(), 6945 operand->reg(),
6944 operand->reg(), 6946 operand->reg(),
6945 smi_value, 6947 smi_value,
6946 overwrite_mode); 6948 overwrite_mode);
6947 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 6949 JumpIfNotSmiUsingTypeInfo(operand->reg(), operand->type_info(),
6950 deferred);
6948 __ SmiShiftArithmeticRightConstant(operand->reg(), 6951 __ SmiShiftArithmeticRightConstant(operand->reg(),
6949 operand->reg(), 6952 operand->reg(),
6950 shift_value); 6953 shift_value);
6951 deferred->BindExit(); 6954 deferred->BindExit();
6952 answer = *operand; 6955 answer = *operand;
6953 } 6956 }
6954 break; 6957 break;
6955 6958
6956 case Token::SHR: 6959 case Token::SHR:
6957 if (reversed) { 6960 if (reversed) {
6958 Result constant_operand(value); 6961 Result constant_operand(value);
6959 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand, 6962 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
6960 overwrite_mode); 6963 overwrite_mode);
6961 } else { 6964 } else {
6962 // Only the least significant 5 bits of the shift value are used. 6965 // Only the least significant 5 bits of the shift value are used.
6963 // In the slow case, this masking is done inside the runtime call. 6966 // In the slow case, this masking is done inside the runtime call.
6964 int shift_value = int_value & 0x1f; 6967 int shift_value = int_value & 0x1f;
6965 operand->ToRegister(); 6968 operand->ToRegister();
6966 answer = allocator()->Allocate(); 6969 answer = allocator()->Allocate();
6967 ASSERT(answer.is_valid()); 6970 ASSERT(answer.is_valid());
6968 DeferredInlineSmiOperation* deferred = 6971 DeferredInlineSmiOperation* deferred =
6969 new DeferredInlineSmiOperation(op, 6972 new DeferredInlineSmiOperation(op,
6970 answer.reg(), 6973 answer.reg(),
6971 operand->reg(), 6974 operand->reg(),
6972 smi_value, 6975 smi_value,
6973 overwrite_mode); 6976 overwrite_mode);
6974 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 6977 JumpIfNotSmiUsingTypeInfo(operand->reg(), operand->type_info(),
6978 deferred);
6975 __ SmiShiftLogicalRightConstant(answer.reg(), 6979 __ SmiShiftLogicalRightConstant(answer.reg(),
6976 operand->reg(), 6980 operand->reg(),
6977 shift_value, 6981 shift_value,
6978 deferred->entry_label()); 6982 deferred->entry_label());
6979 deferred->BindExit(); 6983 deferred->BindExit();
6980 operand->Unuse(); 6984 operand->Unuse();
6981 } 6985 }
6982 break; 6986 break;
6983 6987
6984 case Token::SHL: 6988 case Token::SHL:
(...skipping 11 matching lines...) Expand all
6996 answer = allocator()->Allocate(); 7000 answer = allocator()->Allocate();
6997 // rcx_reg goes out of scope. 7001 // rcx_reg goes out of scope.
6998 } 7002 }
6999 7003
7000 DeferredInlineSmiOperationReversed* deferred = 7004 DeferredInlineSmiOperationReversed* deferred =
7001 new DeferredInlineSmiOperationReversed(op, 7005 new DeferredInlineSmiOperationReversed(op,
7002 answer.reg(), 7006 answer.reg(),
7003 smi_value, 7007 smi_value,
7004 operand->reg(), 7008 operand->reg(),
7005 overwrite_mode); 7009 overwrite_mode);
7006 if (!operand->type_info().IsSmi()) { 7010 JumpIfNotSmiUsingTypeInfo(operand->reg(), operand->type_info(),
7007 Condition is_smi = masm_->CheckSmi(operand->reg()); 7011 deferred);
7008 deferred->Branch(NegateCondition(is_smi));
7009 } else if (FLAG_debug_code) {
7010 __ AbortIfNotSmi(operand->reg());
7011 }
7012 7012
7013 __ Move(answer.reg(), smi_value); 7013 __ Move(answer.reg(), smi_value);
7014 __ SmiShiftLeft(answer.reg(), answer.reg(), operand->reg()); 7014 __ SmiShiftLeft(answer.reg(), answer.reg(), operand->reg());
7015 operand->Unuse(); 7015 operand->Unuse();
7016 7016
7017 deferred->BindExit(); 7017 deferred->BindExit();
7018 } else { 7018 } else {
7019 // Only the least significant 5 bits of the shift value are used. 7019 // Only the least significant 5 bits of the shift value are used.
7020 // In the slow case, this masking is done inside the runtime call. 7020 // In the slow case, this masking is done inside the runtime call.
7021 int shift_value = int_value & 0x1f; 7021 int shift_value = int_value & 0x1f;
7022 operand->ToRegister(); 7022 operand->ToRegister();
7023 if (shift_value == 0) { 7023 if (shift_value == 0) {
7024 // Spill operand so it can be overwritten in the slow case. 7024 // Spill operand so it can be overwritten in the slow case.
7025 frame_->Spill(operand->reg()); 7025 frame_->Spill(operand->reg());
7026 DeferredInlineSmiOperation* deferred = 7026 DeferredInlineSmiOperation* deferred =
7027 new DeferredInlineSmiOperation(op, 7027 new DeferredInlineSmiOperation(op,
7028 operand->reg(), 7028 operand->reg(),
7029 operand->reg(), 7029 operand->reg(),
7030 smi_value, 7030 smi_value,
7031 overwrite_mode); 7031 overwrite_mode);
7032 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 7032 JumpIfNotSmiUsingTypeInfo(operand->reg(), operand->type_info(),
7033 deferred);
7033 deferred->BindExit(); 7034 deferred->BindExit();
7034 answer = *operand; 7035 answer = *operand;
7035 } else { 7036 } else {
7036 // Use a fresh temporary for nonzero shift values. 7037 // Use a fresh temporary for nonzero shift values.
7037 answer = allocator()->Allocate(); 7038 answer = allocator()->Allocate();
7038 ASSERT(answer.is_valid()); 7039 ASSERT(answer.is_valid());
7039 DeferredInlineSmiOperation* deferred = 7040 DeferredInlineSmiOperation* deferred =
7040 new DeferredInlineSmiOperation(op, 7041 new DeferredInlineSmiOperation(op,
7041 answer.reg(), 7042 answer.reg(),
7042 operand->reg(), 7043 operand->reg(),
7043 smi_value, 7044 smi_value,
7044 overwrite_mode); 7045 overwrite_mode);
7045 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 7046 JumpIfNotSmiUsingTypeInfo(operand->reg(), operand->type_info(),
7047 deferred);
7046 __ SmiShiftLeftConstant(answer.reg(), 7048 __ SmiShiftLeftConstant(answer.reg(),
7047 operand->reg(), 7049 operand->reg(),
7048 shift_value); 7050 shift_value);
7049 deferred->BindExit(); 7051 deferred->BindExit();
7050 operand->Unuse(); 7052 operand->Unuse();
7051 } 7053 }
7052 } 7054 }
7053 break; 7055 break;
7054 7056
7055 case Token::BIT_OR: 7057 case Token::BIT_OR:
7056 case Token::BIT_XOR: 7058 case Token::BIT_XOR:
7057 case Token::BIT_AND: { 7059 case Token::BIT_AND: {
7058 operand->ToRegister(); 7060 operand->ToRegister();
7059 frame_->Spill(operand->reg()); 7061 frame_->Spill(operand->reg());
7060 if (reversed) { 7062 if (reversed) {
7061 // Bit operations with a constant smi are commutative. 7063 // Bit operations with a constant smi are commutative.
7062 // We can swap left and right operands with no problem. 7064 // We can swap left and right operands with no problem.
7063 // Swap left and right overwrite modes. 0->0, 1->2, 2->1. 7065 // Swap left and right overwrite modes. 0->0, 1->2, 2->1.
7064 overwrite_mode = static_cast<OverwriteMode>((2 * overwrite_mode) % 3); 7066 overwrite_mode = static_cast<OverwriteMode>((2 * overwrite_mode) % 3);
7065 } 7067 }
7066 DeferredCode* deferred = new DeferredInlineSmiOperation(op, 7068 DeferredCode* deferred = new DeferredInlineSmiOperation(op,
7067 operand->reg(), 7069 operand->reg(),
7068 operand->reg(), 7070 operand->reg(),
7069 smi_value, 7071 smi_value,
7070 overwrite_mode); 7072 overwrite_mode);
7071 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 7073 JumpIfNotSmiUsingTypeInfo(operand->reg(), operand->type_info(),
7074 deferred);
7072 if (op == Token::BIT_AND) { 7075 if (op == Token::BIT_AND) {
7073 __ SmiAndConstant(operand->reg(), operand->reg(), smi_value); 7076 __ SmiAndConstant(operand->reg(), operand->reg(), smi_value);
7074 } else if (op == Token::BIT_XOR) { 7077 } else if (op == Token::BIT_XOR) {
7075 if (int_value != 0) { 7078 if (int_value != 0) {
7076 __ SmiXorConstant(operand->reg(), operand->reg(), smi_value); 7079 __ SmiXorConstant(operand->reg(), operand->reg(), smi_value);
7077 } 7080 }
7078 } else { 7081 } else {
7079 ASSERT(op == Token::BIT_OR); 7082 ASSERT(op == Token::BIT_OR);
7080 if (int_value != 0) { 7083 if (int_value != 0) {
7081 __ SmiOrConstant(operand->reg(), operand->reg(), smi_value); 7084 __ SmiOrConstant(operand->reg(), operand->reg(), smi_value);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
7126 overwrite_mode); 7129 overwrite_mode);
7127 } 7130 }
7128 break; 7131 break;
7129 } 7132 }
7130 } 7133 }
7131 ASSERT(answer.is_valid()); 7134 ASSERT(answer.is_valid());
7132 return answer; 7135 return answer;
7133 } 7136 }
7134 7137
7135 7138
7139 void CodeGenerator::JumpIfNotSmiUsingTypeInfo(Register reg,
7140 TypeInfo type,
7141 DeferredCode* deferred) {
7142 if (!type.IsSmi()) {
7143 __ JumpIfNotSmi(reg, deferred->entry_label());
7144 }
Lasse Reichstein 2010/06/10 10:02:36 Is it possible to have a typeinfo that says that t
7145 if (FLAG_debug_code) {
7146 __ AbortIfNotSmi(reg);
7147 }
7148 }
7149
7150
7136 void CodeGenerator::JumpIfNotBothSmiUsingTypeInfo(Register left, 7151 void CodeGenerator::JumpIfNotBothSmiUsingTypeInfo(Register left,
7137 Register right, 7152 Register right,
7138 TypeInfo left_info, 7153 TypeInfo left_info,
7139 TypeInfo right_info, 7154 TypeInfo right_info,
7140 DeferredCode* deferred) { 7155 DeferredCode* deferred) {
7141 if (!left_info.IsSmi() && !right_info.IsSmi()) { 7156 if (!left_info.IsSmi() && !right_info.IsSmi()) {
7142 __ JumpIfNotBothSmi(left, right, deferred->entry_label()); 7157 __ JumpIfNotBothSmi(left, right, deferred->entry_label());
7143 } else if (!left_info.IsSmi()) { 7158 } else if (!left_info.IsSmi()) {
7144 __ JumpIfNotSmi(left, deferred->entry_label()); 7159 __ JumpIfNotSmi(left, deferred->entry_label());
7145 } else if (!right_info.IsSmi()) { 7160 } else if (!right_info.IsSmi()) {
(...skipping 4784 matching lines...) Expand 10 before | Expand all | Expand 10 after
11930 } 11945 }
11931 11946
11932 #endif 11947 #endif
11933 11948
11934 11949
11935 #undef __ 11950 #undef __
11936 11951
11937 } } // namespace v8::internal 11952 } } // namespace v8::internal
11938 11953
11939 #endif // V8_TARGET_ARCH_X64 11954 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698