cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

decoder-a64.h (10320B)


      1// Copyright 2014, 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#ifndef VIXL_A64_DECODER_A64_H_
     28#define VIXL_A64_DECODER_A64_H_
     29
     30#include <list>
     31
     32#include "vixl/globals.h"
     33#include "vixl/a64/instructions-a64.h"
     34
     35
     36// List macro containing all visitors needed by the decoder class.
     37
     38#define VISITOR_LIST_THAT_RETURN(V) \
     39  V(PCRelAddressing)                \
     40  V(AddSubImmediate)                \
     41  V(LogicalImmediate)               \
     42  V(MoveWideImmediate)              \
     43  V(Bitfield)                       \
     44  V(Extract)                        \
     45  V(UnconditionalBranch)            \
     46  V(UnconditionalBranchToRegister)  \
     47  V(CompareBranch)                  \
     48  V(TestBranch)                     \
     49  V(ConditionalBranch)              \
     50  V(System)                         \
     51  V(Exception)                      \
     52  V(LoadStorePairPostIndex)         \
     53  V(LoadStorePairOffset)            \
     54  V(LoadStorePairPreIndex)          \
     55  V(LoadStorePairNonTemporal)       \
     56  V(LoadLiteral)                    \
     57  V(LoadStoreUnscaledOffset)        \
     58  V(LoadStorePostIndex)             \
     59  V(LoadStorePreIndex)              \
     60  V(LoadStoreRegisterOffset)        \
     61  V(LoadStoreUnsignedOffset)        \
     62  V(LoadStoreExclusive)             \
     63  V(LogicalShifted)                 \
     64  V(AddSubShifted)                  \
     65  V(AddSubExtended)                 \
     66  V(AddSubWithCarry)                \
     67  V(ConditionalCompareRegister)     \
     68  V(ConditionalCompareImmediate)    \
     69  V(ConditionalSelect)              \
     70  V(DataProcessing1Source)          \
     71  V(DataProcessing2Source)          \
     72  V(DataProcessing3Source)          \
     73  V(FPCompare)                      \
     74  V(FPConditionalCompare)           \
     75  V(FPConditionalSelect)            \
     76  V(FPImmediate)                    \
     77  V(FPDataProcessing1Source)        \
     78  V(FPDataProcessing2Source)        \
     79  V(FPDataProcessing3Source)        \
     80  V(FPIntegerConvert)               \
     81  V(FPFixedPointConvert)            \
     82  V(Crypto2RegSHA)                  \
     83  V(Crypto3RegSHA)                  \
     84  V(CryptoAES)                      \
     85  V(NEON2RegMisc)                   \
     86  V(NEON3Different)                 \
     87  V(NEON3Same)                      \
     88  V(NEONAcrossLanes)                \
     89  V(NEONByIndexedElement)           \
     90  V(NEONCopy)                       \
     91  V(NEONExtract)                    \
     92  V(NEONLoadStoreMultiStruct)       \
     93  V(NEONLoadStoreMultiStructPostIndex)  \
     94  V(NEONLoadStoreSingleStruct)      \
     95  V(NEONLoadStoreSingleStructPostIndex) \
     96  V(NEONModifiedImmediate)          \
     97  V(NEONScalar2RegMisc)             \
     98  V(NEONScalar3Diff)                \
     99  V(NEONScalar3Same)                \
    100  V(NEONScalarByIndexedElement)     \
    101  V(NEONScalarCopy)                 \
    102  V(NEONScalarPairwise)             \
    103  V(NEONScalarShiftImmediate)       \
    104  V(NEONShiftImmediate)             \
    105  V(NEONTable)                      \
    106  V(NEONPerm)                       \
    107
    108#define VISITOR_LIST_THAT_DONT_RETURN(V)  \
    109  V(Unallocated)                          \
    110  V(Unimplemented)                        \
    111
    112#define VISITOR_LIST(V)             \
    113  VISITOR_LIST_THAT_RETURN(V)       \
    114  VISITOR_LIST_THAT_DONT_RETURN(V)  \
    115
    116namespace vixl {
    117
    118// The Visitor interface. Disassembler and simulator (and other tools)
    119// must provide implementations for all of these functions.
    120class DecoderVisitor {
    121 public:
    122  enum VisitorConstness {
    123    kConstVisitor,
    124    kNonConstVisitor
    125  };
    126  explicit DecoderVisitor(VisitorConstness constness = kConstVisitor)
    127      : constness_(constness) {}
    128
    129  virtual ~DecoderVisitor() {}
    130
    131  #define DECLARE(A) virtual void Visit##A(const Instruction* instr) = 0;
    132  VISITOR_LIST(DECLARE)
    133  #undef DECLARE
    134
    135  bool IsConstVisitor() const { return constness_ == kConstVisitor; }
    136  Instruction* MutableInstruction(const Instruction* instr) {
    137    VIXL_ASSERT(!IsConstVisitor());
    138    return const_cast<Instruction*>(instr);
    139  }
    140
    141 private:
    142  const VisitorConstness constness_;
    143};
    144
    145
    146class Decoder {
    147 public:
    148  Decoder() {}
    149
    150  // Top-level wrappers around the actual decoding function.
    151  void Decode(const Instruction* instr) {
    152    std::list<DecoderVisitor*>::iterator it;
    153    for (it = visitors_.begin(); it != visitors_.end(); it++) {
    154      VIXL_ASSERT((*it)->IsConstVisitor());
    155    }
    156    DecodeInstruction(instr);
    157  }
    158  void Decode(Instruction* instr) {
    159    DecodeInstruction(const_cast<const Instruction*>(instr));
    160  }
    161
    162  // Register a new visitor class with the decoder.
    163  // Decode() will call the corresponding visitor method from all registered
    164  // visitor classes when decoding reaches the leaf node of the instruction
    165  // decode tree.
    166  // Visitors are called in order.
    167  // A visitor can be registered multiple times.
    168  //
    169  //   d.AppendVisitor(V1);
    170  //   d.AppendVisitor(V2);
    171  //   d.PrependVisitor(V2);
    172  //   d.AppendVisitor(V3);
    173  //
    174  //   d.Decode(i);
    175  //
    176  // will call in order visitor methods in V2, V1, V2, V3.
    177  void AppendVisitor(DecoderVisitor* visitor);
    178  void PrependVisitor(DecoderVisitor* visitor);
    179  // These helpers register `new_visitor` before or after the first instance of
    180  // `registered_visiter` in the list.
    181  // So if
    182  //   V1, V2, V1, V2
    183  // are registered in this order in the decoder, calls to
    184  //   d.InsertVisitorAfter(V3, V1);
    185  //   d.InsertVisitorBefore(V4, V2);
    186  // will yield the order
    187  //   V1, V3, V4, V2, V1, V2
    188  //
    189  // For more complex modifications of the order of registered visitors, one can
    190  // directly access and modify the list of visitors via the `visitors()'
    191  // accessor.
    192  void InsertVisitorBefore(DecoderVisitor* new_visitor,
    193                           DecoderVisitor* registered_visitor);
    194  void InsertVisitorAfter(DecoderVisitor* new_visitor,
    195                          DecoderVisitor* registered_visitor);
    196
    197  // Remove all instances of a previously registered visitor class from the list
    198  // of visitors stored by the decoder.
    199  void RemoveVisitor(DecoderVisitor* visitor);
    200
    201  #define DECLARE(A) void Visit##A(const Instruction* instr);
    202  VISITOR_LIST(DECLARE)
    203  #undef DECLARE
    204
    205
    206  std::list<DecoderVisitor*>* visitors() { return &visitors_; }
    207
    208 private:
    209  // Decodes an instruction and calls the visitor functions registered with the
    210  // Decoder class.
    211  void DecodeInstruction(const Instruction* instr);
    212
    213  // Decode the PC relative addressing instruction, and call the corresponding
    214  // visitors.
    215  // On entry, instruction bits 27:24 = 0x0.
    216  void DecodePCRelAddressing(const Instruction* instr);
    217
    218  // Decode the add/subtract immediate instruction, and call the correspoding
    219  // visitors.
    220  // On entry, instruction bits 27:24 = 0x1.
    221  void DecodeAddSubImmediate(const Instruction* instr);
    222
    223  // Decode the branch, system command, and exception generation parts of
    224  // the instruction tree, and call the corresponding visitors.
    225  // On entry, instruction bits 27:24 = {0x4, 0x5, 0x6, 0x7}.
    226  void DecodeBranchSystemException(const Instruction* instr);
    227
    228  // Decode the load and store parts of the instruction tree, and call
    229  // the corresponding visitors.
    230  // On entry, instruction bits 27:24 = {0x8, 0x9, 0xC, 0xD}.
    231  void DecodeLoadStore(const Instruction* instr);
    232
    233  // Decode the logical immediate and move wide immediate parts of the
    234  // instruction tree, and call the corresponding visitors.
    235  // On entry, instruction bits 27:24 = 0x2.
    236  void DecodeLogical(const Instruction* instr);
    237
    238  // Decode the bitfield and extraction parts of the instruction tree,
    239  // and call the corresponding visitors.
    240  // On entry, instruction bits 27:24 = 0x3.
    241  void DecodeBitfieldExtract(const Instruction* instr);
    242
    243  // Decode the data processing parts of the instruction tree, and call the
    244  // corresponding visitors.
    245  // On entry, instruction bits 27:24 = {0x1, 0xA, 0xB}.
    246  void DecodeDataProcessing(const Instruction* instr);
    247
    248  // Decode the floating point parts of the instruction tree, and call the
    249  // corresponding visitors.
    250  // On entry, instruction bits 27:24 = {0xE, 0xF}.
    251  void DecodeFP(const Instruction* instr);
    252
    253  // Decode the Advanced SIMD (NEON) load/store part of the instruction tree,
    254  // and call the corresponding visitors.
    255  // On entry, instruction bits 29:25 = 0x6.
    256  void DecodeNEONLoadStore(const Instruction* instr);
    257
    258  // Decode the Advanced SIMD (NEON) vector data processing part of the
    259  // instruction tree, and call the corresponding visitors.
    260  // On entry, instruction bits 28:25 = 0x7.
    261  void DecodeNEONVectorDataProcessing(const Instruction* instr);
    262
    263  // Decode the Advanced SIMD (NEON) scalar data processing part of the
    264  // instruction tree, and call the corresponding visitors.
    265  // On entry, instruction bits 28:25 = 0xF.
    266  void DecodeNEONScalarDataProcessing(const Instruction* instr);
    267
    268 private:
    269  // Visitors are registered in a list.
    270  std::list<DecoderVisitor*> visitors_;
    271};
    272
    273}  // namespace vixl
    274
    275#endif  // VIXL_A64_DECODER_A64_H_