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 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 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 |