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