Clean up irgen.h a bit
[hiphop-php.git] / hphp / runtime / vm / jit / align-internal-inl.h
blob921f94858105c0796b3f9a294ea007ba552cd489
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2016 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/mc-generator.h"
19 #include "hphp/util/data-block.h"
21 #include <folly/Bits.h>
22 #include <utility>
24 namespace HPHP { namespace jit {
26 ///////////////////////////////////////////////////////////////////////////////
28 namespace {
30 ///////////////////////////////////////////////////////////////////////////////
32 bool is_aligned(TCA frontier, const AlignInfo& a) {
33 assertx(a.nbytes <= a.align);
34 assertx(folly::isPowTwo(a.align));
36 auto const mask = a.align - 1;
38 auto const ifrontier = reinterpret_cast<size_t>(frontier);
39 auto const first_byte = ifrontier + a.offset;
40 auto const last_byte = ifrontier + a.nbytes - 1;
42 return (first_byte & ~mask) == (last_byte & ~mask);
45 size_t align_gap(TCA frontier, const AlignInfo& a) {
46 auto const ifrontier = reinterpret_cast<size_t>(frontier);
47 auto const gap = a.align - ((a.align - 1) & (ifrontier + a.offset));
49 return gap == a.align ? 0 : gap;
52 ///////////////////////////////////////////////////////////////////////////////
56 ///////////////////////////////////////////////////////////////////////////////
58 template <class AImpl>
59 bool is_aligned(TCA frontier, Alignment alignment) {
60 auto const idx = static_cast<uint32_t>(alignment);
61 bool const is_jccandjmp = alignment == Alignment::SmashJccAndJmp;
63 return is_aligned(frontier, AImpl::s_table[idx]) &&
64 (!is_jccandjmp || is_aligned(frontier, AImpl::s_table[idx + 1]));
67 template <class AImpl>
68 void align(CodeBlock& cb, CGMeta* meta,
69 Alignment alignment, AlignContext context) {
70 auto const idx = static_cast<uint32_t>(alignment);
71 bool const is_jccandjmp = alignment == Alignment::SmashJccAndJmp;
73 auto const pad_for_align = [&] (const AlignInfo& ali) {
74 if (is_aligned(cb.frontier(), ali)) return;
75 AImpl::pad(cb, context, align_gap(cb.frontier(), ali));
78 pad_for_align(AImpl::s_table[idx]);
79 if (is_jccandjmp) {
80 pad_for_align(AImpl::s_table[idx + 1]);
83 assertx(is_aligned(cb.frontier(), AImpl::s_table[idx]));
84 assertx(IMPLIES(is_jccandjmp,
85 is_aligned(cb.frontier(), AImpl::s_table[idx + 1])));
87 if (meta) {
88 meta->alignments.emplace(
89 cb.frontier(),
90 std::make_pair(alignment, context)
95 ///////////////////////////////////////////////////////////////////////////////