constants-arm.h revision 7f4d5bd8c03935e2c0cd412e561b8fc5a6a880ae
1// Copyright 2010 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 27 28#ifndef V8_ARM_CONSTANTS_ARM_H_ 29#define V8_ARM_CONSTANTS_ARM_H_ 30 31// 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 33// old ABI uses fp registers in the calling convention and the simulator does 34// not simulate fp registers or coroutine instructions. 35#if defined(__ARM_EABI__) || !defined(__arm__) 36# define USE_ARM_EABI 1 37#endif 38 39// 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 41// be used on real hardware. 42#if defined(__THUMB_INTERWORK__) || !defined(__arm__) 43# define USE_THUMB_INTERWORK 1 44#endif 45 46#if defined(__ARM_ARCH_7A__) || \ 47 defined(__ARM_ARCH_7R__) || \ 48 defined(__ARM_ARCH_7__) 49# define CAN_USE_ARMV7_INSTRUCTIONS 1 50#endif 51 52#if defined(__ARM_ARCH_6__) || \ 53 defined(__ARM_ARCH_6J__) || \ 54 defined(__ARM_ARCH_6K__) || \ 55 defined(__ARM_ARCH_6Z__) || \ 56 defined(__ARM_ARCH_6ZK__) || \ 57 defined(__ARM_ARCH_6T2__) || \ 58 defined(CAN_USE_ARMV7_INSTRUCTIONS) 59# define CAN_USE_ARMV6_INSTRUCTIONS 1 60#endif 61 62#if defined(__ARM_ARCH_5T__) || \ 63 defined(__ARM_ARCH_5TE__) || \ 64 defined(CAN_USE_ARMV6_INSTRUCTIONS) 65# define CAN_USE_ARMV5_INSTRUCTIONS 1 66# define CAN_USE_THUMB_INSTRUCTIONS 1 67#endif 68 69// Simulator should support ARM5 instructions and unaligned access by default. 70#if !defined(__arm__) 71# define CAN_USE_ARMV5_INSTRUCTIONS 1 72# define CAN_USE_THUMB_INSTRUCTIONS 1 73 74# ifndef CAN_USE_UNALIGNED_ACCESSES 75# define CAN_USE_UNALIGNED_ACCESSES 1 76# endif 77 78#endif 79 80#if CAN_USE_UNALIGNED_ACCESSES 81#define V8_TARGET_CAN_READ_UNALIGNED 1 82#endif 83 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) 86#define USE_BLX 1 87#endif 88 89namespace assembler { 90namespace arm { 91 92// Number of registers in normal ARM mode. 93static const int kNumRegisters = 16; 94 95// VFP support. 96static const int kNumVFPSingleRegisters = 32; 97static const int kNumVFPDoubleRegisters = 16; 98static const int kNumVFPRegisters = 99 kNumVFPSingleRegisters + kNumVFPDoubleRegisters; 100 101// PC is register 15. 102static const int kPCRegister = 15; 103static const int kNoRegister = -1; 104 105// Defines constants and accessor classes to assemble, disassemble and 106// simulate ARM instructions. 107// 108// 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) 110// 111// Constants for specific fields are defined in their respective named enums. 112// General constants are in an anonymous enum in class Instr. 113 114typedef unsigned char byte; 115 116// Values for the condition field as defined in section A3.2 117enum Condition { 118 no_condition = -1, 119 EQ = 0, // equal 120 NE = 1, // not equal 121 CS = 2, // carry set/unsigned higher or same 122 CC = 3, // carry clear/unsigned lower 123 MI = 4, // minus/negative 124 PL = 5, // plus/positive or zero 125 VS = 6, // overflow 126 VC = 7, // no overflow 127 HI = 8, // unsigned higher 128 LS = 9, // unsigned lower or same 129 GE = 10, // signed greater than or equal 130 LT = 11, // signed less than 131 GT = 12, // signed greater than 132 LE = 13, // signed less than or equal 133 AL = 14, // always (unconditional) 134 special_condition = 15, // special condition (refer to section A3.2.1) 135 max_condition = 16 136}; 137 138 139// Opcodes for Data-processing instructions (instructions with a type 0 and 1) 140// as defined in section A3.4 141enum Opcode { 142 no_operand = -1, 143 AND = 0, // Logical AND 144 EOR = 1, // Logical Exclusive OR 145 SUB = 2, // Subtract 146 RSB = 3, // Reverse Subtract 147 ADD = 4, // Add 148 ADC = 5, // Add with Carry 149 SBC = 6, // Subtract with Carry 150 RSC = 7, // Reverse Subtract with Carry 151 TST = 8, // Test 152 TEQ = 9, // Test Equivalence 153 CMP = 10, // Compare 154 CMN = 11, // Compare Negated 155 ORR = 12, // Logical (inclusive) OR 156 MOV = 13, // Move 157 BIC = 14, // Bit Clear 158 MVN = 15, // Move Not 159 max_operand = 16 160}; 161 162 163// The bits for bit 7-4 for some type 0 miscellaneous instructions. 164enum MiscInstructionsBits74 { 165 // With bits 22-21 01. 166 BX = 1, 167 BXJ = 2, 168 BLX = 3, 169 BKPT = 7, 170 171 // With bits 22-21 11. 172 CLZ = 1 173}; 174 175 176// Shifter types for Data-processing operands as defined in section A5.1.2. 177enum Shift { 178 no_shift = -1, 179 LSL = 0, // Logical shift left 180 LSR = 1, // Logical shift right 181 ASR = 2, // Arithmetic shift right 182 ROR = 3, // Rotate right 183 max_shift = 4 184}; 185 186 187// Special Software Interrupt codes when used in the presence of the ARM 188// simulator. 189enum SoftwareInterruptCodes { 190 // transition to C code 191 call_rt_redirected = 0x10, 192 // break point 193 break_point = 0x20 194}; 195 196 197typedef int32_t instr_t; 198 199 200// The class Instr enables access to individual fields defined in the ARM 201// architecture instruction set encoding as described in figure A3-1. 202// 203// Example: Test whether the instruction at ptr does set the condition code 204// bits. 205// 206// bool InstructionSetsConditionCodes(byte* ptr) { 207// Instr* instr = Instr::At(ptr); 208// int type = instr->TypeField(); 209// return ((type == 0) || (type == 1)) && instr->HasS(); 210// } 211// 212class Instr { 213 public: 214 enum { 215 kInstrSize = 4, 216 kInstrSizeLog2 = 2, 217 kPCReadOffset = 8 218 }; 219 220 // Get the raw instruction bits. 221 inline instr_t InstructionBits() const { 222 return *reinterpret_cast<const instr_t*>(this); 223 } 224 225 // Set the raw instruction bits to value. 226 inline void SetInstructionBits(instr_t value) { 227 *reinterpret_cast<instr_t*>(this) = value; 228 } 229 230 // Read one particular bit out of the instruction bits. 231 inline int Bit(int nr) const { 232 return (InstructionBits() >> nr) & 1; 233 } 234 235 // Read a bit field out of the instruction bits. 236 inline int Bits(int hi, int lo) const { 237 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1); 238 } 239 240 241 // Accessors for the different named fields used in the ARM encoding. 242 // The naming of these accessor corresponds to figure A3-1. 243 // Generally applicable fields 244 inline Condition ConditionField() const { 245 return static_cast<Condition>(Bits(31, 28)); 246 } 247 inline int TypeField() const { return Bits(27, 25); } 248 249 inline int RnField() const { return Bits(19, 16); } 250 inline int RdField() const { return Bits(15, 12); } 251 252 inline int CoprocessorField() const { return Bits(11, 8); } 253 // Support for VFP. 254 // Vn(19-16) | Vd(15-12) | Vm(3-0) 255 inline int VnField() const { return Bits(19, 16); } 256 inline int VmField() const { return Bits(3, 0); } 257 inline int VdField() const { return Bits(15, 12); } 258 inline int NField() const { return Bit(7); } 259 inline int MField() const { return Bit(5); } 260 inline int DField() const { return Bit(22); } 261 inline int RtField() const { return Bits(15, 12); } 262 inline int PField() const { return Bit(24); } 263 inline int UField() const { return Bit(23); } 264 inline int Opc1Field() const { return (Bit(23) << 2) | Bits(21, 20); } 265 inline int Opc2Field() const { return Bits(19, 16); } 266 inline int Opc3Field() const { return Bits(7, 6); } 267 inline int SzField() const { return Bit(8); } 268 inline int VLField() const { return Bit(20); } 269 inline int VCField() const { return Bit(8); } 270 inline int VAField() const { return Bits(23, 21); } 271 inline int VBField() const { return Bits(6, 5); } 272 273 // Fields used in Data processing instructions 274 inline Opcode OpcodeField() const { 275 return static_cast<Opcode>(Bits(24, 21)); 276 } 277 inline int SField() const { return Bit(20); } 278 // with register 279 inline int RmField() const { return Bits(3, 0); } 280 inline Shift ShiftField() const { return static_cast<Shift>(Bits(6, 5)); } 281 inline int RegShiftField() const { return Bit(4); } 282 inline int RsField() const { return Bits(11, 8); } 283 inline int ShiftAmountField() const { return Bits(11, 7); } 284 // with immediate 285 inline int RotateField() const { return Bits(11, 8); } 286 inline int Immed8Field() const { return Bits(7, 0); } 287 288 // Fields used in Load/Store instructions 289 inline int PUField() const { return Bits(24, 23); } 290 inline int BField() const { return Bit(22); } 291 inline int WField() const { return Bit(21); } 292 inline int LField() const { return Bit(20); } 293 // with register uses same fields as Data processing instructions above 294 // with immediate 295 inline int Offset12Field() const { return Bits(11, 0); } 296 // multiple 297 inline int RlistField() const { return Bits(15, 0); } 298 // extra loads and stores 299 inline int SignField() const { return Bit(6); } 300 inline int HField() const { return Bit(5); } 301 inline int ImmedHField() const { return Bits(11, 8); } 302 inline int ImmedLField() const { return Bits(3, 0); } 303 304 // Fields used in Branch instructions 305 inline int LinkField() const { return Bit(24); } 306 inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); } 307 308 // Fields used in Software interrupt instructions 309 inline SoftwareInterruptCodes SwiField() const { 310 return static_cast<SoftwareInterruptCodes>(Bits(23, 0)); 311 } 312 313 // Test for special encodings of type 0 instructions (extra loads and stores, 314 // as well as multiplications). 315 inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); } 316 317 // Test for miscellaneous instructions encodings of type 0 instructions. 318 inline bool IsMiscType0() const { return (Bit(24) == 1) 319 && (Bit(23) == 0) 320 && (Bit(20) == 0) 321 && ((Bit(7) == 0)); } 322 323 // Special accessors that test for existence of a value. 324 inline bool HasS() const { return SField() == 1; } 325 inline bool HasB() const { return BField() == 1; } 326 inline bool HasW() const { return WField() == 1; } 327 inline bool HasL() const { return LField() == 1; } 328 inline bool HasU() const { return UField() == 1; } 329 inline bool HasSign() const { return SignField() == 1; } 330 inline bool HasH() const { return HField() == 1; } 331 inline bool HasLink() const { return LinkField() == 1; } 332 333 // Instructions are read of out a code stream. The only way to get a 334 // reference to an instruction is to convert a pointer. There is no way 335 // to allocate or create instances of class Instr. 336 // Use the At(pc) function to create references to Instr. 337 static Instr* At(byte* pc) { return reinterpret_cast<Instr*>(pc); } 338 339 private: 340 // We need to prevent the creation of instances of class Instr. 341 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); 342}; 343 344 345// Helper functions for converting between register numbers and names. 346class Registers { 347 public: 348 // Return the name of the register. 349 static const char* Name(int reg); 350 351 // Lookup the register number for the name provided. 352 static int Number(const char* name); 353 354 struct RegisterAlias { 355 int reg; 356 const char* name; 357 }; 358 359 private: 360 static const char* names_[kNumRegisters]; 361 static const RegisterAlias aliases_[]; 362}; 363 364// Helper functions for converting between VFP register numbers and names. 365class VFPRegisters { 366 public: 367 // Return the name of the register. 368 static const char* Name(int reg, bool is_double); 369 370 // Lookup the register number for the name provided. 371 // Set flag pointed by is_double to true if register 372 // is double-precision. 373 static int Number(const char* name, bool* is_double); 374 375 private: 376 static const char* names_[kNumVFPRegisters]; 377}; 378 379 380} } // namespace assembler::arm 381 382#endif // V8_ARM_CONSTANTS_ARM_H_ 383