OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 10 matching lines...) Expand all Loading... | |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #ifndef V8_ARM_CONSTANTS_ARM_H_ | 28 #ifndef V8_ARM_CONSTANTS_ARM_H_ |
29 #define V8_ARM_CONSTANTS_ARM_H_ | 29 #define V8_ARM_CONSTANTS_ARM_H_ |
30 | 30 |
31 // Include globals.h to import the byte typedef and thus avoid to redeclare | |
32 // another similar type. | |
33 #include "globals.h" | |
34 using v8::internal::byte; | |
35 | |
31 // The simulator emulates the EABI so we define the USE_ARM_EABI macro if we | 36 // 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 | 37 // 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 | 38 // old ABI uses fp registers in the calling convention and the simulator does |
34 // not simulate fp registers or coroutine instructions. | 39 // not simulate fp registers or coroutine instructions. |
35 #if defined(__ARM_EABI__) || !defined(__arm__) | 40 #if defined(__ARM_EABI__) || !defined(__arm__) |
36 # define USE_ARM_EABI 1 | 41 # define USE_ARM_EABI 1 |
37 #endif | 42 #endif |
38 | 43 |
39 // This means that interwork-compatible jump instructions are generated. We | 44 // 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 | 45 // want to generate them on the simulator too so it makes snapshots that can |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
79 | 84 |
80 #if CAN_USE_UNALIGNED_ACCESSES | 85 #if CAN_USE_UNALIGNED_ACCESSES |
81 #define V8_TARGET_CAN_READ_UNALIGNED 1 | 86 #define V8_TARGET_CAN_READ_UNALIGNED 1 |
82 #endif | 87 #endif |
83 | 88 |
84 // Using blx may yield better code, so use it when required or when available | 89 // Using blx may yield better code, so use it when required or when available |
85 #if defined(USE_THUMB_INTERWORK) || defined(CAN_USE_ARMV5_INSTRUCTIONS) | 90 #if defined(USE_THUMB_INTERWORK) || defined(CAN_USE_ARMV5_INSTRUCTIONS) |
86 #define USE_BLX 1 | 91 #define USE_BLX 1 |
87 #endif | 92 #endif |
88 | 93 |
89 namespace assembler { | 94 namespace assembler { |
Mads Ager (chromium)
2011/01/20 14:02:14
No that we are sharing all of this why don't we us
Alexandre
2011/01/21 16:22:15
Done!
This is much more convenient.
On 2011/01/20
| |
90 namespace arm { | 95 namespace arm { |
91 | 96 |
92 // Number of registers in normal ARM mode. | 97 // Number of registers in normal ARM mode. |
93 static const int kNumRegisters = 16; | 98 static const int kNumRegisters = 16; |
94 | 99 |
95 // VFP support. | 100 // VFP support. |
96 static const int kNumVFPSingleRegisters = 32; | 101 static const int kNumVFPSingleRegisters = 32; |
97 static const int kNumVFPDoubleRegisters = 16; | 102 static const int kNumVFPDoubleRegisters = 16; |
98 static const int kNumVFPRegisters = | 103 static const int kNumVFPRegisters = |
99 kNumVFPSingleRegisters + kNumVFPDoubleRegisters; | 104 kNumVFPSingleRegisters + kNumVFPDoubleRegisters; |
100 | 105 |
101 // PC is register 15. | 106 // PC is register 15. |
102 static const int kPCRegister = 15; | 107 static const int kPCRegister = 15; |
103 static const int kNoRegister = -1; | 108 static const int kNoRegister = -1; |
104 | 109 |
110 // ----------------------------------------------------------------------------- | |
111 // Conditions. | |
112 | |
105 // Defines constants and accessor classes to assemble, disassemble and | 113 // Defines constants and accessor classes to assemble, disassemble and |
106 // simulate ARM instructions. | 114 // simulate ARM instructions. |
107 // | 115 // |
108 // Section references in the code refer to the "ARM Architecture Reference | 116 // Section references in the code refer to the "ARM Architecture Reference |
109 // Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf) | 117 // Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf) |
110 // | 118 // |
111 // Constants for specific fields are defined in their respective named enums. | 119 // Constants for specific fields are defined in their respective named enums. |
112 // General constants are in an anonymous enum in class Instr. | 120 // General constants are in an anonymous enum in class Instr. |
113 | 121 |
114 typedef unsigned char byte; | |
115 | |
116 // Values for the condition field as defined in section A3.2 | 122 // Values for the condition field as defined in section A3.2 |
117 enum Condition { | 123 enum Condition { |
118 no_condition = -1, | 124 no_condition = -1, |
119 EQ = 0, // equal | 125 |
120 NE = 1, // not equal | 126 eq = 0 << 28, // Z set Equal. |
121 CS = 2, // carry set/unsigned higher or same | 127 ne = 1 << 28, // Z clear Not equal. |
122 CC = 3, // carry clear/unsigned lower | 128 cs = 2 << 28, // C set Unsigned higher or same. |
123 MI = 4, // minus/negative | 129 cc = 3 << 28, // C clear Unsigned lower. |
124 PL = 5, // plus/positive or zero | 130 mi = 4 << 28, // N set Negative. |
125 VS = 6, // overflow | 131 pl = 5 << 28, // N clear Positive or zero. |
126 VC = 7, // no overflow | 132 vs = 6 << 28, // V set Overflow. |
127 HI = 8, // unsigned higher | 133 vc = 7 << 28, // V clear No overflow. |
128 LS = 9, // unsigned lower or same | 134 hi = 8 << 28, // C set, Z clear Unsigned higher. |
129 GE = 10, // signed greater than or equal | 135 ls = 9 << 28, // C clear or Z set Unsigned lower or same. |
130 LT = 11, // signed less than | 136 ge = 10 << 28, // N == V Greater or equal. |
131 GT = 12, // signed greater than | 137 lt = 11 << 28, // N != V Less than. |
132 LE = 13, // signed less than or equal | 138 gt = 12 << 28, // Z clear, N == V Greater than. |
133 AL = 14, // always (unconditional) | 139 le = 13 << 28, // Z set or N != V Less then or equal |
134 special_condition = 15, // special condition (refer to section A3.2.1) | 140 al = 14 << 28, // Always. |
135 max_condition = 16 | 141 |
136 }; | 142 special_condition = 15 << 28, // Special condition (refer to section A3.2.1). |
143 number_of_conditions = 16, | |
144 | |
145 // Aliases. | |
146 hs = cs, // C set Unsigned higher or same. | |
147 lo = cc // C clear Unsigned lower. | |
148 }; | |
149 | |
150 | |
151 inline Condition NegateCondition(Condition cond) { | |
152 ASSERT(cond != al); | |
153 return static_cast<Condition>(cond ^ ne); | |
154 } | |
155 | |
156 | |
157 // Corresponds to transposing the operands of a comparison. | |
158 inline Condition ReverseCondition(Condition cond) { | |
159 switch (cond) { | |
160 case lo: | |
161 return hi; | |
162 case hi: | |
163 return lo; | |
164 case hs: | |
165 return ls; | |
166 case ls: | |
167 return hs; | |
168 case lt: | |
169 return gt; | |
170 case gt: | |
171 return lt; | |
172 case ge: | |
173 return le; | |
174 case le: | |
175 return ge; | |
176 default: | |
177 return cond; | |
178 }; | |
179 } | |
180 | |
181 | |
182 // ----------------------------------------------------------------------------- | |
183 // Instructions encoding. | |
184 | |
185 // Instr is merely used by the Assembler to distinguish 32bit integers | |
186 // representing instructions from usual 32 bit values. | |
187 // Instruction objects are pointers to 32bit values, and provide methods to | |
188 // access the various ISA fields. | |
189 typedef int32_t Instr; | |
137 | 190 |
138 | 191 |
139 // Opcodes for Data-processing instructions (instructions with a type 0 and 1) | 192 // Opcodes for Data-processing instructions (instructions with a type 0 and 1) |
140 // as defined in section A3.4 | 193 // as defined in section A3.4 |
141 enum Opcode { | 194 enum Opcode { |
142 no_operand = -1, | 195 AND = 0 << 21, // Logical AND. |
143 AND = 0, // Logical AND | 196 EOR = 1 << 21, // Logical Exclusive OR. |
144 EOR = 1, // Logical Exclusive OR | 197 SUB = 2 << 21, // Subtract. |
145 SUB = 2, // Subtract | 198 RSB = 3 << 21, // Reverse Subtract. |
146 RSB = 3, // Reverse Subtract | 199 ADD = 4 << 21, // Add. |
147 ADD = 4, // Add | 200 ADC = 5 << 21, // Add with Carry. |
148 ADC = 5, // Add with Carry | 201 SBC = 6 << 21, // Subtract with Carry. |
149 SBC = 6, // Subtract with Carry | 202 RSC = 7 << 21, // Reverse Subtract with Carry. |
150 RSC = 7, // Reverse Subtract with Carry | 203 TST = 8 << 21, // Test. |
151 TST = 8, // Test | 204 TEQ = 9 << 21, // Test Equivalence. |
152 TEQ = 9, // Test Equivalence | 205 CMP = 10 << 21, // Compare. |
153 CMP = 10, // Compare | 206 CMN = 11 << 21, // Compare Negated. |
154 CMN = 11, // Compare Negated | 207 ORR = 12 << 21, // Logical (inclusive) OR. |
155 ORR = 12, // Logical (inclusive) OR | 208 MOV = 13 << 21, // Move. |
156 MOV = 13, // Move | 209 BIC = 14 << 21, // Bit Clear. |
157 BIC = 14, // Bit Clear | 210 MVN = 15 << 21 // Move Not. |
158 MVN = 15, // Move Not | |
159 max_operand = 16 | |
160 }; | 211 }; |
161 | 212 |
162 | 213 |
163 // The bits for bit 7-4 for some type 0 miscellaneous instructions. | 214 // The bits for bit 7-4 for some type 0 miscellaneous instructions. |
164 enum MiscInstructionsBits74 { | 215 enum MiscInstructionsBits74 { |
165 // With bits 22-21 01. | 216 // With bits 22-21 01. |
166 BX = 1, | 217 BX = 1 << 4, |
167 BXJ = 2, | 218 BXJ = 2 << 4, |
168 BLX = 3, | 219 BLX = 3 << 4, |
169 BKPT = 7, | 220 BKPT = 7 << 4, |
170 | 221 |
171 // With bits 22-21 11. | 222 // With bits 22-21 11. |
172 CLZ = 1 | 223 CLZ = 1 << 4 |
224 }; | |
225 | |
226 | |
227 // Instruction encoding bits and masks. | |
228 enum { | |
229 H = 1 << 5, // Halfword (or byte). | |
230 S6 = 1 << 6, // Signed (or unsigned). | |
231 L = 1 << 20, // Load (or store). | |
232 S = 1 << 20, // Set condition code (or leave unchanged). | |
233 W = 1 << 21, // Writeback base register (or leave unchanged). | |
234 A = 1 << 21, // Accumulate in multiply instruction (or not). | |
235 B = 1 << 22, // Unsigned byte (or word). | |
236 N = 1 << 22, // Long (or short). | |
237 U = 1 << 23, // Positive (or negative) offset/index. | |
238 P = 1 << 24, // Offset/pre-indexed addressing (or post-indexed addressing). | |
239 I = 1 << 25, // Immediate shifter operand (or not). | |
240 | |
241 B4 = 1 << 4, | |
242 B5 = 1 << 5, | |
243 B6 = 1 << 6, | |
244 B7 = 1 << 7, | |
245 B8 = 1 << 8, | |
246 B9 = 1 << 9, | |
247 B12 = 1 << 12, | |
248 B16 = 1 << 16, | |
249 B18 = 1 << 18, | |
250 B19 = 1 << 19, | |
251 B20 = 1 << 20, | |
252 B21 = 1 << 21, | |
253 B22 = 1 << 22, | |
254 B23 = 1 << 23, | |
255 B24 = 1 << 24, | |
256 B25 = 1 << 25, | |
257 B26 = 1 << 26, | |
258 B27 = 1 << 27, | |
259 B28 = 1 << 28, | |
260 | |
261 // Instruction bit masks. | |
262 CondMask = 15 << 28, | |
263 ALUMask = 0x6f << 21, | |
264 RdMask = 15 << 12, // In str instruction. | |
265 CoprocessorMask = 15 << 8, | |
266 OpCodeMask = 15 << 21, // In data-processing instructions. | |
267 Imm24Mask = (1 << 24) - 1, | |
268 Off12Mask = (1 << 12) - 1 | |
269 }; | |
270 | |
271 | |
272 // ----------------------------------------------------------------------------- | |
273 // Addressing modes and instruction variants. | |
274 | |
275 // Condition code updating mode. | |
276 enum SBit { | |
277 SetCC = 1 << 20, // Set condition code. | |
278 LeaveCC = 0 << 20 // Leave condition code unchanged. | |
279 }; | |
280 | |
281 | |
282 // Status register selection. | |
283 enum SRegister { | |
284 CPSR = 0 << 22, | |
285 SPSR = 1 << 22 | |
173 }; | 286 }; |
174 | 287 |
175 | 288 |
176 // Shifter types for Data-processing operands as defined in section A5.1.2. | 289 // Shifter types for Data-processing operands as defined in section A5.1.2. |
177 enum Shift { | 290 enum ShiftOp { |
178 no_shift = -1, | 291 LSL = 0 << 5, // Logical shift left. |
179 LSL = 0, // Logical shift left | 292 LSR = 1 << 5, // Logical shift right. |
180 LSR = 1, // Logical shift right | 293 ASR = 2 << 5, // Arithmetic shift right. |
181 ASR = 2, // Arithmetic shift right | 294 ROR = 3 << 5, // Rotate right. |
182 ROR = 3, // Rotate right | 295 |
183 max_shift = 4 | 296 // RRX is encoded as ROR with shift_imm == 0. |
184 }; | 297 // Use a special code to make the distinction. The RRX ShiftOp is only used |
185 | 298 // as an argument, and will never actually be encoded. The Assembler will |
299 // detect it and emit the correct ROR shift operand with shift_imm == 0. | |
300 RRX = -1, | |
301 number_of_shifts = 4 | |
302 }; | |
303 | |
304 | |
305 // Status register fields. | |
306 enum SRegisterField { | |
307 CPSR_c = CPSR | 1 << 16, | |
308 CPSR_x = CPSR | 1 << 17, | |
309 CPSR_s = CPSR | 1 << 18, | |
310 CPSR_f = CPSR | 1 << 19, | |
311 SPSR_c = SPSR | 1 << 16, | |
312 SPSR_x = SPSR | 1 << 17, | |
313 SPSR_s = SPSR | 1 << 18, | |
314 SPSR_f = SPSR | 1 << 19 | |
315 }; | |
316 | |
317 // Status register field mask (or'ed SRegisterField enum values). | |
318 typedef uint32_t SRegisterFieldMask; | |
319 | |
320 | |
321 // Memory operand addressing mode. | |
322 enum AddrMode { | |
323 // Bit encoding P U W. | |
324 Offset = (8|4|0) << 21, // Offset (without writeback to base). | |
325 PreIndex = (8|4|1) << 21, // Pre-indexed addressing with writeback. | |
326 PostIndex = (0|4|0) << 21, // Post-indexed addressing with writeback. | |
327 NegOffset = (8|0|0) << 21, // Negative offset (without writeback to base). | |
328 NegPreIndex = (8|0|1) << 21, // Negative pre-indexed with writeback. | |
329 NegPostIndex = (0|0|0) << 21 // Negative post-indexed with writeback. | |
330 }; | |
331 | |
332 | |
333 // Load/store multiple addressing mode. | |
334 enum BlockAddrMode { | |
335 // Bit encoding P U W . | |
336 da = (0|0|0) << 21, // Decrement after. | |
337 ia = (0|4|0) << 21, // Increment after. | |
338 db = (8|0|0) << 21, // Decrement before. | |
339 ib = (8|4|0) << 21, // Increment before. | |
340 da_w = (0|0|1) << 21, // Decrement after with writeback to base. | |
341 ia_w = (0|4|1) << 21, // Increment after with writeback to base. | |
342 db_w = (8|0|1) << 21, // Decrement before with writeback to base. | |
343 ib_w = (8|4|1) << 21, // Increment before with writeback to base. | |
344 | |
345 // Alias modes for comparison when writeback does not matter. | |
346 da_x = (0|0|0) << 21, // Decrement after. | |
347 ia_x = (0|4|0) << 21, // Increment after. | |
348 db_x = (8|0|0) << 21, // Decrement before. | |
349 ib_x = (8|4|0) << 21 // Increment before. | |
350 }; | |
351 | |
352 | |
353 // Coprocessor load/store operand size. | |
354 enum LFlag { | |
355 Long = 1 << 22, // Long load/store coprocessor. | |
356 Short = 0 << 22 // Short load/store coprocessor. | |
357 }; | |
358 | |
359 | |
360 // ----------------------------------------------------------------------------- | |
361 // Supervisor Call (svc) specific support. | |
186 | 362 |
187 // Special Software Interrupt codes when used in the presence of the ARM | 363 // Special Software Interrupt codes when used in the presence of the ARM |
188 // simulator. | 364 // simulator. |
189 // svc (formerly swi) provides a 24bit immediate value. Use bits 22:0 for | 365 // svc (formerly swi) provides a 24bit immediate value. Use bits 22:0 for |
190 // standard SoftwareInterrupCode. Bit 23 is reserved for the stop feature. | 366 // standard SoftwareInterrupCode. Bit 23 is reserved for the stop feature. |
191 enum SoftwareInterruptCodes { | 367 enum SoftwareInterruptCodes { |
192 // transition to C code | 368 // transition to C code |
193 call_rt_redirected = 0x10, | 369 call_rt_redirected = 0x10, |
194 // break point | 370 // break point |
195 break_point = 0x20, | 371 break_point = 0x20, |
196 // stop | 372 // stop |
197 stop = 1 << 23 | 373 stop_code = 1 << 23 |
198 }; | 374 }; |
199 static const int32_t kStopCodeMask = stop - 1; | 375 static const uint32_t kStopCodeMask = stop_code - 1; |
200 static const uint32_t kMaxStopCode = stop - 1; | 376 static const uint32_t kMaxStopCode = stop_code - 1; |
377 static const int32_t kDefaultStopCode = -1; | |
201 | 378 |
202 | 379 |
203 // Type of VFP register. Determines register encoding. | 380 // Type of VFP register. Determines register encoding. |
204 enum VFPRegPrecision { | 381 enum VFPRegPrecision { |
205 kSinglePrecision = 0, | 382 kSinglePrecision = 0, |
206 kDoublePrecision = 1 | 383 kDoublePrecision = 1 |
207 }; | 384 }; |
208 | 385 |
386 | |
387 // VFP FPSCR constants. | |
388 static const uint32_t kVFPExceptionMask = 0xf; | |
389 static const uint32_t kVFPRoundingModeMask = 3 << 22; | |
390 static const uint32_t kVFPFlushToZeroMask = 1 << 24; | |
391 static const uint32_t kVFPRoundToMinusInfinityBits = 2 << 22; | |
392 static const uint32_t kVFPInvalidExceptionBit = 1; | |
393 | |
394 static const uint32_t kVFPNConditionFlagBit = 1 << 31; | |
395 static const uint32_t kVFPZConditionFlagBit = 1 << 30; | |
396 static const uint32_t kVFPCConditionFlagBit = 1 << 29; | |
397 static const uint32_t kVFPVConditionFlagBit = 1 << 28; | |
398 | |
399 | |
209 // VFP rounding modes. See ARM DDI 0406B Page A2-29. | 400 // VFP rounding modes. See ARM DDI 0406B Page A2-29. |
210 enum FPSCRRoundingModes { | 401 enum FPSCRRoundingModes { |
211 RN, // Round to Nearest. | 402 RN, // Round to Nearest. |
212 RP, // Round towards Plus Infinity. | 403 RP, // Round towards Plus Infinity. |
213 RM, // Round towards Minus Infinity. | 404 RM, // Round towards Minus Infinity. |
214 RZ // Round towards zero. | 405 RZ // Round towards zero. |
215 }; | 406 }; |
216 | 407 |
217 typedef int32_t instr_t; | 408 |
409 // ----------------------------------------------------------------------------- | |
410 // Hints. | |
411 | |
412 // Branch hints are not used on the ARM. They are defined so that they can | |
413 // appear in shared function signatures, but will be ignored in ARM | |
414 // implementations. | |
415 enum Hint { no_hint }; | |
416 | |
417 // Hints are not used on the arm. Negating is trivial. | |
418 inline Hint NegateHint(Hint ignored) { return no_hint; } | |
218 | 419 |
219 | 420 |
220 // The class Instr enables access to individual fields defined in the ARM | 421 // ----------------------------------------------------------------------------- |
422 // Specific instructions, constants, and masks. | |
423 // These constants are declared in assembler-arm.cc, as they use named registers | |
424 // and other constants. | |
425 | |
426 | |
427 // add(sp, sp, 4) instruction (aka Pop()) | |
428 extern const Instr kPopInstruction; | |
429 | |
430 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r)) | |
431 // register r is not encoded. | |
432 extern const Instr kPushRegPattern; | |
433 | |
434 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r)) | |
435 // register r is not encoded. | |
436 extern const Instr kPopRegPattern; | |
437 | |
438 // mov lr, pc | |
439 extern const Instr kMovLrPc; | |
440 // ldr rd, [pc, #offset] | |
441 extern const Instr kLdrPCMask; | |
442 extern const Instr kLdrPCPattern; | |
443 // blxcc rm | |
444 extern const Instr kBlxRegMask; | |
445 | |
446 extern const Instr kBlxRegPattern; | |
447 | |
448 extern const Instr kMovMvnMask; | |
449 extern const Instr kMovMvnPattern; | |
450 extern const Instr kMovMvnFlip; | |
451 extern const Instr kMovLeaveCCMask; | |
452 extern const Instr kMovLeaveCCPattern; | |
453 extern const Instr kMovwMask; | |
454 extern const Instr kMovwPattern; | |
455 extern const Instr kMovwLeaveCCFlip; | |
456 extern const Instr kCmpCmnMask; | |
457 extern const Instr kCmpCmnPattern; | |
458 extern const Instr kCmpCmnFlip; | |
459 extern const Instr kAddSubFlip; | |
460 extern const Instr kAndBicFlip; | |
461 | |
462 // A mask for the Rd register for push, pop, ldr, str instructions. | |
463 extern const Instr kLdrRegFpOffsetPattern; | |
464 | |
465 extern const Instr kStrRegFpOffsetPattern; | |
466 | |
467 extern const Instr kLdrRegFpNegOffsetPattern; | |
468 | |
469 extern const Instr kStrRegFpNegOffsetPattern; | |
470 | |
471 extern const Instr kLdrStrInstrTypeMask; | |
472 extern const Instr kLdrStrInstrArgumentMask; | |
473 extern const Instr kLdrStrOffsetMask; | |
474 | |
475 | |
476 // ----------------------------------------------------------------------------- | |
477 // Instruction abstraction. | |
478 | |
479 // The class Instruction enables access to individual fields defined in the ARM | |
221 // architecture instruction set encoding as described in figure A3-1. | 480 // architecture instruction set encoding as described in figure A3-1. |
481 // Note that the Assembler uses typedef int32_t Instr. | |
222 // | 482 // |
223 // Example: Test whether the instruction at ptr does set the condition code | 483 // Example: Test whether the instruction at ptr does set the condition code |
224 // bits. | 484 // bits. |
225 // | 485 // |
226 // bool InstructionSetsConditionCodes(byte* ptr) { | 486 // bool InstructionSetsConditionCodes(byte* ptr) { |
227 // Instr* instr = Instr::At(ptr); | 487 // Instruction* instr = Instruction::At(ptr); |
228 // int type = instr->TypeField(); | 488 // int type = instr->TypeValue(); |
229 // return ((type == 0) || (type == 1)) && instr->HasS(); | 489 // return ((type == 0) || (type == 1)) && instr->HasS(); |
230 // } | 490 // } |
231 // | 491 // |
232 class Instr { | 492 class Instruction { |
233 public: | 493 public: |
234 enum { | 494 enum { |
235 kInstrSize = 4, | 495 kInstrSize = 4, |
236 kInstrSizeLog2 = 2, | 496 kInstrSizeLog2 = 2, |
237 kPCReadOffset = 8 | 497 kPCReadOffset = 8 |
238 }; | 498 }; |
239 | 499 |
500 // Helper macro to define static accessors. | |
501 // We use the cast to char* trick to bypass the strict anti-aliasing rules. | |
502 #define DECLARE_STATIC_TYPED_ACCESSOR(return_type, Name) \ | |
503 static inline return_type Name(Instr instr) { \ | |
504 char* temp = reinterpret_cast<char*>(&instr); \ | |
505 return reinterpret_cast<Instruction*>(temp)->Name(); \ | |
506 } | |
507 | |
508 #define DECLARE_STATIC_ACCESSOR(Name) DECLARE_STATIC_TYPED_ACCESSOR(int, Name) | |
509 | |
240 // Get the raw instruction bits. | 510 // Get the raw instruction bits. |
241 inline instr_t InstructionBits() const { | 511 inline Instr InstructionBits() const { |
242 return *reinterpret_cast<const instr_t*>(this); | 512 return *reinterpret_cast<const Instr*>(this); |
243 } | 513 } |
244 | 514 |
245 // Set the raw instruction bits to value. | 515 // Set the raw instruction bits to value. |
246 inline void SetInstructionBits(instr_t value) { | 516 inline void SetInstructionBits(Instr value) { |
247 *reinterpret_cast<instr_t*>(this) = value; | 517 *reinterpret_cast<Instr*>(this) = value; |
248 } | 518 } |
249 | 519 |
250 // Read one particular bit out of the instruction bits. | 520 // Read one particular bit out of the instruction bits. |
251 inline int Bit(int nr) const { | 521 inline int Bit(int nr) const { |
252 return (InstructionBits() >> nr) & 1; | 522 return (InstructionBits() >> nr) & 1; |
253 } | 523 } |
254 | 524 |
255 // Read a bit field out of the instruction bits. | 525 // Read a bit field's value out of the instruction bits. |
256 inline int Bits(int hi, int lo) const { | 526 inline int Bits(int hi, int lo) const { |
257 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1); | 527 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1); |
258 } | 528 } |
259 | 529 |
530 // Read a bit field out of the instruction bits. | |
531 inline int BitField(int hi, int lo) const { | |
532 return InstructionBits() & (((2 << (hi - lo)) - 1) << lo); | |
533 } | |
534 | |
535 // Static support. | |
536 | |
537 // Read one particular bit out of the instruction bits. | |
538 static inline int Bit(Instr instr, int nr) { | |
539 return (instr >> nr) & 1; | |
540 } | |
541 | |
542 // Read the value of a bit field out of the instruction bits. | |
543 static inline int Bits(Instr instr, int hi, int lo) { | |
544 return (instr >> lo) & ((2 << (hi - lo)) - 1); | |
545 } | |
546 | |
547 | |
548 // Read a bit field out of the instruction bits. | |
549 static inline int BitField(Instr instr, int hi, int lo) { | |
550 return instr & (((2 << (hi - lo)) - 1) << lo); | |
551 } | |
552 | |
260 | 553 |
261 // Accessors for the different named fields used in the ARM encoding. | 554 // Accessors for the different named fields used in the ARM encoding. |
262 // The naming of these accessor corresponds to figure A3-1. | 555 // The naming of these accessor corresponds to figure A3-1. |
556 // | |
557 // Two kind of accessors are declared: | |
558 // - <Name>Field() will return the raw field, ie the field's bits at their | |
559 // original place in the instruction encoding. | |
560 // eg. if instr is the 'addgt r0, r1, r2' instruction, encoded as 0xC0810002 | |
561 // ConditionField(instr) will return 0xC0000000. | |
562 // - <Name>Value() will return the field value, shifted back to bit 0. | |
563 // eg. if instr is the 'addgt r0, r1, r2' instruction, encoded as 0xC0810002 | |
564 // ConditionField(instr) will return 0xC. | |
565 | |
566 | |
263 // Generally applicable fields | 567 // Generally applicable fields |
264 inline Condition ConditionField() const { | 568 inline Condition ConditionValue() const { |
265 return static_cast<Condition>(Bits(31, 28)); | 569 return static_cast<Condition>(Bits(31, 28)); |
266 } | 570 } |
267 inline int TypeField() const { return Bits(27, 25); } | 571 inline Condition ConditionField() const { |
572 return static_cast<Condition>(BitField(31, 28)); | |
573 } | |
574 DECLARE_STATIC_TYPED_ACCESSOR(Condition, ConditionValue); | |
575 DECLARE_STATIC_TYPED_ACCESSOR(Condition, ConditionField); | |
268 | 576 |
269 inline int RnField() const { return Bits(19, 16); } | 577 inline int TypeValue() const { return Bits(27, 25); } |
270 inline int RdField() const { return Bits(15, 12); } | |
271 | 578 |
272 inline int CoprocessorField() const { return Bits(11, 8); } | 579 inline int RnValue() const { return Bits(19, 16); } |
580 inline int RdValue() const { return Bits(15, 12); } | |
581 DECLARE_STATIC_ACCESSOR(RdValue); | |
582 | |
583 inline int CoprocessorValue() const { return Bits(11, 8); } | |
273 // Support for VFP. | 584 // Support for VFP. |
274 // Vn(19-16) | Vd(15-12) | Vm(3-0) | 585 // Vn(19-16) | Vd(15-12) | Vm(3-0) |
275 inline int VnField() const { return Bits(19, 16); } | 586 inline int VnValue() const { return Bits(19, 16); } |
276 inline int VmField() const { return Bits(3, 0); } | 587 inline int VmValue() const { return Bits(3, 0); } |
277 inline int VdField() const { return Bits(15, 12); } | 588 inline int VdValue() const { return Bits(15, 12); } |
278 inline int NField() const { return Bit(7); } | 589 inline int NValue() const { return Bit(7); } |
279 inline int MField() const { return Bit(5); } | 590 inline int MValue() const { return Bit(5); } |
280 inline int DField() const { return Bit(22); } | 591 inline int DValue() const { return Bit(22); } |
281 inline int RtField() const { return Bits(15, 12); } | 592 inline int RtValue() const { return Bits(15, 12); } |
282 inline int PField() const { return Bit(24); } | 593 inline int PValue() const { return Bit(24); } |
283 inline int UField() const { return Bit(23); } | 594 inline int UValue() const { return Bit(23); } |
284 inline int Opc1Field() const { return (Bit(23) << 2) | Bits(21, 20); } | 595 inline int Opc1Value() const { return (Bit(23) << 2) | Bits(21, 20); } |
285 inline int Opc2Field() const { return Bits(19, 16); } | 596 inline int Opc2Value() const { return Bits(19, 16); } |
286 inline int Opc3Field() const { return Bits(7, 6); } | 597 inline int Opc3Value() const { return Bits(7, 6); } |
287 inline int SzField() const { return Bit(8); } | 598 inline int SzValue() const { return Bit(8); } |
288 inline int VLField() const { return Bit(20); } | 599 inline int VLValue() const { return Bit(20); } |
289 inline int VCField() const { return Bit(8); } | 600 inline int VCValue() const { return Bit(8); } |
290 inline int VAField() const { return Bits(23, 21); } | 601 inline int VAValue() const { return Bits(23, 21); } |
291 inline int VBField() const { return Bits(6, 5); } | 602 inline int VBValue() const { return Bits(6, 5); } |
292 inline int VFPNRegCode(VFPRegPrecision pre) { | 603 inline int VFPNRegValue(VFPRegPrecision pre) { |
293 return VFPGlueRegCode(pre, 16, 7); | 604 return VFPGlueRegValue(pre, 16, 7); |
294 } | 605 } |
295 inline int VFPMRegCode(VFPRegPrecision pre) { | 606 inline int VFPMRegValue(VFPRegPrecision pre) { |
296 return VFPGlueRegCode(pre, 0, 5); | 607 return VFPGlueRegValue(pre, 0, 5); |
297 } | 608 } |
298 inline int VFPDRegCode(VFPRegPrecision pre) { | 609 inline int VFPDRegValue(VFPRegPrecision pre) { |
299 return VFPGlueRegCode(pre, 12, 22); | 610 return VFPGlueRegValue(pre, 12, 22); |
300 } | 611 } |
301 | 612 |
302 // Fields used in Data processing instructions | 613 // Fields used in Data processing instructions |
303 inline Opcode OpcodeField() const { | 614 inline int OpcodeValue() const { |
304 return static_cast<Opcode>(Bits(24, 21)); | 615 return static_cast<Opcode>(Bits(24, 21)); |
305 } | 616 } |
306 inline int SField() const { return Bit(20); } | 617 inline Opcode OpcodeField() const { |
618 return static_cast<Opcode>(BitField(24, 21)); | |
619 } | |
620 inline int SValue() const { return Bit(20); } | |
307 // with register | 621 // with register |
308 inline int RmField() const { return Bits(3, 0); } | 622 inline int RmValue() const { return Bits(3, 0); } |
309 inline Shift ShiftField() const { return static_cast<Shift>(Bits(6, 5)); } | 623 inline int ShiftValue() const { return static_cast<ShiftOp>(Bits(6, 5)); } |
310 inline int RegShiftField() const { return Bit(4); } | 624 inline ShiftOp ShiftField() const { |
311 inline int RsField() const { return Bits(11, 8); } | 625 return static_cast<ShiftOp>(BitField(6, 5)); |
312 inline int ShiftAmountField() const { return Bits(11, 7); } | 626 } |
627 inline int RegShiftValue() const { return Bit(4); } | |
628 inline int RsValue() const { return Bits(11, 8); } | |
629 inline int ShiftAmountValue() const { return Bits(11, 7); } | |
313 // with immediate | 630 // with immediate |
314 inline int RotateField() const { return Bits(11, 8); } | 631 inline int RotateValue() const { return Bits(11, 8); } |
315 inline int Immed8Field() const { return Bits(7, 0); } | 632 inline int Immed8Value() const { return Bits(7, 0); } |
316 inline int Immed4Field() const { return Bits(19, 16); } | 633 inline int Immed4Value() const { return Bits(19, 16); } |
317 inline int ImmedMovwMovtField() const { | 634 inline int ImmedMovwMovtValue() const { |
318 return Immed4Field() << 12 | Offset12Field(); } | 635 return Immed4Value() << 12 | Offset12Value(); } |
319 | 636 |
320 // Fields used in Load/Store instructions | 637 // Fields used in Load/Store instructions |
321 inline int PUField() const { return Bits(24, 23); } | 638 inline int PUValue() const { return Bits(24, 23); } |
322 inline int BField() const { return Bit(22); } | 639 inline int PUField() const { return BitField(24, 23); } |
323 inline int WField() const { return Bit(21); } | 640 inline int BValue() const { return Bit(22); } |
324 inline int LField() const { return Bit(20); } | 641 inline int WValue() const { return Bit(21); } |
642 inline int LValue() const { return Bit(20); } | |
325 // with register uses same fields as Data processing instructions above | 643 // with register uses same fields as Data processing instructions above |
326 // with immediate | 644 // with immediate |
327 inline int Offset12Field() const { return Bits(11, 0); } | 645 inline int Offset12Value() const { return Bits(11, 0); } |
328 // multiple | 646 // multiple |
329 inline int RlistField() const { return Bits(15, 0); } | 647 inline int RlistValue() const { return Bits(15, 0); } |
330 // extra loads and stores | 648 // extra loads and stores |
331 inline int SignField() const { return Bit(6); } | 649 inline int SignValue() const { return Bit(6); } |
332 inline int HField() const { return Bit(5); } | 650 inline int HValue() const { return Bit(5); } |
333 inline int ImmedHField() const { return Bits(11, 8); } | 651 inline int ImmedHValue() const { return Bits(11, 8); } |
334 inline int ImmedLField() const { return Bits(3, 0); } | 652 inline int ImmedLValue() const { return Bits(3, 0); } |
335 | 653 |
336 // Fields used in Branch instructions | 654 // Fields used in Branch instructions |
337 inline int LinkField() const { return Bit(24); } | 655 inline int LinkValue() const { return Bit(24); } |
338 inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); } | 656 inline int SImmed24Value() const { return ((InstructionBits() << 8) >> 8); } |
339 | 657 |
340 // Fields used in Software interrupt instructions | 658 // Fields used in Software interrupt instructions |
341 inline SoftwareInterruptCodes SvcField() const { | 659 inline SoftwareInterruptCodes SvcValue() const { |
342 return static_cast<SoftwareInterruptCodes>(Bits(23, 0)); | 660 return static_cast<SoftwareInterruptCodes>(Bits(23, 0)); |
343 } | 661 } |
344 | 662 |
345 // Test for special encodings of type 0 instructions (extra loads and stores, | 663 // Test for special encodings of type 0 instructions (extra loads and stores, |
346 // as well as multiplications). | 664 // as well as multiplications). |
347 inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); } | 665 inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); } |
348 | 666 |
349 // Test for miscellaneous instructions encodings of type 0 instructions. | 667 // Test for miscellaneous instructions encodings of type 0 instructions. |
350 inline bool IsMiscType0() const { return (Bit(24) == 1) | 668 inline bool IsMiscType0() const { return (Bit(24) == 1) |
351 && (Bit(23) == 0) | 669 && (Bit(23) == 0) |
352 && (Bit(20) == 0) | 670 && (Bit(20) == 0) |
353 && ((Bit(7) == 0)); } | 671 && ((Bit(7) == 0)); } |
354 | 672 |
355 // Test for a stop instruction. | 673 // Test for a stop instruction. |
356 inline bool IsStop() const { | 674 inline bool IsStop() const { |
357 return (TypeField() == 7) && (Bit(24) == 1) && (SvcField() >= stop); | 675 return (TypeValue() == 7) && (Bit(24) == 1) && (SvcValue() >= stop_code); |
358 } | 676 } |
359 | 677 |
360 // Special accessors that test for existence of a value. | 678 // Special accessors that test for existence of a value. |
361 inline bool HasS() const { return SField() == 1; } | 679 inline bool HasS() const { return SValue() == 1; } |
362 inline bool HasB() const { return BField() == 1; } | 680 inline bool HasB() const { return BValue() == 1; } |
363 inline bool HasW() const { return WField() == 1; } | 681 inline bool HasW() const { return WValue() == 1; } |
364 inline bool HasL() const { return LField() == 1; } | 682 inline bool HasL() const { return LValue() == 1; } |
365 inline bool HasU() const { return UField() == 1; } | 683 inline bool HasU() const { return UValue() == 1; } |
366 inline bool HasSign() const { return SignField() == 1; } | 684 inline bool HasSign() const { return SignValue() == 1; } |
367 inline bool HasH() const { return HField() == 1; } | 685 inline bool HasH() const { return HValue() == 1; } |
368 inline bool HasLink() const { return LinkField() == 1; } | 686 inline bool HasLink() const { return LinkValue() == 1; } |
369 | 687 |
370 // Decoding the double immediate in the vmov instruction. | 688 // Decoding the double immediate in the vmov instruction. |
371 double DoubleImmedVmov() const; | 689 double DoubleImmedVmov() const; |
372 | 690 |
373 // Instructions are read of out a code stream. The only way to get a | 691 // Instructions are read of out a code stream. The only way to get a |
374 // reference to an instruction is to convert a pointer. There is no way | 692 // reference to an instruction is to convert a pointer. There is no way |
375 // to allocate or create instances of class Instr. | 693 // to allocate or create instances of class Instruction. |
376 // Use the At(pc) function to create references to Instr. | 694 // Use the At(pc) function to create references to Instruction. |
377 static Instr* At(byte* pc) { return reinterpret_cast<Instr*>(pc); } | 695 static Instruction* At(byte* pc) { |
696 return reinterpret_cast<Instruction*>(pc); | |
697 } | |
698 | |
378 | 699 |
379 private: | 700 private: |
380 // Join split register codes, depending on single or double precision. | 701 // Join split register codes, depending on single or double precision. |
381 // four_bit is the position of the least-significant bit of the four | 702 // four_bit is the position of the least-significant bit of the four |
382 // bit specifier. one_bit is the position of the additional single bit | 703 // bit specifier. one_bit is the position of the additional single bit |
383 // specifier. | 704 // specifier. |
384 inline int VFPGlueRegCode(VFPRegPrecision pre, int four_bit, int one_bit) { | 705 inline int VFPGlueRegValue(VFPRegPrecision pre, int four_bit, int one_bit) { |
385 if (pre == kSinglePrecision) { | 706 if (pre == kSinglePrecision) { |
386 return (Bits(four_bit + 3, four_bit) << 1) | Bit(one_bit); | 707 return (Bits(four_bit + 3, four_bit) << 1) | Bit(one_bit); |
387 } | 708 } |
388 return (Bit(one_bit) << 4) | Bits(four_bit + 3, four_bit); | 709 return (Bit(one_bit) << 4) | Bits(four_bit + 3, four_bit); |
389 } | 710 } |
390 | 711 |
391 // We need to prevent the creation of instances of class Instr. | 712 // We need to prevent the creation of instances of class Instruction. |
392 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); | 713 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); |
393 }; | 714 }; |
394 | 715 |
395 | 716 |
396 // Helper functions for converting between register numbers and names. | 717 // Helper functions for converting between register numbers and names. |
397 class Registers { | 718 class Registers { |
398 public: | 719 public: |
399 // Return the name of the register. | 720 // Return the name of the register. |
400 static const char* Name(int reg); | 721 static const char* Name(int reg); |
401 | 722 |
402 // Lookup the register number for the name provided. | 723 // Lookup the register number for the name provided. |
(...skipping 21 matching lines...) Expand all Loading... | |
424 static int Number(const char* name, bool* is_double); | 745 static int Number(const char* name, bool* is_double); |
425 | 746 |
426 private: | 747 private: |
427 static const char* names_[kNumVFPRegisters]; | 748 static const char* names_[kNumVFPRegisters]; |
428 }; | 749 }; |
429 | 750 |
430 | 751 |
431 } } // namespace assembler::arm | 752 } } // namespace assembler::arm |
432 | 753 |
433 #endif // V8_ARM_CONSTANTS_ARM_H_ | 754 #endif // V8_ARM_CONSTANTS_ARM_H_ |
OLD | NEW |