tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MozInstructions-vixl.cpp (6449B)


      1 // Copyright 2013, ARM Limited
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 #include "jit/arm64/Architecture-arm64.h"
     28 #include "jit/arm64/vixl/Assembler-vixl.h"
     29 #include "jit/arm64/vixl/Instructions-vixl.h"
     30 
     31 namespace vixl {
     32 
     33 bool Instruction::IsUncondB() const {
     34  return Mask(UnconditionalBranchMask) == (UnconditionalBranchFixed | B);
     35 }
     36 
     37 
     38 bool Instruction::IsCondB() const {
     39  return Mask(ConditionalBranchMask) == (ConditionalBranchFixed | B_cond);
     40 }
     41 
     42 
     43 bool Instruction::IsBL() const {
     44  return Mask(UnconditionalBranchMask) == (UnconditionalBranchFixed | BL);
     45 }
     46 
     47 
     48 bool Instruction::IsBR() const {
     49  return Mask(UnconditionalBranchToRegisterMask) == (UnconditionalBranchToRegisterFixed | BR);
     50 }
     51 
     52 
     53 bool Instruction::IsBLR() const {
     54  return Mask(UnconditionalBranchToRegisterMask) == (UnconditionalBranchToRegisterFixed | BLR);
     55 }
     56 
     57 
     58 bool Instruction::IsTBZ() const {
     59  return Mask(TestBranchMask) == TBZ;
     60 }
     61 
     62 
     63 bool Instruction::IsTBNZ() const {
     64  return Mask(TestBranchMask) == TBNZ;
     65 }
     66 
     67 
     68 bool Instruction::IsCBZ() const {
     69  return Mask(CompareBranchMask) == CBZ_w || Mask(CompareBranchMask) == CBZ_x;
     70 }
     71 
     72 
     73 bool Instruction::IsCBNZ() const {
     74  return Mask(CompareBranchMask) == CBNZ_w || Mask(CompareBranchMask) == CBNZ_x;
     75 }
     76 
     77 
     78 bool Instruction::IsLDR() const {
     79  return Mask(LoadLiteralMask) == LDR_x_lit;
     80 }
     81 
     82 
     83 bool Instruction::IsNOP() const {
     84  return Mask(SystemHintMask) == HINT && ImmHint() == NOP;
     85 }
     86 
     87 
     88 bool Instruction::IsCSDB() const {
     89  return Mask(SystemHintMask) == HINT && ImmHint() == CSDB;
     90 }
     91 
     92 
     93 bool Instruction::IsADR() const {
     94  return Mask(PCRelAddressingMask) == ADR;
     95 }
     96 
     97 
     98 bool Instruction::IsADRP() const {
     99  return Mask(PCRelAddressingMask) == ADRP;
    100 }
    101 
    102 
    103 bool Instruction::IsMovz() const {
    104  return (Mask(MoveWideImmediateMask) == MOVZ_x) ||
    105         (Mask(MoveWideImmediateMask) == MOVZ_w);
    106 }
    107 
    108 
    109 bool Instruction::IsMovk() const {
    110  return (Mask(MoveWideImmediateMask) == MOVK_x) ||
    111         (Mask(MoveWideImmediateMask) == MOVK_w);
    112 }
    113 
    114 bool Instruction::IsBranchLinkImm() const {
    115  return Mask(UnconditionalBranchFMask) == (UnconditionalBranchFixed | BL);
    116 }
    117 
    118 
    119 bool Instruction::IsTargetReachable(const Instruction* target) const {
    120    VIXL_ASSERT(((target - this) & 3) == 0);
    121    int offset = (target - this) >> kInstructionSizeLog2;
    122    switch (BranchType()) {
    123      case CondBranchType:
    124        return IsInt19(offset);
    125      case UncondBranchType:
    126        return IsInt26(offset);
    127      case CompareBranchType:
    128        return IsInt19(offset);
    129      case TestBranchType:
    130        return IsInt14(offset);
    131      default:
    132        VIXL_UNREACHABLE();
    133    }
    134 }
    135 
    136 
    137 ptrdiff_t Instruction::ImmPCRawOffset() const {
    138  ptrdiff_t offset;
    139  if (IsPCRelAddressing()) {
    140    // ADR and ADRP.
    141    offset = ImmPCRel();
    142  } else if (BranchType() == UnknownBranchType) {
    143    offset = ImmLLiteral();
    144  } else {
    145    offset = ImmBranch();
    146  }
    147  return offset;
    148 }
    149 
    150 void
    151 Instruction::SetImmPCRawOffset(ptrdiff_t offset)
    152 {
    153  if (IsPCRelAddressing()) {
    154    // ADR and ADRP. We're encoding a raw offset here.
    155    // See also SetPCRelImmTarget().
    156    Instr imm = vixl::Assembler::ImmPCRelAddress(offset);
    157    SetInstructionBits(Mask(~ImmPCRel_mask) | imm);
    158  } else {
    159    SetBranchImmTarget(this + (offset << kInstructionSizeLog2));
    160  }
    161 }
    162 
    163 // Is this a stack pointer synchronization instruction as inserted by
    164 // MacroAssembler::syncStackPtr()?
    165 bool
    166 Instruction::IsStackPtrSync() const
    167 {
    168    // The stack pointer sync is a move to the stack pointer.
    169    // This is encoded as 'add sp, Rs, #0'.
    170    return IsAddSubImmediate() && Rd() == js::jit::Registers::sp && ImmAddSub() == 0;
    171 }
    172 
    173 // Skip over a constant pool at |this| if there is one.
    174 //
    175 // If |this| is pointing to the artifical guard branch around a constant pool,
    176 // return the instruction after the pool. Otherwise return |this| itself.
    177 //
    178 // This function does not skip constant pools with a natural guard branch. It
    179 // is assumed that anyone inspecting the instruction stream understands about
    180 // branches that were inserted naturally.
    181 const Instruction*
    182 Instruction::skipPool() const
    183 {
    184    // Artificial pool guards can only be B (rather than BR), and they must be
    185    // forward branches.
    186    if (!IsUncondB() || ImmUncondBranch() <= 0)
    187        return this;
    188 
    189    // Check for a constant pool header which has the high 16 bits set. See
    190    // struct PoolHeader. Bit 15 indicates a natural pool guard when set. It
    191    // must be clear which indicates an artificial pool guard.
    192    const Instruction *header = InstructionAtOffset(kInstructionSize);
    193    if (header->Mask(0xffff8000) != 0xffff0000)
    194        return this;
    195 
    196    // OK, this is an artificial jump around a constant pool.
    197    return ImmPCOffsetTarget();
    198 }
    199 
    200 
    201 void Instruction::SetBits32(int msb, int lsb, unsigned value) {
    202  uint32_t me;
    203  memcpy(&me, this, sizeof(me));
    204  uint32_t new_mask = (1 << (msb+1)) - (1 << lsb);
    205  uint32_t keep_mask = ~new_mask;
    206  me = (me & keep_mask) | ((value << lsb) & new_mask);
    207  memcpy(this, &me, sizeof(me));
    208 }
    209 
    210 
    211 } // namespace vixl