Home | History | Annotate | Download | only in aarch32
      1 // Copyright 2017, 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 extern "C" {
     28 #include <stdint.h>
     29 }
     30 
     31 #include <cassert>
     32 #include <cstdio>
     33 #include <cstdlib>
     34 #include <cstring>
     35 #include <iostream>
     36 
     37 #include "utils-vixl.h"
     38 #include "aarch32/constants-aarch32.h"
     39 #include "aarch32/instructions-aarch32.h"
     40 
     41 namespace vixl {
     42 namespace aarch32 {
     43 
     44 
     45 bool Shift::IsValidAmount(uint32_t amount) const {
     46   switch (GetType()) {
     47     case LSL:
     48       return amount <= 31;
     49     case ROR:
     50       return (amount > 0) && (amount <= 31);
     51     case LSR:
     52     case ASR:
     53       return (amount > 0) && (amount <= 32);
     54     case RRX:
     55       return amount == 0;
     56     default:
     57       VIXL_UNREACHABLE();
     58       return false;
     59   }
     60 }
     61 
     62 
     63 std::ostream& operator<<(std::ostream& os, const Register reg) {
     64   switch (reg.GetCode()) {
     65     case 12:
     66       return os << "ip";
     67     case 13:
     68       return os << "sp";
     69     case 14:
     70       return os << "lr";
     71     case 15:
     72       return os << "pc";
     73     default:
     74       return os << "r" << reg.GetCode();
     75   }
     76 }
     77 
     78 
     79 SRegister VRegister::S() const {
     80   VIXL_ASSERT(GetType() == kSRegister);
     81   return SRegister(GetCode());
     82 }
     83 
     84 
     85 DRegister VRegister::D() const {
     86   VIXL_ASSERT(GetType() == kDRegister);
     87   return DRegister(GetCode());
     88 }
     89 
     90 
     91 QRegister VRegister::Q() const {
     92   VIXL_ASSERT(GetType() == kQRegister);
     93   return QRegister(GetCode());
     94 }
     95 
     96 
     97 Register RegisterList::GetFirstAvailableRegister() const {
     98   for (uint32_t i = 0; i < kNumberOfRegisters; i++) {
     99     if (((list_ >> i) & 1) != 0) return Register(i);
    100   }
    101   return Register();
    102 }
    103 
    104 
    105 std::ostream& PrintRegisterList(std::ostream& os,  // NOLINT(runtime/references)
    106                                 uint32_t list) {
    107   os << "{";
    108   bool first = true;
    109   int code = 0;
    110   while (list != 0) {
    111     if ((list & 1) != 0) {
    112       if (first) {
    113         first = false;
    114       } else {
    115         os << ",";
    116       }
    117       os << Register(code);
    118     }
    119     list >>= 1;
    120     code++;
    121   }
    122   os << "}";
    123   return os;
    124 }
    125 
    126 
    127 std::ostream& operator<<(std::ostream& os, RegisterList registers) {
    128   return PrintRegisterList(os, registers.GetList());
    129 }
    130 
    131 
    132 QRegister VRegisterList::GetFirstAvailableQRegister() const {
    133   for (uint32_t i = 0; i < kNumberOfQRegisters; i++) {
    134     if (((list_ >> (i * 4)) & 0xf) == 0xf) return QRegister(i);
    135   }
    136   return QRegister();
    137 }
    138 
    139 
    140 DRegister VRegisterList::GetFirstAvailableDRegister() const {
    141   for (uint32_t i = 0; i < kMaxNumberOfDRegisters; i++) {
    142     if (((list_ >> (i * 2)) & 0x3) == 0x3) return DRegister(i);
    143   }
    144   return DRegister();
    145 }
    146 
    147 
    148 SRegister VRegisterList::GetFirstAvailableSRegister() const {
    149   for (uint32_t i = 0; i < kNumberOfSRegisters; i++) {
    150     if (((list_ >> i) & 0x1) != 0) return SRegister(i);
    151   }
    152   return SRegister();
    153 }
    154 
    155 
    156 std::ostream& operator<<(std::ostream& os, SRegisterList reglist) {
    157   SRegister first = reglist.GetFirstSRegister();
    158   SRegister last = reglist.GetLastSRegister();
    159   if (first.Is(last))
    160     os << "{" << first << "}";
    161   else
    162     os << "{" << first << "-" << last << "}";
    163   return os;
    164 }
    165 
    166 
    167 std::ostream& operator<<(std::ostream& os, DRegisterList reglist) {
    168   DRegister first = reglist.GetFirstDRegister();
    169   DRegister last = reglist.GetLastDRegister();
    170   if (first.Is(last))
    171     os << "{" << first << "}";
    172   else
    173     os << "{" << first << "-" << last << "}";
    174   return os;
    175 }
    176 
    177 std::ostream& operator<<(std::ostream& os, NeonRegisterList nreglist) {
    178   DRegister first = nreglist.GetFirstDRegister();
    179   int increment = nreglist.IsSingleSpaced() ? 1 : 2;
    180   int count =
    181       nreglist.GetLastDRegister().GetCode() - first.GetCode() + increment;
    182   if (count < 0) count += kMaxNumberOfDRegisters;
    183   os << "{";
    184   bool first_displayed = false;
    185   for (;;) {
    186     if (first_displayed) {
    187       os << ",";
    188     } else {
    189       first_displayed = true;
    190     }
    191     os << first;
    192     if (nreglist.IsTransferOneLane()) {
    193       os << "[" << nreglist.GetTransferLane() << "]";
    194     } else if (nreglist.IsTransferAllLanes()) {
    195       os << "[]";
    196     }
    197     count -= increment;
    198     if (count <= 0) break;
    199     unsigned next = first.GetCode() + increment;
    200     if (next >= kMaxNumberOfDRegisters) next -= kMaxNumberOfDRegisters;
    201     first = DRegister(next);
    202   }
    203   os << "}";
    204   return os;
    205 }
    206 
    207 
    208 const char* SpecialRegister::GetName() const {
    209   switch (reg_) {
    210     case APSR:
    211       return "APSR";
    212     case SPSR:
    213       return "SPSR";
    214   }
    215   VIXL_UNREACHABLE();
    216   return "??";
    217 }
    218 
    219 
    220 const char* MaskedSpecialRegister::GetName() const {
    221   switch (reg_) {
    222     case APSR_nzcvq:
    223       return "APSR_nzcvq";
    224     case APSR_g:
    225       return "APSR_g";
    226     case APSR_nzcvqg:
    227       return "APSR_nzcvqg";
    228     case CPSR_c:
    229       return "CPSR_c";
    230     case CPSR_x:
    231       return "CPSR_x";
    232     case CPSR_xc:
    233       return "CPSR_xc";
    234     case CPSR_sc:
    235       return "CPSR_sc";
    236     case CPSR_sx:
    237       return "CPSR_sx";
    238     case CPSR_sxc:
    239       return "CPSR_sxc";
    240     case CPSR_fc:
    241       return "CPSR_fc";
    242     case CPSR_fx:
    243       return "CPSR_fx";
    244     case CPSR_fxc:
    245       return "CPSR_fxc";
    246     case CPSR_fsc:
    247       return "CPSR_fsc";
    248     case CPSR_fsx:
    249       return "CPSR_fsx";
    250     case CPSR_fsxc:
    251       return "CPSR_fsxc";
    252     case SPSR_c:
    253       return "SPSR_c";
    254     case SPSR_x:
    255       return "SPSR_x";
    256     case SPSR_xc:
    257       return "SPSR_xc";
    258     case SPSR_s:
    259       return "SPSR_s";
    260     case SPSR_sc:
    261       return "SPSR_sc";
    262     case SPSR_sx:
    263       return "SPSR_sx";
    264     case SPSR_sxc:
    265       return "SPSR_sxc";
    266     case SPSR_f:
    267       return "SPSR_f";
    268     case SPSR_fc:
    269       return "SPSR_fc";
    270     case SPSR_fx:
    271       return "SPSR_fx";
    272     case SPSR_fxc:
    273       return "SPSR_fxc";
    274     case SPSR_fs:
    275       return "SPSR_fs";
    276     case SPSR_fsc:
    277       return "SPSR_fsc";
    278     case SPSR_fsx:
    279       return "SPSR_fsx";
    280     case SPSR_fsxc:
    281       return "SPSR_fsxc";
    282   }
    283   VIXL_UNREACHABLE();
    284   return "??";
    285 }
    286 
    287 
    288 const char* BankedRegister::GetName() const {
    289   switch (reg_) {
    290     case R8_usr:
    291       return "R8_usr";
    292     case R9_usr:
    293       return "R9_usr";
    294     case R10_usr:
    295       return "R10_usr";
    296     case R11_usr:
    297       return "R11_usr";
    298     case R12_usr:
    299       return "R12_usr";
    300     case SP_usr:
    301       return "SP_usr";
    302     case LR_usr:
    303       return "LR_usr";
    304     case R8_fiq:
    305       return "R8_fiq";
    306     case R9_fiq:
    307       return "R9_fiq";
    308     case R10_fiq:
    309       return "R10_fiq";
    310     case R11_fiq:
    311       return "R11_fiq";
    312     case R12_fiq:
    313       return "R12_fiq";
    314     case SP_fiq:
    315       return "SP_fiq";
    316     case LR_fiq:
    317       return "LR_fiq";
    318     case LR_irq:
    319       return "LR_irq";
    320     case SP_irq:
    321       return "SP_irq";
    322     case LR_svc:
    323       return "LR_svc";
    324     case SP_svc:
    325       return "SP_svc";
    326     case LR_abt:
    327       return "LR_abt";
    328     case SP_abt:
    329       return "SP_abt";
    330     case LR_und:
    331       return "LR_und";
    332     case SP_und:
    333       return "SP_und";
    334     case LR_mon:
    335       return "LR_mon";
    336     case SP_mon:
    337       return "SP_mon";
    338     case ELR_hyp:
    339       return "ELR_hyp";
    340     case SP_hyp:
    341       return "SP_hyp";
    342     case SPSR_fiq:
    343       return "SPSR_fiq";
    344     case SPSR_irq:
    345       return "SPSR_irq";
    346     case SPSR_svc:
    347       return "SPSR_svc";
    348     case SPSR_abt:
    349       return "SPSR_abt";
    350     case SPSR_und:
    351       return "SPSR_und";
    352     case SPSR_mon:
    353       return "SPSR_mon";
    354     case SPSR_hyp:
    355       return "SPSR_hyp";
    356   }
    357   VIXL_UNREACHABLE();
    358   return "??";
    359 }
    360 
    361 const char* SpecialFPRegister::GetName() const {
    362   switch (reg_) {
    363     case FPSID:
    364       return "FPSID";
    365     case FPSCR:
    366       return "FPSCR";
    367     case MVFR2:
    368       return "MVFR2";
    369     case MVFR1:
    370       return "MVFR1";
    371     case MVFR0:
    372       return "MVFR0";
    373     case FPEXC:
    374       return "FPEXC";
    375   }
    376   VIXL_UNREACHABLE();
    377   return "??";
    378 }
    379 
    380 
    381 const char* Condition::GetName() const {
    382   switch (condition_) {
    383     case eq:
    384       return "eq";
    385     case ne:
    386       return "ne";
    387     case cs:
    388       return "cs";
    389     case cc:
    390       return "cc";
    391     case mi:
    392       return "mi";
    393     case pl:
    394       return "pl";
    395     case vs:
    396       return "vs";
    397     case vc:
    398       return "vc";
    399     case hi:
    400       return "hi";
    401     case ls:
    402       return "ls";
    403     case ge:
    404       return "ge";
    405     case lt:
    406       return "lt";
    407     case gt:
    408       return "gt";
    409     case le:
    410       return "le";
    411     case al:
    412       return "";
    413     case Condition::kNone:
    414       return "";
    415   }
    416   return "<und>";
    417 }
    418 
    419 
    420 const char* Shift::GetName() const {
    421   switch (shift_) {
    422     case LSL:
    423       return "lsl";
    424     case LSR:
    425       return "lsr";
    426     case ASR:
    427       return "asr";
    428     case ROR:
    429       return "ror";
    430     case RRX:
    431       return "rrx";
    432   }
    433   VIXL_UNREACHABLE();
    434   return "??";
    435 }
    436 
    437 
    438 const char* EncodingSize::GetName() const {
    439   switch (size_) {
    440     case Best:
    441     case Narrow:
    442       return "";
    443     case Wide:
    444       return ".w";
    445   }
    446   VIXL_UNREACHABLE();
    447   return "??";
    448 }
    449 
    450 
    451 const char* DataType::GetName() const {
    452   switch (value_) {
    453     case kDataTypeValueInvalid:
    454       return ".??";
    455     case kDataTypeValueNone:
    456       return "";
    457     case S8:
    458       return ".s8";
    459     case S16:
    460       return ".s16";
    461     case S32:
    462       return ".s32";
    463     case S64:
    464       return ".s64";
    465     case U8:
    466       return ".u8";
    467     case U16:
    468       return ".u16";
    469     case U32:
    470       return ".u32";
    471     case U64:
    472       return ".u64";
    473     case F16:
    474       return ".f16";
    475     case F32:
    476       return ".f32";
    477     case F64:
    478       return ".f64";
    479     case I8:
    480       return ".i8";
    481     case I16:
    482       return ".i16";
    483     case I32:
    484       return ".i32";
    485     case I64:
    486       return ".i64";
    487     case P8:
    488       return ".p8";
    489     case P64:
    490       return ".p64";
    491     case Untyped8:
    492       return ".8";
    493     case Untyped16:
    494       return ".16";
    495     case Untyped32:
    496       return ".32";
    497     case Untyped64:
    498       return ".64";
    499   }
    500   VIXL_UNREACHABLE();
    501   return ".??";
    502 }
    503 
    504 
    505 const char* MemoryBarrier::GetName() const {
    506   switch (type_) {
    507     case OSHLD:
    508       return "oshld";
    509     case OSHST:
    510       return "oshst";
    511     case OSH:
    512       return "osh";
    513     case NSHLD:
    514       return "nshld";
    515     case NSHST:
    516       return "nshst";
    517     case NSH:
    518       return "nsh";
    519     case ISHLD:
    520       return "ishld";
    521     case ISHST:
    522       return "ishst";
    523     case ISH:
    524       return "ish";
    525     case LD:
    526       return "ld";
    527     case ST:
    528       return "st";
    529     case SY:
    530       return "sy";
    531   }
    532   switch (static_cast<int>(type_)) {
    533     case 0:
    534       return "#0x0";
    535     case 4:
    536       return "#0x4";
    537     case 8:
    538       return "#0x8";
    539     case 0xc:
    540       return "#0xc";
    541   }
    542   VIXL_UNREACHABLE();
    543   return "??";
    544 }
    545 
    546 
    547 const char* InterruptFlags::GetName() const {
    548   switch (type_) {
    549     case F:
    550       return "f";
    551     case I:
    552       return "i";
    553     case IF:
    554       return "if";
    555     case A:
    556       return "a";
    557     case AF:
    558       return "af";
    559     case AI:
    560       return "ai";
    561     case AIF:
    562       return "aif";
    563   }
    564   VIXL_ASSERT(type_ == 0);
    565   return "";
    566 }
    567 
    568 
    569 const char* Endianness::GetName() const {
    570   switch (type_) {
    571     case LE:
    572       return "le";
    573     case BE:
    574       return "be";
    575   }
    576   VIXL_UNREACHABLE();
    577   return "??";
    578 }
    579 
    580 
    581 // Constructor used for disassembly.
    582 ImmediateShiftOperand::ImmediateShiftOperand(int shift_value, int amount_value)
    583     : Shift(shift_value) {
    584   switch (shift_value) {
    585     case LSL:
    586       amount_ = amount_value;
    587       break;
    588     case LSR:
    589     case ASR:
    590       amount_ = (amount_value == 0) ? 32 : amount_value;
    591       break;
    592     case ROR:
    593       amount_ = amount_value;
    594       if (amount_value == 0) SetType(RRX);
    595       break;
    596     default:
    597       VIXL_UNREACHABLE();
    598       SetType(LSL);
    599       amount_ = 0;
    600       break;
    601   }
    602 }
    603 
    604 
    605 ImmediateT32::ImmediateT32(uint32_t imm) {
    606   // 00000000 00000000 00000000 abcdefgh
    607   if ((imm & ~0xff) == 0) {
    608     SetEncodingValue(imm);
    609     return;
    610   }
    611   if ((imm >> 16) == (imm & 0xffff)) {
    612     if ((imm & 0xff00) == 0) {
    613       // 00000000 abcdefgh 00000000 abcdefgh
    614       SetEncodingValue((imm & 0xff) | (0x1 << 8));
    615       return;
    616     }
    617     if ((imm & 0xff) == 0) {
    618       // abcdefgh 00000000 abcdefgh 00000000
    619       SetEncodingValue(((imm >> 8) & 0xff) | (0x2 << 8));
    620       return;
    621     }
    622     if (((imm >> 8) & 0xff) == (imm & 0xff)) {
    623       // abcdefgh abcdefgh abcdefgh abcdefgh
    624       SetEncodingValue((imm & 0xff) | (0x3 << 8));
    625       return;
    626     }
    627   }
    628   for (int shift = 0; shift < 24; shift++) {
    629     uint32_t imm8 = imm >> (24 - shift);
    630     uint32_t overflow = imm << (8 + shift);
    631     if ((imm8 <= 0xff) && ((imm8 & 0x80) != 0) && (overflow == 0)) {
    632       SetEncodingValue(((shift + 8) << 7) | (imm8 & 0x7F));
    633       return;
    634     }
    635   }
    636 }
    637 
    638 
    639 static inline uint32_t ror(uint32_t x, int i) {
    640   VIXL_ASSERT((0 < i) && (i < 32));
    641   return (x >> i) | (x << (32 - i));
    642 }
    643 
    644 
    645 bool ImmediateT32::IsImmediateT32(uint32_t imm) {
    646   /* abcdefgh abcdefgh abcdefgh abcdefgh */
    647   if ((imm ^ ror(imm, 8)) == 0) return true;
    648   /* 00000000 abcdefgh 00000000 abcdefgh */
    649   /* abcdefgh 00000000 abcdefgh 00000000 */
    650   if ((imm ^ ror(imm, 16)) == 0 &&
    651       (((imm & 0xff00) == 0) || ((imm & 0xff) == 0)))
    652     return true;
    653   /* isolate least-significant set bit */
    654   uint32_t lsb = imm & -imm;
    655   /* if imm is less than lsb*256 then it fits, but instead we test imm/256 to
    656   * avoid overflow (underflow is always a successful case) */
    657   return ((imm >> 8) < lsb);
    658 }
    659 
    660 
    661 uint32_t ImmediateT32::Decode(uint32_t value) {
    662   uint32_t base = value & 0xff;
    663   switch (value >> 8) {
    664     case 0:
    665       return base;
    666     case 1:
    667       return base | (base << 16);
    668     case 2:
    669       return (base << 8) | (base << 24);
    670     case 3:
    671       return base | (base << 8) | (base << 16) | (base << 24);
    672     default:
    673       base |= 0x80;
    674       return base << (32 - (value >> 7));
    675   }
    676 }
    677 
    678 
    679 ImmediateA32::ImmediateA32(uint32_t imm) {
    680   // Deal with rot = 0 first to avoid undefined shift by 32.
    681   if (imm <= 0xff) {
    682     SetEncodingValue(imm);
    683     return;
    684   }
    685   for (int rot = 2; rot < 32; rot += 2) {
    686     uint32_t imm8 = (imm << rot) | (imm >> (32 - rot));
    687     if (imm8 <= 0xff) {
    688       SetEncodingValue((rot << 7) | imm8);
    689       return;
    690     }
    691   }
    692 }
    693 
    694 
    695 bool ImmediateA32::IsImmediateA32(uint32_t imm) {
    696   /* fast-out */
    697   if (imm < 256) return true;
    698   /* avoid getting confused by wrapped-around bytes (this transform has no
    699    * effect on pass/fail results) */
    700   if (imm & 0xff000000) imm = ror(imm, 16);
    701   /* copy odd-numbered set bits into even-numbered bits immediately below, so
    702    * that the least-significant set bit is always an even bit */
    703   imm = imm | ((imm >> 1) & 0x55555555);
    704   /* isolate least-significant set bit (always even) */
    705   uint32_t lsb = imm & -imm;
    706   /* if imm is less than lsb*256 then it fits, but instead we test imm/256 to
    707    * avoid overflow (underflow is always a successful case) */
    708   return ((imm >> 8) < lsb);
    709 }
    710 
    711 
    712 uint32_t ImmediateA32::Decode(uint32_t value) {
    713   int rotation = (value >> 8) * 2;
    714   VIXL_ASSERT(rotation >= 0);
    715   VIXL_ASSERT(rotation <= 30);
    716   value &= 0xff;
    717   if (rotation == 0) return value;
    718   return (value >> rotation) | (value << (32 - rotation));
    719 }
    720 
    721 
    722 uint32_t TypeEncodingValue(Shift shift) {
    723   return shift.IsRRX() ? kRRXEncodedValue : shift.GetValue();
    724 }
    725 
    726 
    727 uint32_t AmountEncodingValue(Shift shift, uint32_t amount) {
    728   switch (shift.GetType()) {
    729     case LSL:
    730     case ROR:
    731       return amount;
    732     case LSR:
    733     case ASR:
    734       return amount % 32;
    735     case RRX:
    736       return 0;
    737   }
    738   return 0;
    739 }
    740 
    741 }  // namespace aarch32
    742 }  // namespace vixl
    743