tor-browser

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

Registers-vixl.cpp (9275B)


      1 // Copyright 2019, VIXL authors
      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/vixl/Registers-vixl.h"
     28 
     29 namespace vixl {
     30 
     31 unsigned CPURegister::GetMaxCodeFor(CPURegister::RegisterBank bank) {
     32  switch (bank) {
     33    case kNoRegisterBank:
     34      return 0;
     35    case kRRegisterBank:
     36      return Register::GetMaxCode();
     37    case kVRegisterBank:
     38 #ifdef VIXL_HAS_CONSTEXPR
     39      VIXL_STATIC_ASSERT(VRegister::GetMaxCode() == ZRegister::GetMaxCode());
     40 #else
     41      VIXL_ASSERT(VRegister::GetMaxCode() == ZRegister::GetMaxCode());
     42 #endif
     43      return VRegister::GetMaxCode();
     44    case kPRegisterBank:
     45      return PRegister::GetMaxCode();
     46  }
     47  VIXL_UNREACHABLE();
     48  return 0;
     49 }
     50 
     51 // Most coercions simply invoke the necessary constructor.
     52 #define VIXL_CPUREG_COERCION_LIST(U) \
     53  U(Register, W, R)                  \
     54  U(Register, X, R)                  \
     55  U(VRegister, B, V)                 \
     56  U(VRegister, H, V)                 \
     57  U(VRegister, S, V)                 \
     58  U(VRegister, D, V)                 \
     59  U(VRegister, Q, V)                 \
     60  U(VRegister, V, V)                 \
     61  U(ZRegister, Z, V)                 \
     62  U(PRegister, P, P)
     63 #define VIXL_DEFINE_CPUREG_COERCION(RET_TYPE, CTOR_TYPE, BANK) \
     64  RET_TYPE CPURegister::CTOR_TYPE() const {                    \
     65    VIXL_ASSERT(GetBank() == k##BANK##RegisterBank);           \
     66    return CTOR_TYPE##Register(GetCode());                     \
     67  }
     68 VIXL_CPUREG_COERCION_LIST(VIXL_DEFINE_CPUREG_COERCION)
     69 #undef VIXL_CPUREG_COERCION_LIST
     70 #undef VIXL_DEFINE_CPUREG_COERCION
     71 
     72 // NEON lane-format coercions always return VRegisters.
     73 #define VIXL_CPUREG_NEON_COERCION_LIST(V) \
     74  V(8, B)                                 \
     75  V(16, B)                                \
     76  V(2, H)                                 \
     77  V(4, H)                                 \
     78  V(8, H)                                 \
     79  V(2, S)                                 \
     80  V(4, S)                                 \
     81  V(1, D)                                 \
     82  V(2, D)                                 \
     83  V(1, Q)
     84 #define VIXL_DEFINE_CPUREG_NEON_COERCION(LANES, LANE_TYPE)             \
     85  VRegister VRegister::V##LANES##LANE_TYPE() const {                   \
     86    VIXL_ASSERT(IsVRegister());                                        \
     87    return VRegister(GetCode(), LANES * k##LANE_TYPE##RegSize, LANES); \
     88  }
     89 VIXL_CPUREG_NEON_COERCION_LIST(VIXL_DEFINE_CPUREG_NEON_COERCION)
     90 #undef VIXL_CPUREG_NEON_COERCION_LIST
     91 #undef VIXL_DEFINE_CPUREG_NEON_COERCION
     92 
     93 // Semantic type coercion for sdot and udot.
     94 // TODO: Use the qualifiers_ field to distinguish this from ::S().
     95 VRegister VRegister::S4B() const {
     96  VIXL_ASSERT(IsVRegister());
     97  return SRegister(GetCode());
     98 }
     99 
    100 bool AreAliased(const CPURegister& reg1,
    101                const CPURegister& reg2,
    102                const CPURegister& reg3,
    103                const CPURegister& reg4,
    104                const CPURegister& reg5,
    105                const CPURegister& reg6,
    106                const CPURegister& reg7,
    107                const CPURegister& reg8) {
    108  int number_of_valid_regs = 0;
    109  int number_of_valid_vregs = 0;
    110  int number_of_valid_pregs = 0;
    111 
    112  RegList unique_regs = 0;
    113  RegList unique_vregs = 0;
    114  RegList unique_pregs = 0;
    115 
    116  const CPURegister regs[] = {reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8};
    117 
    118  for (size_t i = 0; i < ArrayLength(regs); i++) {
    119    switch (regs[i].GetBank()) {
    120      case CPURegister::kRRegisterBank:
    121        number_of_valid_regs++;
    122        unique_regs |= regs[i].GetBit();
    123        break;
    124      case CPURegister::kVRegisterBank:
    125        number_of_valid_vregs++;
    126        unique_vregs |= regs[i].GetBit();
    127        break;
    128      case CPURegister::kPRegisterBank:
    129        number_of_valid_pregs++;
    130        unique_pregs |= regs[i].GetBit();
    131        break;
    132      case CPURegister::kNoRegisterBank:
    133        VIXL_ASSERT(regs[i].IsNone());
    134        break;
    135    }
    136  }
    137 
    138  int number_of_unique_regs = CountSetBits(unique_regs);
    139  int number_of_unique_vregs = CountSetBits(unique_vregs);
    140  int number_of_unique_pregs = CountSetBits(unique_pregs);
    141 
    142  VIXL_ASSERT(number_of_valid_regs >= number_of_unique_regs);
    143  VIXL_ASSERT(number_of_valid_vregs >= number_of_unique_vregs);
    144  VIXL_ASSERT(number_of_valid_pregs >= number_of_unique_pregs);
    145 
    146  return (number_of_valid_regs != number_of_unique_regs) ||
    147         (number_of_valid_vregs != number_of_unique_vregs) ||
    148         (number_of_valid_pregs != number_of_unique_pregs);
    149 }
    150 
    151 bool AreSameSizeAndType(const CPURegister& reg1,
    152                        const CPURegister& reg2,
    153                        const CPURegister& reg3,
    154                        const CPURegister& reg4,
    155                        const CPURegister& reg5,
    156                        const CPURegister& reg6,
    157                        const CPURegister& reg7,
    158                        const CPURegister& reg8) {
    159  VIXL_ASSERT(reg1.IsValid());
    160  bool match = true;
    161  match &= !reg2.IsValid() || reg2.IsSameSizeAndType(reg1);
    162  match &= !reg3.IsValid() || reg3.IsSameSizeAndType(reg1);
    163  match &= !reg4.IsValid() || reg4.IsSameSizeAndType(reg1);
    164  match &= !reg5.IsValid() || reg5.IsSameSizeAndType(reg1);
    165  match &= !reg6.IsValid() || reg6.IsSameSizeAndType(reg1);
    166  match &= !reg7.IsValid() || reg7.IsSameSizeAndType(reg1);
    167  match &= !reg8.IsValid() || reg8.IsSameSizeAndType(reg1);
    168  return match;
    169 }
    170 
    171 bool AreEven(const CPURegister& reg1,
    172             const CPURegister& reg2,
    173             const CPURegister& reg3,
    174             const CPURegister& reg4,
    175             const CPURegister& reg5,
    176             const CPURegister& reg6,
    177             const CPURegister& reg7,
    178             const CPURegister& reg8) {
    179  VIXL_ASSERT(reg1.IsValid());
    180  bool even = (reg1.GetCode() % 2) == 0;
    181  even &= !reg2.IsValid() || ((reg2.GetCode() % 2) == 0);
    182  even &= !reg3.IsValid() || ((reg3.GetCode() % 2) == 0);
    183  even &= !reg4.IsValid() || ((reg4.GetCode() % 2) == 0);
    184  even &= !reg5.IsValid() || ((reg5.GetCode() % 2) == 0);
    185  even &= !reg6.IsValid() || ((reg6.GetCode() % 2) == 0);
    186  even &= !reg7.IsValid() || ((reg7.GetCode() % 2) == 0);
    187  even &= !reg8.IsValid() || ((reg8.GetCode() % 2) == 0);
    188  return even;
    189 }
    190 
    191 bool AreConsecutive(const CPURegister& reg1,
    192                    const CPURegister& reg2,
    193                    const CPURegister& reg3,
    194                    const CPURegister& reg4) {
    195  VIXL_ASSERT(reg1.IsValid());
    196 
    197  if (!reg2.IsValid()) {
    198    return true;
    199  } else if (reg2.GetCode() !=
    200             ((reg1.GetCode() + 1) % (reg1.GetMaxCode() + 1))) {
    201    return false;
    202  }
    203 
    204  if (!reg3.IsValid()) {
    205    return true;
    206  } else if (reg3.GetCode() !=
    207             ((reg2.GetCode() + 1) % (reg1.GetMaxCode() + 1))) {
    208    return false;
    209  }
    210 
    211  if (!reg4.IsValid()) {
    212    return true;
    213  } else if (reg4.GetCode() !=
    214             ((reg3.GetCode() + 1) % (reg1.GetMaxCode() + 1))) {
    215    return false;
    216  }
    217 
    218  return true;
    219 }
    220 
    221 bool AreSameFormat(const CPURegister& reg1,
    222                   const CPURegister& reg2,
    223                   const CPURegister& reg3,
    224                   const CPURegister& reg4) {
    225  VIXL_ASSERT(reg1.IsValid());
    226  bool match = true;
    227  match &= !reg2.IsValid() || reg2.IsSameFormat(reg1);
    228  match &= !reg3.IsValid() || reg3.IsSameFormat(reg1);
    229  match &= !reg4.IsValid() || reg4.IsSameFormat(reg1);
    230  return match;
    231 }
    232 
    233 bool AreSameLaneSize(const CPURegister& reg1,
    234                     const CPURegister& reg2,
    235                     const CPURegister& reg3,
    236                     const CPURegister& reg4) {
    237  VIXL_ASSERT(reg1.IsValid());
    238  bool match = true;
    239  match &=
    240      !reg2.IsValid() || (reg2.GetLaneSizeInBits() == reg1.GetLaneSizeInBits());
    241  match &=
    242      !reg3.IsValid() || (reg3.GetLaneSizeInBits() == reg1.GetLaneSizeInBits());
    243  match &=
    244      !reg4.IsValid() || (reg4.GetLaneSizeInBits() == reg1.GetLaneSizeInBits());
    245  return match;
    246 }
    247 }  // namespace vixl