| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/base/adapters.h" | 5 #include "src/base/adapters.h" |
| 6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
| 7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
| 8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
| 9 #include "src/ppc/frames-ppc.h" | 9 #include "src/ppc/frames-ppc.h" |
| 10 | 10 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, | 135 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, |
| 136 ImmediateMode operand_mode) { | 136 ImmediateMode operand_mode) { |
| 137 FlagsContinuation cont; | 137 FlagsContinuation cont; |
| 138 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); | 138 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); |
| 139 } | 139 } |
| 140 | 140 |
| 141 } // namespace | 141 } // namespace |
| 142 | 142 |
| 143 | 143 |
| 144 void InstructionSelector::VisitLoad(Node* node) { | 144 void InstructionSelector::VisitLoad(Node* node) { |
| 145 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 145 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
| 146 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
| 147 PPCOperandGenerator g(this); | 146 PPCOperandGenerator g(this); |
| 148 Node* base = node->InputAt(0); | 147 Node* base = node->InputAt(0); |
| 149 Node* offset = node->InputAt(1); | 148 Node* offset = node->InputAt(1); |
| 150 | |
| 151 ArchOpcode opcode; | 149 ArchOpcode opcode; |
| 152 ImmediateMode mode = kInt16Imm; | 150 ImmediateMode mode = kInt16Imm; |
| 153 switch (rep) { | 151 switch (load_rep.representation()) { |
| 154 case kRepFloat32: | 152 case MachineRepresentation::kFloat32: |
| 155 opcode = kPPC_LoadFloat32; | 153 opcode = kPPC_LoadFloat32; |
| 156 break; | 154 break; |
| 157 case kRepFloat64: | 155 case MachineRepresentation::kFloat64: |
| 158 opcode = kPPC_LoadDouble; | 156 opcode = kPPC_LoadDouble; |
| 159 break; | 157 break; |
| 160 case kRepBit: // Fall through. | 158 case MachineRepresentation::kBit: // Fall through. |
| 161 case kRepWord8: | 159 case MachineRepresentation::kWord8: |
| 162 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS8 : kPPC_LoadWordU8; | 160 opcode = load_rep.IsSigned() ? kPPC_LoadWordS8 : kPPC_LoadWordU8; |
| 163 break; | 161 break; |
| 164 case kRepWord16: | 162 case MachineRepresentation::kWord16: |
| 165 opcode = (typ == kTypeInt32) ? kPPC_LoadWordS16 : kPPC_LoadWordU16; | 163 opcode = load_rep.IsSigned() ? kPPC_LoadWordS16 : kPPC_LoadWordU16; |
| 166 break; | 164 break; |
| 167 #if !V8_TARGET_ARCH_PPC64 | 165 #if !V8_TARGET_ARCH_PPC64 |
| 168 case kRepTagged: // Fall through. | 166 case MachineRepresentation::kTagged: // Fall through. |
| 169 #endif | 167 #endif |
| 170 case kRepWord32: | 168 case MachineRepresentation::kWord32: |
| 171 opcode = kPPC_LoadWordS32; | 169 opcode = kPPC_LoadWordS32; |
| 172 #if V8_TARGET_ARCH_PPC64 | 170 #if V8_TARGET_ARCH_PPC64 |
| 173 // TODO(mbrandy): this applies to signed loads only (lwa) | 171 // TODO(mbrandy): this applies to signed loads only (lwa) |
| 174 mode = kInt16Imm_4ByteAligned; | 172 mode = kInt16Imm_4ByteAligned; |
| 175 #endif | 173 #endif |
| 176 break; | 174 break; |
| 177 #if V8_TARGET_ARCH_PPC64 | 175 #if V8_TARGET_ARCH_PPC64 |
| 178 case kRepTagged: // Fall through. | 176 case MachineRepresentation::kTagged: // Fall through. |
| 179 case kRepWord64: | 177 case MachineRepresentation::kWord64: |
| 180 opcode = kPPC_LoadWord64; | 178 opcode = kPPC_LoadWord64; |
| 181 mode = kInt16Imm_4ByteAligned; | 179 mode = kInt16Imm_4ByteAligned; |
| 182 break; | 180 break; |
| 183 #endif | 181 #endif |
| 184 default: | 182 default: |
| 185 UNREACHABLE(); | 183 UNREACHABLE(); |
| 186 return; | 184 return; |
| 187 } | 185 } |
| 188 if (g.CanBeImmediate(offset, mode)) { | 186 if (g.CanBeImmediate(offset, mode)) { |
| 189 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 187 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 190 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(offset)); | 188 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(offset)); |
| 191 } else if (g.CanBeImmediate(base, mode)) { | 189 } else if (g.CanBeImmediate(base, mode)) { |
| 192 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 190 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
| 193 g.DefineAsRegister(node), g.UseRegister(offset), g.UseImmediate(base)); | 191 g.DefineAsRegister(node), g.UseRegister(offset), g.UseImmediate(base)); |
| 194 } else { | 192 } else { |
| 195 Emit(opcode | AddressingModeField::encode(kMode_MRR), | 193 Emit(opcode | AddressingModeField::encode(kMode_MRR), |
| 196 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset)); | 194 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset)); |
| 197 } | 195 } |
| 198 } | 196 } |
| 199 | 197 |
| 200 | 198 |
| 201 void InstructionSelector::VisitStore(Node* node) { | 199 void InstructionSelector::VisitStore(Node* node) { |
| 202 PPCOperandGenerator g(this); | 200 PPCOperandGenerator g(this); |
| 203 Node* base = node->InputAt(0); | 201 Node* base = node->InputAt(0); |
| 204 Node* offset = node->InputAt(1); | 202 Node* offset = node->InputAt(1); |
| 205 Node* value = node->InputAt(2); | 203 Node* value = node->InputAt(2); |
| 206 | 204 |
| 207 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 205 StoreRepresentation store_rep = StoreRepresentationOf(node->op()); |
| 208 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 206 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
| 209 MachineType rep = RepresentationOf(store_rep.machine_type()); | 207 MachineRepresentation rep = store_rep.representation(); |
| 210 | 208 |
| 211 // TODO(ppc): I guess this could be done in a better way. | 209 // TODO(ppc): I guess this could be done in a better way. |
| 212 if (write_barrier_kind != kNoWriteBarrier) { | 210 if (write_barrier_kind != kNoWriteBarrier) { |
| 213 DCHECK_EQ(kRepTagged, rep); | 211 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
| 214 InstructionOperand inputs[3]; | 212 InstructionOperand inputs[3]; |
| 215 size_t input_count = 0; | 213 size_t input_count = 0; |
| 216 inputs[input_count++] = g.UseUniqueRegister(base); | 214 inputs[input_count++] = g.UseUniqueRegister(base); |
| 217 inputs[input_count++] = g.UseUniqueRegister(offset); | 215 inputs[input_count++] = g.UseUniqueRegister(offset); |
| 218 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) | 216 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
| 219 ? g.UseRegister(value) | 217 ? g.UseRegister(value) |
| 220 : g.UseUniqueRegister(value); | 218 : g.UseUniqueRegister(value); |
| 221 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; | 219 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
| 222 switch (write_barrier_kind) { | 220 switch (write_barrier_kind) { |
| 223 case kNoWriteBarrier: | 221 case kNoWriteBarrier: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 235 } | 233 } |
| 236 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 234 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 237 size_t const temp_count = arraysize(temps); | 235 size_t const temp_count = arraysize(temps); |
| 238 InstructionCode code = kArchStoreWithWriteBarrier; | 236 InstructionCode code = kArchStoreWithWriteBarrier; |
| 239 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 237 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 240 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 238 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 241 } else { | 239 } else { |
| 242 ArchOpcode opcode; | 240 ArchOpcode opcode; |
| 243 ImmediateMode mode = kInt16Imm; | 241 ImmediateMode mode = kInt16Imm; |
| 244 switch (rep) { | 242 switch (rep) { |
| 245 case kRepFloat32: | 243 case MachineRepresentation::kFloat32: |
| 246 opcode = kPPC_StoreFloat32; | 244 opcode = kPPC_StoreFloat32; |
| 247 break; | 245 break; |
| 248 case kRepFloat64: | 246 case MachineRepresentation::kFloat64: |
| 249 opcode = kPPC_StoreDouble; | 247 opcode = kPPC_StoreDouble; |
| 250 break; | 248 break; |
| 251 case kRepBit: // Fall through. | 249 case MachineRepresentation::kBit: // Fall through. |
| 252 case kRepWord8: | 250 case MachineRepresentation::kWord8: |
| 253 opcode = kPPC_StoreWord8; | 251 opcode = kPPC_StoreWord8; |
| 254 break; | 252 break; |
| 255 case kRepWord16: | 253 case MachineRepresentation::kWord16: |
| 256 opcode = kPPC_StoreWord16; | 254 opcode = kPPC_StoreWord16; |
| 257 break; | 255 break; |
| 258 #if !V8_TARGET_ARCH_PPC64 | 256 #if !V8_TARGET_ARCH_PPC64 |
| 259 case kRepTagged: // Fall through. | 257 case MachineRepresentation::kTagged: // Fall through. |
| 260 #endif | 258 #endif |
| 261 case kRepWord32: | 259 case MachineRepresentation::kWord32: |
| 262 opcode = kPPC_StoreWord32; | 260 opcode = kPPC_StoreWord32; |
| 263 break; | 261 break; |
| 264 #if V8_TARGET_ARCH_PPC64 | 262 #if V8_TARGET_ARCH_PPC64 |
| 265 case kRepTagged: // Fall through. | 263 case MachineRepresentation::kTagged: // Fall through. |
| 266 case kRepWord64: | 264 case MachineRepresentation::kWord64: |
| 267 opcode = kPPC_StoreWord64; | 265 opcode = kPPC_StoreWord64; |
| 268 mode = kInt16Imm_4ByteAligned; | 266 mode = kInt16Imm_4ByteAligned; |
| 269 break; | 267 break; |
| 270 #endif | 268 #endif |
| 271 default: | 269 default: |
| 272 UNREACHABLE(); | 270 UNREACHABLE(); |
| 273 return; | 271 return; |
| 274 } | 272 } |
| 275 if (g.CanBeImmediate(offset, mode)) { | 273 if (g.CanBeImmediate(offset, mode)) { |
| 276 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 274 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 277 g.UseRegister(base), g.UseImmediate(offset), g.UseRegister(value)); | 275 g.UseRegister(base), g.UseImmediate(offset), g.UseRegister(value)); |
| 278 } else if (g.CanBeImmediate(base, mode)) { | 276 } else if (g.CanBeImmediate(base, mode)) { |
| 279 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 277 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
| 280 g.UseRegister(offset), g.UseImmediate(base), g.UseRegister(value)); | 278 g.UseRegister(offset), g.UseImmediate(base), g.UseRegister(value)); |
| 281 } else { | 279 } else { |
| 282 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), | 280 Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), |
| 283 g.UseRegister(base), g.UseRegister(offset), g.UseRegister(value)); | 281 g.UseRegister(base), g.UseRegister(offset), g.UseRegister(value)); |
| 284 } | 282 } |
| 285 } | 283 } |
| 286 } | 284 } |
| 287 | 285 |
| 288 | 286 |
| 289 void InstructionSelector::VisitCheckedLoad(Node* node) { | 287 void InstructionSelector::VisitCheckedLoad(Node* node) { |
| 290 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 288 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
| 291 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
| 292 PPCOperandGenerator g(this); | 289 PPCOperandGenerator g(this); |
| 293 Node* const base = node->InputAt(0); | 290 Node* const base = node->InputAt(0); |
| 294 Node* const offset = node->InputAt(1); | 291 Node* const offset = node->InputAt(1); |
| 295 Node* const length = node->InputAt(2); | 292 Node* const length = node->InputAt(2); |
| 296 ArchOpcode opcode; | 293 ArchOpcode opcode; |
| 297 switch (rep) { | 294 switch (load_rep.representation()) { |
| 298 case kRepWord8: | 295 case MachineRepresentation::kWord8: |
| 299 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 296 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
| 300 break; | 297 break; |
| 301 case kRepWord16: | 298 case MachineRepresentation::kWord16: |
| 302 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 299 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
| 303 break; | 300 break; |
| 304 case kRepWord32: | 301 case MachineRepresentation::kWord32: |
| 305 opcode = kCheckedLoadWord32; | 302 opcode = kCheckedLoadWord32; |
| 306 break; | 303 break; |
| 307 case kRepWord64: | 304 case MachineRepresentation::kWord64: |
| 308 opcode = kCheckedLoadWord64; | 305 opcode = kCheckedLoadWord64; |
| 309 break; | 306 break; |
| 310 case kRepFloat32: | 307 case MachineRepresentation::kFloat32: |
| 311 opcode = kCheckedLoadFloat32; | 308 opcode = kCheckedLoadFloat32; |
| 312 break; | 309 break; |
| 313 case kRepFloat64: | 310 case MachineRepresentation::kFloat64: |
| 314 opcode = kCheckedLoadFloat64; | 311 opcode = kCheckedLoadFloat64; |
| 315 break; | 312 break; |
| 316 default: | 313 default: |
| 317 UNREACHABLE(); | 314 UNREACHABLE(); |
| 318 return; | 315 return; |
| 319 } | 316 } |
| 320 AddressingMode addressingMode = kMode_MRR; | 317 AddressingMode addressingMode = kMode_MRR; |
| 321 Emit(opcode | AddressingModeField::encode(addressingMode), | 318 Emit(opcode | AddressingModeField::encode(addressingMode), |
| 322 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset), | 319 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset), |
| 323 g.UseOperand(length, kInt16Imm_Unsigned)); | 320 g.UseOperand(length, kInt16Imm_Unsigned)); |
| 324 } | 321 } |
| 325 | 322 |
| 326 | 323 |
| 327 void InstructionSelector::VisitCheckedStore(Node* node) { | 324 void InstructionSelector::VisitCheckedStore(Node* node) { |
| 328 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 325 MachineRepresentation rep = CheckedStoreRepresentationOf(node->op()); |
| 329 PPCOperandGenerator g(this); | 326 PPCOperandGenerator g(this); |
| 330 Node* const base = node->InputAt(0); | 327 Node* const base = node->InputAt(0); |
| 331 Node* const offset = node->InputAt(1); | 328 Node* const offset = node->InputAt(1); |
| 332 Node* const length = node->InputAt(2); | 329 Node* const length = node->InputAt(2); |
| 333 Node* const value = node->InputAt(3); | 330 Node* const value = node->InputAt(3); |
| 334 ArchOpcode opcode; | 331 ArchOpcode opcode; |
| 335 switch (rep) { | 332 switch (rep) { |
| 336 case kRepWord8: | 333 case MachineRepresentation::kWord8: |
| 337 opcode = kCheckedStoreWord8; | 334 opcode = kCheckedStoreWord8; |
| 338 break; | 335 break; |
| 339 case kRepWord16: | 336 case MachineRepresentation::kWord16: |
| 340 opcode = kCheckedStoreWord16; | 337 opcode = kCheckedStoreWord16; |
| 341 break; | 338 break; |
| 342 case kRepWord32: | 339 case MachineRepresentation::kWord32: |
| 343 opcode = kCheckedStoreWord32; | 340 opcode = kCheckedStoreWord32; |
| 344 break; | 341 break; |
| 345 case kRepWord64: | 342 case MachineRepresentation::kWord64: |
| 346 opcode = kCheckedStoreWord64; | 343 opcode = kCheckedStoreWord64; |
| 347 break; | 344 break; |
| 348 case kRepFloat32: | 345 case MachineRepresentation::kFloat32: |
| 349 opcode = kCheckedStoreFloat32; | 346 opcode = kCheckedStoreFloat32; |
| 350 break; | 347 break; |
| 351 case kRepFloat64: | 348 case MachineRepresentation::kFloat64: |
| 352 opcode = kCheckedStoreFloat64; | 349 opcode = kCheckedStoreFloat64; |
| 353 break; | 350 break; |
| 354 default: | 351 default: |
| 355 UNREACHABLE(); | 352 UNREACHABLE(); |
| 356 return; | 353 return; |
| 357 } | 354 } |
| 358 AddressingMode addressingMode = kMode_MRR; | 355 AddressingMode addressingMode = kMode_MRR; |
| 359 Emit(opcode | AddressingModeField::encode(addressingMode), g.NoOutput(), | 356 Emit(opcode | AddressingModeField::encode(addressingMode), g.NoOutput(), |
| 360 g.UseRegister(base), g.UseRegister(offset), | 357 g.UseRegister(base), g.UseRegister(offset), |
| 361 g.UseOperand(length, kInt16Imm_Unsigned), g.UseRegister(value)); | 358 g.UseOperand(length, kInt16Imm_Unsigned), g.UseRegister(value)); |
| (...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1723 MachineOperatorBuilder::kFloat64RoundTruncate | | 1720 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1724 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1721 MachineOperatorBuilder::kFloat64RoundTiesAway | |
| 1725 MachineOperatorBuilder::kWord32Popcnt | | 1722 MachineOperatorBuilder::kWord32Popcnt | |
| 1726 MachineOperatorBuilder::kWord64Popcnt; | 1723 MachineOperatorBuilder::kWord64Popcnt; |
| 1727 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. | 1724 // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f. |
| 1728 } | 1725 } |
| 1729 | 1726 |
| 1730 } // namespace compiler | 1727 } // namespace compiler |
| 1731 } // namespace internal | 1728 } // namespace internal |
| 1732 } // namespace v8 | 1729 } // namespace v8 |
| OLD | NEW |