Don't use Aast.Any when marking expressions as type Tany
[hiphop-php.git] / hphp / ppc64-asm / branch-ppc64.h
bloba2f711feac2aa139a635b6b721d4f28d6ca996de
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | (c) Copyright IBM Corporation 2015-2016 |
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 #ifndef incl_HPHP_PPC64_ASM_BRANCH_PPC64_H_
18 #define incl_HPHP_PPC64_ASM_BRANCH_PPC64_H_
20 #include "hphp/util/asm-x64.h"
22 #include "hphp/ppc64-asm/isa-ppc64.h"
24 namespace ppc64_asm {
26 /* using override */ using HPHP::jit::ConditionCode;
28 #define BRANCHES(cr) \
29 CR##cr##_LessThan, \
30 CR##cr##_LessThanEqual, \
31 CR##cr##_GreaterThan, \
32 CR##cr##_GreaterThanEqual, \
33 CR##cr##_Equal, \
34 CR##cr##_NotEqual, \
35 CR##cr##_Overflow, \
36 CR##cr##_NoOverflow
38 enum class BranchConditions {
39 BRANCHES(0),
40 BRANCHES(1),
41 BRANCHES(2),
42 BRANCHES(3),
43 BRANCHES(4),
44 BRANCHES(5),
45 BRANCHES(6),
46 BRANCHES(7),
47 Always,
49 // mnemonics for the common case by using CR0:
50 LessThan = CR0_LessThan,
51 LessThanEqual = CR0_LessThanEqual,
52 GreaterThan = CR0_GreaterThan,
53 GreaterThanEqual = CR0_GreaterThanEqual,
54 LessThan_Unsigned = CR1_LessThan,
55 LessThanEqual_Unsigned = CR1_LessThanEqual,
56 GreaterThan_Unsigned = CR1_GreaterThan,
57 GreaterThanEqual_Unsigned = CR1_GreaterThanEqual,
58 Equal = CR0_Equal,
59 NotEqual = CR0_NotEqual,
60 Overflow = CR0_Overflow,
61 NoOverflow = CR0_NoOverflow
64 #undef BRANCHES
66 struct BranchParams {
67 /* BO and BI parameter mapping related to BranchConditions */
68 enum class BO {
69 CRNotSet = 4,
70 CRSet = 12,
71 Always = 20
74 #define CR_CONDITIONS(cr) \
75 CR##cr##_LessThan = (0 + (cr * 4)), \
76 CR##cr##_GreaterThan = (1 + (cr * 4)), \
77 CR##cr##_Equal = (2 + (cr * 4)), \
78 CR##cr##_SummaryOverflow = (3 + (cr * 4))
80 enum class BI {
81 CR_CONDITIONS(0),
82 CR_CONDITIONS(1),
83 CR_CONDITIONS(2),
84 CR_CONDITIONS(3),
85 CR_CONDITIONS(4),
86 CR_CONDITIONS(5),
87 CR_CONDITIONS(6),
88 CR_CONDITIONS(7)
91 #undef CR_CONDITIONS
93 enum class BH {
94 CTR_Loop = 0,
95 LR_Loop = 1,
96 Reserved = 2,
97 NoBranchPrediction = 3
100 private:
102 /* Constructor auxiliary */
103 void defineBoBi(BranchConditions bc) {
104 switch (bc) {
105 /* Signed comparison */
106 case BranchConditions::LessThan:
107 m_bo = BO::CRSet;
108 m_bi = BI::CR0_LessThan;
109 break;
110 case BranchConditions::LessThanEqual:
111 m_bo = BO::CRNotSet;
112 m_bi = BI::CR0_GreaterThan;
113 break;
114 case BranchConditions::GreaterThan:
115 m_bo = BO::CRSet;
116 m_bi = BI::CR0_GreaterThan;
117 break;
118 case BranchConditions::GreaterThanEqual:
119 m_bo = BO::CRNotSet;
120 m_bi = BI::CR0_LessThan;
121 break;
123 /* Unsigned comparison */
124 case BranchConditions::LessThan_Unsigned:
125 m_bo = BO::CRSet;
126 m_bi = BI::CR1_LessThan;
127 break;
128 case BranchConditions::LessThanEqual_Unsigned:
129 m_bo = BO::CRNotSet;
130 m_bi = BI::CR1_GreaterThan;
131 break;
132 case BranchConditions::GreaterThan_Unsigned:
133 m_bo = BO::CRSet;
134 m_bi = BI::CR1_GreaterThan;
135 break;
136 case BranchConditions::GreaterThanEqual_Unsigned:
137 m_bo = BO::CRNotSet;
138 m_bi = BI::CR1_LessThan;
139 break;
141 case BranchConditions::Equal:
142 m_bo = BO::CRSet;
143 m_bi = BI::CR0_Equal;
144 break;
145 case BranchConditions::NotEqual:
146 m_bo = BO::CRNotSet;
147 m_bi = BI::CR0_Equal;
148 break;
149 case BranchConditions::Overflow:
150 m_bo = BO::CRSet;
151 m_bi = BI::CR0_SummaryOverflow;
152 break;
153 case BranchConditions::NoOverflow:
154 m_bo = BO::CRNotSet;
155 m_bi = BI::CR0_SummaryOverflow;
156 break;
157 case BranchConditions::Always:
158 m_bo = BO::Always;
159 m_bi = BI(0);
160 break;
162 default:
163 not_implemented();
165 m_lr = false;
167 #undef SWITCHES
169 public:
170 BranchParams() = delete;
172 BranchParams(BranchConditions bc) { defineBoBi(bc); }
173 BranchParams(ConditionCode cc) { defineBoBi(convertCC(cc)); }
175 static BranchConditions convertCC(ConditionCode cc) {
176 BranchConditions ret = BranchConditions::Always;
178 switch (cc) {
179 case HPHP::jit::CC_O:
180 ret = BranchConditions::Overflow;
181 break;
182 case HPHP::jit::CC_NO:
183 ret = BranchConditions::NoOverflow;
184 break;
185 case HPHP::jit::CC_B:
186 ret = BranchConditions::LessThan_Unsigned;
187 break;
188 case HPHP::jit::CC_AE:
189 ret = BranchConditions::GreaterThanEqual_Unsigned;
190 break;
191 case HPHP::jit::CC_E:
192 ret = BranchConditions::Equal;
193 break;
194 case HPHP::jit::CC_NE:
195 ret = BranchConditions::NotEqual;
196 break;
197 case HPHP::jit::CC_BE:
198 ret = BranchConditions::LessThanEqual_Unsigned;
199 break;
200 case HPHP::jit::CC_A:
201 ret = BranchConditions::GreaterThan_Unsigned;
202 break;
203 case HPHP::jit::CC_S:
204 ret = BranchConditions::LessThan;
205 break;
206 case HPHP::jit::CC_NS:
207 ret = BranchConditions::GreaterThan;
208 break;
211 * Parity works only for unordered double comparison
212 * Todo: fixed point comparison parity
213 * http://stackoverflow.com/q/32319673/5013070
215 case HPHP::jit::CC_P:
216 ret = BranchConditions::Overflow;
217 break;
218 case HPHP::jit::CC_NP:
219 ret = BranchConditions::NoOverflow;
220 break;
222 case HPHP::jit::CC_L:
223 ret = BranchConditions::LessThan;
224 break;
225 case HPHP::jit::CC_NL:
226 ret = BranchConditions::GreaterThanEqual;
227 break;
228 case HPHP::jit::CC_NG:
229 ret = BranchConditions::LessThanEqual;
230 break;
231 case HPHP::jit::CC_G:
232 ret = BranchConditions::GreaterThan;
233 break;
235 case HPHP::jit::CC_None:
236 ret = BranchConditions::Always;
237 break;
239 default:
240 not_implemented();
241 break;
243 return ret;
247 * Get the BranchParams from an emitted conditional branch
248 * Also set m_lr accordingly.
250 BranchParams(const PPC64Instr* const pinstr) { decodeInstr(pinstr); }
251 BranchParams(const uint8_t* const pinstr) {
252 decodeInstr(reinterpret_cast<const PPC64Instr* const>(pinstr));
255 void decodeInstr(const PPC64Instr* const pinstr);
257 ~BranchParams() {}
260 * Converts to ConditionCode upon casting to it
262 /* implicit */ operator ConditionCode() {
263 ConditionCode ret = HPHP::jit::CC_None;
265 switch (m_bi) {
266 case BI::CR0_LessThan:
267 if (m_bo == BO::CRSet) ret = HPHP::jit::CC_L; // CC_S
268 else if (m_bo == BO::CRNotSet) ret = HPHP::jit::CC_NL;
269 break;
270 case BI::CR0_GreaterThan:
271 if (m_bo == BO::CRSet) ret = HPHP::jit::CC_G; // CC_NS
272 else if (m_bo == BO::CRNotSet) ret = HPHP::jit::CC_NG;
273 break;
274 case BI::CR1_LessThan:
275 if (m_bo == BO::CRSet) ret = HPHP::jit::CC_B; // CC_S
276 else if (m_bo == BO::CRNotSet) ret = HPHP::jit::CC_AE;
277 break;
278 case BI::CR1_GreaterThan:
279 if (m_bo == BO::CRSet) ret = HPHP::jit::CC_A; // CC_NS
280 else if (m_bo == BO::CRNotSet) ret = HPHP::jit::CC_BE;
281 break;
282 case BI::CR0_Equal:
283 if (m_bo == BO::CRSet) ret = HPHP::jit::CC_E;
284 else if (m_bo == BO::CRNotSet) ret = HPHP::jit::CC_NE;
285 break;
286 case BI::CR0_SummaryOverflow:
287 if (m_bo == BO::CRSet) ret = HPHP::jit::CC_O;
288 else if (m_bo == BO::CRNotSet) ret = HPHP::jit::CC_NO;
289 break;
290 default:
291 assert(false && "Not a valid conditional branch parameter");
292 break;
295 return ret;
298 explicit operator BranchConditions() {
299 return convertCC(static_cast<ConditionCode>(*this));
302 uint8_t bo() { return (uint8_t)m_bo; }
303 uint8_t bi() { return (uint8_t)m_bi; }
304 bool savesLR() { return m_lr; }
306 private:
307 BranchParams::BO m_bo;
308 BranchParams::BI m_bi;
309 bool m_lr;
312 } // namespace ppc64_asm
314 #endif