| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 // Nop insertion | 580 // Nop insertion |
| 581 if (Ctx->getFlags().shouldDoNopInsertion()) { | 581 if (Ctx->getFlags().shouldDoNopInsertion()) { |
| 582 Func->doNopInsertion(); | 582 Func->doNopInsertion(); |
| 583 } | 583 } |
| 584 } | 584 } |
| 585 | 585 |
| 586 namespace { | 586 namespace { |
| 587 | 587 |
| 588 bool canRMW(const InstArithmetic *Arith) { | 588 bool canRMW(const InstArithmetic *Arith) { |
| 589 Type Ty = Arith->getDest()->getType(); | 589 Type Ty = Arith->getDest()->getType(); |
| 590 // X86 vector instructions write to a register and have no RMW |
| 591 // option. |
| 592 if (isVectorType(Ty)) |
| 593 return false; |
| 590 bool isI64 = Ty == IceType_i64; | 594 bool isI64 = Ty == IceType_i64; |
| 591 bool isVector = isVectorType(Ty); | |
| 592 | 595 |
| 593 switch (Arith->getOp()) { | 596 switch (Arith->getOp()) { |
| 594 // Not handled for lack of simple lowering: | 597 // Not handled for lack of simple lowering: |
| 595 // shift on i64 and vectors | 598 // shift on i64 |
| 596 // mul, udiv, urem, sdiv, srem, frem | 599 // mul, udiv, urem, sdiv, srem, frem |
| 600 // Not handled for lack of RMW instructions: |
| 601 // fadd, fsub, fmul, fdiv (also vector types) |
| 597 default: | 602 default: |
| 598 return false; | 603 return false; |
| 599 case InstArithmetic::Add: | 604 case InstArithmetic::Add: |
| 600 return !isI64 && !isVector; // TODO(stichnot): implement i64 and vector | |
| 601 case InstArithmetic::Sub: | 605 case InstArithmetic::Sub: |
| 602 case InstArithmetic::And: | 606 case InstArithmetic::And: |
| 603 case InstArithmetic::Or: | 607 case InstArithmetic::Or: |
| 604 case InstArithmetic::Xor: | 608 case InstArithmetic::Xor: |
| 605 case InstArithmetic::Fadd: | |
| 606 case InstArithmetic::Fsub: | |
| 607 case InstArithmetic::Fmul: | |
| 608 case InstArithmetic::Fdiv: | |
| 609 return false; // TODO(stichnot): implement | |
| 610 return true; | 609 return true; |
| 611 case InstArithmetic::Shl: | 610 case InstArithmetic::Shl: |
| 612 case InstArithmetic::Lshr: | 611 case InstArithmetic::Lshr: |
| 613 case InstArithmetic::Ashr: | 612 case InstArithmetic::Ashr: |
| 614 return false; // TODO(stichnot): implement | 613 return false; // TODO(stichnot): implement |
| 615 return !isI64 && !isVector; | 614 return !isI64; |
| 616 } | 615 } |
| 617 } | 616 } |
| 618 | 617 |
| 619 bool isSameMemAddressOperand(const Operand *A, const Operand *B) { | 618 bool isSameMemAddressOperand(const Operand *A, const Operand *B) { |
| 620 if (A == B) | 619 if (A == B) |
| 621 return true; | 620 return true; |
| 622 if (auto *MemA = llvm::dyn_cast<OperandX8632Mem>(A)) { | 621 if (auto *MemA = llvm::dyn_cast<OperandX8632Mem>(A)) { |
| 623 if (auto *MemB = llvm::dyn_cast<OperandX8632Mem>(B)) { | 622 if (auto *MemB = llvm::dyn_cast<OperandX8632Mem>(B)) { |
| 624 return MemA->getBase() == MemB->getBase() && | 623 return MemA->getBase() == MemB->getBase() && |
| 625 MemA->getOffset() == MemB->getOffset() && | 624 MemA->getOffset() == MemB->getOffset() && |
| (...skipping 2809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3435 Context.insert( | 3434 Context.insert( |
| 3436 InstFakeUse::create(Func, Context.getLastInserted()->getDest())); | 3435 InstFakeUse::create(Func, Context.getLastInserted()->getDest())); |
| 3437 return; | 3436 return; |
| 3438 } | 3437 } |
| 3439 case Intrinsics::AtomicRMW: | 3438 case Intrinsics::AtomicRMW: |
| 3440 if (!Intrinsics::isMemoryOrderValid( | 3439 if (!Intrinsics::isMemoryOrderValid( |
| 3441 ID, getConstantMemoryOrder(Instr->getArg(3)))) { | 3440 ID, getConstantMemoryOrder(Instr->getArg(3)))) { |
| 3442 Func->setError("Unexpected memory ordering for AtomicRMW"); | 3441 Func->setError("Unexpected memory ordering for AtomicRMW"); |
| 3443 return; | 3442 return; |
| 3444 } | 3443 } |
| 3445 lowerAtomicRMW(Instr->getDest(), | 3444 lowerAtomicRMW( |
| 3446 static_cast<uint32_t>(llvm::cast<ConstantInteger32>( | 3445 Instr->getDest(), |
| 3447 Instr->getArg(0))->getValue()), | 3446 static_cast<uint32_t>( |
| 3448 Instr->getArg(1), Instr->getArg(2)); | 3447 llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue()), |
| 3448 Instr->getArg(1), Instr->getArg(2)); |
| 3449 return; | 3449 return; |
| 3450 case Intrinsics::AtomicStore: { | 3450 case Intrinsics::AtomicStore: { |
| 3451 if (!Intrinsics::isMemoryOrderValid( | 3451 if (!Intrinsics::isMemoryOrderValid( |
| 3452 ID, getConstantMemoryOrder(Instr->getArg(2)))) { | 3452 ID, getConstantMemoryOrder(Instr->getArg(2)))) { |
| 3453 Func->setError("Unexpected memory ordering for AtomicStore"); | 3453 Func->setError("Unexpected memory ordering for AtomicStore"); |
| 3454 return; | 3454 return; |
| 3455 } | 3455 } |
| 3456 // We require the memory address to be naturally aligned. | 3456 // We require the memory address to be naturally aligned. |
| 3457 // Given that is the case, then normal stores are atomic. | 3457 // Given that is the case, then normal stores are atomic. |
| 3458 // Add a fence after the store to make it visible. | 3458 // Add a fence after the store to make it visible. |
| (...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4653 // still there, either because the value being stored is used beyond | 4653 // still there, either because the value being stored is used beyond |
| 4654 // the Store instruction, or because dead code elimination did not | 4654 // the Store instruction, or because dead code elimination did not |
| 4655 // happen. In either case, we cancel RMW lowering (and the caller | 4655 // happen. In either case, we cancel RMW lowering (and the caller |
| 4656 // deletes the RMW instruction). | 4656 // deletes the RMW instruction). |
| 4657 if (!RMW->isLastUse(RMW->getBeacon())) | 4657 if (!RMW->isLastUse(RMW->getBeacon())) |
| 4658 return; | 4658 return; |
| 4659 Operand *Src = RMW->getData(); | 4659 Operand *Src = RMW->getData(); |
| 4660 Type Ty = Src->getType(); | 4660 Type Ty = Src->getType(); |
| 4661 OperandX8632Mem *Addr = formMemoryOperand(RMW->getAddr(), Ty); | 4661 OperandX8632Mem *Addr = formMemoryOperand(RMW->getAddr(), Ty); |
| 4662 if (Ty == IceType_i64) { | 4662 if (Ty == IceType_i64) { |
| 4663 // TODO(stichnot): Implement. | 4663 Operand *SrcLo = legalize(loOperand(Src), Legal_Reg | Legal_Imm); |
| 4664 } else if (isVectorType(Ty)) { | 4664 Operand *SrcHi = legalize(hiOperand(Src), Legal_Reg | Legal_Imm); |
| 4665 // TODO(stichnot): Implement. | 4665 OperandX8632Mem *AddrLo = llvm::cast<OperandX8632Mem>(loOperand(Addr)); |
| 4666 } else { | 4666 OperandX8632Mem *AddrHi = llvm::cast<OperandX8632Mem>(hiOperand(Addr)); |
| 4667 // i8, i16, i32, f32, f64 | |
| 4668 switch (RMW->getOp()) { | 4667 switch (RMW->getOp()) { |
| 4669 default: | 4668 default: |
| 4670 // TODO(stichnot): Implement other arithmetic operators. | 4669 // TODO(stichnot): Implement other arithmetic operators. |
| 4670 break; |
| 4671 case InstArithmetic::Add: |
| 4672 _add_rmw(AddrLo, SrcLo); |
| 4673 _adc_rmw(AddrHi, SrcHi); |
| 4674 return; |
| 4675 case InstArithmetic::Sub: |
| 4676 _sub_rmw(AddrLo, SrcLo); |
| 4677 _sbb_rmw(AddrHi, SrcHi); |
| 4678 return; |
| 4679 case InstArithmetic::And: |
| 4680 _and_rmw(AddrLo, SrcLo); |
| 4681 _and_rmw(AddrHi, SrcHi); |
| 4682 return; |
| 4683 case InstArithmetic::Or: |
| 4684 _or_rmw(AddrLo, SrcLo); |
| 4685 _or_rmw(AddrHi, SrcHi); |
| 4686 return; |
| 4687 case InstArithmetic::Xor: |
| 4688 _xor_rmw(AddrLo, SrcLo); |
| 4689 _xor_rmw(AddrHi, SrcHi); |
| 4690 return; |
| 4691 } |
| 4692 } else { |
| 4693 // i8, i16, i32 |
| 4694 switch (RMW->getOp()) { |
| 4695 default: |
| 4696 // TODO(stichnot): Implement other arithmetic operators. |
| 4671 break; | 4697 break; |
| 4672 case InstArithmetic::Add: | 4698 case InstArithmetic::Add: |
| 4673 Src = legalize(Src, Legal_Reg | Legal_Imm); | 4699 Src = legalize(Src, Legal_Reg | Legal_Imm); |
| 4674 _add_rmw(Addr, Src); | 4700 _add_rmw(Addr, Src); |
| 4675 return; | 4701 return; |
| 4702 case InstArithmetic::Sub: |
| 4703 Src = legalize(Src, Legal_Reg | Legal_Imm); |
| 4704 _sub_rmw(Addr, Src); |
| 4705 return; |
| 4706 case InstArithmetic::And: |
| 4707 Src = legalize(Src, Legal_Reg | Legal_Imm); |
| 4708 _and_rmw(Addr, Src); |
| 4709 return; |
| 4710 case InstArithmetic::Or: |
| 4711 Src = legalize(Src, Legal_Reg | Legal_Imm); |
| 4712 _or_rmw(Addr, Src); |
| 4713 return; |
| 4714 case InstArithmetic::Xor: |
| 4715 Src = legalize(Src, Legal_Reg | Legal_Imm); |
| 4716 _xor_rmw(Addr, Src); |
| 4717 return; |
| 4676 } | 4718 } |
| 4677 } | 4719 } |
| 4678 llvm::report_fatal_error("Couldn't lower RMW instruction"); | 4720 llvm::report_fatal_error("Couldn't lower RMW instruction"); |
| 4679 } | 4721 } |
| 4680 | 4722 |
| 4681 void TargetX8632::lowerOther(const Inst *Instr) { | 4723 void TargetX8632::lowerOther(const Inst *Instr) { |
| 4682 if (const auto *RMW = llvm::dyn_cast<InstX8632FakeRMW>(Instr)) { | 4724 if (const auto *RMW = llvm::dyn_cast<InstX8632FakeRMW>(Instr)) { |
| 4683 lowerRMW(RMW); | 4725 lowerRMW(RMW); |
| 4684 } else { | 4726 } else { |
| 4685 TargetLowering::lowerOther(Instr); | 4727 TargetLowering::lowerOther(Instr); |
| (...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5303 emitConstantPool<PoolTypeConverter<float>>(Ctx); | 5345 emitConstantPool<PoolTypeConverter<float>>(Ctx); |
| 5304 emitConstantPool<PoolTypeConverter<double>>(Ctx); | 5346 emitConstantPool<PoolTypeConverter<double>>(Ctx); |
| 5305 } break; | 5347 } break; |
| 5306 } | 5348 } |
| 5307 } | 5349 } |
| 5308 | 5350 |
| 5309 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx) | 5351 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx) |
| 5310 : TargetHeaderLowering(Ctx) {} | 5352 : TargetHeaderLowering(Ctx) {} |
| 5311 | 5353 |
| 5312 } // end of namespace Ice | 5354 } // end of namespace Ice |
| OLD | NEW |