Chromium Code Reviews| Index: src/trusted/validator_mips/model.h |
| diff --git a/src/trusted/validator_mips/model.h b/src/trusted/validator_mips/model.h |
| new file mode 100755 |
| index 0000000000000000000000000000000000000000..5e4b6fb4eb120b8a83da85f21e6adb4f3549bb77 |
| --- /dev/null |
| +++ b/src/trusted/validator_mips/model.h |
| @@ -0,0 +1,193 @@ |
| +/* |
| + * Copyright 2012 The Native Client Authors. All rights reserved. |
| + * Use of this source code is governed by a BSD-style license that can |
| + * be found in the LICENSE file. |
| + * Copyright 2012, Google Inc. |
| + */ |
| + |
| +#ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H |
| +#define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H |
| + |
| +/* |
| + * Models instructions and decode results. |
| + * |
| + * Implementation Note: |
| + * All the classes in this file are designed to be fully inlined as 32-bit |
| + * integers. The goal: to provide a nice, fluent interface for describing |
| + * instruction bit operations, with zero runtime cost. Compare: |
| + * |
| + * return (1 << ((insn >> 12) & 0xF)) | (1 << ((insn >> 19) & 0xF)); |
| + * |
| + * return insn.reg(15,12) + insn.reg(19,16); |
| + * |
| + * Both lines compile to the same machine code, but the second one is easier |
| + * to read, and eliminates a common error (using X in place of 1 << X). |
| + * |
| + * To this end, keep the following in mind: |
| + * - Avoid virtual methods. |
| + * - Mark all methods as inline. Small method bodies may be included here, |
| + * but anything nontrivial should go in model-inl.h. |
| + * - Do not declare destructors. A destructor causes an object to be passed |
| + * on the stack, even when passed by value. (This may be a GCC bug.) |
| + * Adding a destructor to Instruction slowed the decoder down by 10% on |
| + * gcc 4.3.3. |
| + */ |
| + |
| +#include <stdint.h> |
| + |
| +namespace nacl_mips_dec { |
| + |
| +/* |
| + * A value class that names a single register. We could use a typedef for this, |
| + * but it introduces some ambiguity problems because of the implicit conversion |
| + * to/from int. |
| + * |
| + * May be implicitly converted to a single-entry RegisterList (see below). |
| + */ |
| +class Register { |
| + public: |
| + explicit inline Register(uint32_t); |
| + |
| + /* |
| + * Produces the bitmask used to represent this register. |
| + */ |
| + inline uint32_t bitmask() const; |
| + |
| + inline bool operator==(const Register &) const; |
|
Brad Chen
2012/05/04 22:49:50
avoid operator overloading
petarj
2012/05/08 14:54:19
Seen in validator_arm/model.h
|
| + inline bool operator!=(const Register &) const; |
| + |
| + private: |
| + uint32_t _number; |
| +}; |
| + |
| +const Register kRegisterNone(0); |
| + |
| +// Registers with special meaning in our model: |
| +const Register kRegisterStack(29); |
| +const Register kRegisterJumpMask(14); // $t6 = holds mask for jr. |
| +const Register kRegisterLoadStoreMask(15); // $t7 = holds mask for load/store. |
| +const Register kRegisterTls(24); // $t8 = holds tls index. |
| + |
| +const Register kRegisterZero(0); |
| + |
| + |
| +/* |
| + * A collection of Registers. Used to describe the side effects of operations. |
| + * |
| + * Note that this is technically a set, not a list -- but RegisterSet is a |
| + * well-known term that means something else. |
| + */ |
| +class RegisterList { |
| + public: |
| + /* |
| + * Produces a RegisterList that contains the registers specified in the |
| + * given bitmask. To indicate rN, the bitmask must include (1 << N). |
| + */ |
| + explicit inline RegisterList(uint32_t bitmask); |
| + |
| + /* |
| + * Produces a RegisterList containing a single register. |
| + * |
| + * Note that this is an implicit constructor. This is okay in this case |
| + * because |
| + * - It converts between two types that we control, |
| + * - It converts at most one step (no implicit conversions to Register), |
| + * - It inlines to a single machine instruction, |
| + * - The readability gain in inst_classes.cc is large. |
| + */ |
| + inline RegisterList(const Register r); |
| + |
| + /* |
| + * Checks whether this list contains the given register. |
| + */ |
| + inline bool operator[](const Register) const; |
| + |
| + // Checks whether this list contains all the registers in the operand. |
| + inline bool contains_all(RegisterList) const; |
| + |
| + // Checks whether this list contains any of the registers in the operand. |
| + inline bool contains_any(RegisterList) const; |
| + |
| + inline bool operator==(RegisterList) const; |
| + |
| + inline const RegisterList operator&(const RegisterList) const; |
| + |
| + // Allow the addition operator access to our bitwise representation. |
| + friend const RegisterList operator+(const RegisterList, const RegisterList); |
| + |
| + private: |
| + uint32_t _bits; |
| +}; |
| + |
| +/* |
| + * Returns a new RegisterList that contains the union of two lists. |
| + * |
| + * This is not a member function to allow implicit conversion of Register. |
| + */ |
| +inline const RegisterList operator+(const RegisterList, const RegisterList); |
| + |
| +/* |
| + * A list containing every possible register, even some we don't define. |
| + * Used exclusively as a bogus scary return value for forbidden instructions. |
| + */ |
| +static const RegisterList kRegisterListEverything = RegisterList(-1); |
| + |
| +static uint32_t const kReservedRegsBitmask = kRegisterTls.bitmask() |
| + + kRegisterJumpMask.bitmask() |
| + + kRegisterLoadStoreMask.bitmask(); |
| +static RegisterList const kRegListReserved = RegisterList(kReservedRegsBitmask); |
| + |
| +/* |
| + * A 32-bit Mips instruction of unspecified type. |
| + * |
| + * This class is designed for efficiency: |
| + * - Its public methods for bitfield extraction are short and inline. |
| + * - It has no vtable, so on 32-bit platforms it's exactly the size of the |
| + * instruction it models. |
| + */ |
| +class Instruction { |
| + public: |
| + explicit inline Instruction(uint32_t bits); |
| + |
| + /* |
| + * Extracts a range of contiguous bits, right-justifies it, and returns it. |
| + * Note that the range follows hardware convention, with the high bit first. |
| + */ |
| + inline uint32_t bits(int hi, int lo) const; |
| + |
| + /* |
| + * A convenience method that's exactly equivalent to |
| + * Register(instruction.bits(hi, lo)) |
| + * |
| + * This sequence is quite common in inst_classes.cc. |
| + */ |
| + inline const Register reg(int hi, int lo) const; |
| + |
| + /* |
| + * Extracts a single bit (0 - 31). |
| + */ |
| + inline bool bit(int index) const; |
| + |
| + |
| + /* |
| + * Returns an integer equivalent of this instruction, masked by the given |
| + * mask. Used during decoding to test bitfields. |
| + */ |
| + inline uint32_t operator&(uint32_t) const; |
| + |
| + |
| + |
| + private: |
| + uint32_t _bits; |
| +}; |
| + |
| +uint32_t const kInstrSize = 4; |
| +uint32_t const kInstrAlign = 0xFFFFFFFC; |
| +uint32_t const kBundleAlign = 0xFFFFFFF0; |
| + |
| +} // namespace |
| + |
| +// Definitions for our inlined functions. |
| +#include "native_client/src/trusted/validator_mips/model-inl.h" |
| + |
| +#endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H |