1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_
6 #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_
7 
8 #include "src/compiler/machine-type.h"
9 #include "src/handles.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 // Forward declarations.
15 template <class>
16 class TypeImpl;
17 struct ZoneTypeConfig;
18 typedef TypeImpl<ZoneTypeConfig> Type;
19 class Zone;
20 
21 
22 namespace compiler {
23 
24 // Forward declarations.
25 class Operator;
26 struct SimplifiedOperatorBuilderImpl;
27 
28 
29 enum BaseTaggedness { kUntaggedBase, kTaggedBase };
30 
31 OStream& operator<<(OStream&, BaseTaggedness);
32 
33 // An access descriptor for loads/stores of fixed structures like field
34 // accesses of heap objects. Accesses from either tagged or untagged base
35 // pointers are supported; untagging is done automatically during lowering.
36 struct FieldAccess {
37   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
38   int offset;                     // offset of the field, without tag.
39   Handle<Name> name;              // debugging only.
40   Type* type;                     // type of the field.
41   MachineType machine_type;       // machine type of the field.
42 
tagFieldAccess43   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
44 };
45 
46 
47 // An access descriptor for loads/stores of indexed structures like characters
48 // in strings or off-heap backing stores. Accesses from either tagged or
49 // untagged base pointers are supported; untagging is done automatically during
50 // lowering.
51 struct ElementAccess {
52   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
53   int header_size;                // size of the header, without tag.
54   Type* type;                     // type of the element.
55   MachineType machine_type;       // machine type of the element.
56 
tagElementAccess57   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
58 };
59 
60 bool operator==(ElementAccess const& lhs, ElementAccess const& rhs);
61 bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs);
62 
63 OStream& operator<<(OStream&, ElementAccess const&);
64 
65 
66 // If the accessed object is not a heap object, add this to the header_size.
67 static const int kNonHeapObjectHeaderSize = kHeapObjectTag;
68 
69 
70 const FieldAccess& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT;
71 const ElementAccess& ElementAccessOf(const Operator* op) WARN_UNUSED_RESULT;
72 
73 
74 // Interface for building simplified operators, which represent the
75 // medium-level operations of V8, including adding numbers, allocating objects,
76 // indexing into objects and arrays, etc.
77 // All operators are typed but many are representation independent.
78 
79 // Number values from JS can be in one of these representations:
80 //   - Tagged: word-sized integer that is either
81 //     - a signed small integer (31 or 32 bits plus a tag)
82 //     - a tagged pointer to a HeapNumber object that has a float64 field
83 //   - Int32: an untagged signed 32-bit integer
84 //   - Uint32: an untagged unsigned 32-bit integer
85 //   - Float64: an untagged float64
86 
87 // Additional representations for intermediate code or non-JS code:
88 //   - Int64: an untagged signed 64-bit integer
89 //   - Uint64: an untagged unsigned 64-bit integer
90 //   - Float32: an untagged float32
91 
92 // Boolean values can be:
93 //   - Bool: a tagged pointer to either the canonical JS #false or
94 //           the canonical JS #true object
95 //   - Bit: an untagged integer 0 or 1, but word-sized
96 class SimplifiedOperatorBuilder FINAL {
97  public:
98   explicit SimplifiedOperatorBuilder(Zone* zone);
99 
100   const Operator* BooleanNot();
101   const Operator* BooleanToNumber();
102 
103   const Operator* NumberEqual();
104   const Operator* NumberLessThan();
105   const Operator* NumberLessThanOrEqual();
106   const Operator* NumberAdd();
107   const Operator* NumberSubtract();
108   const Operator* NumberMultiply();
109   const Operator* NumberDivide();
110   const Operator* NumberModulus();
111   const Operator* NumberToInt32();
112   const Operator* NumberToUint32();
113 
114   const Operator* ReferenceEqual(Type* type);
115 
116   const Operator* StringEqual();
117   const Operator* StringLessThan();
118   const Operator* StringLessThanOrEqual();
119   const Operator* StringAdd();
120 
121   const Operator* ChangeTaggedToInt32();
122   const Operator* ChangeTaggedToUint32();
123   const Operator* ChangeTaggedToFloat64();
124   const Operator* ChangeInt32ToTagged();
125   const Operator* ChangeUint32ToTagged();
126   const Operator* ChangeFloat64ToTagged();
127   const Operator* ChangeBoolToBit();
128   const Operator* ChangeBitToBool();
129 
130   const Operator* LoadField(const FieldAccess&);
131   const Operator* StoreField(const FieldAccess&);
132 
133   // load-element [base + index], length
134   const Operator* LoadElement(ElementAccess const&);
135 
136   // store-element [base + index], length, value
137   const Operator* StoreElement(ElementAccess const&);
138 
139  private:
zone()140   Zone* zone() const { return zone_; }
141 
142   const SimplifiedOperatorBuilderImpl& impl_;
143   Zone* const zone_;
144 
145   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder);
146 };
147 
148 }  // namespace compiler
149 }  // namespace internal
150 }  // namespace v8
151 
152 #endif  // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
153