OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2009 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can |
| 4 * be found in the LICENSE file. |
| 5 * Copyright 2009, Google Inc. |
| 6 */ |
| 7 |
| 8 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H |
| 9 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H |
| 10 |
| 11 /* |
| 12 * Models instructions and decode results. |
| 13 * |
| 14 * Implementation Note: |
| 15 * All the classes in this file are designed to be fully inlined as 32-bit |
| 16 * integers. The goal: to provide a nice, fluent interface for describing |
| 17 * instruction bit operations, with zero runtime cost. Compare: |
| 18 * |
| 19 * return (1 << ((insn >> 12) & 0xF)) | (1 << ((insn >> 19) & 0xF)); |
| 20 * |
| 21 * return insn.reg(15,12) + insn.reg(19,16); |
| 22 * |
| 23 * Both lines compile to the same machine code, but the second one is easier |
| 24 * to read, and eliminates a common error (using X in place of 1 << X). |
| 25 * |
| 26 * To this end, keep the following in mind: |
| 27 * - Avoid virtual methods. |
| 28 * - Mark all methods as inline. Small method bodies may be included here, |
| 29 * but anything nontrivial should go in model-inl.h. |
| 30 * - Do not declare destructors. A destructor causes an object to be passed |
| 31 * on the stack, even when passed by value. (This may be a GCC bug.) |
| 32 * Adding a destructor to Instruction slowed the decoder down by 10% on |
| 33 * gcc 4.3.3. |
| 34 */ |
| 35 |
| 36 #include <stdint.h> |
| 37 |
| 38 namespace nacl_mips_dec { |
| 39 |
| 40 /* |
| 41 * A value class that names a single register. We could use a typedef for this, |
| 42 * but it introduces some ambiguity problems because of the implicit conversion |
| 43 * to/from int. |
| 44 * |
| 45 * May be implicitly converted to a single-entry RegisterList (see below). |
| 46 */ |
| 47 class Register { |
| 48 public: |
| 49 explicit inline Register(uint32_t); |
| 50 |
| 51 /* |
| 52 * Produces the bitmask used to represent this register. |
| 53 */ |
| 54 inline uint32_t bitmask() const; |
| 55 |
| 56 inline bool operator==(const Register &) const; |
| 57 inline bool operator!=(const Register &) const; |
| 58 |
| 59 private: |
| 60 uint32_t _number; |
| 61 }; |
| 62 |
| 63 const Register kRegisterNone(0); |
| 64 |
| 65 // Registers with special meaning in our model: |
| 66 const Register kRegisterStack(29); |
| 67 const Register kRegisterJumpMask(14); // $t6 = holds mask for jr. |
| 68 const Register kRegisterLoadStoreMask(15); // $t7 = holds mask for load/store. |
| 69 const Register kRegisterTls(24); // $t8 = holds tls index. |
| 70 |
| 71 const Register kRegisterZero(0); |
| 72 |
| 73 |
| 74 /* |
| 75 * A collection of Registers. Used to describe the side effects of operations. |
| 76 * |
| 77 * Note that this is technically a set, not a list -- but RegisterSet is a |
| 78 * well-known term that means something else. |
| 79 */ |
| 80 class RegisterList { |
| 81 public: |
| 82 /* |
| 83 * Produces a RegisterList that contains the registers specified in the |
| 84 * given bitmask. To indicate rN, the bitmask must include (1 << N). |
| 85 */ |
| 86 explicit inline RegisterList(uint32_t bitmask); |
| 87 |
| 88 /* |
| 89 * Produces a RegisterList containing a single register. |
| 90 * |
| 91 * Note that this is an implicit constructor. This is okay in this case |
| 92 * because |
| 93 * - It converts between two types that we control, |
| 94 * - It converts at most one step (no implicit conversions to Register), |
| 95 * - It inlines to a single machine instruction, |
| 96 * - The readability gain in inst_classes.cc is large. |
| 97 */ |
| 98 inline RegisterList(const Register r); |
| 99 |
| 100 /* |
| 101 * Checks whether this list contains the given register. |
| 102 */ |
| 103 inline bool operator[](const Register) const; |
| 104 |
| 105 // Checks whether this list contains all the registers in the operand. |
| 106 inline bool contains_all(RegisterList) const; |
| 107 |
| 108 // Checks whether this list contains any of the registers in the operand. |
| 109 inline bool contains_any(RegisterList) const; |
| 110 |
| 111 inline bool operator==(RegisterList) const; |
| 112 |
| 113 inline const RegisterList operator&(const RegisterList) const; |
| 114 |
| 115 // Allow the addition operator access to our bitwise representation. |
| 116 friend const RegisterList operator+(const RegisterList, const RegisterList); |
| 117 |
| 118 private: |
| 119 uint32_t _bits; |
| 120 }; |
| 121 |
| 122 /* |
| 123 * Returns a new RegisterList that contains the union of two lists. |
| 124 * |
| 125 * This is not a member function to allow implicit conversion of Register. |
| 126 */ |
| 127 inline const RegisterList operator+(const RegisterList, const RegisterList); |
| 128 |
| 129 /* |
| 130 * A list containing every possible register, even some we don't define. |
| 131 * Used exclusively as a bogus scary return value for forbidden instructions. |
| 132 */ |
| 133 static const RegisterList kRegisterListEverything = RegisterList(-1); |
| 134 |
| 135 static uint32_t const kReservedRegsBitmask = kRegisterTls.bitmask() |
| 136 + kRegisterJumpMask.bitmask() |
| 137 + kRegisterLoadStoreMask.bitmask(); |
| 138 static RegisterList const kRegListReserved = RegisterList(kReservedRegsBitmask); |
| 139 |
| 140 /* |
| 141 * A 32-bit Mips instruction of unspecified type. |
| 142 * |
| 143 * This class is designed for efficiency: |
| 144 * - Its public methods for bitfield extraction are short and inline. |
| 145 * - It has no vtable, so on 32-bit platforms it's exactly the size of the |
| 146 * instruction it models. |
| 147 */ |
| 148 class Instruction { |
| 149 public: |
| 150 explicit inline Instruction(uint32_t bits); |
| 151 |
| 152 /* |
| 153 * Extracts a range of contiguous bits, right-justifies it, and returns it. |
| 154 * Note that the range follows hardware convention, with the high bit first. |
| 155 */ |
| 156 inline uint32_t bits(int hi, int lo) const; |
| 157 |
| 158 /* |
| 159 * A convenience method that's exactly equivalent to |
| 160 * Register(instruction.bits(hi, lo)) |
| 161 * |
| 162 * This sequence is quite common in inst_classes.cc. |
| 163 */ |
| 164 inline const Register reg(int hi, int lo) const; |
| 165 |
| 166 /* |
| 167 * Extracts a single bit (0 - 31). |
| 168 */ |
| 169 inline bool bit(int index) const; |
| 170 |
| 171 |
| 172 /* |
| 173 * Returns an integer equivalent of this instruction, masked by the given |
| 174 * mask. Used during decoding to test bitfields. |
| 175 */ |
| 176 inline uint32_t operator&(uint32_t) const; |
| 177 |
| 178 |
| 179 |
| 180 private: |
| 181 uint32_t _bits; |
| 182 }; |
| 183 |
| 184 uint32_t const kInstrSize = 4; |
| 185 uint32_t const kInstrAlign = 0xFFFFFFFC; |
| 186 uint32_t const kBundleAlign = 0xFFFFFFF0; |
| 187 |
| 188 } // namespace |
| 189 |
| 190 // Definitions for our inlined functions. |
| 191 #include "native_client/src/trusted/validator_mips/model-inl.h" |
| 192 |
| 193 #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H |
OLD | NEW |