- ICmpInst* is_reverse =
- new ICmpInst(ICmpInst::ICMP_UGT, Lo, Hi, "", small);
- new BranchInst(reverse, forward, is_reverse, small);
-
- // Block "forward"
- Value* t1 = BinaryOperator::createLShr(ValMask, Hi, "", forward);
- Value* t2 = BinaryOperator::createShl(t1, Lo, "", forward);
- Value* nott2 = BinaryOperator::createXor(t2, ValMask, "", forward);
- Value* t3 = BinaryOperator::createShl(Rep4, Lo, "", forward);
- Value* t4 = BinaryOperator::createAnd(nott2, Val, "", forward);
- Value* FRslt = BinaryOperator::createOr(t3, t4, "", forward);
- new ReturnInst(FRslt, forward);
-
- // Block "reverse"
- Value* t5 = BinaryOperator::createShl(ValMask, Lo, "", reverse);
- Value* t6 = BinaryOperator::createShl(ValMask, Hi, "", reverse);
- Value* t7 = BinaryOperator::createOr(t6, t5, "", reverse);
- Value* t8 = BinaryOperator::createXor(t7, ValMask, "", reverse);
- Value* t9 = BinaryOperator::createAnd(t8, Val, "", reverse);
- Value* t10 = BinaryOperator::createShl(Rep4, Lo, "", reverse);
- if (RepBits < ValBits)
- RepBitWidth =
- cast<ConstantInt>(ConstantExpr::getZExt(RepBitWidth, ValTy));
- else if (RepBits > ValBits)
- RepBitWidth =
- cast<ConstantInt>(ConstantExpr::getTrunc(RepBitWidth, ValTy));
- Value* t11 = BinaryOperator::createSub(RepBitWidth, Hi, "", reverse);
- Value* t13 = BinaryOperator::createLShr(Rep4, t11, "",reverse);
- Value* t14 = BinaryOperator::createOr(t10, t9, "", reverse);
- Value* RRslt = BinaryOperator::createOr(t14, t13, "", reverse);
- new ReturnInst(RRslt, reverse);
+ BranchInst::Create(result, reverse, is_forward, small);
+
+ // BASIC BLOCK: reverse (reverses the bits of the replacement)
+ // Set up our loop counter as a PHI so we can decrement on each iteration.
+ // We will loop for the number of bits in the replacement value.
+ PHINode *Count = PHINode::Create(Type::Int32Ty, "count", reverse);
+ Count->reserveOperandSpace(2);
+ Count->addIncoming(NumBits, small);
+
+ // Get the value that we are shifting bits out of as a PHI because
+ // we'll change this with each iteration.
+ PHINode *BitsToShift = PHINode::Create(Val->getType(), "val", reverse);
+ BitsToShift->reserveOperandSpace(2);
+ BitsToShift->addIncoming(Rep4, small);
+
+ // Get the result of the last computation or zero on first iteration
+ PHINode *RRes = PHINode::Create(Val->getType(), "rres", reverse);
+ RRes->reserveOperandSpace(2);
+ RRes->addIncoming(ValZero, small);
+
+ // Decrement the loop counter by one
+ Instruction *Decr = BinaryOperator::CreateSub(Count, One, "", reverse);
+ Count->addIncoming(Decr, reverse);
+
+ // Get the bit that we want to move into the result
+ Value *Bit = BinaryOperator::CreateAnd(BitsToShift, ValOne, "", reverse);
+
+ // Compute the new value of the bits to shift for the next iteration.
+ Value *NewVal = BinaryOperator::CreateLShr(BitsToShift, ValOne,"", reverse);
+ BitsToShift->addIncoming(NewVal, reverse);
+
+ // Shift the bit we extracted into the low bit of the result.
+ Instruction *NewRes = BinaryOperator::CreateShl(RRes, ValOne, "", reverse);
+ NewRes = BinaryOperator::CreateOr(NewRes, Bit, "", reverse);
+ RRes->addIncoming(NewRes, reverse);
+
+ // Terminate loop if we've moved all the bits.
+ ICmpInst *Cond = new ICmpInst(ICmpInst::ICMP_EQ, Decr, Zero, "", reverse);
+ BranchInst::Create(result, reverse, Cond, reverse);
+
+ // BASIC BLOCK: result
+ PHINode *Rplcmnt = PHINode::Create(Val->getType(), "", result);
+ Rplcmnt->reserveOperandSpace(2);
+ Rplcmnt->addIncoming(NewRes, reverse);
+ Rplcmnt->addIncoming(Rep4, small);
+ Value* t0 = CastInst::CreateIntegerCast(NumBits,ValTy,false,"",result);
+ Value* t1 = BinaryOperator::CreateShl(ValMask, Lo, "", result);
+ Value* t2 = BinaryOperator::CreateNot(t1, "", result);
+ Value* t3 = BinaryOperator::CreateShl(t1, t0, "", result);
+ Value* t4 = BinaryOperator::CreateOr(t2, t3, "", result);
+ Value* t5 = BinaryOperator::CreateAnd(t4, Val, "", result);
+ Value* t6 = BinaryOperator::CreateShl(Rplcmnt, Lo, "", result);
+ Value* Rslt = BinaryOperator::CreateOr(t5, t6, "part_set", result);
+ ReturnInst::Create(Rslt, result);