OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 return ge; | 228 return ge; |
229 case kSignedLessThanOrEqual: | 229 case kSignedLessThanOrEqual: |
230 case kUnsignedLessThanOrEqual: | 230 case kUnsignedLessThanOrEqual: |
231 return le; | 231 return le; |
232 case kSignedGreaterThan: | 232 case kSignedGreaterThan: |
233 case kUnsignedGreaterThan: | 233 case kUnsignedGreaterThan: |
234 return gt; | 234 return gt; |
235 case kOverflow: | 235 case kOverflow: |
236 // Overflow checked for AddP/SubP only. | 236 // Overflow checked for AddP/SubP only. |
237 switch (op) { | 237 switch (op) { |
238 #if V8_TARGET_ARCH_S390X | 238 case kS390_Add32: |
239 case kS390_Add: | 239 case kS390_Add64: |
240 case kS390_Sub: | 240 case kS390_Sub32: |
241 #endif | 241 case kS390_Sub64: |
242 case kS390_AddWithOverflow32: | 242 return overflow; |
243 case kS390_SubWithOverflow32: | |
244 return lt; | |
245 default: | 243 default: |
246 break; | 244 break; |
247 } | 245 } |
248 break; | 246 break; |
249 case kNotOverflow: | 247 case kNotOverflow: |
250 switch (op) { | 248 switch (op) { |
251 #if V8_TARGET_ARCH_S390X | 249 case kS390_Add32: |
252 case kS390_Add: | 250 case kS390_Add64: |
253 case kS390_Sub: | 251 case kS390_Sub32: |
254 #endif | 252 case kS390_Sub64: |
255 case kS390_AddWithOverflow32: | 253 return nooverflow; |
256 case kS390_SubWithOverflow32: | |
257 return ge; | |
258 default: | 254 default: |
259 break; | 255 break; |
260 } | 256 } |
261 break; | 257 break; |
262 default: | 258 default: |
263 break; | 259 break; |
264 } | 260 } |
265 UNREACHABLE(); | 261 UNREACHABLE(); |
266 return kNoCondition; | 262 return kNoCondition; |
267 } | 263 } |
(...skipping 15 matching lines...) Expand all Loading... |
283 do { \ | 279 do { \ |
284 if (HasRegisterInput(instr, 1)) { \ | 280 if (HasRegisterInput(instr, 1)) { \ |
285 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ | 281 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ |
286 i.InputRegister(1)); \ | 282 i.InputRegister(1)); \ |
287 } else { \ | 283 } else { \ |
288 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ | 284 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ |
289 i.InputImmediate(1)); \ | 285 i.InputImmediate(1)); \ |
290 } \ | 286 } \ |
291 } while (0) | 287 } while (0) |
292 | 288 |
293 #define ASSEMBLE_BINOP_INT(asm_instr_reg, asm_instr_imm) \ | |
294 do { \ | |
295 if (HasRegisterInput(instr, 1)) { \ | |
296 __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \ | |
297 i.InputRegister(1)); \ | |
298 } else { \ | |
299 __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \ | |
300 i.InputInt32(1)); \ | |
301 } \ | |
302 } while (0) | |
303 | |
304 #define ASSEMBLE_ADD_WITH_OVERFLOW() \ | |
305 do { \ | |
306 if (HasRegisterInput(instr, 1)) { \ | |
307 __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ | |
308 i.InputRegister(1), kScratchReg, r0); \ | |
309 } else { \ | |
310 __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ | |
311 i.InputInt32(1), kScratchReg, r0); \ | |
312 } \ | |
313 } while (0) | |
314 | |
315 #define ASSEMBLE_SUB_WITH_OVERFLOW() \ | |
316 do { \ | |
317 if (HasRegisterInput(instr, 1)) { \ | |
318 __ SubAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ | |
319 i.InputRegister(1), kScratchReg, r0); \ | |
320 } else { \ | |
321 __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \ | |
322 -i.InputInt32(1), kScratchReg, r0); \ | |
323 } \ | |
324 } while (0) | |
325 | |
326 #if V8_TARGET_ARCH_S390X | |
327 #define ASSEMBLE_ADD_WITH_OVERFLOW32() \ | |
328 do { \ | |
329 ASSEMBLE_ADD_WITH_OVERFLOW(); \ | |
330 __ LoadAndTestP_ExtendSrc(kScratchReg, kScratchReg); \ | |
331 } while (0) | |
332 | |
333 #define ASSEMBLE_SUB_WITH_OVERFLOW32() \ | |
334 do { \ | |
335 ASSEMBLE_SUB_WITH_OVERFLOW(); \ | |
336 __ LoadAndTestP_ExtendSrc(kScratchReg, kScratchReg); \ | |
337 } while (0) | |
338 #else | |
339 #define ASSEMBLE_ADD_WITH_OVERFLOW32 ASSEMBLE_ADD_WITH_OVERFLOW | |
340 #define ASSEMBLE_SUB_WITH_OVERFLOW32 ASSEMBLE_SUB_WITH_OVERFLOW | |
341 #endif | |
342 | |
343 #define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \ | 289 #define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \ |
344 do { \ | 290 do { \ |
345 if (HasRegisterInput(instr, 1)) { \ | 291 if (HasRegisterInput(instr, 1)) { \ |
346 if (i.CompareLogical()) { \ | 292 if (i.CompareLogical()) { \ |
347 __ cmpl_instr(i.InputRegister(0), i.InputRegister(1)); \ | 293 __ cmpl_instr(i.InputRegister(0), i.InputRegister(1)); \ |
348 } else { \ | 294 } else { \ |
349 __ cmp_instr(i.InputRegister(0), i.InputRegister(1)); \ | 295 __ cmp_instr(i.InputRegister(0), i.InputRegister(1)); \ |
350 } \ | 296 } \ |
351 } else { \ | 297 } else { \ |
352 if (i.CompareLogical()) { \ | 298 if (i.CompareLogical()) { \ |
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 Operand(endBit), Operand(shiftAmount), true); | 1148 Operand(endBit), Operand(shiftAmount), true); |
1203 } else { | 1149 } else { |
1204 int shiftAmount = i.InputInt32(1); | 1150 int shiftAmount = i.InputInt32(1); |
1205 int clearBit = i.InputInt32(2); | 1151 int clearBit = i.InputInt32(2); |
1206 __ rllg(i.OutputRegister(), i.InputRegister(0), Operand(shiftAmount)); | 1152 __ rllg(i.OutputRegister(), i.InputRegister(0), Operand(shiftAmount)); |
1207 __ srlg(i.OutputRegister(), i.OutputRegister(), Operand(clearBit)); | 1153 __ srlg(i.OutputRegister(), i.OutputRegister(), Operand(clearBit)); |
1208 __ sllg(i.OutputRegister(), i.OutputRegister(), Operand(clearBit)); | 1154 __ sllg(i.OutputRegister(), i.OutputRegister(), Operand(clearBit)); |
1209 } | 1155 } |
1210 break; | 1156 break; |
1211 #endif | 1157 #endif |
1212 case kS390_Add: | 1158 case kS390_Add32: |
1213 #if V8_TARGET_ARCH_S390X | 1159 ASSEMBLE_BINOP(Add32); |
1214 if (FlagsModeField::decode(instr->opcode()) != kFlags_none) { | 1160 __ LoadW(i.OutputRegister(), i.OutputRegister()); |
1215 ASSEMBLE_ADD_WITH_OVERFLOW(); | |
1216 } else { | |
1217 #endif | |
1218 ASSEMBLE_BINOP(AddP); | |
1219 #if V8_TARGET_ARCH_S390X | |
1220 } | |
1221 #endif | |
1222 break; | 1161 break; |
1223 case kS390_AddWithOverflow32: | 1162 case kS390_Add64: |
1224 ASSEMBLE_ADD_WITH_OVERFLOW32(); | 1163 ASSEMBLE_BINOP(AddP); |
1225 break; | 1164 break; |
1226 case kS390_AddFloat: | 1165 case kS390_AddFloat: |
1227 // Ensure we don't clobber right/InputReg(1) | 1166 // Ensure we don't clobber right/InputReg(1) |
1228 if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) { | 1167 if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) { |
1229 ASSEMBLE_FLOAT_UNOP(aebr); | 1168 ASSEMBLE_FLOAT_UNOP(aebr); |
1230 } else { | 1169 } else { |
1231 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) | 1170 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) |
1232 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1171 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1233 __ aebr(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); | 1172 __ aebr(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); |
1234 } | 1173 } |
1235 break; | 1174 break; |
1236 case kS390_AddDouble: | 1175 case kS390_AddDouble: |
1237 // Ensure we don't clobber right/InputReg(1) | 1176 // Ensure we don't clobber right/InputReg(1) |
1238 if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) { | 1177 if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) { |
1239 ASSEMBLE_FLOAT_UNOP(adbr); | 1178 ASSEMBLE_FLOAT_UNOP(adbr); |
1240 } else { | 1179 } else { |
1241 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) | 1180 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) |
1242 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1181 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1243 __ adbr(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); | 1182 __ adbr(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); |
1244 } | 1183 } |
1245 break; | 1184 break; |
1246 case kS390_Sub: | 1185 case kS390_Sub32: |
1247 #if V8_TARGET_ARCH_S390X | 1186 ASSEMBLE_BINOP(Sub32); |
1248 if (FlagsModeField::decode(instr->opcode()) != kFlags_none) { | 1187 __ LoadW(i.OutputRegister(), i.OutputRegister()); |
1249 ASSEMBLE_SUB_WITH_OVERFLOW(); | |
1250 } else { | |
1251 #endif | |
1252 ASSEMBLE_BINOP(SubP); | |
1253 #if V8_TARGET_ARCH_S390X | |
1254 } | |
1255 #endif | |
1256 break; | 1188 break; |
1257 case kS390_SubWithOverflow32: | 1189 case kS390_Sub64: |
1258 ASSEMBLE_SUB_WITH_OVERFLOW32(); | 1190 ASSEMBLE_BINOP(SubP); |
1259 break; | 1191 break; |
1260 case kS390_SubFloat: | 1192 case kS390_SubFloat: |
1261 // OutputDoubleReg() = i.InputDoubleRegister(0) - i.InputDoubleRegister(1) | 1193 // OutputDoubleReg() = i.InputDoubleRegister(0) - i.InputDoubleRegister(1) |
1262 if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) { | 1194 if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) { |
1263 __ ldr(kScratchDoubleReg, i.InputDoubleRegister(1)); | 1195 __ ldr(kScratchDoubleReg, i.InputDoubleRegister(1)); |
1264 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1196 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1265 __ sebr(i.OutputDoubleRegister(), kScratchDoubleReg); | 1197 __ sebr(i.OutputDoubleRegister(), kScratchDoubleReg); |
1266 } else { | 1198 } else { |
1267 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) { | 1199 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) { |
1268 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1200 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1479 break; | 1411 break; |
1480 case kIeee754Float64Log10: | 1412 case kIeee754Float64Log10: |
1481 ASSEMBLE_IEEE754_UNOP(log10); | 1413 ASSEMBLE_IEEE754_UNOP(log10); |
1482 break; | 1414 break; |
1483 case kIeee754Float64Pow: { | 1415 case kIeee754Float64Pow: { |
1484 MathPowStub stub(isolate(), MathPowStub::DOUBLE); | 1416 MathPowStub stub(isolate(), MathPowStub::DOUBLE); |
1485 __ CallStub(&stub); | 1417 __ CallStub(&stub); |
1486 __ Move(d1, d3); | 1418 __ Move(d1, d3); |
1487 break; | 1419 break; |
1488 } | 1420 } |
1489 case kS390_Neg: | 1421 case kS390_Neg32: |
1490 __ LoadComplementRR(i.OutputRegister(), i.InputRegister(0)); | 1422 __ lcr(i.OutputRegister(), i.InputRegister(0)); |
| 1423 __ LoadW(i.OutputRegister(), i.OutputRegister()); |
| 1424 break; |
| 1425 case kS390_Neg64: |
| 1426 __ lcgr(i.OutputRegister(), i.InputRegister(0)); |
1491 break; | 1427 break; |
1492 case kS390_MaxDouble: | 1428 case kS390_MaxDouble: |
1493 ASSEMBLE_FLOAT_MAX(); | 1429 ASSEMBLE_FLOAT_MAX(); |
1494 break; | 1430 break; |
1495 case kS390_MinDouble: | 1431 case kS390_MinDouble: |
1496 ASSEMBLE_FLOAT_MIN(); | 1432 ASSEMBLE_FLOAT_MIN(); |
1497 break; | 1433 break; |
1498 case kS390_AbsDouble: | 1434 case kS390_AbsDouble: |
1499 __ lpdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1435 __ lpdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1500 break; | 1436 break; |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2013 } | 1949 } |
2014 | 1950 |
2015 void CodeGenerator::AssembleArchJump(RpoNumber target) { | 1951 void CodeGenerator::AssembleArchJump(RpoNumber target) { |
2016 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); | 1952 if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target)); |
2017 } | 1953 } |
2018 | 1954 |
2019 // Assembles boolean materializations after an instruction. | 1955 // Assembles boolean materializations after an instruction. |
2020 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 1956 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
2021 FlagsCondition condition) { | 1957 FlagsCondition condition) { |
2022 S390OperandConverter i(this, instr); | 1958 S390OperandConverter i(this, instr); |
2023 Label done; | |
2024 ArchOpcode op = instr->arch_opcode(); | 1959 ArchOpcode op = instr->arch_opcode(); |
2025 bool check_unordered = (op == kS390_CmpDouble || kS390_CmpFloat); | 1960 bool check_unordered = (op == kS390_CmpDouble || op == kS390_CmpFloat); |
2026 | 1961 |
2027 // Overflow checked for add/sub only. | 1962 // Overflow checked for add/sub only. |
2028 DCHECK((condition != kOverflow && condition != kNotOverflow) || | 1963 DCHECK((condition != kOverflow && condition != kNotOverflow) || |
2029 (op == kS390_AddWithOverflow32 || op == kS390_SubWithOverflow32) || | 1964 (op == kS390_Add32 || kS390_Add64 || op == kS390_Sub32 || |
2030 (op == kS390_Add || op == kS390_Sub)); | 1965 op == kS390_Sub64)); |
2031 | 1966 |
2032 // Materialize a full 32-bit 1 or 0 value. The result register is always the | 1967 // Materialize a full 32-bit 1 or 0 value. The result register is always the |
2033 // last output of the instruction. | 1968 // last output of the instruction. |
2034 DCHECK_NE(0u, instr->OutputCount()); | 1969 DCHECK_NE(0u, instr->OutputCount()); |
2035 Register reg = i.OutputRegister(instr->OutputCount() - 1); | 1970 Register reg = i.OutputRegister(instr->OutputCount() - 1); |
2036 Condition cond = FlagsConditionToCondition(condition, op); | 1971 Condition cond = FlagsConditionToCondition(condition, op); |
2037 switch (cond) { | 1972 Label done; |
2038 case ne: | 1973 if (check_unordered) { |
2039 case ge: | 1974 __ LoadImmP(reg, (cond == eq || cond == le || cond == lt) ? Operand::Zero() |
2040 case gt: | 1975 : Operand(1)); |
2041 if (check_unordered) { | 1976 __ bunordered(&done); |
2042 __ LoadImmP(reg, Operand(1)); | |
2043 __ LoadImmP(kScratchReg, Operand::Zero()); | |
2044 __ bunordered(&done); | |
2045 Label cond_true; | |
2046 __ b(cond, &cond_true, Label::kNear); | |
2047 __ LoadRR(reg, kScratchReg); | |
2048 __ bind(&cond_true); | |
2049 } else { | |
2050 Label cond_true, done_here; | |
2051 __ LoadImmP(reg, Operand(1)); | |
2052 __ b(cond, &cond_true, Label::kNear); | |
2053 __ LoadImmP(reg, Operand::Zero()); | |
2054 __ bind(&cond_true); | |
2055 } | |
2056 break; | |
2057 case eq: | |
2058 case lt: | |
2059 case le: | |
2060 if (check_unordered) { | |
2061 __ LoadImmP(reg, Operand::Zero()); | |
2062 __ LoadImmP(kScratchReg, Operand(1)); | |
2063 __ bunordered(&done); | |
2064 Label cond_false; | |
2065 __ b(NegateCondition(cond), &cond_false, Label::kNear); | |
2066 __ LoadRR(reg, kScratchReg); | |
2067 __ bind(&cond_false); | |
2068 } else { | |
2069 __ LoadImmP(reg, Operand::Zero()); | |
2070 Label cond_false; | |
2071 __ b(NegateCondition(cond), &cond_false, Label::kNear); | |
2072 __ LoadImmP(reg, Operand(1)); | |
2073 __ bind(&cond_false); | |
2074 } | |
2075 break; | |
2076 default: | |
2077 UNREACHABLE(); | |
2078 break; | |
2079 } | 1977 } |
| 1978 __ LoadImmP(reg, Operand::Zero()); |
| 1979 __ LoadImmP(kScratchReg, Operand(1)); |
| 1980 // locr is sufficient since reg's upper 32 is guarrantee to be 0 |
| 1981 __ locr(cond, reg, kScratchReg); |
2080 __ bind(&done); | 1982 __ bind(&done); |
2081 } | 1983 } |
2082 | 1984 |
2083 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { | 1985 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { |
2084 S390OperandConverter i(this, instr); | 1986 S390OperandConverter i(this, instr); |
2085 Register input = i.InputRegister(0); | 1987 Register input = i.InputRegister(0); |
2086 for (size_t index = 2; index < instr->InputCount(); index += 2) { | 1988 for (size_t index = 2; index < instr->InputCount(); index += 2) { |
2087 __ Cmp32(input, Operand(i.InputInt32(index + 0))); | 1989 __ Cmp32(input, Operand(i.InputInt32(index + 0))); |
2088 __ beq(GetLabel(i.InputRpo(index + 1))); | 1990 __ beq(GetLabel(i.InputRpo(index + 1))); |
2089 } | 1991 } |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2460 padding_size -= 2; | 2362 padding_size -= 2; |
2461 } | 2363 } |
2462 } | 2364 } |
2463 } | 2365 } |
2464 | 2366 |
2465 #undef __ | 2367 #undef __ |
2466 | 2368 |
2467 } // namespace compiler | 2369 } // namespace compiler |
2468 } // namespace internal | 2370 } // namespace internal |
2469 } // namespace v8 | 2371 } // namespace v8 |
OLD | NEW |