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
76// Use this form for Load (but not Load8Z, Load8S, or any of the Loads that have a suffix that
77// describes the returned type).
78MemoryValue::MemoryValue(MemoryValue::MemoryValueLoad, Kind kind, Type type, Origin origin, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
79 : Value(CheckedOpcode, kind, type, One, origin, pointer)
80 , m_offset(offset)
81 , m_range(range)
82 , m_fenceRange(fenceRange)
83{
84 if (!ASSERT_DISABLED) {
85 switch (kind.opcode()) {
86 case Load:
87 break;
88 case Load8Z:
89 case Load8S:
90 case Load16Z:
91 case Load16S:
92 ASSERT(type == Int32);
93 break;
94 case Store8:
95 case Store16:
96 case Store:
97 ASSERT(type == Void);
98 break;
99 default:
100 ASSERT_NOT_REACHED();
101 }
102 }
103}
104
105// Use this form for loads where the return type is implied.
106MemoryValue::MemoryValue(MemoryValue::MemoryValueLoadImplied, Kind kind, Origin origin, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
107 : MemoryValue(kind, Int32, origin, pointer, offset, range, fenceRange)
108{
109 if (!ASSERT_DISABLED) {
110 switch (kind.opcode()) {
111 case Load8Z:
112 case Load8S:
113 case Load16Z:
114 case Load16S:
115 break;
116 default:
117 ASSERT_NOT_REACHED();
118 }
119 }
120}
121
122// Use this form for stores.
123MemoryValue::MemoryValue(MemoryValue::MemoryValueStore, Kind kind, Origin origin, Value* value, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
124 : Value(CheckedOpcode, kind, Void, Two, origin, value, pointer)
125 , m_offset(offset)
126 , m_range(range)
127 , m_fenceRange(fenceRange)
128{
129 ASSERT(B3::isStore(kind.opcode()));
130}
131
132} } // namespace JSC::B3
133
134#endif // ENABLE(B3_JIT)
135