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/vasm-instr.h"
19 namespace HPHP
{ namespace jit
{
20 ///////////////////////////////////////////////////////////////////////////////
22 #define O(name, ...) \
23 static_assert(sizeof(name) <= 48, "vasm struct " #name " is too big");
26 static_assert(sizeof(Vinstr
) <= 64, "Vinstr should be <= 64 bytes");
28 const char* vinst_names
[] = {
29 #define O(name, imms, uses, defs) #name,
34 ///////////////////////////////////////////////////////////////////////////////
36 bool isBlockEnd(const Vinstr
& inst
) {
38 // service request-y things
40 case Vinstr::fallback
:
51 case Vinstr::tailcallstub
:
52 case Vinstr::tailcallstubr
:
53 case Vinstr::resumetc
:
57 case Vinstr::contenter
:
64 case Vinstr::fallthru
:
71 bool isCall(Vinstr::Opcode op
) {
74 case Vinstr::callfaststub
:
77 case Vinstr::callphpr
:
78 case Vinstr::callphps
:
81 case Vinstr::callstub
:
82 case Vinstr::tailcallstub
:
83 case Vinstr::tailcallstubr
:
92 Width
width(Vinstr::Opcode op
) {
97 case Vinstr::bindaddr
:
98 case Vinstr::fallback
:
99 case Vinstr::fallbackcc
:
101 case Vinstr::conjure
:
102 case Vinstr::conjureuse
:
105 case Vinstr::copyargs
:
106 case Vinstr::debugtrap
:
107 case Vinstr::fallthru
:
112 case Vinstr::ldundefq
:
119 case Vinstr::inlinestart
:
120 case Vinstr::inlineend
:
121 case Vinstr::pushframe
:
122 case Vinstr::popframe
:
123 case Vinstr::recordstack
:
124 case Vinstr::recordbasenativesp
:
125 case Vinstr::unrecordbasenativesp
:
127 case Vinstr::spillbi
:
128 case Vinstr::spillli
:
129 case Vinstr::spillqi
:
130 case Vinstr::spillundefq
:
132 case Vinstr::ssaalias
:
133 // native function abi
135 case Vinstr::vinvoke
:
142 case Vinstr::stublogue
:
143 case Vinstr::unstublogue
:
144 case Vinstr::stubret
:
145 case Vinstr::callstub
:
146 case Vinstr::callfaststub
:
147 case Vinstr::tailcallstub
:
148 case Vinstr::tailcallstubr
:
149 case Vinstr::stubunwind
:
151 case Vinstr::defvmsp
:
152 case Vinstr::defvmfp
:
153 case Vinstr::pushvmfp
:
154 case Vinstr::popvmfp
:
155 case Vinstr::syncvmsp
:
156 case Vinstr::defvmretdata
:
157 case Vinstr::defvmrettype
:
158 case Vinstr::syncvmret
:
159 case Vinstr::syncvmrettype
:
160 case Vinstr::phplogue
:
161 case Vinstr::stubtophp
:
162 case Vinstr::loadstubret
:
164 case Vinstr::callphp
:
165 case Vinstr::callphpr
:
166 case Vinstr::callphps
:
167 case Vinstr::contenter
:
169 case Vinstr::resumetc
:
171 case Vinstr::leavetc
:
172 // exception intrinsics
173 case Vinstr::landingpad
:
174 case Vinstr::nothrow
:
175 case Vinstr::syncpoint
:
180 // restrict/unrestrict new virtuals
181 case Vinstr::vregrestrict
:
182 case Vinstr::vregunrestrict
:
183 // sign/zero-extending/truncating copies
219 // floating-point conversions
220 case Vinstr::cvttsd2siq
:
221 case Vinstr::cvtsi2sd
:
222 case Vinstr::cvtsi2sdm
:
223 case Vinstr::unpcklpd
:
250 case Vinstr::testbim
:
257 case Vinstr::loadtqb
:
259 case Vinstr::storebi
:
276 case Vinstr::testwim
:
281 case Vinstr::storewi
:
310 case Vinstr::testlim
:
314 case Vinstr::loadzbl
:
315 case Vinstr::loadsbl
:
316 case Vinstr::loadtql
:
318 case Vinstr::storeli
:
329 case Vinstr::andqi64
:
332 case Vinstr::decqmlock
:
362 case Vinstr::testqim
:
372 case Vinstr::loadzbq
:
373 case Vinstr::loadzwq
:
374 case Vinstr::loadzlq
:
375 case Vinstr::loadsbq
:
376 case Vinstr::storeqi
:
380 case Vinstr::ucomisd
:
382 case Vinstr::storesd
:
386 case Vinstr::roundsd
:
391 case Vinstr::loadups
:
392 case Vinstr::storeups
:
398 bool instrHasIndirectFixup(const Vinstr
& inst
) {
401 return inst
.vcall_
.fixup
.isIndirect();
402 case Vinstr::vinvoke
:
403 return inst
.vinvoke_
.fixup
.isIndirect();
404 case Vinstr::syncpoint
:
405 return inst
.syncpoint_
.fix
.isIndirect();
406 case Vinstr::callfaststub
:
407 return inst
.callfaststub_
.fix
.isIndirect();
414 void updateIndirectFixupBySpill(Vinstr
& inst
, size_t spillSize
) {
415 assertx(instrHasIndirectFixup(inst
));
416 auto const update
= [&](Fixup
& f
) {
417 assertx(f
.isIndirect());
418 f
.adjustRipOffset(spillSize
);
422 update(inst
.vcall_
.fixup
);
424 case Vinstr::vinvoke
:
425 update(inst
.vinvoke_
.fixup
);
427 case Vinstr::syncpoint
:
428 update(inst
.syncpoint_
.fix
);
430 case Vinstr::callfaststub
:
431 update(inst
.callfaststub_
.fix
);
434 always_assert(false);
439 ///////////////////////////////////////////////////////////////////////////////