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

Side by Side Diff: runtime/lib/integers.cc

Issue 8984003: Port code generator to x64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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 | « no previous file | runtime/vm/assembler_macros_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/bootstrap_natives.h" 5 #include "vm/bootstrap_natives.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/exceptions.h" 9 #include "vm/exceptions.h"
10 #include "vm/native_entry.h" 10 #include "vm/native_entry.h"
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", 196 OS::Print("Integer_bitXorFromInteger %s ^ %s\n",
197 left.ToCString(), right.ToCString()); 197 left.ToCString(), right.ToCString());
198 } 198 }
199 Integer& result = Integer::Handle( 199 Integer& result = Integer::Handle(
200 IntegerBitOperation(Token::kBIT_XOR, left, right)); 200 IntegerBitOperation(Token::kBIT_XOR, left, right));
201 arguments->SetReturn(Integer::Handle(AsInteger(result))); 201 arguments->SetReturn(Integer::Handle(AsInteger(result)));
202 } 202 }
203 203
204 204
205 // The result is invalid if it is outside the range 205 // The result is invalid if it is outside the range
206 // Smi::kMaxValue..Smi::kMinValue. 206 // Smi::kMinValue..Smi::kMaxValue.
207 static int64_t BinaryOpWithTwoSmis(Token::Kind operation, 207 static int64_t BinaryOpWithTwoSmis(Token::Kind operation,
208 const Smi& left, 208 const Smi& left,
209 const Smi& right) { 209 const Smi& right) {
210 switch (operation) { 210 switch (operation) {
211 case Token::kADD: 211 case Token::kADD:
212 // TODO(regis): We may need an overflow check in 64-bit mode. Revisit.
212 return left.Value() + right.Value(); 213 return left.Value() + right.Value();
213 case Token::kSUB: 214 case Token::kSUB:
214 return left.Value() - right.Value(); 215 return left.Value() - right.Value();
215 case Token::kMUL: { 216 case Token::kMUL: {
216 #if defined(TARGET_ARCH_X64) 217 // TODO(regis): Using Bigint here may be a performance issue. Revisit.
217 // Overflow check for 64-bit platforms unimplemented. 218 const Bigint& big_left =
218 UNIMPLEMENTED(); 219 Bigint::Handle(BigintOperations::NewFromSmi(left));
219 return 0; 220 const Bigint& big_right =
220 #else 221 Bigint::Handle(BigintOperations::NewFromSmi(right));
221 int64_t result_64 = 222 const Bigint& big_result =
222 static_cast<int64_t>(left.Value()) * 223 Bigint::Handle(BigintOperations::Multiply(big_left, big_right));
223 static_cast<int64_t>(right.Value()); 224 if (BigintOperations::FitsIntoInt64(big_result)) {
224 return result_64; 225 return BigintOperations::ToInt64(big_result);
225 #endif 226 } else {
227 // Overflow, return an invalid Smi.
228 return Smi::kMaxValue + 1;
229 }
226 } 230 }
227 case Token::kTRUNCDIV: 231 case Token::kTRUNCDIV:
228 return left.Value() / right.Value(); 232 return left.Value() / right.Value();
229 case Token::kMOD: { 233 case Token::kMOD: {
230 intptr_t remainder = left.Value() % right.Value(); 234 intptr_t remainder = left.Value() % right.Value();
231 if (remainder < 0) { 235 if (remainder < 0) {
232 if (right.Value() < 0) { 236 if (right.Value() < 0) {
233 return remainder - right.Value(); 237 return remainder - right.Value();
234 } else { 238 } else {
235 return remainder + right.Value(); 239 return remainder + right.Value();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 const Integer& right_int) { 282 const Integer& right_int) {
279 if (left_int.IsSmi() && right_int.IsSmi()) { 283 if (left_int.IsSmi() && right_int.IsSmi()) {
280 Smi& left_smi = Smi::Handle(); 284 Smi& left_smi = Smi::Handle();
281 Smi& right_smi = Smi::Handle(); 285 Smi& right_smi = Smi::Handle();
282 left_smi ^= left_int.raw(); 286 left_smi ^= left_int.raw();
283 right_smi ^= right_int.raw(); 287 right_smi ^= right_int.raw();
284 int64_t result = BinaryOpWithTwoSmis(operation, left_smi, right_smi); 288 int64_t result = BinaryOpWithTwoSmis(operation, left_smi, right_smi);
285 if (Smi::IsValid64(result)) { 289 if (Smi::IsValid64(result)) {
286 return Smi::New(result); 290 return Smi::New(result);
287 } else { 291 } else {
292 // TODO(regis): This is not going to work on x64. Check other operations.
293 #if defined(TARGET_ARCH_X64)
294 UNIMPLEMENTED();
295 return 0;
296 #else
288 // Overflow to Mint. 297 // Overflow to Mint.
289 return Mint::New(result); 298 return Mint::New(result);
299 #endif
290 } 300 }
291 } else if (AreBoth64bitOperands(left_int, right_int)) { 301 } else if (AreBoth64bitOperands(left_int, right_int)) {
292 // TODO(srdjan): Test for overflow of result instead of operand 302 // TODO(srdjan): Test for overflow of result instead of operand
293 // types. 303 // types.
294 const int64_t a = left_int.AsInt64Value(); 304 const int64_t a = left_int.AsInt64Value();
295 const int64_t b = right_int.AsInt64Value(); 305 const int64_t b = right_int.AsInt64Value();
296 switch (operation) { 306 switch (operation) {
297 case Token::kADD: 307 case Token::kADD:
298 return Integer::New(a + b); 308 return Integer::New(a + b);
299 case Token::kSUB: 309 case Token::kSUB:
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 589
580 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { 590 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) {
581 const Bigint& value = Bigint::CheckedHandle(arguments->At(0)); 591 const Bigint& value = Bigint::CheckedHandle(arguments->At(0));
582 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); 592 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value));
583 ASSERT(CheckInteger(value)); 593 ASSERT(CheckInteger(value));
584 ASSERT(CheckInteger(result)); 594 ASSERT(CheckInteger(result));
585 arguments->SetReturn(Integer::Handle(AsInteger(result))); 595 arguments->SetReturn(Integer::Handle(AsInteger(result)));
586 } 596 }
587 597
588 } // namespace dart 598 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_macros_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698