char TrueRandomClass::randomByte(void) { char result; uint8_t i; result = 0; for (i=8; i--;) result += result + randomBit(); return result; }
long TrueRandomClass::random(long howBig) { long randomValue; long maxRandomValue; long topBit; long bitPosition; if (!howBig) return 0; randomValue = 0; if (howBig & (howBig-1)) { // Range is not a power of 2 - use slow method topBit = howBig-1; topBit |= topBit>>1; topBit |= topBit>>2; topBit |= topBit>>4; topBit |= topBit>>8; topBit |= topBit>>16; topBit = (topBit+1) >> 1; bitPosition = topBit; do { // Generate the next bit of the result if (randomBit()) randomValue |= bitPosition; // Check if bit if (randomValue >= howBig) { // Number is over the top limit - start again. randomValue = 0; bitPosition = topBit; } else { // Repeat for next bit bitPosition >>= 1; } } while (bitPosition); } else {
long TrueRandomClass::random() { long result; uint8_t i; result = 0; for (i=31; i--;) result += result + randomBit(); return result; }
int TrueRandomClass::rand() { int result; uint8_t i; result = 0; for (i=15; i--;) result += result + randomBit(); return result; }
static void randomize(const Instruction &Instr, const Variable &Var, llvm::MCOperand &AssignedValue, const llvm::BitVector &ForbiddenRegs) { const Operand &Op = Instr.getPrimaryOperand(Var); switch (Op.getExplicitOperandInfo().OperandType) { case llvm::MCOI::OperandType::OPERAND_IMMEDIATE: // FIXME: explore immediate values too. AssignedValue = llvm::MCOperand::createImm(1); break; case llvm::MCOI::OperandType::OPERAND_REGISTER: { assert(Op.isReg()); auto AllowedRegs = Op.getRegisterAliasing().sourceBits(); assert(AllowedRegs.size() == ForbiddenRegs.size()); for (auto I : ForbiddenRegs.set_bits()) AllowedRegs.reset(I); AssignedValue = llvm::MCOperand::createReg(randomBit(AllowedRegs)); break; } default: break; } }
llvm::Expected<std::vector<CodeTemplate>> UopsSnippetGenerator::generateCodeTemplates(const Instruction &Instr) const { CodeTemplate CT; const llvm::BitVector *ScratchSpaceAliasedRegs = nullptr; if (Instr.hasMemoryOperands()) { const auto &ET = State.getExegesisTarget(); CT.ScratchSpacePointerInReg = ET.getScratchMemoryRegister(State.getTargetMachine().getTargetTriple()); if (CT.ScratchSpacePointerInReg == 0) return llvm::make_error<BenchmarkFailure>( "Infeasible : target does not support memory instructions"); ScratchSpaceAliasedRegs = &State.getRATC().getRegister(CT.ScratchSpacePointerInReg).aliasedBits(); // If the instruction implicitly writes to ScratchSpacePointerInReg , abort. // FIXME: We could make a copy of the scratch register. for (const auto &Op : Instr.Operands) { if (Op.isDef() && Op.isImplicitReg() && ScratchSpaceAliasedRegs->test(Op.getImplicitReg())) return llvm::make_error<BenchmarkFailure>( "Infeasible : memory instruction uses scratch memory register"); } } const AliasingConfigurations SelfAliasing(Instr, Instr); InstructionTemplate IT(Instr); if (SelfAliasing.empty()) { CT.Info = "instruction is parallel, repeating a random one."; CT.Instructions.push_back(std::move(IT)); instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions); return getSingleton(std::move(CT)); } if (SelfAliasing.hasImplicitAliasing()) { CT.Info = "instruction is serial, repeating a random one."; CT.Instructions.push_back(std::move(IT)); instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions); return getSingleton(std::move(CT)); } const auto TiedVariables = getVariablesWithTiedOperands(Instr); if (!TiedVariables.empty()) { CT.Info = "instruction has tied variables, using static renaming."; CT.Instructions = generateSnippetUsingStaticRenaming( State, IT, TiedVariables, ScratchSpaceAliasedRegs); instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions); return getSingleton(std::move(CT)); } const auto &ReservedRegisters = State.getRATC().reservedRegisters(); // No tied variables, we pick random values for defs. llvm::BitVector Defs(State.getRegInfo().getNumRegs()); for (const auto &Op : Instr.Operands) { if (Op.isReg() && Op.isExplicit() && Op.isDef() && !Op.isMemory()) { auto PossibleRegisters = Op.getRegisterAliasing().sourceBits(); remove(PossibleRegisters, ReservedRegisters); // Do not use the scratch memory address register. if (ScratchSpaceAliasedRegs) remove(PossibleRegisters, *ScratchSpaceAliasedRegs); assert(PossibleRegisters.any() && "No register left to choose from"); const auto RandomReg = randomBit(PossibleRegisters); Defs.set(RandomReg); IT.getValueFor(Op) = llvm::MCOperand::createReg(RandomReg); } } // And pick random use values that are not reserved and don't alias with defs. const auto DefAliases = getAliasedBits(State.getRegInfo(), Defs); for (const auto &Op : Instr.Operands) { if (Op.isReg() && Op.isExplicit() && Op.isUse() && !Op.isMemory()) { auto PossibleRegisters = Op.getRegisterAliasing().sourceBits(); remove(PossibleRegisters, ReservedRegisters); // Do not use the scratch memory address register. if (ScratchSpaceAliasedRegs) remove(PossibleRegisters, *ScratchSpaceAliasedRegs); remove(PossibleRegisters, DefAliases); assert(PossibleRegisters.any() && "No register left to choose from"); const auto RandomReg = randomBit(PossibleRegisters); IT.getValueFor(Op) = llvm::MCOperand::createReg(RandomReg); } } CT.Info = "instruction has no tied variables picking Uses different from defs"; CT.Instructions.push_back(std::move(IT)); instantiateMemoryOperands(CT.ScratchSpacePointerInReg, CT.Instructions); return getSingleton(std::move(CT)); }