machine-type.h 13.6 KB
Newer Older
1 2 3 4
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#ifndef V8_CODEGEN_MACHINE_TYPE_H_
#define V8_CODEGEN_MACHINE_TYPE_H_
7

8 9
#include <iosfwd>

10
#include "src/base/bits.h"
11
#include "src/common/globals.h"
12
#include "src/flags/flags.h"
13

14 15 16
namespace v8 {
namespace internal {

17
enum class MachineRepresentation : uint8_t {
18 19
  kNone,
  kBit,
20
  // Integral representations must be consecutive, in order of increasing order.
21 22 23 24
  kWord8,
  kWord16,
  kWord32,
  kWord64,
25 26 27 28 29 30 31 32 33 34 35 36 37
  // (uncompressed) MapWord
  // kMapWord is the representation of a map word, i.e. a map in the header
  // of a HeapObject.
  // If V8_MAP_PACKING is disabled, a map word is just the map itself. Hence
  //     kMapWord is equivalent to kTaggedPointer -- in fact it will be
  //     translated to kTaggedPointer during memory lowering.
  // If V8_MAP_PACKING is enabled, a map word is a Smi-like encoding of a map
  //     and some meta data. Memory lowering of kMapWord loads/stores
  //     produces low-level kTagged loads/stores plus the necessary
  //     decode/encode operations.
  // In either case, the kMapWord representation is not used after memory
  // lowering.
  kMapWord,
38 39 40 41 42
  kTaggedSigned,       // (uncompressed) Smi
  kTaggedPointer,      // (uncompressed) HeapObject
  kTagged,             // (uncompressed) Object (Smi or HeapObject)
  kCompressedPointer,  // (compressed) HeapObject
  kCompressed,         // (compressed) Object (Smi or HeapObject)
43
  // FP and SIMD representations must be last, and in order of increasing size.
44 45 46
  kFloat32,
  kFloat64,
  kSimd128,
47
  kFirstFPRepresentation = kFloat32,
48
  kLastRepresentation = kSimd128
49
};
50

51 52
bool IsSubtype(MachineRepresentation rep1, MachineRepresentation rep2);

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
#define ASSERT_CONSECUTIVE(rep1, rep2)                                      \
  static_assert(static_cast<uint8_t>(MachineRepresentation::k##rep1) + 1 == \
                    static_cast<uint8_t>(MachineRepresentation::k##rep2),   \
                #rep1 " and " #rep2 " must be consecutive.");

ASSERT_CONSECUTIVE(Word8, Word16)
ASSERT_CONSECUTIVE(Word16, Word32)
ASSERT_CONSECUTIVE(Word32, Word64)
ASSERT_CONSECUTIVE(Float32, Float64)
ASSERT_CONSECUTIVE(Float64, Simd128)
#undef ASSERT_CONSECUTIVE

static_assert(MachineRepresentation::kLastRepresentation ==
                  MachineRepresentation::kSimd128,
              "FP and SIMD representations must be last.");

69 70 71 72
static_assert(static_cast<int>(MachineRepresentation::kLastRepresentation) <
                  kIntSize * kBitsPerByte,
              "Bit masks of MachineRepresentation should fit in an int");

73
V8_EXPORT_PRIVATE const char* MachineReprToString(MachineRepresentation);
74

75
enum class MachineSemantic : uint8_t {
76 77 78 79 80 81 82 83 84 85
  kNone,
  kBool,
  kInt32,
  kUint32,
  kInt64,
  kUint64,
  kNumber,
  kAny
};

86
V8_EXPORT_PRIVATE inline constexpr int ElementSizeLog2Of(MachineRepresentation);
87

88 89
V8_EXPORT_PRIVATE inline constexpr int ElementSizeInBytes(
    MachineRepresentation);
90

91 92
class MachineType {
 public:
93
  constexpr MachineType()
94 95
      : representation_(MachineRepresentation::kNone),
        semantic_(MachineSemantic::kNone) {}
96 97
  constexpr MachineType(MachineRepresentation representation,
                        MachineSemantic semantic)
98 99
      : representation_(representation), semantic_(semantic) {}

100
  constexpr bool operator==(MachineType other) const {
101 102 103 104
    return representation() == other.representation() &&
           semantic() == other.semantic();
  }

105 106 107
  constexpr bool operator!=(MachineType other) const {
    return !(*this == other);
  }
108

109 110 111 112
  constexpr MachineRepresentation representation() const {
    return representation_;
  }
  constexpr MachineSemantic semantic() const { return semantic_; }
113

114 115 116
  constexpr bool IsNone() const {
    return representation() == MachineRepresentation::kNone;
  }
117

118 119 120 121
  constexpr bool IsMapWord() const {
    return representation() == MachineRepresentation::kMapWord;
  }

122
  constexpr bool IsSigned() const {
123 124 125
    return semantic() == MachineSemantic::kInt32 ||
           semantic() == MachineSemantic::kInt64;
  }
126
  constexpr bool IsUnsigned() const {
127 128 129
    return semantic() == MachineSemantic::kUint32 ||
           semantic() == MachineSemantic::kUint64;
  }
130 131 132 133 134
  constexpr bool IsTagged() const {
    return representation() == MachineRepresentation::kTaggedPointer ||
           representation() == MachineRepresentation::kTaggedSigned ||
           representation() == MachineRepresentation::kTagged;
  }
135 136 137 138 139 140
  constexpr bool IsTaggedSigned() const {
    return representation() == MachineRepresentation::kTaggedSigned;
  }
  constexpr bool IsTaggedPointer() const {
    return representation() == MachineRepresentation::kTaggedPointer;
  }
141 142 143 144 145 146 147
  constexpr bool IsCompressed() const {
    return representation() == MachineRepresentation::kCompressedPointer ||
           representation() == MachineRepresentation::kCompressed;
  }
  constexpr bool IsCompressedPointer() const {
    return representation() == MachineRepresentation::kCompressedPointer;
  }
148 149 150 151
  constexpr static MachineRepresentation TaggedRepresentation() {
    return (kTaggedSize == 4) ? MachineRepresentation::kWord32
                              : MachineRepresentation::kWord64;
  }
152
  constexpr static MachineRepresentation PointerRepresentation() {
153 154
    return (kSystemPointerSize == 4) ? MachineRepresentation::kWord32
                                     : MachineRepresentation::kWord64;
155
  }
156
  constexpr static MachineType UintPtr() {
157
    return (kSystemPointerSize == 4) ? Uint32() : Uint64();
158
  }
159
  constexpr static MachineType IntPtr() {
160
    return (kSystemPointerSize == 4) ? Int32() : Int64();
161
  }
162
  constexpr static MachineType Int8() {
163 164
    return MachineType(MachineRepresentation::kWord8, MachineSemantic::kInt32);
  }
165
  constexpr static MachineType Uint8() {
166 167
    return MachineType(MachineRepresentation::kWord8, MachineSemantic::kUint32);
  }
168
  constexpr static MachineType Int16() {
169 170
    return MachineType(MachineRepresentation::kWord16, MachineSemantic::kInt32);
  }
171
  constexpr static MachineType Uint16() {
172 173 174
    return MachineType(MachineRepresentation::kWord16,
                       MachineSemantic::kUint32);
  }
175
  constexpr static MachineType Int32() {
176 177
    return MachineType(MachineRepresentation::kWord32, MachineSemantic::kInt32);
  }
178
  constexpr static MachineType Uint32() {
179 180 181
    return MachineType(MachineRepresentation::kWord32,
                       MachineSemantic::kUint32);
  }
182
  constexpr static MachineType Int64() {
183 184
    return MachineType(MachineRepresentation::kWord64, MachineSemantic::kInt64);
  }
185
  constexpr static MachineType Uint64() {
186 187 188
    return MachineType(MachineRepresentation::kWord64,
                       MachineSemantic::kUint64);
  }
189
  constexpr static MachineType Float32() {
190 191 192
    return MachineType(MachineRepresentation::kFloat32,
                       MachineSemantic::kNumber);
  }
193
  constexpr static MachineType Float64() {
194 195 196
    return MachineType(MachineRepresentation::kFloat64,
                       MachineSemantic::kNumber);
  }
197
  constexpr static MachineType Simd128() {
198 199
    return MachineType(MachineRepresentation::kSimd128, MachineSemantic::kNone);
  }
200
  constexpr static MachineType Pointer() {
201 202
    return MachineType(PointerRepresentation(), MachineSemantic::kNone);
  }
203
  constexpr static MachineType TaggedPointer() {
204 205 206
    return MachineType(MachineRepresentation::kTaggedPointer,
                       MachineSemantic::kAny);
  }
207 208 209
  constexpr static MachineType MapInHeader() {
    return MachineType(MachineRepresentation::kMapWord, MachineSemantic::kAny);
  }
210
  constexpr static MachineType TaggedSigned() {
211 212 213
    return MachineType(MachineRepresentation::kTaggedSigned,
                       MachineSemantic::kInt32);
  }
214
  constexpr static MachineType AnyTagged() {
215 216
    return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny);
  }
217 218 219 220 221 222 223 224
  constexpr static MachineType CompressedPointer() {
    return MachineType(MachineRepresentation::kCompressedPointer,
                       MachineSemantic::kAny);
  }
  constexpr static MachineType AnyCompressed() {
    return MachineType(MachineRepresentation::kCompressed,
                       MachineSemantic::kAny);
  }
225
  constexpr static MachineType Bool() {
226 227
    return MachineType(MachineRepresentation::kBit, MachineSemantic::kBool);
  }
228
  constexpr static MachineType None() {
229 230 231
    return MachineType(MachineRepresentation::kNone, MachineSemantic::kNone);
  }

232
  static MachineType TypeForRepresentation(const MachineRepresentation& rep,
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
                                           bool isSigned = true) {
    switch (rep) {
      case MachineRepresentation::kNone:
        return MachineType::None();
      case MachineRepresentation::kBit:
        return MachineType::Bool();
      case MachineRepresentation::kWord8:
        return isSigned ? MachineType::Int8() : MachineType::Uint8();
      case MachineRepresentation::kWord16:
        return isSigned ? MachineType::Int16() : MachineType::Uint16();
      case MachineRepresentation::kWord32:
        return isSigned ? MachineType::Int32() : MachineType::Uint32();
      case MachineRepresentation::kWord64:
        return isSigned ? MachineType::Int64() : MachineType::Uint64();
      case MachineRepresentation::kFloat32:
        return MachineType::Float32();
      case MachineRepresentation::kFloat64:
        return MachineType::Float64();
      case MachineRepresentation::kSimd128:
        return MachineType::Simd128();
      case MachineRepresentation::kTagged:
        return MachineType::AnyTagged();
255 256 257 258
      case MachineRepresentation::kTaggedSigned:
        return MachineType::TaggedSigned();
      case MachineRepresentation::kTaggedPointer:
        return MachineType::TaggedPointer();
259 260 261 262
      case MachineRepresentation::kCompressed:
        return MachineType::AnyCompressed();
      case MachineRepresentation::kCompressedPointer:
        return MachineType::CompressedPointer();
263 264 265 266 267
      default:
        UNREACHABLE();
    }
  }

268
  constexpr bool LessThanOrEqualPointerSize() const {
269
    return ElementSizeLog2Of(this->representation()) <= kSystemPointerSizeLog2;
270 271
  }

272 273 274 275
  constexpr byte MemSize() const {
    return 1 << i::ElementSizeLog2Of(this->representation());
  }

276 277 278 279 280 281 282
 private:
  MachineRepresentation representation_;
  MachineSemantic semantic_;
};

V8_INLINE size_t hash_value(MachineRepresentation rep) {
  return static_cast<size_t>(rep);
283 284
}

285 286 287 288 289
V8_INLINE size_t hash_value(MachineType type) {
  return static_cast<size_t>(type.representation()) +
         static_cast<size_t>(type.semantic()) * 16;
}

290 291
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                           MachineRepresentation rep);
292
std::ostream& operator<<(std::ostream& os, MachineSemantic type);
293
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, MachineType type);
294

295 296 297 298 299
inline bool IsIntegral(MachineRepresentation rep) {
  return rep >= MachineRepresentation::kWord8 &&
         rep <= MachineRepresentation::kWord64;
}

300
inline bool IsFloatingPoint(MachineRepresentation rep) {
301
  return rep >= MachineRepresentation::kFirstFPRepresentation;
302 303
}

304 305
inline bool CanBeTaggedPointer(MachineRepresentation rep) {
  return rep == MachineRepresentation::kTagged ||
306 307
         rep == MachineRepresentation::kTaggedPointer ||
         rep == MachineRepresentation::kMapWord;
308 309
}

310 311 312 313 314
inline bool CanBeTaggedSigned(MachineRepresentation rep) {
  return rep == MachineRepresentation::kTagged ||
         rep == MachineRepresentation::kTaggedSigned;
}

315 316 317 318
inline bool IsAnyTagged(MachineRepresentation rep) {
  return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned;
}

319 320 321 322 323
inline bool CanBeCompressedPointer(MachineRepresentation rep) {
  return rep == MachineRepresentation::kCompressed ||
         rep == MachineRepresentation::kCompressedPointer;
}

324 325 326 327
inline bool CanBeTaggedOrCompressedPointer(MachineRepresentation rep) {
  return CanBeTaggedPointer(rep) || CanBeCompressedPointer(rep);
}

328
inline bool IsAnyCompressed(MachineRepresentation rep) {
329
  return CanBeCompressedPointer(rep);
330 331
}

332
// Gets the log2 of the element size in bytes of the machine type.
333 334
V8_EXPORT_PRIVATE inline constexpr int ElementSizeLog2Of(
    MachineRepresentation rep) {
335 336 337
  switch (rep) {
    case MachineRepresentation::kBit:
    case MachineRepresentation::kWord8:
338
      return 0;
339
    case MachineRepresentation::kWord16:
340
      return 1;
341 342
    case MachineRepresentation::kWord32:
    case MachineRepresentation::kFloat32:
343
      return 2;
344 345
    case MachineRepresentation::kWord64:
    case MachineRepresentation::kFloat64:
346
      return 3;
347 348
    case MachineRepresentation::kSimd128:
      return 4;
349 350
    case MachineRepresentation::kTaggedSigned:
    case MachineRepresentation::kTaggedPointer:
351
    case MachineRepresentation::kTagged:
352
    case MachineRepresentation::kMapWord:
353 354
    case MachineRepresentation::kCompressedPointer:
    case MachineRepresentation::kCompressed:
355
      return kTaggedSizeLog2;
356
    default:
357
      UNREACHABLE();
358
  }
359 360
}

361 362 363 364 365 366 367 368 369
constexpr int kMaximumReprSizeLog2 =
    ElementSizeLog2Of(MachineRepresentation::kSimd128);
constexpr int kMaximumReprSizeInBytes = 1 << kTaggedSizeLog2;

STATIC_ASSERT(kMaximumReprSizeLog2 >=
              ElementSizeLog2Of(MachineRepresentation::kTagged));
STATIC_ASSERT(kMaximumReprSizeLog2 >=
              ElementSizeLog2Of(MachineRepresentation::kWord64));

370 371
V8_EXPORT_PRIVATE inline constexpr int ElementSizeInBytes(
    MachineRepresentation rep) {
372 373 374
  return 1 << ElementSizeLog2Of(rep);
}

375 376 377 378 379 380
V8_EXPORT_PRIVATE inline constexpr int ElementSizeInPointers(
    MachineRepresentation rep) {
  return (ElementSizeInBytes(rep) + kSystemPointerSize - 1) /
         kSystemPointerSize;
}

381 382 383 384 385 386
// Converts representation to bit for representation masks.
V8_EXPORT_PRIVATE inline constexpr int RepresentationBit(
    MachineRepresentation rep) {
  return 1 << static_cast<int>(rep);
}

387 388
}  // namespace internal
}  // namespace v8
389

390
#endif  // V8_CODEGEN_MACHINE_TYPE_H_