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