constants-arm.h revision a7e24c173cf37484693b9abb38e494fa7bd7baeb
1// Copyright 2009 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_5T__) || \ 47 defined(__ARM_ARCH_5TE__) || \ 48 defined(__ARM_ARCH_6__) || \ 49 defined(__ARM_ARCH_7A__) || \ 50 defined(__ARM_ARCH_7__) 51# define CAN_USE_ARMV5_INSTRUCTIONS 1 52# define CAN_USE_THUMB_INSTRUCTIONS 1 53#endif 54 55#if defined(__ARM_ARCH_6__) || \ 56 defined(__ARM_ARCH_7A__) || \ 57 defined(__ARM_ARCH_7__) 58# define CAN_USE_ARMV6_INSTRUCTIONS 1 59#endif 60 61#if defined(__ARM_ARCH_7A__) || \ 62 defined(__ARM_ARCH_7__) 63# define CAN_USE_ARMV7_INSTRUCTIONS 1 64#endif 65 66// Simulator should support ARM5 instructions. 67#if !defined(__arm__) 68# define CAN_USE_ARMV5_INSTRUCTIONS 1 69# define CAN_USE_THUMB_INSTRUCTIONS 1 70#endif 71 72namespace assembler { 73namespace arm { 74 75// Number of registers in normal ARM mode. 76static const int kNumRegisters = 16; 77 78// PC is register 15. 79static const int kPCRegister = 15; 80static const int kNoRegister = -1; 81 82// Defines constants and accessor classes to assemble, disassemble and 83// simulate ARM instructions. 84// 85// Section references in the code refer to the "ARM Architecture Reference 86// Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf) 87// 88// Constants for specific fields are defined in their respective named enums. 89// General constants are in an anonymous enum in class Instr. 90 91typedef unsigned char byte; 92 93// Values for the condition field as defined in section A3.2 94enum Condition { 95 no_condition = -1, 96 EQ = 0, // equal 97 NE = 1, // not equal 98 CS = 2, // carry set/unsigned higher or same 99 CC = 3, // carry clear/unsigned lower 100 MI = 4, // minus/negative 101 PL = 5, // plus/positive or zero 102 VS = 6, // overflow 103 VC = 7, // no overflow 104 HI = 8, // unsigned higher 105 LS = 9, // unsigned lower or same 106 GE = 10, // signed greater than or equal 107 LT = 11, // signed less than 108 GT = 12, // signed greater than 109 LE = 13, // signed less than or equal 110 AL = 14, // always (unconditional) 111 special_condition = 15, // special condition (refer to section A3.2.1) 112 max_condition = 16 113}; 114 115 116// Opcodes for Data-processing instructions (instructions with a type 0 and 1) 117// as defined in section A3.4 118enum Opcode { 119 no_operand = -1, 120 AND = 0, // Logical AND 121 EOR = 1, // Logical Exclusive OR 122 SUB = 2, // Subtract 123 RSB = 3, // Reverse Subtract 124 ADD = 4, // Add 125 ADC = 5, // Add with Carry 126 SBC = 6, // Subtract with Carry 127 RSC = 7, // Reverse Subtract with Carry 128 TST = 8, // Test 129 TEQ = 9, // Test Equivalence 130 CMP = 10, // Compare 131 CMN = 11, // Compare Negated 132 ORR = 12, // Logical (inclusive) OR 133 MOV = 13, // Move 134 BIC = 14, // Bit Clear 135 MVN = 15, // Move Not 136 max_operand = 16 137}; 138 139 140// Some special instructions encoded as a TEQ with S=0 (bit 20). 141enum Opcode9Bits { 142 BX = 1, 143 BXJ = 2, 144 BLX = 3, 145 BKPT = 7 146}; 147 148 149// Some special instructions encoded as a CMN with S=0 (bit 20). 150enum Opcode11Bits { 151 CLZ = 1 152}; 153 154 155// S 156 157 158// Shifter types for Data-processing operands as defined in section A5.1.2. 159enum Shift { 160 no_shift = -1, 161 LSL = 0, // Logical shift left 162 LSR = 1, // Logical shift right 163 ASR = 2, // Arithmetic shift right 164 ROR = 3, // Rotate right 165 max_shift = 4 166}; 167 168 169// Special Software Interrupt codes when used in the presence of the ARM 170// simulator. 171enum SoftwareInterruptCodes { 172 // transition to C code 173 call_rt_redirected = 0x10, 174 // break point 175 break_point = 0x20 176}; 177 178 179typedef int32_t instr_t; 180 181 182// The class Instr enables access to individual fields defined in the ARM 183// architecture instruction set encoding as described in figure A3-1. 184// 185// Example: Test whether the instruction at ptr does set the condition code 186// bits. 187// 188// bool InstructionSetsConditionCodes(byte* ptr) { 189// Instr* instr = Instr::At(ptr); 190// int type = instr->TypeField(); 191// return ((type == 0) || (type == 1)) && instr->HasS(); 192// } 193// 194class Instr { 195 public: 196 enum { 197 kInstrSize = 4, 198 kInstrSizeLog2 = 2, 199 kPCReadOffset = 8 200 }; 201 202 // Get the raw instruction bits. 203 inline instr_t InstructionBits() const { 204 return *reinterpret_cast<const instr_t*>(this); 205 } 206 207 // Set the raw instruction bits to value. 208 inline void SetInstructionBits(instr_t value) { 209 *reinterpret_cast<instr_t*>(this) = value; 210 } 211 212 // Read one particular bit out of the instruction bits. 213 inline int Bit(int nr) const { 214 return (InstructionBits() >> nr) & 1; 215 } 216 217 // Read a bit field out of the instruction bits. 218 inline int Bits(int hi, int lo) const { 219 return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1); 220 } 221 222 223 // Accessors for the different named fields used in the ARM encoding. 224 // The naming of these accessor corresponds to figure A3-1. 225 // Generally applicable fields 226 inline Condition ConditionField() const { 227 return static_cast<Condition>(Bits(31, 28)); 228 } 229 inline int TypeField() const { return Bits(27, 25); } 230 231 inline int RnField() const { return Bits(19, 16); } 232 inline int RdField() const { return Bits(15, 12); } 233 234 // Fields used in Data processing instructions 235 inline Opcode OpcodeField() const { 236 return static_cast<Opcode>(Bits(24, 21)); 237 } 238 inline int SField() const { return Bit(20); } 239 // with register 240 inline int RmField() const { return Bits(3, 0); } 241 inline Shift ShiftField() const { return static_cast<Shift>(Bits(6, 5)); } 242 inline int RegShiftField() const { return Bit(4); } 243 inline int RsField() const { return Bits(11, 8); } 244 inline int ShiftAmountField() const { return Bits(11, 7); } 245 // with immediate 246 inline int RotateField() const { return Bits(11, 8); } 247 inline int Immed8Field() const { return Bits(7, 0); } 248 249 // Fields used in Load/Store instructions 250 inline int PUField() const { return Bits(24, 23); } 251 inline int BField() const { return Bit(22); } 252 inline int WField() const { return Bit(21); } 253 inline int LField() const { return Bit(20); } 254 // with register uses same fields as Data processing instructions above 255 // with immediate 256 inline int Offset12Field() const { return Bits(11, 0); } 257 // multiple 258 inline int RlistField() const { return Bits(15, 0); } 259 // extra loads and stores 260 inline int SignField() const { return Bit(6); } 261 inline int HField() const { return Bit(5); } 262 inline int ImmedHField() const { return Bits(11, 8); } 263 inline int ImmedLField() const { return Bits(3, 0); } 264 265 // Fields used in Branch instructions 266 inline int LinkField() const { return Bit(24); } 267 inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); } 268 269 // Fields used in Software interrupt instructions 270 inline SoftwareInterruptCodes SwiField() const { 271 return static_cast<SoftwareInterruptCodes>(Bits(23, 0)); 272 } 273 274 // Test for special encodings of type 0 instructions (extra loads and stores, 275 // as well as multiplications). 276 inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); } 277 278 // Special accessors that test for existence of a value. 279 inline bool HasS() const { return SField() == 1; } 280 inline bool HasB() const { return BField() == 1; } 281 inline bool HasW() const { return WField() == 1; } 282 inline bool HasL() const { return LField() == 1; } 283 inline bool HasSign() const { return SignField() == 1; } 284 inline bool HasH() const { return HField() == 1; } 285 inline bool HasLink() const { return LinkField() == 1; } 286 287 // Instructions are read of out a code stream. The only way to get a 288 // reference to an instruction is to convert a pointer. There is no way 289 // to allocate or create instances of class Instr. 290 // Use the At(pc) function to create references to Instr. 291 static Instr* At(byte* pc) { return reinterpret_cast<Instr*>(pc); } 292 293 private: 294 // We need to prevent the creation of instances of class Instr. 295 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); 296}; 297 298 299// Helper functions for converting between register numbers and names. 300class Registers { 301 public: 302 // Return the name of the register. 303 static const char* Name(int reg); 304 305 // Lookup the register number for the name provided. 306 static int Number(const char* name); 307 308 struct RegisterAlias { 309 int reg; 310 const char *name; 311 }; 312 313 private: 314 static const char* names_[kNumRegisters]; 315 static const RegisterAlias aliases_[]; 316}; 317 318 319 320} } // namespace assembler::arm 321 322#endif // V8_ARM_CONSTANTS_ARM_H_ 323