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