| 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 |