[JSC] Int52Rep(DoubleRepAnyIntUse) should not call operation function
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLOutput.cpp
1 /*
2  * Copyright (C) 2013-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 "FTLOutput.h"
28
29 #if ENABLE(FTL_JIT)
30
31 #include "B3ArgumentRegValue.h"
32 #include "B3AtomicValue.h"
33 #include "B3BasicBlockInlines.h"
34 #include "B3CCallValue.h"
35 #include "B3Const32Value.h"
36 #include "B3ConstPtrValue.h"
37 #include "B3FenceValue.h"
38 #include "B3MathExtras.h"
39 #include "B3MemoryValue.h"
40 #include "B3SlotBaseValue.h"
41 #include "B3StackmapGenerationParams.h"
42 #include "B3SwitchValue.h"
43 #include "B3UpsilonValue.h"
44 #include "B3ValueInlines.h"
45 #include "SuperSampler.h"
46
47 namespace JSC { namespace FTL {
48
49 using namespace B3;
50
51 Output::Output(State& state)
52     : m_proc(*state.proc)
53 {
54 }
55
56 Output::~Output()
57 {
58 }
59
60 void Output::initialize(AbstractHeapRepository& heaps)
61 {
62     m_heaps = &heaps;
63 }
64
65 LBasicBlock Output::newBlock()
66 {
67     LBasicBlock result = m_proc.addBlock(m_frequency);
68
69     if (!m_nextBlock)
70         m_blockOrder.append(result);
71     else
72         m_blockOrder.insertBefore(m_nextBlock, result);
73
74     return result;
75 }
76
77 void Output::applyBlockOrder()
78 {
79     m_proc.setBlockOrder(m_blockOrder);
80 }
81
82 LBasicBlock Output::appendTo(LBasicBlock block, LBasicBlock nextBlock)
83 {
84     appendTo(block);
85     return insertNewBlocksBefore(nextBlock);
86 }
87
88 void Output::appendTo(LBasicBlock block)
89 {
90     m_block = block;
91 }
92
93 LValue Output::framePointer()
94 {
95     return m_block->appendNew<B3::Value>(m_proc, B3::FramePointer, origin());
96 }
97
98 SlotBaseValue* Output::lockedStackSlot(size_t bytes)
99 {
100     return m_block->appendNew<SlotBaseValue>(m_proc, origin(), m_proc.addStackSlot(bytes));
101 }
102
103 LValue Output::constBool(bool value)
104 {
105     if (value)
106         return booleanTrue;
107     return booleanFalse;
108 }
109
110 LValue Output::constInt32(int32_t value)
111 {
112     return m_block->appendNew<B3::Const32Value>(m_proc, origin(), value);
113 }
114
115 LValue Output::constInt64(int64_t value)
116 {
117     return m_block->appendNew<B3::Const64Value>(m_proc, origin(), value);
118 }
119
120 LValue Output::constDouble(double value)
121 {
122     return m_block->appendNew<B3::ConstDoubleValue>(m_proc, origin(), value);
123 }
124
125 LValue Output::phi(LType type)
126 {
127     return m_block->appendNew<B3::Value>(m_proc, B3::Phi, type, origin());
128 }
129
130 LValue Output::opaque(LValue value)
131 {
132     return m_block->appendNew<Value>(m_proc, Opaque, origin(), value);
133 }
134
135 LValue Output::add(LValue left, LValue right)
136 {
137     if (Value* result = left->addConstant(m_proc, right)) {
138         m_block->append(result);
139         return result;
140     }
141     return m_block->appendNew<B3::Value>(m_proc, B3::Add, origin(), left, right);
142 }
143
144 LValue Output::sub(LValue left, LValue right)
145 {
146     return m_block->appendNew<B3::Value>(m_proc, B3::Sub, origin(), left, right);
147 }
148
149 LValue Output::mul(LValue left, LValue right)
150 {
151     return m_block->appendNew<B3::Value>(m_proc, B3::Mul, origin(), left, right);
152 }
153
154 LValue Output::div(LValue left, LValue right)
155 {
156     return m_block->appendNew<B3::Value>(m_proc, B3::Div, origin(), left, right);
157 }
158
159 LValue Output::chillDiv(LValue left, LValue right)
160 {
161     return m_block->appendNew<B3::Value>(m_proc, chill(B3::Div), origin(), left, right);
162 }
163
164 LValue Output::mod(LValue left, LValue right)
165 {
166     return m_block->appendNew<B3::Value>(m_proc, B3::Mod, origin(), left, right);
167 }
168
169 LValue Output::chillMod(LValue left, LValue right)
170 {
171     return m_block->appendNew<B3::Value>(m_proc, chill(B3::Mod), origin(), left, right);
172 }
173
174 LValue Output::neg(LValue value)
175 {
176     return m_block->appendNew<Value>(m_proc, B3::Neg, origin(), value);
177 }
178
179 LValue Output::doubleAdd(LValue left, LValue right)
180 {
181     return m_block->appendNew<B3::Value>(m_proc, B3::Add, origin(), left, right);
182 }
183
184 LValue Output::doubleSub(LValue left, LValue right)
185 {
186     return m_block->appendNew<B3::Value>(m_proc, B3::Sub, origin(), left, right);
187 }
188
189 LValue Output::doubleMul(LValue left, LValue right)
190 {
191     return m_block->appendNew<B3::Value>(m_proc, B3::Mul, origin(), left, right);
192 }
193
194 LValue Output::doubleDiv(LValue left, LValue right)
195 {
196     return m_block->appendNew<B3::Value>(m_proc, B3::Div, origin(), left, right);
197 }
198
199 LValue Output::doubleMod(LValue left, LValue right)
200 {
201     return m_block->appendNew<B3::Value>(m_proc, B3::Mod, origin(), left, right);
202 }
203
204 LValue Output::bitAnd(LValue left, LValue right)
205 {
206     return m_block->appendNew<B3::Value>(m_proc, B3::BitAnd, origin(), left, right);
207 }
208
209 LValue Output::bitOr(LValue left, LValue right)
210 {
211     return m_block->appendNew<B3::Value>(m_proc, B3::BitOr, origin(), left, right);
212 }
213
214 LValue Output::bitXor(LValue left, LValue right)
215 {
216     return m_block->appendNew<B3::Value>(m_proc, B3::BitXor, origin(), left, right);
217 }
218
219 LValue Output::shl(LValue left, LValue right)
220 {
221     right = castToInt32(right);
222     if (Value* result = left->shlConstant(m_proc, right)) {
223         m_block->append(result);
224         return result;
225     }
226     return m_block->appendNew<B3::Value>(m_proc, B3::Shl, origin(), left, right);
227 }
228
229 LValue Output::aShr(LValue left, LValue right)
230 {
231     right = castToInt32(right);
232     if (Value* result = left->sShrConstant(m_proc, right)) {
233         m_block->append(result);
234         return result;
235     }
236     return m_block->appendNew<B3::Value>(m_proc, B3::SShr, origin(), left, right);
237 }
238
239 LValue Output::lShr(LValue left, LValue right)
240 {
241     right = castToInt32(right);
242     if (Value* result = left->zShrConstant(m_proc, right)) {
243         m_block->append(result);
244         return result;
245     }
246     return m_block->appendNew<B3::Value>(m_proc, B3::ZShr, origin(), left, right);
247 }
248
249 LValue Output::bitNot(LValue value)
250 {
251     return m_block->appendNew<B3::Value>(m_proc, B3::BitXor, origin(),
252         value,
253         m_block->appendIntConstant(m_proc, origin(), value->type(), -1));
254 }
255
256 LValue Output::logicalNot(LValue value)
257 {
258     return m_block->appendNew<B3::Value>(m_proc, B3::Equal, origin(), value, int32Zero);
259 }
260
261 LValue Output::ctlz32(LValue operand)
262 {
263     return m_block->appendNew<B3::Value>(m_proc, B3::Clz, origin(), operand);
264 }
265
266 LValue Output::doubleAbs(LValue value)
267 {
268     return m_block->appendNew<B3::Value>(m_proc, B3::Abs, origin(), value);
269 }
270
271 LValue Output::doubleCeil(LValue operand)
272 {
273     return m_block->appendNew<B3::Value>(m_proc, B3::Ceil, origin(), operand);
274 }
275
276 LValue Output::doubleFloor(LValue operand)
277 {
278     return m_block->appendNew<B3::Value>(m_proc, B3::Floor, origin(), operand);
279 }
280
281 LValue Output::doubleTrunc(LValue value)
282 {
283     if (MacroAssembler::supportsFloatingPointRounding()) {
284         PatchpointValue* result = patchpoint(Double);
285         result->append(value, ValueRep::SomeRegister);
286         result->setGenerator(
287             [] (CCallHelpers& jit, const StackmapGenerationParams& params) {
288                 jit.roundTowardZeroDouble(params[1].fpr(), params[0].fpr());
289             });
290         result->effects = Effects::none();
291         return result;
292     }
293     double (*truncDouble)(double) = trunc;
294     return callWithoutSideEffects(Double, truncDouble, value);
295 }
296
297 LValue Output::doubleUnary(DFG::Arith::UnaryType type, LValue value)
298 {
299     double (*unaryFunction)(double) = DFG::arithUnaryFunction(type);
300     return callWithoutSideEffects(B3::Double, unaryFunction, value);
301 }
302
303 LValue Output::doublePow(LValue xOperand, LValue yOperand)
304 {
305     double (*powDouble)(double, double) = pow;
306     return callWithoutSideEffects(B3::Double, powDouble, xOperand, yOperand);
307 }
308
309 LValue Output::doublePowi(LValue x, LValue y)
310 {
311     // FIXME: powDoubleInt32() should be inlined here since Output knows about block layout and
312     // should be involved in any operation that creates blocks.
313     // https://bugs.webkit.org/show_bug.cgi?id=152223
314     auto result = powDoubleInt32(m_proc, m_block, origin(), x, y);
315     m_block = result.first;
316     return result.second;
317 }
318
319 LValue Output::doubleSqrt(LValue value)
320 {
321     return m_block->appendNew<B3::Value>(m_proc, B3::Sqrt, origin(), value);
322 }
323
324 LValue Output::doubleToInt(LValue value)
325 {
326     PatchpointValue* result = patchpoint(Int32);
327     result->append(value, ValueRep::SomeRegister);
328     result->setGenerator(
329         [] (CCallHelpers& jit, const StackmapGenerationParams& params) {
330             jit.truncateDoubleToInt32(params[1].fpr(), params[0].gpr());
331         });
332     result->effects = Effects::none();
333     return result;
334 }
335
336 LValue Output::doubleToInt64(LValue value)
337 {
338     PatchpointValue* result = patchpoint(Int64);
339     result->append(value, ValueRep::SomeRegister);
340     result->setGenerator(
341         [] (CCallHelpers& jit, const StackmapGenerationParams& params) {
342             jit.truncateDoubleToInt64(params[1].fpr(), params[0].gpr());
343         });
344     result->effects = Effects::none();
345     return result;
346 }
347
348 LValue Output::doubleToUInt(LValue value)
349 {
350     PatchpointValue* result = patchpoint(Int32);
351     result->append(value, ValueRep::SomeRegister);
352     result->setGenerator(
353         [] (CCallHelpers& jit, const StackmapGenerationParams& params) {
354             jit.truncateDoubleToUint32(params[1].fpr(), params[0].gpr());
355         });
356     result->effects = Effects::none();
357     return result;
358 }
359
360 LValue Output::signExt32To64(LValue value)
361 {
362     return m_block->appendNew<B3::Value>(m_proc, B3::SExt32, origin(), value);
363 }
364
365 LValue Output::signExt32ToPtr(LValue value)
366 {
367     return signExt32To64(value);
368 }
369
370 LValue Output::zeroExt(LValue value, LType type)
371 {
372     if (value->type() == type)
373         return value;
374     if (value->hasInt32())
375         return m_block->appendIntConstant(m_proc, origin(), Int64, static_cast<uint64_t>(static_cast<uint32_t>(value->asInt32())));
376     return m_block->appendNew<B3::Value>(m_proc, B3::ZExt32, origin(), value);
377 }
378
379 LValue Output::intToDouble(LValue value)
380 {
381     return m_block->appendNew<B3::Value>(m_proc, B3::IToD, origin(), value);
382 }
383
384 LValue Output::unsignedToDouble(LValue value)
385 {
386     return intToDouble(zeroExt(value, Int64));
387 }
388
389 LValue Output::castToInt32(LValue value)
390 {
391     if (value->type() == Int32)
392         return value;
393     if (value->hasInt64())
394         return constInt32(static_cast<int32_t>(value->asInt64()));
395     return m_block->appendNew<B3::Value>(m_proc, B3::Trunc, origin(), value);
396 }
397
398 LValue Output::doubleToFloat(LValue value)
399 {
400     return m_block->appendNew<B3::Value>(m_proc, B3::DoubleToFloat, origin(), value);
401 }
402
403 LValue Output::floatToDouble(LValue value)
404 {
405     return m_block->appendNew<B3::Value>(m_proc, B3::FloatToDouble, origin(), value);
406 }
407
408 LValue Output::load(TypedPointer pointer, LType type)
409 {
410     LValue load = m_block->appendNew<MemoryValue>(m_proc, Load, type, origin(), pointer.value());
411     m_heaps->decorateMemory(pointer.heap(), load);
412     return load;
413 }
414
415 LValue Output::load8SignExt32(TypedPointer pointer)
416 {
417     LValue load = m_block->appendNew<MemoryValue>(m_proc, Load8S, Int32, origin(), pointer.value());
418     m_heaps->decorateMemory(pointer.heap(), load);
419     return load;
420 }
421
422 LValue Output::load8ZeroExt32(TypedPointer pointer)
423 {
424     LValue load = m_block->appendNew<MemoryValue>(m_proc, Load8Z, Int32, origin(), pointer.value());
425     m_heaps->decorateMemory(pointer.heap(), load);
426     return load;
427 }
428
429 LValue Output::load16SignExt32(TypedPointer pointer)
430 {
431     LValue load = m_block->appendNew<MemoryValue>(m_proc, Load16S, Int32, origin(), pointer.value());
432     m_heaps->decorateMemory(pointer.heap(), load);
433     return load;
434 }
435
436 LValue Output::load16ZeroExt32(TypedPointer pointer)
437 {
438     LValue load = m_block->appendNew<MemoryValue>(m_proc, Load16Z, Int32, origin(), pointer.value());
439     m_heaps->decorateMemory(pointer.heap(), load);
440     return load;
441 }
442
443 LValue Output::store(LValue value, TypedPointer pointer)
444 {
445     LValue store = m_block->appendNew<MemoryValue>(m_proc, Store, origin(), value, pointer.value());
446     m_heaps->decorateMemory(pointer.heap(), store);
447     return store;
448 }
449
450 FenceValue* Output::fence(const AbstractHeap* read, const AbstractHeap* write)
451 {
452     FenceValue* result = m_block->appendNew<FenceValue>(m_proc, origin());
453     m_heaps->decorateFenceRead(read, result);
454     m_heaps->decorateFenceWrite(write, result);
455     return result;
456 }
457
458 LValue Output::store32As8(LValue value, TypedPointer pointer)
459 {
460     LValue store = m_block->appendNew<MemoryValue>(m_proc, Store8, origin(), value, pointer.value());
461     m_heaps->decorateMemory(pointer.heap(), store);
462     return store;
463 }
464
465 LValue Output::store32As16(LValue value, TypedPointer pointer)
466 {
467     LValue store = m_block->appendNew<MemoryValue>(m_proc, Store16, origin(), value, pointer.value());
468     m_heaps->decorateMemory(pointer.heap(), store);
469     return store;
470 }
471
472 LValue Output::baseIndex(LValue base, LValue index, Scale scale, ptrdiff_t offset)
473 {
474     LValue accumulatedOffset;
475         
476     switch (scale) {
477     case ScaleOne:
478         accumulatedOffset = index;
479         break;
480     case ScaleTwo:
481         accumulatedOffset = shl(index, intPtrOne);
482         break;
483     case ScaleFour:
484         accumulatedOffset = shl(index, intPtrTwo);
485         break;
486     case ScaleEight:
487     case ScalePtr:
488         accumulatedOffset = shl(index, intPtrThree);
489         break;
490     }
491         
492     if (offset)
493         accumulatedOffset = add(accumulatedOffset, constIntPtr(offset));
494         
495     return add(base, accumulatedOffset);
496 }
497
498 LValue Output::equal(LValue left, LValue right)
499 {
500     TriState result = left->equalConstant(right);
501     if (result != MixedTriState)
502         return constBool(result == TrueTriState);
503     return m_block->appendNew<B3::Value>(m_proc, B3::Equal, origin(), left, right);
504 }
505
506 LValue Output::notEqual(LValue left, LValue right)
507 {
508     TriState result = left->notEqualConstant(right);
509     if (result != MixedTriState)
510         return constBool(result == TrueTriState);
511     return m_block->appendNew<B3::Value>(m_proc, B3::NotEqual, origin(), left, right);
512 }
513
514 LValue Output::above(LValue left, LValue right)
515 {
516     TriState result = left->aboveConstant(right);
517     if (result != MixedTriState)
518         return constBool(result == TrueTriState);
519     return m_block->appendNew<B3::Value>(m_proc, B3::Above, origin(), left, right);
520 }
521
522 LValue Output::aboveOrEqual(LValue left, LValue right)
523 {
524     TriState result = left->aboveEqualConstant(right);
525     if (result != MixedTriState)
526         return constBool(result == TrueTriState);
527     return m_block->appendNew<B3::Value>(m_proc, B3::AboveEqual, origin(), left, right);
528 }
529
530 LValue Output::below(LValue left, LValue right)
531 {
532     TriState result = left->belowConstant(right);
533     if (result != MixedTriState)
534         return constBool(result == TrueTriState);
535     return m_block->appendNew<B3::Value>(m_proc, B3::Below, origin(), left, right);
536 }
537
538 LValue Output::belowOrEqual(LValue left, LValue right)
539 {
540     TriState result = left->belowEqualConstant(right);
541     if (result != MixedTriState)
542         return constBool(result == TrueTriState);
543     return m_block->appendNew<B3::Value>(m_proc, B3::BelowEqual, origin(), left, right);
544 }
545
546 LValue Output::greaterThan(LValue left, LValue right)
547 {
548     TriState result = left->greaterThanConstant(right);
549     if (result != MixedTriState)
550         return constBool(result == TrueTriState);
551     return m_block->appendNew<B3::Value>(m_proc, B3::GreaterThan, origin(), left, right);
552 }
553
554 LValue Output::greaterThanOrEqual(LValue left, LValue right)
555 {
556     TriState result = left->greaterEqualConstant(right);
557     if (result != MixedTriState)
558         return constBool(result == TrueTriState);
559     return m_block->appendNew<B3::Value>(m_proc, B3::GreaterEqual, origin(), left, right);
560 }
561
562 LValue Output::lessThan(LValue left, LValue right)
563 {
564     TriState result = left->lessThanConstant(right);
565     if (result != MixedTriState)
566         return constBool(result == TrueTriState);
567     return m_block->appendNew<B3::Value>(m_proc, B3::LessThan, origin(), left, right);
568 }
569
570 LValue Output::lessThanOrEqual(LValue left, LValue right)
571 {
572     TriState result = left->lessEqualConstant(right);
573     if (result != MixedTriState)
574         return constBool(result == TrueTriState);
575     return m_block->appendNew<B3::Value>(m_proc, B3::LessEqual, origin(), left, right);
576 }
577
578 LValue Output::doubleEqual(LValue left, LValue right)
579 {
580     return m_block->appendNew<B3::Value>(m_proc, B3::Equal, origin(), left, right);
581 }
582
583 LValue Output::doubleEqualOrUnordered(LValue left, LValue right)
584 {
585     return m_block->appendNew<B3::Value>(m_proc, B3::EqualOrUnordered, origin(), left, right);
586 }
587
588 LValue Output::doubleNotEqualOrUnordered(LValue left, LValue right)
589 {
590     return m_block->appendNew<B3::Value>(m_proc, B3::NotEqual, origin(), left, right);
591 }
592
593 LValue Output::doubleLessThan(LValue left, LValue right)
594 {
595     return m_block->appendNew<B3::Value>(m_proc, B3::LessThan, origin(), left, right);
596 }
597
598 LValue Output::doubleLessThanOrEqual(LValue left, LValue right)
599 {
600     return m_block->appendNew<B3::Value>(m_proc, B3::LessEqual, origin(), left, right);
601 }
602
603 LValue Output::doubleGreaterThan(LValue left, LValue right)
604 {
605     return m_block->appendNew<B3::Value>(m_proc, B3::GreaterThan, origin(), left, right);
606 }
607
608 LValue Output::doubleGreaterThanOrEqual(LValue left, LValue right)
609 {
610     return m_block->appendNew<B3::Value>(m_proc, B3::GreaterEqual, origin(), left, right);
611 }
612
613 LValue Output::doubleNotEqualAndOrdered(LValue left, LValue right)
614 {
615     return logicalNot(doubleEqualOrUnordered(left, right));
616 }
617
618 LValue Output::doubleLessThanOrUnordered(LValue left, LValue right)
619 {
620     return logicalNot(doubleGreaterThanOrEqual(left, right));
621 }
622
623 LValue Output::doubleLessThanOrEqualOrUnordered(LValue left, LValue right)
624 {
625     return logicalNot(doubleGreaterThan(left, right));
626 }
627
628 LValue Output::doubleGreaterThanOrUnordered(LValue left, LValue right)
629 {
630     return logicalNot(doubleLessThanOrEqual(left, right));
631 }
632
633 LValue Output::doubleGreaterThanOrEqualOrUnordered(LValue left, LValue right)
634 {
635     return logicalNot(doubleLessThan(left, right));
636 }
637
638 LValue Output::isZero32(LValue value)
639 {
640     return m_block->appendNew<B3::Value>(m_proc, B3::Equal, origin(), value, int32Zero);
641 }
642
643 LValue Output::notZero32(LValue value)
644 {
645     return m_block->appendNew<B3::Value>(m_proc, B3::NotEqual, origin(), value, int32Zero);
646 }
647
648 LValue Output::isZero64(LValue value)
649 {
650     return m_block->appendNew<B3::Value>(m_proc, B3::Equal, origin(), value, int64Zero);
651 }
652
653 LValue Output::notZero64(LValue value)
654 {
655     return m_block->appendNew<B3::Value>(m_proc, B3::NotEqual, origin(), value, int64Zero);
656 }
657
658 LValue Output::select(LValue value, LValue taken, LValue notTaken)
659 {
660     if (value->hasInt32()) {
661         if (value->asInt32())
662             return taken;
663         else
664             return notTaken;
665     }
666     return m_block->appendNew<B3::Value>(m_proc, B3::Select, origin(), value, taken, notTaken);
667 }
668
669 LValue Output::atomicXchgAdd(LValue operand, TypedPointer pointer, Width width)
670 {
671     LValue result = m_block->appendNew<AtomicValue>(m_proc, AtomicXchgAdd, origin(), width, operand, pointer.value(), 0, HeapRange(), HeapRange());
672     m_heaps->decorateMemory(pointer.heap(), result);
673     return result;
674 }
675
676 LValue Output::atomicXchgAnd(LValue operand, TypedPointer pointer, Width width)
677 {
678     LValue result = m_block->appendNew<AtomicValue>(m_proc, AtomicXchgAnd, origin(), width, operand, pointer.value(), 0, HeapRange(), HeapRange());
679     m_heaps->decorateMemory(pointer.heap(), result);
680     return result;
681 }
682
683 LValue Output::atomicXchgOr(LValue operand, TypedPointer pointer, Width width)
684 {
685     LValue result = m_block->appendNew<AtomicValue>(m_proc, AtomicXchgOr, origin(), width, operand, pointer.value(), 0, HeapRange(), HeapRange());
686     m_heaps->decorateMemory(pointer.heap(), result);
687     return result;
688 }
689
690 LValue Output::atomicXchgSub(LValue operand, TypedPointer pointer, Width width)
691 {
692     LValue result = m_block->appendNew<AtomicValue>(m_proc, AtomicXchgSub, origin(), width, operand, pointer.value(), 0, HeapRange(), HeapRange());
693     m_heaps->decorateMemory(pointer.heap(), result);
694     return result;
695 }
696
697 LValue Output::atomicXchgXor(LValue operand, TypedPointer pointer, Width width)
698 {
699     LValue result = m_block->appendNew<AtomicValue>(m_proc, AtomicXchgXor, origin(), width, operand, pointer.value(), 0, HeapRange(), HeapRange());
700     m_heaps->decorateMemory(pointer.heap(), result);
701     return result;
702 }
703
704 LValue Output::atomicXchg(LValue operand, TypedPointer pointer, Width width)
705 {
706     LValue result = m_block->appendNew<AtomicValue>(m_proc, AtomicXchg, origin(), width, operand, pointer.value(), 0, HeapRange(), HeapRange());
707     m_heaps->decorateMemory(pointer.heap(), result);
708     return result;
709 }
710
711 LValue Output::atomicStrongCAS(LValue expected, LValue newValue, TypedPointer pointer, Width width)
712 {
713     LValue result = m_block->appendNew<AtomicValue>(m_proc, AtomicStrongCAS, origin(), width, expected, newValue, pointer.value(), 0, HeapRange(), HeapRange());
714     m_heaps->decorateMemory(pointer.heap(), result);
715     return result;
716 }
717
718 void Output::jump(LBasicBlock destination)
719 {
720     m_block->appendNewControlValue(m_proc, B3::Jump, origin(), B3::FrequentedBlock(destination));
721 }
722
723 void Output::branch(LValue condition, LBasicBlock taken, Weight takenWeight, LBasicBlock notTaken, Weight notTakenWeight)
724 {
725     m_block->appendNewControlValue(
726         m_proc, B3::Branch, origin(), condition,
727         FrequentedBlock(taken, takenWeight.frequencyClass()),
728         FrequentedBlock(notTaken, notTakenWeight.frequencyClass()));
729 }
730
731 void Output::check(LValue condition, WeightedTarget taken, Weight notTakenWeight)
732 {
733     LBasicBlock continuation = newBlock();
734     branch(condition, taken, WeightedTarget(continuation, notTakenWeight));
735     appendTo(continuation);
736 }
737
738 void Output::check(LValue condition, WeightedTarget taken)
739 {
740     check(condition, taken, taken.weight().inverse());
741 }
742
743 void Output::ret(LValue value)
744 {
745     m_block->appendNewControlValue(m_proc, B3::Return, origin(), value);
746 }
747
748 void Output::unreachable()
749 {
750     m_block->appendNewControlValue(m_proc, B3::Oops, origin());
751 }
752
753 void Output::appendSuccessor(WeightedTarget target)
754 {
755     m_block->appendSuccessor(target.frequentedBlock());
756 }
757
758 CheckValue* Output::speculate(LValue value)
759 {
760     return m_block->appendNew<B3::CheckValue>(m_proc, B3::Check, origin(), value);
761 }
762
763 CheckValue* Output::speculateAdd(LValue left, LValue right)
764 {
765     return m_block->appendNew<B3::CheckValue>(m_proc, B3::CheckAdd, origin(), left, right);
766 }
767
768 CheckValue* Output::speculateSub(LValue left, LValue right)
769 {
770     return m_block->appendNew<B3::CheckValue>(m_proc, B3::CheckSub, origin(), left, right);
771 }
772
773 CheckValue* Output::speculateMul(LValue left, LValue right)
774 {
775     return m_block->appendNew<B3::CheckValue>(m_proc, B3::CheckMul, origin(), left, right);
776 }
777
778 PatchpointValue* Output::patchpoint(LType type)
779 {
780     return m_block->appendNew<B3::PatchpointValue>(m_proc, type, origin());
781 }
782
783 void Output::trap()
784 {
785     m_block->appendNewControlValue(m_proc, B3::Oops, origin());
786 }
787
788 ValueFromBlock Output::anchor(LValue value)
789 {
790     B3::UpsilonValue* upsilon = m_block->appendNew<B3::UpsilonValue>(m_proc, origin(), value);
791     return ValueFromBlock(upsilon, m_block);
792 }
793
794 LValue Output::bitCast(LValue value, LType type)
795 {
796     ASSERT_UNUSED(type, type == Int64 || type == Double);
797     return m_block->appendNew<B3::Value>(m_proc, B3::BitwiseCast, origin(), value);
798 }
799
800 LValue Output::fround(LValue doubleValue)
801 {
802     return floatToDouble(doubleToFloat(doubleValue));
803 }
804
805 LValue Output::load(TypedPointer pointer, LoadType type)
806 {
807     switch (type) {
808     case Load8SignExt32:
809         return load8SignExt32(pointer);
810     case Load8ZeroExt32:
811         return load8ZeroExt32(pointer);
812     case Load16SignExt32:
813         return load8SignExt32(pointer);
814     case Load16ZeroExt32:
815         return load8ZeroExt32(pointer);
816     case Load32:
817         return load32(pointer);
818     case Load64:
819         return load64(pointer);
820     case LoadPtr:
821         return loadPtr(pointer);
822     case LoadFloat:
823         return loadFloat(pointer);
824     case LoadDouble:
825         return loadDouble(pointer);
826     }
827     RELEASE_ASSERT_NOT_REACHED();
828     return nullptr;
829 }
830
831 LValue Output::store(LValue value, TypedPointer pointer, StoreType type)
832 {
833     switch (type) {
834     case Store32As8:
835         return store32As8(value, pointer);
836     case Store32As16:
837         return store32As16(value, pointer);
838     case Store32:
839         return store32(value, pointer);
840     case Store64:
841         return store64(value, pointer);
842     case StorePtr:
843         return storePtr(value, pointer);
844     case StoreFloat:
845         return storeFloat(value, pointer);
846     case StoreDouble:
847         return storeDouble(value, pointer);
848     }
849     RELEASE_ASSERT_NOT_REACHED();
850     return nullptr;
851 }
852
853 TypedPointer Output::absolute(const void* address)
854 {
855     return TypedPointer(m_heaps->absolute[address], constIntPtr(address));
856 }
857
858 void Output::incrementSuperSamplerCount()
859 {
860     TypedPointer counter = absolute(bitwise_cast<void*>(&g_superSamplerCount));
861     store32(add(load32(counter), int32One), counter);
862 }
863
864 void Output::decrementSuperSamplerCount()
865 {
866     TypedPointer counter = absolute(bitwise_cast<void*>(&g_superSamplerCount));
867     store32(sub(load32(counter), int32One), counter);
868 }
869
870 void Output::addIncomingToPhi(LValue phi, ValueFromBlock value)
871 {
872     if (value)
873         value.value()->as<B3::UpsilonValue>()->setPhi(phi);
874 }
875
876 void Output::entrySwitch(const Vector<LBasicBlock>& cases)
877 {
878     RELEASE_ASSERT(cases.size() == m_proc.numEntrypoints());
879     m_block->appendNew<Value>(m_proc, EntrySwitch, origin());
880     for (LBasicBlock block : cases)
881         m_block->appendSuccessor(FrequentedBlock(block));
882 }
883
884 } } // namespace JSC::FTL
885
886 #endif // ENABLE(FTL_JIT)
887