2 +----------------------------------------------------------------------+
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"
26 /* using override */ using HPHP::jit::ConditionCode
;
28 #define BRANCHES(cr) \
30 CR##cr##_LessThanEqual, \
31 CR##cr##_GreaterThan, \
32 CR##cr##_GreaterThanEqual, \
38 enum class BranchConditions
{
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
,
59 NotEqual
= CR0_NotEqual
,
60 Overflow
= CR0_Overflow
,
61 NoOverflow
= CR0_NoOverflow
67 /* BO and BI parameter mapping related to BranchConditions */
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))
97 NoBranchPrediction
= 3
102 /* Constructor auxiliary */
103 void defineBoBi(BranchConditions bc
) {
105 /* Signed comparison */
106 case BranchConditions::LessThan
:
108 m_bi
= BI::CR0_LessThan
;
110 case BranchConditions::LessThanEqual
:
112 m_bi
= BI::CR0_GreaterThan
;
114 case BranchConditions::GreaterThan
:
116 m_bi
= BI::CR0_GreaterThan
;
118 case BranchConditions::GreaterThanEqual
:
120 m_bi
= BI::CR0_LessThan
;
123 /* Unsigned comparison */
124 case BranchConditions::LessThan_Unsigned
:
126 m_bi
= BI::CR1_LessThan
;
128 case BranchConditions::LessThanEqual_Unsigned
:
130 m_bi
= BI::CR1_GreaterThan
;
132 case BranchConditions::GreaterThan_Unsigned
:
134 m_bi
= BI::CR1_GreaterThan
;
136 case BranchConditions::GreaterThanEqual_Unsigned
:
138 m_bi
= BI::CR1_LessThan
;
141 case BranchConditions::Equal
:
143 m_bi
= BI::CR0_Equal
;
145 case BranchConditions::NotEqual
:
147 m_bi
= BI::CR0_Equal
;
149 case BranchConditions::Overflow
:
151 m_bi
= BI::CR0_SummaryOverflow
;
153 case BranchConditions::NoOverflow
:
155 m_bi
= BI::CR0_SummaryOverflow
;
157 case BranchConditions::Always
:
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
;
179 case HPHP::jit::CC_O
:
180 ret
= BranchConditions::Overflow
;
182 case HPHP::jit::CC_NO
:
183 ret
= BranchConditions::NoOverflow
;
185 case HPHP::jit::CC_B
:
186 ret
= BranchConditions::LessThan_Unsigned
;
188 case HPHP::jit::CC_AE
:
189 ret
= BranchConditions::GreaterThanEqual_Unsigned
;
191 case HPHP::jit::CC_E
:
192 ret
= BranchConditions::Equal
;
194 case HPHP::jit::CC_NE
:
195 ret
= BranchConditions::NotEqual
;
197 case HPHP::jit::CC_BE
:
198 ret
= BranchConditions::LessThanEqual_Unsigned
;
200 case HPHP::jit::CC_A
:
201 ret
= BranchConditions::GreaterThan_Unsigned
;
203 case HPHP::jit::CC_S
:
204 ret
= BranchConditions::LessThan
;
206 case HPHP::jit::CC_NS
:
207 ret
= BranchConditions::GreaterThan
;
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
;
218 case HPHP::jit::CC_NP
:
219 ret
= BranchConditions::NoOverflow
;
222 case HPHP::jit::CC_L
:
223 ret
= BranchConditions::LessThan
;
225 case HPHP::jit::CC_NL
:
226 ret
= BranchConditions::GreaterThanEqual
;
228 case HPHP::jit::CC_NG
:
229 ret
= BranchConditions::LessThanEqual
;
231 case HPHP::jit::CC_G
:
232 ret
= BranchConditions::GreaterThan
;
235 case HPHP::jit::CC_None
:
236 ret
= BranchConditions::Always
;
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
);
260 * Converts to ConditionCode upon casting to it
262 /* implicit */ operator ConditionCode() {
263 ConditionCode ret
= HPHP::jit::CC_None
;
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
;
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
;
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
;
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
;
283 if (m_bo
== BO::CRSet
) ret
= HPHP::jit::CC_E
;
284 else if (m_bo
== BO::CRNotSet
) ret
= HPHP::jit::CC_NE
;
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
;
291 assert(false && "Not a valid conditional branch parameter");
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
; }
307 BranchParams::BO m_bo
;
308 BranchParams::BI m_bi
;
312 } // namespace ppc64_asm