OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1057 __ Cvttsd2siq(i.OutputRegister(0), i.InputDoubleRegister(0)); | 1057 __ Cvttsd2siq(i.OutputRegister(0), i.InputDoubleRegister(0)); |
1058 } else { | 1058 } else { |
1059 __ Cvttsd2siq(i.OutputRegister(0), i.InputOperand(0)); | 1059 __ Cvttsd2siq(i.OutputRegister(0), i.InputOperand(0)); |
1060 } | 1060 } |
1061 if (instr->OutputCount() > 1) { | 1061 if (instr->OutputCount() > 1) { |
1062 __ Set(i.OutputRegister(1), 0x8000000000000000); | 1062 __ Set(i.OutputRegister(1), 0x8000000000000000); |
1063 __ subq(i.OutputRegister(1), i.OutputRegister(0)); | 1063 __ subq(i.OutputRegister(1), i.OutputRegister(0)); |
1064 } | 1064 } |
1065 break; | 1065 break; |
1066 case kSSEFloat32ToUint64: { | 1066 case kSSEFloat32ToUint64: { |
| 1067 Label done; |
| 1068 Label success; |
| 1069 if (instr->OutputCount() > 1) { |
| 1070 __ Set(i.OutputRegister(1), 0); |
| 1071 __ xorps(kScratchDoubleReg, kScratchDoubleReg); |
| 1072 |
| 1073 if (instr->InputAt(0)->IsDoubleRegister()) { |
| 1074 __ Ucomiss(kScratchDoubleReg, i.InputDoubleRegister(0)); |
| 1075 } else { |
| 1076 __ Ucomiss(kScratchDoubleReg, i.InputOperand(0)); |
| 1077 } |
| 1078 __ j(above, &done); |
| 1079 } |
1067 // There does not exist a Float32ToUint64 instruction, so we have to use | 1080 // There does not exist a Float32ToUint64 instruction, so we have to use |
1068 // the Float32ToInt64 instruction. | 1081 // the Float32ToInt64 instruction. |
1069 if (instr->InputAt(0)->IsDoubleRegister()) { | 1082 if (instr->InputAt(0)->IsDoubleRegister()) { |
1070 __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); | 1083 __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); |
1071 } else { | 1084 } else { |
1072 __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); | 1085 __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); |
1073 } | 1086 } |
1074 // Check if the result of the Float32ToInt64 conversion is positive, we | 1087 // Check if the result of the Float32ToInt64 conversion is positive, we |
1075 // are already done. | 1088 // are already done. |
1076 __ testq(i.OutputRegister(), i.OutputRegister()); | 1089 __ testq(i.OutputRegister(), i.OutputRegister()); |
1077 Label done; | 1090 __ j(positive, &success); |
1078 __ j(positive, &done); | |
1079 // The result of the first conversion was negative, which means that the | 1091 // The result of the first conversion was negative, which means that the |
1080 // input value was not within the positive int64 range. We subtract 2^64 | 1092 // input value was not within the positive int64 range. We subtract 2^64 |
1081 // and convert it again to see if it is within the uint64 range. | 1093 // and convert it again to see if it is within the uint64 range. |
1082 __ Move(kScratchDoubleReg, -9223372036854775808.0f); | 1094 __ Move(kScratchDoubleReg, -9223372036854775808.0f); |
1083 if (instr->InputAt(0)->IsDoubleRegister()) { | 1095 if (instr->InputAt(0)->IsDoubleRegister()) { |
1084 __ addss(kScratchDoubleReg, i.InputDoubleRegister(0)); | 1096 __ addss(kScratchDoubleReg, i.InputDoubleRegister(0)); |
1085 } else { | 1097 } else { |
1086 __ addss(kScratchDoubleReg, i.InputOperand(0)); | 1098 __ addss(kScratchDoubleReg, i.InputOperand(0)); |
1087 } | 1099 } |
1088 __ Cvttss2siq(i.OutputRegister(), kScratchDoubleReg); | 1100 __ Cvttss2siq(i.OutputRegister(), kScratchDoubleReg); |
1089 __ testq(i.OutputRegister(), i.OutputRegister()); | 1101 __ testq(i.OutputRegister(), i.OutputRegister()); |
1090 // The only possible negative value here is 0x80000000000000000, which is | 1102 // The only possible negative value here is 0x80000000000000000, which is |
1091 // used on x64 to indicate an integer overflow. | 1103 // used on x64 to indicate an integer overflow. |
1092 __ j(negative, &done); | 1104 __ j(negative, &done); |
1093 // The input value is within uint64 range and the second conversion worked | 1105 // The input value is within uint64 range and the second conversion worked |
1094 // successfully, but we still have to undo the subtraction we did | 1106 // successfully, but we still have to undo the subtraction we did |
1095 // earlier. | 1107 // earlier. |
1096 __ Set(kScratchRegister, 0x8000000000000000); | 1108 __ Set(kScratchRegister, 0x8000000000000000); |
1097 __ orq(i.OutputRegister(), kScratchRegister); | 1109 __ orq(i.OutputRegister(), kScratchRegister); |
| 1110 __ bind(&success); |
| 1111 if (instr->OutputCount() > 1) { |
| 1112 __ Set(i.OutputRegister(1), 1); |
| 1113 } |
1098 __ bind(&done); | 1114 __ bind(&done); |
1099 break; | 1115 break; |
1100 } | 1116 } |
1101 case kSSEFloat64ToUint64: { | 1117 case kSSEFloat64ToUint64: { |
| 1118 Label done; |
| 1119 Label success; |
| 1120 if (instr->OutputCount() > 1) { |
| 1121 __ Set(i.OutputRegister(1), 0); |
| 1122 __ xorps(kScratchDoubleReg, kScratchDoubleReg); |
| 1123 |
| 1124 if (instr->InputAt(0)->IsDoubleRegister()) { |
| 1125 __ Ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0)); |
| 1126 } else { |
| 1127 __ Ucomisd(kScratchDoubleReg, i.InputOperand(0)); |
| 1128 } |
| 1129 __ j(above, &done); |
| 1130 } |
1102 // There does not exist a Float64ToUint64 instruction, so we have to use | 1131 // There does not exist a Float64ToUint64 instruction, so we have to use |
1103 // the Float64ToInt64 instruction. | 1132 // the Float64ToInt64 instruction. |
1104 if (instr->InputAt(0)->IsDoubleRegister()) { | 1133 if (instr->InputAt(0)->IsDoubleRegister()) { |
1105 __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); | 1134 __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); |
1106 } else { | 1135 } else { |
1107 __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); | 1136 __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); |
1108 } | 1137 } |
1109 if (instr->OutputCount() > 1) { | |
1110 __ Set(i.OutputRegister(1), 0); | |
1111 } | |
1112 // Check if the result of the Float64ToInt64 conversion is positive, we | 1138 // Check if the result of the Float64ToInt64 conversion is positive, we |
1113 // are already done. | 1139 // are already done. |
1114 __ testq(i.OutputRegister(), i.OutputRegister()); | 1140 __ testq(i.OutputRegister(), i.OutputRegister()); |
1115 Label done; | |
1116 Label success; | |
1117 __ j(positive, &success); | 1141 __ j(positive, &success); |
1118 // The result of the first conversion was negative, which means that the | 1142 // The result of the first conversion was negative, which means that the |
1119 // input value was not within the positive int64 range. We subtract 2^64 | 1143 // input value was not within the positive int64 range. We subtract 2^64 |
1120 // and convert it again to see if it is within the uint64 range. | 1144 // and convert it again to see if it is within the uint64 range. |
1121 __ Move(kScratchDoubleReg, -9223372036854775808.0); | 1145 __ Move(kScratchDoubleReg, -9223372036854775808.0); |
1122 if (instr->InputAt(0)->IsDoubleRegister()) { | 1146 if (instr->InputAt(0)->IsDoubleRegister()) { |
1123 __ addsd(kScratchDoubleReg, i.InputDoubleRegister(0)); | 1147 __ addsd(kScratchDoubleReg, i.InputDoubleRegister(0)); |
1124 } else { | 1148 } else { |
1125 __ addsd(kScratchDoubleReg, i.InputOperand(0)); | 1149 __ addsd(kScratchDoubleReg, i.InputOperand(0)); |
1126 } | 1150 } |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2059 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2083 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2060 __ Nop(padding_size); | 2084 __ Nop(padding_size); |
2061 } | 2085 } |
2062 } | 2086 } |
2063 | 2087 |
2064 #undef __ | 2088 #undef __ |
2065 | 2089 |
2066 } // namespace compiler | 2090 } // namespace compiler |
2067 } // namespace internal | 2091 } // namespace internal |
2068 } // namespace v8 | 2092 } // namespace v8 |
OLD | NEW |