2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/containers.h"
18 #include "hphp/runtime/vm/jit/vasm.h"
19 #include "hphp/runtime/vm/jit/vasm-gen.h"
20 #include "hphp/runtime/vm/jit/vasm-instr.h"
21 #include "hphp/runtime/vm/jit/vasm-print.h"
22 #include "hphp/runtime/vm/jit/vasm-unit.h"
24 #include <folly/portability/GTest.h>
30 // Strip extraneous whitespace from vasm code strings.
31 std::string
stripWhitespace(std::string str
) {
32 if (str
.length() > 1 && str
[0] == '\n' && str
[1] == ' ') {
36 while((spc
= str
.find(" ", pos
)) != std::string::npos
) {
41 while((spc
= str
.find(" \n", pos
)) != std::string::npos
) {
46 while((spc
= str
.find("\n ", pos
)) != std::string::npos
) {
56 unit
.entry
= unit
.makeBlock(AreaIndex::Main
, 1);
57 Vout
v(unit
, unit
.entry
);
59 auto sf
= v
.makeReg();
60 auto dst
= v
.makeReg();
61 auto xdst
= v
.makeReg();
62 v
<< movl
{unit
.makeConst(42u), sf
};
63 v
<< setcc
{CC_Z
, sf
, dst
};
64 v
<< xorbi
{1, dst
, xdst
, v
.makeReg()};
68 // Test that setcc/xor pair is collapsed.
71 "movl %131(42l) => %128\n"
72 "setcc NE, %128 => %130\n",
73 stripWhitespace(show(unit
))
79 unit
.entry
= unit
.makeBlock(AreaIndex::Main
, 1);
80 Vout
v(unit
, unit
.entry
);
82 auto sf
= v
.makeReg();
83 auto dst
= v
.makeReg();
84 auto xdst
= v
.makeReg();
85 v
<< movl
{unit
.makeConst(42u), sf
};
86 v
<< setcc
{CC_Z
, sf
, dst
};
87 v
<< xorbi
{1, dst
, xdst
, v
.makeReg()};
88 v
<< movl
{dst
, v
.makeReg()};
92 // Test that setcc/xor pair is not collapsed when setcc result
93 // has more than one use.
96 "movl %131(42l) => %128\n"
97 "setcc E, %128 => %129\n"
98 "xorbi 1, %129 => %130, %132\n"
99 "movl %129 => %133\n",
100 stripWhitespace(show(unit
))
106 unit
.entry
= unit
.makeBlock(AreaIndex::Main
, 1);
107 Vout
v(unit
, unit
.entry
);
109 auto sf
= v
.makeReg();
110 auto dst
= v
.makeReg();
111 auto xdst
= v
.makeReg();
112 v
<< movl
{unit
.makeConst(42u), sf
};
113 v
<< setcc
{CC_NZ
, sf
, dst
};
114 v
<< xorbi
{1, dst
, xdst
, v
.makeReg()};
118 // Check that setcc/xor pair is collapsed with different condition.
121 "movl %131(42l) => %128\n"
122 "setcc E, %128 => %130\n",
123 stripWhitespace(show(unit
))
129 unit
.entry
= unit
.makeBlock(AreaIndex::Main
, 1);
130 Vout
v(unit
, unit
.entry
);
132 auto sf
= v
.makeReg();
133 auto dst
= v
.makeReg();
134 v
<< movl
{unit
.makeConst(42u), sf
};
135 v
<< setcc
{CC_NZ
, sf
, dst
};
139 // Make sure that setcc with no xor doesn't cause a buffer overrun.
142 "movl %130(42l) => %128\n"
143 "setcc NE, %128 => %129\n",
144 stripWhitespace(show(unit
))
150 unit
.entry
= unit
.makeBlock(AreaIndex::Main
, 1);
151 Vout
v(unit
, unit
.entry
);
153 auto sf
= v
.makeReg();
154 auto dst
= v
.makeReg();
155 auto xdst
= v
.makeReg();
156 v
<< movl
{unit
.makeConst(42u), sf
};
157 v
<< setcc
{CC_NZ
, sf
, dst
};
158 v
<< xorbi
{2, dst
, xdst
, v
.makeReg()};
162 // Make sure that setcc/xor with an non-1 xor constant is skipped.
165 "movl %131(42l) => %128\n"
166 "setcc NE, %128 => %129\n"
167 "xorbi 2, %129 => %130, %132\n",
168 stripWhitespace(show(unit
))
174 unit
.entry
= unit
.makeBlock(AreaIndex::Main
, 1);
175 Vout
v(unit
, unit
.entry
);
177 auto sf
= v
.makeReg();
178 auto dst
= v
.makeReg();
179 auto xdst
= v
.makeReg();
180 auto xsf
= v
.makeReg();
181 v
<< movl
{unit
.makeConst(42u), sf
};
182 v
<< setcc
{CC_NZ
, sf
, dst
};
183 v
<< xorbi
{1, dst
, xdst
, xsf
};
184 v
<< movl
{xsf
, v
.makeReg()};
188 // Make sure that setcc/xor with xor status flags being used is skipped.
191 "movl %132(42l) => %128\n"
192 "setcc NE, %128 => %129\n"
193 "xorbi 1, %129 => %130, %131\n"
194 "movl %131 => %133\n",
195 stripWhitespace(show(unit
))
202 TEST(Vasm
, Simplifier
) {