1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_COMPILER_INSTRUCTION_CODES_H_ 6 #define V8_COMPILER_INSTRUCTION_CODES_H_ 7 8 #include <iosfwd> 9 10 #if V8_TARGET_ARCH_ARM 11 #include "src/compiler/arm/instruction-codes-arm.h" 12 #elif V8_TARGET_ARCH_ARM64 13 #include "src/compiler/arm64/instruction-codes-arm64.h" 14 #elif V8_TARGET_ARCH_IA32 15 #include "src/compiler/ia32/instruction-codes-ia32.h" 16 #elif V8_TARGET_ARCH_MIPS 17 #include "src/compiler/mips/instruction-codes-mips.h" 18 #elif V8_TARGET_ARCH_MIPS64 19 #include "src/compiler/mips64/instruction-codes-mips64.h" 20 #elif V8_TARGET_ARCH_X64 21 #include "src/compiler/x64/instruction-codes-x64.h" 22 #elif V8_TARGET_ARCH_PPC 23 #include "src/compiler/ppc/instruction-codes-ppc.h" 24 #elif V8_TARGET_ARCH_S390 25 #include "src/compiler/s390/instruction-codes-s390.h" 26 #else 27 #define TARGET_ARCH_OPCODE_LIST(V) 28 #define TARGET_ADDRESSING_MODE_LIST(V) 29 #endif 30 #include "src/globals.h" 31 #include "src/utils.h" 32 33 namespace v8 { 34 namespace internal { 35 namespace compiler { 36 37 // Modes for ArchStoreWithWriteBarrier below. 38 enum class RecordWriteMode { kValueIsMap, kValueIsPointer, kValueIsAny }; 39 40 41 // Target-specific opcodes that specify which assembly sequence to emit. 42 // Most opcodes specify a single instruction. 43 #define COMMON_ARCH_OPCODE_LIST(V) \ 44 V(ArchCallCodeObject) \ 45 V(ArchTailCallCodeObjectFromJSFunction) \ 46 V(ArchTailCallCodeObject) \ 47 V(ArchCallJSFunction) \ 48 V(ArchTailCallAddress) \ 49 V(ArchPrepareCallCFunction) \ 50 V(ArchSaveCallerRegisters) \ 51 V(ArchRestoreCallerRegisters) \ 52 V(ArchCallCFunction) \ 53 V(ArchPrepareTailCall) \ 54 V(ArchCallWasmFunction) \ 55 V(ArchTailCallWasm) \ 56 V(ArchJmp) \ 57 V(ArchBinarySearchSwitch) \ 58 V(ArchLookupSwitch) \ 59 V(ArchTableSwitch) \ 60 V(ArchNop) \ 61 V(ArchDebugAbort) \ 62 V(ArchDebugBreak) \ 63 V(ArchComment) \ 64 V(ArchThrowTerminator) \ 65 V(ArchDeoptimize) \ 66 V(ArchRet) \ 67 V(ArchStackPointer) \ 68 V(ArchFramePointer) \ 69 V(ArchParentFramePointer) \ 70 V(ArchTruncateDoubleToI) \ 71 V(ArchStoreWithWriteBarrier) \ 72 V(ArchStackSlot) \ 73 V(ArchWordPoisonOnSpeculation) \ 74 V(Word32AtomicLoadInt8) \ 75 V(Word32AtomicLoadUint8) \ 76 V(Word32AtomicLoadInt16) \ 77 V(Word32AtomicLoadUint16) \ 78 V(Word32AtomicLoadWord32) \ 79 V(Word32AtomicStoreWord8) \ 80 V(Word32AtomicStoreWord16) \ 81 V(Word32AtomicStoreWord32) \ 82 V(Word32AtomicExchangeInt8) \ 83 V(Word32AtomicExchangeUint8) \ 84 V(Word32AtomicExchangeInt16) \ 85 V(Word32AtomicExchangeUint16) \ 86 V(Word32AtomicExchangeWord32) \ 87 V(Word32AtomicCompareExchangeInt8) \ 88 V(Word32AtomicCompareExchangeUint8) \ 89 V(Word32AtomicCompareExchangeInt16) \ 90 V(Word32AtomicCompareExchangeUint16) \ 91 V(Word32AtomicCompareExchangeWord32) \ 92 V(Word32AtomicAddInt8) \ 93 V(Word32AtomicAddUint8) \ 94 V(Word32AtomicAddInt16) \ 95 V(Word32AtomicAddUint16) \ 96 V(Word32AtomicAddWord32) \ 97 V(Word32AtomicSubInt8) \ 98 V(Word32AtomicSubUint8) \ 99 V(Word32AtomicSubInt16) \ 100 V(Word32AtomicSubUint16) \ 101 V(Word32AtomicSubWord32) \ 102 V(Word32AtomicAndInt8) \ 103 V(Word32AtomicAndUint8) \ 104 V(Word32AtomicAndInt16) \ 105 V(Word32AtomicAndUint16) \ 106 V(Word32AtomicAndWord32) \ 107 V(Word32AtomicOrInt8) \ 108 V(Word32AtomicOrUint8) \ 109 V(Word32AtomicOrInt16) \ 110 V(Word32AtomicOrUint16) \ 111 V(Word32AtomicOrWord32) \ 112 V(Word32AtomicXorInt8) \ 113 V(Word32AtomicXorUint8) \ 114 V(Word32AtomicXorInt16) \ 115 V(Word32AtomicXorUint16) \ 116 V(Word32AtomicXorWord32) \ 117 V(Ieee754Float64Acos) \ 118 V(Ieee754Float64Acosh) \ 119 V(Ieee754Float64Asin) \ 120 V(Ieee754Float64Asinh) \ 121 V(Ieee754Float64Atan) \ 122 V(Ieee754Float64Atanh) \ 123 V(Ieee754Float64Atan2) \ 124 V(Ieee754Float64Cbrt) \ 125 V(Ieee754Float64Cos) \ 126 V(Ieee754Float64Cosh) \ 127 V(Ieee754Float64Exp) \ 128 V(Ieee754Float64Expm1) \ 129 V(Ieee754Float64Log) \ 130 V(Ieee754Float64Log1p) \ 131 V(Ieee754Float64Log10) \ 132 V(Ieee754Float64Log2) \ 133 V(Ieee754Float64Pow) \ 134 V(Ieee754Float64Sin) \ 135 V(Ieee754Float64Sinh) \ 136 V(Ieee754Float64Tan) \ 137 V(Ieee754Float64Tanh) 138 139 #define ARCH_OPCODE_LIST(V) \ 140 COMMON_ARCH_OPCODE_LIST(V) \ 141 TARGET_ARCH_OPCODE_LIST(V) 142 143 enum ArchOpcode { 144 #define DECLARE_ARCH_OPCODE(Name) k##Name, 145 ARCH_OPCODE_LIST(DECLARE_ARCH_OPCODE) 146 #undef DECLARE_ARCH_OPCODE 147 #define COUNT_ARCH_OPCODE(Name) +1 148 kLastArchOpcode = -1 ARCH_OPCODE_LIST(COUNT_ARCH_OPCODE) 149 #undef COUNT_ARCH_OPCODE 150 }; 151 152 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 153 const ArchOpcode& ao); 154 155 // Addressing modes represent the "shape" of inputs to an instruction. 156 // Many instructions support multiple addressing modes. Addressing modes 157 // are encoded into the InstructionCode of the instruction and tell the 158 // code generator after register allocation which assembler method to call. 159 #define ADDRESSING_MODE_LIST(V) \ 160 V(None) \ 161 TARGET_ADDRESSING_MODE_LIST(V) 162 163 enum AddressingMode { 164 #define DECLARE_ADDRESSING_MODE(Name) kMode_##Name, 165 ADDRESSING_MODE_LIST(DECLARE_ADDRESSING_MODE) 166 #undef DECLARE_ADDRESSING_MODE 167 #define COUNT_ADDRESSING_MODE(Name) +1 168 kLastAddressingMode = -1 ADDRESSING_MODE_LIST(COUNT_ADDRESSING_MODE) 169 #undef COUNT_ADDRESSING_MODE 170 }; 171 172 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 173 const AddressingMode& am); 174 175 // The mode of the flags continuation (see below). 176 enum FlagsMode { 177 kFlags_none = 0, 178 kFlags_branch = 1, 179 kFlags_branch_and_poison = 2, 180 kFlags_deoptimize = 3, 181 kFlags_deoptimize_and_poison = 4, 182 kFlags_set = 5, 183 kFlags_trap = 6 184 }; 185 186 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 187 const FlagsMode& fm); 188 189 // The condition of flags continuation (see below). 190 enum FlagsCondition { 191 kEqual, 192 kNotEqual, 193 kSignedLessThan, 194 kSignedGreaterThanOrEqual, 195 kSignedLessThanOrEqual, 196 kSignedGreaterThan, 197 kUnsignedLessThan, 198 kUnsignedGreaterThanOrEqual, 199 kUnsignedLessThanOrEqual, 200 kUnsignedGreaterThan, 201 kFloatLessThanOrUnordered, 202 kFloatGreaterThanOrEqual, 203 kFloatLessThanOrEqual, 204 kFloatGreaterThanOrUnordered, 205 kFloatLessThan, 206 kFloatGreaterThanOrEqualOrUnordered, 207 kFloatLessThanOrEqualOrUnordered, 208 kFloatGreaterThan, 209 kUnorderedEqual, 210 kUnorderedNotEqual, 211 kOverflow, 212 kNotOverflow, 213 kPositiveOrZero, 214 kNegative 215 }; 216 217 inline FlagsCondition NegateFlagsCondition(FlagsCondition condition) { 218 return static_cast<FlagsCondition>(condition ^ 1); 219 } 220 221 FlagsCondition CommuteFlagsCondition(FlagsCondition condition); 222 223 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 224 const FlagsCondition& fc); 225 226 enum MemoryAccessMode { 227 kMemoryAccessDirect = 0, 228 kMemoryAccessProtected = 1, 229 kMemoryAccessPoisoned = 2 230 }; 231 232 // The InstructionCode is an opaque, target-specific integer that encodes 233 // what code to emit for an instruction in the code generator. It is not 234 // interesting to the register allocator, as the inputs and flags on the 235 // instructions specify everything of interest. 236 typedef int32_t InstructionCode; 237 238 // Helpers for encoding / decoding InstructionCode into the fields needed 239 // for code generation. We encode the instruction, addressing mode, and flags 240 // continuation into a single InstructionCode which is stored as part of 241 // the instruction. 242 typedef BitField<ArchOpcode, 0, 9> ArchOpcodeField; 243 typedef BitField<AddressingMode, 9, 5> AddressingModeField; 244 typedef BitField<FlagsMode, 14, 3> FlagsModeField; 245 typedef BitField<FlagsCondition, 17, 5> FlagsConditionField; 246 typedef BitField<int, 22, 10> MiscField; 247 248 } // namespace compiler 249 } // namespace internal 250 } // namespace v8 251 252 #endif // V8_COMPILER_INSTRUCTION_CODES_H_ 253