Adding copyright notices to most files. Also add readme file, and some
[jitcs.git] / tests / test_allinstructions.cpp
blob4fdb22f86c8a2c0c9c82d8e15038039249167300
1 //===-- tests/test_allinstructions.cpp --------------------------*- C++ -*-===//
2 // Test all instruction encodings provided by JITCS.
3 //
4 // Copyright (C) 2013-2014 Dirk Steinke.
5 // See copyright and license notice in COPYRIGHT or include/jitcs.h
6 //
7 // Will report wrong encodings, and instructions which have not been encoded
8 // at all. For that purpose, we pull in several *.as files from the _bin/{arch}
9 // directory. These *.as files have been created from *.ins files in
10 // tests/{arch}, enriched by the target encodings as used by NASM.
11 //===----------------------------------------------------------------------===//
13 #include "jitcs.h"
14 #include "unittest.h"
15 #include "jitcs_instructionstream.h"
16 #include "jitcs_dumper.h"
17 #include "jitcs_memmgr.h"
18 #include "jitcs_x86_32.h"
19 #include "jitcs_x86_64.h"
20 #include <unordered_set>
21 #include "jitcs_int_machine.h"
22 #include "jitcs_int_bitfuncs.h"
23 #include "test_asm_x86_32.h"
24 #include "test_asm_x86_64.h"
26 #include <stdio.h>
28 using namespace jitcs;
30 static void test(UnitTest& t) {
31 typedef void (__cdecl *FT0_c)();
32 RefCounter<TempAllocator> alloc(new TempAllocator);
33 RefCounter<MemoryMgr> mgr = MemoryMgr::Create();
35 #ifdef EVM_WINDOWS
36 std::string path = "data\\";
37 #else
38 std::string path = "data/";
39 #endif
41 std::vector<std::string> x86as_files;
42 x86as_files.push_back("mov_set");
43 x86as_files.push_back("arith");
44 x86as_files.push_back("other");
45 x86as_files.push_back("other_vex");
46 x86as_files.push_back("simd_mov");
47 x86as_files.push_back("simd_arith");
48 x86as_files.push_back("simd_blend");
49 x86as_files.push_back("simd_cvt");
50 x86as_files.push_back("simd_insext");
51 x86as_files.push_back("simd_shuffle");
52 x86as_files.push_back("simd_mov_vex");
53 x86as_files.push_back("simd_arith_vex");
54 x86as_files.push_back("simd_blend_vex");
55 x86as_files.push_back("simd_cvt_vex");
56 x86as_files.push_back("simd_insext_vex");
57 x86as_files.push_back("simd_shuffle_vex");
58 x86as_files.push_back("cf");
59 x86as_files.push_back("addrmode");
61 std::unordered_set<u32> allins;
62 std::unordered_set<u32> allins_compressed;
64 std::string prefix = path + "x86_32_";
66 RefCounter<IMachineInfo> mi = GetX86_32WinMachineInfo();
67 TestAssemblerX86_32 asm_win32(mgr, alloc, mi);
68 allins.clear();
69 allins_compressed.clear();
71 for (auto fn: x86as_files)
72 asm_win32.checkFile(t, prefix + fn + ".as", &allins,
73 prefix + fn + ".bin");
75 for (auto v: allins) {
76 u32 vv = v & 0x7fffffff;
77 allins_compressed.insert(((vv >> x86_32::ICL_NonMainBits) << x86_32::ICL_SubBits)
78 + (vv & x86_32::ICL_SubMask));
81 size_t n = 0;
82 for (u32 i = x86_32::ICL_First; i < x86_32::ICL_Last; ++i) {
83 n += popcnt(x86_32::ToValidMask(static_cast<x86_32::InsClassId>(i)));
85 char buffer[128];
86 sprintf(buffer, "x86_32/completeness: %d ins available, %d ins handled", n, allins_compressed.size());
87 t.check(buffer, n == allins_compressed.size());
88 if (n > allins_compressed.size()) {
89 PrintFDumper dd;
90 MachineDumper md(dd, *mi);
91 md.write("unhandled:");
92 for (u32 i = x86_32::ICL_First; i < x86_32::ICL_Last; ++i) {
93 u32 mask = x86_32::ToValidMask(static_cast<x86_32::InsClassId>(i));
94 for (size_t i2 = 0; i2 < 32; ++i2) {
95 if ((mask & (1 << i2)) == 0) continue;
96 u32 a = (i << x86_32::ICL_NonMainBits) + i2;
97 u32 b = (i << x86_32::ICL_SubBits) + i2;
98 if (allins_compressed.find(b) == allins_compressed.end()) {
99 md.write(" ");
100 md.write(static_cast<InsId>(a));
104 md.write("\n");
109 std::string prefix = path + "x86_64_";
111 RefCounter<IMachineInfo> mi = GetX86_64WinMachineInfo();
112 TestAssemblerX86_64 asm_win64(mgr, alloc, mi);
113 allins.clear();
114 allins_compressed.clear();
116 for (auto fn: x86as_files)
117 asm_win64.checkFile(t, prefix + fn + ".as", &allins,
118 prefix + fn + ".bin");
120 for (auto v: allins) {
121 u32 vv = v & 0x7fffffff;
122 allins_compressed.insert
123 (((vv >> x86_64::ICL_NonMainBits) << x86_64::ICL_SubBits)
124 + (vv & x86_64::ICL_SubMask));
127 size_t n = 0;
128 for (u32 i = x86_64::ICL_First; i < x86_64::ICL_Last; ++i) {
129 n += popcnt(x86_64::ToValidMask(static_cast<x86_64::InsClassId>(i)));
131 char buffer[128];
132 sprintf(buffer, "x86_64/completeness: %d ins available, %d ins handled", n, allins_compressed.size());
133 t.check(buffer, n == allins_compressed.size());
134 if (n > allins_compressed.size()) {
135 PrintFDumper dd;
136 MachineDumper md(dd, *mi);
137 md.write("unhandled:");
138 for (u32 i = x86_64::ICL_First; i < x86_64::ICL_Last; ++i) {
139 u32 mask = x86_64::ToValidMask(static_cast<x86_64::InsClassId>(i));
140 for (size_t i2 = 0; i2 < 32; ++i2) {
141 if ((mask & (1 << i2)) == 0) continue;
142 u32 a = (i << x86_64::ICL_NonMainBits) + i2;
143 u32 b = (i << x86_64::ICL_SubBits) + i2;
144 if (allins_compressed.find(b) == allins_compressed.end()) {
145 md.write(" ");
146 md.write(static_cast<InsId>(a));
150 md.write("\n");
156 static UnitTestRun _("AllInstructions", test);