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 |