#include "stdafx.h"

#define LLVM_AVAILABLE

#include "Utilities/Log.h"
#include "Emu/Cell/PPULLVMRecompiler.h"
#include "llvm/Support/Host.h"
#include "llvm/IR/Verifier.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/MC/MCDisassembler.h"

#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/IR/Dominators.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Vectorize.h"
#include "llvm/Support/TargetSelect.h"

#include "Emu/System.h"
#include "Emu/IdManager.h"

#include <sstream>

using namespace llvm;
using namespace ppu_recompiler_llvm;

/// Register state of a PPU
struct ppu_recompiler_llvm::PPUState {
	/// Floating point registers
	PPCdouble FPR[32];

	///Floating point status and control register
	FPSCRhdr FPSCR;

	/// General purpose reggisters
	u64 GPR[32];

	/// Vector purpose registers
	v128 VPR[32];

	/// Condition register
	CRhdr CR;

	/// Fixed point exception register
	XERhdr XER;

	/// Vector status and control register
	VSCRhdr VSCR;

	/// Link register
	u64 LR;

	/// Count register
	u64 CTR;

	/// SPR general purpose registers
	u64 SPRG[8];

	/// Time base register
	u64 TB;

	/// Memory block
	u32 address;
	u64 mem_block[64];

	void Load(PPUThread & ppu, u32 addr) {
		for (int i = 0; i < 32; i++) {
			FPR[i] = ppu.FPR[i];
			GPR[i] = ppu.GPR[i];
			VPR[i] = ppu.VPR[i];

			if (i < 8) {
				SPRG[i] = ppu.SPRG[i];
			}
		}

		FPSCR = ppu.FPSCR;
		CR = ppu.CR;
		XER = ppu.XER;
		VSCR = ppu.VSCR;
		LR = ppu.LR;
		CTR = ppu.CTR;
		TB = ppu.TB;

		address = addr;
		for (int i = 0; i < (sizeof(mem_block) / 8); i++) {
			mem_block[i] = vm::ps3::read64(address + (i * 8));
		}
	}

	void Store(PPUThread & ppu) {
		for (int i = 0; i < 32; i++) {
			ppu.FPR[i] = FPR[i];
			ppu.GPR[i] = GPR[i];
			ppu.VPR[i] = VPR[i];

			if (i < 8) {
				ppu.SPRG[i] = SPRG[i];
			}
		}

		ppu.FPSCR = FPSCR;
		ppu.CR = CR;
		ppu.XER = XER;
		ppu.VSCR = VSCR;
		ppu.LR = LR;
		ppu.CTR = CTR;
		ppu.TB = TB;

		for (int i = 0; i < (sizeof(mem_block) / 8); i++) {
			vm::ps3::write64(address + (i * 8), mem_block[i]);
		}
	}

	void SetRandom(u32 addr) {
		std::mt19937_64 rng;

		rng.seed((u32)std::chrono::high_resolution_clock::now().time_since_epoch().count());
		for (int i = 0; i < 32; i++) {
			FPR[i] = (double)rng();
			GPR[i] = rng();
			VPR[i]._f[0] = (float)rng();
			VPR[i]._f[1] = (float)(rng() & 0x7FFFFFFF);
			VPR[i]._f[2] = -(float)(rng() & 0x7FFFFFFF);
			VPR[i]._f[3] = -(float)rng();

			if (i < 8) {
				SPRG[i] = rng();
			}
		}

		FPSCR.FPSCR = (u32)rng();
		CR.CR = (u32)rng();
		XER.XER = 0;
		XER.CA = (u32)rng();
		XER.SO = (u32)rng();
		XER.OV = (u32)rng();
		VSCR.VSCR = (u32)rng();
		VSCR.X = 0;
		VSCR.Y = 0;
		LR = rng();
		CTR = rng();
		TB = rng();

		address = addr;
		for (int i = 0; i < (sizeof(mem_block) / 8); i++) {
			mem_block[i] = rng();
		}
	}

	std::string ToString() const {
		std::string ret;

		for (int i = 0; i < 32; i++) {
			ret += fmt::format("GPR[%02d] = 0x%016llx  FPR[%02d] = %16g (0x%016llx)  VPR[%02d] = 0x%s [%s]\n", i, GPR[i], i, FPR[i]._double, FPR[i]._u64, i, VPR[i].to_hex().c_str(), VPR[i].to_xyzw().c_str());
		}

		for (int i = 0; i < 8; i++) {
			ret += fmt::format("SPRG[%d] = 0x%016llx\n", i, SPRG[i]);
		}

		ret += fmt::format("CR      = 0x%08x LR = 0x%016llx CTR = 0x%016llx TB=0x%016llx\n", CR.CR, LR, CTR, TB);
		ret += fmt::format("XER     = 0x%016llx [CA=%d | OV=%d | SO=%d]\n", XER.XER, u32{ XER.CA }, u32{ XER.OV }, u32{ XER.SO });

		for (int i = 0; i < (sizeof(mem_block) / 8); i += 2) {
//			ret += fmt::format("mem_block[%d] = 0x%016llx mem_block[%d] = 0x%016llx\n", i, mem_block[i], i + 1, mem_block[i + 1]);
		}

		return ret;
	}
};

