| Index: src/IceInstX8632.cpp
|
| diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
|
| index b4e597292a4712f92ba78694ba3495cc4e7640a5..817b41d4ec5905dee05624b2a76d906477309968 100644
|
| --- a/src/IceInstX8632.cpp
|
| +++ b/src/IceInstX8632.cpp
|
| @@ -101,6 +101,20 @@ MachineTraits<TargetX8632>::X86OperandMem::X86OperandMem(
|
| void MachineTraits<TargetX8632>::X86OperandMem::emit(const Cfg *Func) const {
|
| if (!BuildDefs::dump())
|
| return;
|
| + const ::Ice::TargetLowering *Target = Func->getTarget();
|
| + // If the base is rematerializable, we need to replace it with the correct
|
| + // physical register (esp or ebp), and update the Offset.
|
| + int32_t Disp = 0;
|
| + if (getBase() && getBase()->isRematerializable()) {
|
| + Disp += getBase()->getStackOffset();
|
| + if (!getIgnoreStackAdjust())
|
| + Disp += Target->getStackAdjustment();
|
| + }
|
| + // The index should never be rematerializable. But if we ever allow it, then
|
| + // we should make sure the rematerialization offset is shifted by the Shift
|
| + // value.
|
| + if (getIndex())
|
| + assert(!getIndex()->isRematerializable());
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| if (SegmentReg != DefaultSegment) {
|
| assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
|
| @@ -108,27 +122,33 @@ void MachineTraits<TargetX8632>::X86OperandMem::emit(const Cfg *Func) const {
|
| }
|
| // Emit as Offset(Base,Index,1<<Shift). Offset is emitted without the leading
|
| // '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr.
|
| - if (!Offset) {
|
| + if (getOffset() == 0 && Disp == 0) {
|
| // No offset, emit nothing.
|
| - } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
|
| - if (Base == nullptr || CI->getValue())
|
| + } else if (getOffset() == 0 && Disp != 0) {
|
| + Str << Disp;
|
| + } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
|
| + if (getBase() == nullptr || CI->getValue() || Disp != 0)
|
| // Emit a non-zero offset without a leading '$'.
|
| - Str << CI->getValue();
|
| - } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
|
| + Str << CI->getValue() + Disp;
|
| + } else if (const auto *CR =
|
| + llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
|
| + // TODO(sehr): ConstantRelocatable still needs updating for
|
| + // rematerializable base/index and Disp.
|
| + assert(Disp == 0);
|
| CR->emitWithoutPrefix(Func->getTarget());
|
| } else {
|
| llvm_unreachable("Invalid offset type for x86 mem operand");
|
| }
|
|
|
| - if (Base || Index) {
|
| + if (getBase() || getIndex()) {
|
| Str << "(";
|
| - if (Base)
|
| - Base->emit(Func);
|
| - if (Index) {
|
| + if (getBase())
|
| + getBase()->emit(Func);
|
| + if (getIndex()) {
|
| Str << ",";
|
| - Index->emit(Func);
|
| - if (Shift)
|
| - Str << "," << (1u << Shift);
|
| + getIndex()->emit(Func);
|
| + if (getShift())
|
| + Str << "," << (1u << getShift());
|
| }
|
| Str << ")";
|
| }
|
| @@ -144,44 +164,54 @@ void MachineTraits<TargetX8632>::X86OperandMem::dump(const Cfg *Func,
|
| }
|
| bool Dumped = false;
|
| Str << "[";
|
| - if (Base) {
|
| + int32_t Disp = 0;
|
| + if (getBase() && getBase()->isRematerializable()) {
|
| + Disp += getBase()->getStackOffset();
|
| + if (!getIgnoreStackAdjust())
|
| + Disp += Func->getTarget()->getStackAdjustment();
|
| + }
|
| + if (getBase()) {
|
| if (Func)
|
| - Base->dump(Func);
|
| + getBase()->dump(Func);
|
| else
|
| - Base->dump(Str);
|
| + getBase()->dump(Str);
|
| Dumped = true;
|
| }
|
| - if (Index) {
|
| - if (Base)
|
| + if (getIndex()) {
|
| + assert(!getIndex()->isRematerializable());
|
| + if (getBase())
|
| Str << "+";
|
| - if (Shift > 0)
|
| - Str << (1u << Shift) << "*";
|
| + if (getShift() > 0)
|
| + Str << (1u << getShift()) << "*";
|
| if (Func)
|
| - Index->dump(Func);
|
| + getIndex()->dump(Func);
|
| else
|
| - Index->dump(Str);
|
| + getIndex()->dump(Str);
|
| Dumped = true;
|
| }
|
| // Pretty-print the Offset.
|
| bool OffsetIsZero = false;
|
| bool OffsetIsNegative = false;
|
| - if (!Offset) {
|
| + if (getOffset() == 0 && Disp == 0) {
|
| OffsetIsZero = true;
|
| - } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
|
| - OffsetIsZero = (CI->getValue() == 0);
|
| - OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
|
| + } else if (getOffset() == 0 && Disp != 0) {
|
| + OffsetIsZero = (Disp == 0);
|
| + OffsetIsNegative = (Disp < 0);
|
| + } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
|
| + OffsetIsZero = (CI->getValue() + Disp == 0);
|
| + OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) + Disp < 0);
|
| } else {
|
| - assert(llvm::isa<ConstantRelocatable>(Offset));
|
| + assert(llvm::isa<ConstantRelocatable>(getOffset()) && Disp == 0);
|
| }
|
| if (Dumped) {
|
| if (!OffsetIsZero) { // Suppress if Offset is known to be 0
|
| if (!OffsetIsNegative) // Suppress if Offset is known to be negative
|
| Str << "+";
|
| - Offset->dump(Func, Str);
|
| + getOffset()->dump(Func, Str);
|
| }
|
| } else {
|
| // There is only the offset.
|
| - Offset->dump(Func, Str);
|
| + getOffset()->dump(Func, Str);
|
| }
|
| Str << "]";
|
| }
|
| @@ -196,16 +226,28 @@ void MachineTraits<TargetX8632>::X86OperandMem::emitSegmentOverride(
|
|
|
| MachineTraits<TargetX8632>::Address
|
| MachineTraits<TargetX8632>::X86OperandMem::toAsmAddress(
|
| - MachineTraits<TargetX8632>::Assembler *Asm) const {
|
| + MachineTraits<TargetX8632>::Assembler *Asm,
|
| + const Ice::TargetLowering *Target) const {
|
| int32_t Disp = 0;
|
| + if (getBase() && getBase()->isRematerializable()) {
|
| + Disp += getBase()->getStackOffset();
|
| + if (!getIgnoreStackAdjust()) {
|
| + Disp += Target->getStackAdjustment();
|
| + }
|
| + }
|
| + // The index should never be rematerializable. But if we ever allow it, then
|
| + // we should make sure the rematerialization offset is shifted by the Shift
|
| + // value.
|
| + if (getIndex())
|
| + assert(!getIndex()->isRematerializable());
|
| AssemblerFixup *Fixup = nullptr;
|
| // Determine the offset (is it relocatable?)
|
| if (getOffset()) {
|
| if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
|
| - Disp = static_cast<int32_t>(CI->getValue());
|
| + Disp += static_cast<int32_t>(CI->getValue());
|
| } else if (const auto CR =
|
| llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
|
| - Disp = CR->getOffset();
|
| + Disp += CR->getOffset();
|
| Fixup = Asm->createFixup(RelFixup, CR);
|
| } else {
|
| llvm_unreachable("Unexpected offset type");
|
|
|