LCOV - code coverage report
Current view: top level - js/src/jit/x64 - SharedIC-x64.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 38 122 31.1 %
Date: 2017-07-14 16:53:18 Functions: 2 2 100.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             : #include "jit/BaselineIC.h"
       8             : #include "jit/SharedICHelpers.h"
       9             : 
      10             : #include "jit/MacroAssembler-inl.h"
      11             : 
      12             : using namespace js;
      13             : using namespace js::jit;
      14             : 
      15             : namespace js {
      16             : namespace jit {
      17             : 
      18             : // ICBinaryArith_Int32
      19             : 
      20             : bool
      21          64 : ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
      22             : {
      23             :     // Guard that R0 is an integer and R1 is an integer.
      24         128 :     Label failure;
      25          64 :     masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
      26          64 :     masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
      27             : 
      28             :     // The scratch register is only used in the case of JSOP_URSH.
      29         128 :     mozilla::Maybe<ScratchRegisterScope> scratch;
      30             : 
      31         128 :     Label revertRegister, maybeNegZero;
      32          64 :     switch(op_) {
      33             :       case JSOP_ADD:
      34          39 :         masm.unboxInt32(R0, ExtractTemp0);
      35             :         // Just jump to failure on overflow. R0 and R1 are preserved, so we can just jump to
      36             :         // the next stub.
      37          39 :         masm.addl(R1.valueReg(), ExtractTemp0);
      38          39 :         masm.j(Assembler::Overflow, &failure);
      39             : 
      40             :         // Box the result
      41          39 :         masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg());
      42          39 :         break;
      43             :       case JSOP_SUB:
      44           9 :         masm.unboxInt32(R0, ExtractTemp0);
      45           9 :         masm.subl(R1.valueReg(), ExtractTemp0);
      46           9 :         masm.j(Assembler::Overflow, &failure);
      47           9 :         masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg());
      48           9 :         break;
      49             :       case JSOP_MUL:
      50           0 :         masm.unboxInt32(R0, ExtractTemp0);
      51           0 :         masm.imull(R1.valueReg(), ExtractTemp0);
      52           0 :         masm.j(Assembler::Overflow, &failure);
      53             : 
      54           0 :         masm.branchTest32(Assembler::Zero, ExtractTemp0, ExtractTemp0, &maybeNegZero);
      55             : 
      56           0 :         masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg());
      57           0 :         break;
      58             :       case JSOP_DIV:
      59             :       {
      60           0 :         MOZ_ASSERT(R2.scratchReg() == rax);
      61           0 :         MOZ_ASSERT(R0.valueReg() != rdx);
      62           0 :         MOZ_ASSERT(R1.valueReg() != rdx);
      63           0 :         masm.unboxInt32(R0, eax);
      64           0 :         masm.unboxInt32(R1, ExtractTemp0);
      65             : 
      66             :         // Prevent division by 0.
      67           0 :         masm.branchTest32(Assembler::Zero, ExtractTemp0, ExtractTemp0, &failure);
      68             : 
      69             :         // Prevent negative 0 and -2147483648 / -1.
      70           0 :         masm.branch32(Assembler::Equal, eax, Imm32(INT32_MIN), &failure);
      71             : 
      72           0 :         Label notZero;
      73           0 :         masm.branch32(Assembler::NotEqual, eax, Imm32(0), &notZero);
      74           0 :         masm.branchTest32(Assembler::Signed, ExtractTemp0, ExtractTemp0, &failure);
      75           0 :         masm.bind(&notZero);
      76             : 
      77             :         // Sign extend eax into edx to make (edx:eax), since idiv is 64-bit.
      78           0 :         masm.cdq();
      79           0 :         masm.idiv(ExtractTemp0);
      80             : 
      81             :         // A remainder implies a double result.
      82           0 :         masm.branchTest32(Assembler::NonZero, edx, edx, &failure);
      83             : 
      84           0 :         masm.boxValue(JSVAL_TYPE_INT32, eax, R0.valueReg());
      85           0 :         break;
      86             :       }
      87             :       case JSOP_MOD:
      88             :       {
      89           0 :         MOZ_ASSERT(R2.scratchReg() == rax);
      90           0 :         MOZ_ASSERT(R0.valueReg() != rdx);
      91           0 :         MOZ_ASSERT(R1.valueReg() != rdx);
      92           0 :         masm.unboxInt32(R0, eax);
      93           0 :         masm.unboxInt32(R1, ExtractTemp0);
      94             : 
      95             :         // x % 0 always results in NaN.
      96           0 :         masm.branchTest32(Assembler::Zero, ExtractTemp0, ExtractTemp0, &failure);
      97             : 
      98             :         // Prevent negative 0 and -2147483648 % -1.
      99           0 :         masm.branchTest32(Assembler::Zero, eax, Imm32(0x7fffffff), &failure);
     100             : 
     101             :         // Sign extend eax into edx to make (edx:eax), since idiv is 64-bit.
     102           0 :         masm.cdq();
     103           0 :         masm.idiv(ExtractTemp0);
     104             : 
     105             :         // Fail when we would need a negative remainder.
     106           0 :         Label done;
     107           0 :         masm.branchTest32(Assembler::NonZero, edx, edx, &done);
     108           0 :         masm.orl(ExtractTemp0, eax);
     109           0 :         masm.branchTest32(Assembler::Signed, eax, eax, &failure);
     110             : 
     111           0 :         masm.bind(&done);
     112           0 :         masm.boxValue(JSVAL_TYPE_INT32, edx, R0.valueReg());
     113           0 :         break;
     114             :       }
     115             :       case JSOP_BITOR:
     116             :         // We can overide R0, because the instruction is unfailable.
     117             :         // Because the tag bits are the same, we don't need to retag.
     118           8 :         masm.orq(R1.valueReg(), R0.valueReg());
     119           8 :         break;
     120             :       case JSOP_BITXOR:
     121           0 :         masm.xorl(R1.valueReg(), R0.valueReg());
     122           0 :         masm.tagValue(JSVAL_TYPE_INT32, R0.valueReg(), R0);
     123           0 :         break;
     124             :       case JSOP_BITAND:
     125           8 :         masm.andq(R1.valueReg(), R0.valueReg());
     126           8 :         break;
     127             :       case JSOP_LSH:
     128           0 :         masm.unboxInt32(R0, ExtractTemp0);
     129           0 :         masm.unboxInt32(R1, ecx); // Unboxing R1 to ecx, clobbers R0.
     130           0 :         masm.shll_cl(ExtractTemp0);
     131           0 :         masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg());
     132           0 :         break;
     133             :       case JSOP_RSH:
     134           0 :         masm.unboxInt32(R0, ExtractTemp0);
     135           0 :         masm.unboxInt32(R1, ecx);
     136           0 :         masm.sarl_cl(ExtractTemp0);
     137           0 :         masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg());
     138           0 :         break;
     139             :       case JSOP_URSH:
     140           0 :         if (!allowDouble_) {
     141           0 :             scratch.emplace(masm);
     142           0 :             masm.movq(R0.valueReg(), *scratch);
     143             :         }
     144             : 
     145           0 :         masm.unboxInt32(R0, ExtractTemp0);
     146           0 :         masm.unboxInt32(R1, ecx); // This clobbers R0
     147             : 
     148           0 :         masm.shrl_cl(ExtractTemp0);
     149           0 :         masm.test32(ExtractTemp0, ExtractTemp0);
     150           0 :         if (allowDouble_) {
     151           0 :             Label toUint;
     152           0 :             masm.j(Assembler::Signed, &toUint);
     153             : 
     154             :             // Box and return.
     155           0 :             masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg());
     156           0 :             EmitReturnFromIC(masm);
     157             : 
     158           0 :             masm.bind(&toUint);
     159           0 :             ScratchDoubleScope scratchDouble(masm);
     160           0 :             masm.convertUInt32ToDouble(ExtractTemp0, scratchDouble);
     161           0 :             masm.boxDouble(scratchDouble, R0);
     162             :         } else {
     163           0 :             masm.j(Assembler::Signed, &revertRegister);
     164           0 :             masm.boxValue(JSVAL_TYPE_INT32, ExtractTemp0, R0.valueReg());
     165             :         }
     166           0 :         break;
     167             :       default:
     168           0 :         MOZ_CRASH("Unhandled op in BinaryArith_Int32");
     169             :     }
     170             : 
     171             :     // Return from stub.
     172          64 :     EmitReturnFromIC(masm);
     173             : 
     174          64 :     if (op_ == JSOP_MUL) {
     175           0 :         masm.bind(&maybeNegZero);
     176             : 
     177             :         // Result is -0 if exactly one of lhs or rhs is negative.
     178             :         {
     179           0 :             ScratchRegisterScope scratch(masm);
     180           0 :             masm.movl(R0.valueReg(), scratch);
     181           0 :             masm.orl(R1.valueReg(), scratch);
     182           0 :             masm.j(Assembler::Signed, &failure);
     183             :         }
     184             : 
     185             :         // Result is +0.
     186           0 :         masm.moveValue(Int32Value(0), R0);
     187           0 :         EmitReturnFromIC(masm);
     188             :     }
     189             : 
     190             :     // Revert the content of R0 in the fallible >>> case.
     191          64 :     if (op_ == JSOP_URSH && !allowDouble_) {
     192             :         // Scope continuation from JSOP_URSH case above.
     193           0 :         masm.bind(&revertRegister);
     194             :         // Restore tag and payload.
     195           0 :         masm.movq(*scratch, R0.valueReg());
     196             :         // Fall through to failure.
     197             :     }
     198             :     // Failure case - jump to next stub
     199          64 :     masm.bind(&failure);
     200          64 :     EmitStubGuardFailure(masm);
     201             : 
     202         128 :     return true;
     203             : }
     204             : 
     205             : bool
     206           1 : ICUnaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm)
     207             : {
     208           2 :     Label failure;
     209           1 :     masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
     210             : 
     211           1 :     switch (op) {
     212             :       case JSOP_BITNOT:
     213           1 :         masm.notl(R0.valueReg());
     214           1 :         break;
     215             :       case JSOP_NEG:
     216             :         // Guard against 0 and MIN_INT, both result in a double.
     217           0 :         masm.branchTest32(Assembler::Zero, R0.valueReg(), Imm32(0x7fffffff), &failure);
     218           0 :         masm.negl(R0.valueReg());
     219           0 :         break;
     220             :       default:
     221           0 :         MOZ_CRASH("Unexpected op");
     222             :     }
     223             : 
     224           1 :     masm.tagValue(JSVAL_TYPE_INT32, R0.valueReg(), R0);
     225             : 
     226           1 :     EmitReturnFromIC(masm);
     227             : 
     228           1 :     masm.bind(&failure);
     229           1 :     EmitStubGuardFailure(masm);
     230           2 :     return true;
     231             : }
     232             : 
     233             : } // namespace jit
     234             : } // namespace js

Generated by: LCOV version 1.13