• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_ARM_CONSTANTS_ARM_H_
29 #define V8_ARM_CONSTANTS_ARM_H_
30 
31 // The simulator emulates the EABI so we define the USE_ARM_EABI macro if we
32 // are not running on real ARM hardware.  One reason for this is that the
33 // old ABI uses fp registers in the calling convention and the simulator does
34 // not simulate fp registers or coroutine instructions.
35 #if defined(__ARM_EABI__) || !defined(__arm__)
36 # define USE_ARM_EABI 1
37 #endif
38 
39 // This means that interwork-compatible jump instructions are generated.  We
40 // want to generate them on the simulator too so it makes snapshots that can
41 // be used on real hardware.
42 #if defined(__THUMB_INTERWORK__) || !defined(__arm__)
43 # define USE_THUMB_INTERWORK 1
44 #endif
45 
46 #if defined(__ARM_ARCH_7A__) || \
47     defined(__ARM_ARCH_7R__) || \
48     defined(__ARM_ARCH_7__)
49 # define CAN_USE_ARMV7_INSTRUCTIONS 1
50 #endif
51 
52 #if defined(__ARM_ARCH_6__) ||   \
53     defined(__ARM_ARCH_6J__) ||  \
54     defined(__ARM_ARCH_6K__) ||  \
55     defined(__ARM_ARCH_6Z__) ||  \
56     defined(__ARM_ARCH_6ZK__) || \
57     defined(__ARM_ARCH_6T2__) || \
58     defined(CAN_USE_ARMV7_INSTRUCTIONS)
59 # define CAN_USE_ARMV6_INSTRUCTIONS 1
60 #endif
61 
62 #if defined(__ARM_ARCH_5T__)            || \
63     defined(__ARM_ARCH_5TE__)           || \
64     defined(CAN_USE_ARMV6_INSTRUCTIONS)
65 # define CAN_USE_ARMV5_INSTRUCTIONS 1
66 # define CAN_USE_THUMB_INSTRUCTIONS 1
67 #endif
68 
69 // Simulator should support ARM5 instructions.
70 #if !defined(__arm__)
71 # define CAN_USE_ARMV5_INSTRUCTIONS 1
72 # define CAN_USE_THUMB_INSTRUCTIONS 1
73 #endif
74 
75 namespace assembler {
76 namespace arm {
77 
78 // Number of registers in normal ARM mode.
79 static const int kNumRegisters = 16;
80 
81 // VFP support.
82 static const int kNumVFPRegisters = 48;
83 
84 // PC is register 15.
85 static const int kPCRegister = 15;
86 static const int kNoRegister = -1;
87 
88 // Defines constants and accessor classes to assemble, disassemble and
89 // simulate ARM instructions.
90 //
91 // Section references in the code refer to the "ARM Architecture Reference
92 // Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
93 //
94 // Constants for specific fields are defined in their respective named enums.
95 // General constants are in an anonymous enum in class Instr.
96 
97 typedef unsigned char byte;
98 
99 // Values for the condition field as defined in section A3.2
100 enum Condition {
101   no_condition = -1,
102   EQ =  0,  // equal
103   NE =  1,  // not equal
104   CS =  2,  // carry set/unsigned higher or same
105   CC =  3,  // carry clear/unsigned lower
106   MI =  4,  // minus/negative
107   PL =  5,  // plus/positive or zero
108   VS =  6,  // overflow
109   VC =  7,  // no overflow
110   HI =  8,  // unsigned higher
111   LS =  9,  // unsigned lower or same
112   GE = 10,  // signed greater than or equal
113   LT = 11,  // signed less than
114   GT = 12,  // signed greater than
115   LE = 13,  // signed less than or equal
116   AL = 14,  // always (unconditional)
117   special_condition = 15,  // special condition (refer to section A3.2.1)
118   max_condition = 16
119 };
120 
121 
122 // Opcodes for Data-processing instructions (instructions with a type 0 and 1)
123 // as defined in section A3.4
124 enum Opcode {
125   no_operand = -1,
126   AND =  0,  // Logical AND
127   EOR =  1,  // Logical Exclusive OR
128   SUB =  2,  // Subtract
129   RSB =  3,  // Reverse Subtract
130   ADD =  4,  // Add
131   ADC =  5,  // Add with Carry
132   SBC =  6,  // Subtract with Carry
133   RSC =  7,  // Reverse Subtract with Carry
134   TST =  8,  // Test
135   TEQ =  9,  // Test Equivalence
136   CMP = 10,  // Compare
137   CMN = 11,  // Compare Negated
138   ORR = 12,  // Logical (inclusive) OR
139   MOV = 13,  // Move
140   BIC = 14,  // Bit Clear
141   MVN = 15,  // Move Not
142   max_operand = 16
143 };
144 
145 
146 // Some special instructions encoded as a TEQ with S=0 (bit 20).
147 enum Opcode9Bits {
148   BX   =  1,
149   BXJ  =  2,
150   BLX  =  3,
151   BKPT =  7
152 };
153 
154 
155 // Some special instructions encoded as a CMN with S=0 (bit 20).
156 enum Opcode11Bits {
157   CLZ  =  1
158 };
159 
160 
161 // S
162 
163 
164 // Shifter types for Data-processing operands as defined in section A5.1.2.
165 enum Shift {
166   no_shift = -1,
167   LSL = 0,  // Logical shift left
168   LSR = 1,  // Logical shift right
169   ASR = 2,  // Arithmetic shift right
170   ROR = 3,  // Rotate right
171   max_shift = 4
172 };
173 
174 
175 // Special Software Interrupt codes when used in the presence of the ARM
176 // simulator.
177 enum SoftwareInterruptCodes {
178   // transition to C code
179   call_rt_redirected = 0x10,
180   // break point
181   break_point = 0x20
182 };
183 
184 
185 typedef int32_t instr_t;
186 
187 
188 // The class Instr enables access to individual fields defined in the ARM
189 // architecture instruction set encoding as described in figure A3-1.
190 //
191 // Example: Test whether the instruction at ptr does set the condition code
192 // bits.
193 //
194 // bool InstructionSetsConditionCodes(byte* ptr) {
195 //   Instr* instr = Instr::At(ptr);
196 //   int type = instr->TypeField();
197 //   return ((type == 0) || (type == 1)) && instr->HasS();
198 // }
199 //
200 class Instr {
201  public:
202   enum {
203     kInstrSize = 4,
204     kInstrSizeLog2 = 2,
205     kPCReadOffset = 8
206   };
207 
208   // Get the raw instruction bits.
InstructionBits()209   inline instr_t InstructionBits() const {
210     return *reinterpret_cast<const instr_t*>(this);
211   }
212 
213   // Set the raw instruction bits to value.
SetInstructionBits(instr_t value)214   inline void SetInstructionBits(instr_t value) {
215     *reinterpret_cast<instr_t*>(this) = value;
216   }
217 
218   // Read one particular bit out of the instruction bits.
Bit(int nr)219   inline int Bit(int nr) const {
220     return (InstructionBits() >> nr) & 1;
221   }
222 
223   // Read a bit field out of the instruction bits.
Bits(int hi,int lo)224   inline int Bits(int hi, int lo) const {
225     return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
226   }
227 
228 
229   // Accessors for the different named fields used in the ARM encoding.
230   // The naming of these accessor corresponds to figure A3-1.
231   // Generally applicable fields
ConditionField()232   inline Condition ConditionField() const {
233     return static_cast<Condition>(Bits(31, 28));
234   }
TypeField()235   inline int TypeField() const { return Bits(27, 25); }
236 
RnField()237   inline int RnField() const { return Bits(19, 16); }
RdField()238   inline int RdField() const { return Bits(15, 12); }
239 
CoprocessorField()240   inline int CoprocessorField() const { return Bits(11, 8); }
241   // Support for VFP.
242   // Vn(19-16) | Vd(15-12) |  Vm(3-0)
VnField()243   inline int VnField() const { return Bits(19, 16); }
VmField()244   inline int VmField() const { return Bits(3, 0); }
VdField()245   inline int VdField() const { return Bits(15, 12); }
NField()246   inline int NField() const { return Bit(7); }
MField()247   inline int MField() const { return Bit(5); }
DField()248   inline int DField() const { return Bit(22); }
RtField()249   inline int RtField() const { return Bits(15, 12); }
PField()250   inline int PField() const { return Bit(24); }
UField()251   inline int UField() const { return Bit(23); }
252 
253   // Fields used in Data processing instructions
OpcodeField()254   inline Opcode OpcodeField() const {
255     return static_cast<Opcode>(Bits(24, 21));
256   }
SField()257   inline int SField() const { return Bit(20); }
258     // with register
RmField()259   inline int RmField() const { return Bits(3, 0); }
ShiftField()260   inline Shift ShiftField() const { return static_cast<Shift>(Bits(6, 5)); }
RegShiftField()261   inline int RegShiftField() const { return Bit(4); }
RsField()262   inline int RsField() const { return Bits(11, 8); }
ShiftAmountField()263   inline int ShiftAmountField() const { return Bits(11, 7); }
264     // with immediate
RotateField()265   inline int RotateField() const { return Bits(11, 8); }
Immed8Field()266   inline int Immed8Field() const { return Bits(7, 0); }
267 
268   // Fields used in Load/Store instructions
PUField()269   inline int PUField() const { return Bits(24, 23); }
BField()270   inline int  BField() const { return Bit(22); }
WField()271   inline int  WField() const { return Bit(21); }
LField()272   inline int  LField() const { return Bit(20); }
273     // with register uses same fields as Data processing instructions above
274     // with immediate
Offset12Field()275   inline int Offset12Field() const { return Bits(11, 0); }
276     // multiple
RlistField()277   inline int RlistField() const { return Bits(15, 0); }
278     // extra loads and stores
SignField()279   inline int SignField() const { return Bit(6); }
HField()280   inline int HField() const { return Bit(5); }
ImmedHField()281   inline int ImmedHField() const { return Bits(11, 8); }
ImmedLField()282   inline int ImmedLField() const { return Bits(3, 0); }
283 
284   // Fields used in Branch instructions
LinkField()285   inline int LinkField() const { return Bit(24); }
SImmed24Field()286   inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
287 
288   // Fields used in Software interrupt instructions
SwiField()289   inline SoftwareInterruptCodes SwiField() const {
290     return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
291   }
292 
293   // Test for special encodings of type 0 instructions (extra loads and stores,
294   // as well as multiplications).
IsSpecialType0()295   inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); }
296 
297   // Special accessors that test for existence of a value.
HasS()298   inline bool HasS()    const { return SField() == 1; }
HasB()299   inline bool HasB()    const { return BField() == 1; }
HasW()300   inline bool HasW()    const { return WField() == 1; }
HasL()301   inline bool HasL()    const { return LField() == 1; }
HasU()302   inline bool HasU()    const { return UField() == 1; }
HasSign()303   inline bool HasSign() const { return SignField() == 1; }
HasH()304   inline bool HasH()    const { return HField() == 1; }
HasLink()305   inline bool HasLink() const { return LinkField() == 1; }
306 
307   // Instructions are read of out a code stream. The only way to get a
308   // reference to an instruction is to convert a pointer. There is no way
309   // to allocate or create instances of class Instr.
310   // Use the At(pc) function to create references to Instr.
At(byte * pc)311   static Instr* At(byte* pc) { return reinterpret_cast<Instr*>(pc); }
312 
313  private:
314   // We need to prevent the creation of instances of class Instr.
315   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
316 };
317 
318 
319 // Helper functions for converting between register numbers and names.
320 class Registers {
321  public:
322   // Return the name of the register.
323   static const char* Name(int reg);
324 
325   // Lookup the register number for the name provided.
326   static int Number(const char* name);
327 
328   struct RegisterAlias {
329     int reg;
330     const char* name;
331   };
332 
333  private:
334   static const char* names_[kNumRegisters];
335   static const RegisterAlias aliases_[];
336 };
337 
338 // Helper functions for converting between VFP register numbers and names.
339 class VFPRegisters {
340  public:
341   // Return the name of the register.
342   static const char* Name(int reg);
343 
344  private:
345   static const char* names_[kNumVFPRegisters];
346 };
347 
348 
349 } }  // namespace assembler::arm
350 
351 #endif  // V8_ARM_CONSTANTS_ARM_H_
352