Refactor back ends into implementations of BackEnd.
[hiphop-php.git] / hphp / runtime / vm / jit / service-requests-inline.h
blobaf253b417794bf04385b01caf70f515db9ebfba0
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_RUNTIME_VM_SERVICE_REQUESTS_INLINE_H_
17 #define incl_HPHP_RUNTIME_VM_SERVICE_REQUESTS_INLINE_H_
19 #include "hphp/runtime/vm/jit/service-requests.h"
20 #include "hphp/runtime/vm/jit/mc-generator.h"
22 namespace HPHP { namespace JIT {
24 inline ServiceReqArgInfo ccServiceReqArgInfo(JIT::ConditionCode cc) {
25 return ServiceReqArgInfo{ServiceReqArgInfo::CondCode, { uint64_t(cc) }};
28 template<typename T>
29 typename std::enable_if<
30 // Only allow for things with a sensible cast to uint64_t.
31 std::is_integral<T>::value || std::is_pointer<T>::value ||
32 std::is_enum<T>::value
33 >::type packServiceReqArg(ServiceReqArgVec& args, T arg) {
34 // By default, assume we meant to pass an immediate arg.
35 args.push_back({ ServiceReqArgInfo::Immediate, { uint64_t(arg) } });
38 inline void packServiceReqArg(ServiceReqArgVec& args,
39 const ServiceReqArgInfo& argInfo) {
40 args.push_back(argInfo);
43 template<typename T, typename... Arg>
44 void packServiceReqArgs(ServiceReqArgVec& argv, T arg, Arg... args) {
45 packServiceReqArg(argv, arg);
46 packServiceReqArgs(argv, args...);
49 inline void packServiceReqArgs(ServiceReqArgVec& argv) {
50 // Recursive base case.
53 //////////////////////////////////////////////////////////////////////
55 template<typename... Arg>
56 TCA emitServiceReq(CodeBlock& cb, SRFlags flags, ServiceRequest sr, Arg... a) {
57 // These should reuse stubs. Use emitEphemeralServiceReq.
58 assert(sr != REQ_BIND_JMPCC_FIRST &&
59 sr != REQ_BIND_JMPCC_SECOND &&
60 sr != REQ_BIND_JMP);
62 ServiceReqArgVec argv;
63 packServiceReqArgs(argv, a...);
64 return mcg->backEnd().emitServiceReqWork(cb, cb.frontier(), true, flags, sr,
65 argv);
68 template<typename... Arg>
69 TCA emitServiceReq(CodeBlock& cb, ServiceRequest sr, Arg... a) {
70 return emitServiceReq(cb, SRFlags::None, sr, a...);
73 template<typename... Arg>
74 TCA emitEphemeralServiceReq(CodeBlock& cb, TCA start, ServiceRequest sr,
75 Arg... a) {
76 assert(sr == REQ_BIND_JMPCC_FIRST ||
77 sr == REQ_BIND_JMPCC_SECOND ||
78 sr == REQ_BIND_JMP);
79 assert(cb.contains(start));
81 ServiceReqArgVec argv;
82 packServiceReqArgs(argv, a...);
83 return mcg->backEnd().emitServiceReqWork(cb, start, false, SRFlags::None, sr,
84 argv);
87 //////////////////////////////////////////////////////////////////////
91 namespace std {
93 template<> struct hash<HPHP::JIT::ServiceRequest> {
94 size_t operator()(const HPHP::JIT::ServiceRequest& sr) const {
95 return sr;
101 #endif