1/*
2 * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "B3MemoryValue.h"
28
29#if ENABLE(B3_JIT)
30
31#include "B3AtomicValue.h"
32#include "B3MemoryValueInlines.h"
33#include "B3ValueInlines.h"
34
35namespace JSC { namespace B3 {
36
37MemoryValue::~MemoryValue()
38{
39}
40
41bool MemoryValue::isLegalOffsetImpl(int64_t offset) const
42{
43 return B3::isRepresentableAs<OffsetType>(offset) && isLegalOffset(static_cast<OffsetType>(offset));
44}
45
46Type MemoryValue::accessType() const
47{
48 if (isLoad())
49 return type();
50 // This happens to work for atomics, too. That's why AtomicValue does not need to override this.
51 return child(0)->type();
52}
53
54Bank MemoryValue::accessBank() const
55{
56 return bankForType(accessType());
57}
58
59size_t MemoryValue::accessByteSize() const
60{
61 return bytes(accessWidth());
62}
63
64void MemoryValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
65{
66 if (m_offset)
67 out.print(comma, "offset = ", m_offset);
68 if ((isLoad() && effects().reads != range())
69 || (isStore() && effects().writes != range())
70 || isExotic())
71 out.print(comma, "range = ", range());
72 if (isExotic())
73 out.print(comma, "fenceRange = ", fenceRange());
74}
75
76Value* MemoryValue::cloneImpl() const
77{
78 return new MemoryValue(*this);
79}
80
81// Use this form for Load (but not Load8Z, Load8S, or any of the Loads that have a suffix that
82// describes the returned type).
83MemoryValue::MemoryValue(MemoryValue::MemoryValueLoad, Kind kind, Type type, Origin origin, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
84 : Value(CheckedOpcode, kind, type, origin, pointer)
85 , m_offset(offset)
86 , m_range(range)
87 , m_fenceRange(fenceRange)
88{
89 if (!ASSERT_DISABLED) {
90 switch (kind.opcode()) {
91 case Load:
92 break;
93 case Load8Z:
94 case Load8S:
95 case Load16Z:
96 case Load16S:
97 ASSERT(type == Int32);
98 break;
99 case Store8:
100 case Store16:
101 case Store:
102 ASSERT(type == Void);
103 break;
104 default:
105 ASSERT_NOT_REACHED();
106 }
107 }
108}
109
110// Use this form for loads where the return type is implied.
111MemoryValue::MemoryValue(MemoryValue::MemoryValueLoadImplied, Kind kind, Origin origin, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
112 : MemoryValue(kind, Int32, origin, pointer, offset, range, fenceRange)
113{
114 if (!ASSERT_DISABLED) {
115 switch (kind.opcode()) {
116 case Load8Z:
117 case Load8S:
118 case Load16Z:
119 case Load16S:
120 break;
121 default:
122 ASSERT_NOT_REACHED();
123 }
124 }
125}
126
127// Use this form for stores.
128MemoryValue::MemoryValue(MemoryValue::MemoryValueStore, Kind kind, Origin origin, Value* value, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
129 : Value(CheckedOpcode, kind, Void, origin, value, pointer)
130 , m_offset(offset)
131 , m_range(range)
132 , m_fenceRange(fenceRange)
133{
134 ASSERT(B3::isStore(kind.opcode()));
135}
136
137} } // namespace JSC::B3
138
139#endif // ENABLE(B3_JIT)
140