static std::string StateDiff(PPUState const & recomp, PPUState const & interp) {
	std::string ret;

	for (int i = 0; i < 32; i++) {
		if (recomp.GPR[i] != interp.GPR[i]) {
			ret += fmt::format("recomp: GPR[%02d] = 0x%016llx interp: GPR[%02d] = 0x%016llx\n", i, recomp.GPR[i], i, interp.GPR[i]);
		}
		if (recomp.FPR[i]._u64 != interp.FPR[i]._u64) {
			ret += fmt::format("recomp: FPR[%02d] = %16g (0x%016llx) interp: FPR[%02d] = %16g (0x%016llx)\n", i, recomp.FPR[i]._double, recomp.FPR[i]._u64, i, interp.FPR[i]._double, interp.FPR[i]._u64);
		}
		if (recomp.VPR[i] != interp.VPR[i]) {
			ret += fmt::format("recomp: VPR[%02d] = 0x%s [%s]\n", i, recomp.VPR[i].to_hex().c_str(), recomp.VPR[i].to_xyzw().c_str());
			ret += fmt::format("interp: VPR[%02d] = 0x%s [%s]\n", i, interp.VPR[i].to_hex().c_str(), interp.VPR[i].to_xyzw().c_str());
		}
	}

	for (int i = 0; i < 8; i++) {
		if (recomp.SPRG[i] != interp.SPRG[i])
			ret += fmt::format("recomp: SPRG[%d] = 0x%016llx interp: SPRG[%d] = 0x%016llx\n", i, recomp.SPRG[i], i, interp.SPRG[i]);
	}

	if (recomp.CR.CR != interp.CR.CR) {
		ret += fmt::format("recomp: CR      = 0x%08x\n", recomp.CR.CR);
		ret += fmt::format("interp: CR      = 0x%08x\n", interp.CR.CR);
	}
	if (recomp.LR != interp.LR) {
		ret += fmt::format("recomp: LR = 0x%016llx\n", recomp.LR);
		ret += fmt::format("interp: LR = 0x%016llx\n", interp.LR);
	}
	if (recomp.CTR != interp.CTR) {
		ret += fmt::format("recomp: CTR = 0x%016llx\n", recomp.CTR);
		ret += fmt::format("interp: CTR = 0x%016llx\n", interp.CTR);
	}
	if (recomp.TB != interp.TB) {
		ret += fmt::format("recomp: TB = 0x%016llx\n", recomp.TB);
		ret += fmt::format("interp: TB = 0x%016llx\n", interp.TB);
	}

	if (recomp.XER.XER != interp.XER.XER) {
		ret += fmt::format("recomp: XER     = 0x%016llx [CA=%d | OV=%d | SO=%d]\n", recomp.XER.XER, u32{ recomp.XER.CA }, u32{ recomp.XER.OV }, u32{ recomp.XER.SO });
		ret += fmt::format("interp: XER     = 0x%016llx [CA=%d | OV=%d | SO=%d]\n", interp.XER.XER, u32{ interp.XER.CA }, u32{ interp.XER.OV }, u32{ interp.XER.SO });
	}

	for (int i = 0; i < (sizeof(recomp.mem_block) / 8); i++) {
		if (recomp.mem_block[i] != interp.mem_block[i]) {
			ret += fmt::format("recomp: mem_block[%d] = 0x%016llx\n", i, recomp.mem_block[i]);
			ret += fmt::format("interp: mem_block[%d] = 0x%016llx\n", i, interp.mem_block[i]);
		}
	}

	return ret;
}



class ppu_llvm_test_class;

class TestCompiler : public ppu_recompiler_llvm::Compiler
{
	friend class ppu_llvm_test_class;
	TestCompiler(LLVMContext *ctx, IRBuilder<> *builder, std::unordered_map<std::string, void*> map) : Compiler(ctx, builder, map)
	{}
public:
	template <class... Args>
	static std::pair<std::unique_ptr<llvm::ExecutionEngine>, Executable> build_test(void (Compiler::*recomp_fn)(Args...), Args... args)
	{
		LLVMContext &context(getGlobalContext());
		IRBuilder<> builder(getGlobalContext());
		std::unordered_map<std::string, void*> executable_map;

		std::unique_ptr<llvm::Module> module = Compiler::create_module(context);

		TestCompiler compiler(&context, &builder, executable_map);

		compiler.m_module = module.get();
		compiler.initiate_function("test");
		auto block = BasicBlock::Create(context, "start", compiler.m_state.function);
		builder.SetInsertPoint(block);

		(compiler.*recomp_fn)(args...);
		builder.CreateRet(builder.getInt32(0));

		Compiler::optimise_module(module.get());
		llvm::Module *module_ptr = module.get();

		llvm::ExecutionEngine *execution_engine =
			EngineBuilder(std::move(module))
			.setEngineKind(EngineKind::JIT)
			.setMCJITMemoryManager(std::unique_ptr<llvm::SectionMemoryManager>(new CustomSectionMemoryManager(executable_map)))
			.setOptLevel(llvm::CodeGenOpt::Aggressive)
			.setMCPU("nehalem")
			.create();
		module_ptr->setDataLayout(execution_engine->getDataLayout());

		execution_engine->finalizeObject();

		Function *llvm_function = module_ptr->getFunction("test");
		void *function = execution_engine->getPointerToFunction(llvm_function);

		return std::make_pair(std::unique_ptr<llvm::ExecutionEngine>(execution_engine), (Executable)function);
	}
};

