• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2009 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 // Simulator should support ARM5 instructions.
47 #if !defined(__arm__)
48 # define __ARM_ARCH_5__ 1
49 # define __ARM_ARCH_5T__ 1
50 #endif
51 
52 namespace assembler {
53 namespace arm {
54 
55 // Defines constants and accessor classes to assemble, disassemble and
56 // simulate ARM instructions.
57 //
58 // Section references in the code refer to the "ARM Architecture Reference
59 // Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
60 //
61 // Constants for specific fields are defined in their respective named enums.
62 // General constants are in an anonymous enum in class Instr.
63 
64 typedef unsigned char byte;
65 
66 // Values for the condition field as defined in section A3.2
67 enum Condition {
68   no_condition = -1,
69   EQ =  0,  // equal
70   NE =  1,  // not equal
71   CS =  2,  // carry set/unsigned higher or same
72   CC =  3,  // carry clear/unsigned lower
73   MI =  4,  // minus/negative
74   PL =  5,  // plus/positive or zero
75   VS =  6,  // overflow
76   VC =  7,  // no overflow
77   HI =  8,  // unsigned higher
78   LS =  9,  // unsigned lower or same
79   GE = 10,  // signed greater than or equal
80   LT = 11,  // signed less than
81   GT = 12,  // signed greater than
82   LE = 13,  // signed less than or equal
83   AL = 14,  // always (unconditional)
84   special_condition = 15,  // special condition (refer to section A3.2.1)
85   max_condition = 16
86 };
87 
88 
89 // Opcodes for Data-processing instructions (instructions with a type 0 and 1)
90 // as defined in section A3.4
91 enum Opcode {
92   no_operand = -1,
93   AND =  0,  // Logical AND
94   EOR =  1,  // Logical Exclusive OR
95   SUB =  2,  // Subtract
96   RSB =  3,  // Reverse Subtract
97   ADD =  4,  // Add
98   ADC =  5,  // Add with Carry
99   SBC =  6,  // Subtract with Carry
100   RSC =  7,  // Reverse Subtract with Carry
101   TST =  8,  // Test
102   TEQ =  9,  // Test Equivalence
103   CMP = 10,  // Compare
104   CMN = 11,  // Compare Negated
105   ORR = 12,  // Logical (inclusive) OR
106   MOV = 13,  // Move
107   BIC = 14,  // Bit Clear
108   MVN = 15,  // Move Not
109   max_operand = 16
110 };
111 
112 
113 // Some special instructions encoded as a TEQ with S=0 (bit 20).
114 enum Opcode9Bits {
115   BX   =  1,
116   BXJ  =  2,
117   BLX  =  3,
118   BKPT =  7
119 };
120 
121 
122 // Some special instructions encoded as a CMN with S=0 (bit 20).
123 enum Opcode11Bits {
124   CLZ  =  1
125 };
126 
127 
128 // S
129 
130 
131 // Shifter types for Data-processing operands as defined in section A5.1.2.
132 enum Shift {
133   no_shift = -1,
134   LSL = 0,  // Logical shift left
135   LSR = 1,  // Logical shift right
136   ASR = 2,  // Arithmetic shift right
137   ROR = 3,  // Rotate right
138   max_shift = 4
139 };
140 
141 
142 // Special Software Interrupt codes when used in the presence of the ARM
143 // simulator.
144 enum SoftwareInterruptCodes {
145   // transition to C code
146   call_rt_redirected = 0x10,
147   // break point
148   break_point = 0x20
149 };
150 
151 
152 typedef int32_t instr_t;
153 
154 
155 // The class Instr enables access to individual fields defined in the ARM
156 // architecture instruction set encoding as described in figure A3-1.
157 //
158 // Example: Test whether the instruction at ptr does set the condition code
159 // bits.
160 //
161 // bool InstructionSetsConditionCodes(byte* ptr) {
162 //   Instr* instr = Instr::At(ptr);
163 //   int type = instr->TypeField();
164 //   return ((type == 0) || (type == 1)) && instr->HasS();
165 // }
166 //
167 class Instr {
168  public:
169   enum {
170     kInstrSize = 4,
171     kInstrSizeLog2 = 2,
172     kPCReadOffset = 8
173   };
174 
175   // Get the raw instruction bits.
InstructionBits()176   inline instr_t InstructionBits() const {
177     return *reinterpret_cast<const instr_t*>(this);
178   }
179 
180   // Set the raw instruction bits to value.
SetInstructionBits(instr_t value)181   inline void SetInstructionBits(instr_t value) {
182     *reinterpret_cast<instr_t*>(this) = value;
183   }
184 
185   // Read one particular bit out of the instruction bits.
Bit(int nr)186   inline int Bit(int nr) const {
187     return (InstructionBits() >> nr) & 1;
188   }
189 
190   // Read a bit field out of the instruction bits.
Bits(int hi,int lo)191   inline int Bits(int hi, int lo) const {
192     return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
193   }
194 
195 
196   // Accessors for the different named fields used in the ARM encoding.
197   // The naming of these accessor corresponds to figure A3-1.
198   // Generally applicable fields
ConditionField()199   inline Condition ConditionField() const {
200     return static_cast<Condition>(Bits(31, 28));
201   }
TypeField()202   inline int TypeField() const { return Bits(27, 25); }
203 
RnField()204   inline int RnField() const { return Bits(19, 16); }
RdField()205   inline int RdField() const { return Bits(15, 12); }
206 
207   // Fields used in Data processing instructions
OpcodeField()208   inline Opcode OpcodeField() const {
209     return static_cast<Opcode>(Bits(24, 21));
210   }
SField()211   inline int SField() const { return Bit(20); }
212     // with register
RmField()213   inline int RmField() const { return Bits(3, 0); }
ShiftField()214   inline Shift ShiftField() const { return static_cast<Shift>(Bits(6, 5)); }
RegShiftField()215   inline int RegShiftField() const { return Bit(4); }
RsField()216   inline int RsField() const { return Bits(11, 8); }
ShiftAmountField()217   inline int ShiftAmountField() const { return Bits(11, 7); }
218     // with immediate
RotateField()219   inline int RotateField() const { return Bits(11, 8); }
Immed8Field()220   inline int Immed8Field() const { return Bits(7, 0); }
221 
222   // Fields used in Load/Store instructions
PUField()223   inline int PUField() const { return Bits(24, 23); }
BField()224   inline int  BField() const { return Bit(22); }
WField()225   inline int  WField() const { return Bit(21); }
LField()226   inline int  LField() const { return Bit(20); }
227     // with register uses same fields as Data processing instructions above
228     // with immediate
Offset12Field()229   inline int Offset12Field() const { return Bits(11, 0); }
230     // multiple
RlistField()231   inline int RlistField() const { return Bits(15, 0); }
232     // extra loads and stores
SignField()233   inline int SignField() const { return Bit(6); }
HField()234   inline int HField() const { return Bit(5); }
ImmedHField()235   inline int ImmedHField() const { return Bits(11, 8); }
ImmedLField()236   inline int ImmedLField() const { return Bits(3, 0); }
237 
238   // Fields used in Branch instructions
LinkField()239   inline int LinkField() const { return Bit(24); }
SImmed24Field()240   inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
241 
242   // Fields used in Software interrupt instructions
SwiField()243   inline SoftwareInterruptCodes SwiField() const {
244     return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
245   }
246 
247   // Test for special encodings of type 0 instructions (extra loads and stores,
248   // as well as multiplications).
IsSpecialType0()249   inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); }
250 
251   // Special accessors that test for existence of a value.
HasS()252   inline bool HasS()    const { return SField() == 1; }
HasB()253   inline bool HasB()    const { return BField() == 1; }
HasW()254   inline bool HasW()    const { return WField() == 1; }
HasL()255   inline bool HasL()    const { return LField() == 1; }
HasSign()256   inline bool HasSign() const { return SignField() == 1; }
HasH()257   inline bool HasH()    const { return HField() == 1; }
HasLink()258   inline bool HasLink() const { return LinkField() == 1; }
259 
260   // Instructions are read of out a code stream. The only way to get a
261   // reference to an instruction is to convert a pointer. There is no way
262   // to allocate or create instances of class Instr.
263   // Use the At(pc) function to create references to Instr.
At(byte * pc)264   static Instr* At(byte* pc) { return reinterpret_cast<Instr*>(pc); }
265 
266  private:
267   // We need to prevent the creation of instances of class Instr.
268   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
269 };
270 
271 
272 } }  // namespace assembler::arm
273 
274 #endif  // V8_ARM_CONSTANTS_ARM_H_
275