Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: src/arm/constants-arm.h

Issue 6274009: ARM: Merging constants in simulator and assembler header files and other clea... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 kNoCondition = -1,
119 EQ = 0, // equal 120
120 NE = 1, // not equal 121 eq = 0 << 28, // Z set Equal.
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 kSpecialCondition = 15 << 28, // Special condition (refer to section A3.2.1).
138 kNumberOfConditions = 16,
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.
257 kCondMask = 15 << 28,
258 kALUMask = 0x6f << 21,
259 kRdMask = 15 << 12, // In str instruction.
260 kCoprocessorMask = 15 << 8,
261 kOpCodeMask = 15 << 21, // In data-processing instructions.
262 kImm24Mask = (1 << 24) - 1,
263 kOff12Mask = (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 kNumberOfShifts = 4
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 kCallRtRedirected= 0x10,
194 // break point 365 // break point
195 break_point = 0x20, 366 kBreakpoint= 0x20,
196 // stop 367 // stop
197 stop = 1 << 23 368 kStopCode = 1 << 23
198 }; 369 };
199 static const int32_t kStopCodeMask = stop - 1; 370 static const uint32_t kStopCodeMask = kStopCode - 1;
200 static const uint32_t kMaxStopCode = stop - 1; 371 static const uint32_t kMaxStopCode = kStopCode - 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() >= kStopCode);
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698