[JSC] Add SameValue DFG node
[WebKit-https.git] / Source / JavaScriptCore / assembler / MacroAssembler.h
1 /*
2  * Copyright (C) 2008-2018 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 #pragma once
27
28 #if ENABLE(ASSEMBLER)
29
30 #include "JSCJSValue.h"
31
32 #if CPU(ARM_THUMB2)
33 #define TARGET_ASSEMBLER ARMv7Assembler
34 #define TARGET_MACROASSEMBLER MacroAssemblerARMv7
35 #include "MacroAssemblerARMv7.h"
36 namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; };
37
38 #elif CPU(ARM64E) && __has_include(<WebKitAdditions/MacroAssemblerARM64E.h>)
39 #define TARGET_ASSEMBLER ARM64EAssembler
40 #define TARGET_MACROASSEMBLER MacroAssemblerARM64E
41 #include <WebKitAdditions/MacroAssemblerARM64E.h>
42
43 #elif CPU(ARM64)
44 #define TARGET_ASSEMBLER ARM64Assembler
45 #define TARGET_MACROASSEMBLER MacroAssemblerARM64
46 #include "MacroAssemblerARM64.h"
47
48 #elif CPU(ARM_TRADITIONAL)
49 #define TARGET_ASSEMBLER ARMAssembler
50 #define TARGET_MACROASSEMBLER MacroAssemblerARM
51 #include "MacroAssemblerARM.h"
52
53 #elif CPU(MIPS)
54 #define TARGET_ASSEMBLER MIPSAssembler
55 #define TARGET_MACROASSEMBLER MacroAssemblerMIPS
56 #include "MacroAssemblerMIPS.h"
57
58 #elif CPU(X86)
59 #define TARGET_ASSEMBLER X86Assembler
60 #define TARGET_MACROASSEMBLER MacroAssemblerX86
61 #include "MacroAssemblerX86.h"
62
63 #elif CPU(X86_64)
64 #define TARGET_ASSEMBLER X86Assembler
65 #define TARGET_MACROASSEMBLER MacroAssemblerX86_64
66 #include "MacroAssemblerX86_64.h"
67
68 #else
69 #error "The MacroAssembler is not supported on this platform."
70 #endif
71
72 #include "MacroAssemblerHelpers.h"
73
74 namespace WTF {
75
76 template<typename FunctionType>
77 class ScopedLambda;
78
79 } // namespace WTF
80
81 namespace JSC {
82
83 #if ENABLE(MASM_PROBE)
84 namespace Probe {
85
86 class Context;
87 typedef void (*Function)(Context&);
88
89 } // namespace Probe
90 #endif // ENABLE(MASM_PROBE)
91
92 namespace Printer {
93
94 struct PrintRecord;
95 typedef Vector<PrintRecord> PrintRecordList;
96
97 } // namespace Printer
98
99 using MacroAssemblerBase = TARGET_MACROASSEMBLER;
100
101 class MacroAssembler : public MacroAssemblerBase {
102 public:
103
104     static constexpr RegisterID nextRegister(RegisterID reg)
105     {
106         return static_cast<RegisterID>(reg + 1);
107     }
108     
109     static constexpr FPRegisterID nextFPRegister(FPRegisterID reg)
110     {
111         return static_cast<FPRegisterID>(reg + 1);
112     }
113     
114     static constexpr unsigned registerIndex(RegisterID reg)
115     {
116         return reg - firstRegister();
117     }
118     
119     static constexpr unsigned fpRegisterIndex(FPRegisterID reg)
120     {
121         return reg - firstFPRegister();
122     }
123     
124     static constexpr unsigned registerIndex(FPRegisterID reg)
125     {
126         return fpRegisterIndex(reg) + numberOfRegisters();
127     }
128     
129     static constexpr unsigned totalNumberOfRegisters()
130     {
131         return numberOfRegisters() + numberOfFPRegisters();
132     }
133
134     using MacroAssemblerBase::pop;
135     using MacroAssemblerBase::jump;
136     using MacroAssemblerBase::branch32;
137     using MacroAssemblerBase::compare32;
138     using MacroAssemblerBase::move;
139     using MacroAssemblerBase::moveDouble;
140     using MacroAssemblerBase::add32;
141     using MacroAssemblerBase::mul32;
142     using MacroAssemblerBase::and32;
143     using MacroAssemblerBase::branchAdd32;
144     using MacroAssemblerBase::branchMul32;
145 #if CPU(ARM64) || CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL) || CPU(X86_64) || CPU(MIPS)
146     using MacroAssemblerBase::branchPtr;
147 #endif
148     using MacroAssemblerBase::branchSub32;
149     using MacroAssemblerBase::lshift32;
150     using MacroAssemblerBase::or32;
151     using MacroAssemblerBase::rshift32;
152     using MacroAssemblerBase::store32;
153     using MacroAssemblerBase::sub32;
154     using MacroAssemblerBase::urshift32;
155     using MacroAssemblerBase::xor32;
156
157     static bool isPtrAlignedAddressOffset(ptrdiff_t value)
158     {
159         return value == static_cast<int32_t>(value);
160     }
161
162     static const double twoToThe32; // This is super useful for some double code.
163
164     // Utilities used by the DFG JIT.
165     using AbstractMacroAssemblerBase::invert;
166     using MacroAssemblerBase::invert;
167     
168     static DoubleCondition invert(DoubleCondition cond)
169     {
170         switch (cond) {
171         case DoubleEqual:
172             return DoubleNotEqualOrUnordered;
173         case DoubleNotEqual:
174             return DoubleEqualOrUnordered;
175         case DoubleGreaterThan:
176             return DoubleLessThanOrEqualOrUnordered;
177         case DoubleGreaterThanOrEqual:
178             return DoubleLessThanOrUnordered;
179         case DoubleLessThan:
180             return DoubleGreaterThanOrEqualOrUnordered;
181         case DoubleLessThanOrEqual:
182             return DoubleGreaterThanOrUnordered;
183         case DoubleEqualOrUnordered:
184             return DoubleNotEqual;
185         case DoubleNotEqualOrUnordered:
186             return DoubleEqual;
187         case DoubleGreaterThanOrUnordered:
188             return DoubleLessThanOrEqual;
189         case DoubleGreaterThanOrEqualOrUnordered:
190             return DoubleLessThan;
191         case DoubleLessThanOrUnordered:
192             return DoubleGreaterThanOrEqual;
193         case DoubleLessThanOrEqualOrUnordered:
194             return DoubleGreaterThan;
195         }
196         RELEASE_ASSERT_NOT_REACHED();
197         return DoubleEqual; // make compiler happy
198     }
199     
200     static bool isInvertible(ResultCondition cond)
201     {
202         switch (cond) {
203         case Zero:
204         case NonZero:
205         case Signed:
206         case PositiveOrZero:
207             return true;
208         default:
209             return false;
210         }
211     }
212     
213     static ResultCondition invert(ResultCondition cond)
214     {
215         switch (cond) {
216         case Zero:
217             return NonZero;
218         case NonZero:
219             return Zero;
220         case Signed:
221             return PositiveOrZero;
222         case PositiveOrZero:
223             return Signed;
224         default:
225             RELEASE_ASSERT_NOT_REACHED();
226             return Zero; // Make compiler happy for release builds.
227         }
228     }
229
230     static RelationalCondition flip(RelationalCondition cond)
231     {
232         switch (cond) {
233         case Equal:
234         case NotEqual:
235             return cond;
236         case Above:
237             return Below;
238         case AboveOrEqual:
239             return BelowOrEqual;
240         case Below:
241             return Above;
242         case BelowOrEqual:
243             return AboveOrEqual;
244         case GreaterThan:
245             return LessThan;
246         case GreaterThanOrEqual:
247             return LessThanOrEqual;
248         case LessThan:
249             return GreaterThan;
250         case LessThanOrEqual:
251             return GreaterThanOrEqual;
252         }
253
254         RELEASE_ASSERT_NOT_REACHED();
255         return Equal;
256     }
257
258     static bool isSigned(RelationalCondition cond)
259     {
260         return MacroAssemblerHelpers::isSigned<MacroAssembler>(cond);
261     }
262
263     static bool isUnsigned(RelationalCondition cond)
264     {
265         return MacroAssemblerHelpers::isUnsigned<MacroAssembler>(cond);
266     }
267
268     static bool isSigned(ResultCondition cond)
269     {
270         return MacroAssemblerHelpers::isSigned<MacroAssembler>(cond);
271     }
272
273     static bool isUnsigned(ResultCondition cond)
274     {
275         return MacroAssemblerHelpers::isUnsigned<MacroAssembler>(cond);
276     }
277
278     // Platform agnostic convenience functions,
279     // described in terms of other macro assembly methods.
280     void pop()
281     {
282         addPtr(TrustedImm32(sizeof(void*)), stackPointerRegister);
283     }
284     
285     void peek(RegisterID dest, int index = 0)
286     {
287         loadPtr(Address(stackPointerRegister, (index * sizeof(void*))), dest);
288     }
289
290     Address addressForPoke(int index)
291     {
292         return Address(stackPointerRegister, (index * sizeof(void*)));
293     }
294     
295     void poke(RegisterID src, int index = 0)
296     {
297         storePtr(src, addressForPoke(index));
298     }
299
300     void poke(TrustedImm32 value, int index = 0)
301     {
302         store32(value, addressForPoke(index));
303     }
304
305     void poke(TrustedImmPtr imm, int index = 0)
306     {
307         storePtr(imm, addressForPoke(index));
308     }
309
310     void poke(FPRegisterID src, int index = 0)
311     {
312         storeDouble(src, addressForPoke(index));
313     }
314
315 #if !CPU(ARM64)
316     void pushToSave(RegisterID src)
317     {
318         push(src);
319     }
320     void pushToSaveImmediateWithoutTouchingRegisters(TrustedImm32 imm)
321     {
322         push(imm);
323     }
324     void popToRestore(RegisterID dest)
325     {
326         pop(dest);
327     }
328     void pushToSave(FPRegisterID src)
329     {
330         subPtr(TrustedImm32(sizeof(double)), stackPointerRegister);
331         storeDouble(src, stackPointerRegister);
332     }
333     void popToRestore(FPRegisterID dest)
334     {
335         loadDouble(stackPointerRegister, dest);
336         addPtr(TrustedImm32(sizeof(double)), stackPointerRegister);
337     }
338     
339     static ptrdiff_t pushToSaveByteOffset() { return sizeof(void*); }
340 #endif // !CPU(ARM64)
341
342 #if CPU(X86_64) || CPU(ARM64)
343     void peek64(RegisterID dest, int index = 0)
344     {
345         load64(Address(stackPointerRegister, (index * sizeof(void*))), dest);
346     }
347
348     void poke(TrustedImm64 value, int index = 0)
349     {
350         store64(value, addressForPoke(index));
351     }
352
353     void poke64(RegisterID src, int index = 0)
354     {
355         store64(src, addressForPoke(index));
356     }
357 #endif
358
359     // Immediate shifts only have 5 controllable bits
360     // so we'll consider them safe for now.
361     TrustedImm32 trustedImm32ForShift(Imm32 imm)
362     {
363         return TrustedImm32(imm.asTrustedImm32().m_value & 31);
364     }
365
366     // Backwards banches, these are currently all implemented using existing forwards branch mechanisms.
367     void branchPtr(RelationalCondition cond, RegisterID op1, TrustedImmPtr imm, Label target)
368     {
369         branchPtr(cond, op1, imm).linkTo(target, this);
370     }
371     void branchPtr(RelationalCondition cond, RegisterID op1, ImmPtr imm, Label target)
372     {
373         branchPtr(cond, op1, imm).linkTo(target, this);
374     }
375
376     Jump branch32(RelationalCondition cond, RegisterID left, AbsoluteAddress right)
377     {
378         return branch32(flip(cond), right, left);
379     }
380
381     void branch32(RelationalCondition cond, RegisterID op1, RegisterID op2, Label target)
382     {
383         branch32(cond, op1, op2).linkTo(target, this);
384     }
385
386     void branch32(RelationalCondition cond, RegisterID op1, TrustedImm32 imm, Label target)
387     {
388         branch32(cond, op1, imm).linkTo(target, this);
389     }
390     
391     void branch32(RelationalCondition cond, RegisterID op1, Imm32 imm, Label target)
392     {
393         branch32(cond, op1, imm).linkTo(target, this);
394     }
395
396     void branch32(RelationalCondition cond, RegisterID left, Address right, Label target)
397     {
398         branch32(cond, left, right).linkTo(target, this);
399     }
400
401     Jump branch32(RelationalCondition cond, TrustedImm32 left, RegisterID right)
402     {
403         return branch32(commute(cond), right, left);
404     }
405
406     Jump branch32(RelationalCondition cond, Imm32 left, RegisterID right)
407     {
408         return branch32(commute(cond), right, left);
409     }
410
411     void compare32(RelationalCondition cond, Imm32 left, RegisterID right, RegisterID dest)
412     {
413         compare32(commute(cond), right, left, dest);
414     }
415
416     void branchTestPtr(ResultCondition cond, RegisterID reg, Label target)
417     {
418         branchTestPtr(cond, reg).linkTo(target, this);
419     }
420
421 #if !CPU(ARM_THUMB2) && !CPU(ARM64)
422     PatchableJump patchableBranchPtr(RelationalCondition cond, Address left, TrustedImmPtr right = TrustedImmPtr(nullptr))
423     {
424         return PatchableJump(branchPtr(cond, left, right));
425     }
426     
427     PatchableJump patchableBranchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(nullptr))
428     {
429         return PatchableJump(branchPtrWithPatch(cond, left, dataLabel, initialRightValue));
430     }
431
432     PatchableJump patchableBranch32WithPatch(RelationalCondition cond, Address left, DataLabel32& dataLabel, TrustedImm32 initialRightValue = TrustedImm32(0))
433     {
434         return PatchableJump(branch32WithPatch(cond, left, dataLabel, initialRightValue));
435     }
436
437 #if !CPU(ARM_TRADITIONAL)
438     PatchableJump patchableJump()
439     {
440         return PatchableJump(jump());
441     }
442
443     PatchableJump patchableBranchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
444     {
445         return PatchableJump(branchTest32(cond, reg, mask));
446     }
447
448     PatchableJump patchableBranch32(RelationalCondition cond, RegisterID reg, TrustedImm32 imm)
449     {
450         return PatchableJump(branch32(cond, reg, imm));
451     }
452
453     PatchableJump patchableBranch32(RelationalCondition cond, Address address, TrustedImm32 imm)
454     {
455         return PatchableJump(branch32(cond, address, imm));
456     }
457 #endif
458 #endif
459
460     void jump(Label target)
461     {
462         jump().linkTo(target, this);
463     }
464
465     // Commute a relational condition, returns a new condition that will produce
466     // the same results given the same inputs but with their positions exchanged.
467     static RelationalCondition commute(RelationalCondition condition)
468     {
469         switch (condition) {
470         case Above:
471             return Below;
472         case AboveOrEqual:
473             return BelowOrEqual;
474         case Below:
475             return Above;
476         case BelowOrEqual:
477             return AboveOrEqual;
478         case GreaterThan:
479             return LessThan;
480         case GreaterThanOrEqual:
481             return LessThanOrEqual;
482         case LessThan:
483             return GreaterThan;
484         case LessThanOrEqual:
485             return GreaterThanOrEqual;
486         default:
487             break;
488         }
489
490         ASSERT(condition == Equal || condition == NotEqual);
491         return condition;
492     }
493
494     void oops()
495     {
496         abortWithReason(B3Oops);
497     }
498
499     // B3 has additional pseudo-opcodes for returning, when it wants to signal that the return
500     // consumes some register in some way.
501     void retVoid() { ret(); }
502     void ret32(RegisterID) { ret(); }
503     void ret64(RegisterID) { ret(); }
504     void retFloat(FPRegisterID) { ret(); }
505     void retDouble(FPRegisterID) { ret(); }
506
507     static const unsigned BlindingModulus = 64;
508     bool shouldConsiderBlinding()
509     {
510         return !(random() & (BlindingModulus - 1));
511     }
512
513     void move(Address src, Address dest, RegisterID scratch)
514     {
515         loadPtr(src, scratch);
516         storePtr(scratch, dest);
517     }
518     
519     void move32(Address src, Address dest, RegisterID scratch)
520     {
521         load32(src, scratch);
522         store32(scratch, dest);
523     }
524     
525     void moveFloat(Address src, Address dest, FPRegisterID scratch)
526     {
527         loadFloat(src, scratch);
528         storeFloat(scratch, dest);
529     }
530
531     // Overload mostly for use in templates.
532     void move(FPRegisterID src, FPRegisterID dest)
533     {
534         moveDouble(src, dest);
535     }
536
537     void moveDouble(Address src, Address dest, FPRegisterID scratch)
538     {
539         loadDouble(src, scratch);
540         storeDouble(scratch, dest);
541     }
542
543     // Ptr methods
544     // On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents.
545     // FIXME: should this use a test for 32-bitness instead of this specific exception?
546 #if !CPU(X86_64) && !CPU(ARM64)
547     void addPtr(Address src, RegisterID dest)
548     {
549         add32(src, dest);
550     }
551
552     void addPtr(AbsoluteAddress src, RegisterID dest)
553     {
554         add32(src, dest);
555     }
556
557     void addPtr(RegisterID src, RegisterID dest)
558     {
559         add32(src, dest);
560     }
561
562     void addPtr(RegisterID left, RegisterID right, RegisterID dest)
563     {
564         add32(left, right, dest);
565     }
566
567     void addPtr(TrustedImm32 imm, RegisterID srcDest)
568     {
569         add32(imm, srcDest);
570     }
571
572     void addPtr(TrustedImmPtr imm, RegisterID dest)
573     {
574         add32(TrustedImm32(imm), dest);
575     }
576
577     void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest)
578     {
579         add32(imm, src, dest);
580     }
581
582     void addPtr(TrustedImm32 imm, AbsoluteAddress address)
583     {
584         add32(imm, address);
585     }
586     
587     void andPtr(RegisterID src, RegisterID dest)
588     {
589         and32(src, dest);
590     }
591
592     void andPtr(TrustedImm32 imm, RegisterID srcDest)
593     {
594         and32(imm, srcDest);
595     }
596
597     void andPtr(TrustedImmPtr imm, RegisterID srcDest)
598     {
599         and32(TrustedImm32(imm), srcDest);
600     }
601
602     void lshiftPtr(Imm32 imm, RegisterID srcDest)
603     {
604         lshift32(trustedImm32ForShift(imm), srcDest);
605     }
606     
607     void lshiftPtr(TrustedImm32 imm, RegisterID srcDest)
608     {
609         lshift32(imm, srcDest);
610     }
611     
612     void rshiftPtr(Imm32 imm, RegisterID srcDest)
613     {
614         rshift32(trustedImm32ForShift(imm), srcDest);
615     }
616
617     void rshiftPtr(TrustedImm32 imm, RegisterID srcDest)
618     {
619         rshift32(imm, srcDest);
620     }
621
622     void urshiftPtr(Imm32 imm, RegisterID srcDest)
623     {
624         urshift32(trustedImm32ForShift(imm), srcDest);
625     }
626
627     void urshiftPtr(RegisterID shiftAmmount, RegisterID srcDest)
628     {
629         urshift32(shiftAmmount, srcDest);
630     }
631
632     void negPtr(RegisterID dest)
633     {
634         neg32(dest);
635     }
636
637     void negPtr(RegisterID src, RegisterID dest)
638     {
639         neg32(src, dest);
640     }
641
642     void orPtr(RegisterID src, RegisterID dest)
643     {
644         or32(src, dest);
645     }
646
647     void orPtr(RegisterID op1, RegisterID op2, RegisterID dest)
648     {
649         or32(op1, op2, dest);
650     }
651
652     void orPtr(TrustedImmPtr imm, RegisterID dest)
653     {
654         or32(TrustedImm32(imm), dest);
655     }
656
657     void orPtr(TrustedImm32 imm, RegisterID dest)
658     {
659         or32(imm, dest);
660     }
661
662     void subPtr(RegisterID src, RegisterID dest)
663     {
664         sub32(src, dest);
665     }
666     
667     void subPtr(TrustedImm32 imm, RegisterID dest)
668     {
669         sub32(imm, dest);
670     }
671     
672     void subPtr(TrustedImmPtr imm, RegisterID dest)
673     {
674         sub32(TrustedImm32(imm), dest);
675     }
676
677     void xorPtr(RegisterID src, RegisterID dest)
678     {
679         xor32(src, dest);
680     }
681
682     void xorPtr(TrustedImm32 imm, RegisterID srcDest)
683     {
684         xor32(imm, srcDest);
685     }
686
687     void xorPtr(TrustedImmPtr imm, RegisterID srcDest)
688     {
689         xor32(TrustedImm32(imm), srcDest);
690     }
691
692     void xorPtr(Address src, RegisterID dest)
693     {
694         xor32(src, dest);
695     }
696
697     void loadPtr(ImplicitAddress address, RegisterID dest)
698     {
699         load32(address, dest);
700     }
701
702     void loadPtr(BaseIndex address, RegisterID dest)
703     {
704         load32(address, dest);
705     }
706
707     void loadPtr(const void* address, RegisterID dest)
708     {
709         load32(address, dest);
710     }
711
712 #if ENABLE(FAST_TLS_JIT)
713     void loadFromTLSPtr(uint32_t offset, RegisterID dst)
714     {
715         loadFromTLS32(offset, dst);
716     }
717
718     void storeToTLSPtr(RegisterID src, uint32_t offset)
719     {
720         storeToTLS32(src, offset);
721     }
722 #endif
723
724     DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
725     {
726         return load32WithAddressOffsetPatch(address, dest);
727     }
728     
729     DataLabelCompact loadPtrWithCompactAddressOffsetPatch(Address address, RegisterID dest)
730     {
731         return load32WithCompactAddressOffsetPatch(address, dest);
732     }
733
734     void move(ImmPtr imm, RegisterID dest)
735     {
736         move(Imm32(imm.asTrustedImmPtr()), dest);
737     }
738     
739     void comparePtr(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
740     {
741         compare32(cond, left, right, dest);
742     }
743
744     void comparePtr(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
745     {
746         compare32(cond, left, right, dest);
747     }
748     
749     void storePtr(RegisterID src, ImplicitAddress address)
750     {
751         store32(src, address);
752     }
753
754     void storePtr(RegisterID src, BaseIndex address)
755     {
756         store32(src, address);
757     }
758
759     void storePtr(RegisterID src, void* address)
760     {
761         store32(src, address);
762     }
763
764     void storePtr(TrustedImmPtr imm, ImplicitAddress address)
765     {
766         store32(TrustedImm32(imm), address);
767     }
768     
769     void storePtr(ImmPtr imm, Address address)
770     {
771         store32(Imm32(imm.asTrustedImmPtr()), address);
772     }
773
774     void storePtr(TrustedImmPtr imm, void* address)
775     {
776         store32(TrustedImm32(imm), address);
777     }
778
779     void storePtr(TrustedImm32 imm, ImplicitAddress address)
780     {
781         store32(imm, address);
782     }
783
784     void storePtr(TrustedImmPtr imm, BaseIndex address)
785     {
786         store32(TrustedImm32(imm), address);
787     }
788
789     DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
790     {
791         return store32WithAddressOffsetPatch(src, address);
792     }
793
794     Jump branchPtr(RelationalCondition cond, RegisterID left, RegisterID right)
795     {
796         return branch32(cond, left, right);
797     }
798
799     Jump branchPtr(RelationalCondition cond, RegisterID left, TrustedImmPtr right)
800     {
801         return branch32(cond, left, TrustedImm32(right));
802     }
803     
804     Jump branchPtr(RelationalCondition cond, RegisterID left, ImmPtr right)
805     {
806         return branch32(cond, left, Imm32(right.asTrustedImmPtr()));
807     }
808
809     Jump branchPtr(RelationalCondition cond, RegisterID left, Address right)
810     {
811         return branch32(cond, left, right);
812     }
813
814     Jump branchPtr(RelationalCondition cond, Address left, RegisterID right)
815     {
816         return branch32(cond, left, right);
817     }
818
819     Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, RegisterID right)
820     {
821         return branch32(cond, left, right);
822     }
823
824     Jump branchPtr(RelationalCondition cond, Address left, TrustedImmPtr right)
825     {
826         return branch32(cond, left, TrustedImm32(right));
827     }
828     
829     Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, TrustedImmPtr right)
830     {
831         return branch32(cond, left, TrustedImm32(right));
832     }
833
834     Jump branchSubPtr(ResultCondition cond, RegisterID src, RegisterID dest)
835     {
836         return branchSub32(cond, src, dest);
837     }
838
839     Jump branchTestPtr(ResultCondition cond, RegisterID reg, RegisterID mask)
840     {
841         return branchTest32(cond, reg, mask);
842     }
843
844     Jump branchTestPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
845     {
846         return branchTest32(cond, reg, mask);
847     }
848
849     Jump branchTestPtr(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
850     {
851         return branchTest32(cond, address, mask);
852     }
853
854     Jump branchTestPtr(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
855     {
856         return branchTest32(cond, address, mask);
857     }
858
859     Jump branchAddPtr(ResultCondition cond, RegisterID src, RegisterID dest)
860     {
861         return branchAdd32(cond, src, dest);
862     }
863
864     Jump branchSubPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
865     {
866         return branchSub32(cond, imm, dest);
867     }
868     using MacroAssemblerBase::branchTest8;
869     Jump branchTest8(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1))
870     {
871         return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask);
872     }
873
874 #else // !CPU(X86_64) && !CPU(ARM64)
875
876     void addPtr(RegisterID src, RegisterID dest)
877     {
878         add64(src, dest);
879     }
880
881     void addPtr(RegisterID left, RegisterID right, RegisterID dest)
882     {
883         add64(left, right, dest);
884     }
885     
886     void addPtr(Address src, RegisterID dest)
887     {
888         add64(src, dest);
889     }
890
891     void addPtr(TrustedImm32 imm, RegisterID srcDest)
892     {
893         add64(imm, srcDest);
894     }
895
896     void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest)
897     {
898         add64(imm, src, dest);
899     }
900
901     void addPtr(TrustedImm32 imm, Address address)
902     {
903         add64(imm, address);
904     }
905
906     void addPtr(AbsoluteAddress src, RegisterID dest)
907     {
908         add64(src, dest);
909     }
910
911     void addPtr(TrustedImmPtr imm, RegisterID dest)
912     {
913         add64(TrustedImm64(imm), dest);
914     }
915
916     void addPtr(TrustedImm32 imm, AbsoluteAddress address)
917     {
918         add64(imm, address);
919     }
920
921     void andPtr(RegisterID src, RegisterID dest)
922     {
923         and64(src, dest);
924     }
925
926     void andPtr(TrustedImm32 imm, RegisterID srcDest)
927     {
928         and64(imm, srcDest);
929     }
930     
931     void andPtr(TrustedImmPtr imm, RegisterID srcDest)
932     {
933         and64(imm, srcDest);
934     }
935     
936     void lshiftPtr(Imm32 imm, RegisterID srcDest)
937     {
938         lshift64(trustedImm32ForShift(imm), srcDest);
939     }
940
941     void lshiftPtr(TrustedImm32 imm, RegisterID srcDest)
942     {
943         lshift64(imm, srcDest);
944     }
945
946     void rshiftPtr(Imm32 imm, RegisterID srcDest)
947     {
948         rshift64(trustedImm32ForShift(imm), srcDest);
949     }
950
951     void rshiftPtr(TrustedImm32 imm, RegisterID srcDest)
952     {
953         rshift64(imm, srcDest);
954     }
955
956     void urshiftPtr(Imm32 imm, RegisterID srcDest)
957     {
958         urshift64(trustedImm32ForShift(imm), srcDest);
959     }
960
961     void urshiftPtr(RegisterID shiftAmmount, RegisterID srcDest)
962     {
963         urshift64(shiftAmmount, srcDest);
964     }
965
966     void negPtr(RegisterID dest)
967     {
968         neg64(dest);
969     }
970
971     void negPtr(RegisterID src, RegisterID dest)
972     {
973         neg64(src, dest);
974     }
975
976     void orPtr(RegisterID src, RegisterID dest)
977     {
978         or64(src, dest);
979     }
980
981     void orPtr(TrustedImm32 imm, RegisterID dest)
982     {
983         or64(imm, dest);
984     }
985
986     void orPtr(TrustedImmPtr imm, RegisterID dest)
987     {
988         or64(TrustedImm64(imm), dest);
989     }
990
991     void orPtr(RegisterID op1, RegisterID op2, RegisterID dest)
992     {
993         or64(op1, op2, dest);
994     }
995
996     void orPtr(TrustedImm32 imm, RegisterID src, RegisterID dest)
997     {
998         or64(imm, src, dest);
999     }
1000     
1001     void rotateRightPtr(TrustedImm32 imm, RegisterID srcDst)
1002     {
1003         rotateRight64(imm, srcDst);
1004     }
1005
1006     void subPtr(RegisterID src, RegisterID dest)
1007     {
1008         sub64(src, dest);
1009     }
1010     
1011     void subPtr(TrustedImm32 imm, RegisterID dest)
1012     {
1013         sub64(imm, dest);
1014     }
1015     
1016     void subPtr(TrustedImmPtr imm, RegisterID dest)
1017     {
1018         sub64(TrustedImm64(imm), dest);
1019     }
1020
1021     void xorPtr(RegisterID src, RegisterID dest)
1022     {
1023         xor64(src, dest);
1024     }
1025     
1026     void xorPtr(Address src, RegisterID dest)
1027     {
1028         xor64(src, dest);
1029     }
1030     
1031     void xorPtr(RegisterID src, Address dest)
1032     {
1033         xor64(src, dest);
1034     }
1035
1036     void xorPtr(TrustedImm32 imm, RegisterID srcDest)
1037     {
1038         xor64(imm, srcDest);
1039     }
1040
1041     // FIXME: Look into making the need for a scratch register explicit, or providing the option to specify a scratch register.
1042     void xorPtr(TrustedImmPtr imm, RegisterID srcDest)
1043     {
1044         xor64(TrustedImm64(imm), srcDest);
1045     }
1046
1047     void loadPtr(ImplicitAddress address, RegisterID dest)
1048     {
1049         load64(address, dest);
1050     }
1051
1052     void loadPtr(BaseIndex address, RegisterID dest)
1053     {
1054         load64(address, dest);
1055     }
1056
1057     void loadPtr(const void* address, RegisterID dest)
1058     {
1059         load64(address, dest);
1060     }
1061
1062 #if ENABLE(FAST_TLS_JIT)
1063     void loadFromTLSPtr(uint32_t offset, RegisterID dst)
1064     {
1065         loadFromTLS64(offset, dst);
1066     }
1067     void storeToTLSPtr(RegisterID src, uint32_t offset)
1068     {
1069         storeToTLS64(src, offset);
1070     }
1071 #endif
1072
1073     DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
1074     {
1075         return load64WithAddressOffsetPatch(address, dest);
1076     }
1077     
1078     DataLabelCompact loadPtrWithCompactAddressOffsetPatch(Address address, RegisterID dest)
1079     {
1080         return load64WithCompactAddressOffsetPatch(address, dest);
1081     }
1082
1083     void storePtr(RegisterID src, ImplicitAddress address)
1084     {
1085         store64(src, address);
1086     }
1087
1088     void storePtr(RegisterID src, BaseIndex address)
1089     {
1090         store64(src, address);
1091     }
1092     
1093     void storePtr(RegisterID src, void* address)
1094     {
1095         store64(src, address);
1096     }
1097
1098     void storePtr(TrustedImmPtr imm, ImplicitAddress address)
1099     {
1100         store64(TrustedImm64(imm), address);
1101     }
1102
1103     void storePtr(TrustedImm32 imm, ImplicitAddress address)
1104     {
1105         store64(imm, address);
1106     }
1107
1108     void storePtr(TrustedImmPtr imm, BaseIndex address)
1109     {
1110         store64(TrustedImm64(imm), address);
1111     }
1112
1113     DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
1114     {
1115         return store64WithAddressOffsetPatch(src, address);
1116     }
1117
1118     void comparePtr(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
1119     {
1120         compare64(cond, left, right, dest);
1121     }
1122     
1123     void comparePtr(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
1124     {
1125         compare64(cond, left, right, dest);
1126     }
1127     
1128     void testPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest)
1129     {
1130         test64(cond, reg, mask, dest);
1131     }
1132
1133     void testPtr(ResultCondition cond, RegisterID reg, RegisterID mask, RegisterID dest)
1134     {
1135         test64(cond, reg, mask, dest);
1136     }
1137
1138     Jump branchPtr(RelationalCondition cond, RegisterID left, RegisterID right)
1139     {
1140         return branch64(cond, left, right);
1141     }
1142
1143     Jump branchPtr(RelationalCondition cond, RegisterID left, TrustedImmPtr right)
1144     {
1145         return branch64(cond, left, TrustedImm64(right));
1146     }
1147     
1148     Jump branchPtr(RelationalCondition cond, RegisterID left, Address right)
1149     {
1150         return branch64(cond, left, right);
1151     }
1152
1153     Jump branchPtr(RelationalCondition cond, Address left, RegisterID right)
1154     {
1155         return branch64(cond, left, right);
1156     }
1157
1158     Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, RegisterID right)
1159     {
1160         return branch64(cond, left, right);
1161     }
1162
1163     Jump branchPtr(RelationalCondition cond, Address left, TrustedImmPtr right)
1164     {
1165         return branch64(cond, left, TrustedImm64(right));
1166     }
1167
1168     Jump branchTestPtr(ResultCondition cond, RegisterID reg, RegisterID mask)
1169     {
1170         return branchTest64(cond, reg, mask);
1171     }
1172     
1173     Jump branchTestPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
1174     {
1175         return branchTest64(cond, reg, mask);
1176     }
1177
1178     Jump branchTestPtr(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
1179     {
1180         return branchTest64(cond, address, mask);
1181     }
1182
1183     Jump branchTestPtr(ResultCondition cond, Address address, RegisterID reg)
1184     {
1185         return branchTest64(cond, address, reg);
1186     }
1187
1188     Jump branchTestPtr(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
1189     {
1190         return branchTest64(cond, address, mask);
1191     }
1192
1193     Jump branchTestPtr(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
1194     {
1195         return branchTest64(cond, address, mask);
1196     }
1197
1198     Jump branchAddPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
1199     {
1200         return branchAdd64(cond, imm, dest);
1201     }
1202
1203     Jump branchAddPtr(ResultCondition cond, RegisterID src, RegisterID dest)
1204     {
1205         return branchAdd64(cond, src, dest);
1206     }
1207
1208     Jump branchSubPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
1209     {
1210         return branchSub64(cond, imm, dest);
1211     }
1212
1213     Jump branchSubPtr(ResultCondition cond, RegisterID src, RegisterID dest)
1214     {
1215         return branchSub64(cond, src, dest);
1216     }
1217
1218     Jump branchSubPtr(ResultCondition cond, RegisterID src1, TrustedImm32 src2, RegisterID dest)
1219     {
1220         return branchSub64(cond, src1, src2, dest);
1221     }
1222
1223     using MacroAssemblerBase::and64;
1224     using MacroAssemblerBase::convertInt32ToDouble;
1225     using MacroAssemblerBase::store64;
1226     bool shouldBlindDouble(double value)
1227     {
1228         // Don't trust NaN or +/-Infinity
1229         if (!std::isfinite(value))
1230             return shouldConsiderBlinding();
1231
1232         // Try to force normalisation, and check that there's no change
1233         // in the bit pattern
1234         if (bitwise_cast<uint64_t>(value * 1.0) != bitwise_cast<uint64_t>(value))
1235             return shouldConsiderBlinding();
1236
1237         value = fabs(value);
1238         // Only allow a limited set of fractional components
1239         double scaledValue = value * 8;
1240         if (scaledValue / 8 != value)
1241             return shouldConsiderBlinding();
1242         double frac = scaledValue - floor(scaledValue);
1243         if (frac != 0.0)
1244             return shouldConsiderBlinding();
1245
1246         return value > 0xff;
1247     }
1248     
1249     bool shouldBlindPointerForSpecificArch(uintptr_t value)
1250     {
1251         if (sizeof(void*) == 4)
1252             return shouldBlindForSpecificArch(static_cast<uint32_t>(value));
1253         return shouldBlindForSpecificArch(static_cast<uint64_t>(value));
1254     }
1255     
1256     bool shouldBlind(ImmPtr imm)
1257     {
1258         if (!canBlind())
1259             return false;
1260         
1261 #if ENABLE(FORCED_JIT_BLINDING)
1262         UNUSED_PARAM(imm);
1263         // Debug always blind all constants, if only so we know
1264         // if we've broken blinding during patch development.
1265         return true;
1266 #endif
1267
1268         // First off we'll special case common, "safe" values to avoid hurting
1269         // performance too much
1270         uintptr_t value = imm.asTrustedImmPtr().asIntptr();
1271         switch (value) {
1272         case 0xffff:
1273         case 0xffffff:
1274         case 0xffffffffL:
1275         case 0xffffffffffL:
1276         case 0xffffffffffffL:
1277         case 0xffffffffffffffL:
1278         case 0xffffffffffffffffL:
1279             return false;
1280         default: {
1281             if (value <= 0xff)
1282                 return false;
1283             if (~value <= 0xff)
1284                 return false;
1285         }
1286         }
1287
1288         if (!shouldConsiderBlinding())
1289             return false;
1290
1291         return shouldBlindPointerForSpecificArch(value);
1292     }
1293     
1294     struct RotatedImmPtr {
1295         RotatedImmPtr(uintptr_t v1, uint8_t v2)
1296             : value(v1)
1297             , rotation(v2)
1298         {
1299         }
1300         TrustedImmPtr value;
1301         TrustedImm32 rotation;
1302     };
1303     
1304     RotatedImmPtr rotationBlindConstant(ImmPtr imm)
1305     {
1306         uint8_t rotation = random() % (sizeof(void*) * 8);
1307         uintptr_t value = imm.asTrustedImmPtr().asIntptr();
1308         value = (value << rotation) | (value >> (sizeof(void*) * 8 - rotation));
1309         return RotatedImmPtr(value, rotation);
1310     }
1311     
1312     void loadRotationBlindedConstant(RotatedImmPtr constant, RegisterID dest)
1313     {
1314         move(constant.value, dest);
1315         rotateRightPtr(constant.rotation, dest);
1316     }
1317
1318     bool shouldBlind(Imm64 imm)
1319     {
1320 #if ENABLE(FORCED_JIT_BLINDING)
1321         UNUSED_PARAM(imm);
1322         // Debug always blind all constants, if only so we know
1323         // if we've broken blinding during patch development.
1324         return true;        
1325 #endif
1326
1327         // First off we'll special case common, "safe" values to avoid hurting
1328         // performance too much
1329         uint64_t value = imm.asTrustedImm64().m_value;
1330         switch (value) {
1331         case 0xffff:
1332         case 0xffffff:
1333         case 0xffffffffL:
1334         case 0xffffffffffL:
1335         case 0xffffffffffffL:
1336         case 0xffffffffffffffL:
1337         case 0xffffffffffffffffL:
1338             return false;
1339         default: {
1340             if (value <= 0xff)
1341                 return false;
1342             if (~value <= 0xff)
1343                 return false;
1344
1345             JSValue jsValue = JSValue::decode(value);
1346             if (jsValue.isInt32())
1347                 return shouldBlind(Imm32(jsValue.asInt32()));
1348             if (jsValue.isDouble() && !shouldBlindDouble(jsValue.asDouble()))
1349                 return false;
1350
1351             if (!shouldBlindDouble(bitwise_cast<double>(value)))
1352                 return false;
1353         }
1354         }
1355
1356         if (!shouldConsiderBlinding())
1357             return false;
1358
1359         return shouldBlindForSpecificArch(value);
1360     }
1361     
1362     struct RotatedImm64 {
1363         RotatedImm64(uint64_t v1, uint8_t v2)
1364             : value(v1)
1365             , rotation(v2)
1366         {
1367         }
1368         TrustedImm64 value;
1369         TrustedImm32 rotation;
1370     };
1371     
1372     RotatedImm64 rotationBlindConstant(Imm64 imm)
1373     {
1374         uint8_t rotation = random() % (sizeof(int64_t) * 8);
1375         uint64_t value = imm.asTrustedImm64().m_value;
1376         value = (value << rotation) | (value >> (sizeof(int64_t) * 8 - rotation));
1377         return RotatedImm64(value, rotation);
1378     }
1379     
1380     void loadRotationBlindedConstant(RotatedImm64 constant, RegisterID dest)
1381     {
1382         move(constant.value, dest);
1383         rotateRight64(constant.rotation, dest);
1384     }
1385
1386     void convertInt32ToDouble(Imm32 imm, FPRegisterID dest)
1387     {
1388         if (shouldBlind(imm) && haveScratchRegisterForBlinding()) {
1389             RegisterID scratchRegister = scratchRegisterForBlinding();
1390             loadXorBlindedConstant(xorBlindConstant(imm), scratchRegister);
1391             convertInt32ToDouble(scratchRegister, dest);
1392         } else
1393             convertInt32ToDouble(imm.asTrustedImm32(), dest);
1394     }
1395
1396     void move(ImmPtr imm, RegisterID dest)
1397     {
1398         if (shouldBlind(imm))
1399             loadRotationBlindedConstant(rotationBlindConstant(imm), dest);
1400         else
1401             move(imm.asTrustedImmPtr(), dest);
1402     }
1403
1404     void move(Imm64 imm, RegisterID dest)
1405     {
1406         if (shouldBlind(imm))
1407             loadRotationBlindedConstant(rotationBlindConstant(imm), dest);
1408         else
1409             move(imm.asTrustedImm64(), dest);
1410     }
1411
1412 #if CPU(X86_64) || CPU(ARM64)
1413     void moveDouble(Imm64 imm, FPRegisterID dest)
1414     {
1415         move(imm, scratchRegister());
1416         move64ToDouble(scratchRegister(), dest);
1417     }
1418 #endif
1419
1420     void and64(Imm32 imm, RegisterID dest)
1421     {
1422         if (shouldBlind(imm)) {
1423             BlindedImm32 key = andBlindedConstant(imm);
1424             and64(key.value1, dest);
1425             and64(key.value2, dest);
1426         } else
1427             and64(imm.asTrustedImm32(), dest);
1428     }
1429
1430     Jump branchPtr(RelationalCondition cond, RegisterID left, ImmPtr right)
1431     {
1432         if (shouldBlind(right) && haveScratchRegisterForBlinding()) {
1433             RegisterID scratchRegister = scratchRegisterForBlinding();
1434             loadRotationBlindedConstant(rotationBlindConstant(right), scratchRegister);
1435             return branchPtr(cond, left, scratchRegister);
1436         }
1437         return branchPtr(cond, left, right.asTrustedImmPtr());
1438     }
1439     
1440     void storePtr(ImmPtr imm, Address dest)
1441     {
1442         if (shouldBlind(imm) && haveScratchRegisterForBlinding()) {
1443             RegisterID scratchRegister = scratchRegisterForBlinding();
1444             loadRotationBlindedConstant(rotationBlindConstant(imm), scratchRegister);
1445             storePtr(scratchRegister, dest);
1446         } else
1447             storePtr(imm.asTrustedImmPtr(), dest);
1448     }
1449
1450     void store64(Imm64 imm, Address dest)
1451     {
1452         if (shouldBlind(imm) && haveScratchRegisterForBlinding()) {
1453             RegisterID scratchRegister = scratchRegisterForBlinding();
1454             loadRotationBlindedConstant(rotationBlindConstant(imm), scratchRegister);
1455             store64(scratchRegister, dest);
1456         } else
1457             store64(imm.asTrustedImm64(), dest);
1458     }
1459
1460 #endif // !CPU(X86_64)
1461
1462     // We should implement this the right way eventually, but for now, it's fine because it arises so
1463     // infrequently.
1464
1465 #if !CPU(X86) && !CPU(X86_64)
1466     void compareDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID dest)
1467     {
1468         move(TrustedImm32(0), dest);
1469         Jump falseCase = branchDouble(invert(cond), left, right);
1470         move(TrustedImm32(1), dest);
1471         falseCase.link(this);
1472     }
1473 #endif
1474
1475 #if ENABLE(B3_JIT)
1476     void compareFloat(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID dest)
1477     {
1478         move(TrustedImm32(0), dest);
1479         Jump falseCase = branchFloat(invert(cond), left, right);
1480         move(TrustedImm32(1), dest);
1481         falseCase.link(this);
1482     }
1483 #endif
1484
1485     void lea32(Address address, RegisterID dest)
1486     {
1487         add32(TrustedImm32(address.offset), address.base, dest);
1488     }
1489
1490 #if CPU(X86_64) || CPU(ARM64)
1491     void lea64(Address address, RegisterID dest)
1492     {
1493         add64(TrustedImm32(address.offset), address.base, dest);
1494     }
1495 #endif // CPU(X86_64) || CPU(ARM64)
1496
1497     bool shouldBlind(Imm32 imm)
1498     {
1499 #if ENABLE(FORCED_JIT_BLINDING)
1500         UNUSED_PARAM(imm);
1501         // Debug always blind all constants, if only so we know
1502         // if we've broken blinding during patch development.
1503         return true;
1504 #else // ENABLE(FORCED_JIT_BLINDING)
1505
1506         // First off we'll special case common, "safe" values to avoid hurting
1507         // performance too much
1508         uint32_t value = imm.asTrustedImm32().m_value;
1509         switch (value) {
1510         case 0xffff:
1511         case 0xffffff:
1512         case 0xffffffff:
1513             return false;
1514         default:
1515             if (value <= 0xff)
1516                 return false;
1517             if (~value <= 0xff)
1518                 return false;
1519         }
1520
1521         if (!shouldConsiderBlinding())
1522             return false;
1523
1524         return shouldBlindForSpecificArch(value);
1525 #endif // ENABLE(FORCED_JIT_BLINDING)
1526     }
1527
1528     struct BlindedImm32 {
1529         BlindedImm32(int32_t v1, int32_t v2)
1530             : value1(v1)
1531             , value2(v2)
1532         {
1533         }
1534         TrustedImm32 value1;
1535         TrustedImm32 value2;
1536     };
1537
1538     uint32_t keyForConstant(uint32_t value, uint32_t& mask)
1539     {
1540         uint32_t key = random();
1541         if (value <= 0xff)
1542             mask = 0xff;
1543         else if (value <= 0xffff)
1544             mask = 0xffff;
1545         else if (value <= 0xffffff)
1546             mask = 0xffffff;
1547         else
1548             mask = 0xffffffff;
1549         return key & mask;
1550     }
1551
1552     uint32_t keyForConstant(uint32_t value)
1553     {
1554         uint32_t mask = 0;
1555         return keyForConstant(value, mask);
1556     }
1557
1558     BlindedImm32 xorBlindConstant(Imm32 imm)
1559     {
1560         uint32_t baseValue = imm.asTrustedImm32().m_value;
1561         uint32_t key = keyForConstant(baseValue);
1562         return BlindedImm32(baseValue ^ key, key);
1563     }
1564
1565     BlindedImm32 additionBlindedConstant(Imm32 imm)
1566     {
1567         // The addition immediate may be used as a pointer offset. Keep aligned based on "imm".
1568         static uint32_t maskTable[4] = { 0xfffffffc, 0xffffffff, 0xfffffffe, 0xffffffff };
1569
1570         uint32_t baseValue = imm.asTrustedImm32().m_value;
1571         uint32_t key = keyForConstant(baseValue) & maskTable[baseValue & 3];
1572         if (key > baseValue)
1573             key = key - baseValue;
1574         return BlindedImm32(baseValue - key, key);
1575     }
1576     
1577     BlindedImm32 andBlindedConstant(Imm32 imm)
1578     {
1579         uint32_t baseValue = imm.asTrustedImm32().m_value;
1580         uint32_t mask = 0;
1581         uint32_t key = keyForConstant(baseValue, mask);
1582         ASSERT((baseValue & mask) == baseValue);
1583         return BlindedImm32(((baseValue & key) | ~key) & mask, ((baseValue & ~key) | key) & mask);
1584     }
1585     
1586     BlindedImm32 orBlindedConstant(Imm32 imm)
1587     {
1588         uint32_t baseValue = imm.asTrustedImm32().m_value;
1589         uint32_t mask = 0;
1590         uint32_t key = keyForConstant(baseValue, mask);
1591         ASSERT((baseValue & mask) == baseValue);
1592         return BlindedImm32((baseValue & key) & mask, (baseValue & ~key) & mask);
1593     }
1594     
1595     void loadXorBlindedConstant(BlindedImm32 constant, RegisterID dest)
1596     {
1597         move(constant.value1, dest);
1598         xor32(constant.value2, dest);
1599     }
1600     
1601     void add32(Imm32 imm, RegisterID dest)
1602     {
1603         if (shouldBlind(imm)) {
1604             BlindedImm32 key = additionBlindedConstant(imm);
1605             add32(key.value1, dest);
1606             add32(key.value2, dest);
1607         } else
1608             add32(imm.asTrustedImm32(), dest);
1609     }
1610
1611     void add32(Imm32 imm, RegisterID src, RegisterID dest)
1612     {
1613         if (shouldBlind(imm)) {
1614             BlindedImm32 key = additionBlindedConstant(imm);
1615             add32(key.value1, src, dest);
1616             add32(key.value2, dest);
1617         } else
1618             add32(imm.asTrustedImm32(), src, dest);
1619     }
1620     
1621     void addPtr(Imm32 imm, RegisterID dest)
1622     {
1623         if (shouldBlind(imm)) {
1624             BlindedImm32 key = additionBlindedConstant(imm);
1625             addPtr(key.value1, dest);
1626             addPtr(key.value2, dest);
1627         } else
1628             addPtr(imm.asTrustedImm32(), dest);
1629     }
1630
1631     void mul32(Imm32 imm, RegisterID src, RegisterID dest)
1632     {
1633         if (shouldBlind(imm)) {
1634             if (src != dest || haveScratchRegisterForBlinding()) {
1635                 if (src == dest) {
1636                     move(src, scratchRegisterForBlinding());
1637                     src = scratchRegisterForBlinding();
1638                 }
1639                 loadXorBlindedConstant(xorBlindConstant(imm), dest);
1640                 mul32(src, dest);
1641                 return;
1642             }
1643             // If we don't have a scratch register available for use, we'll just
1644             // place a random number of nops.
1645             uint32_t nopCount = random() & 3;
1646             while (nopCount--)
1647                 nop();
1648         }
1649         mul32(imm.asTrustedImm32(), src, dest);
1650     }
1651
1652     void and32(Imm32 imm, RegisterID dest)
1653     {
1654         if (shouldBlind(imm)) {
1655             BlindedImm32 key = andBlindedConstant(imm);
1656             and32(key.value1, dest);
1657             and32(key.value2, dest);
1658         } else
1659             and32(imm.asTrustedImm32(), dest);
1660     }
1661
1662     void andPtr(Imm32 imm, RegisterID dest)
1663     {
1664         if (shouldBlind(imm)) {
1665             BlindedImm32 key = andBlindedConstant(imm);
1666             andPtr(key.value1, dest);
1667             andPtr(key.value2, dest);
1668         } else
1669             andPtr(imm.asTrustedImm32(), dest);
1670     }
1671     
1672     void and32(Imm32 imm, RegisterID src, RegisterID dest)
1673     {
1674         if (shouldBlind(imm)) {
1675             if (src == dest)
1676                 return and32(imm.asTrustedImm32(), dest);
1677             loadXorBlindedConstant(xorBlindConstant(imm), dest);
1678             and32(src, dest);
1679         } else
1680             and32(imm.asTrustedImm32(), src, dest);
1681     }
1682
1683     void move(Imm32 imm, RegisterID dest)
1684     {
1685         if (shouldBlind(imm))
1686             loadXorBlindedConstant(xorBlindConstant(imm), dest);
1687         else
1688             move(imm.asTrustedImm32(), dest);
1689     }
1690     
1691     void or32(Imm32 imm, RegisterID src, RegisterID dest)
1692     {
1693         if (shouldBlind(imm)) {
1694             if (src == dest)
1695                 return or32(imm, dest);
1696             loadXorBlindedConstant(xorBlindConstant(imm), dest);
1697             or32(src, dest);
1698         } else
1699             or32(imm.asTrustedImm32(), src, dest);
1700     }
1701     
1702     void or32(Imm32 imm, RegisterID dest)
1703     {
1704         if (shouldBlind(imm)) {
1705             BlindedImm32 key = orBlindedConstant(imm);
1706             or32(key.value1, dest);
1707             or32(key.value2, dest);
1708         } else
1709             or32(imm.asTrustedImm32(), dest);
1710     }
1711     
1712     void poke(Imm32 value, int index = 0)
1713     {
1714         store32(value, addressForPoke(index));
1715     }
1716     
1717     void poke(ImmPtr value, int index = 0)
1718     {
1719         storePtr(value, addressForPoke(index));
1720     }
1721     
1722 #if CPU(X86_64) || CPU(ARM64)
1723     void poke(Imm64 value, int index = 0)
1724     {
1725         store64(value, addressForPoke(index));
1726     }
1727 #endif // CPU(X86_64)
1728     
1729     void store32(Imm32 imm, Address dest)
1730     {
1731         if (shouldBlind(imm)) {
1732 #if CPU(X86) || CPU(X86_64)
1733             BlindedImm32 blind = xorBlindConstant(imm);
1734             store32(blind.value1, dest);
1735             xor32(blind.value2, dest);
1736 #else // CPU(X86) || CPU(X86_64)
1737             if (haveScratchRegisterForBlinding()) {
1738                 loadXorBlindedConstant(xorBlindConstant(imm), scratchRegisterForBlinding());
1739                 store32(scratchRegisterForBlinding(), dest);
1740             } else {
1741                 // If we don't have a scratch register available for use, we'll just 
1742                 // place a random number of nops.
1743                 uint32_t nopCount = random() & 3;
1744                 while (nopCount--)
1745                     nop();
1746                 store32(imm.asTrustedImm32(), dest);
1747             }
1748 #endif // CPU(X86) || CPU(X86_64)
1749         } else
1750             store32(imm.asTrustedImm32(), dest);
1751     }
1752     
1753     void sub32(Imm32 imm, RegisterID dest)
1754     {
1755         if (shouldBlind(imm)) {
1756             BlindedImm32 key = additionBlindedConstant(imm);
1757             sub32(key.value1, dest);
1758             sub32(key.value2, dest);
1759         } else
1760             sub32(imm.asTrustedImm32(), dest);
1761     }
1762     
1763     void subPtr(Imm32 imm, RegisterID dest)
1764     {
1765         if (shouldBlind(imm)) {
1766             BlindedImm32 key = additionBlindedConstant(imm);
1767             subPtr(key.value1, dest);
1768             subPtr(key.value2, dest);
1769         } else
1770             subPtr(imm.asTrustedImm32(), dest);
1771     }
1772     
1773     void xor32(Imm32 imm, RegisterID src, RegisterID dest)
1774     {
1775         if (shouldBlind(imm)) {
1776             BlindedImm32 blind = xorBlindConstant(imm);
1777             xor32(blind.value1, src, dest);
1778             xor32(blind.value2, dest);
1779         } else
1780             xor32(imm.asTrustedImm32(), src, dest);
1781     }
1782     
1783     void xor32(Imm32 imm, RegisterID dest)
1784     {
1785         if (shouldBlind(imm)) {
1786             BlindedImm32 blind = xorBlindConstant(imm);
1787             xor32(blind.value1, dest);
1788             xor32(blind.value2, dest);
1789         } else
1790             xor32(imm.asTrustedImm32(), dest);
1791     }
1792
1793     Jump branch32(RelationalCondition cond, RegisterID left, Imm32 right)
1794     {
1795         if (shouldBlind(right)) {
1796             if (haveScratchRegisterForBlinding()) {
1797                 loadXorBlindedConstant(xorBlindConstant(right), scratchRegisterForBlinding());
1798                 return branch32(cond, left, scratchRegisterForBlinding());
1799             }
1800             // If we don't have a scratch register available for use, we'll just 
1801             // place a random number of nops.
1802             uint32_t nopCount = random() & 3;
1803             while (nopCount--)
1804                 nop();
1805             return branch32(cond, left, right.asTrustedImm32());
1806         }
1807         
1808         return branch32(cond, left, right.asTrustedImm32());
1809     }
1810
1811     void compare32(RelationalCondition cond, RegisterID left, Imm32 right, RegisterID dest)
1812     {
1813         if (shouldBlind(right)) {
1814             if (left != dest || haveScratchRegisterForBlinding()) {
1815                 RegisterID blindedConstantReg = dest;
1816                 if (left == dest)
1817                     blindedConstantReg = scratchRegisterForBlinding();
1818                 loadXorBlindedConstant(xorBlindConstant(right), blindedConstantReg);
1819                 compare32(cond, left, blindedConstantReg, dest);
1820                 return;
1821             }
1822             // If we don't have a scratch register available for use, we'll just
1823             // place a random number of nops.
1824             uint32_t nopCount = random() & 3;
1825             while (nopCount--)
1826                 nop();
1827             compare32(cond, left, right.asTrustedImm32(), dest);
1828             return;
1829         }
1830
1831         compare32(cond, left, right.asTrustedImm32(), dest);
1832     }
1833
1834     Jump branchAdd32(ResultCondition cond, RegisterID src, Imm32 imm, RegisterID dest)
1835     {
1836         if (shouldBlind(imm)) {
1837             if (src != dest || haveScratchRegisterForBlinding()) {
1838                 if (src == dest) {
1839                     move(src, scratchRegisterForBlinding());
1840                     src = scratchRegisterForBlinding();
1841                 }
1842                 loadXorBlindedConstant(xorBlindConstant(imm), dest);
1843                 return branchAdd32(cond, src, dest);
1844             }
1845             // If we don't have a scratch register available for use, we'll just
1846             // place a random number of nops.
1847             uint32_t nopCount = random() & 3;
1848             while (nopCount--)
1849                 nop();
1850         }
1851         return branchAdd32(cond, src, imm.asTrustedImm32(), dest);            
1852     }
1853     
1854     Jump branchMul32(ResultCondition cond, RegisterID src, Imm32 imm, RegisterID dest)
1855     {
1856         if (src == dest)
1857             ASSERT(haveScratchRegisterForBlinding());
1858
1859         if (shouldBlind(imm)) {
1860             if (src == dest) {
1861                 move(src, scratchRegisterForBlinding());
1862                 src = scratchRegisterForBlinding();
1863             }
1864             loadXorBlindedConstant(xorBlindConstant(imm), dest);
1865             return branchMul32(cond, src, dest);  
1866         }
1867         return branchMul32(cond, src, imm.asTrustedImm32(), dest);
1868     }
1869
1870     // branchSub32 takes a scratch register as 32 bit platforms make use of this,
1871     // with src == dst, and on x86-32 we don't have a platform scratch register.
1872     Jump branchSub32(ResultCondition cond, RegisterID src, Imm32 imm, RegisterID dest, RegisterID scratch)
1873     {
1874         if (shouldBlind(imm)) {
1875             ASSERT(scratch != dest);
1876             ASSERT(scratch != src);
1877             loadXorBlindedConstant(xorBlindConstant(imm), scratch);
1878             return branchSub32(cond, src, scratch, dest);
1879         }
1880         return branchSub32(cond, src, imm.asTrustedImm32(), dest);            
1881     }
1882     
1883     void lshift32(Imm32 imm, RegisterID dest)
1884     {
1885         lshift32(trustedImm32ForShift(imm), dest);
1886     }
1887     
1888     void lshift32(RegisterID src, Imm32 amount, RegisterID dest)
1889     {
1890         lshift32(src, trustedImm32ForShift(amount), dest);
1891     }
1892     
1893     void rshift32(Imm32 imm, RegisterID dest)
1894     {
1895         rshift32(trustedImm32ForShift(imm), dest);
1896     }
1897     
1898     void rshift32(RegisterID src, Imm32 amount, RegisterID dest)
1899     {
1900         rshift32(src, trustedImm32ForShift(amount), dest);
1901     }
1902     
1903     void urshift32(Imm32 imm, RegisterID dest)
1904     {
1905         urshift32(trustedImm32ForShift(imm), dest);
1906     }
1907     
1908     void urshift32(RegisterID src, Imm32 amount, RegisterID dest)
1909     {
1910         urshift32(src, trustedImm32ForShift(amount), dest);
1911     }
1912
1913     // If the result jump is taken that means the assert passed.
1914     void jitAssert(const WTF::ScopedLambda<Jump(void)>&);
1915
1916 #if ENABLE(MASM_PROBE)
1917     // This function emits code to preserve the CPUState (e.g. registers),
1918     // call a user supplied probe function, and restore the CPUState before
1919     // continuing with other JIT generated code.
1920     //
1921     // The user supplied probe function will be called with a single pointer to
1922     // a Probe::State struct (defined below) which contains, among other things,
1923     // the preserved CPUState. This allows the user probe function to inspect
1924     // the CPUState at that point in the JIT generated code.
1925     //
1926     // If the user probe function alters the register values in the Probe::State,
1927     // the altered values will be loaded into the CPU registers when the probe
1928     // returns.
1929     //
1930     // The Probe::State is stack allocated and is only valid for the duration
1931     // of the call to the user probe function.
1932     //
1933     // The probe function may choose to move the stack pointer (in any direction).
1934     // To do this, the probe function needs to set the new sp value in the CPUState.
1935     //
1936     // The probe function may also choose to fill stack space with some values.
1937     // To do this, the probe function must first:
1938     // 1. Set the new sp value in the Probe::State's CPUState.
1939     // 2. Set the Probe::State's initializeStackFunction to a Probe::Function callback
1940     //    which will do the work of filling in the stack values after the probe
1941     //    trampoline has adjusted the machine stack pointer.
1942     // 3. Set the Probe::State's initializeStackArgs to any value that the client wants
1943     //    to pass to the initializeStackFunction callback.
1944     // 4. Return from the probe function.
1945     //
1946     // Upon returning from the probe function, the probe trampoline will adjust the
1947     // the stack pointer based on the sp value in CPUState. If initializeStackFunction
1948     // is not set, the probe trampoline will restore registers and return to its caller.
1949     //
1950     // If initializeStackFunction is set, the trampoline will move the Probe::State
1951     // beyond the range of the stack pointer i.e. it will place the new Probe::State at
1952     // an address lower than where CPUState.sp() points. This ensures that the
1953     // Probe::State will not be trashed by the initializeStackFunction when it writes to
1954     // the stack. Then, the trampoline will call back to the initializeStackFunction
1955     // Probe::Function to let it fill in the stack values as desired. The
1956     // initializeStackFunction Probe::Function will be passed the moved Probe::State at
1957     // the new location.
1958     //
1959     // initializeStackFunction may now write to the stack at addresses greater or
1960     // equal to CPUState.sp(), but not below that. initializeStackFunction is also
1961     // not allowed to change CPUState.sp(). If the initializeStackFunction does not
1962     // abide by these rules, then behavior is undefined, and bad things may happen.
1963     //
1964     // Note: this version of probe() should be implemented by the target specific
1965     // MacroAssembler.
1966     void probe(Probe::Function, void* arg);
1967
1968     JS_EXPORT_PRIVATE void probe(std::function<void(Probe::Context&)>);
1969
1970     // Let's you print from your JIT generated code.
1971     // See comments in MacroAssemblerPrinter.h for examples of how to use this.
1972     template<typename... Arguments>
1973     void print(Arguments&&... args);
1974
1975     void print(Printer::PrintRecordList*);
1976 #endif // ENABLE(MASM_PROBE)
1977 };
1978
1979 } // namespace JSC
1980
1981 namespace WTF {
1982
1983 class PrintStream;
1984
1985 void printInternal(PrintStream&, JSC::MacroAssembler::RelationalCondition);
1986 void printInternal(PrintStream&, JSC::MacroAssembler::ResultCondition);
1987 void printInternal(PrintStream&, JSC::MacroAssembler::DoubleCondition);
1988
1989 } // namespace WTF
1990
1991 #else // ENABLE(ASSEMBLER)
1992
1993 namespace JSC {
1994
1995 // If there is no assembler for this platform, at least allow code to make references to
1996 // some of the things it would otherwise define, albeit without giving that code any way
1997 // of doing anything useful.
1998 class MacroAssembler {
1999 private:
2000     MacroAssembler() { }
2001     
2002 public:
2003     
2004     enum RegisterID { NoRegister };
2005     enum FPRegisterID { NoFPRegister };
2006 };
2007
2008 } // namespace JSC
2009
2010 #endif // ENABLE(ASSEMBLER)