| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- #include "pch.h"
- #include "Assembly.h"
- #include "CppUnitTest.h"
- using namespace Microsoft::VisualStudio::CppUnitTestFramework;
- int globalFunc(int a, int b)
- {
- return a * b;
- }
- class A
- {
- public:
- virtual int getValue()
- {
- return 0;
- }
- };
- class B : public A
- {
- public:
- virtual int getValue() override
- {
- return 10;
- }
- };
- namespace FrameworkTests
- {
- TEST_CLASS (AssemblyTests)
- {
- public:
- TEST_METHOD (Add8Test)
- {
- Framework::Assembly::AssemblyBlock codeBlock;
- codeBlock.addMoveValue(Framework::Assembly::RAX,
- 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.addMoveValue(Framework::Assembly::RAX,
- 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.addMoveValue(Framework::Assembly::RAX,
- 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.addMoveValue(
- Framework::Assembly::RAX, 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);
- }
- int c;
- int testMethod(int a, int b)
- {
- return a + b + c;
- }
- TEST_METHOD (testCall)
- {
- std::cout << 1.463f << 4.235;
- Framework::Assembly::AssemblyBlock gfcodeBlock;
- gfcodeBlock.addEnter();
- gfcodeBlock.addMoveValue(Framework::Assembly::RCX, 20);
- gfcodeBlock.addMoveValue(Framework::Assembly::RDX, 50);
- gfcodeBlock.addCall(globalFunc);
- gfcodeBlock.addLeave();
- int (*f)() = gfcodeBlock.compileToFunction<int (*)()>();
- int result = f();
- Assert::AreEqual(globalFunc(20, 50), result);
- Framework::Assembly::AssemblyBlock lfcodeBlock;
- lfcodeBlock.addEnter();
- lfcodeBlock.addLoadAddress(this, Framework::Assembly::RCX);
- lfcodeBlock.addMoveValue(Framework::Assembly::RCX, 20);
- lfcodeBlock.addMoveValue(Framework::Assembly::RDX, 50);
- lfcodeBlock.addMemberCall(&AssemblyTests::testMethod);
- lfcodeBlock.addLeave();
- c = 1;
- f = lfcodeBlock.compileToFunction<int (*)()>();
- result = f();
- A* a = new B();
- Assert::AreEqual(testMethod(20, 50), result);
- Framework::Assembly::AssemblyBlock vfcodeBlock;
- vfcodeBlock.addEnter();
- vfcodeBlock.addLoadAddress(a, Framework::Assembly::RCX);
- vfcodeBlock.addMemberCall(&A::getValue);
- vfcodeBlock.addLeave();
- c = 1;
- f = vfcodeBlock.compileToFunction<int (*)()>();
- result = f();
- Assert::AreEqual(a->getValue(), result);
- delete a;
- }
- };
- } // namespace FrameworkTests
|