LCOV - code coverage report
Current view: top level - js/src/jit/x86-shared - MacroAssembler-x86-shared-inl.h (source / functions) Hit Total Coverage
Test: output.info Lines: 266 575 46.3 %
Date: 2017-07-14 16:53:18 Functions: 103 183 56.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef jit_x86_shared_MacroAssembler_x86_shared_inl_h
       8             : #define jit_x86_shared_MacroAssembler_x86_shared_inl_h
       9             : 
      10             : #include "jit/x86-shared/MacroAssembler-x86-shared.h"
      11             : 
      12             : namespace js {
      13             : namespace jit {
      14             : 
      15             : //{{{ check_macroassembler_style
      16             : // ===============================================================
      17             : // Move instructions
      18             : 
      19             : void
      20           0 : MacroAssembler::moveFloat32ToGPR(FloatRegister src, Register dest)
      21             : {
      22           0 :     vmovd(src, dest);
      23           0 : }
      24             : 
      25             : void
      26           0 : MacroAssembler::moveGPRToFloat32(Register src, FloatRegister dest)
      27             : {
      28           0 :     vmovd(src, dest);
      29           0 : }
      30             : 
      31             : void
      32           0 : MacroAssembler::move8SignExtend(Register src, Register dest)
      33             : {
      34           0 :     movsbl(src, dest);
      35           0 : }
      36             : 
      37             : void
      38           0 : MacroAssembler::move16SignExtend(Register src, Register dest)
      39             : {
      40           0 :     movswl(src, dest);
      41           0 : }
      42             : 
      43             : // ===============================================================
      44             : // Logical instructions
      45             : 
      46             : void
      47           0 : MacroAssembler::not32(Register reg)
      48             : {
      49           0 :     notl(reg);
      50           0 : }
      51             : 
      52             : void
      53         164 : MacroAssembler::and32(Register src, Register dest)
      54             : {
      55         164 :     andl(src, dest);
      56         164 : }
      57             : 
      58             : void
      59         192 : MacroAssembler::and32(Imm32 imm, Register dest)
      60             : {
      61         192 :     andl(imm, dest);
      62         192 : }
      63             : 
      64             : void
      65           0 : MacroAssembler::and32(Imm32 imm, const Address& dest)
      66             : {
      67           0 :     andl(imm, Operand(dest));
      68           0 : }
      69             : 
      70             : void
      71           4 : MacroAssembler::and32(const Address& src, Register dest)
      72             : {
      73           4 :     andl(Operand(src), dest);
      74           4 : }
      75             : 
      76             : void
      77           0 : MacroAssembler::or32(Register src, Register dest)
      78             : {
      79           0 :     orl(src, dest);
      80           0 : }
      81             : 
      82             : void
      83           0 : MacroAssembler::or32(Imm32 imm, Register dest)
      84             : {
      85           0 :     orl(imm, dest);
      86           0 : }
      87             : 
      88             : void
      89         185 : MacroAssembler::or32(Imm32 imm, const Address& dest)
      90             : {
      91         185 :     orl(imm, Operand(dest));
      92         185 : }
      93             : 
      94             : void
      95           0 : MacroAssembler::xor32(Register src, Register dest)
      96             : {
      97           0 :     xorl(src, dest);
      98           0 : }
      99             : 
     100             : void
     101          37 : MacroAssembler::xor32(Imm32 imm, Register dest)
     102             : {
     103          37 :     xorl(imm, dest);
     104          37 : }
     105             : 
     106             : void
     107           0 : MacroAssembler::clz32(Register src, Register dest, bool knownNotZero)
     108             : {
     109             :     // On very recent chips (Haswell and newer?) there is actually an
     110             :     // LZCNT instruction that does all of this.
     111             : 
     112           0 :     bsrl(src, dest);
     113           0 :     if (!knownNotZero) {
     114             :         // If the source is zero then bsrl leaves garbage in the destination.
     115           0 :         Label nonzero;
     116           0 :         j(Assembler::NonZero, &nonzero);
     117           0 :         movl(Imm32(0x3F), dest);
     118           0 :         bind(&nonzero);
     119             :     }
     120           0 :     xorl(Imm32(0x1F), dest);
     121           0 : }
     122             : 
     123             : void
     124           0 : MacroAssembler::ctz32(Register src, Register dest, bool knownNotZero)
     125             : {
     126           0 :     bsfl(src, dest);
     127           0 :     if (!knownNotZero) {
     128           0 :         Label nonzero;
     129           0 :         j(Assembler::NonZero, &nonzero);
     130           0 :         movl(Imm32(32), dest);
     131           0 :         bind(&nonzero);
     132             :     }
     133           0 : }
     134             : 
     135             : void
     136           0 : MacroAssembler::popcnt32(Register input, Register output, Register tmp)
     137             : {
     138           0 :     if (AssemblerX86Shared::HasPOPCNT()) {
     139           0 :         popcntl(input, output);
     140           0 :         return;
     141             :     }
     142             : 
     143           0 :     MOZ_ASSERT(tmp != InvalidReg);
     144             : 
     145             :     // Equivalent to mozilla::CountPopulation32()
     146             : 
     147           0 :     movl(input, tmp);
     148           0 :     if (input != output)
     149           0 :         movl(input, output);
     150           0 :     shrl(Imm32(1), output);
     151           0 :     andl(Imm32(0x55555555), output);
     152           0 :     subl(output, tmp);
     153           0 :     movl(tmp, output);
     154           0 :     andl(Imm32(0x33333333), output);
     155           0 :     shrl(Imm32(2), tmp);
     156           0 :     andl(Imm32(0x33333333), tmp);
     157           0 :     addl(output, tmp);
     158           0 :     movl(tmp, output);
     159           0 :     shrl(Imm32(4), output);
     160           0 :     addl(tmp, output);
     161           0 :     andl(Imm32(0xF0F0F0F), output);
     162           0 :     imull(Imm32(0x1010101), output, output);
     163           0 :     shrl(Imm32(24), output);
     164             : }
     165             : 
     166             : // ===============================================================
     167             : // Arithmetic instructions
     168             : 
     169             : void
     170           4 : MacroAssembler::add32(Register src, Register dest)
     171             : {
     172           4 :     addl(src, dest);
     173           4 : }
     174             : 
     175             : void
     176        1147 : MacroAssembler::add32(Imm32 imm, Register dest)
     177             : {
     178        1147 :     addl(imm, dest);
     179        1147 : }
     180             : 
     181             : void
     182           8 : MacroAssembler::add32(Imm32 imm, const Address& dest)
     183             : {
     184           8 :     addl(imm, Operand(dest));
     185           8 : }
     186             : 
     187             : void
     188             : MacroAssembler::add32(Imm32 imm, const AbsoluteAddress& dest)
     189             : {
     190             :     addl(imm, Operand(dest));
     191             : }
     192             : 
     193             : void
     194           0 : MacroAssembler::addFloat32(FloatRegister src, FloatRegister dest)
     195             : {
     196           0 :     vaddss(src, dest, dest);
     197           0 : }
     198             : 
     199             : void
     200           0 : MacroAssembler::addDouble(FloatRegister src, FloatRegister dest)
     201             : {
     202           0 :     vaddsd(src, dest, dest);
     203           0 : }
     204             : 
     205             : void
     206           6 : MacroAssembler::sub32(Register src, Register dest)
     207             : {
     208           6 :     subl(src, dest);
     209           6 : }
     210             : 
     211             : void
     212         453 : MacroAssembler::sub32(Imm32 imm, Register dest)
     213             : {
     214         453 :     subl(imm, dest);
     215         453 : }
     216             : 
     217             : void
     218           0 : MacroAssembler::sub32(const Address& src, Register dest)
     219             : {
     220           0 :     subl(Operand(src), dest);
     221           0 : }
     222             : 
     223             : void
     224           0 : MacroAssembler::subDouble(FloatRegister src, FloatRegister dest)
     225             : {
     226           0 :     vsubsd(src, dest, dest);
     227           0 : }
     228             : 
     229             : void
     230           0 : MacroAssembler::subFloat32(FloatRegister src, FloatRegister dest)
     231             : {
     232           0 :     vsubss(src, dest, dest);
     233           0 : }
     234             : 
     235             : void
     236           0 : MacroAssembler::mul32(Register rhs, Register srcDest)
     237             : {
     238           0 :     MOZ_ASSERT(srcDest == eax);
     239           0 :     imull(rhs, srcDest);        // Clobbers edx
     240           0 : }
     241             : 
     242             : void
     243           0 : MacroAssembler::mulFloat32(FloatRegister src, FloatRegister dest)
     244             : {
     245           0 :     vmulss(src, dest, dest);
     246           0 : }
     247             : 
     248             : void
     249           0 : MacroAssembler::mulDouble(FloatRegister src, FloatRegister dest)
     250             : {
     251           0 :     vmulsd(src, dest, dest);
     252           0 : }
     253             : 
     254             : void
     255           0 : MacroAssembler::quotient32(Register rhs, Register srcDest, bool isUnsigned)
     256             : {
     257           0 :     MOZ_ASSERT(srcDest == eax);
     258             : 
     259             :     // Sign extend eax into edx to make (edx:eax): idiv/udiv are 64-bit.
     260           0 :     if (isUnsigned) {
     261           0 :         mov(ImmWord(0), edx);
     262           0 :         udiv(rhs);
     263             :     } else {
     264           0 :         cdq();
     265           0 :         idiv(rhs);
     266             :     }
     267           0 : }
     268             : 
     269             : void
     270           0 : MacroAssembler::remainder32(Register rhs, Register srcDest, bool isUnsigned)
     271             : {
     272           0 :     MOZ_ASSERT(srcDest == eax);
     273             : 
     274             :     // Sign extend eax into edx to make (edx:eax): idiv/udiv are 64-bit.
     275           0 :     if (isUnsigned) {
     276           0 :         mov(ImmWord(0), edx);
     277           0 :         udiv(rhs);
     278             :     } else {
     279           0 :         cdq();
     280           0 :         idiv(rhs);
     281             :     }
     282           0 :     mov(edx, eax);
     283           0 : }
     284             : 
     285             : void
     286           0 : MacroAssembler::divFloat32(FloatRegister src, FloatRegister dest)
     287             : {
     288           0 :     vdivss(src, dest, dest);
     289           0 : }
     290             : 
     291             : void
     292           1 : MacroAssembler::divDouble(FloatRegister src, FloatRegister dest)
     293             : {
     294           1 :     vdivsd(src, dest, dest);
     295           1 : }
     296             : 
     297             : void
     298           0 : MacroAssembler::neg32(Register reg)
     299             : {
     300           0 :     negl(reg);
     301           0 : }
     302             : 
     303             : void
     304           0 : MacroAssembler::negateFloat(FloatRegister reg)
     305             : {
     306           0 :     ScratchFloat32Scope scratch(*this);
     307           0 :     vpcmpeqw(Operand(scratch), scratch, scratch);
     308           0 :     vpsllq(Imm32(31), scratch, scratch);
     309             : 
     310             :     // XOR the float in a float register with -0.0.
     311           0 :     vxorps(scratch, reg, reg); // s ^ 0x80000000
     312           0 : }
     313             : 
     314             : void
     315           0 : MacroAssembler::negateDouble(FloatRegister reg)
     316             : {
     317             :     // From MacroAssemblerX86Shared::maybeInlineDouble
     318           0 :     ScratchDoubleScope scratch(*this);
     319           0 :     vpcmpeqw(Operand(scratch), scratch, scratch);
     320           0 :     vpsllq(Imm32(63), scratch, scratch);
     321             : 
     322             :     // XOR the float in a float register with -0.0.
     323           0 :     vxorpd(scratch, reg, reg); // s ^ 0x80000000000000
     324           0 : }
     325             : 
     326             : void
     327           0 : MacroAssembler::absFloat32(FloatRegister src, FloatRegister dest)
     328             : {
     329           0 :     ScratchFloat32Scope scratch(*this);
     330           0 :     loadConstantFloat32(mozilla::SpecificNaN<float>(0, mozilla::FloatingPoint<float>::kSignificandBits), scratch);
     331           0 :     vandps(scratch, src, dest);
     332           0 : }
     333             : 
     334             : void
     335           0 : MacroAssembler::absDouble(FloatRegister src, FloatRegister dest)
     336             : {
     337           0 :     ScratchDoubleScope scratch(*this);
     338           0 :     loadConstantDouble(mozilla::SpecificNaN<double>(0, mozilla::FloatingPoint<double>::kSignificandBits), scratch);
     339           0 :     vandpd(scratch, src, dest);
     340           0 : }
     341             : 
     342             : void
     343           0 : MacroAssembler::sqrtFloat32(FloatRegister src, FloatRegister dest)
     344             : {
     345           0 :     vsqrtss(src, src, dest);
     346           0 : }
     347             : 
     348             : void
     349           0 : MacroAssembler::sqrtDouble(FloatRegister src, FloatRegister dest)
     350             : {
     351           0 :     vsqrtsd(src, src, dest);
     352           0 : }
     353             : 
     354             : void
     355           0 : MacroAssembler::minFloat32(FloatRegister other, FloatRegister srcDest, bool handleNaN)
     356             : {
     357           0 :     minMaxFloat32(srcDest, other, handleNaN, false);
     358           0 : }
     359             : 
     360             : void
     361           0 : MacroAssembler::minDouble(FloatRegister other, FloatRegister srcDest, bool handleNaN)
     362             : {
     363           0 :     minMaxDouble(srcDest, other, handleNaN, false);
     364           0 : }
     365             : 
     366             : void
     367           0 : MacroAssembler::maxFloat32(FloatRegister other, FloatRegister srcDest, bool handleNaN)
     368             : {
     369           0 :     minMaxFloat32(srcDest, other, handleNaN, true);
     370           0 : }
     371             : 
     372             : void
     373           0 : MacroAssembler::maxDouble(FloatRegister other, FloatRegister srcDest, bool handleNaN)
     374             : {
     375           0 :     minMaxDouble(srcDest, other, handleNaN, true);
     376           0 : }
     377             : 
     378             : // ===============================================================
     379             : // Rotation instructions
     380             : void
     381           0 : MacroAssembler::rotateLeft(Imm32 count, Register input, Register dest)
     382             : {
     383           0 :     MOZ_ASSERT(input == dest, "defineReuseInput");
     384           0 :     count.value &= 0x1f;
     385           0 :     if (count.value)
     386           0 :         roll(count, input);
     387           0 : }
     388             : 
     389             : void
     390           0 : MacroAssembler::rotateLeft(Register count, Register input, Register dest)
     391             : {
     392           0 :     MOZ_ASSERT(input == dest, "defineReuseInput");
     393           0 :     MOZ_ASSERT(count == ecx, "defineFixed(ecx)");
     394           0 :     roll_cl(input);
     395           0 : }
     396             : 
     397             : void
     398           0 : MacroAssembler::rotateRight(Imm32 count, Register input, Register dest)
     399             : {
     400           0 :     MOZ_ASSERT(input == dest, "defineReuseInput");
     401           0 :     count.value &= 0x1f;
     402           0 :     if (count.value)
     403           0 :         rorl(count, input);
     404           0 : }
     405             : 
     406             : void
     407           0 : MacroAssembler::rotateRight(Register count, Register input, Register dest)
     408             : {
     409           0 :     MOZ_ASSERT(input == dest, "defineReuseInput");
     410           0 :     MOZ_ASSERT(count == ecx, "defineFixed(ecx)");
     411           0 :     rorl_cl(input);
     412           0 : }
     413             : 
     414             : // ===============================================================
     415             : // Shift instructions
     416             : 
     417             : void
     418           0 : MacroAssembler::lshift32(Register shift, Register srcDest)
     419             : {
     420           0 :     MOZ_ASSERT(shift == ecx);
     421           0 :     shll_cl(srcDest);
     422           0 : }
     423             : 
     424             : void
     425           0 : MacroAssembler::rshift32(Register shift, Register srcDest)
     426             : {
     427           0 :     MOZ_ASSERT(shift == ecx);
     428           0 :     shrl_cl(srcDest);
     429           0 : }
     430             : 
     431             : void
     432           0 : MacroAssembler::rshift32Arithmetic(Register shift, Register srcDest)
     433             : {
     434           0 :     MOZ_ASSERT(shift == ecx);
     435           0 :     sarl_cl(srcDest);
     436           0 : }
     437             : 
     438             : void
     439           0 : MacroAssembler::lshift32(Imm32 shift, Register srcDest)
     440             : {
     441           0 :     shll(shift, srcDest);
     442           0 : }
     443             : 
     444             : void
     445           2 : MacroAssembler::rshift32(Imm32 shift, Register srcDest)
     446             : {
     447           2 :     shrl(shift, srcDest);
     448           2 : }
     449             : 
     450             : void
     451           0 : MacroAssembler::rshift32Arithmetic(Imm32 shift, Register srcDest)
     452             : {
     453           0 :     sarl(shift, srcDest);
     454           0 : }
     455             : 
     456             : // ===============================================================
     457             : // Condition functions
     458             : 
     459             : template <typename T1, typename T2>
     460             : void
     461           2 : MacroAssembler::cmp32Set(Condition cond, T1 lhs, T2 rhs, Register dest)
     462             : {
     463           2 :     cmp32(lhs, rhs);
     464           2 :     emitSet(cond, dest);
     465           2 : }
     466             : 
     467             : // ===============================================================
     468             : // Branch instructions
     469             : 
     470             : template <class L>
     471             : void
     472          78 : MacroAssembler::branch32(Condition cond, Register lhs, Register rhs, L label)
     473             : {
     474          78 :     cmp32(lhs, rhs);
     475          78 :     j(cond, label);
     476          78 : }
     477             : 
     478             : template <class L>
     479             : void
     480        2067 : MacroAssembler::branch32(Condition cond, Register lhs, Imm32 rhs, L label)
     481             : {
     482        2067 :     cmp32(lhs, rhs);
     483        2067 :     j(cond, label);
     484        2067 : }
     485             : 
     486             : void
     487         101 : MacroAssembler::branch32(Condition cond, const Address& lhs, Register rhs, Label* label)
     488             : {
     489         101 :     cmp32(Operand(lhs), rhs);
     490         101 :     j(cond, label);
     491         101 : }
     492             : 
     493             : void
     494        1601 : MacroAssembler::branch32(Condition cond, const Address& lhs, Imm32 rhs, Label* label)
     495             : {
     496        1601 :     cmp32(Operand(lhs), rhs);
     497        1601 :     j(cond, label);
     498        1601 : }
     499             : 
     500             : void
     501             : MacroAssembler::branch32(Condition cond, const BaseIndex& lhs, Register rhs, Label* label)
     502             : {
     503             :     cmp32(Operand(lhs), rhs);
     504             :     j(cond, label);
     505             : }
     506             : 
     507             : void
     508           0 : MacroAssembler::branch32(Condition cond, const BaseIndex& lhs, Imm32 rhs, Label* label)
     509             : {
     510           0 :     cmp32(Operand(lhs), rhs);
     511           0 :     j(cond, label);
     512           0 : }
     513             : 
     514             : void
     515             : MacroAssembler::branch32(Condition cond, const Operand& lhs, Register rhs, Label* label)
     516             : {
     517             :     cmp32(lhs, rhs);
     518             :     j(cond, label);
     519             : }
     520             : 
     521             : void
     522           0 : MacroAssembler::branch32(Condition cond, const Operand& lhs, Imm32 rhs, Label* label)
     523             : {
     524           0 :     cmp32(lhs, rhs);
     525           0 :     j(cond, label);
     526           0 : }
     527             : 
     528             : template <class L>
     529             : void
     530         305 : MacroAssembler::branchPtr(Condition cond, Register lhs, Register rhs, L label)
     531             : {
     532         305 :     cmpPtr(lhs, rhs);
     533         305 :     j(cond, label);
     534         305 : }
     535             : 
     536             : void
     537        1329 : MacroAssembler::branchPtr(Condition cond, Register lhs, Imm32 rhs, Label* label)
     538             : {
     539        1329 :     branchPtrImpl(cond, lhs, rhs, label);
     540        1329 : }
     541             : 
     542             : void
     543          70 : MacroAssembler::branchPtr(Condition cond, Register lhs, ImmPtr rhs, Label* label)
     544             : {
     545          70 :     branchPtrImpl(cond, lhs, rhs, label);
     546          70 : }
     547             : 
     548             : void
     549         101 : MacroAssembler::branchPtr(Condition cond, Register lhs, ImmGCPtr rhs, Label* label)
     550             : {
     551         101 :     branchPtrImpl(cond, lhs, rhs, label);
     552         101 : }
     553             : 
     554             : void
     555         311 : MacroAssembler::branchPtr(Condition cond, Register lhs, ImmWord rhs, Label* label)
     556             : {
     557         311 :     branchPtrImpl(cond, lhs, rhs, label);
     558         311 : }
     559             : 
     560             : template <class L>
     561             : void
     562        1633 : MacroAssembler::branchPtr(Condition cond, const Address& lhs, Register rhs, L label)
     563             : {
     564        1633 :     branchPtrImpl(cond, lhs, rhs, label);
     565        1633 : }
     566             : 
     567             : void
     568         945 : MacroAssembler::branchPtr(Condition cond, const Address& lhs, ImmPtr rhs, Label* label)
     569             : {
     570         945 :     branchPtrImpl(cond, lhs, rhs, label);
     571         945 : }
     572             : 
     573             : void
     574          25 : MacroAssembler::branchPtr(Condition cond, const Address& lhs, ImmGCPtr rhs, Label* label)
     575             : {
     576          25 :     branchPtrImpl(cond, lhs, rhs, label);
     577          25 : }
     578             : 
     579             : void
     580          92 : MacroAssembler::branchPtr(Condition cond, const Address& lhs, ImmWord rhs, Label* label)
     581             : {
     582          92 :     branchPtrImpl(cond, lhs, rhs, label);
     583          92 : }
     584             : 
     585             : void
     586           7 : MacroAssembler::branchPtr(Condition cond, const BaseIndex& lhs, ImmWord rhs, Label* label)
     587             : {
     588           7 :     branchPtrImpl(cond, lhs, rhs, label);
     589           7 : }
     590             : 
     591             : template <typename T, typename S, typename L>
     592             : void
     593        4686 : MacroAssembler::branchPtrImpl(Condition cond, const T& lhs, const S& rhs, L label)
     594             : {
     595        4686 :     cmpPtr(Operand(lhs), rhs);
     596        4686 :     j(cond, label);
     597        4686 : }
     598             : 
     599             : template <typename T>
     600             : CodeOffsetJump
     601             : MacroAssembler::branchPtrWithPatch(Condition cond, Register lhs, T rhs, RepatchLabel* label)
     602             : {
     603             :     cmpPtr(lhs, rhs);
     604             :     return jumpWithPatch(label, cond);
     605             : }
     606             : 
     607             : template <typename T>
     608             : CodeOffsetJump
     609             : MacroAssembler::branchPtrWithPatch(Condition cond, Address lhs, T rhs, RepatchLabel* label)
     610             : {
     611             :     cmpPtr(lhs, rhs);
     612             :     return jumpWithPatch(label, cond);
     613             : }
     614             : 
     615             : void
     616           0 : MacroAssembler::branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
     617             :                             Label* label)
     618             : {
     619           0 :     compareFloat(cond, lhs, rhs);
     620             : 
     621           0 :     if (cond == DoubleEqual) {
     622           0 :         Label unordered;
     623           0 :         j(Parity, &unordered);
     624           0 :         j(Equal, label);
     625           0 :         bind(&unordered);
     626           0 :         return;
     627             :     }
     628             : 
     629           0 :     if (cond == DoubleNotEqualOrUnordered) {
     630           0 :         j(NotEqual, label);
     631           0 :         j(Parity, label);
     632           0 :         return;
     633             :     }
     634             : 
     635           0 :     MOZ_ASSERT(!(cond & DoubleConditionBitSpecial));
     636           0 :     j(ConditionFromDoubleCondition(cond), label);
     637             : }
     638             : 
     639             : void
     640           0 : MacroAssembler::branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
     641             :                              Label* label)
     642             : {
     643           0 :     compareDouble(cond, lhs, rhs);
     644             : 
     645           0 :     if (cond == DoubleEqual) {
     646           0 :         Label unordered;
     647           0 :         j(Parity, &unordered);
     648           0 :         j(Equal, label);
     649           0 :         bind(&unordered);
     650           0 :         return;
     651             :     }
     652           0 :     if (cond == DoubleNotEqualOrUnordered) {
     653           0 :         j(NotEqual, label);
     654           0 :         j(Parity, label);
     655           0 :         return;
     656             :     }
     657             : 
     658           0 :     MOZ_ASSERT(!(cond & DoubleConditionBitSpecial));
     659           0 :     j(ConditionFromDoubleCondition(cond), label);
     660             : }
     661             : 
     662             : template <typename T, typename L>
     663             : void
     664           0 : MacroAssembler::branchAdd32(Condition cond, T src, Register dest, L label)
     665             : {
     666           0 :     addl(src, dest);
     667           0 :     j(cond, label);
     668           0 : }
     669             : 
     670             : template <typename T>
     671             : void
     672         201 : MacroAssembler::branchSub32(Condition cond, T src, Register dest, Label* label)
     673             : {
     674         201 :     subl(src, dest);
     675         201 :     j(cond, label);
     676         201 : }
     677             : 
     678             : void
     679           0 : MacroAssembler::decBranchPtr(Condition cond, Register lhs, Imm32 rhs, Label* label)
     680             : {
     681           0 :     subPtr(rhs, lhs);
     682           0 :     j(cond, label);
     683           0 : }
     684             : 
     685             : template <class L>
     686             : void
     687         551 : MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)
     688             : {
     689         551 :     MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
     690         551 :     test32(lhs, rhs);
     691         551 :     j(cond, label);
     692         551 : }
     693             : 
     694             : template <class L>
     695             : void
     696         199 : MacroAssembler::branchTest32(Condition cond, Register lhs, Imm32 rhs, L label)
     697             : {
     698         199 :     MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
     699         199 :     test32(lhs, rhs);
     700         199 :     j(cond, label);
     701         199 : }
     702             : 
     703             : void
     704        7713 : MacroAssembler::branchTest32(Condition cond, const Address& lhs, Imm32 rhs, Label* label)
     705             : {
     706        7713 :     MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
     707        7713 :     test32(Operand(lhs), rhs);
     708        7713 :     j(cond, label);
     709        7713 : }
     710             : 
     711             : template <class L>
     712             : void
     713         357 : MacroAssembler::branchTestPtr(Condition cond, Register lhs, Register rhs, L label)
     714             : {
     715         357 :     testPtr(lhs, rhs);
     716         357 :     j(cond, label);
     717         357 : }
     718             : 
     719             : void
     720       13390 : MacroAssembler::branchTestPtr(Condition cond, Register lhs, Imm32 rhs, Label* label)
     721             : {
     722       13390 :     testPtr(lhs, rhs);
     723       13390 :     j(cond, label);
     724       13390 : }
     725             : 
     726             : void
     727          57 : MacroAssembler::branchTestPtr(Condition cond, const Address& lhs, Imm32 rhs, Label* label)
     728             : {
     729          57 :     testPtr(Operand(lhs), rhs);
     730          57 :     j(cond, label);
     731          57 : }
     732             : 
     733             : void
     734         105 : MacroAssembler::branchTestUndefined(Condition cond, Register tag, Label* label)
     735             : {
     736         105 :     branchTestUndefinedImpl(cond, tag, label);
     737         105 : }
     738             : 
     739             : void
     740           0 : MacroAssembler::branchTestUndefined(Condition cond, const Address& address, Label* label)
     741             : {
     742           0 :     branchTestUndefinedImpl(cond, address, label);
     743           0 : }
     744             : 
     745             : void
     746             : MacroAssembler::branchTestUndefined(Condition cond, const BaseIndex& address, Label* label)
     747             : {
     748             :     branchTestUndefinedImpl(cond, address, label);
     749             : }
     750             : 
     751             : void
     752         339 : MacroAssembler::branchTestUndefined(Condition cond, const ValueOperand& value, Label* label)
     753             : {
     754         339 :     branchTestUndefinedImpl(cond, value, label);
     755         339 : }
     756             : 
     757             : template <typename T>
     758             : void
     759         444 : MacroAssembler::branchTestUndefinedImpl(Condition cond, const T& t, Label* label)
     760             : {
     761         444 :     cond = testUndefined(cond, t);
     762         444 :     j(cond, label);
     763         444 : }
     764             : 
     765             : void
     766          34 : MacroAssembler::branchTestInt32(Condition cond, Register tag, Label* label)
     767             : {
     768          34 :     branchTestInt32Impl(cond, tag, label);
     769          34 : }
     770             : 
     771             : void
     772          32 : MacroAssembler::branchTestInt32(Condition cond, const Address& address, Label* label)
     773             : {
     774          32 :     branchTestInt32Impl(cond, address, label);
     775          32 : }
     776             : 
     777             : void
     778           0 : MacroAssembler::branchTestInt32(Condition cond, const BaseIndex& address, Label* label)
     779             : {
     780           0 :     branchTestInt32Impl(cond, address, label);
     781           0 : }
     782             : 
     783             : void
     784         560 : MacroAssembler::branchTestInt32(Condition cond, const ValueOperand& value, Label* label)
     785             : {
     786         560 :     branchTestInt32Impl(cond, value, label);
     787         560 : }
     788             : 
     789             : template <typename T>
     790             : void
     791         626 : MacroAssembler::branchTestInt32Impl(Condition cond, const T& t, Label* label)
     792             : {
     793         626 :     cond = testInt32(cond, t);
     794         626 :     j(cond, label);
     795         626 : }
     796             : 
     797             : void
     798          11 : MacroAssembler::branchTestInt32Truthy(bool truthy, const ValueOperand& value, Label* label)
     799             : {
     800          11 :     Condition cond = testInt32Truthy(truthy, value);
     801          11 :     j(cond, label);
     802          11 : }
     803             : 
     804             : void
     805          24 : MacroAssembler::branchTestDouble(Condition cond, Register tag, Label* label)
     806             : {
     807          24 :     branchTestDoubleImpl(cond, tag, label);
     808          24 : }
     809             : 
     810             : void
     811           0 : MacroAssembler::branchTestDouble(Condition cond, const Address& address, Label* label)
     812             : {
     813           0 :     branchTestDoubleImpl(cond, address, label);
     814           0 : }
     815             : 
     816             : void
     817             : MacroAssembler::branchTestDouble(Condition cond, const BaseIndex& address, Label* label)
     818             : {
     819             :     branchTestDoubleImpl(cond, address, label);
     820             : }
     821             : 
     822             : void
     823          27 : MacroAssembler::branchTestDouble(Condition cond, const ValueOperand& value, Label* label)
     824             : {
     825          27 :     branchTestDoubleImpl(cond, value, label);
     826          27 : }
     827             : 
     828             : template <typename T>
     829             : void
     830          51 : MacroAssembler::branchTestDoubleImpl(Condition cond, const T& t, Label* label)
     831             : {
     832          51 :     cond = testDouble(cond, t);
     833          51 :     j(cond, label);
     834          51 : }
     835             : 
     836             : void
     837           1 : MacroAssembler::branchTestDoubleTruthy(bool truthy, FloatRegister reg, Label* label)
     838             : {
     839           1 :     Condition cond = testDoubleTruthy(truthy, reg);
     840           1 :     j(cond, label);
     841           1 : }
     842             : 
     843             : void
     844           1 : MacroAssembler::branchTestNumber(Condition cond, Register tag, Label* label)
     845             : {
     846           1 :     branchTestNumberImpl(cond, tag, label);
     847           1 : }
     848             : 
     849             : void
     850         173 : MacroAssembler::branchTestNumber(Condition cond, const ValueOperand& value, Label* label)
     851             : {
     852         173 :     branchTestNumberImpl(cond, value, label);
     853         173 : }
     854             : 
     855             : template <typename T>
     856             : void
     857         174 : MacroAssembler::branchTestNumberImpl(Condition cond, const T& t, Label* label)
     858             : {
     859         174 :     cond = testNumber(cond, t);
     860         174 :     j(cond, label);
     861         174 : }
     862             : 
     863             : void
     864          52 : MacroAssembler::branchTestBoolean(Condition cond, Register tag, Label* label)
     865             : {
     866          52 :     branchTestBooleanImpl(cond, tag, label);
     867          52 : }
     868             : 
     869             : void
     870           0 : MacroAssembler::branchTestBoolean(Condition cond, const Address& address, Label* label)
     871             : {
     872           0 :     branchTestBooleanImpl(cond, address, label);
     873           0 : }
     874             : 
     875             : void
     876             : MacroAssembler::branchTestBoolean(Condition cond, const BaseIndex& address, Label* label)
     877             : {
     878             :     branchTestBooleanImpl(cond, address, label);
     879             : }
     880             : 
     881             : void
     882        1613 : MacroAssembler::branchTestBoolean(Condition cond, const ValueOperand& value, Label* label)
     883             : {
     884        1613 :     branchTestBooleanImpl(cond, value, label);
     885        1613 : }
     886             : 
     887             : template <typename T>
     888             : void
     889        1665 : MacroAssembler::branchTestBooleanImpl(Condition cond, const T& t, Label* label)
     890             : {
     891        1665 :     cond = testBoolean(cond, t);
     892        1665 :     j(cond, label);
     893        1665 : }
     894             : 
     895             : void
     896          25 : MacroAssembler::branchTestString(Condition cond, Register tag, Label* label)
     897             : {
     898          25 :     branchTestStringImpl(cond, tag, label);
     899          25 : }
     900             : 
     901             : void
     902             : MacroAssembler::branchTestString(Condition cond, const BaseIndex& address, Label* label)
     903             : {
     904             :     branchTestStringImpl(cond, address, label);
     905             : }
     906             : 
     907             : void
     908         312 : MacroAssembler::branchTestString(Condition cond, const ValueOperand& value, Label* label)
     909             : {
     910         312 :     branchTestStringImpl(cond, value, label);
     911         312 : }
     912             : 
     913             : template <typename T>
     914             : void
     915         337 : MacroAssembler::branchTestStringImpl(Condition cond, const T& t, Label* label)
     916             : {
     917         337 :     cond = testString(cond, t);
     918         337 :     j(cond, label);
     919         337 : }
     920             : 
     921             : void
     922          21 : MacroAssembler::branchTestStringTruthy(bool truthy, const ValueOperand& value, Label* label)
     923             : {
     924          21 :     Condition cond = testStringTruthy(truthy, value);
     925          21 :     j(cond, label);
     926          21 : }
     927             : 
     928             : void
     929           0 : MacroAssembler::branchTestSymbol(Condition cond, Register tag, Label* label)
     930             : {
     931           0 :     branchTestSymbolImpl(cond, tag, label);
     932           0 : }
     933             : 
     934             : void
     935             : MacroAssembler::branchTestSymbol(Condition cond, const BaseIndex& address, Label* label)
     936             : {
     937             :     branchTestSymbolImpl(cond, address, label);
     938             : }
     939             : 
     940             : void
     941          21 : MacroAssembler::branchTestSymbol(Condition cond, const ValueOperand& value, Label* label)
     942             : {
     943          21 :     branchTestSymbolImpl(cond, value, label);
     944          21 : }
     945             : 
     946             : template <typename T>
     947             : void
     948          21 : MacroAssembler::branchTestSymbolImpl(Condition cond, const T& t, Label* label)
     949             : {
     950          21 :     cond = testSymbol(cond, t);
     951          21 :     j(cond, label);
     952          21 : }
     953             : 
     954             : void
     955           3 : MacroAssembler::branchTestNull(Condition cond, Register tag, Label* label)
     956             : {
     957           3 :     branchTestNullImpl(cond, tag, label);
     958           3 : }
     959             : 
     960             : void
     961           4 : MacroAssembler::branchTestNull(Condition cond, const Address& address, Label* label)
     962             : {
     963           4 :     branchTestNullImpl(cond, address, label);
     964           4 : }
     965             : 
     966             : void
     967             : MacroAssembler::branchTestNull(Condition cond, const BaseIndex& address, Label* label)
     968             : {
     969             :     branchTestNullImpl(cond, address, label);
     970             : }
     971             : 
     972             : void
     973         243 : MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value, Label* label)
     974             : {
     975         243 :     branchTestNullImpl(cond, value, label);
     976         243 : }
     977             : 
     978             : template <typename T>
     979             : void
     980         250 : MacroAssembler::branchTestNullImpl(Condition cond, const T& t, Label* label)
     981             : {
     982         250 :     cond = testNull(cond, t);
     983         250 :     j(cond, label);
     984         250 : }
     985             : 
     986             : void
     987          38 : MacroAssembler::branchTestObject(Condition cond, Register tag, Label* label)
     988             : {
     989          38 :     branchTestObjectImpl(cond, tag, label);
     990          38 : }
     991             : 
     992             : void
     993          24 : MacroAssembler::branchTestObject(Condition cond, const Address& address, Label* label)
     994             : {
     995          24 :     branchTestObjectImpl(cond, address, label);
     996          24 : }
     997             : 
     998             : void
     999           2 : MacroAssembler::branchTestObject(Condition cond, const BaseIndex& address, Label* label)
    1000             : {
    1001           2 :     branchTestObjectImpl(cond, address, label);
    1002           2 : }
    1003             : 
    1004             : void
    1005        1605 : MacroAssembler::branchTestObject(Condition cond, const ValueOperand& value, Label* label)
    1006             : {
    1007        1605 :     branchTestObjectImpl(cond, value, label);
    1008        1605 : }
    1009             : 
    1010             : template <typename T>
    1011             : void
    1012        1669 : MacroAssembler::branchTestObjectImpl(Condition cond, const T& t, Label* label)
    1013             : {
    1014        1669 :     cond = testObject(cond, t);
    1015        1669 :     j(cond, label);
    1016        1669 : }
    1017             : 
    1018             : void
    1019         190 : MacroAssembler::branchTestGCThing(Condition cond, const Address& address, Label* label)
    1020             : {
    1021         190 :     branchTestGCThingImpl(cond, address, label);
    1022         190 : }
    1023             : 
    1024             : void
    1025          17 : MacroAssembler::branchTestGCThing(Condition cond, const BaseIndex& address, Label* label)
    1026             : {
    1027          17 :     branchTestGCThingImpl(cond, address, label);
    1028          17 : }
    1029             : 
    1030             : template <typename T>
    1031             : void
    1032         207 : MacroAssembler::branchTestGCThingImpl(Condition cond, const T& t, Label* label)
    1033             : {
    1034         207 :     cond = testGCThing(cond, t);
    1035         207 :     j(cond, label);
    1036         207 : }
    1037             : 
    1038             : void
    1039             : MacroAssembler::branchTestPrimitive(Condition cond, Register tag, Label* label)
    1040             : {
    1041             :     branchTestPrimitiveImpl(cond, tag, label);
    1042             : }
    1043             : 
    1044             : void
    1045           4 : MacroAssembler::branchTestPrimitive(Condition cond, const ValueOperand& value, Label* label)
    1046             : {
    1047           4 :     branchTestPrimitiveImpl(cond, value, label);
    1048           4 : }
    1049             : 
    1050             : template <typename T>
    1051             : void
    1052           4 : MacroAssembler::branchTestPrimitiveImpl(Condition cond, const T& t, Label* label)
    1053             : {
    1054           4 :     cond = testPrimitive(cond, t);
    1055           4 :     j(cond, label);
    1056           4 : }
    1057             : 
    1058             : void
    1059           0 : MacroAssembler::branchTestMagic(Condition cond, Register tag, Label* label)
    1060             : {
    1061           0 :     branchTestMagicImpl(cond, tag, label);
    1062           0 : }
    1063             : 
    1064             : void
    1065          28 : MacroAssembler::branchTestMagic(Condition cond, const Address& address, Label* label)
    1066             : {
    1067          28 :     branchTestMagicImpl(cond, address, label);
    1068          28 : }
    1069             : 
    1070             : void
    1071          21 : MacroAssembler::branchTestMagic(Condition cond, const BaseIndex& address, Label* label)
    1072             : {
    1073          21 :     branchTestMagicImpl(cond, address, label);
    1074          21 : }
    1075             : 
    1076             : template <class L>
    1077             : void
    1078          12 : MacroAssembler::branchTestMagic(Condition cond, const ValueOperand& value, L label)
    1079             : {
    1080          12 :     branchTestMagicImpl(cond, value, label);
    1081          12 : }
    1082             : 
    1083             : template <typename T, class L>
    1084             : void
    1085          61 : MacroAssembler::branchTestMagicImpl(Condition cond, const T& t, L label)
    1086             : {
    1087          61 :     cond = testMagic(cond, t);
    1088          61 :     j(cond, label);
    1089          61 : }
    1090             : 
    1091             : // ========================================================================
    1092             : // Canonicalization primitives.
    1093             : void
    1094             : MacroAssembler::canonicalizeFloat32x4(FloatRegister reg, FloatRegister scratch)
    1095             : {
    1096             :     ScratchSimd128Scope scratch2(*this);
    1097             : 
    1098             :     MOZ_ASSERT(scratch.asSimd128() != scratch2.asSimd128());
    1099             :     MOZ_ASSERT(reg.asSimd128() != scratch2.asSimd128());
    1100             :     MOZ_ASSERT(reg.asSimd128() != scratch.asSimd128());
    1101             : 
    1102             :     FloatRegister mask = scratch;
    1103             :     vcmpordps(Operand(reg), reg, mask);
    1104             : 
    1105             :     FloatRegister ifFalse = scratch2;
    1106             :     float nanf = float(JS::GenericNaN());
    1107             :     loadConstantSimd128Float(SimdConstant::SplatX4(nanf), ifFalse);
    1108             : 
    1109             :     bitwiseAndSimd128(Operand(mask), reg);
    1110             :     bitwiseAndNotSimd128(Operand(ifFalse), mask);
    1111             :     bitwiseOrSimd128(Operand(mask), reg);
    1112             : }
    1113             : 
    1114             : // ========================================================================
    1115             : // Memory access primitives.
    1116             : void
    1117           6 : MacroAssembler::storeUncanonicalizedDouble(FloatRegister src, const Address& dest)
    1118             : {
    1119           6 :     vmovsd(src, dest);
    1120           6 : }
    1121             : void
    1122           0 : MacroAssembler::storeUncanonicalizedDouble(FloatRegister src, const BaseIndex& dest)
    1123             : {
    1124           0 :     vmovsd(src, dest);
    1125           0 : }
    1126             : void
    1127           0 : MacroAssembler::storeUncanonicalizedDouble(FloatRegister src, const Operand& dest)
    1128             : {
    1129           0 :     switch (dest.kind()) {
    1130             :       case Operand::MEM_REG_DISP:
    1131           0 :         storeUncanonicalizedDouble(src, dest.toAddress());
    1132           0 :         break;
    1133             :       case Operand::MEM_SCALE:
    1134           0 :         storeUncanonicalizedDouble(src, dest.toBaseIndex());
    1135           0 :         break;
    1136             :       default:
    1137           0 :         MOZ_CRASH("unexpected operand kind");
    1138             :     }
    1139           0 : }
    1140             : 
    1141             : template void MacroAssembler::storeDouble(FloatRegister src, const Operand& dest);
    1142             : 
    1143             : void
    1144           0 : MacroAssembler::storeUncanonicalizedFloat32(FloatRegister src, const Address& dest)
    1145             : {
    1146           0 :     vmovss(src, dest);
    1147           0 : }
    1148             : void
    1149           0 : MacroAssembler::storeUncanonicalizedFloat32(FloatRegister src, const BaseIndex& dest)
    1150             : {
    1151           0 :     vmovss(src, dest);
    1152           0 : }
    1153             : void
    1154           0 : MacroAssembler::storeUncanonicalizedFloat32(FloatRegister src, const Operand& dest)
    1155             : {
    1156           0 :     switch (dest.kind()) {
    1157             :       case Operand::MEM_REG_DISP:
    1158           0 :         storeUncanonicalizedFloat32(src, dest.toAddress());
    1159           0 :         break;
    1160             :       case Operand::MEM_SCALE:
    1161           0 :         storeUncanonicalizedFloat32(src, dest.toBaseIndex());
    1162           0 :         break;
    1163             :       default:
    1164           0 :         MOZ_CRASH("unexpected operand kind");
    1165             :     }
    1166           0 : }
    1167             : 
    1168             : template void MacroAssembler::storeFloat32(FloatRegister src, const Operand& dest);
    1169             : 
    1170             : void
    1171           0 : MacroAssembler::storeFloat32x3(FloatRegister src, const Address& dest)
    1172             : {
    1173           0 :     Address destZ(dest);
    1174           0 :     destZ.offset += 2 * sizeof(int32_t);
    1175           0 :     storeDouble(src, dest);
    1176           0 :     ScratchSimd128Scope scratch(*this);
    1177           0 :     vmovhlps(src, scratch, scratch);
    1178           0 :     storeFloat32(scratch, destZ);
    1179           0 : }
    1180             : void
    1181           0 : MacroAssembler::storeFloat32x3(FloatRegister src, const BaseIndex& dest)
    1182             : {
    1183           0 :     BaseIndex destZ(dest);
    1184           0 :     destZ.offset += 2 * sizeof(int32_t);
    1185           0 :     storeDouble(src, dest);
    1186           0 :     ScratchSimd128Scope scratch(*this);
    1187           0 :     vmovhlps(src, scratch, scratch);
    1188           0 :     storeFloat32(scratch, destZ);
    1189           0 : }
    1190             : 
    1191             : void
    1192           0 : MacroAssembler::memoryBarrier(MemoryBarrierBits barrier)
    1193             : {
    1194           0 :     if (barrier & MembarStoreLoad)
    1195           0 :         storeLoadFence();
    1196           0 : }
    1197             : 
    1198             : // ========================================================================
    1199             : // Truncate floating point.
    1200             : 
    1201             : void
    1202             : MacroAssembler::truncateFloat32ToInt64(Address src, Address dest, Register temp)
    1203             : {
    1204             :     if (Assembler::HasSSE3()) {
    1205             :         fld32(Operand(src));
    1206             :         fisttp(Operand(dest));
    1207             :         return;
    1208             :     }
    1209             : 
    1210             :     if (src.base == esp)
    1211             :         src.offset += 2 * sizeof(int32_t);
    1212             :     if (dest.base == esp)
    1213             :         dest.offset += 2 * sizeof(int32_t);
    1214             : 
    1215             :     reserveStack(2 * sizeof(int32_t));
    1216             : 
    1217             :     // Set conversion to truncation.
    1218             :     fnstcw(Operand(esp, 0));
    1219             :     load32(Operand(esp, 0), temp);
    1220             :     andl(Imm32(~0xFF00), temp);
    1221             :     orl(Imm32(0xCFF), temp);
    1222             :     store32(temp, Address(esp, sizeof(int32_t)));
    1223             :     fldcw(Operand(esp, sizeof(int32_t)));
    1224             : 
    1225             :     // Load double on fp stack, convert and load regular stack.
    1226             :     fld32(Operand(src));
    1227             :     fistp(Operand(dest));
    1228             : 
    1229             :     // Reset the conversion flag.
    1230             :     fldcw(Operand(esp, 0));
    1231             : 
    1232             :     freeStack(2 * sizeof(int32_t));
    1233             : }
    1234             : void
    1235             : MacroAssembler::truncateDoubleToInt64(Address src, Address dest, Register temp)
    1236             : {
    1237             :     if (Assembler::HasSSE3()) {
    1238             :         fld(Operand(src));
    1239             :         fisttp(Operand(dest));
    1240             :         return;
    1241             :     }
    1242             : 
    1243             :     if (src.base == esp)
    1244             :         src.offset += 2*sizeof(int32_t);
    1245             :     if (dest.base == esp)
    1246             :         dest.offset += 2*sizeof(int32_t);
    1247             : 
    1248             :     reserveStack(2*sizeof(int32_t));
    1249             : 
    1250             :     // Set conversion to truncation.
    1251             :     fnstcw(Operand(esp, 0));
    1252             :     load32(Operand(esp, 0), temp);
    1253             :     andl(Imm32(~0xFF00), temp);
    1254             :     orl(Imm32(0xCFF), temp);
    1255             :     store32(temp, Address(esp, 1*sizeof(int32_t)));
    1256             :     fldcw(Operand(esp, 1*sizeof(int32_t)));
    1257             : 
    1258             :     // Load double on fp stack, convert and load regular stack.
    1259             :     fld(Operand(src));
    1260             :     fistp(Operand(dest));
    1261             : 
    1262             :     // Reset the conversion flag.
    1263             :     fldcw(Operand(esp, 0));
    1264             : 
    1265             :     freeStack(2*sizeof(int32_t));
    1266             : }
    1267             : 
    1268             : // ===============================================================
    1269             : // Clamping functions.
    1270             : 
    1271             : void
    1272           0 : MacroAssembler::clampIntToUint8(Register reg)
    1273             : {
    1274           0 :     Label inRange;
    1275           0 :     branchTest32(Assembler::Zero, reg, Imm32(0xffffff00), &inRange);
    1276             :     {
    1277           0 :         sarl(Imm32(31), reg);
    1278           0 :         notl(reg);
    1279           0 :         andl(Imm32(255), reg);
    1280             :     }
    1281           0 :     bind(&inRange);
    1282           0 : }
    1283             : 
    1284             : //}}} check_macroassembler_style
    1285             : // ===============================================================
    1286             : 
    1287             : } // namespace jit
    1288             : } // namespace js
    1289             : 
    1290             : #endif /* jit_x86_shared_MacroAssembler_x86_shared_inl_h */

Generated by: LCOV version 1.13