OLD | NEW |
(Empty) | |
| 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_MACHINE_NODE_FACTORY_H_ |
| 6 #define V8_COMPILER_MACHINE_NODE_FACTORY_H_ |
| 7 |
| 8 #ifdef USE_SIMULATOR |
| 9 #define MACHINE_ASSEMBLER_SUPPORTS_CALL_C 0 |
| 10 #else |
| 11 #define MACHINE_ASSEMBLER_SUPPORTS_CALL_C 1 |
| 12 #endif |
| 13 |
| 14 #include "src/v8.h" |
| 15 |
| 16 #include "src/compiler/machine-operator.h" |
| 17 #include "src/compiler/node.h" |
| 18 |
| 19 namespace v8 { |
| 20 namespace internal { |
| 21 namespace compiler { |
| 22 |
| 23 class MachineCallDescriptorBuilder : public ZoneObject { |
| 24 public: |
| 25 MachineCallDescriptorBuilder(MachineRepresentation return_type, |
| 26 int parameter_count, |
| 27 const MachineRepresentation* parameter_types) |
| 28 : return_type_(return_type), |
| 29 parameter_count_(parameter_count), |
| 30 parameter_types_(parameter_types) {} |
| 31 |
| 32 int parameter_count() const { return parameter_count_; } |
| 33 const MachineRepresentation* parameter_types() const { |
| 34 return parameter_types_; |
| 35 } |
| 36 |
| 37 CallDescriptor* BuildCallDescriptor(Zone* zone) { |
| 38 return Linkage::GetSimplifiedCDescriptor(zone, parameter_count_, |
| 39 return_type_, parameter_types_); |
| 40 } |
| 41 |
| 42 private: |
| 43 const MachineRepresentation return_type_; |
| 44 const int parameter_count_; |
| 45 const MachineRepresentation* const parameter_types_; |
| 46 }; |
| 47 |
| 48 |
| 49 #define ZONE() static_cast<NodeFactory*>(this)->zone() |
| 50 #define COMMON() static_cast<NodeFactory*>(this)->common() |
| 51 #define MACHINE() static_cast<NodeFactory*>(this)->machine() |
| 52 #define NEW_NODE_0(op) static_cast<NodeFactory*>(this)->NewNode(op) |
| 53 #define NEW_NODE_1(op, a) static_cast<NodeFactory*>(this)->NewNode(op, a) |
| 54 #define NEW_NODE_2(op, a, b) static_cast<NodeFactory*>(this)->NewNode(op, a, b) |
| 55 #define NEW_NODE_3(op, a, b, c) \ |
| 56 static_cast<NodeFactory*>(this)->NewNode(op, a, b, c) |
| 57 |
| 58 template <typename NodeFactory> |
| 59 class MachineNodeFactory { |
| 60 public: |
| 61 // Constants. |
| 62 Node* PointerConstant(void* value) { |
| 63 return IntPtrConstant(reinterpret_cast<intptr_t>(value)); |
| 64 } |
| 65 Node* IntPtrConstant(intptr_t value) { |
| 66 // TODO(dcarney): mark generated code as unserializable if value != 0. |
| 67 return kPointerSize == 8 ? Int64Constant(value) : Int32Constant(value); |
| 68 } |
| 69 Node* Int32Constant(int32_t value) { |
| 70 return NEW_NODE_0(COMMON()->Int32Constant(value)); |
| 71 } |
| 72 Node* Int64Constant(int64_t value) { |
| 73 return NEW_NODE_0(COMMON()->Int64Constant(value)); |
| 74 } |
| 75 Node* NumberConstant(double value) { |
| 76 return NEW_NODE_0(COMMON()->NumberConstant(value)); |
| 77 } |
| 78 Node* Float64Constant(double value) { |
| 79 return NEW_NODE_0(COMMON()->Float64Constant(value)); |
| 80 } |
| 81 Node* HeapConstant(Handle<Object> object) { |
| 82 PrintableUnique<Object> val = |
| 83 PrintableUnique<Object>::CreateUninitialized(ZONE(), object); |
| 84 return NEW_NODE_0(COMMON()->HeapConstant(val)); |
| 85 } |
| 86 |
| 87 // Memory Operations. |
| 88 Node* Load(MachineRepresentation rep, Node* base) { |
| 89 return Load(rep, base, Int32Constant(0)); |
| 90 } |
| 91 Node* Load(MachineRepresentation rep, Node* base, Node* index) { |
| 92 return NEW_NODE_2(MACHINE()->Load(rep), base, index); |
| 93 } |
| 94 void Store(MachineRepresentation rep, Node* base, Node* value) { |
| 95 Store(rep, base, Int32Constant(0), value); |
| 96 } |
| 97 void Store(MachineRepresentation rep, Node* base, Node* index, Node* value) { |
| 98 NEW_NODE_3(MACHINE()->Store(rep), base, index, value); |
| 99 } |
| 100 // Arithmetic Operations. |
| 101 Node* WordAnd(Node* a, Node* b) { |
| 102 return NEW_NODE_2(MACHINE()->WordAnd(), a, b); |
| 103 } |
| 104 Node* WordOr(Node* a, Node* b) { |
| 105 return NEW_NODE_2(MACHINE()->WordOr(), a, b); |
| 106 } |
| 107 Node* WordXor(Node* a, Node* b) { |
| 108 return NEW_NODE_2(MACHINE()->WordXor(), a, b); |
| 109 } |
| 110 Node* WordShl(Node* a, Node* b) { |
| 111 return NEW_NODE_2(MACHINE()->WordShl(), a, b); |
| 112 } |
| 113 Node* WordShr(Node* a, Node* b) { |
| 114 return NEW_NODE_2(MACHINE()->WordShr(), a, b); |
| 115 } |
| 116 Node* WordSar(Node* a, Node* b) { |
| 117 return NEW_NODE_2(MACHINE()->WordSar(), a, b); |
| 118 } |
| 119 Node* WordEqual(Node* a, Node* b) { |
| 120 return NEW_NODE_2(MACHINE()->WordEqual(), a, b); |
| 121 } |
| 122 Node* WordNotEqual(Node* a, Node* b) { |
| 123 return WordBinaryNot(WordEqual(a, b)); |
| 124 } |
| 125 Node* WordNot(Node* a) { |
| 126 if (MACHINE()->is32()) { |
| 127 return Word32Not(a); |
| 128 } else { |
| 129 return Word64Not(a); |
| 130 } |
| 131 } |
| 132 Node* WordBinaryNot(Node* a) { |
| 133 if (MACHINE()->is32()) { |
| 134 return Word32BinaryNot(a); |
| 135 } else { |
| 136 return Word64BinaryNot(a); |
| 137 } |
| 138 } |
| 139 |
| 140 Node* Word32And(Node* a, Node* b) { |
| 141 return NEW_NODE_2(MACHINE()->Word32And(), a, b); |
| 142 } |
| 143 Node* Word32Or(Node* a, Node* b) { |
| 144 return NEW_NODE_2(MACHINE()->Word32Or(), a, b); |
| 145 } |
| 146 Node* Word32Xor(Node* a, Node* b) { |
| 147 return NEW_NODE_2(MACHINE()->Word32Xor(), a, b); |
| 148 } |
| 149 Node* Word32Shl(Node* a, Node* b) { |
| 150 return NEW_NODE_2(MACHINE()->Word32Shl(), a, b); |
| 151 } |
| 152 Node* Word32Shr(Node* a, Node* b) { |
| 153 return NEW_NODE_2(MACHINE()->Word32Shr(), a, b); |
| 154 } |
| 155 Node* Word32Sar(Node* a, Node* b) { |
| 156 return NEW_NODE_2(MACHINE()->Word32Sar(), a, b); |
| 157 } |
| 158 Node* Word32Equal(Node* a, Node* b) { |
| 159 return NEW_NODE_2(MACHINE()->Word32Equal(), a, b); |
| 160 } |
| 161 Node* Word32NotEqual(Node* a, Node* b) { |
| 162 return Word32BinaryNot(Word32Equal(a, b)); |
| 163 } |
| 164 Node* Word32Not(Node* a) { return Word32Xor(a, Int32Constant(-1)); } |
| 165 Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); } |
| 166 |
| 167 Node* Word64And(Node* a, Node* b) { |
| 168 return NEW_NODE_2(MACHINE()->Word64And(), a, b); |
| 169 } |
| 170 Node* Word64Or(Node* a, Node* b) { |
| 171 return NEW_NODE_2(MACHINE()->Word64Or(), a, b); |
| 172 } |
| 173 Node* Word64Xor(Node* a, Node* b) { |
| 174 return NEW_NODE_2(MACHINE()->Word64Xor(), a, b); |
| 175 } |
| 176 Node* Word64Shl(Node* a, Node* b) { |
| 177 return NEW_NODE_2(MACHINE()->Word64Shl(), a, b); |
| 178 } |
| 179 Node* Word64Shr(Node* a, Node* b) { |
| 180 return NEW_NODE_2(MACHINE()->Word64Shr(), a, b); |
| 181 } |
| 182 Node* Word64Sar(Node* a, Node* b) { |
| 183 return NEW_NODE_2(MACHINE()->Word64Sar(), a, b); |
| 184 } |
| 185 Node* Word64Equal(Node* a, Node* b) { |
| 186 return NEW_NODE_2(MACHINE()->Word64Equal(), a, b); |
| 187 } |
| 188 Node* Word64NotEqual(Node* a, Node* b) { |
| 189 return Word64BinaryNot(Word64Equal(a, b)); |
| 190 } |
| 191 Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); } |
| 192 Node* Word64BinaryNot(Node* a) { return Word64Equal(a, Int64Constant(0)); } |
| 193 |
| 194 Node* Int32Add(Node* a, Node* b) { |
| 195 return NEW_NODE_2(MACHINE()->Int32Add(), a, b); |
| 196 } |
| 197 Node* Int32Sub(Node* a, Node* b) { |
| 198 return NEW_NODE_2(MACHINE()->Int32Sub(), a, b); |
| 199 } |
| 200 Node* Int32Mul(Node* a, Node* b) { |
| 201 return NEW_NODE_2(MACHINE()->Int32Mul(), a, b); |
| 202 } |
| 203 Node* Int32Div(Node* a, Node* b) { |
| 204 return NEW_NODE_2(MACHINE()->Int32Div(), a, b); |
| 205 } |
| 206 Node* Int32UDiv(Node* a, Node* b) { |
| 207 return NEW_NODE_2(MACHINE()->Int32UDiv(), a, b); |
| 208 } |
| 209 Node* Int32Mod(Node* a, Node* b) { |
| 210 return NEW_NODE_2(MACHINE()->Int32Mod(), a, b); |
| 211 } |
| 212 Node* Int32UMod(Node* a, Node* b) { |
| 213 return NEW_NODE_2(MACHINE()->Int32UMod(), a, b); |
| 214 } |
| 215 Node* Int32LessThan(Node* a, Node* b) { |
| 216 return NEW_NODE_2(MACHINE()->Int32LessThan(), a, b); |
| 217 } |
| 218 Node* Int32LessThanOrEqual(Node* a, Node* b) { |
| 219 return NEW_NODE_2(MACHINE()->Int32LessThanOrEqual(), a, b); |
| 220 } |
| 221 Node* Uint32LessThan(Node* a, Node* b) { |
| 222 return NEW_NODE_2(MACHINE()->Uint32LessThan(), a, b); |
| 223 } |
| 224 Node* Uint32LessThanOrEqual(Node* a, Node* b) { |
| 225 return NEW_NODE_2(MACHINE()->Uint32LessThanOrEqual(), a, b); |
| 226 } |
| 227 Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); } |
| 228 Node* Int32GreaterThanOrEqual(Node* a, Node* b) { |
| 229 return Int32LessThanOrEqual(b, a); |
| 230 } |
| 231 Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); } |
| 232 |
| 233 Node* Int64Add(Node* a, Node* b) { |
| 234 return NEW_NODE_2(MACHINE()->Int64Add(), a, b); |
| 235 } |
| 236 Node* Int64Sub(Node* a, Node* b) { |
| 237 return NEW_NODE_2(MACHINE()->Int64Sub(), a, b); |
| 238 } |
| 239 Node* Int64Mul(Node* a, Node* b) { |
| 240 return NEW_NODE_2(MACHINE()->Int64Mul(), a, b); |
| 241 } |
| 242 Node* Int64Div(Node* a, Node* b) { |
| 243 return NEW_NODE_2(MACHINE()->Int64Div(), a, b); |
| 244 } |
| 245 Node* Int64UDiv(Node* a, Node* b) { |
| 246 return NEW_NODE_2(MACHINE()->Int64UDiv(), a, b); |
| 247 } |
| 248 Node* Int64Mod(Node* a, Node* b) { |
| 249 return NEW_NODE_2(MACHINE()->Int64Mod(), a, b); |
| 250 } |
| 251 Node* Int64UMod(Node* a, Node* b) { |
| 252 return NEW_NODE_2(MACHINE()->Int64UMod(), a, b); |
| 253 } |
| 254 Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); } |
| 255 Node* Int64LessThan(Node* a, Node* b) { |
| 256 return NEW_NODE_2(MACHINE()->Int64LessThan(), a, b); |
| 257 } |
| 258 Node* Int64LessThanOrEqual(Node* a, Node* b) { |
| 259 return NEW_NODE_2(MACHINE()->Int64LessThanOrEqual(), a, b); |
| 260 } |
| 261 Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); } |
| 262 Node* Int64GreaterThanOrEqual(Node* a, Node* b) { |
| 263 return Int64LessThanOrEqual(b, a); |
| 264 } |
| 265 |
| 266 Node* ConvertIntPtrToInt32(Node* a) { |
| 267 return kPointerSize == 8 ? NEW_NODE_1(MACHINE()->ConvertInt64ToInt32(), a) |
| 268 : a; |
| 269 } |
| 270 Node* ConvertInt32ToIntPtr(Node* a) { |
| 271 return kPointerSize == 8 ? NEW_NODE_1(MACHINE()->ConvertInt32ToInt64(), a) |
| 272 : a; |
| 273 } |
| 274 |
| 275 #define INTPTR_BINOP(prefix, name) \ |
| 276 Node* IntPtr##name(Node* a, Node* b) { \ |
| 277 return kPointerSize == 8 ? prefix##64##name(a, b) \ |
| 278 : prefix##32##name(a, b); \ |
| 279 } |
| 280 |
| 281 INTPTR_BINOP(Int, Add); |
| 282 INTPTR_BINOP(Int, Sub); |
| 283 INTPTR_BINOP(Int, LessThan); |
| 284 INTPTR_BINOP(Int, LessThanOrEqual); |
| 285 INTPTR_BINOP(Word, Equal); |
| 286 INTPTR_BINOP(Word, NotEqual); |
| 287 INTPTR_BINOP(Int, GreaterThanOrEqual); |
| 288 INTPTR_BINOP(Int, GreaterThan); |
| 289 |
| 290 #undef INTPTR_BINOP |
| 291 |
| 292 Node* Float64Add(Node* a, Node* b) { |
| 293 return NEW_NODE_2(MACHINE()->Float64Add(), a, b); |
| 294 } |
| 295 Node* Float64Sub(Node* a, Node* b) { |
| 296 return NEW_NODE_2(MACHINE()->Float64Sub(), a, b); |
| 297 } |
| 298 Node* Float64Mul(Node* a, Node* b) { |
| 299 return NEW_NODE_2(MACHINE()->Float64Mul(), a, b); |
| 300 } |
| 301 Node* Float64Div(Node* a, Node* b) { |
| 302 return NEW_NODE_2(MACHINE()->Float64Div(), a, b); |
| 303 } |
| 304 Node* Float64Mod(Node* a, Node* b) { |
| 305 return NEW_NODE_2(MACHINE()->Float64Mod(), a, b); |
| 306 } |
| 307 Node* Float64Equal(Node* a, Node* b) { |
| 308 return NEW_NODE_2(MACHINE()->Float64Equal(), a, b); |
| 309 } |
| 310 Node* Float64NotEqual(Node* a, Node* b) { |
| 311 return WordBinaryNot(Float64Equal(a, b)); |
| 312 } |
| 313 Node* Float64LessThan(Node* a, Node* b) { |
| 314 return NEW_NODE_2(MACHINE()->Float64LessThan(), a, b); |
| 315 } |
| 316 Node* Float64LessThanOrEqual(Node* a, Node* b) { |
| 317 return NEW_NODE_2(MACHINE()->Float64LessThanOrEqual(), a, b); |
| 318 } |
| 319 Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); } |
| 320 Node* Float64GreaterThanOrEqual(Node* a, Node* b) { |
| 321 return Float64LessThanOrEqual(b, a); |
| 322 } |
| 323 |
| 324 // Conversions. |
| 325 Node* ConvertInt32ToInt64(Node* a) { |
| 326 return NEW_NODE_1(MACHINE()->ConvertInt32ToInt64(), a); |
| 327 } |
| 328 Node* ConvertInt64ToInt32(Node* a) { |
| 329 return NEW_NODE_1(MACHINE()->ConvertInt64ToInt32(), a); |
| 330 } |
| 331 Node* ConvertInt32ToFloat64(Node* a) { |
| 332 return NEW_NODE_1(MACHINE()->ConvertInt32ToFloat64(), a); |
| 333 } |
| 334 Node* ConvertFloat64ToInt32(Node* a) { |
| 335 return NEW_NODE_1(MACHINE()->ConvertFloat64ToInt32(), a); |
| 336 } |
| 337 |
| 338 #ifdef MACHINE_ASSEMBLER_SUPPORTS_CALL_C |
| 339 // Call to C. |
| 340 Node* CallC(Node* function_address, MachineRepresentation return_type, |
| 341 MachineRepresentation* arg_types, Node** args, int n_args) { |
| 342 CallDescriptor* descriptor = Linkage::GetSimplifiedCDescriptor( |
| 343 ZONE(), n_args, return_type, arg_types); |
| 344 Node** passed_args = |
| 345 static_cast<Node**>(alloca((n_args + 1) * sizeof(args[0]))); |
| 346 passed_args[0] = function_address; |
| 347 for (int i = 0; i < n_args; ++i) { |
| 348 passed_args[i + 1] = args[i]; |
| 349 } |
| 350 return NEW_NODE_2(COMMON()->Call(descriptor), n_args + 1, passed_args); |
| 351 } |
| 352 #endif |
| 353 }; |
| 354 |
| 355 #undef NEW_NODE_0 |
| 356 #undef NEW_NODE_1 |
| 357 #undef NEW_NODE_2 |
| 358 #undef NEW_NODE_3 |
| 359 #undef MACHINE |
| 360 #undef COMMON |
| 361 #undef ZONE |
| 362 |
| 363 } // namespace compiler |
| 364 } // namespace internal |
| 365 } // namespace v8 |
| 366 |
| 367 #endif // V8_COMPILER_MACHINE_NODE_FACTORY_H_ |
OLD | NEW |