namespace
{
	template <int n, class... Args>
	void verify_instruction_against_interpreter_using_random_inputs(void (Compiler::*recomp_fn)(Args...), void (PPUInterpreter::*interp_fn)(Args...), Args... args)
	{
		InitializeNativeTarget();
		InitializeNativeTargetAsmPrinter();
		InitializeNativeTargetDisassembler();

		std::pair<std::unique_ptr<llvm::ExecutionEngine>, Executable> build_result = TestCompiler::template build_test(recomp_fn, args...);
		PPUState recomp_output_state;
		PPUState interp_output_state;

		PPUThread      * s_ppu_state = idm::make_ptr<PPUThread>("Test Thread").get();
		PPUInterpreter interpreter(*s_ppu_state);
		PPUInterpreter * s_interpreter = &interpreter;

		Emu.SetTestMode();
		vm::ps3::init();
		u32 addr = vm::alloc(1024, vm::memory_location_t::main);

		PPUState input;
		for (int i = 0; i < n; i++) {
			input.SetRandom(0x10000);

			input.Store(*s_ppu_state);
			build_result.second(s_ppu_state, 0);
			recomp_output_state.Load(*s_ppu_state, addr);

			input.Store(*s_ppu_state);
			(s_interpreter->*interp_fn)(args...);
			interp_output_state.Load(*s_ppu_state, addr);

			Assert::AreEqual(interp_output_state.ToString(), recomp_output_state.ToString());
		}
		vm::dealloc(addr, vm::memory_location_t::main);
	}

	template <class... Args>
	void verify_instruction_against_interpreter_using_determined_inputs(PPUState &input, void (Compiler::*recomp_fn)(Args...), void (PPUInterpreter::*interp_fn)(Args...), Args... args)
	{
		InitializeNativeTarget();
		InitializeNativeTargetAsmPrinter();
		InitializeNativeTargetDisassembler();

		std::pair<std::unique_ptr<llvm::ExecutionEngine>, Executable> build_result = TestCompiler::template build_test(recomp_fn, args...);

		Emu.SetTestMode();
		vm::ps3::init();
		u32 addr = vm::alloc(1024, vm::memory_location_t::main);

		PPUState recomp_output_state;
		PPUState interp_output_state;

		PPUThread      * s_ppu_state = idm::make_ptr<PPUThread>("Test Thread").get();
		PPUInterpreter interpreter(*s_ppu_state);
		PPUInterpreter * s_interpreter = &interpreter;

		input.Store(*s_ppu_state);
		build_result.second(s_ppu_state, 0);
		recomp_output_state.Load(*s_ppu_state, addr);

		input.Store(*s_ppu_state);
		(s_interpreter->*interp_fn)(args...);
		interp_output_state.Load(*s_ppu_state, addr);

		Assert::AreEqual(interp_output_state.ToString(), recomp_output_state.ToString());
	}
}

#define VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(fn, s, n, ...) \


