3 #include "jitcs_instructionstream.h"
4 #include "jitcs_dumper.h"
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();
27 host::CMP_RR(ibuf
, param0
, param1
);
28 host::JGE_BB_FT(ibuf
, bb2
, bb3
);
32 host::MOV_RR(ibuf
, result0
, param0
);
37 host::MOV_RR(ibuf
, result0
, param1
);
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();
47 if (&bb
== bb1
._ptr
) ++c1
;
48 if (&bb
== bb2
._ptr
) ++c2
;
49 if (&bb
== bb3
._ptr
) ++c3
;
52 t
.check("Build/Enumerate basic blocks", c1
== 1 && c2
== 1 && c3
== 1 && c
== 3);
55 Enumerator
<const Instruction
> enumins
= bb1
->instructions();
57 ok
= !enumins
.empty();
59 const Instruction
& ins
= enumins
.front();
60 ok
= ok
&& (ins
.getInsId() == host::I_CMP_RR
);
63 t
.check("Build/Enumerate instructions on BB1/1", ok
);
64 ok
= ok
&& !enumins
.empty();
66 const Instruction
& ins
= enumins
.front();
67 ok
= ok
&& (ins
.getInsId() == host::I_JGE_BB_FT
);
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();
81 if (&bb
== bb1
._ptr
) ++c1
;
82 if (&bb
== bb2
._ptr
) ++c2
;
83 if (&bb
== bb3
._ptr
) ++c3
;
86 t
.check("Build/Pred+succ",
87 predbb
.empty() && c
== 2 && c2
== 1 && c3
== 1);
91 MachineDumper
mdumper(dumper
, *mi
);
93 std::string dumpresult
= dumper
.takeResult();
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"
103 " mov_ww VR4096_GR32/r VR4098_GR32/w\n"
106 " mov_ww VR4097_GR32/r VR4098_GR32/w\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
);