1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H
8 : #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H
9 :
10 : /*
11 : * Models instructions and decode results.
12 : *
13 : * TODO(petarj): This file and the classes have been based on the same named
14 : * module within validator_arm folder. The code has been reduced and changed
15 : * slightly to accommodate some style issues. There still may be room for
16 : * improvement as we have not investigated performance impact of this classes.
17 : * Thus, this should be done later and the code should be revisited.
18 : */
19 :
20 : #include <stdint.h>
21 :
22 : namespace nacl_mips_dec {
23 :
24 : /*
25 : * A value class that names a single register. We could use a typedef for this,
26 : * but it introduces some ambiguity problems because of the implicit conversion
27 : * to/from int.
28 : *
29 : * May be implicitly converted to a single-entry RegisterList (see below).
30 : */
31 : class Register {
32 : public:
33 : typedef uint8_t Number;
34 : explicit inline Register(uint32_t);
35 :
36 : /*
37 : * Produces the bitmask used to represent this register.
38 : */
39 : inline uint32_t Bitmask() const;
40 :
41 : inline bool Equals(const Register &) const;
42 :
43 : static const Number kJumpMask = 14; // $t6 = holds mask for jr.
44 : static const Number kLoadStoreMask = 15; // $t7 = holds mask for load/store.
45 : static const Number kTls = 24; // $t8 = holds tls index.
46 : static const Number kSp = 29; // Stack pointer.
47 :
48 : static const Number kNone = 32;
49 :
50 : /*
51 : * A special value used to indicate that a register field is not used.
52 : * This is specially chosen to ensure that bitmask() == 0, so it can be added
53 : * to any RegisterList with no effect.
54 : */
55 72 : static Register None() { return Register(kNone); }
56 :
57 : /* Registers with special meaning in our model: */
58 4 : static Register JumpMask() { return Register(kJumpMask); }
59 78 : static Register LoadStoreMask() { return Register(kLoadStoreMask); }
60 30 : static Register Tls() { return Register(kTls); }
61 327 : static Register Sp() { return Register(kSp); }
62 :
63 : private:
64 : uint32_t _number;
65 : };
66 :
67 : /*
68 : * A collection of Registers. Used to describe the side effects of operations.
69 : *
70 : * Note that this is technically a set, not a list -- but RegisterSet is a
71 : * well-known term that means something else.
72 : */
73 : class RegisterList {
74 : public:
75 : /*
76 : * Produces a RegisterList that contains the registers specified in the
77 : * given bitmask. To indicate rN, the bitmask must include (1 << N).
78 : */
79 : explicit inline RegisterList(uint32_t bitmask);
80 :
81 : /*
82 : * Produces a RegisterList containing a single register.
83 : *
84 : * Note that this is an implicit constructor. This is okay in this case
85 : * because
86 : * - It converts between two types that we control,
87 : * - It converts at most one step (no implicit conversions to Register),
88 : * - It inlines to a single machine instruction,
89 : * - The readability gain in inst_classes.cc is large.
90 : */
91 : explicit inline RegisterList(const Register r);
92 :
93 : /*
94 : * Checks whether this list contains the given register.
95 : */
96 : inline bool operator[](const Register) const;
97 :
98 : // Checks whether this list contains all the registers in the operand.
99 : inline bool ContainsAll(RegisterList) const;
100 :
101 : // Checks whether this list contains any of the registers in the operand.
102 : inline bool ContainsAny(RegisterList) const;
103 :
104 : inline const RegisterList operator&(const RegisterList) const;
105 :
106 : /*
107 : * A list containing every possible register, even some we do not define.
108 : * Used exclusively as a bogus scary return value for forbidden instructions.
109 : */
110 : static RegisterList Everything() { return RegisterList(-1); }
111 :
112 : /* A list of registers that can not be modified by untrusted code. */
113 10 : static RegisterList ReservedRegs() {
114 : return RegisterList(((1 << Register::kJumpMask) |
115 : (1 << Register::kLoadStoreMask) |
116 10 : (1 << Register::kTls)));
117 : }
118 :
119 : /* A list of registers that can be used for addressing memory locations. */
120 10 : static RegisterList DataAddrRegs() {
121 : return RegisterList(((1 << Register::kSp) |
122 10 : (1 << Register::kTls)));
123 : }
124 :
125 : private:
126 : uint32_t _bits;
127 : };
128 :
129 : /*
130 : * A 32-bit Mips instruction of unspecified type.
131 : *
132 : * This class is designed for efficiency:
133 : * - Its public methods for bitfield extraction are short and inline.
134 : * - It has no vtable, so on 32-bit platforms it's exactly the size of the
135 : * instruction it models.
136 : */
137 : class Instruction {
138 : public:
139 : explicit inline Instruction(uint32_t bits);
140 :
141 : /*
142 : * Extracts a range of contiguous bits, right-justifies it, and returns it.
143 : * Note that the range follows hardware convention, with the high bit first.
144 : */
145 : inline uint32_t Bits(int hi, int lo) const;
146 :
147 : /*
148 : * A convenience method that's exactly equivalent to
149 : * Register(instruction.bits(hi, lo))
150 : *
151 : * This sequence is quite common in inst_classes.cc.
152 : */
153 : inline const Register Reg(int hi, int lo) const;
154 :
155 : /*
156 : * Extracts a single bit (0 - 31).
157 : */
158 : inline bool Bit(int index) const;
159 :
160 : /*
161 : * Returns an integer equivalent of this instruction, masked by the given
162 : * mask. Used during decoding to test bitfields.
163 : */
164 : inline uint32_t operator&(uint32_t) const;
165 :
166 : private:
167 : uint32_t _bits;
168 : };
169 :
170 : uint32_t const kInstrSize = 4;
171 : uint32_t const kInstrAlign = 0xFFFFFFFC;
172 : uint32_t const kBundleAlign = 0xFFFFFFF0;
173 :
174 : // Opcode for nop instruction.
175 : uint32_t const kNop = 0x0;
176 :
177 : } // namespace
178 :
179 : // Definitions for our inlined functions.
180 : #include "native_client/src/trusted/validator_mips/model-inl.h"
181 :
182 : #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_MIPS_MODEL_H
|