#define TEST_INSTRUCTION_USING_RANDOM_INPUT(name, fn, n, ...) \
	TEST_METHOD(random_##name) \
	{ \
		verify_instruction_against_interpreter_using_random_inputs<n>(&TestCompiler::fn, &PPUInterpreter::fn, ##__VA_ARGS__); \
	}

#define TEST_INSTRUCTION_USING_DETERMINED_INPUT(name, fn, ...) \
	TEST_METHOD(name) \
	{ \
		PPUState input; \
		input.SetRandom(0x10000); \
		input.GPR[14] = 10; \
		input.GPR[21] = 15; \
		input.GPR[23] = 0x10000; \
		input.mem_block[0] = 0x8877665544332211; \
		input.GPR[1] = 9223372036854775807; \
		input.GPR[2] = 1; \
		input.GPR[3] = 0; \
		input.XER.XER = 0; \
		verify_instruction_against_interpreter_using_determined_inputs(input, &TestCompiler::fn, &PPUInterpreter::fn, ##__VA_ARGS__); \
	}

TEST_CLASS(ppu_llvm_test_class)
{
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MFVSCR, MFVSCR, 50, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTVSCR, MTVSCR, 50, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDCUW, VADDCUW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDFP, VADDFP, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDSBS, VADDSBS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDSHS, VADDSHS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDSWS, VADDSWS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDUBM, VADDUBM, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDUBS, VADDUBS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDUHM, VADDUHM, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDUHS, VADDUHS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDUWM, VADDUWM, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VADDUWS, VADDUWS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VAND, VAND, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VANDC, VANDC, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VAVGSB, VAVGSB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VAVGSH, VAVGSH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VAVGSW, VAVGSW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VAVGUB, VAVGUB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VAVGUH, VAVGUH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VAVGUW, VAVGUW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCFSX1, VCFSX, 50, 0u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCFSX2, VCFSX, 50, 0u, 3u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCFUX1, VCFUX, 50, 0u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCFUX2, VCFUX, 50, 0u, 2u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPBFP1, VCMPBFP, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPBFP2, VCMPBFP, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPBFP_1, VCMPBFP_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPBFP_2, VCMPBFP_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQFP1, VCMPEQFP, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQFP2, VCMPEQFP, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQFP_1, VCMPEQFP_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQFP_2, VCMPEQFP_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUB1, VCMPEQUB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUB2, VCMPEQUB, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUB_1, VCMPEQUB_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUB_2, VCMPEQUB_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUH1, VCMPEQUH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUH2, VCMPEQUH, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUH_1, VCMPEQUH_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUH_2, VCMPEQUH_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUW1, VCMPEQUW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUW2, VCMPEQUW, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUW_1, VCMPEQUW_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPEQUW_2, VCMPEQUW_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGEFP1, VCMPGEFP, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGEFP2, VCMPGEFP, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGEFP_1, VCMPGEFP_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGEFP_2, VCMPGEFP_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTFP1, VCMPGTFP, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTFP2, VCMPGTFP, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTFP_1, VCMPGTFP_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTFP_2, VCMPGTFP_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSB1, VCMPGTSB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSB2, VCMPGTSB, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSB_1, VCMPGTSB_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSB_2, VCMPGTSB_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSH1, VCMPGTSH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSH2, VCMPGTSH, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSH_1, VCMPGTSH_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSH_2, VCMPGTSH_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSW1, VCMPGTSW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSW2, VCMPGTSW, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSW_1, VCMPGTSW_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTSW_2, VCMPGTSW_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUB1, VCMPGTUB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUB2, VCMPGTUB, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUB_1, VCMPGTUB_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUB_2, VCMPGTUB_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUH1, VCMPGTUH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUH2, VCMPGTUH, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUH_1, VCMPGTUH_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUH_2, VCMPGTUH_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUW1, VCMPGTUW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUW2, VCMPGTUW, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUW_1, VCMPGTUW_, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCMPGTUW_2, VCMPGTUW_, 50, 0u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCTSXS1, VCTSXS, 50, 0u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCTSXS2, VCTSXS, 50, 0u, 3u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCTUXS1, VCTUXS, 50, 0u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VCTUXS2, VCTUXS, 50, 0u, 3u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VEXPTEFP, VEXPTEFP, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VLOGEFP, VLOGEFP, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMADDFP, VMADDFP, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMAXFP, VMAXFP, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMAXSB, VMAXSB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMAXSH, VMAXSH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMAXSW, VMAXSW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMAXUB, VMAXUB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMAXUH, VMAXUH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMAXUW, VMAXUW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMHADDSHS, VMHADDSHS, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMHRADDSHS, VMHRADDSHS, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMINFP, VMINFP, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMINSB, VMINSB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMINSH, VMINSH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMINSW, VMINSW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMINUB, VMINUB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMINUH, VMINUH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMINUW, VMINUW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMLADDUHM, VMLADDUHM, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMRGHB, VMRGHB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMRGHH, VMRGHH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMRGHW, VMRGHW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMRGLB, VMRGLB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMRGLH, VMRGLH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMRGLW, VMRGLW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMSUMMBM, VMSUMMBM, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMSUMSHM, VMSUMSHM, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMSUMSHS, VMSUMSHS, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMSUMUBM, VMSUMUBM, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMSUMUHM, VMSUMUHM, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMSUMUHS, VMSUMUHS, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMULESB, VMULESB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMULESH, VMULESH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMULEUB, VMULEUB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMULEUH, VMULEUH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMULOSB, VMULOSB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMULOSH, VMULOSH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMULOUB, VMULOUB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VMULOUH, VMULOUH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VNMSUBFP, VNMSUBFP, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VNOR, VNOR, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VOR, VOR, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPERM, VPERM, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPKPX, VPKPX, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPKSHSS, VPKSHSS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPKSHUS, VPKSHUS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPKSWSS, VPKSWSS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPKSWUS, VPKSWUS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPKUHUM, VPKUHUM, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPKUHUS, VPKUHUS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPKUWUM, VPKUWUM, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VPKUWUS, VPKUWUS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VREFP, VREFP, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VRFIM, VRFIM, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VRFIN, VRFIN, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VRFIP, VRFIP, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VRFIZ, VRFIZ, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VRLB, VRLB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VRLH, VRLH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VRLW, VRLW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VRSQRTEFP, VRSQRTEFP, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSEL, VSEL, 50, 0u, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSL, VSL, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSLB, VSLB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSLDOI, VSLDOI, 50, 0u, 1u, 2u, 6u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSLH, VSLH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSLO, VSLO, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSLW, VSLW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSPLTB, VSPLTB, 50, 0u, 3u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSPLTH, VSPLTH, 50, 0u, 3u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSPLTISB, VSPLTISB, 50, 0u, 12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSPLTISH, VSPLTISH, 50, 0u, 12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSPLTISW, VSPLTISW, 50, 0u, -12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSPLTW, VSPLTW, 50, 0u, 3u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSR, VSR, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSRAB, VSRAB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSRAH, VSRAH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSRAW, VSRAW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSRB, VSRB, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSRH, VSRH, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSRO, VSRO, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSRW, VSRW, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBFP, VSUBFP, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBSBS, VSUBSBS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBSHS, VSUBSHS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBSWS, VSUBSWS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBUBM, VSUBUBM, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBUBS, VSUBUBS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBUHM, VSUBUHM, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBUHS, VSUBUHS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBUWM, VSUBUWM, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUBUWS, VSUBUWS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUMSWS, VSUMSWS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUM2SWS, VSUM2SWS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUM4SBS, VSUM4SBS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUM4SHS, VSUM4SHS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VSUM4UBS, VSUM4UBS, 50, 0u, 1u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VUPKHPX, VUPKHPX, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VUPKHSB, VUPKHSB, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VUPKHSH, VUPKHSH, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VUPKLPX, VUPKLPX, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VUPKLSB, VUPKLSB, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VUPKLSH, VUPKLSH, 50, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(VXOR, VXOR, 50, 0u, 1u, 2u);
	// TODO: Rest of the vector instructions

	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULLI, MULLI, 50, 1u, 2u, 12345);

	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFIC1, SUBFIC, 50, 1u, 2u, 12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFIC2, SUBFIC, 10, 1u, 2u, -12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFIC3, SUBFIC, 15, 1u, 2u, 32767);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFIC4, SUBFIC, 20, 1u, 2u, -32767);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFIC5, SUBFIC, 25, 1u, 2u, 0);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFIC6, SUBFIC, 30, 0u, 1u, -1);

	TEST_INSTRUCTION_USING_RANDOM_INPUT(CMPLI1, CMPLI, 50, 1u, 0u, 7u, 12345u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CMPLI2, CMPLI, 50, 1u, 1u, 7u, 12345u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CMPI1, CMPI, 50, 5u, 0u, 7u, -12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CMPI2, CMPI, 50, 5u, 1u, 7u, -12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDIC, ADDIC, 50, 1u, 2u, 12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDIC_, ADDIC_, 50, 1u, 2u, 12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDI1, ADDI, 50, 1u, 2u, 12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDI2, ADDI, 50, 0u, 2u, 12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDIS1, ADDIS, 50, 1u, 2u, -12345);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDIS2, ADDIS, 50, 0u, 2u, -12345);
	// TODO: BC
	// TODO: SC
	// TODO: B
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MCRF1, MCRF, 50, 0u, 7u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MCRF2, MCRF, 50, 6u, 2u);
	// TODO: BCLR
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CRNOR, CRNOR, 50, 0u, 7u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CRANDC, CRANDC, 50, 5u, 6u, 7u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ISYNC, ISYNC, 5);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CRXOR, CRXOR, 50, 7u, 7u, 7u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CRNAND, CRNAND, 50, 3u, 4u, 5u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CRAND, CRAND, 50, 1u, 2u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CREQV, CREQV, 50, 2u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CRORC, CRORC, 50, 3u, 4u, 5u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CROR, CROR, 50, 6u, 7u, 0u);
	// TODO: BCCTR
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLWIMI1, RLWIMI, 50, 7u, 8u, 9u, 12u, 25u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLWIMI2, RLWIMI, 50, 21u, 22u, 21u, 18u, 24u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLWINM1, RLWINM, 50, 7u, 8u, 9u, 12u, 25u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLWINM2, RLWINM, 50, 21u, 22u, 21u, 18u, 24u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLWNM1, RLWNM, 50, 7u, 8u, 9u, 12u, 25u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLWNM2, RLWNM, 50, 21u, 22u, 21u, 18u, 24u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ORI, ORI, 50, 25u, 29u, 12345u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ORIS, ORIS, 50, 7u, 31u, 12345u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(XORI, XORI, 50, 0u, 19u, 12345u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(XORIS, XORIS, 50, 3u, 14u, 12345u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ANDI_, ANDI_, 50, 16u, 7u, 12345u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ANDIS_, ANDIS_, 50, 23u, 21u, 12345u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDICL1, RLDICL, 50, 7u, 8u, 9u, 12u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDICL2, RLDICL, 50, 21u, 22u, 43u, 43u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDICR1, RLDICR, 50, 7u, 8u, 0u, 12u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDICR2, RLDICR, 50, 21u, 22u, 63u, 43u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDIC1, RLDIC, 50, 7u, 8u, 9u, 12u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDIC2, RLDIC, 50, 21u, 22u, 23u, 43u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDIMI1, RLDIMI, 50, 7u, 8u, 9u, 12u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDIMI2, RLDIMI, 50, 21u, 22u, 23u, 43u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDC_LR1, RLDC_LR, 50, 7u, 8u, 9u, 12u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(RLDC_LR2, RLDC_LR, 50, 21u, 22u, 23u, 43u, 1u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CMP1, CMP, 50, 3u, 0u, 9u, 31u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CMP2, CMP, 50, 6u, 1u, 23u, 14u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFC1, SUBFC, 50, 0u, 1u, 2u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFC2, SUBFC, 50, 0u, 1u, 2u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDC1, ADDC, 50, 0u, 1u, 2u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDC2, ADDC, 50, 0u, 1u, 2u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULHDU1, MULHDU, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULHDU2, MULHDU, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULHWU1, MULHWU, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULHWU2, MULHWU, 50, 21u, 22u, 23u, 1u);
	// TODO: MFOCRF
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SLW1, SLW, 50, 5u, 6u, 7u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SLW2, SLW, 50, 5u, 6u, 7u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CNTLZW1, CNTLZW, 50, 5u, 6u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CNTLZW2, CNTLZW, 50, 5u, 6u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SLD1, SLD, 50, 5u, 6u, 7u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SLD2, SLD, 50, 5u, 6u, 7u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(AND1, AND, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(AND2, AND, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CMPL1, CMPL, 50, 3u, 0u, 9u, 31u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CMPL2, CMPL, 50, 6u, 1u, 23u, 14u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBF1, SUBF, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBF2, SUBF, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CNTLZD1, CNTLZD, 50, 5u, 6u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(CNTLZD2, CNTLZD, 50, 5u, 6u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ANDC1, ANDC, 50, 5u, 6u, 7u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ANDC2, ANDC, 50, 5u, 6u, 7u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULHD1, MULHD, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULHD2, MULHD, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULHW1, MULHW, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULHW2, MULHW, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(NEG1, NEG, 50, 7u, 8u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(NEG2, NEG, 50, 21u, 22u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(NOR1, NOR, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(NOR2, NOR, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFE1, SUBFE, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFE2, SUBFE, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDE1, ADDE, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDE2, ADDE, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTOCRF1, MTOCRF, 50, 7u, 8u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTOCRF2, MTOCRF, 50, 0u, 22u, 1u)
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDZE1, ADDZE, 50, 7u, 8u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDZE2, ADDZE, 50, 21u, 22u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFZE1, SUBFZE, 50, 7u, 8u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFZE2, SUBFZE, 50, 21u, 22u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFME1, SUBFME, 50, 7u, 8u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SUBFME2, SUBFME, 50, 21u, 22u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULLD1, MULLD, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULLD2, MULLD, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDME1, ADDME, 50, 7u, 8u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADDME2, ADDME, 50, 21u, 22u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULLW1, MULLW, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MULLW2, MULLW, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADD1, ADD, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ADD2, ADD, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(EQV1, EQV, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(EQV2, EQV, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(XOR1, XOR, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(XOR2, XOR, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MFSPR1, MFSPR, 50, 5u, 0x20u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MFSPR2, MFSPR, 50, 5u, 0x100u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MFSPR3, MFSPR, 10, 5u, 0x120u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MFSPR4, MFSPR, 15, 5u, 0x8u);
	// TODO: MFTB
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ORC1, ORC, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(ORC2, ORC, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(OR1, OR, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(OR2, OR, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(DIVDU1, DIVDU, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(DIVDU2, DIVDU, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(DIVWU1, DIVWU, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(DIVWU2, DIVWU, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTSPR1, MTSPR, 50, 0x20u, 5u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTSPR2, MTSPR, 50, 0x100u, 5u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTSPR3, MTSPR, 10, 0x120u, 5u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTSPR4, MTSPR, 15, 0x8u, 5u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(NAND1, NAND, 50, 7u, 8u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(NAND2, NAND, 50, 21u, 22u, 23u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(DIVD1, DIVD, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(DIVD2, DIVD, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(DIVW1, DIVW, 50, 7u, 8u, 9u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(DIVW2, DIVW, 50, 21u, 22u, 23u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRW1, SRW, 50, 5u, 6u, 7u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRW2, SRW, 50, 5u, 6u, 7u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRD1, SRD, 50, 5u, 6u, 7u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRD2, SRD, 50, 5u, 6u, 7u, 1u);
	// TODO: SYNC
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRAW1, SRAW, 50, 5u, 6u, 7u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRAW2, SRAW, 50, 5u, 6u, 7u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRAD1, SRAD, 50, 5u, 6u, 7u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRAD2, SRAD, 50, 5u, 6u, 7u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRAWI1, SRAWI, 50, 5u, 6u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRAWI2, SRAWI, 50, 5u, 6u, 12u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRAWI3, SRAWI, 10, 5u, 6u, 22u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRAWI4, SRAWI, 15, 5u, 6u, 31u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRADI11, SRADI1, 50, 5u, 6u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRADI12, SRADI1, 50, 5u, 6u, 12u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRADI13, SRADI1, 10, 5u, 6u, 48u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(SRADI14, SRADI1, 15, 5u, 6u, 63u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(EIEIO, EIEIO, 5);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(EXTSH1, EXTSH, 50, 6u, 9u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(EXTSH2, EXTSH, 50, 6u, 9u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(EXTSB1, EXTSB, 50, 3u, 5u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(EXTSB2, EXTSB, 50, 3u, 5u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(EXTSW1, EXTSW, 50, 25u, 29u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(EXTSW2, EXTSW, 50, 25u, 29u, 1u);

	TEST_INSTRUCTION_USING_RANDOM_INPUT(FDIVS, FDIVS, 50, 0u, 1u, 2u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FSUBS, FSUBS, 50, 0u, 1u, 2u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FADDS, FADDS, 50, 0u, 1u, 2u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FSQRTS, FSQRTS, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FRES, FRES, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FMULS, FMULS, 50, 0u, 1u, 2u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FMADDS, FMADDS, 50, 0u, 1u, 2u, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FMSUBS, FMSUBS, 50, 0u, 1u, 2u, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FNMSUBS, FNMSUBS, 50, 0u, 1u, 2u, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FNMADDS, FNMADDS, 50, 0u, 1u, 2u, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSB11, MTFSB1, 50, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSB12, MTFSB1, 50, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSB13, MTFSB1, 10, 25u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSB14, MTFSB1, 15, 31u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MCRFS1, MCRFS, 50, 0u, 7u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MCRFS2, MCRFS, 50, 7u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MCRFS3, MCRFS, 10, 5u, 2u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MCRFS4, MCRFS, 15, 5u, 3u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSB01, MTFSB0, 50, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSB02, MTFSB0, 50, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSB03, MTFSB0, 10, 25u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSB04, MTFSB0, 15, 31u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSFI1, MTFSFI, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSFI2, MTFSFI, 50, 2u, 6u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSFI3, MTFSFI, 10, 5u, 11u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSFI4, MTFSFI, 15, 7u, 14u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MFFS, MFFS, 50, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSF1, MTFSF, 50, 0u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSF2, MTFSF, 50, 2u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSF3, MTFSF, 10, 5u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(MTFSF4, MTFSF, 15, 7u, 0u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FCMPU, FCMPU, 50, 5u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FRSP, FRSP, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FCTIW, FCTIW, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FCTIWZ, FCTIWZ, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FDIV, FDIV, 50, 0u, 1u, 2u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FSUB, FSUB, 50, 0u, 1u, 2u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FADD, FADD, 50, 0u, 1u, 2u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FSQRT, FSQRT, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FSEL, FSEL, 50, 0u, 1u, 2u, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FMUL, FMUL, 50, 0u, 1u, 2u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FRSQRTE, FRSQRTE, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FMSUB, FMSUB, 50, 0u, 1u, 2u, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FMADD, FMADD, 50, 0u, 1u, 2u, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FNMSUB, FNMSUB, 50, 0u, 1u, 2u, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FNMADD, FNMADD, 50, 0u, 1u, 2u, 3u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FCMPO, FCMPO, 50, 3u, 0u, 1u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FNEG, FNEG, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FMR, FMR, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FNABS, FNABS, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FABS, FABS, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FCTID1, FCTID, 50, 0u, 1u, 0u);
	TEST_INSTRUCTION_USING_RANDOM_INPUT(FCFID2, FCTID, 50, 0u, 1u, 0u);

	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC1, SUBFIC, 1u, 2u, -32767);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC2, SUBFIC, 1u, 2u, -1);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC3, SUBFIC, 1u, 2u, 0);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC4, SUBFIC, 1u, 1u, -32767);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC5, SUBFIC, 1u, 1u, -1);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC6, SUBFIC, 1u, 1u, 0);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC7, SUBFIC, 3u, 3u, -32767);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC8, SUBFIC, 3u, 3u, -1);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC9, SUBFIC, 3u, 3u, 0);

	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC10, SUBFIC, 1u, 2u, 32767);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC11, SUBFIC, 1u, 2u, 1);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC12, SUBFIC, 1u, 2u, 0);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC13, SUBFIC, 1u, 1u, 32767);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC14, SUBFIC, 1u, 1u, 1);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC15, SUBFIC, 1u, 1u, 0);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC16, SUBFIC, 3u, 3u, 32767);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC17, SUBFIC, 3u, 3u, 1);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(SUBFIC18, SUBFIC, 3u, 3u, 0);

	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LBZ1, LBZ, 5u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LBZ2, LBZ, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LBZU, LBZU, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LBZX1, LBZX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LBZX2, LBZX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LBZUX, LBZUX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHZ1, LHZ, 5u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHZ2, LHZ, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHZU, LHZU, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHZX1, LHZX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHZX2, LHZX, 5u, 14u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(ECIWX, 0, 5u, 0u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(ECIWX, 1, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHZUX, LHZUX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHA1, LHA, 5u, 0u, 0x100F0);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHA2, LHA, 5u, 14u, 0x100F0);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHAU, LHAU, 5u, 14u, 0x100F0);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHAX1, LHAX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHAX2, LHAX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHAUX, LHAUX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LHBRX, LHBRX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWZ1, LWZ, 5u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWZ2, LWZ, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWZU, LWZU, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWZX1, LWZX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWZX2, LWZX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWZUX, LWZUX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWA1, LWA, 5u, 0u, 0x100F0);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWA2, LWA, 5u, 14u, 0x100F0);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWAX1, LWAX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWAX2, LWAX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWAUX, LWAUX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWBRX, LWAUX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LD1, LD, 5u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LD2, LD, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LDU, LDU, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LDX1, LDX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LDX2, LDX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LDUX, LDUX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LDBRX, LDBRX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFS1, LFS, 5u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFS2, LFS, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFSU, LFSU, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFSX1, LFSX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFSX2, LFSX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFSUX, LFSUX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFD1, LFD, 5u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFD2, LFD, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFDU, LFDU, 5u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFDX1, LFDX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFDX2, LFDX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LFDUX, LFDUX, 5u, 14u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWARX, 0, 5u, 0u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(LWARX, 1, 5u, 14u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(LDARX, 0, 5u, 0u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(LDARX, 1, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LSWI1, LSWI, 5u, 23u, 0u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LSWI2, LSWI, 5u, 23u, 2u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LSWI3, LSWI, 5u, 23u, 7u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LSWI4, LSWI, 5u, 23u, 25u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LMW1, LMW, 5u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LMW2, LMW, 16u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVX1, LVX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVX2, LVX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVXL1, LVXL, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVXL2, LVXL, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVSL1, LVSL, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVSL2, LVSL, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVSL3, LVSL, 5u, 21u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVSR1, LVSR, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVSR2, LVSR, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVSR3, LVSR, 5u, 21u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVEBX1, LVEBX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVEBX2, LVEBX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVEBX3, LVEBX, 5u, 21u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVEHX1, LVEHX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVEHX2, LVEHX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVEHX3, LVEHX, 5u, 21u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVEWX1, LVEWX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVEWX2, LVEWX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVEWX3, LVEWX, 5u, 21u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVLX1, LVLX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVLX2, LVLX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVLX3, LVLX, 5u, 21u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVRX1, LVRX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVRX2, LVRX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(LVRX3, LVRX, 5u, 21u, 23u);

	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STB1, STB, 3u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STB2, STB, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STBU, STBU, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STDCX_, STDCX_, 3u, 0u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(STDCX_, 1, 3u, 14u, 23u); unhandled unknown exception, new
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STBX1, STBX, 3u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STBX2, STBX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STBUX, STBUX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STH1, STH, 3u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STH2, STH, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STHU, STHU, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STHX1, STHX, 3u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STHX2, STHX, 3u, 14u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(ECOWX, 0, 3u, 0u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(ECOWX, 1, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STHUX, STHUX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STHBRX, STHBRX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STW1, STW, 3u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STW2, STW, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STWU, STWU, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STWX1, STWX, 3u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STWX2, STWX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STWUX, STWUX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVLX1, STVLX, 0u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVLX2, STVLX, 0u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVLX3, STVLX, 0u, 21u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STWBRX, STWBRX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STD1, STD, 3u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STD2, STD, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STDU, STDU, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STDX1, STDX, 3u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STDX2, STDX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STWCX_, STWCX_, 3u, 0u, 23u);
	//TEST_INSTRUCTION_USING_DETERMINED_INPUT(STWCX_, 1, 3u, 14u, 23u); unhandled unknown exception, new
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STDUX, STDUX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFS1, STFS, 3u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFS2, STFS, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFSU, STFSU, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFSX1, STFSX, 3u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFSX2, STFSX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVRX1, STVRX, 0u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVRX2, STVRX, 0u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVRX3, STVRX, 0u, 21u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFSUX, STFSUX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFD1, STFD, 3u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFD2, STFD, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFDU, STFDU, 3u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFDX1, STFDX, 3u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFDX2, STFDX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFDUX, STFDUX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STFIWX, STFIWX, 3u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVX1, STVX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVX2, STVX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVXL1, STVXL, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVXL2, STVXL, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVEBX1, STVEBX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVEBX2, STVEBX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVEHX1, STVEHX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVEHX2, STVEHX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVEWX1, STVEWX, 5u, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STVEWX2, STVEWX, 5u, 14u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STMW1, STMW, 5u, 0u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STMW2, STMW, 16u, 14u, 0x10000);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STSWI1, STSWI, 5u, 23u, 0u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STSWI2, STSWI, 5u, 23u, 2u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STSWI3, STSWI, 5u, 23u, 7u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(STSWI4, STSWI, 5u, 23u, 25u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(DCBZ1, DCBZ, 0u, 23u);
	TEST_INSTRUCTION_USING_DETERMINED_INPUT(DCBZ2, DCBZ, 14u, 23u);
};