Switch-related cleanup
[hiphop-php.git] / hphp / runtime / vm / jit / stack-offsets.h
blob8684cbb34c5bcf0f28d890f8130c552af7870a68
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2015 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_JIT_STACK_OFFSETS_H_
17 #define incl_HPHP_JIT_STACK_OFFSETS_H_
19 #include "hphp/util/safe-cast.h"
22 * We compute and store 'stack offsets' in many different places in the jit,
23 * and there are a number of different frames of reference for these offsets.
24 * This header declares some structs that allow us to be explicit about which
25 * frame of reference we're using and provides a little bit of type safety when
26 * converting between these various reference frames. Below is a diagram of how
27 * the stack is generally laid out along with an example of what some offsets in
28 * each reference frame refers to.
30 * Stack reference frames:
32 * Actual memory:
34 * | ActRec | higher addresses
35 * | ActRec | |
36 * | ActRec | <--- fp |
37 * +-------------+ |
38 * | evalslot AA | |
39 * +-------------+ |
40 * | evalslot BB | |
41 * +-------------+ |
42 * | evalslot CC | <--- stkptr |
43 * +-------------+ |
44 * | evalslot DD | |
45 * +-------------+ |
46 * | evalslot EE | |
47 * +-------------+ |
48 * | ........... | |
49 * lower addresses
51 * FPRel: Offset in cells relative to the frame pointer in address order.
52 * FPInv: Offset in cells relative to the frame pointer in reverse address
53 * order (i.e. a positive offset indicates lower address).
54 * IRSP: Offset in cells relative to the IR stack pointer in address order.
55 * BCSP: Offset in cells relative to the top of the stack at the start of the
56 * current bytecode in address order.
58 * Supposing we're translating a bytecode instruction where EE is "top of
59 * stack" in HHBC semantics, then here are some examples:
61 * slot FPRel FPInv IRSP BCSP
62 * EE -5 5 -2 0
63 * DD -4 4 -1 1
64 * CC -3 3 0 2
65 * BB -2 2 1 3
66 * AA -1 1 2 4
70 * NB: The operators that are present in the various offset structs were added on
71 * an as-needed basis. If you find that something obvious is missing, it's
72 * probably because nobody was doing it previously. Do keep in mind, however,
73 * that it doesn't always make sense to add all operators for all offset types.
74 * For example, it doesn't really make sense to add an IRSPOffset and a
75 * BCSPOffset together.
78 namespace HPHP { namespace jit {
80 struct IRSPOffset {
81 int32_t offset;
83 bool operator==(IRSPOffset o) const { return offset == o.offset; }
84 bool operator==(int32_t other) const { return offset == other; }
86 IRSPOffset operator+(int32_t x) const { return IRSPOffset{offset + x}; }
87 IRSPOffset operator-(int32_t x) const { return IRSPOffset{offset - x}; }
89 bool operator<(IRSPOffset o) const { return offset < o.offset; }
90 bool operator>(IRSPOffset o) const { return offset > o.offset; }
92 IRSPOffset& operator+=(size_t delta) {
93 offset += delta;
94 return *this;
98 inline IRSPOffset operator+(int32_t lhs, IRSPOffset rhs) {
99 return rhs + lhs;
101 inline IRSPOffset operator-(int32_t lhs, IRSPOffset rhs) {
102 return IRSPOffset{lhs - rhs.offset};
105 struct BCSPOffset {
106 int32_t offset;
108 bool operator==(BCSPOffset o) const { return offset == o.offset; }
109 bool operator==(int32_t otherOffset) const { return offset == otherOffset; }
110 bool operator>=(int32_t otherOffset) const { return offset >= otherOffset; }
111 bool operator<(BCSPOffset other) const { return offset < other.offset; }
112 bool operator>(BCSPOffset other) const { return offset > other.offset; }
113 bool operator<(int32_t otherOffset) const { return offset < otherOffset; }
115 BCSPOffset& operator++() {
116 offset++;
117 return *this;
120 BCSPOffset operator++(int) {
121 auto before = BCSPOffset{offset};
122 offset++;
123 return before;
126 BCSPOffset& operator+=(size_t delta) {
127 offset += safe_cast<int32_t>(delta);
128 return *this;
131 BCSPOffset operator-() const { return BCSPOffset{-offset}; }
133 BCSPOffset operator-(int32_t delta) { return BCSPOffset{offset - delta}; }
136 struct FPInvOffset {
137 int32_t offset;
139 static constexpr FPInvOffset invalid() { return FPInvOffset{INT_MIN}; }
141 bool operator==(FPInvOffset o) const { return offset == o.offset; }
143 bool isValid() const {
144 return offset != INT_MIN;
147 FPInvOffset operator+(int32_t delta) const {
148 return FPInvOffset{offset + delta};
151 // Return an int32_t because the difference between two FPInvOffsets is no
152 // longer an FPInvOffset.
153 int32_t operator-(FPInvOffset o) const { return offset - o.offset; }
154 FPInvOffset operator-(BCSPOffset o) const {
155 return FPInvOffset{offset - o.offset};
157 FPInvOffset operator-(IRSPOffset o) {
158 return FPInvOffset{offset - o.offset};
160 FPInvOffset operator-(int32_t delta) const {
161 return FPInvOffset{offset - delta};
164 FPInvOffset& operator++() {
165 offset++;
166 return *this;
169 FPInvOffset& operator--() {
170 offset--;
171 return *this;
174 FPInvOffset& operator+=(int32_t delta) {
175 offset += delta;
176 return *this;
178 FPInvOffset& operator-=(int32_t delta) {
179 offset -= delta;
180 return *this;
183 bool operator>(FPInvOffset o) const { return offset > o.offset; }
184 bool operator>(int32_t otherOffset) const { return offset > otherOffset; }
185 bool operator>=(int32_t otherOffset) const { return offset >= otherOffset; }
186 bool operator<(FPInvOffset other) const { return offset < other.offset; }
187 bool operator<(int32_t otherOffset) const { return offset < otherOffset; }
190 inline bool operator>=(size_t lhs, FPInvOffset rhs) {
191 return safe_cast<int32_t>(lhs) >= rhs.offset;
194 struct FPRelOffset {
195 int32_t offset;
197 FPRelOffset operator+(int32_t x) const { return FPRelOffset{offset + x}; }
198 FPRelOffset operator-(int32_t x) const { return FPRelOffset{offset - x}; }
201 inline FPRelOffset operator+(int32_t lhs, FPRelOffset rhs) {
202 return rhs + lhs;
205 } } // HPHP::jit
207 #endif // incl_HPHP_JIT_STACK_OFFSETS_H_