Welcome to mirror list, hosted at ThFree Co, Russian Federation.

archtraits.cpp « core « asmjit « src - github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b83d930d25d3bc099e85cdc125439ab31240d6a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// This file is part of AsmJit project <https://asmjit.com>
//
// See asmjit.h or LICENSE.md for license and copyright information
// SPDX-License-Identifier: Zlib

#include "../core/api-build_p.h"
#include "../core/archtraits.h"
#include "../core/misc_p.h"

#if !defined(ASMJIT_NO_X86)
  #include "../x86/x86archtraits_p.h"
#endif

#ifdef ASMJIT_BUILD_ARM
  #include "../arm/armarchtraits_p.h"
#endif

ASMJIT_BEGIN_NAMESPACE

static const constexpr ArchTraits noArchTraits = {
  // SP/FP/LR/PC.
  0xFF, 0xFF, 0xFF, 0xFF,

  // Reserved,
  { 0, 0, 0 },

  // HW stack alignment.
  0,

  // Min/Max stack offset.
  0, 0,

  // ISA features [Gp, Vec, Other0, Other1].
  {{
    InstHints::kNoHints,
    InstHints::kNoHints,
    InstHints::kNoHints,
    InstHints::kNoHints
  }},

  // RegTypeToSignature.
  #define V(index) OperandSignature{0}
  {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
  #undef V

  // RegTypeToTypeId.
  #define V(index) TypeId::kVoid
  {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
  #undef V

  // TypeIdToRegType.
  #define V(index) RegType::kNone
  {{ ASMJIT_LOOKUP_TABLE_32(V, 0) }},
  #undef V

  // Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
  {
    ArchTypeNameId::kByte,
    ArchTypeNameId::kHalf,
    ArchTypeNameId::kWord,
    ArchTypeNameId::kQuad
  }
};

ASMJIT_VARAPI const ArchTraits _archTraits[uint32_t(Arch::kMaxValue) + 1] = {
  // No architecture.
  noArchTraits,

  // X86/X86 architectures.
#if !defined(ASMJIT_NO_X86)
  x86::x86ArchTraits,
  x86::x64ArchTraits,
#else
  noArchTraits,
  noArchTraits,
#endif

  // RISCV32/RISCV64 architectures.
  noArchTraits,
  noArchTraits,

  // ARM architecture
  noArchTraits,

  // AArch64 architecture.
#ifdef ASMJIT_BUILD_ARM
  arm::a64ArchTraits,
#else
  noArchTraits,
#endif

  // ARM/Thumb architecture.
  noArchTraits,

  // Reserved.
  noArchTraits,

  // MIPS32/MIPS64
  noArchTraits,
  noArchTraits
};

ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegSignature(Arch arch, TypeId typeId, TypeId* typeIdOut, OperandSignature* regSignatureOut) noexcept {
  const ArchTraits& archTraits = ArchTraits::byArch(arch);

  // TODO: Remove this, should never be used like this.
  // Passed RegType instead of TypeId?
  if (uint32_t(typeId) <= uint32_t(RegType::kMaxValue))
    typeId = archTraits.regTypeToTypeId(RegType(uint32_t(typeId)));

  if (ASMJIT_UNLIKELY(!TypeUtils::isValid(typeId)))
    return DebugUtils::errored(kErrorInvalidTypeId);

  // First normalize architecture dependent types.
  if (TypeUtils::isAbstract(typeId)) {
    bool is32Bit = Environment::is32Bit(arch);
    if (typeId == TypeId::kIntPtr)
      typeId = is32Bit ? TypeId::kInt32 : TypeId::kInt64;
    else
      typeId = is32Bit ? TypeId::kUInt32 : TypeId::kUInt64;
  }

  // Type size helps to construct all groups of registers.
  // TypeId is invalid if the size is zero.
  uint32_t size = TypeUtils::sizeOf(typeId);
  if (ASMJIT_UNLIKELY(!size))
    return DebugUtils::errored(kErrorInvalidTypeId);

  if (ASMJIT_UNLIKELY(typeId == TypeId::kFloat80))
    return DebugUtils::errored(kErrorInvalidUseOfF80);

  RegType regType = RegType::kNone;
  if (TypeUtils::isBetween(typeId, TypeId::_kBaseStart, TypeId::_kVec32Start)) {
    regType = archTraits._typeIdToRegType[uint32_t(typeId) - uint32_t(TypeId::_kBaseStart)];
    if (regType == RegType::kNone) {
      if (typeId == TypeId::kInt64 || typeId == TypeId::kUInt64)
        return DebugUtils::errored(kErrorInvalidUseOfGpq);
      else
        return DebugUtils::errored(kErrorInvalidTypeId);
    }
  }
  else {
    if (size <= 8 && archTraits._regSignature[RegType::kVec64].isValid())
      regType = RegType::kVec64;
    else if (size <= 16 && archTraits._regSignature[RegType::kVec128].isValid())
      regType = RegType::kVec128;
    else if (size == 32 && archTraits._regSignature[RegType::kVec256].isValid())
      regType = RegType::kVec256;
    else if (archTraits._regSignature[RegType::kVec512].isValid())
      regType = RegType::kVec512;
    else
      return DebugUtils::errored(kErrorInvalidTypeId);
  }

  *typeIdOut = typeId;
  *regSignatureOut = archTraits.regTypeToSignature(regType);
  return kErrorOk;
}

ASMJIT_END_NAMESPACE