| 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" |
| 11 #include "src/compiler/osr.h" | 11 #include "src/compiler/osr.h" |
| 12 #include "src/s390/macro-assembler-s390.h" | 12 #include "src/s390/macro-assembler-s390.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 namespace compiler { | 16 namespace compiler { |
| 17 | 17 |
| 18 #define __ masm()-> | 18 #define __ masm()-> |
| 19 | 19 |
| 20 #define kScratchReg ip | 20 #define kScratchReg ip |
| 21 | 21 |
| 22 // Adds S390-specific methods to convert InstructionOperands. | 22 // Adds S390-specific methods to convert InstructionOperands. |
| 23 class S390OperandConverter final : public InstructionOperandConverter { | 23 class S390OperandConverter final : public InstructionOperandConverter { |
| 24 public: | 24 public: |
| 25 S390OperandConverter(CodeGenerator* gen, Instruction* instr) | 25 S390OperandConverter(CodeGenerator* gen, Instruction* instr) |
| 26 : InstructionOperandConverter(gen, instr) {} | 26 : InstructionOperandConverter(gen, instr) {} |
| 27 | 27 |
| 28 size_t OutputCount() { return instr_->OutputCount(); } | 28 size_t OutputCount() { return instr_->OutputCount(); } |
| 29 | 29 |
| 30 bool Is64BitOperand(int index) { |
| 31 return LocationOperand::cast(instr_->InputAt(index))->representation() == |
| 32 MachineRepresentation::kWord64; |
| 33 } |
| 34 |
| 35 bool Is32BitOperand(int index) { |
| 36 return LocationOperand::cast(instr_->InputAt(index))->representation() == |
| 37 MachineRepresentation::kWord32; |
| 38 } |
| 39 |
| 30 bool CompareLogical() const { | 40 bool CompareLogical() const { |
| 31 switch (instr_->flags_condition()) { | 41 switch (instr_->flags_condition()) { |
| 32 case kUnsignedLessThan: | 42 case kUnsignedLessThan: |
| 33 case kUnsignedGreaterThanOrEqual: | 43 case kUnsignedGreaterThanOrEqual: |
| 34 case kUnsignedLessThanOrEqual: | 44 case kUnsignedLessThanOrEqual: |
| 35 case kUnsignedGreaterThan: | 45 case kUnsignedGreaterThan: |
| 36 return true; | 46 return true; |
| 37 default: | 47 default: |
| 38 return false; | 48 return false; |
| 39 } | 49 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 MemOperand ToMemOperand(InstructionOperand* op) const { | 107 MemOperand ToMemOperand(InstructionOperand* op) const { |
| 98 DCHECK_NOT_NULL(op); | 108 DCHECK_NOT_NULL(op); |
| 99 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); | 109 DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); |
| 100 return SlotToMemOperand(AllocatedOperand::cast(op)->index()); | 110 return SlotToMemOperand(AllocatedOperand::cast(op)->index()); |
| 101 } | 111 } |
| 102 | 112 |
| 103 MemOperand SlotToMemOperand(int slot) const { | 113 MemOperand SlotToMemOperand(int slot) const { |
| 104 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); | 114 FrameOffset offset = frame_access_state()->GetFrameOffset(slot); |
| 105 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); | 115 return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset()); |
| 106 } | 116 } |
| 117 |
| 118 MemOperand InputStackSlot(size_t index) { |
| 119 InstructionOperand* op = instr_->InputAt(index); |
| 120 return SlotToMemOperand(AllocatedOperand::cast(op)->index()); |
| 121 } |
| 107 }; | 122 }; |
| 108 | 123 |
| 109 static inline bool HasRegisterInput(Instruction* instr, int index) { | 124 static inline bool HasRegisterInput(Instruction* instr, int index) { |
| 110 return instr->InputAt(index)->IsRegister(); | 125 return instr->InputAt(index)->IsRegister(); |
| 111 } | 126 } |
| 112 | 127 |
| 128 static inline bool HasImmediateInput(Instruction* instr, size_t index) { |
| 129 return instr->InputAt(index)->IsImmediate(); |
| 130 } |
| 131 |
| 132 static inline bool HasStackSlotInput(Instruction* instr, size_t index) { |
| 133 return instr->InputAt(index)->IsStackSlot(); |
| 134 } |
| 135 |
| 113 namespace { | 136 namespace { |
| 114 | 137 |
| 115 class OutOfLineLoadNAN32 final : public OutOfLineCode { | 138 class OutOfLineLoadNAN32 final : public OutOfLineCode { |
| 116 public: | 139 public: |
| 117 OutOfLineLoadNAN32(CodeGenerator* gen, DoubleRegister result) | 140 OutOfLineLoadNAN32(CodeGenerator* gen, DoubleRegister result) |
| 118 : OutOfLineCode(gen), result_(result) {} | 141 : OutOfLineCode(gen), result_(result) {} |
| 119 | 142 |
| 120 void Generate() final { | 143 void Generate() final { |
| 121 __ LoadDoubleLiteral(result_, std::numeric_limits<float>::quiet_NaN(), | 144 __ LoadDoubleLiteral(result_, std::numeric_limits<float>::quiet_NaN(), |
| 122 kScratchReg); | 145 kScratchReg); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 do { \ | 303 do { \ |
| 281 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ | 304 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ |
| 282 i.InputDoubleRegister(1)); \ | 305 i.InputDoubleRegister(1)); \ |
| 283 } while (0) | 306 } while (0) |
| 284 | 307 |
| 285 #define ASSEMBLE_BINOP(asm_instr) \ | 308 #define ASSEMBLE_BINOP(asm_instr) \ |
| 286 do { \ | 309 do { \ |
| 287 if (HasRegisterInput(instr, 1)) { \ | 310 if (HasRegisterInput(instr, 1)) { \ |
| 288 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ | 311 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ |
| 289 i.InputRegister(1)); \ | 312 i.InputRegister(1)); \ |
| 290 } else { \ | 313 } else if (HasImmediateInput(instr, 1)) { \ |
| 291 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ | 314 __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ |
| 292 i.InputImmediate(1)); \ | 315 i.InputImmediate(1)); \ |
| 316 } else { \ |
| 317 UNIMPLEMENTED(); \ |
| 293 } \ | 318 } \ |
| 294 } while (0) | 319 } while (0) |
| 295 | 320 |
| 296 #define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \ | 321 #define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr) \ |
| 297 do { \ | 322 do { \ |
| 298 if (HasRegisterInput(instr, 1)) { \ | 323 if (HasRegisterInput(instr, 1)) { \ |
| 299 if (i.CompareLogical()) { \ | 324 if (i.CompareLogical()) { \ |
| 300 __ cmpl_instr(i.InputRegister(0), i.InputRegister(1)); \ | 325 __ cmpl_instr(i.InputRegister(0), i.InputRegister(1)); \ |
| 301 } else { \ | 326 } else { \ |
| 302 __ cmp_instr(i.InputRegister(0), i.InputRegister(1)); \ | 327 __ cmp_instr(i.InputRegister(0), i.InputRegister(1)); \ |
| (...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1241 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1217 __ sdbr(i.OutputDoubleRegister(), kScratchDoubleReg); | 1242 __ sdbr(i.OutputDoubleRegister(), kScratchDoubleReg); |
| 1218 } else { | 1243 } else { |
| 1219 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) { | 1244 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) { |
| 1220 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1245 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1221 } | 1246 } |
| 1222 __ sdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); | 1247 __ sdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); |
| 1223 } | 1248 } |
| 1224 break; | 1249 break; |
| 1225 case kS390_Mul32: | 1250 case kS390_Mul32: |
| 1226 #if V8_TARGET_ARCH_S390X | 1251 if (HasRegisterInput(instr, 1)) { |
| 1252 __ Mul32(i.InputRegister(0), i.InputRegister(1)); |
| 1253 } else if (HasImmediateInput(instr, 1)) { |
| 1254 __ Mul32(i.InputRegister(0), i.InputImmediate(1)); |
| 1255 } else if (HasStackSlotInput(instr, 1)) { |
| 1256 #ifdef V8_TARGET_ARCH_S390X |
| 1257 // Avoid endian-issue here: |
| 1258 // stg r1, 0(fp) |
| 1259 // ... |
| 1260 // msy r2, 0(fp) <-- This will read the upper 32 bits |
| 1261 __ lg(kScratchReg, i.InputStackSlot(1)); |
| 1262 __ Mul32(i.InputRegister(0), kScratchReg); |
| 1263 #else |
| 1264 __ Mul32(i.InputRegister(0), i.InputStackSlot(1)); |
| 1265 #endif |
| 1266 } else { |
| 1267 UNIMPLEMENTED(); |
| 1268 } |
| 1269 break; |
| 1227 case kS390_Mul64: | 1270 case kS390_Mul64: |
| 1228 #endif | 1271 if (HasRegisterInput(instr, 1)) { |
| 1229 __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1)); | 1272 __ Mul64(i.InputRegister(0), i.InputRegister(1)); |
| 1273 } else if (HasImmediateInput(instr, 1)) { |
| 1274 __ Mul64(i.InputRegister(0), i.InputImmediate(1)); |
| 1275 } else if (HasStackSlotInput(instr, 1)) { |
| 1276 __ Mul64(i.InputRegister(0), i.InputStackSlot(1)); |
| 1277 } else { |
| 1278 UNIMPLEMENTED(); |
| 1279 } |
| 1230 break; | 1280 break; |
| 1231 case kS390_MulHigh32: | 1281 case kS390_MulHigh32: |
| 1232 __ LoadRR(r1, i.InputRegister(0)); | 1282 __ LoadRR(r1, i.InputRegister(0)); |
| 1233 __ mr_z(r0, i.InputRegister(1)); | 1283 if (HasRegisterInput(instr, 1)) { |
| 1284 __ mr_z(r0, i.InputRegister(1)); |
| 1285 } else if (HasStackSlotInput(instr, 1)) { |
| 1286 #ifdef V8_TARGET_ARCH_S390X |
| 1287 // Avoid endian-issue here: |
| 1288 // stg r1, 0(fp) |
| 1289 // ... |
| 1290 // mfy r2, 0(fp) <-- This will read the upper 32 bits |
| 1291 __ lg(kScratchReg, i.InputStackSlot(1)); |
| 1292 __ mr_z(r0, kScratchReg); |
| 1293 #else |
| 1294 __ mfy(r0, i.InputStackSlot(1)); |
| 1295 #endif |
| 1296 } else { |
| 1297 UNIMPLEMENTED(); |
| 1298 } |
| 1234 __ LoadW(i.OutputRegister(), r0); | 1299 __ LoadW(i.OutputRegister(), r0); |
| 1235 break; | 1300 break; |
| 1236 case kS390_Mul32WithHigh32: | 1301 case kS390_Mul32WithHigh32: |
| 1237 __ LoadRR(r1, i.InputRegister(0)); | 1302 __ LoadRR(r1, i.InputRegister(0)); |
| 1238 __ mr_z(r0, i.InputRegister(1)); | 1303 __ mr_z(r0, i.InputRegister(1)); |
| 1239 __ LoadW(i.OutputRegister(0), r1); // low | 1304 __ LoadW(i.OutputRegister(0), r1); // low |
| 1240 __ LoadW(i.OutputRegister(1), r0); // high | 1305 __ LoadW(i.OutputRegister(1), r0); // high |
| 1241 break; | 1306 break; |
| 1242 case kS390_MulHighU32: | 1307 case kS390_MulHighU32: |
| 1243 __ LoadRR(r1, i.InputRegister(0)); | 1308 __ LoadRR(r1, i.InputRegister(0)); |
| 1244 __ mlr(r0, i.InputRegister(1)); | 1309 if (HasRegisterInput(instr, 1)) { |
| 1310 __ mlr(r0, i.InputRegister(1)); |
| 1311 } else if (HasStackSlotInput(instr, 1)) { |
| 1312 #ifdef V8_TARGET_ARCH_S390X |
| 1313 // Avoid endian-issue here: |
| 1314 // stg r1, 0(fp) |
| 1315 // ... |
| 1316 // mfy r2, 0(fp) <-- This will read the upper 32 bits |
| 1317 __ lg(kScratchReg, i.InputStackSlot(1)); |
| 1318 __ mlr(r0, kScratchReg); |
| 1319 #else |
| 1320 __ ml(r0, i.InputStackSlot(1)); |
| 1321 #endif |
| 1322 } else { |
| 1323 UNIMPLEMENTED(); |
| 1324 } |
| 1245 __ LoadlW(i.OutputRegister(), r0); | 1325 __ LoadlW(i.OutputRegister(), r0); |
| 1246 break; | 1326 break; |
| 1247 case kS390_MulFloat: | 1327 case kS390_MulFloat: |
| 1248 // Ensure we don't clobber right | 1328 // Ensure we don't clobber right |
| 1249 if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) { | 1329 if (i.OutputDoubleRegister().is(i.InputDoubleRegister(1))) { |
| 1250 ASSEMBLE_FLOAT_UNOP(meebr); | 1330 ASSEMBLE_FLOAT_UNOP(meebr); |
| 1251 } else { | 1331 } else { |
| 1252 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) | 1332 if (!i.OutputDoubleRegister().is(i.InputDoubleRegister(0))) |
| 1253 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1333 __ ldr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
| 1254 __ meebr(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); | 1334 __ meebr(i.OutputDoubleRegister(), i.InputDoubleRegister(1)); |
| (...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2372 padding_size -= 2; | 2452 padding_size -= 2; |
| 2373 } | 2453 } |
| 2374 } | 2454 } |
| 2375 } | 2455 } |
| 2376 | 2456 |
| 2377 #undef __ | 2457 #undef __ |
| 2378 | 2458 |
| 2379 } // namespace compiler | 2459 } // namespace compiler |
| 2380 } // namespace internal | 2460 } // namespace internal |
| 2381 } // namespace v8 | 2461 } // namespace v8 |
| OLD | NEW |