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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 6812046: X64: Convert HeapNumbers that contain valid smi values to smis in binop-stub. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 8 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 overwrite_name, 1098 overwrite_name,
1099 TRBinaryOpIC::GetName(operands_type_)); 1099 TRBinaryOpIC::GetName(operands_type_));
1100 return name_; 1100 return name_;
1101 } 1101 }
1102 1102
1103 1103
1104 void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, 1104 void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
1105 Label* slow, 1105 Label* slow,
1106 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { 1106 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
1107 1107
1108 // Arguments to TypeRecordingBinaryOpStub are in rdx and rax.
1109 Register left = rdx;
1110 Register right = rax;
1111
1108 // We only generate heapnumber answers for overflowing calculations 1112 // We only generate heapnumber answers for overflowing calculations
1109 // for the four basic arithmetic operations. 1113 // for the four basic arithmetic operations and logical right shift by 0.
1110 bool generate_inline_heapnumber_results = 1114 bool generate_inline_heapnumber_results =
1111 (allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS) && 1115 (allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS) &&
1112 (op_ == Token::ADD || op_ == Token::SUB || 1116 (op_ == Token::ADD || op_ == Token::SUB ||
1113 op_ == Token::MUL || op_ == Token::DIV || op_ == Token::SHR); 1117 op_ == Token::MUL || op_ == Token::DIV || op_ == Token::SHR);
1114 1118
1115 // Arguments to TypeRecordingBinaryOpStub are in rdx and rax.
1116 Register left = rdx;
1117 Register right = rax;
1118
1119
1120 // Smi check of both operands. If op is BIT_OR, the check is delayed 1119 // Smi check of both operands. If op is BIT_OR, the check is delayed
1121 // until after the OR operation. 1120 // until after the OR operation.
1122 Label not_smis; 1121 Label not_smis;
1123 Label use_fp_on_smis; 1122 Label use_fp_on_smis;
1124 Label restore_MOD_registers; // Only used if op_ == Token::MOD. 1123 Label fail;
1125 1124
1126 if (op_ != Token::BIT_OR) { 1125 Comment smi_check_comment(masm, "-- Smi check arguments");
1127 Comment smi_check_comment(masm, "-- Smi check arguments"); 1126 __ JumpIfNotBothSmi(left, right, &not_smis);
1128 __ JumpIfNotBothSmi(left, right, &not_smis);
1129 }
1130 1127
1128 Label smi_values;
1129 __ bind(&smi_values);
1131 // Perform the operation. 1130 // Perform the operation.
1132 Comment perform_smi(masm, "-- Perform smi operation"); 1131 Comment perform_smi(masm, "-- Perform smi operation");
1133 switch (op_) { 1132 switch (op_) {
1134 case Token::ADD: 1133 case Token::ADD:
1135 ASSERT(right.is(rax)); 1134 ASSERT(right.is(rax));
1136 __ SmiAdd(right, right, left, &use_fp_on_smis); // ADD is commutative. 1135 __ SmiAdd(right, right, left, &use_fp_on_smis); // ADD is commutative.
1137 break; 1136 break;
1138 1137
1139 case Token::SUB: 1138 case Token::SUB:
1140 __ SmiSub(left, left, right, &use_fp_on_smis); 1139 __ SmiSub(left, left, right, &use_fp_on_smis);
(...skipping 18 matching lines...) Expand all
1159 // SmiMod will not accept left in rdx or right in rax. 1158 // SmiMod will not accept left in rdx or right in rax.
1160 left = rcx; 1159 left = rcx;
1161 right = rbx; 1160 right = rbx;
1162 __ movq(rbx, rax); 1161 __ movq(rbx, rax);
1163 __ movq(rcx, rdx); 1162 __ movq(rcx, rdx);
1164 __ SmiMod(rax, left, right, &use_fp_on_smis); 1163 __ SmiMod(rax, left, right, &use_fp_on_smis);
1165 break; 1164 break;
1166 1165
1167 case Token::BIT_OR: { 1166 case Token::BIT_OR: {
1168 ASSERT(right.is(rax)); 1167 ASSERT(right.is(rax));
1169 __ movq(rcx, right); // Save the right operand.
1170 __ SmiOr(right, right, left); // BIT_OR is commutative. 1168 __ SmiOr(right, right, left); // BIT_OR is commutative.
William Hesse 2011/04/08 09:27:58 Change to SmiOrAndJumpIfNotBothSmi(right, right, l
1171 __ JumpIfNotSmi(right, &not_smis); // Test delayed until after BIT_OR.
1172 break; 1169 break;
1173 } 1170 }
1174 case Token::BIT_XOR: 1171 case Token::BIT_XOR:
1175 ASSERT(right.is(rax)); 1172 ASSERT(right.is(rax));
1176 __ SmiXor(right, right, left); // BIT_XOR is commutative. 1173 __ SmiXor(right, right, left); // BIT_XOR is commutative.
1177 break; 1174 break;
1178 1175
1179 case Token::BIT_AND: 1176 case Token::BIT_AND:
1180 ASSERT(right.is(rax)); 1177 ASSERT(right.is(rax));
1181 __ SmiAnd(right, right, left); // BIT_AND is commutative. 1178 __ SmiAnd(right, right, left); // BIT_AND is commutative.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 case Token::ADD: __ addsd(xmm0, xmm1); break; 1223 case Token::ADD: __ addsd(xmm0, xmm1); break;
1227 case Token::SUB: __ subsd(xmm0, xmm1); break; 1224 case Token::SUB: __ subsd(xmm0, xmm1); break;
1228 case Token::MUL: __ mulsd(xmm0, xmm1); break; 1225 case Token::MUL: __ mulsd(xmm0, xmm1); break;
1229 case Token::DIV: __ divsd(xmm0, xmm1); break; 1226 case Token::DIV: __ divsd(xmm0, xmm1); break;
1230 default: UNREACHABLE(); 1227 default: UNREACHABLE();
1231 } 1228 }
1232 } 1229 }
1233 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0); 1230 __ movsd(FieldOperand(rcx, HeapNumber::kValueOffset), xmm0);
1234 __ movq(rax, rcx); 1231 __ movq(rax, rcx);
1235 __ ret(0); 1232 __ ret(0);
1233 } else {
1234 __ jmp(&fail);
1236 } 1235 }
1237 } 1236 }
1238 1237
1239 // 7. Non-smi operands reach the end of the code generated by 1238 // 7. Non-smi operands reach the end of the code generated by
1240 // GenerateSmiCode, and fall through to subsequent code, 1239 // GenerateSmiCode, and fall through to subsequent code,
1241 // with the operands in rdx and rax. 1240 // with the operands in rdx and rax.
1241 // But first we check if non-smi values are HeapNumbers holding
1242 // values that could be smi.
1242 Comment done_comment(masm, "-- Enter non-smi code"); 1243 Comment done_comment(masm, "-- Enter non-smi code");
1243 __ bind(&not_smis); 1244 __ bind(&not_smis);
1244 if (op_ == Token::BIT_OR) { 1245 { // See if there were smi values stored in HeapNumbers.
William Hesse 2011/04/08 09:27:58 I would use LoadAsIntegers (really LoadUnknownsAsI
Lasse Reichstein 2011/04/08 11:18:10 LoadNumberAsIntegers will do truncating conversion
1245 __ movq(right, rcx); 1246 __ LoadRoot(rcx, Heap::kHeapNumberMapRootIndex);
1247 NearLabel left_smi, check_right;
1248 __ JumpIfSmi(left, &left_smi);
1249 __ cmpq(FieldOperand(left, HeapObject::kMapOffset), rcx);
1250 __ j(not_equal, &fail);
1251 // Convert HeapNumber to smi if possible.
1252 __ movsd(xmm0, FieldOperand(left, HeapNumber::kValueOffset));
1253 __ movq(rbx, xmm0);
1254 __ cvttsd2siq(rdi, xmm0);
1255 // Check if conversion was successful by converting back and
1256 // comparing to the original double's bits.
1257 __ cvtlsi2sd(xmm1, rdi);
1258 __ movq(kScratchRegister, xmm1);
1259 __ cmpq(rbx, kScratchRegister);
1260 __ j(not_equal, &fail);
1261 __ Integer32ToSmi(left, rdi);
1262
1263 __ bind(&check_right);
1264 __ JumpIfSmi(right, &smi_values);
1265 __ bind(&left_smi);
1266 if (FLAG_debug_code) {
1267 // One of left or right should be non-smi if we get here.
1268 __ AbortIfSmi(right);
1269 }
1270 __ cmpq(FieldOperand(right, HeapObject::kMapOffset), rcx);
1271 __ j(not_equal, &fail);
1272 // Convert right to smi, if possible.
1273 __ movsd(xmm0, FieldOperand(right, HeapNumber::kValueOffset));
1274 __ movq(rbx, xmm0);
1275 __ cvttsd2siq(rdi, xmm0);
1276 __ cvtlsi2sd(xmm1, rdi);
1277 __ movq(kScratchRegister, xmm1);
1278 __ cmpq(rbx, kScratchRegister);
1279 __ j(not_equal, &fail);
1280 __ Integer32ToSmi(right, rdi);
1281 __ jmp(&smi_values);
1246 } 1282 }
1283 __ bind(&fail);
1247 } 1284 }
1248 1285
1249 1286
1250 void TypeRecordingBinaryOpStub::GenerateFloatingPointCode( 1287 void TypeRecordingBinaryOpStub::GenerateFloatingPointCode(
1251 MacroAssembler* masm, 1288 MacroAssembler* masm,
1252 Label* allocation_failure, 1289 Label* allocation_failure,
1253 Label* non_numeric_failure) { 1290 Label* non_numeric_failure) {
1254 switch (op_) { 1291 switch (op_) {
1255 case Token::ADD: 1292 case Token::ADD:
1256 case Token::SUB: 1293 case Token::SUB:
(...skipping 3885 matching lines...) Expand 10 before | Expand all | Expand 10 after
5142 // Do a tail call to the rewritten stub. 5179 // Do a tail call to the rewritten stub.
5143 __ jmp(rdi); 5180 __ jmp(rdi);
5144 } 5181 }
5145 5182
5146 5183
5147 #undef __ 5184 #undef __
5148 5185
5149 } } // namespace v8::internal 5186 } } // namespace v8::internal
5150 5187
5151 #endif // V8_TARGET_ARCH_X64 5188 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/v8globals.h ('K') | « src/v8globals.h ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698