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

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 10 matching lines...) Expand all
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698