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