Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef jit_x86_shared_Constants_x86_shared_h
8 : #define jit_x86_shared_Constants_x86_shared_h
9 :
10 : #include "mozilla/ArrayUtils.h"
11 : #include "mozilla/Assertions.h"
12 :
13 : #include <stddef.h>
14 : #include <stdint.h>
15 :
16 : namespace js {
17 : namespace jit {
18 :
19 : namespace X86Encoding {
20 :
21 : enum RegisterID : uint8_t {
22 : rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi
23 : #ifdef JS_CODEGEN_X64
24 : ,r8, r9, r10, r11, r12, r13, r14, r15
25 : #endif
26 : ,invalid_reg
27 : };
28 :
29 : enum HRegisterID {
30 : ah = rsp,
31 : ch = rbp,
32 : dh = rsi,
33 : bh = rdi
34 : };
35 :
36 : enum XMMRegisterID {
37 : xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
38 : #ifdef JS_CODEGEN_X64
39 : ,xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
40 : #endif
41 : ,invalid_xmm
42 : };
43 :
44 331515 : inline const char* XMMRegName(XMMRegisterID reg)
45 : {
46 : static const char* const names[] = {
47 : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7"
48 : #ifdef JS_CODEGEN_X64
49 : ,"%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15"
50 : #endif
51 : };
52 331515 : MOZ_ASSERT(size_t(reg) < mozilla::ArrayLength(names));
53 331520 : return names[reg];
54 : }
55 :
56 : #ifdef JS_CODEGEN_X64
57 1046974 : inline const char* GPReg64Name(RegisterID reg)
58 : {
59 : static const char* const names[] = {
60 : "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi"
61 : #ifdef JS_CODEGEN_X64
62 : ,"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
63 : #endif
64 : };
65 1046974 : MOZ_ASSERT(size_t(reg) < mozilla::ArrayLength(names));
66 1047012 : return names[reg];
67 : }
68 : #endif
69 :
70 31866 : inline const char* GPReg32Name(RegisterID reg)
71 : {
72 : static const char* const names[] = {
73 : "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
74 : #ifdef JS_CODEGEN_X64
75 : ,"%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
76 : #endif
77 : };
78 31866 : MOZ_ASSERT(size_t(reg) < mozilla::ArrayLength(names));
79 31866 : return names[reg];
80 : }
81 :
82 36 : inline const char* GPReg16Name(RegisterID reg)
83 : {
84 : static const char* const names[] = {
85 : "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di"
86 : #ifdef JS_CODEGEN_X64
87 : ,"%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
88 : #endif
89 : };
90 36 : MOZ_ASSERT(size_t(reg) < mozilla::ArrayLength(names));
91 36 : return names[reg];
92 : }
93 :
94 15427 : inline const char* GPReg8Name(RegisterID reg)
95 : {
96 : static const char* const names[] = {
97 : "%al", "%cl", "%dl", "%bl"
98 : #ifdef JS_CODEGEN_X64
99 : ,"%spl", "%bpl", "%sil", "%dil",
100 : "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
101 : #endif
102 : };
103 15427 : MOZ_ASSERT(size_t(reg) < mozilla::ArrayLength(names));
104 15427 : return names[reg];
105 : }
106 :
107 715770 : inline const char* GPRegName(RegisterID reg)
108 : {
109 : #ifdef JS_CODEGEN_X64
110 715770 : return GPReg64Name(reg);
111 : #else
112 : return GPReg32Name(reg);
113 : #endif
114 : }
115 :
116 13577 : inline bool HasSubregL(RegisterID reg)
117 : {
118 : #ifdef JS_CODEGEN_X64
119 : // In 64-bit mode, all registers have an 8-bit lo subreg.
120 13577 : return true;
121 : #else
122 : // In 32-bit mode, only the first four registers do.
123 : return reg <= rbx;
124 : #endif
125 : }
126 :
127 0 : inline bool HasSubregH(RegisterID reg)
128 : {
129 : // The first four registers always have h registers. However, note that
130 : // on x64, h registers may not be used in instructions using REX
131 : // prefixes. Also note that this may depend on what other registers are
132 : // used!
133 0 : return reg <= rbx;
134 : }
135 :
136 0 : inline HRegisterID GetSubregH(RegisterID reg)
137 : {
138 0 : MOZ_ASSERT(HasSubregH(reg));
139 0 : return HRegisterID(reg + 4);
140 : }
141 :
142 0 : inline const char* HRegName8(HRegisterID reg)
143 : {
144 : static const char* const names[] = {
145 : "%ah", "%ch", "%dh", "%bh"
146 : };
147 0 : size_t index = reg - GetSubregH(rax);
148 0 : MOZ_ASSERT(index < mozilla::ArrayLength(names));
149 0 : return names[index];
150 : }
151 :
152 : enum Condition {
153 : ConditionO,
154 : ConditionNO,
155 : ConditionB,
156 : ConditionAE,
157 : ConditionE,
158 : ConditionNE,
159 : ConditionBE,
160 : ConditionA,
161 : ConditionS,
162 : ConditionNS,
163 : ConditionP,
164 : ConditionNP,
165 : ConditionL,
166 : ConditionGE,
167 : ConditionLE,
168 : ConditionG,
169 :
170 : ConditionC = ConditionB,
171 : ConditionNC = ConditionAE
172 : };
173 :
174 41089 : inline const char* CCName(Condition cc)
175 : {
176 : static const char* const names[] = {
177 : "o ", "no", "b ", "ae", "e ", "ne", "be", "a ",
178 : "s ", "ns", "p ", "np", "l ", "ge", "le", "g "
179 : };
180 41089 : MOZ_ASSERT(size_t(cc) < mozilla::ArrayLength(names));
181 41089 : return names[cc];
182 : }
183 :
184 : // Conditions for CMP instructions (CMPSS, CMPSD, CMPPS, CMPPD, etc).
185 : enum ConditionCmp {
186 : ConditionCmp_EQ = 0x0,
187 : ConditionCmp_LT = 0x1,
188 : ConditionCmp_LE = 0x2,
189 : ConditionCmp_UNORD = 0x3,
190 : ConditionCmp_NEQ = 0x4,
191 : ConditionCmp_NLT = 0x5,
192 : ConditionCmp_NLE = 0x6,
193 : ConditionCmp_ORD = 0x7,
194 : };
195 :
196 : // Rounding modes for ROUNDSD.
197 : enum RoundingMode {
198 : RoundToNearest = 0x0,
199 : RoundDown = 0x1,
200 : RoundUp = 0x2,
201 : RoundToZero = 0x3
202 : };
203 :
204 : // Test whether the given address will fit in an address immediate field.
205 : // This is always true on x86, but on x64 it's only true for addreses which
206 : // fit in the 32-bit immediate field.
207 13806 : inline bool IsAddressImmediate(const void* address)
208 : {
209 13806 : intptr_t value = reinterpret_cast<intptr_t>(address);
210 13806 : int32_t immediate = static_cast<int32_t>(value);
211 13806 : return value == immediate;
212 : }
213 :
214 : // Convert the given address to a 32-bit immediate field value. This is a
215 : // no-op on x86, but on x64 it asserts that the address is actually a valid
216 : // address immediate.
217 0 : inline int32_t AddressImmediate(const void* address)
218 : {
219 0 : MOZ_ASSERT(IsAddressImmediate(address));
220 0 : return static_cast<int32_t>(reinterpret_cast<intptr_t>(address));
221 : }
222 :
223 : } // namespace X86Encoding
224 :
225 : } // namespace jit
226 : } // namespace js
227 :
228 : #endif /* jit_x86_shared_Constants_x86_shared_h */
|