#include "pch.h" #include "Assembly.h" #include "CppUnitTest.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; namespace FrameworkTests { TEST_CLASS (AssemblyTests) { public: TEST_METHOD (Add8Test) { Framework::Assembly::AssemblyBlock codeBlock; codeBlock.addInstruction( new Framework::Assembly::Instruction(Framework::Assembly::MOV, {new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RAX, Framework::Assembly::LOWER8), new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RDX, Framework::Assembly::LOWER8)})); codeBlock.addInstruction( new Framework::Assembly::Instruction(Framework::Assembly::ADD, {new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RAX, Framework::Assembly::LOWER8), new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RCX, Framework::Assembly::LOWER8)})); char (*add)(char a, char b) = (char (*)(char, char))codeBlock.compile(); char result = add(22, 15); char result2 = add(5, 6); Assert::AreEqual((char)37, result); Assert::AreEqual((char)11, result2); } TEST_METHOD (Add16Test) { Framework::Assembly::AssemblyBlock codeBlock; codeBlock.addInstruction(new Framework::Assembly::Instruction( Framework::Assembly::MOV, {new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RAX, Framework::Assembly::LOWER16), new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RDX, Framework::Assembly::LOWER16)})); codeBlock.addInstruction(new Framework::Assembly::Instruction( Framework::Assembly::ADD, {new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RAX, Framework::Assembly::LOWER16), new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RCX, Framework::Assembly::LOWER16)})); short (*add)(short a, short b) = (short (*)(short, short))codeBlock.compile(); short result = add(22, 15); short result2 = add(5, 6); Assert::AreEqual((short)37, result); Assert::AreEqual((short)11, result2); } TEST_METHOD (Add32Test) { Framework::Assembly::AssemblyBlock codeBlock; codeBlock.addInstruction(new Framework::Assembly::Instruction( Framework::Assembly::MOV, {new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RAX, Framework::Assembly::LOWER32), new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RDX, Framework::Assembly::LOWER32)})); codeBlock.addInstruction(new Framework::Assembly::Instruction( Framework::Assembly::ADD, {new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RAX, Framework::Assembly::LOWER32), new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RCX, Framework::Assembly::LOWER32)})); int (*add)(int a, int b) = (int (*)(int, int))codeBlock.compile(); int result = add(22, 15); int result2 = add(5, 6); Assert::AreEqual((int)37, result); Assert::AreEqual((int)11, result2); } TEST_METHOD (Add64Test) { Framework::Assembly::AssemblyBlock codeBlock; codeBlock.addInstruction( new Framework::Assembly::Instruction(Framework::Assembly::MOV, {new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RAX), new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RDX)})); codeBlock.addInstruction( new Framework::Assembly::Instruction(Framework::Assembly::ADD, {new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RAX), new Framework::Assembly::GPRegisterArgument( Framework::Assembly::RCX)})); __int64 (*add)(__int64 a, __int64 b) = (__int64 (*)(__int64, __int64))codeBlock.compile(); __int64 result = add(22, 15); __int64 result2 = add(5, 6); Assert::AreEqual((__int64)37, result); Assert::AreEqual((__int64)11, result2); } TEST_METHOD (AddFloatTest) { Framework::Assembly::AssemblyBlock codeBlock; codeBlock.addInstruction( new Framework::Assembly::Instruction(Framework::Assembly::ADDSS, {new Framework::Assembly::FPRegisterArgument( Framework::Assembly::MM0, Framework::Assembly::FPRegisterPart::X), new Framework::Assembly::FPRegisterArgument( Framework::Assembly::MM1, Framework::Assembly::FPRegisterPart::X)})); float (*add)(float a, float b) = (float (*)(float, float))codeBlock.compile(); float result = add(4.24f, 8.54f); float result2 = add(0.3f, 7.6f); Assert::AreEqual((float)(4.24f + 8.54f), result); Assert::AreEqual((float)(0.3f + 7.6f), result2); } TEST_METHOD (AddDoubleTest) { Framework::Assembly::AssemblyBlock codeBlock; codeBlock.addInstruction( new Framework::Assembly::Instruction(Framework::Assembly::ADDSD, {new Framework::Assembly::FPRegisterArgument( Framework::Assembly::MM0, Framework::Assembly::FPRegisterPart::X), new Framework::Assembly::FPRegisterArgument( Framework::Assembly::MM1, Framework::Assembly::FPRegisterPart::X)})); double (*add)(double a, double b) = (double (*)(double, double))codeBlock.compile(); double result = add(4.24, 8.54); double result2 = add(0.3, 7.6); Assert::AreEqual(4.24 + 8.54, result); Assert::AreEqual(0.3 + 7.6, result2); } TEST_METHOD (returnRefTest) { char cRef = 1; short sRef = 2; int iRef = 3; __int64 lRef = 4; float fRef = 5.0f; double dRef = 6.0; Framework::Assembly::AssemblyBlock ccodeBlock; ccodeBlock.addLoadValue(&cRef, Framework::Assembly::RAX); char (*getc)() = (char (*)())ccodeBlock.compile(); char cresult = getc(); Assert::AreEqual((char)1, cresult); cRef = 11; cresult = getc(); Assert::AreEqual((char)11, cresult); Framework::Assembly::AssemblyBlock scodeBlock; scodeBlock.addLoadValue(&sRef, Framework::Assembly::RAX); short (*gets)() = (short (*)())scodeBlock.compile(); short sresult = gets(); Assert::AreEqual((short)2, sresult); sRef = 22; sresult = gets(); Assert::AreEqual((short)22, sresult); Framework::Assembly::AssemblyBlock icodeBlock; icodeBlock.addLoadValue(&iRef, Framework::Assembly::RAX); int (*geti)() = (int (*)())icodeBlock.compile(); int iresult = geti(); Assert::AreEqual((int)3, iresult); iRef = 33; iresult = geti(); Assert::AreEqual((int)33, iresult); Framework::Assembly::AssemblyBlock lcodeBlock; lcodeBlock.addLoadValue(&lRef, Framework::Assembly::RAX); __int64 (*getl)() = (__int64 (*)())lcodeBlock.compile(); __int64 lresult = getl(); Assert::AreEqual((__int64)4, lresult); lRef = 44; lresult = getl(); Assert::AreEqual((__int64)44, lresult); Framework::Assembly::AssemblyBlock fcodeBlock; fcodeBlock.addLoadValue(&fRef, Framework::Assembly::MM0); float (*getf)() = (float (*)())fcodeBlock.compile(); float fresult = getf(); Assert::AreEqual((float)5.0f, fresult); fRef = 55.0f; fresult = getf(); Assert::AreEqual((float)55.0f, fresult); Framework::Assembly::AssemblyBlock dcodeBlock; dcodeBlock.addLoadValue(&dRef, Framework::Assembly::MM0); double (*getd)() = (double (*)())dcodeBlock.compile(); double dresult = getd(); Assert::AreEqual((double)6.0, dresult); dRef = 66.0; dresult = getd(); Assert::AreEqual((double)66.0, dresult); } }; } // namespace FrameworkTests