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_RAW_MACHINE_ASSEMBLER_H_ 6 #define V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_ 7 8 #include "src/assembler.h" 9 #include "src/compiler/common-operator.h" 10 #include "src/compiler/graph.h" 11 #include "src/compiler/linkage.h" 12 #include "src/compiler/machine-operator.h" 13 #include "src/compiler/node.h" 14 #include "src/compiler/operator.h" 15 #include "src/factory.h" 16 17 namespace v8 { 18 namespace internal { 19 namespace compiler { 20 21 class BasicBlock; 22 class RawMachineLabel; 23 class Schedule; 24 25 26 // The RawMachineAssembler produces a low-level IR graph. All nodes are wired 27 // into a graph and also placed into a schedule immediately, hence subsequent 28 // code generation can happen without the need for scheduling. 29 // 30 // In order to create a schedule on-the-fly, the assembler keeps track of basic 31 // blocks by having one current basic block being populated and by referencing 32 // other basic blocks through the use of labels. 33 // 34 // Also note that the generated graph is only valid together with the generated 35 // schedule, using one without the other is invalid as the graph is inherently 36 // non-schedulable due to missing control and effect dependencies. 37 class RawMachineAssembler { 38 public: 39 RawMachineAssembler( 40 Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor, 41 MachineRepresentation word = MachineType::PointerRepresentation(), 42 MachineOperatorBuilder::Flags flags = 43 MachineOperatorBuilder::Flag::kNoFlags); ~RawMachineAssembler()44 ~RawMachineAssembler() {} 45 isolate()46 Isolate* isolate() const { return isolate_; } graph()47 Graph* graph() const { return graph_; } zone()48 Zone* zone() const { return graph()->zone(); } machine()49 MachineOperatorBuilder* machine() { return &machine_; } common()50 CommonOperatorBuilder* common() { return &common_; } call_descriptor()51 CallDescriptor* call_descriptor() const { return call_descriptor_; } 52 53 // Finalizes the schedule and exports it to be used for code generation. Note 54 // that this RawMachineAssembler becomes invalid after export. 55 Schedule* Export(); 56 57 // =========================================================================== 58 // The following utility methods create new nodes with specific operators and 59 // place them into the current basic block. They don't perform control flow, 60 // hence will not switch the current basic block. 61 NullConstant()62 Node* NullConstant() { 63 return HeapConstant(isolate()->factory()->null_value()); 64 } 65 UndefinedConstant()66 Node* UndefinedConstant() { 67 return HeapConstant(isolate()->factory()->undefined_value()); 68 } 69 70 // Constants. PointerConstant(void * value)71 Node* PointerConstant(void* value) { 72 return IntPtrConstant(reinterpret_cast<intptr_t>(value)); 73 } IntPtrConstant(intptr_t value)74 Node* IntPtrConstant(intptr_t value) { 75 // TODO(dcarney): mark generated code as unserializable if value != 0. 76 return kPointerSize == 8 ? Int64Constant(value) 77 : Int32Constant(static_cast<int>(value)); 78 } 79 Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode); Int32Constant(int32_t value)80 Node* Int32Constant(int32_t value) { 81 return AddNode(common()->Int32Constant(value)); 82 } StackSlot(MachineRepresentation rep)83 Node* StackSlot(MachineRepresentation rep) { 84 return AddNode(machine()->StackSlot(rep)); 85 } Int64Constant(int64_t value)86 Node* Int64Constant(int64_t value) { 87 return AddNode(common()->Int64Constant(value)); 88 } NumberConstant(double value)89 Node* NumberConstant(double value) { 90 return AddNode(common()->NumberConstant(value)); 91 } Float32Constant(float value)92 Node* Float32Constant(float value) { 93 return AddNode(common()->Float32Constant(value)); 94 } Float64Constant(double value)95 Node* Float64Constant(double value) { 96 return AddNode(common()->Float64Constant(value)); 97 } HeapConstant(Handle<HeapObject> object)98 Node* HeapConstant(Handle<HeapObject> object) { 99 return AddNode(common()->HeapConstant(object)); 100 } BooleanConstant(bool value)101 Node* BooleanConstant(bool value) { 102 Handle<Object> object = isolate()->factory()->ToBoolean(value); 103 return HeapConstant(Handle<HeapObject>::cast(object)); 104 } ExternalConstant(ExternalReference address)105 Node* ExternalConstant(ExternalReference address) { 106 return AddNode(common()->ExternalConstant(address)); 107 } RelocatableInt32Constant(int32_t value,RelocInfo::Mode rmode)108 Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) { 109 return AddNode(common()->RelocatableInt32Constant(value, rmode)); 110 } RelocatableInt64Constant(int64_t value,RelocInfo::Mode rmode)111 Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) { 112 return AddNode(common()->RelocatableInt64Constant(value, rmode)); 113 } 114 Projection(int index,Node * a)115 Node* Projection(int index, Node* a) { 116 return AddNode(common()->Projection(index), a); 117 } 118 119 // Memory Operations. Load(MachineType rep,Node * base)120 Node* Load(MachineType rep, Node* base) { 121 return Load(rep, base, IntPtrConstant(0)); 122 } Load(MachineType rep,Node * base,Node * index)123 Node* Load(MachineType rep, Node* base, Node* index) { 124 return AddNode(machine()->Load(rep), base, index); 125 } Store(MachineRepresentation rep,Node * base,Node * value,WriteBarrierKind write_barrier)126 Node* Store(MachineRepresentation rep, Node* base, Node* value, 127 WriteBarrierKind write_barrier) { 128 return Store(rep, base, IntPtrConstant(0), value, write_barrier); 129 } Store(MachineRepresentation rep,Node * base,Node * index,Node * value,WriteBarrierKind write_barrier)130 Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value, 131 WriteBarrierKind write_barrier) { 132 return AddNode(machine()->Store(StoreRepresentation(rep, write_barrier)), 133 base, index, value); 134 } 135 136 // Atomic memory operations. AtomicLoad(MachineType rep,Node * base,Node * index)137 Node* AtomicLoad(MachineType rep, Node* base, Node* index) { 138 return AddNode(machine()->AtomicLoad(rep), base, index); 139 } AtomicStore(MachineRepresentation rep,Node * base,Node * index,Node * value)140 Node* AtomicStore(MachineRepresentation rep, Node* base, Node* index, 141 Node* value) { 142 return AddNode(machine()->AtomicStore(rep), base, index, value); 143 } 144 145 // Arithmetic Operations. WordAnd(Node * a,Node * b)146 Node* WordAnd(Node* a, Node* b) { 147 return AddNode(machine()->WordAnd(), a, b); 148 } WordOr(Node * a,Node * b)149 Node* WordOr(Node* a, Node* b) { return AddNode(machine()->WordOr(), a, b); } WordXor(Node * a,Node * b)150 Node* WordXor(Node* a, Node* b) { 151 return AddNode(machine()->WordXor(), a, b); 152 } WordShl(Node * a,Node * b)153 Node* WordShl(Node* a, Node* b) { 154 return AddNode(machine()->WordShl(), a, b); 155 } WordShr(Node * a,Node * b)156 Node* WordShr(Node* a, Node* b) { 157 return AddNode(machine()->WordShr(), a, b); 158 } WordSar(Node * a,Node * b)159 Node* WordSar(Node* a, Node* b) { 160 return AddNode(machine()->WordSar(), a, b); 161 } WordRor(Node * a,Node * b)162 Node* WordRor(Node* a, Node* b) { 163 return AddNode(machine()->WordRor(), a, b); 164 } WordEqual(Node * a,Node * b)165 Node* WordEqual(Node* a, Node* b) { 166 return AddNode(machine()->WordEqual(), a, b); 167 } WordNotEqual(Node * a,Node * b)168 Node* WordNotEqual(Node* a, Node* b) { 169 return Word32BinaryNot(WordEqual(a, b)); 170 } WordNot(Node * a)171 Node* WordNot(Node* a) { 172 if (machine()->Is32()) { 173 return Word32Not(a); 174 } else { 175 return Word64Not(a); 176 } 177 } 178 Word32And(Node * a,Node * b)179 Node* Word32And(Node* a, Node* b) { 180 return AddNode(machine()->Word32And(), a, b); 181 } Word32Or(Node * a,Node * b)182 Node* Word32Or(Node* a, Node* b) { 183 return AddNode(machine()->Word32Or(), a, b); 184 } Word32Xor(Node * a,Node * b)185 Node* Word32Xor(Node* a, Node* b) { 186 return AddNode(machine()->Word32Xor(), a, b); 187 } Word32Shl(Node * a,Node * b)188 Node* Word32Shl(Node* a, Node* b) { 189 return AddNode(machine()->Word32Shl(), a, b); 190 } Word32Shr(Node * a,Node * b)191 Node* Word32Shr(Node* a, Node* b) { 192 return AddNode(machine()->Word32Shr(), a, b); 193 } Word32Sar(Node * a,Node * b)194 Node* Word32Sar(Node* a, Node* b) { 195 return AddNode(machine()->Word32Sar(), a, b); 196 } Word32Ror(Node * a,Node * b)197 Node* Word32Ror(Node* a, Node* b) { 198 return AddNode(machine()->Word32Ror(), a, b); 199 } Word32Clz(Node * a)200 Node* Word32Clz(Node* a) { return AddNode(machine()->Word32Clz(), a); } Word32Equal(Node * a,Node * b)201 Node* Word32Equal(Node* a, Node* b) { 202 return AddNode(machine()->Word32Equal(), a, b); 203 } Word32NotEqual(Node * a,Node * b)204 Node* Word32NotEqual(Node* a, Node* b) { 205 return Word32BinaryNot(Word32Equal(a, b)); 206 } Word32Not(Node * a)207 Node* Word32Not(Node* a) { return Word32Xor(a, Int32Constant(-1)); } Word32BinaryNot(Node * a)208 Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); } 209 Word64And(Node * a,Node * b)210 Node* Word64And(Node* a, Node* b) { 211 return AddNode(machine()->Word64And(), a, b); 212 } Word64Or(Node * a,Node * b)213 Node* Word64Or(Node* a, Node* b) { 214 return AddNode(machine()->Word64Or(), a, b); 215 } Word64Xor(Node * a,Node * b)216 Node* Word64Xor(Node* a, Node* b) { 217 return AddNode(machine()->Word64Xor(), a, b); 218 } Word64Shl(Node * a,Node * b)219 Node* Word64Shl(Node* a, Node* b) { 220 return AddNode(machine()->Word64Shl(), a, b); 221 } Word64Shr(Node * a,Node * b)222 Node* Word64Shr(Node* a, Node* b) { 223 return AddNode(machine()->Word64Shr(), a, b); 224 } Word64Sar(Node * a,Node * b)225 Node* Word64Sar(Node* a, Node* b) { 226 return AddNode(machine()->Word64Sar(), a, b); 227 } Word64Ror(Node * a,Node * b)228 Node* Word64Ror(Node* a, Node* b) { 229 return AddNode(machine()->Word64Ror(), a, b); 230 } Word64Clz(Node * a)231 Node* Word64Clz(Node* a) { return AddNode(machine()->Word64Clz(), a); } Word64Equal(Node * a,Node * b)232 Node* Word64Equal(Node* a, Node* b) { 233 return AddNode(machine()->Word64Equal(), a, b); 234 } Word64NotEqual(Node * a,Node * b)235 Node* Word64NotEqual(Node* a, Node* b) { 236 return Word32BinaryNot(Word64Equal(a, b)); 237 } Word64Not(Node * a)238 Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); } 239 Int32Add(Node * a,Node * b)240 Node* Int32Add(Node* a, Node* b) { 241 return AddNode(machine()->Int32Add(), a, b); 242 } Int32AddWithOverflow(Node * a,Node * b)243 Node* Int32AddWithOverflow(Node* a, Node* b) { 244 return AddNode(machine()->Int32AddWithOverflow(), a, b); 245 } Int32Sub(Node * a,Node * b)246 Node* Int32Sub(Node* a, Node* b) { 247 return AddNode(machine()->Int32Sub(), a, b); 248 } Int32SubWithOverflow(Node * a,Node * b)249 Node* Int32SubWithOverflow(Node* a, Node* b) { 250 return AddNode(machine()->Int32SubWithOverflow(), a, b); 251 } Int32Mul(Node * a,Node * b)252 Node* Int32Mul(Node* a, Node* b) { 253 return AddNode(machine()->Int32Mul(), a, b); 254 } Int32MulHigh(Node * a,Node * b)255 Node* Int32MulHigh(Node* a, Node* b) { 256 return AddNode(machine()->Int32MulHigh(), a, b); 257 } Int32Div(Node * a,Node * b)258 Node* Int32Div(Node* a, Node* b) { 259 return AddNode(machine()->Int32Div(), a, b); 260 } Int32Mod(Node * a,Node * b)261 Node* Int32Mod(Node* a, Node* b) { 262 return AddNode(machine()->Int32Mod(), a, b); 263 } Int32LessThan(Node * a,Node * b)264 Node* Int32LessThan(Node* a, Node* b) { 265 return AddNode(machine()->Int32LessThan(), a, b); 266 } Int32LessThanOrEqual(Node * a,Node * b)267 Node* Int32LessThanOrEqual(Node* a, Node* b) { 268 return AddNode(machine()->Int32LessThanOrEqual(), a, b); 269 } Uint32Div(Node * a,Node * b)270 Node* Uint32Div(Node* a, Node* b) { 271 return AddNode(machine()->Uint32Div(), a, b); 272 } Uint32LessThan(Node * a,Node * b)273 Node* Uint32LessThan(Node* a, Node* b) { 274 return AddNode(machine()->Uint32LessThan(), a, b); 275 } Uint32LessThanOrEqual(Node * a,Node * b)276 Node* Uint32LessThanOrEqual(Node* a, Node* b) { 277 return AddNode(machine()->Uint32LessThanOrEqual(), a, b); 278 } Uint32Mod(Node * a,Node * b)279 Node* Uint32Mod(Node* a, Node* b) { 280 return AddNode(machine()->Uint32Mod(), a, b); 281 } Uint32MulHigh(Node * a,Node * b)282 Node* Uint32MulHigh(Node* a, Node* b) { 283 return AddNode(machine()->Uint32MulHigh(), a, b); 284 } Int32GreaterThan(Node * a,Node * b)285 Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); } Int32GreaterThanOrEqual(Node * a,Node * b)286 Node* Int32GreaterThanOrEqual(Node* a, Node* b) { 287 return Int32LessThanOrEqual(b, a); 288 } Uint32GreaterThan(Node * a,Node * b)289 Node* Uint32GreaterThan(Node* a, Node* b) { return Uint32LessThan(b, a); } Uint32GreaterThanOrEqual(Node * a,Node * b)290 Node* Uint32GreaterThanOrEqual(Node* a, Node* b) { 291 return Uint32LessThanOrEqual(b, a); 292 } Int32Neg(Node * a)293 Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); } 294 Int64Add(Node * a,Node * b)295 Node* Int64Add(Node* a, Node* b) { 296 return AddNode(machine()->Int64Add(), a, b); 297 } Int64AddWithOverflow(Node * a,Node * b)298 Node* Int64AddWithOverflow(Node* a, Node* b) { 299 return AddNode(machine()->Int64AddWithOverflow(), a, b); 300 } Int64Sub(Node * a,Node * b)301 Node* Int64Sub(Node* a, Node* b) { 302 return AddNode(machine()->Int64Sub(), a, b); 303 } Int64SubWithOverflow(Node * a,Node * b)304 Node* Int64SubWithOverflow(Node* a, Node* b) { 305 return AddNode(machine()->Int64SubWithOverflow(), a, b); 306 } Int64Mul(Node * a,Node * b)307 Node* Int64Mul(Node* a, Node* b) { 308 return AddNode(machine()->Int64Mul(), a, b); 309 } Int64Div(Node * a,Node * b)310 Node* Int64Div(Node* a, Node* b) { 311 return AddNode(machine()->Int64Div(), a, b); 312 } Int64Mod(Node * a,Node * b)313 Node* Int64Mod(Node* a, Node* b) { 314 return AddNode(machine()->Int64Mod(), a, b); 315 } Int64Neg(Node * a)316 Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); } Int64LessThan(Node * a,Node * b)317 Node* Int64LessThan(Node* a, Node* b) { 318 return AddNode(machine()->Int64LessThan(), a, b); 319 } Int64LessThanOrEqual(Node * a,Node * b)320 Node* Int64LessThanOrEqual(Node* a, Node* b) { 321 return AddNode(machine()->Int64LessThanOrEqual(), a, b); 322 } Uint64LessThan(Node * a,Node * b)323 Node* Uint64LessThan(Node* a, Node* b) { 324 return AddNode(machine()->Uint64LessThan(), a, b); 325 } Uint64LessThanOrEqual(Node * a,Node * b)326 Node* Uint64LessThanOrEqual(Node* a, Node* b) { 327 return AddNode(machine()->Uint64LessThanOrEqual(), a, b); 328 } Int64GreaterThan(Node * a,Node * b)329 Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); } Int64GreaterThanOrEqual(Node * a,Node * b)330 Node* Int64GreaterThanOrEqual(Node* a, Node* b) { 331 return Int64LessThanOrEqual(b, a); 332 } Uint64GreaterThan(Node * a,Node * b)333 Node* Uint64GreaterThan(Node* a, Node* b) { return Uint64LessThan(b, a); } Uint64GreaterThanOrEqual(Node * a,Node * b)334 Node* Uint64GreaterThanOrEqual(Node* a, Node* b) { 335 return Uint64LessThanOrEqual(b, a); 336 } Uint64Div(Node * a,Node * b)337 Node* Uint64Div(Node* a, Node* b) { 338 return AddNode(machine()->Uint64Div(), a, b); 339 } Uint64Mod(Node * a,Node * b)340 Node* Uint64Mod(Node* a, Node* b) { 341 return AddNode(machine()->Uint64Mod(), a, b); 342 } Int32PairAdd(Node * a_low,Node * a_high,Node * b_low,Node * b_high)343 Node* Int32PairAdd(Node* a_low, Node* a_high, Node* b_low, Node* b_high) { 344 return AddNode(machine()->Int32PairAdd(), a_low, a_high, b_low, b_high); 345 } Int32PairSub(Node * a_low,Node * a_high,Node * b_low,Node * b_high)346 Node* Int32PairSub(Node* a_low, Node* a_high, Node* b_low, Node* b_high) { 347 return AddNode(machine()->Int32PairSub(), a_low, a_high, b_low, b_high); 348 } Int32PairMul(Node * a_low,Node * a_high,Node * b_low,Node * b_high)349 Node* Int32PairMul(Node* a_low, Node* a_high, Node* b_low, Node* b_high) { 350 return AddNode(machine()->Int32PairMul(), a_low, a_high, b_low, b_high); 351 } Word32PairShl(Node * low_word,Node * high_word,Node * shift)352 Node* Word32PairShl(Node* low_word, Node* high_word, Node* shift) { 353 return AddNode(machine()->Word32PairShl(), low_word, high_word, shift); 354 } Word32PairShr(Node * low_word,Node * high_word,Node * shift)355 Node* Word32PairShr(Node* low_word, Node* high_word, Node* shift) { 356 return AddNode(machine()->Word32PairShr(), low_word, high_word, shift); 357 } Word32PairSar(Node * low_word,Node * high_word,Node * shift)358 Node* Word32PairSar(Node* low_word, Node* high_word, Node* shift) { 359 return AddNode(machine()->Word32PairSar(), low_word, high_word, shift); 360 } 361 362 #define INTPTR_BINOP(prefix, name) \ 363 Node* IntPtr##name(Node* a, Node* b) { \ 364 return kPointerSize == 8 ? prefix##64##name(a, b) \ 365 : prefix##32##name(a, b); \ 366 } 367 368 INTPTR_BINOP(Int, Add); 369 INTPTR_BINOP(Int, AddWithOverflow); 370 INTPTR_BINOP(Int, Sub); 371 INTPTR_BINOP(Int, SubWithOverflow); 372 INTPTR_BINOP(Int, Mul); 373 INTPTR_BINOP(Int, Div); 374 INTPTR_BINOP(Int, LessThan); 375 INTPTR_BINOP(Int, LessThanOrEqual); 376 INTPTR_BINOP(Word, Equal); 377 INTPTR_BINOP(Word, NotEqual); 378 INTPTR_BINOP(Int, GreaterThanOrEqual); 379 INTPTR_BINOP(Int, GreaterThan); 380 381 #undef INTPTR_BINOP 382 383 #define UINTPTR_BINOP(prefix, name) \ 384 Node* UintPtr##name(Node* a, Node* b) { \ 385 return kPointerSize == 8 ? prefix##64##name(a, b) \ 386 : prefix##32##name(a, b); \ 387 } 388 389 UINTPTR_BINOP(Uint, LessThan); 390 UINTPTR_BINOP(Uint, LessThanOrEqual); 391 UINTPTR_BINOP(Uint, GreaterThanOrEqual); 392 UINTPTR_BINOP(Uint, GreaterThan); 393 394 #undef UINTPTR_BINOP 395 Float32Add(Node * a,Node * b)396 Node* Float32Add(Node* a, Node* b) { 397 return AddNode(machine()->Float32Add(), a, b); 398 } Float32Sub(Node * a,Node * b)399 Node* Float32Sub(Node* a, Node* b) { 400 return AddNode(machine()->Float32Sub(), a, b); 401 } Float32SubPreserveNan(Node * a,Node * b)402 Node* Float32SubPreserveNan(Node* a, Node* b) { 403 return AddNode(machine()->Float32SubPreserveNan(), a, b); 404 } Float32Mul(Node * a,Node * b)405 Node* Float32Mul(Node* a, Node* b) { 406 return AddNode(machine()->Float32Mul(), a, b); 407 } Float32Div(Node * a,Node * b)408 Node* Float32Div(Node* a, Node* b) { 409 return AddNode(machine()->Float32Div(), a, b); 410 } Float32Max(Node * a,Node * b)411 Node* Float32Max(Node* a, Node* b) { 412 return AddNode(machine()->Float32Max().op(), a, b); 413 } Float32Min(Node * a,Node * b)414 Node* Float32Min(Node* a, Node* b) { 415 return AddNode(machine()->Float32Min().op(), a, b); 416 } Float32Abs(Node * a)417 Node* Float32Abs(Node* a) { return AddNode(machine()->Float32Abs(), a); } Float32Neg(Node * a)418 Node* Float32Neg(Node* a) { return Float32Sub(Float32Constant(-0.0f), a); } Float32Sqrt(Node * a)419 Node* Float32Sqrt(Node* a) { return AddNode(machine()->Float32Sqrt(), a); } Float32Equal(Node * a,Node * b)420 Node* Float32Equal(Node* a, Node* b) { 421 return AddNode(machine()->Float32Equal(), a, b); 422 } Float32NotEqual(Node * a,Node * b)423 Node* Float32NotEqual(Node* a, Node* b) { 424 return Word32BinaryNot(Float32Equal(a, b)); 425 } Float32LessThan(Node * a,Node * b)426 Node* Float32LessThan(Node* a, Node* b) { 427 return AddNode(machine()->Float32LessThan(), a, b); 428 } Float32LessThanOrEqual(Node * a,Node * b)429 Node* Float32LessThanOrEqual(Node* a, Node* b) { 430 return AddNode(machine()->Float32LessThanOrEqual(), a, b); 431 } Float32GreaterThan(Node * a,Node * b)432 Node* Float32GreaterThan(Node* a, Node* b) { return Float32LessThan(b, a); } Float32GreaterThanOrEqual(Node * a,Node * b)433 Node* Float32GreaterThanOrEqual(Node* a, Node* b) { 434 return Float32LessThanOrEqual(b, a); 435 } 436 Float64Add(Node * a,Node * b)437 Node* Float64Add(Node* a, Node* b) { 438 return AddNode(machine()->Float64Add(), a, b); 439 } Float64Sub(Node * a,Node * b)440 Node* Float64Sub(Node* a, Node* b) { 441 return AddNode(machine()->Float64Sub(), a, b); 442 } Float64SubPreserveNan(Node * a,Node * b)443 Node* Float64SubPreserveNan(Node* a, Node* b) { 444 return AddNode(machine()->Float64SubPreserveNan(), a, b); 445 } Float64Mul(Node * a,Node * b)446 Node* Float64Mul(Node* a, Node* b) { 447 return AddNode(machine()->Float64Mul(), a, b); 448 } Float64Div(Node * a,Node * b)449 Node* Float64Div(Node* a, Node* b) { 450 return AddNode(machine()->Float64Div(), a, b); 451 } Float64Mod(Node * a,Node * b)452 Node* Float64Mod(Node* a, Node* b) { 453 return AddNode(machine()->Float64Mod(), a, b); 454 } Float64Max(Node * a,Node * b)455 Node* Float64Max(Node* a, Node* b) { 456 return AddNode(machine()->Float64Max().op(), a, b); 457 } Float64Min(Node * a,Node * b)458 Node* Float64Min(Node* a, Node* b) { 459 return AddNode(machine()->Float64Min().op(), a, b); 460 } Float64Abs(Node * a)461 Node* Float64Abs(Node* a) { return AddNode(machine()->Float64Abs(), a); } Float64Neg(Node * a)462 Node* Float64Neg(Node* a) { return Float64Sub(Float64Constant(-0.0), a); } Float64Atan(Node * a)463 Node* Float64Atan(Node* a) { return AddNode(machine()->Float64Atan(), a); } Float64Atan2(Node * a,Node * b)464 Node* Float64Atan2(Node* a, Node* b) { 465 return AddNode(machine()->Float64Atan2(), a, b); 466 } Float64Atanh(Node * a)467 Node* Float64Atanh(Node* a) { return AddNode(machine()->Float64Atanh(), a); } Float64Cbrt(Node * a)468 Node* Float64Cbrt(Node* a) { return AddNode(machine()->Float64Cbrt(), a); } Float64Cos(Node * a)469 Node* Float64Cos(Node* a) { return AddNode(machine()->Float64Cos(), a); } Float64Exp(Node * a)470 Node* Float64Exp(Node* a) { return AddNode(machine()->Float64Exp(), a); } Float64Expm1(Node * a)471 Node* Float64Expm1(Node* a) { return AddNode(machine()->Float64Expm1(), a); } Float64Log(Node * a)472 Node* Float64Log(Node* a) { return AddNode(machine()->Float64Log(), a); } Float64Log1p(Node * a)473 Node* Float64Log1p(Node* a) { return AddNode(machine()->Float64Log1p(), a); } Float64Log10(Node * a)474 Node* Float64Log10(Node* a) { return AddNode(machine()->Float64Log10(), a); } Float64Log2(Node * a)475 Node* Float64Log2(Node* a) { return AddNode(machine()->Float64Log2(), a); } Float64Sin(Node * a)476 Node* Float64Sin(Node* a) { return AddNode(machine()->Float64Sin(), a); } Float64Sqrt(Node * a)477 Node* Float64Sqrt(Node* a) { return AddNode(machine()->Float64Sqrt(), a); } Float64Tan(Node * a)478 Node* Float64Tan(Node* a) { return AddNode(machine()->Float64Tan(), a); } Float64Equal(Node * a,Node * b)479 Node* Float64Equal(Node* a, Node* b) { 480 return AddNode(machine()->Float64Equal(), a, b); 481 } Float64NotEqual(Node * a,Node * b)482 Node* Float64NotEqual(Node* a, Node* b) { 483 return Word32BinaryNot(Float64Equal(a, b)); 484 } Float64LessThan(Node * a,Node * b)485 Node* Float64LessThan(Node* a, Node* b) { 486 return AddNode(machine()->Float64LessThan(), a, b); 487 } Float64LessThanOrEqual(Node * a,Node * b)488 Node* Float64LessThanOrEqual(Node* a, Node* b) { 489 return AddNode(machine()->Float64LessThanOrEqual(), a, b); 490 } Float64GreaterThan(Node * a,Node * b)491 Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); } Float64GreaterThanOrEqual(Node * a,Node * b)492 Node* Float64GreaterThanOrEqual(Node* a, Node* b) { 493 return Float64LessThanOrEqual(b, a); 494 } 495 496 // Conversions. BitcastWordToTagged(Node * a)497 Node* BitcastWordToTagged(Node* a) { 498 return AddNode(machine()->BitcastWordToTagged(), a); 499 } TruncateFloat64ToWord32(Node * a)500 Node* TruncateFloat64ToWord32(Node* a) { 501 return AddNode(machine()->TruncateFloat64ToWord32(), a); 502 } ChangeFloat32ToFloat64(Node * a)503 Node* ChangeFloat32ToFloat64(Node* a) { 504 return AddNode(machine()->ChangeFloat32ToFloat64(), a); 505 } ChangeInt32ToFloat64(Node * a)506 Node* ChangeInt32ToFloat64(Node* a) { 507 return AddNode(machine()->ChangeInt32ToFloat64(), a); 508 } ChangeUint32ToFloat64(Node * a)509 Node* ChangeUint32ToFloat64(Node* a) { 510 return AddNode(machine()->ChangeUint32ToFloat64(), a); 511 } ChangeFloat64ToInt32(Node * a)512 Node* ChangeFloat64ToInt32(Node* a) { 513 return AddNode(machine()->ChangeFloat64ToInt32(), a); 514 } ChangeFloat64ToUint32(Node * a)515 Node* ChangeFloat64ToUint32(Node* a) { 516 return AddNode(machine()->ChangeFloat64ToUint32(), a); 517 } TruncateFloat64ToUint32(Node * a)518 Node* TruncateFloat64ToUint32(Node* a) { 519 return AddNode(machine()->TruncateFloat64ToUint32(), a); 520 } TruncateFloat32ToInt32(Node * a)521 Node* TruncateFloat32ToInt32(Node* a) { 522 return AddNode(machine()->TruncateFloat32ToInt32(), a); 523 } TruncateFloat32ToUint32(Node * a)524 Node* TruncateFloat32ToUint32(Node* a) { 525 return AddNode(machine()->TruncateFloat32ToUint32(), a); 526 } TryTruncateFloat32ToInt64(Node * a)527 Node* TryTruncateFloat32ToInt64(Node* a) { 528 return AddNode(machine()->TryTruncateFloat32ToInt64(), a); 529 } TryTruncateFloat64ToInt64(Node * a)530 Node* TryTruncateFloat64ToInt64(Node* a) { 531 return AddNode(machine()->TryTruncateFloat64ToInt64(), a); 532 } TryTruncateFloat32ToUint64(Node * a)533 Node* TryTruncateFloat32ToUint64(Node* a) { 534 return AddNode(machine()->TryTruncateFloat32ToUint64(), a); 535 } TryTruncateFloat64ToUint64(Node * a)536 Node* TryTruncateFloat64ToUint64(Node* a) { 537 return AddNode(machine()->TryTruncateFloat64ToUint64(), a); 538 } ChangeInt32ToInt64(Node * a)539 Node* ChangeInt32ToInt64(Node* a) { 540 return AddNode(machine()->ChangeInt32ToInt64(), a); 541 } ChangeUint32ToUint64(Node * a)542 Node* ChangeUint32ToUint64(Node* a) { 543 return AddNode(machine()->ChangeUint32ToUint64(), a); 544 } TruncateFloat64ToFloat32(Node * a)545 Node* TruncateFloat64ToFloat32(Node* a) { 546 return AddNode(machine()->TruncateFloat64ToFloat32(), a); 547 } TruncateInt64ToInt32(Node * a)548 Node* TruncateInt64ToInt32(Node* a) { 549 return AddNode(machine()->TruncateInt64ToInt32(), a); 550 } RoundFloat64ToInt32(Node * a)551 Node* RoundFloat64ToInt32(Node* a) { 552 return AddNode(machine()->RoundFloat64ToInt32(), a); 553 } RoundInt32ToFloat32(Node * a)554 Node* RoundInt32ToFloat32(Node* a) { 555 return AddNode(machine()->RoundInt32ToFloat32(), a); 556 } RoundInt64ToFloat32(Node * a)557 Node* RoundInt64ToFloat32(Node* a) { 558 return AddNode(machine()->RoundInt64ToFloat32(), a); 559 } RoundInt64ToFloat64(Node * a)560 Node* RoundInt64ToFloat64(Node* a) { 561 return AddNode(machine()->RoundInt64ToFloat64(), a); 562 } RoundUint32ToFloat32(Node * a)563 Node* RoundUint32ToFloat32(Node* a) { 564 return AddNode(machine()->RoundUint32ToFloat32(), a); 565 } RoundUint64ToFloat32(Node * a)566 Node* RoundUint64ToFloat32(Node* a) { 567 return AddNode(machine()->RoundUint64ToFloat32(), a); 568 } RoundUint64ToFloat64(Node * a)569 Node* RoundUint64ToFloat64(Node* a) { 570 return AddNode(machine()->RoundUint64ToFloat64(), a); 571 } BitcastFloat32ToInt32(Node * a)572 Node* BitcastFloat32ToInt32(Node* a) { 573 return AddNode(machine()->BitcastFloat32ToInt32(), a); 574 } BitcastFloat64ToInt64(Node * a)575 Node* BitcastFloat64ToInt64(Node* a) { 576 return AddNode(machine()->BitcastFloat64ToInt64(), a); 577 } BitcastInt32ToFloat32(Node * a)578 Node* BitcastInt32ToFloat32(Node* a) { 579 return AddNode(machine()->BitcastInt32ToFloat32(), a); 580 } BitcastInt64ToFloat64(Node * a)581 Node* BitcastInt64ToFloat64(Node* a) { 582 return AddNode(machine()->BitcastInt64ToFloat64(), a); 583 } Float32RoundDown(Node * a)584 Node* Float32RoundDown(Node* a) { 585 return AddNode(machine()->Float32RoundDown().op(), a); 586 } Float64RoundDown(Node * a)587 Node* Float64RoundDown(Node* a) { 588 return AddNode(machine()->Float64RoundDown().op(), a); 589 } Float32RoundUp(Node * a)590 Node* Float32RoundUp(Node* a) { 591 return AddNode(machine()->Float32RoundUp().op(), a); 592 } Float64RoundUp(Node * a)593 Node* Float64RoundUp(Node* a) { 594 return AddNode(machine()->Float64RoundUp().op(), a); 595 } Float32RoundTruncate(Node * a)596 Node* Float32RoundTruncate(Node* a) { 597 return AddNode(machine()->Float32RoundTruncate().op(), a); 598 } Float64RoundTruncate(Node * a)599 Node* Float64RoundTruncate(Node* a) { 600 return AddNode(machine()->Float64RoundTruncate().op(), a); 601 } Float64RoundTiesAway(Node * a)602 Node* Float64RoundTiesAway(Node* a) { 603 return AddNode(machine()->Float64RoundTiesAway().op(), a); 604 } Float32RoundTiesEven(Node * a)605 Node* Float32RoundTiesEven(Node* a) { 606 return AddNode(machine()->Float32RoundTiesEven().op(), a); 607 } Float64RoundTiesEven(Node * a)608 Node* Float64RoundTiesEven(Node* a) { 609 return AddNode(machine()->Float64RoundTiesEven().op(), a); 610 } 611 612 // Float64 bit operations. Float64ExtractLowWord32(Node * a)613 Node* Float64ExtractLowWord32(Node* a) { 614 return AddNode(machine()->Float64ExtractLowWord32(), a); 615 } Float64ExtractHighWord32(Node * a)616 Node* Float64ExtractHighWord32(Node* a) { 617 return AddNode(machine()->Float64ExtractHighWord32(), a); 618 } Float64InsertLowWord32(Node * a,Node * b)619 Node* Float64InsertLowWord32(Node* a, Node* b) { 620 return AddNode(machine()->Float64InsertLowWord32(), a, b); 621 } Float64InsertHighWord32(Node * a,Node * b)622 Node* Float64InsertHighWord32(Node* a, Node* b) { 623 return AddNode(machine()->Float64InsertHighWord32(), a, b); 624 } 625 626 // Stack operations. LoadStackPointer()627 Node* LoadStackPointer() { return AddNode(machine()->LoadStackPointer()); } LoadFramePointer()628 Node* LoadFramePointer() { return AddNode(machine()->LoadFramePointer()); } LoadParentFramePointer()629 Node* LoadParentFramePointer() { 630 return AddNode(machine()->LoadParentFramePointer()); 631 } 632 633 // Parameters. 634 Node* Parameter(size_t index); 635 636 // Pointer utilities. 637 Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) { 638 return Load(rep, PointerConstant(address), Int32Constant(offset)); 639 } StoreToPointer(void * address,MachineRepresentation rep,Node * node)640 Node* StoreToPointer(void* address, MachineRepresentation rep, Node* node) { 641 return Store(rep, PointerConstant(address), node, kNoWriteBarrier); 642 } StringConstant(const char * string)643 Node* StringConstant(const char* string) { 644 return HeapConstant(isolate()->factory()->InternalizeUtf8String(string)); 645 } 646 647 // Call a given call descriptor and the given arguments. 648 Node* CallN(CallDescriptor* desc, Node* function, Node** args); 649 // Call a given call descriptor and the given arguments and frame-state. 650 Node* CallNWithFrameState(CallDescriptor* desc, Node* function, Node** args, 651 Node* frame_state); 652 // Call to a runtime function with zero arguments. 653 Node* CallRuntime0(Runtime::FunctionId function, Node* context); 654 // Call to a runtime function with one arguments. 655 Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context); 656 // Call to a runtime function with two arguments. 657 Node* CallRuntime2(Runtime::FunctionId function, Node* arg1, Node* arg2, 658 Node* context); 659 // Call to a runtime function with three arguments. 660 Node* CallRuntime3(Runtime::FunctionId function, Node* arg1, Node* arg2, 661 Node* arg3, Node* context); 662 // Call to a runtime function with four arguments. 663 Node* CallRuntime4(Runtime::FunctionId function, Node* arg1, Node* arg2, 664 Node* arg3, Node* arg4, Node* context); 665 // Call to a C function with zero arguments. 666 Node* CallCFunction0(MachineType return_type, Node* function); 667 // Call to a C function with one parameter. 668 Node* CallCFunction1(MachineType return_type, MachineType arg0_type, 669 Node* function, Node* arg0); 670 // Call to a C function with two arguments. 671 Node* CallCFunction2(MachineType return_type, MachineType arg0_type, 672 MachineType arg1_type, Node* function, Node* arg0, 673 Node* arg1); 674 // Call to a C function with eight arguments. 675 Node* CallCFunction8(MachineType return_type, MachineType arg0_type, 676 MachineType arg1_type, MachineType arg2_type, 677 MachineType arg3_type, MachineType arg4_type, 678 MachineType arg5_type, MachineType arg6_type, 679 MachineType arg7_type, Node* function, Node* arg0, 680 Node* arg1, Node* arg2, Node* arg3, Node* arg4, 681 Node* arg5, Node* arg6, Node* arg7); 682 683 // Tail call the given call descriptor and the given arguments. 684 Node* TailCallN(CallDescriptor* call_descriptor, Node* function, Node** args); 685 // Tail call to a runtime function with zero arguments. 686 Node* TailCallRuntime0(Runtime::FunctionId function, Node* context); 687 // Tail call to a runtime function with one argument. 688 Node* TailCallRuntime1(Runtime::FunctionId function, Node* arg0, 689 Node* context); 690 // Tail call to a runtime function with two arguments. 691 Node* TailCallRuntime2(Runtime::FunctionId function, Node* arg1, Node* arg2, 692 Node* context); 693 // Tail call to a runtime function with three arguments. 694 Node* TailCallRuntime3(Runtime::FunctionId function, Node* arg1, Node* arg2, 695 Node* arg3, Node* context); 696 // Tail call to a runtime function with four arguments. 697 Node* TailCallRuntime4(Runtime::FunctionId function, Node* arg1, Node* arg2, 698 Node* arg3, Node* arg4, Node* context); 699 700 // =========================================================================== 701 // The following utility methods deal with control flow, hence might switch 702 // the current basic block or create new basic blocks for labels. 703 704 // Control flow. 705 void Goto(RawMachineLabel* label); 706 void Branch(Node* condition, RawMachineLabel* true_val, 707 RawMachineLabel* false_val); 708 void Switch(Node* index, RawMachineLabel* default_label, int32_t* case_values, 709 RawMachineLabel** case_labels, size_t case_count); 710 void Return(Node* value); 711 void Return(Node* v1, Node* v2); 712 void Return(Node* v1, Node* v2, Node* v3); 713 void Bind(RawMachineLabel* label); 714 void Deoptimize(Node* state); 715 void DebugBreak(); 716 void Comment(const char* msg); 717 718 // Variables. Phi(MachineRepresentation rep,Node * n1,Node * n2)719 Node* Phi(MachineRepresentation rep, Node* n1, Node* n2) { 720 return AddNode(common()->Phi(rep, 2), n1, n2, graph()->start()); 721 } Phi(MachineRepresentation rep,Node * n1,Node * n2,Node * n3)722 Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3) { 723 return AddNode(common()->Phi(rep, 3), n1, n2, n3, graph()->start()); 724 } Phi(MachineRepresentation rep,Node * n1,Node * n2,Node * n3,Node * n4)725 Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3, Node* n4) { 726 return AddNode(common()->Phi(rep, 4), n1, n2, n3, n4, graph()->start()); 727 } 728 Node* Phi(MachineRepresentation rep, int input_count, Node* const* inputs); 729 void AppendPhiInput(Node* phi, Node* new_input); 730 731 // =========================================================================== 732 // The following generic node creation methods can be used for operators that 733 // are not covered by the above utility methods. There should rarely be a need 734 // to do that outside of testing though. 735 736 Node* AddNode(const Operator* op, int input_count, Node* const* inputs); 737 AddNode(const Operator * op)738 Node* AddNode(const Operator* op) { 739 return AddNode(op, 0, static_cast<Node* const*>(nullptr)); 740 } 741 742 template <class... TArgs> AddNode(const Operator * op,Node * n1,TArgs...args)743 Node* AddNode(const Operator* op, Node* n1, TArgs... args) { 744 Node* buffer[] = {n1, args...}; 745 return AddNode(op, sizeof...(args) + 1, buffer); 746 } 747 748 private: 749 Node* MakeNode(const Operator* op, int input_count, Node* const* inputs); 750 BasicBlock* Use(RawMachineLabel* label); 751 BasicBlock* EnsureBlock(RawMachineLabel* label); 752 BasicBlock* CurrentBlock(); 753 schedule()754 Schedule* schedule() { return schedule_; } parameter_count()755 size_t parameter_count() const { return machine_sig()->parameter_count(); } machine_sig()756 const MachineSignature* machine_sig() const { 757 return call_descriptor_->GetMachineSignature(); 758 } 759 760 Isolate* isolate_; 761 Graph* graph_; 762 Schedule* schedule_; 763 MachineOperatorBuilder machine_; 764 CommonOperatorBuilder common_; 765 CallDescriptor* call_descriptor_; 766 NodeVector parameters_; 767 BasicBlock* current_block_; 768 769 DISALLOW_COPY_AND_ASSIGN(RawMachineAssembler); 770 }; 771 772 773 class RawMachineLabel final { 774 public: 775 enum Type { kDeferred, kNonDeferred }; 776 777 explicit RawMachineLabel(Type type = kNonDeferred) 778 : deferred_(type == kDeferred) {} 779 ~RawMachineLabel(); 780 781 private: 782 BasicBlock* block_ = nullptr; 783 bool used_ = false; 784 bool bound_ = false; 785 bool deferred_; 786 friend class RawMachineAssembler; 787 DISALLOW_COPY_AND_ASSIGN(RawMachineLabel); 788 }; 789 790 } // namespace compiler 791 } // namespace internal 792 } // namespace v8 793 794 #endif // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_ 795