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