Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1081 } | 1081 } |
| 1082 } | 1082 } |
| 1083 | 1083 |
| 1084 | 1084 |
| 1085 Register MacroAssembler::GetSmiConstant(Smi* source) { | 1085 Register MacroAssembler::GetSmiConstant(Smi* source) { |
| 1086 int value = source->value(); | 1086 int value = source->value(); |
| 1087 if (value == 0) { | 1087 if (value == 0) { |
| 1088 xorl(kScratchRegister, kScratchRegister); | 1088 xorl(kScratchRegister, kScratchRegister); |
| 1089 return kScratchRegister; | 1089 return kScratchRegister; |
| 1090 } | 1090 } |
| 1091 if (value == 1) { | |
| 1092 return kSmiConstantRegister; | |
| 1093 } | |
| 1094 LoadSmiConstant(kScratchRegister, source); | 1091 LoadSmiConstant(kScratchRegister, source); |
| 1095 return kScratchRegister; | 1092 return kScratchRegister; |
| 1096 } | 1093 } |
| 1097 | 1094 |
| 1098 | 1095 |
| 1099 void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { | 1096 void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { |
| 1100 if (emit_debug_code()) { | 1097 Move(dst, source, Assembler::RelocInfoNone()); |
| 1101 Move(dst, Smi::FromInt(kSmiConstantRegisterValue), | |
| 1102 Assembler::RelocInfoNone()); | |
| 1103 cmpp(dst, kSmiConstantRegister); | |
| 1104 Assert(equal, kUninitializedKSmiConstantRegister); | |
| 1105 } | |
| 1106 int value = source->value(); | |
| 1107 if (value == 0) { | |
| 1108 xorl(dst, dst); | |
| 1109 return; | |
| 1110 } | |
| 1111 bool negative = value < 0; | |
| 1112 unsigned int uvalue = negative ? -value : value; | |
| 1113 | |
| 1114 switch (uvalue) { | |
| 1115 case 9: | |
| 1116 leap(dst, | |
| 1117 Operand(kSmiConstantRegister, kSmiConstantRegister, times_8, 0)); | |
| 1118 break; | |
| 1119 case 8: | |
| 1120 xorl(dst, dst); | |
| 1121 leap(dst, Operand(dst, kSmiConstantRegister, times_8, 0)); | |
| 1122 break; | |
| 1123 case 4: | |
| 1124 xorl(dst, dst); | |
| 1125 leap(dst, Operand(dst, kSmiConstantRegister, times_4, 0)); | |
| 1126 break; | |
| 1127 case 5: | |
| 1128 leap(dst, | |
| 1129 Operand(kSmiConstantRegister, kSmiConstantRegister, times_4, 0)); | |
| 1130 break; | |
| 1131 case 3: | |
| 1132 leap(dst, | |
| 1133 Operand(kSmiConstantRegister, kSmiConstantRegister, times_2, 0)); | |
| 1134 break; | |
| 1135 case 2: | |
| 1136 leap(dst, | |
| 1137 Operand(kSmiConstantRegister, kSmiConstantRegister, times_1, 0)); | |
| 1138 break; | |
| 1139 case 1: | |
| 1140 movp(dst, kSmiConstantRegister); | |
| 1141 break; | |
| 1142 case 0: | |
| 1143 UNREACHABLE(); | |
| 1144 return; | |
| 1145 default: | |
| 1146 Move(dst, source, Assembler::RelocInfoNone()); | |
| 1147 return; | |
| 1148 } | |
| 1149 if (negative) { | |
| 1150 negp(dst); | |
| 1151 } | |
| 1152 } | 1098 } |
| 1153 | 1099 |
| 1154 | 1100 |
| 1155 void MacroAssembler::Integer32ToSmi(Register dst, Register src) { | 1101 void MacroAssembler::Integer32ToSmi(Register dst, Register src) { |
| 1156 STATIC_ASSERT(kSmiTag == 0); | 1102 STATIC_ASSERT(kSmiTag == 0); |
| 1157 if (!dst.is(src)) { | 1103 if (!dst.is(src)) { |
| 1158 movl(dst, src); | 1104 movl(dst, src); |
| 1159 } | 1105 } |
| 1160 shlp(dst, Immediate(kSmiShift)); | 1106 shlp(dst, Immediate(kSmiShift)); |
| 1161 } | 1107 } |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1434 if (!scratch.is(first)) { | 1380 if (!scratch.is(first)) { |
| 1435 movl(scratch, first); | 1381 movl(scratch, first); |
| 1436 } | 1382 } |
| 1437 andl(scratch, second); | 1383 andl(scratch, second); |
| 1438 } | 1384 } |
| 1439 testb(scratch, Immediate(kSmiTagMask)); | 1385 testb(scratch, Immediate(kSmiTagMask)); |
| 1440 return zero; | 1386 return zero; |
| 1441 } | 1387 } |
| 1442 | 1388 |
| 1443 | 1389 |
| 1444 Condition MacroAssembler::CheckIsMinSmi(Register src) { | |
| 1445 ASSERT(!src.is(kScratchRegister)); | |
| 1446 // If we overflow by subtracting one, it's the minimal smi value. | |
| 1447 cmpp(src, kSmiConstantRegister); | |
| 1448 return overflow; | |
| 1449 } | |
| 1450 | |
| 1451 | |
| 1452 Condition MacroAssembler::CheckInteger32ValidSmiValue(Register src) { | 1390 Condition MacroAssembler::CheckInteger32ValidSmiValue(Register src) { |
| 1453 if (SmiValuesAre32Bits()) { | 1391 if (SmiValuesAre32Bits()) { |
| 1454 // A 32-bit integer value can always be converted to a smi. | 1392 // A 32-bit integer value can always be converted to a smi. |
| 1455 return always; | 1393 return always; |
| 1456 } else { | 1394 } else { |
| 1457 ASSERT(SmiValuesAre31Bits()); | 1395 ASSERT(SmiValuesAre31Bits()); |
| 1458 cmpl(src, Immediate(0xc0000000)); | 1396 cmpl(src, Immediate(0xc0000000)); |
| 1459 return positive; | 1397 return positive; |
| 1460 } | 1398 } |
| 1461 } | 1399 } |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1580 | 1518 |
| 1581 | 1519 |
| 1582 void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { | 1520 void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { |
| 1583 if (constant->value() == 0) { | 1521 if (constant->value() == 0) { |
| 1584 if (!dst.is(src)) { | 1522 if (!dst.is(src)) { |
| 1585 movp(dst, src); | 1523 movp(dst, src); |
| 1586 } | 1524 } |
| 1587 return; | 1525 return; |
| 1588 } else if (dst.is(src)) { | 1526 } else if (dst.is(src)) { |
| 1589 ASSERT(!dst.is(kScratchRegister)); | 1527 ASSERT(!dst.is(kScratchRegister)); |
| 1590 switch (constant->value()) { | 1528 Register constant_reg = GetSmiConstant(constant); |
| 1591 case 1: | 1529 addp(dst, constant_reg); |
| 1592 addp(dst, kSmiConstantRegister); | |
| 1593 return; | |
| 1594 case 2: | |
| 1595 leap(dst, Operand(src, kSmiConstantRegister, times_2, 0)); | |
| 1596 return; | |
| 1597 case 4: | |
| 1598 leap(dst, Operand(src, kSmiConstantRegister, times_4, 0)); | |
| 1599 return; | |
| 1600 case 8: | |
| 1601 leap(dst, Operand(src, kSmiConstantRegister, times_8, 0)); | |
| 1602 return; | |
| 1603 default: | |
| 1604 Register constant_reg = GetSmiConstant(constant); | |
| 1605 addp(dst, constant_reg); | |
| 1606 return; | |
| 1607 } | |
| 1608 } else { | 1530 } else { |
| 1609 switch (constant->value()) { | 1531 LoadSmiConstant(dst, constant); |
| 1610 case 1: | 1532 addp(dst, src); |
| 1611 leap(dst, Operand(src, kSmiConstantRegister, times_1, 0)); | |
| 1612 return; | |
| 1613 case 2: | |
| 1614 leap(dst, Operand(src, kSmiConstantRegister, times_2, 0)); | |
| 1615 return; | |
| 1616 case 4: | |
| 1617 leap(dst, Operand(src, kSmiConstantRegister, times_4, 0)); | |
| 1618 return; | |
| 1619 case 8: | |
| 1620 leap(dst, Operand(src, kSmiConstantRegister, times_8, 0)); | |
| 1621 return; | |
| 1622 default: | |
| 1623 LoadSmiConstant(dst, constant); | |
| 1624 addp(dst, src); | |
| 1625 return; | |
| 1626 } | |
| 1627 } | 1533 } |
| 1628 } | 1534 } |
| 1629 | 1535 |
| 1630 | 1536 |
| 1631 void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) { | 1537 void MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) { |
| 1632 if (constant->value() != 0) { | 1538 if (constant->value() != 0) { |
| 1633 if (SmiValuesAre32Bits()) { | 1539 if (SmiValuesAre32Bits()) { |
| 1634 addl(Operand(dst, kSmiShift / kBitsPerByte), | 1540 addl(Operand(dst, kSmiShift / kBitsPerByte), |
| 1635 Immediate(constant->value())); | 1541 Immediate(constant->value())); |
| 1636 } else { | 1542 } else { |
| (...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2893 leal(rsp, Operand(rsp, 4)); | 2799 leal(rsp, Operand(rsp, 4)); |
| 2894 } | 2800 } |
| 2895 } | 2801 } |
| 2896 | 2802 |
| 2897 | 2803 |
| 2898 void MacroAssembler::Pop(const Operand& dst) { | 2804 void MacroAssembler::Pop(const Operand& dst) { |
| 2899 if (kPointerSize == kInt64Size) { | 2805 if (kPointerSize == kInt64Size) { |
| 2900 popq(dst); | 2806 popq(dst); |
| 2901 } else { | 2807 } else { |
| 2902 Register scratch = dst.AddressUsesRegister(kScratchRegister) | 2808 Register scratch = dst.AddressUsesRegister(kScratchRegister) |
| 2903 ? kSmiConstantRegister : kScratchRegister; | 2809 ? kRootRegister : kScratchRegister; |
| 2904 movp(scratch, Operand(rsp, 0)); | 2810 movp(scratch, Operand(rsp, 0)); |
| 2905 movp(dst, scratch); | 2811 movp(dst, scratch); |
| 2906 leal(rsp, Operand(rsp, 4)); | 2812 leal(rsp, Operand(rsp, 4)); |
| 2907 if (scratch.is(kSmiConstantRegister)) { | 2813 if (scratch.is(kRootRegister)) { |
| 2908 // Restore kSmiConstantRegister. | 2814 // Restore kRootRegister. |
| 2909 movp(kSmiConstantRegister, | 2815 InitializeRootRegister(); |
| 2910 reinterpret_cast<void*>(Smi::FromInt(kSmiConstantRegisterValue)), | |
| 2911 Assembler::RelocInfoNone()); | |
| 2912 } | 2816 } |
| 2913 } | 2817 } |
| 2914 } | 2818 } |
| 2915 | 2819 |
| 2916 | 2820 |
| 2917 void MacroAssembler::PopQuad(const Operand& dst) { | 2821 void MacroAssembler::PopQuad(const Operand& dst) { |
| 2918 if (kPointerSize == kInt64Size) { | 2822 if (kPointerSize == kInt64Size) { |
| 2919 popq(dst); | 2823 popq(dst); |
| 2920 } else { | 2824 } else { |
| 2921 popq(kScratchRegister); | 2825 popq(kScratchRegister); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3044 Push(rcx); | 2948 Push(rcx); |
| 3045 Push(rdx); | 2949 Push(rdx); |
| 3046 Push(rbx); | 2950 Push(rbx); |
| 3047 // Not pushing rsp or rbp. | 2951 // Not pushing rsp or rbp. |
| 3048 Push(rsi); | 2952 Push(rsi); |
| 3049 Push(rdi); | 2953 Push(rdi); |
| 3050 Push(r8); | 2954 Push(r8); |
| 3051 Push(r9); | 2955 Push(r9); |
| 3052 // r10 is kScratchRegister. | 2956 // r10 is kScratchRegister. |
| 3053 Push(r11); | 2957 Push(r11); |
| 3054 // r12 is kSmiConstantRegister. | 2958 // TODO(bmeurer): r12 is kSmiConstantRegister. |
|
rmcilroy
2014/08/01 14:46:57
nit - r12 is currently unused (will be kConstantPo
| |
| 3055 // r13 is kRootRegister. | 2959 // r13 is kRootRegister. |
| 3056 Push(r14); | 2960 Push(r14); |
| 3057 Push(r15); | 2961 Push(r15); |
| 3058 STATIC_ASSERT(11 == kNumSafepointSavedRegisters); | 2962 STATIC_ASSERT(11 == kNumSafepointSavedRegisters); |
| 3059 // Use lea for symmetry with Popad. | 2963 // Use lea for symmetry with Popad. |
| 3060 int sp_delta = | 2964 int sp_delta = |
| 3061 (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; | 2965 (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; |
| 3062 leap(rsp, Operand(rsp, -sp_delta)); | 2966 leap(rsp, Operand(rsp, -sp_delta)); |
| 3063 } | 2967 } |
| 3064 | 2968 |
| (...skipping 2311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5376 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift())); | 5280 if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift())); |
| 5377 movl(rax, dividend); | 5281 movl(rax, dividend); |
| 5378 shrl(rax, Immediate(31)); | 5282 shrl(rax, Immediate(31)); |
| 5379 addl(rdx, rax); | 5283 addl(rdx, rax); |
| 5380 } | 5284 } |
| 5381 | 5285 |
| 5382 | 5286 |
| 5383 } } // namespace v8::internal | 5287 } } // namespace v8::internal |
| 5384 | 5288 |
| 5385 #endif // V8_TARGET_ARCH_X64 | 5289 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |