Index: lld/ELF/Arch/Hexagon.cpp =================================================================== --- lld/ELF/Arch/Hexagon.cpp +++ lld/ELF/Arch/Hexagon.cpp @@ -35,19 +35,23 @@ // Support V60 only at the moment. uint32_t Hexagon::calcEFlags() const { return 0x60; } -static uint32_t applyMask(uint32_t Mask, uint32_t Data) { - uint32_t Result = 0; - size_t Off = 0; +// This function scatter Val's bits as instructed by Mask. +// Here is an example: +// +// Val: abcd efgh ijkl mnop +// Mask: 1110 0001 1111 0001 +// Result: hij0 000k lmno 000p +// +// Some CPUs support this operation as a single instruction. +// For example, Intel BMI2 extension has this operation as PDEP. +static inline uint32_t scatter(uint32_t Val, uint32_t Mask) { + uint32_t Ret = 0; + size_t I = 0; - for (size_t Bit = 0; Bit != 32; ++Bit) { - uint32_t ValBit = (Data >> Off) & 1; - uint32_t MaskBit = (Mask >> Bit) & 1; - if (MaskBit) { - Result |= (ValBit << Bit); - ++Off; - } - } - return Result; + for (size_t J = 0; J != 32; ++J) + if ((Mask >> J) & 1) + Ret |= ((Val >> I++) & 1) << J; + return Ret; } RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S, @@ -67,7 +71,7 @@ case R_HEX_NONE: break; case R_HEX_B22_PCREL: - or32le(Loc, applyMask(0x1ff3ffe, Val >> 2)); + or32le(Loc, scatter(Val >> 2, 0x1ff3ffe)); break; default: error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));