Changed current relation from BasicBlock to BasicBlockImpl, and Function
[jitcs.git] / tests / test_simplefunction.cpp
blob7f207fcd6de70d16da909c7c042175d8f2b34475
1 #include "jitcs.h"
2 #include "unittest.h"
3 #include "jitcs_instructionstream.h"
4 #include "jitcs_dumper.h"
6 #include <stdio.h>
8 using namespace jitcs;
10 static void test(UnitTest& t) {
11 typedef int (__cdecl *FT0_c)(int, int);
12 RefCounter<IMachineInfo> mi = host::GetMachineInfo();
13 RefCounter<TempAllocator> alloc(new TempAllocator);
15 std::unique_ptr<Function> fn = mi->createFnc<FT0_c>(alloc);
16 InstructionStreamBuffer<256> ibuf;
18 Ref<const VirtualRegister> param0 = fn->getArgumentRegister(0, host::RCL_GR);
19 Ref<const VirtualRegister> param1 = fn->getArgumentRegister(1, host::RCL_GR);
20 Ref<const VirtualRegister> result0 = fn->getResultRegister(0, host::RCL_GR);
22 Ref<BasicBlock> bb1 = fn->getStartBlock();
23 Ref<BasicBlock> bb2 = fn->createBasicBlock();
24 Ref<BasicBlock> bb3 = fn->createBasicBlock();
26 ibuf.start(bb1);
27 host::CMP_RR(ibuf, param0, param1);
28 host::JGE_BB_FT(ibuf, bb2, bb3);
29 ibuf.end();
31 ibuf.start(bb2);
32 host::MOV_RR(ibuf, result0, param0);
33 host::RET(ibuf);
34 ibuf.end();
36 ibuf.start(bb3);
37 host::MOV_RR(ibuf, result0, param1);
38 host::RET(ibuf);
39 ibuf.end();
42 Enumerator<const BasicBlock> enumbb = fn->enumerateBasicBlocks();
43 size_t c = 0, c1 = 0, c2 = 0, c3 = 0;
44 while (!enumbb.empty()) {
45 const BasicBlock& bb = enumbb.front();
46 ++c;
47 if (&bb == bb1._ptr) ++c1;
48 if (&bb == bb2._ptr) ++c2;
49 if (&bb == bb3._ptr) ++c3;
50 enumbb.popFront();
52 t.check("Build/Enumerate basic blocks", c1 == 1 && c2 == 1 && c3 == 1 && c == 3);
55 Enumerator<const Instruction> enumins = bb1->instructions();
56 bool ok = true;
57 ok = !enumins.empty();
58 if (ok) {
59 const Instruction& ins = enumins.front();
60 ok = ok && (ins.getInsId() == host::I_CMP_RR);
61 enumins.popFront();
63 t.check("Build/Enumerate instructions on BB1/1", ok);
64 ok = ok && !enumins.empty();
65 if (ok) {
66 const Instruction& ins = enumins.front();
67 ok = ok && (ins.getInsId() == host::I_JGE_BB_FT);
68 enumins.popFront();
70 t.check("Build/Enumerate instructions on BB1/2", ok);
71 ok = ok && enumins.empty();
72 t.check("Build/Enumerate instructions on BB1/3", ok);
75 Enumerator<const BasicBlock> predbb = bb1->predecessors();
76 Enumerator<const BasicBlock> succbb = bb1->successors();
77 size_t c = 0, c1 = 0, c2 = 0, c3 = 0;
78 while (!succbb.empty()) {
79 const BasicBlock& bb = succbb.front();
80 ++c;
81 if (&bb == bb1._ptr) ++c1;
82 if (&bb == bb2._ptr) ++c2;
83 if (&bb == bb3._ptr) ++c3;
84 succbb.popFront();
86 t.check("Build/Pred+succ",
87 predbb.empty() && c == 2 && c2 == 1 && c3 == 1);
90 StringDumper dumper;
91 MachineDumper mdumper(dumper, *mi);
92 fn->dump(mdumper);
93 std::string dumpresult = dumper.takeResult();
95 std::string expected;
96 if (mi->cpu.isX86_32()) expected =
97 "Function dump: CC{FP1+0(4B)/-, FP1+4(4B)/- -> -/eax}\n"
98 " param/result vregs: VR4096_GR32, VR4097_GR32 -> VR4098_GR32\n"
99 "BB(0): OUT(BB(1),BB(2))\n"
100 " cmp_ww VR4097_GR32/r VR4096_GR32/r\n"
101 " jge_bb_ft BB1 BB2\n"
102 "BB(1): IN(BB(0))\n"
103 " mov_ww VR4096_GR32/r VR4098_GR32/w\n"
104 " ret\n"
105 "BB(2): IN(BB(0))\n"
106 " mov_ww VR4097_GR32/r VR4098_GR32/w\n"
107 " ret\n";
108 t.check("Build/Dump", dumpresult == expected);
111 t.check("Generating code not implemented", false);
112 t.check("Running function not implemented", false);
116 static UnitTestRun _("SimpleFunction", test);