diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp index 631c38c2734..551f0bcca90 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -45,8 +45,8 @@ STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); HexagonMCCodeEmitter::HexagonMCCodeEmitter(MCInstrInfo const &aMII, MCContext &aMCT) : MCT(aMCT), MCII(aMII), Addend(new unsigned(0)), - Extended(new bool(false)), CurrentBundle(new MCInst const *), - CurrentIndex(new size_t(0)) {} + Extended(new bool(false)), SubInst1(new bool(false)), + CurrentBundle(new MCInst const *), CurrentIndex(new size_t(0)) {} uint32_t HexagonMCCodeEmitter::parseBits(size_t Last, MCInst const &MCB, @@ -159,7 +159,9 @@ void HexagonMCCodeEmitter::EncodeSingleInstruction( // get subinstruction slot 0 unsigned subInstSlot0Bits = getBinaryCodeForInstr(*subInst0, Fixups, STI); // get subinstruction slot 1 + *SubInst1 = true; unsigned subInstSlot1Bits = getBinaryCodeForInstr(*subInst1, Fixups, STI); + *SubInst1 = false; Binary |= subInstSlot0Bits | (subInstSlot1Bits << 16); } @@ -350,8 +352,29 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI, if (isa(ME)) ME = &HexagonMCInstrInfo::getExpr(*ME); int64_t Value; - if (ME->evaluateAsAbsolute(Value)) + if (ME->evaluateAsAbsolute(Value)) { + bool InstExtendable = HexagonMCInstrInfo::isExtendable(MCII, MI) || + HexagonMCInstrInfo::isExtended(MCII, MI); + // Only sub-instruction #1 can be extended in a duplex. If MI is a + // sub-instruction #0, it is not extended even if Extended is true + // (it can be true for the duplex as a whole). + bool IsSub0 = HexagonMCInstrInfo::isSubInstruction(MI) && !*SubInst1; + if (*Extended && InstExtendable && !IsSub0) { + unsigned OpIdx = ~0u; + for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) { + if (&MO != &MI.getOperand(I)) + continue; + OpIdx = I; + break; + } + assert(OpIdx != ~0u); + if (OpIdx == HexagonMCInstrInfo::getExtendableOp(MCII, MI)) { + unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MI); + Value = (Value & 0x3f) << Shift; + } + } return Value; + } assert(ME->getKind() == MCExpr::SymbolRef || ME->getKind() == MCExpr::Binary); if (ME->getKind() == MCExpr::Binary) { diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h index be682e571f2..9cf49ef7788 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h @@ -37,6 +37,7 @@ class HexagonMCCodeEmitter : public MCCodeEmitter { MCInstrInfo const &MCII; std::unique_ptr Addend; std::unique_ptr Extended; + std::unique_ptr SubInst1; std::unique_ptr CurrentBundle; std::unique_ptr CurrentIndex; diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp index 454219945e1..93112754d8f 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp @@ -63,21 +63,6 @@ void HexagonMCELFStreamer::EmitInstruction(const MCInst &MCB, assert(MCB.getOpcode() == Hexagon::BUNDLE); assert(HexagonMCInstrInfo::bundleSize(MCB) <= HEXAGON_PACKET_SIZE); assert(HexagonMCInstrInfo::bundleSize(MCB) > 0); - bool Extended = false; - for (auto &I : HexagonMCInstrInfo::bundleInstructions(MCB)) { - MCInst *MCI = const_cast(I.getInst()); - if (Extended) { - if (HexagonMCInstrInfo::isDuplex(*MCII, *MCI)) { - MCInst *SubInst = const_cast(MCI->getOperand(1).getInst()); - HexagonMCInstrInfo::clampExtended(*MCII, getContext(), *SubInst); - } else { - HexagonMCInstrInfo::clampExtended(*MCII, getContext(), *MCI); - } - Extended = false; - } else { - Extended = HexagonMCInstrInfo::isImmext(*MCI); - } - } // At this point, MCB is a bundle // Iterate through the bundle and assign addends for the instructions diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp index 19308cd425e..a11aa92ccbe 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp @@ -158,23 +158,6 @@ bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII, return true; } -void HexagonMCInstrInfo::clampExtended(MCInstrInfo const &MCII, - MCContext &Context, MCInst &MCI) { - assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || - HexagonMCInstrInfo::isExtended(MCII, MCI)); - MCOperand &exOp = - MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); - // If the extended value is a constant, then use it for the extended and - // for the extender instructions, masking off the lower 6 bits and - // including the assumed bits. - int64_t Value; - if (exOp.getExpr()->evaluateAsAbsolute(Value)) { - unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MCI); - exOp.setExpr(HexagonMCExpr::create( - MCConstantExpr::create((Value & 0x3f) << Shift, Context), Context)); - } -} - MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst, MCOperand const &MO) { @@ -330,16 +313,19 @@ unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII, return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); } +bool HexagonMCInstrInfo::isExtentSigned(MCInstrInfo const &MCII, + MCInst const &MCI) { + const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; + return (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; +} + /// Return the maximum value of an extendable operand. int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI) { - const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - bool S = (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; - assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || HexagonMCInstrInfo::isExtended(MCII, MCI)); - if (S) // if value is signed + if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1; return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1; } @@ -347,13 +333,10 @@ int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII, /// Return the minimum value of an extendable operand. int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII, MCInst const &MCI) { - const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; - bool S = (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; - assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || HexagonMCInstrInfo::isExtended(MCII, MCI)); - if (S) // if value is signed + if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)); return 0; } diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h index 28d89429266..d040bea23b6 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h @@ -103,9 +103,6 @@ MCInst deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst, // Convert this instruction in to a duplex subinst MCInst deriveSubInst(MCInst const &Inst); -// Clamp off upper 26 bits of extendable operand for emission -void clampExtended(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI); - // Return the extender for instruction at Index or nullptr if none MCInst const *extenderForIndex(MCInst const &MCB, size_t Index); void extendIfNeeded(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB, @@ -143,6 +140,9 @@ unsigned getExtentAlignment(MCInstrInfo const &MCII, MCInst const &MCI); // Return the number of logical bits of the extendable operand unsigned getExtentBits(MCInstrInfo const &MCII, MCInst const &MCI); +// Check if the extendable operand is signed. +bool isExtentSigned(MCInstrInfo const &MCII, MCInst const &MCI); + // Return the max value that a constant extendable operand can have // without being extended. int getMaxValue(MCInstrInfo const &MCII, MCInst const &MCI); diff --git a/test/MC/Hexagon/extender.s b/test/MC/Hexagon/extender.s index f807dbe0cdd..d0990d1ced7 100644 --- a/test/MC/Hexagon/extender.s +++ b/test/MC/Hexagon/extender.s @@ -208,3 +208,10 @@ # CHECK: r1:0 = memd(gp+#56) + +{ + r0 = add(r0, ##123456) + r1 = add(r1, #-64) +} + +# CHECK: r0 = add(r0,##123456); r1 = add(r1,#-64)