LCOV - code coverage report
Current view: top level - js/src/jit/x64 - MacroAssembler-x64-inl.h (source / functions) Hit Total Coverage
Test: output.info Lines: 115 405 28.4 %
Date: 2017-07-14 16:53:18 Functions: 24 89 27.0 %
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_x64_MacroAssembler_x64_inl_h
       8             : #define jit_x64_MacroAssembler_x64_inl_h
       9             : 
      10             : #include "jit/x64/MacroAssembler-x64.h"
      11             : 
      12             : #include "jit/x86-shared/MacroAssembler-x86-shared-inl.h"
      13             : 
      14             : namespace js {
      15             : namespace jit {
      16             : 
      17             : //{{{ check_macroassembler_style
      18             : // ===============================================================
      19             : 
      20             : void
      21           0 : MacroAssembler::move64(Imm64 imm, Register64 dest)
      22             : {
      23           0 :     movq(ImmWord(imm.value), dest.reg);
      24           0 : }
      25             : 
      26             : void
      27           0 : MacroAssembler::move64(Register64 src, Register64 dest)
      28             : {
      29           0 :     movq(src.reg, dest.reg);
      30           0 : }
      31             : 
      32             : void
      33           0 : MacroAssembler::andPtr(Register src, Register dest)
      34             : {
      35           0 :     andq(src, dest);
      36           0 : }
      37             : 
      38             : void
      39        1334 : MacroAssembler::andPtr(Imm32 imm, Register dest)
      40             : {
      41        1334 :     andq(imm, dest);
      42        1334 : }
      43             : 
      44             : void
      45           0 : MacroAssembler::and64(Imm64 imm, Register64 dest)
      46             : {
      47           0 :     if (INT32_MIN <= int64_t(imm.value) && int64_t(imm.value) <= INT32_MAX) {
      48           0 :         andq(Imm32(imm.value), dest.reg);
      49             :     } else {
      50           0 :         ScratchRegisterScope scratch(*this);
      51           0 :         movq(ImmWord(uintptr_t(imm.value)), scratch);
      52           0 :         andq(scratch, dest.reg);
      53             :     }
      54           0 : }
      55             : 
      56             : void
      57           0 : MacroAssembler::or64(Imm64 imm, Register64 dest)
      58             : {
      59           0 :     if (INT32_MIN <= int64_t(imm.value) && int64_t(imm.value) <= INT32_MAX) {
      60           0 :         orq(Imm32(imm.value), dest.reg);
      61             :     } else {
      62           0 :         ScratchRegisterScope scratch(*this);
      63           0 :         movq(ImmWord(uintptr_t(imm.value)), scratch);
      64           0 :         orq(scratch, dest.reg);
      65             :     }
      66           0 : }
      67             : 
      68             : void
      69           0 : MacroAssembler::xor64(Imm64 imm, Register64 dest)
      70             : {
      71           0 :     if (INT32_MIN <= int64_t(imm.value) && int64_t(imm.value) <= INT32_MAX) {
      72           0 :         xorq(Imm32(imm.value), dest.reg);
      73             :     } else {
      74           0 :         ScratchRegisterScope scratch(*this);
      75           0 :         movq(ImmWord(uintptr_t(imm.value)), scratch);
      76           0 :         xorq(scratch, dest.reg);
      77             :     }
      78           0 : }
      79             : 
      80             : void
      81           6 : MacroAssembler::orPtr(Register src, Register dest)
      82             : {
      83           6 :     orq(src, dest);
      84           6 : }
      85             : 
      86             : void
      87        2084 : MacroAssembler::orPtr(Imm32 imm, Register dest)
      88             : {
      89        2084 :     orq(imm, dest);
      90        2084 : }
      91             : 
      92             : void
      93           0 : MacroAssembler::and64(Register64 src, Register64 dest)
      94             : {
      95           0 :     andq(src.reg, dest.reg);
      96           0 : }
      97             : 
      98             : void
      99           0 : MacroAssembler::or64(Register64 src, Register64 dest)
     100             : {
     101           0 :     orq(src.reg, dest.reg);
     102           0 : }
     103             : 
     104             : void
     105           0 : MacroAssembler::xor64(Register64 src, Register64 dest)
     106             : {
     107           0 :     xorq(src.reg, dest.reg);
     108           0 : }
     109             : 
     110             : void
     111           0 : MacroAssembler::xorPtr(Register src, Register dest)
     112             : {
     113           0 :     xorq(src, dest);
     114           0 : }
     115             : 
     116             : void
     117             : MacroAssembler::xorPtr(Imm32 imm, Register dest)
     118             : {
     119             :     xorq(imm, dest);
     120             : }
     121             : 
     122             : void
     123           0 : MacroAssembler::and64(const Operand& src, Register64 dest)
     124             : {
     125           0 :     andq(src, dest.reg);
     126           0 : }
     127             : 
     128             : void
     129           0 : MacroAssembler::or64(const Operand& src, Register64 dest)
     130             : {
     131           0 :     orq(src, dest.reg);
     132           0 : }
     133             : 
     134             : void
     135           0 : MacroAssembler::xor64(const Operand& src, Register64 dest)
     136             : {
     137           0 :     xorq(src, dest.reg);
     138           0 : }
     139             : 
     140             : // ===============================================================
     141             : // Arithmetic functions
     142             : 
     143             : void
     144         186 : MacroAssembler::addPtr(Register src, Register dest)
     145             : {
     146         186 :     addq(src, dest);
     147         186 : }
     148             : 
     149             : void
     150       33970 : MacroAssembler::addPtr(Imm32 imm, Register dest)
     151             : {
     152       33970 :     addq(imm, dest);
     153       33969 : }
     154             : 
     155             : void
     156           1 : MacroAssembler::addPtr(ImmWord imm, Register dest)
     157             : {
     158           2 :     ScratchRegisterScope scratch(*this);
     159           1 :     MOZ_ASSERT(dest != scratch);
     160           1 :     if ((intptr_t)imm.value <= INT32_MAX && (intptr_t)imm.value >= INT32_MIN) {
     161           1 :         addq(Imm32((int32_t)imm.value), dest);
     162             :     } else {
     163           0 :         mov(imm, scratch);
     164           0 :         addq(scratch, dest);
     165             :     }
     166           1 : }
     167             : 
     168             : void
     169        7508 : MacroAssembler::addPtr(Imm32 imm, const Address& dest)
     170             : {
     171        7508 :     addq(imm, Operand(dest));
     172        7508 : }
     173             : 
     174             : void
     175           0 : MacroAssembler::addPtr(Imm32 imm, const AbsoluteAddress& dest)
     176             : {
     177           0 :     addq(imm, Operand(dest));
     178           0 : }
     179             : 
     180             : void
     181          22 : MacroAssembler::addPtr(const Address& src, Register dest)
     182             : {
     183          22 :     addq(Operand(src), dest);
     184          22 : }
     185             : 
     186             : void
     187           0 : MacroAssembler::add64(const Operand& src, Register64 dest)
     188             : {
     189           0 :     addq(src, dest.reg);
     190           0 : }
     191             : 
     192             : void
     193           0 : MacroAssembler::add64(Register64 src, Register64 dest)
     194             : {
     195           0 :     addq(src.reg, dest.reg);
     196           0 : }
     197             : 
     198             : void
     199           0 : MacroAssembler::add64(Imm32 imm, Register64 dest)
     200             : {
     201           0 :     addq(imm, dest.reg);
     202           0 : }
     203             : 
     204             : void
     205           0 : MacroAssembler::add64(Imm64 imm, Register64 dest)
     206             : {
     207           0 :     addPtr(ImmWord(imm.value), dest.reg);
     208           0 : }
     209             : 
     210             : CodeOffset
     211           0 : MacroAssembler::add32ToPtrWithPatch(Register src, Register dest)
     212             : {
     213           0 :     if (src != dest)
     214           0 :         movePtr(src, dest);
     215           0 :     addqWithPatch(Imm32(0), dest);
     216           0 :     return CodeOffset(currentOffset());
     217             : }
     218             : 
     219             : void
     220           0 : MacroAssembler::patchAdd32ToPtr(CodeOffset offset, Imm32 imm)
     221             : {
     222           0 :     patchAddq(offset, imm.value);
     223           0 : }
     224             : 
     225             : void
     226          48 : MacroAssembler::subPtr(Register src, Register dest)
     227             : {
     228          48 :     subq(src, dest);
     229          48 : }
     230             : 
     231             : void
     232             : MacroAssembler::subPtr(Register src, const Address& dest)
     233             : {
     234             :     subq(src, Operand(dest));
     235             : }
     236             : 
     237             : void
     238        2907 : MacroAssembler::subPtr(Imm32 imm, Register dest)
     239             : {
     240        2907 :     subq(imm, dest);
     241        2907 : }
     242             : 
     243             : void
     244           0 : MacroAssembler::subPtr(ImmWord imm, Register dest)
     245             : {
     246           0 :     ScratchRegisterScope scratch(*this);
     247           0 :     MOZ_ASSERT(dest != scratch);
     248           0 :     if ((intptr_t)imm.value <= INT32_MAX && (intptr_t)imm.value >= INT32_MIN) {
     249           0 :         subq(Imm32((int32_t)imm.value), dest);
     250             :     } else {
     251           0 :         mov(imm, scratch);
     252           0 :         subq(scratch, dest);
     253             :     }
     254           0 : }
     255             : 
     256             : void
     257          91 : MacroAssembler::subPtr(const Address& addr, Register dest)
     258             : {
     259          91 :     subq(Operand(addr), dest);
     260          91 : }
     261             : 
     262             : void
     263           0 : MacroAssembler::sub64(const Operand& src, Register64 dest)
     264             : {
     265           0 :     subq(src, dest.reg);
     266           0 : }
     267             : 
     268             : void
     269           0 : MacroAssembler::sub64(Register64 src, Register64 dest)
     270             : {
     271           0 :     subq(src.reg, dest.reg);
     272           0 : }
     273             : 
     274             : void
     275           0 : MacroAssembler::sub64(Imm64 imm, Register64 dest)
     276             : {
     277           0 :     subPtr(ImmWord(imm.value), dest.reg);
     278           0 : }
     279             : 
     280             : void
     281           0 : MacroAssembler::mul64(Imm64 imm, const Register64& dest, const Register temp)
     282             : {
     283           0 :     MOZ_ASSERT(temp == InvalidReg);
     284           0 :     mul64(imm, dest);
     285           0 : }
     286             : 
     287             : void
     288           0 : MacroAssembler::mul64(Imm64 imm, const Register64& dest)
     289             : {
     290           0 :     movq(ImmWord(uintptr_t(imm.value)), ScratchReg);
     291           0 :     imulq(ScratchReg, dest.reg);
     292           0 : }
     293             : 
     294             : void
     295           0 : MacroAssembler::mul64(const Register64& src, const Register64& dest, const Register temp)
     296             : {
     297           0 :     MOZ_ASSERT(temp == InvalidReg);
     298           0 :     mul64(Operand(src.reg), dest);
     299           0 : }
     300             : 
     301             : void
     302           0 : MacroAssembler::mul64(const Operand& src, const Register64& dest)
     303             : {
     304           0 :     imulq(src, dest.reg);
     305           0 : }
     306             : 
     307             : void
     308           0 : MacroAssembler::mul64(const Operand& src, const Register64& dest, const Register temp)
     309             : {
     310           0 :     MOZ_ASSERT(temp == InvalidReg);
     311           0 :     mul64(src, dest);
     312           0 : }
     313             : 
     314             : void
     315           0 : MacroAssembler::mulBy3(Register src, Register dest)
     316             : {
     317           0 :     lea(Operand(src, src, TimesTwo), dest);
     318           0 : }
     319             : 
     320             : void
     321           0 : MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest)
     322             : {
     323           0 :     movq(imm, ScratchReg);
     324           0 :     vmulsd(Operand(ScratchReg, 0), dest, dest);
     325           0 : }
     326             : 
     327             : void
     328        7452 : MacroAssembler::inc64(AbsoluteAddress dest)
     329             : {
     330        7452 :     if (X86Encoding::IsAddressImmediate(dest.addr)) {
     331           0 :         addPtr(Imm32(1), dest);
     332             :     } else {
     333       14904 :         ScratchRegisterScope scratch(*this);
     334        7452 :         mov(ImmPtr(dest.addr), scratch);
     335        7452 :         addPtr(Imm32(1), Address(scratch, 0));
     336             :     }
     337        7452 : }
     338             : 
     339             : void
     340           0 : MacroAssembler::neg64(Register64 reg)
     341             : {
     342           0 :     negq(reg.reg);
     343           0 : }
     344             : 
     345             : // ===============================================================
     346             : // Shift functions
     347             : 
     348             : void
     349        1668 : MacroAssembler::lshiftPtr(Imm32 imm, Register dest)
     350             : {
     351        1668 :     MOZ_ASSERT(0 <= imm.value && imm.value < 64);
     352        1668 :     shlq(imm, dest);
     353        1668 : }
     354             : 
     355             : void
     356           0 : MacroAssembler::lshift64(Imm32 imm, Register64 dest)
     357             : {
     358           0 :     MOZ_ASSERT(0 <= imm.value && imm.value < 64);
     359           0 :     lshiftPtr(imm, dest.reg);
     360           0 : }
     361             : 
     362             : void
     363           0 : MacroAssembler::lshift64(Register shift, Register64 srcDest)
     364             : {
     365           0 :     MOZ_ASSERT(shift == rcx);
     366           0 :     shlq_cl(srcDest.reg);
     367           0 : }
     368             : 
     369             : void
     370          15 : MacroAssembler::rshiftPtr(Imm32 imm, Register dest)
     371             : {
     372          15 :     MOZ_ASSERT(0 <= imm.value && imm.value < 64);
     373          15 :     shrq(imm, dest);
     374          15 : }
     375             : 
     376             : void
     377           0 : MacroAssembler::rshift64(Imm32 imm, Register64 dest)
     378             : {
     379           0 :     rshiftPtr(imm, dest.reg);
     380           0 : }
     381             : 
     382             : void
     383           0 : MacroAssembler::rshift64(Register shift, Register64 srcDest)
     384             : {
     385           0 :     MOZ_ASSERT(shift == rcx);
     386           0 :     shrq_cl(srcDest.reg);
     387           0 : }
     388             : 
     389             : void
     390          17 : MacroAssembler::rshiftPtrArithmetic(Imm32 imm, Register dest)
     391             : {
     392          17 :     MOZ_ASSERT(0 <= imm.value && imm.value < 64);
     393          17 :     sarq(imm, dest);
     394          17 : }
     395             : 
     396             : void
     397           0 : MacroAssembler::rshift64Arithmetic(Imm32 imm, Register64 dest)
     398             : {
     399           0 :     MOZ_ASSERT(0 <= imm.value && imm.value < 64);
     400           0 :     rshiftPtrArithmetic(imm, dest.reg);
     401           0 : }
     402             : 
     403             : void
     404           0 : MacroAssembler::rshift64Arithmetic(Register shift, Register64 srcDest)
     405             : {
     406           0 :     MOZ_ASSERT(shift == rcx);
     407           0 :     sarq_cl(srcDest.reg);
     408           0 : }
     409             : 
     410             : // ===============================================================
     411             : // Rotation functions
     412             : 
     413             : void
     414           0 : MacroAssembler::rotateLeft64(Register count, Register64 src, Register64 dest)
     415             : {
     416           0 :     MOZ_ASSERT(src == dest, "defineReuseInput");
     417           0 :     MOZ_ASSERT(count == ecx, "defineFixed(ecx)");
     418             : 
     419           0 :     rolq_cl(dest.reg);
     420           0 : }
     421             : 
     422             : void
     423           0 : MacroAssembler::rotateLeft64(Register count, Register64 src, Register64 dest, Register temp)
     424             : {
     425           0 :     MOZ_ASSERT(temp == InvalidReg);
     426           0 :     rotateLeft64(count, src, dest);
     427           0 : }
     428             : 
     429             : void
     430           0 : MacroAssembler::rotateRight64(Register count, Register64 src, Register64 dest)
     431             : {
     432           0 :     MOZ_ASSERT(src == dest, "defineReuseInput");
     433           0 :     MOZ_ASSERT(count == ecx, "defineFixed(ecx)");
     434             : 
     435           0 :     rorq_cl(dest.reg);
     436           0 : }
     437             : 
     438             : void
     439           0 : MacroAssembler::rotateRight64(Register count, Register64 src, Register64 dest, Register temp)
     440             : {
     441           0 :     MOZ_ASSERT(temp == InvalidReg);
     442           0 :     rotateRight64(count, src, dest);
     443           0 : }
     444             : 
     445             : void
     446           0 : MacroAssembler::rotateLeft64(Imm32 count, Register64 src, Register64 dest)
     447             : {
     448           0 :     MOZ_ASSERT(src == dest, "defineReuseInput");
     449           0 :     rolq(count, dest.reg);
     450           0 : }
     451             : 
     452             : void
     453           0 : MacroAssembler::rotateLeft64(Imm32 count, Register64 src, Register64 dest, Register temp)
     454             : {
     455           0 :     MOZ_ASSERT(temp == InvalidReg);
     456           0 :     rotateLeft64(count, src, dest);
     457           0 : }
     458             : 
     459             : void
     460           0 : MacroAssembler::rotateRight64(Imm32 count, Register64 src, Register64 dest)
     461             : {
     462           0 :     MOZ_ASSERT(src == dest, "defineReuseInput");
     463           0 :     rorq(count, dest.reg);
     464           0 : }
     465             : 
     466             : void
     467           0 : MacroAssembler::rotateRight64(Imm32 count, Register64 src, Register64 dest, Register temp)
     468             : {
     469           0 :     MOZ_ASSERT(temp == InvalidReg);
     470           0 :     rotateRight64(count, src, dest);
     471           0 : }
     472             : 
     473             : // ===============================================================
     474             : // Condition functions
     475             : 
     476             : template <typename T1, typename T2>
     477             : void
     478          11 : MacroAssembler::cmpPtrSet(Condition cond, T1 lhs, T2 rhs, Register dest)
     479             : {
     480          11 :     cmpPtr(lhs, rhs);
     481          11 :     emitSet(cond, dest);
     482          11 : }
     483             : 
     484             : // ===============================================================
     485             : // Bit counting functions
     486             : 
     487             : void
     488           0 : MacroAssembler::clz64(Register64 src, Register dest)
     489             : {
     490             :     // On very recent chips (Haswell and newer) there is actually an
     491             :     // LZCNT instruction that does all of this.
     492             : 
     493           0 :     Label nonzero;
     494           0 :     bsrq(src.reg, dest);
     495           0 :     j(Assembler::NonZero, &nonzero);
     496           0 :     movq(ImmWord(0x7F), dest);
     497           0 :     bind(&nonzero);
     498           0 :     xorq(Imm32(0x3F), dest);
     499           0 : }
     500             : 
     501             : void
     502           0 : MacroAssembler::ctz64(Register64 src, Register dest)
     503             : {
     504           0 :     Label nonzero;
     505           0 :     bsfq(src.reg, dest);
     506           0 :     j(Assembler::NonZero, &nonzero);
     507           0 :     movq(ImmWord(64), dest);
     508           0 :     bind(&nonzero);
     509           0 : }
     510             : 
     511             : void
     512           0 : MacroAssembler::popcnt64(Register64 src64, Register64 dest64, Register tmp)
     513             : {
     514           0 :     Register src = src64.reg;
     515           0 :     Register dest = dest64.reg;
     516             : 
     517           0 :     if (AssemblerX86Shared::HasPOPCNT()) {
     518           0 :         MOZ_ASSERT(tmp == InvalidReg);
     519           0 :         popcntq(src, dest);
     520           0 :         return;
     521             :     }
     522             : 
     523           0 :     if (src != dest)
     524           0 :         movq(src, dest);
     525             : 
     526           0 :     MOZ_ASSERT(tmp != dest);
     527             : 
     528           0 :     ScratchRegisterScope scratch(*this);
     529             : 
     530             :     // Equivalent to mozilla::CountPopulation32, adapted for 64 bits.
     531             :     // x -= (x >> 1) & m1;
     532           0 :     movq(src, tmp);
     533           0 :     movq(ImmWord(0x5555555555555555), scratch);
     534           0 :     shrq(Imm32(1), tmp);
     535           0 :     andq(scratch, tmp);
     536           0 :     subq(tmp, dest);
     537             : 
     538             :     // x = (x & m2) + ((x >> 2) & m2);
     539           0 :     movq(dest, tmp);
     540           0 :     movq(ImmWord(0x3333333333333333), scratch);
     541           0 :     andq(scratch, dest);
     542           0 :     shrq(Imm32(2), tmp);
     543           0 :     andq(scratch, tmp);
     544           0 :     addq(tmp, dest);
     545             : 
     546             :     // x = (x + (x >> 4)) & m4;
     547           0 :     movq(dest, tmp);
     548           0 :     movq(ImmWord(0x0f0f0f0f0f0f0f0f), scratch);
     549           0 :     shrq(Imm32(4), tmp);
     550           0 :     addq(tmp, dest);
     551           0 :     andq(scratch, dest);
     552             : 
     553             :     // (x * h01) >> 56
     554           0 :     movq(ImmWord(0x0101010101010101), scratch);
     555           0 :     imulq(scratch, dest);
     556           0 :     shrq(Imm32(56), dest);
     557             : }
     558             : 
     559             : // ===============================================================
     560             : // Branch functions
     561             : 
     562             : void
     563             : MacroAssembler::branch32(Condition cond, const AbsoluteAddress& lhs, Register rhs, Label* label)
     564             : {
     565             :     if (X86Encoding::IsAddressImmediate(lhs.addr)) {
     566             :         branch32(cond, Operand(lhs), rhs, label);
     567             :     } else {
     568             :         ScratchRegisterScope scratch(*this);
     569             :         mov(ImmPtr(lhs.addr), scratch);
     570             :         branch32(cond, Address(scratch, 0), rhs, label);
     571             :     }
     572             : }
     573             : void
     574         364 : MacroAssembler::branch32(Condition cond, const AbsoluteAddress& lhs, Imm32 rhs, Label* label)
     575             : {
     576         364 :     if (X86Encoding::IsAddressImmediate(lhs.addr)) {
     577           0 :         branch32(cond, Operand(lhs), rhs, label);
     578             :     } else {
     579         728 :         ScratchRegisterScope scratch(*this);
     580         364 :         mov(ImmPtr(lhs.addr), scratch);
     581         364 :         branch32(cond, Address(scratch, 0), rhs, label);
     582             :     }
     583         364 : }
     584             : 
     585             : void
     586             : MacroAssembler::branch32(Condition cond, wasm::SymbolicAddress lhs, Imm32 rhs, Label* label)
     587             : {
     588             :     ScratchRegisterScope scratch(*this);
     589             :     mov(lhs, scratch);
     590             :     branch32(cond, Address(scratch, 0), rhs, label);
     591             : }
     592             : 
     593             : void
     594           0 : MacroAssembler::branch64(Condition cond, Register64 lhs, Imm64 val, Label* success, Label* fail)
     595             : {
     596           0 :     MOZ_ASSERT(cond == Assembler::NotEqual || cond == Assembler::Equal ||
     597             :                cond == Assembler::LessThan || cond == Assembler::LessThanOrEqual ||
     598             :                cond == Assembler::GreaterThan || cond == Assembler::GreaterThanOrEqual ||
     599             :                cond == Assembler::Below || cond == Assembler::BelowOrEqual ||
     600             :                cond == Assembler::Above || cond == Assembler::AboveOrEqual,
     601             :                "other condition codes not supported");
     602             : 
     603           0 :     branchPtr(cond, lhs.reg, ImmWord(val.value), success);
     604           0 :     if (fail)
     605           0 :         jump(fail);
     606           0 : }
     607             : 
     608             : void
     609           0 : MacroAssembler::branch64(Condition cond, Register64 lhs, Register64 rhs, Label* success, Label* fail)
     610             : {
     611           0 :     MOZ_ASSERT(cond == Assembler::NotEqual || cond == Assembler::Equal ||
     612             :                cond == Assembler::LessThan || cond == Assembler::LessThanOrEqual ||
     613             :                cond == Assembler::GreaterThan || cond == Assembler::GreaterThanOrEqual ||
     614             :                cond == Assembler::Below || cond == Assembler::BelowOrEqual ||
     615             :                cond == Assembler::Above || cond == Assembler::AboveOrEqual,
     616             :                "other condition codes not supported");
     617             : 
     618           0 :     branchPtr(cond, lhs.reg, rhs.reg, success);
     619           0 :     if (fail)
     620           0 :         jump(fail);
     621           0 : }
     622             : 
     623             : void
     624             : MacroAssembler::branch64(Condition cond, const Address& lhs, Imm64 val, Label* label)
     625             : {
     626             :     MOZ_ASSERT(cond == Assembler::NotEqual || cond == Assembler::Equal,
     627             :                "other condition codes not supported");
     628             : 
     629             :     branchPtr(cond, lhs, ImmWord(val.value), label);
     630             : }
     631             : 
     632             : void
     633           0 : MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, Register scratch,
     634             :                          Label* label)
     635             : {
     636           0 :     MOZ_ASSERT(cond == Assembler::NotEqual || cond == Assembler::Equal,
     637             :                "other condition codes not supported");
     638           0 :     MOZ_ASSERT(lhs.base != scratch);
     639           0 :     MOZ_ASSERT(rhs.base != scratch);
     640             : 
     641           0 :     loadPtr(rhs, scratch);
     642           0 :     branchPtr(cond, lhs, scratch, label);
     643           0 : }
     644             : 
     645             : void
     646          95 : MacroAssembler::branchPtr(Condition cond, const AbsoluteAddress& lhs, Register rhs, Label* label)
     647             : {
     648         190 :     ScratchRegisterScope scratch(*this);
     649          95 :     MOZ_ASSERT(rhs != scratch);
     650          95 :     if (X86Encoding::IsAddressImmediate(lhs.addr)) {
     651           0 :         branchPtrImpl(cond, Operand(lhs), rhs, label);
     652             :     } else {
     653          95 :         mov(ImmPtr(lhs.addr), scratch);
     654          95 :         branchPtrImpl(cond, Operand(scratch, 0x0), rhs, label);
     655             :     }
     656          95 : }
     657             : 
     658             : void
     659          78 : MacroAssembler::branchPtr(Condition cond, const AbsoluteAddress& lhs, ImmWord rhs, Label* label)
     660             : {
     661          78 :     if (X86Encoding::IsAddressImmediate(lhs.addr)) {
     662           0 :         branchPtrImpl(cond, Operand(lhs), rhs, label);
     663             :     } else {
     664         156 :         ScratchRegisterScope scratch(*this);
     665          78 :         mov(ImmPtr(lhs.addr), scratch);
     666          78 :         branchPtrImpl(cond, Operand(scratch, 0x0), rhs, label);
     667             :     }
     668          78 : }
     669             : 
     670             : void
     671             : MacroAssembler::branchPtr(Condition cond, wasm::SymbolicAddress lhs, Register rhs, Label* label)
     672             : {
     673             :     ScratchRegisterScope scratch(*this);
     674             :     MOZ_ASSERT(rhs != scratch);
     675             :     mov(lhs, scratch);
     676             :     branchPtrImpl(cond, Operand(scratch, 0x0), rhs, label);
     677             : }
     678             : 
     679             : void
     680           0 : MacroAssembler::branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label)
     681             : {
     682           0 :     ScratchRegisterScope scratch(*this);
     683           0 :     if (rhs != scratch)
     684           0 :         movePtr(rhs, scratch);
     685             :     // Instead of unboxing lhs, box rhs and do direct comparison with lhs.
     686           0 :     rshiftPtr(Imm32(1), scratch);
     687           0 :     branchPtr(cond, lhs, scratch, label);
     688           0 : }
     689             : 
     690             : void
     691           0 : MacroAssembler::branchTruncateFloat32ToPtr(FloatRegister src, Register dest, Label* fail)
     692             : {
     693           0 :     vcvttss2sq(src, dest);
     694             : 
     695             :     // Same trick as for Doubles
     696           0 :     cmpPtr(dest, Imm32(1));
     697           0 :     j(Assembler::Overflow, fail);
     698           0 : }
     699             : 
     700             : void
     701           0 : MacroAssembler::branchTruncateFloat32MaybeModUint32(FloatRegister src, Register dest, Label* fail)
     702             : {
     703           0 :     branchTruncateFloat32ToPtr(src, dest, fail);
     704           0 :     movl(dest, dest); // Zero upper 32-bits.
     705           0 : }
     706             : 
     707             : void
     708             : MacroAssembler::branchTruncateFloat32ToInt32(FloatRegister src, Register dest, Label* fail)
     709             : {
     710             :     branchTruncateFloat32ToPtr(src, dest, fail);
     711             :     branch32(Assembler::Above, dest, Imm32(0xffffffff), fail);
     712             : }
     713             : 
     714             : void
     715           0 : MacroAssembler::branchTruncateDoubleToPtr(FloatRegister src, Register dest, Label* fail)
     716             : {
     717           0 :     vcvttsd2sq(src, dest);
     718             : 
     719             :     // vcvttsd2sq returns 0x8000000000000000 on failure. Test for it by
     720             :     // subtracting 1 and testing overflow (this avoids the need to
     721             :     // materialize that value in a register).
     722           0 :     cmpPtr(dest, Imm32(1));
     723           0 :     j(Assembler::Overflow, fail);
     724           0 : }
     725             : 
     726             : void
     727           0 : MacroAssembler::branchTruncateDoubleMaybeModUint32(FloatRegister src, Register dest, Label* fail)
     728             : {
     729           0 :     branchTruncateDoubleToPtr(src, dest, fail);
     730           0 :     movl(dest, dest); // Zero upper 32-bits.
     731           0 : }
     732             : 
     733             : void
     734             : MacroAssembler::branchTruncateDoubleToInt32(FloatRegister src, Register dest, Label* fail)
     735             : {
     736             :     branchTruncateDoubleToPtr(src, dest, fail);
     737             :     branch32(Assembler::Above, dest, Imm32(0xffffffff), fail);
     738             : }
     739             : 
     740             : void
     741         247 : MacroAssembler::branchTest32(Condition cond, const AbsoluteAddress& lhs, Imm32 rhs, Label* label)
     742             : {
     743         247 :     if (X86Encoding::IsAddressImmediate(lhs.addr)) {
     744           0 :         test32(Operand(lhs), rhs);
     745             :     } else {
     746         494 :         ScratchRegisterScope scratch(*this);
     747         247 :         mov(ImmPtr(lhs.addr), scratch);
     748         247 :         test32(Operand(scratch, 0), rhs);
     749             :     }
     750         247 :     j(cond, label);
     751         247 : }
     752             : 
     753             : template <class L>
     754             : void
     755           0 : MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Register temp,
     756             :                              L label)
     757             : {
     758           0 :     branchTestPtr(cond, lhs.reg, rhs.reg, label);
     759           0 : }
     760             : 
     761             : void
     762        2631 : MacroAssembler::branchTestBooleanTruthy(bool truthy, const ValueOperand& value, Label* label)
     763             : {
     764        2631 :     test32(value.valueReg(), value.valueReg());
     765        2631 :     j(truthy ? NonZero : Zero, label);
     766        2631 : }
     767             : 
     768             : void
     769           0 : MacroAssembler::branchTestMagic(Condition cond, const Address& valaddr, JSWhyMagic why, Label* label)
     770             : {
     771           0 :     uint64_t magic = MagicValue(why).asRawBits();
     772           0 :     cmpPtr(valaddr, ImmWord(magic));
     773           0 :     j(cond, label);
     774           0 : }
     775             : // ========================================================================
     776             : // Truncate floating point.
     777             : 
     778             : void
     779             : MacroAssembler::truncateFloat32ToUInt64(Address src, Address dest, Register temp,
     780             :                                         FloatRegister floatTemp)
     781             : {
     782             :     Label done;
     783             : 
     784             :     loadFloat32(src, floatTemp);
     785             : 
     786             :     truncateFloat32ToInt64(src, dest, temp);
     787             : 
     788             :     // For unsigned conversion the case of [INT64, UINT64] needs to get handle seperately.
     789             :     loadPtr(dest, temp);
     790             :     branchPtr(Assembler::Condition::NotSigned, temp, Imm32(0), &done);
     791             : 
     792             :     // Move the value inside INT64 range.
     793             :     storeFloat32(floatTemp, dest);
     794             :     loadConstantFloat32(double(int64_t(0x8000000000000000)), floatTemp);
     795             :     vaddss(Operand(dest), floatTemp, floatTemp);
     796             :     storeFloat32(floatTemp, dest);
     797             :     truncateFloat32ToInt64(dest, dest, temp);
     798             : 
     799             :     loadPtr(dest, temp);
     800             :     or64(Imm64(0x8000000000000000), Register64(temp));
     801             :     storePtr(temp, dest);
     802             : 
     803             :     bind(&done);
     804             : }
     805             : 
     806             : void
     807             : MacroAssembler::truncateDoubleToUInt64(Address src, Address dest, Register temp,
     808             :                                        FloatRegister floatTemp)
     809             : {
     810             :     Label done;
     811             : 
     812             :     loadDouble(src, floatTemp);
     813             : 
     814             :     truncateDoubleToInt64(src, dest, temp);
     815             : 
     816             :     // For unsigned conversion the case of [INT64, UINT64] needs to get handle seperately.
     817             :     loadPtr(dest, temp);
     818             :     branchPtr(Assembler::Condition::NotSigned, temp, Imm32(0), &done);
     819             : 
     820             :     // Move the value inside INT64 range.
     821             :     storeDouble(floatTemp, dest);
     822             :     loadConstantDouble(double(int64_t(0x8000000000000000)), floatTemp);
     823             :     vaddsd(Operand(dest), floatTemp, floatTemp);
     824             :     storeDouble(floatTemp, dest);
     825             :     truncateDoubleToInt64(dest, dest, temp);
     826             : 
     827             :     loadPtr(dest, temp);
     828             :     or64(Imm64(0x8000000000000000), Register64(temp));
     829             :     storePtr(temp, dest);
     830             : 
     831             :     bind(&done);
     832             : }
     833             : 
     834             : //}}} check_macroassembler_style
     835             : // ===============================================================
     836             : 
     837             : void
     838          31 : MacroAssemblerX64::incrementInt32Value(const Address& addr)
     839             : {
     840          31 :     asMasm().addPtr(Imm32(1), addr);
     841          31 : }
     842             : 
     843             : void
     844           6 : MacroAssemblerX64::unboxValue(const ValueOperand& src, AnyRegister dest)
     845             : {
     846           6 :     if (dest.isFloat()) {
     847           2 :         Label notInt32, end;
     848           1 :         asMasm().branchTestInt32(Assembler::NotEqual, src, &notInt32);
     849           1 :         convertInt32ToDouble(src.valueReg(), dest.fpu());
     850           1 :         jump(&end);
     851           1 :         bind(&notInt32);
     852           1 :         unboxDouble(src, dest.fpu());
     853           1 :         bind(&end);
     854             :     } else {
     855           5 :         unboxNonDouble(src, dest.gpr());
     856             :     }
     857           6 : }
     858             : 
     859             : template <typename T>
     860             : void
     861           0 : MacroAssemblerX64::loadInt32OrDouble(const T& src, FloatRegister dest)
     862             : {
     863           0 :     Label notInt32, end;
     864           0 :     asMasm().branchTestInt32(Assembler::NotEqual, src, &notInt32);
     865           0 :     convertInt32ToDouble(src, dest);
     866           0 :     jump(&end);
     867           0 :     bind(&notInt32);
     868           0 :     loadDouble(src, dest);
     869           0 :     bind(&end);
     870           0 : }
     871             : 
     872             : // If source is a double, load it into dest. If source is int32,
     873             : // convert it to double. Else, branch to failure.
     874             : void
     875          24 : MacroAssemblerX64::ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure)
     876             : {
     877          48 :     Label isDouble, done;
     878          24 :     Register tag = splitTagForTest(source);
     879          24 :     asMasm().branchTestDouble(Assembler::Equal, tag, &isDouble);
     880          24 :     asMasm().branchTestInt32(Assembler::NotEqual, tag, failure);
     881             : 
     882          48 :     ScratchRegisterScope scratch(asMasm());
     883          24 :     unboxInt32(source, scratch);
     884          24 :     convertInt32ToDouble(scratch, dest);
     885          24 :     jump(&done);
     886             : 
     887          24 :     bind(&isDouble);
     888          24 :     unboxDouble(source, dest);
     889             : 
     890          24 :     bind(&done);
     891          24 : }
     892             : 
     893             : } // namespace jit
     894             : } // namespace js
     895             : 
     896             : #endif /* jit_x64_MacroAssembler_x64_inl_h */

Generated by: LCOV version 1.13