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#include "src/compiler/machine-operator.h" 6 7#include "src/base/lazy-instance.h" 8#include "src/compiler/opcodes.h" 9#include "src/compiler/operator.h" 10 11namespace v8 { 12namespace internal { 13namespace compiler { 14 15OStream& operator<<(OStream& os, const WriteBarrierKind& write_barrier_kind) { 16 switch (write_barrier_kind) { 17 case kNoWriteBarrier: 18 return os << "NoWriteBarrier"; 19 case kFullWriteBarrier: 20 return os << "FullWriteBarrier"; 21 } 22 UNREACHABLE(); 23 return os; 24} 25 26 27OStream& operator<<(OStream& os, const StoreRepresentation& rep) { 28 return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind() 29 << ")"; 30} 31 32 33template <> 34struct StaticParameterTraits<StoreRepresentation> { 35 static OStream& PrintTo(OStream& os, const StoreRepresentation& rep) { 36 return os << rep; 37 } 38 static int HashCode(const StoreRepresentation& rep) { 39 return rep.machine_type() + rep.write_barrier_kind(); 40 } 41 static bool Equals(const StoreRepresentation& rep1, 42 const StoreRepresentation& rep2) { 43 return rep1 == rep2; 44 } 45}; 46 47 48template <> 49struct StaticParameterTraits<LoadRepresentation> { 50 static OStream& PrintTo(OStream& os, LoadRepresentation type) { // NOLINT 51 return os << type; 52 } 53 static int HashCode(LoadRepresentation type) { return type; } 54 static bool Equals(LoadRepresentation lhs, LoadRepresentation rhs) { 55 return lhs == rhs; 56 } 57}; 58 59 60#define PURE_OP_LIST(V) \ 61 V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 62 V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 63 V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 64 V(Word32Shl, Operator::kNoProperties, 2, 1) \ 65 V(Word32Shr, Operator::kNoProperties, 2, 1) \ 66 V(Word32Sar, Operator::kNoProperties, 2, 1) \ 67 V(Word32Ror, Operator::kNoProperties, 2, 1) \ 68 V(Word32Equal, Operator::kCommutative, 2, 1) \ 69 V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 70 V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 71 V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 72 V(Word64Shl, Operator::kNoProperties, 2, 1) \ 73 V(Word64Shr, Operator::kNoProperties, 2, 1) \ 74 V(Word64Sar, Operator::kNoProperties, 2, 1) \ 75 V(Word64Ror, Operator::kNoProperties, 2, 1) \ 76 V(Word64Equal, Operator::kCommutative, 2, 1) \ 77 V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 78 V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative, 2, \ 79 2) \ 80 V(Int32Sub, Operator::kNoProperties, 2, 1) \ 81 V(Int32SubWithOverflow, Operator::kNoProperties, 2, 2) \ 82 V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 83 V(Int32Div, Operator::kNoProperties, 2, 1) \ 84 V(Int32UDiv, Operator::kNoProperties, 2, 1) \ 85 V(Int32Mod, Operator::kNoProperties, 2, 1) \ 86 V(Int32UMod, Operator::kNoProperties, 2, 1) \ 87 V(Int32LessThan, Operator::kNoProperties, 2, 1) \ 88 V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 1) \ 89 V(Uint32LessThan, Operator::kNoProperties, 2, 1) \ 90 V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 1) \ 91 V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 92 V(Int64Sub, Operator::kNoProperties, 2, 1) \ 93 V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 1) \ 94 V(Int64Div, Operator::kNoProperties, 2, 1) \ 95 V(Int64UDiv, Operator::kNoProperties, 2, 1) \ 96 V(Int64Mod, Operator::kNoProperties, 2, 1) \ 97 V(Int64UMod, Operator::kNoProperties, 2, 1) \ 98 V(Int64LessThan, Operator::kNoProperties, 2, 1) \ 99 V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 1) \ 100 V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 1) \ 101 V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 1) \ 102 V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 1) \ 103 V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 1) \ 104 V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 1) \ 105 V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 1) \ 106 V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 1) \ 107 V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 1) \ 108 V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 1) \ 109 V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 1) \ 110 V(Float64Add, Operator::kCommutative, 2, 1) \ 111 V(Float64Sub, Operator::kNoProperties, 2, 1) \ 112 V(Float64Mul, Operator::kCommutative, 2, 1) \ 113 V(Float64Div, Operator::kNoProperties, 2, 1) \ 114 V(Float64Mod, Operator::kNoProperties, 2, 1) \ 115 V(Float64Sqrt, Operator::kNoProperties, 1, 1) \ 116 V(Float64Equal, Operator::kCommutative, 2, 1) \ 117 V(Float64LessThan, Operator::kNoProperties, 2, 1) \ 118 V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 1) 119 120 121#define MACHINE_TYPE_LIST(V) \ 122 V(MachFloat32) \ 123 V(MachFloat64) \ 124 V(MachInt8) \ 125 V(MachUint8) \ 126 V(MachInt16) \ 127 V(MachUint16) \ 128 V(MachInt32) \ 129 V(MachUint32) \ 130 V(MachInt64) \ 131 V(MachUint64) \ 132 V(MachAnyTagged) \ 133 V(RepBit) \ 134 V(RepWord8) \ 135 V(RepWord16) \ 136 V(RepWord32) \ 137 V(RepWord64) \ 138 V(RepFloat32) \ 139 V(RepFloat64) \ 140 V(RepTagged) 141 142 143struct MachineOperatorBuilderImpl { 144#define PURE(Name, properties, input_count, output_count) \ 145 struct Name##Operator FINAL : public SimpleOperator { \ 146 Name##Operator() \ 147 : SimpleOperator(IrOpcode::k##Name, Operator::kPure | properties, \ 148 input_count, output_count, #Name) {} \ 149 }; \ 150 Name##Operator k##Name; 151 PURE_OP_LIST(PURE) 152#undef PURE 153 154#define LOAD(Type) \ 155 struct Load##Type##Operator FINAL : public Operator1<LoadRepresentation> { \ 156 Load##Type##Operator() \ 157 : Operator1<LoadRepresentation>( \ 158 IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, 2, 1, \ 159 "Load", k##Type) {} \ 160 }; \ 161 Load##Type##Operator k##Load##Type; 162 MACHINE_TYPE_LIST(LOAD) 163#undef LOAD 164 165#define STORE(Type) \ 166 struct Store##Type##Operator : public Operator1<StoreRepresentation> { \ 167 explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \ 168 : Operator1<StoreRepresentation>( \ 169 IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, 3, 0, \ 170 "Store", StoreRepresentation(k##Type, write_barrier_kind)) {} \ 171 }; \ 172 struct Store##Type##NoWriteBarrier##Operator FINAL \ 173 : public Store##Type##Operator { \ 174 Store##Type##NoWriteBarrier##Operator() \ 175 : Store##Type##Operator(kNoWriteBarrier) {} \ 176 }; \ 177 struct Store##Type##FullWriteBarrier##Operator FINAL \ 178 : public Store##Type##Operator { \ 179 Store##Type##FullWriteBarrier##Operator() \ 180 : Store##Type##Operator(kFullWriteBarrier) {} \ 181 }; \ 182 Store##Type##NoWriteBarrier##Operator k##Store##Type##NoWriteBarrier; \ 183 Store##Type##FullWriteBarrier##Operator k##Store##Type##FullWriteBarrier; 184 MACHINE_TYPE_LIST(STORE) 185#undef STORE 186}; 187 188 189static base::LazyInstance<MachineOperatorBuilderImpl>::type kImpl = 190 LAZY_INSTANCE_INITIALIZER; 191 192 193MachineOperatorBuilder::MachineOperatorBuilder(MachineType word) 194 : impl_(kImpl.Get()), word_(word) { 195 DCHECK(word == kRepWord32 || word == kRepWord64); 196} 197 198 199#define PURE(Name, properties, input_count, output_count) \ 200 const Operator* MachineOperatorBuilder::Name() { return &impl_.k##Name; } 201PURE_OP_LIST(PURE) 202#undef PURE 203 204 205const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) { 206 switch (rep) { 207#define LOAD(Type) \ 208 case k##Type: \ 209 return &impl_.k##Load##Type; 210 MACHINE_TYPE_LIST(LOAD) 211#undef LOAD 212 213 default: 214 break; 215 } 216 UNREACHABLE(); 217 return NULL; 218} 219 220 221const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) { 222 switch (rep.machine_type()) { 223#define STORE(Type) \ 224 case k##Type: \ 225 switch (rep.write_barrier_kind()) { \ 226 case kNoWriteBarrier: \ 227 return &impl_.k##Store##Type##NoWriteBarrier; \ 228 case kFullWriteBarrier: \ 229 return &impl_.k##Store##Type##FullWriteBarrier; \ 230 } \ 231 break; 232 MACHINE_TYPE_LIST(STORE) 233#undef STORE 234 235 default: 236 break; 237 } 238 UNREACHABLE(); 239 return NULL; 240} 241 242} // namespace compiler 243} // namespace internal 244} // namespace v8 245