1 /**
2  * Define basic types and type masks
3  *
4  * Compiler implementation of the
5  * $(LINK2 https://www.dlang.org, D programming language).
6  *
7  * Copyright:   Copyright (C) 1983-1998 by Symantec
8  *              Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
9  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
10  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
11  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/ty.d, backend/_ty.d)
12  */
13 
14 module dmd.backend.ty;
15 
16 // Online documentation: https://dlang.org/phobos/dmd_backend_ty.html
17 
18 public import dmd.backend.var : tyequiv, dttab, dttab4, tystring, tytouns, _tyrelax, tytab,
19     _tysize, _tyalignsize, TYaarray, TYdelegate, TYdarray, TYptrdiff, TYsize, TYsize_t;
20 
21 @nogc:
22 nothrow:
23 @safe:
24 
25 alias tym_t = uint;
26 
27 /*****************************************
28  * Data types.
29  * (consists of basic type + modifier bits)
30  */
31 
32 // Basic types.
33 // casttab[][] in exp2.c depends on the order of this
34 // typromo[] in cpp.c depends on the order too
35 
36 enum
37 {
38     TYbool              = 0,
39     TYchar              = 1,
40     TYschar             = 2,    // signed char
41     TYuchar             = 3,    // unsigned char
42     TYchar8             = 4,
43     TYchar16            = 5,
44     TYshort             = 6,
45     TYwchar_t           = 7,
46     TYushort            = 8,    // unsigned short
47     TYenum              = 9,    // enumeration value
48     TYint               = 0xA,
49     TYuint              = 0xB,  // unsigned
50     TYlong              = 0xC,
51     TYulong             = 0xD,  // unsigned long
52     TYdchar             = 0xE,  // 32 bit Unicode char
53     TYllong             = 0xF,  // 64 bit long
54     TYullong            = 0x10, // 64 bit unsigned long
55     TYfloat             = 0x11, // 32 bit real
56     TYdouble            = 0x12, // 64 bit real
57 
58     // long double is mapped to either of the following at runtime:
59     TYdouble_alias      = 0x13, // 64 bit real (but distinct for overload purposes)
60     TYldouble           = 0x14, // 80 bit real
61 
62     // Add imaginary and complex types for D and C99
63     TYifloat            = 0x15,
64     TYidouble           = 0x16,
65     TYildouble          = 0x17,
66     TYcfloat            = 0x18,
67     TYcdouble           = 0x19,
68     TYcldouble          = 0x1A,
69 
70     TYnullptr           = 0x1C,
71     TYnptr              = 0x1D, // data segment relative pointer
72     TYref               = 0x24, // reference to another type
73     TYvoid              = 0x25,
74     TYstruct            = 0x26, // watch tyaggregate()
75     TYarray             = 0x27, // watch tyaggregate()
76     TYnfunc             = 0x28, // near C func
77     TYnpfunc            = 0x2A, // near Cpp func
78     TYnsfunc            = 0x2C, // near stdcall func
79     TYifunc             = 0x2E, // interrupt func
80     TYptr               = 0x33, // generic pointer type
81     TYmfunc             = 0x37, // NT C++ member func
82     TYjfunc             = 0x38, // LINK.d D function
83     TYhfunc             = 0x39, // C function with hidden parameter
84     TYnref              = 0x3A, // near reference
85 
86     TYcent              = 0x3C, // 128 bit signed integer
87     TYucent             = 0x3D, // 128 bit unsigned integer
88 
89     // Used for segmented architectures
90     TYsptr              = 0x1E, // stack segment relative pointer
91     TYcptr              = 0x1F, // code segment relative pointer
92     TYf16ptr            = 0x20, // special OS/2 far16 pointer
93     TYfptr              = 0x21, // far pointer (has segment and offset)
94     TYhptr              = 0x22, // huge pointer (has segment and offset)
95     TYvptr              = 0x23, // __handle pointer (has segment and offset)
96     TYffunc             = 0x29, // far  C func
97     TYfpfunc            = 0x2B, // far  Cpp func
98     TYfsfunc            = 0x2D, // far stdcall func
99     TYf16func           = 0x34, // _far16 _pascal function
100     TYnsysfunc          = 0x35, // near __syscall func
101     TYfsysfunc          = 0x36, // far __syscall func
102     TYfref              = 0x3B, // far reference
103 
104     // Used for C++ compiler
105     TYmemptr            = 0x2F, // pointer to member
106     TYident             = 0x30, // type-argument
107     TYtemplate          = 0x31, // unexpanded class template
108     TYvtshape           = 0x32, // virtual function table
109 
110     // SIMD 16 byte vector types        // D type
111     TYfloat4            = 0x3E, // float[4]
112     TYdouble2           = 0x3F, // double[2]
113     TYschar16           = 0x40, // byte[16]
114     TYuchar16           = 0x41, // ubyte[16]
115     TYshort8            = 0x42, // short[8]
116     TYushort8           = 0x43, // ushort[8]
117     TYlong4             = 0x44, // int[4]
118     TYulong4            = 0x45, // uint[4]
119     TYllong2            = 0x46, // long[2]
120     TYullong2           = 0x47, // ulong[2]
121 
122     // SIMD 32 byte vector types        // D type
123     TYfloat8            = 0x48, // float[8]
124     TYdouble4           = 0x49, // double[4]
125     TYschar32           = 0x4A, // byte[32]
126     TYuchar32           = 0x4B, // ubyte[32]
127     TYshort16           = 0x4C, // short[16]
128     TYushort16          = 0x4D, // ushort[16]
129     TYlong8             = 0x4E, // int[8]
130     TYulong8            = 0x4F, // uint[8]
131     TYllong4            = 0x50, // long[4]
132     TYullong4           = 0x51, // ulong[4]
133 
134     // SIMD 64 byte vector types        // D type
135     TYfloat16           = 0x52, // float[16]
136     TYdouble8           = 0x53, // double[8]
137     TYschar64           = 0x54, // byte[64]
138     TYuchar64           = 0x55, // ubyte[64]
139     TYshort32           = 0x56, // short[32]
140     TYushort32          = 0x57, // ushort[32]
141     TYlong16            = 0x58, // int[16]
142     TYulong16           = 0x59, // uint[16]
143     TYllong8            = 0x5A, // long[8]
144     TYullong8           = 0x5B, // ulong[8]
145 
146     TYsharePtr          = 0x5C, // pointer to shared data
147     TYimmutPtr          = 0x5D, // pointer to immutable data
148     TYfgPtr             = 0x5E, // GS: pointer (I32) FS: pointer (I64)
149     TYrestrictPtr       = 0x5F, // restrict pointer
150 
151     TYnoreturn          = 0x60, // bottom type
152 
153     TYMAX               = 0x61,
154 }
155 
156 alias TYerror = TYint;
157 
158 enum
159 {
160     mTYbasic        = 0xFF,          // bit mask for basic types
161 
162    // Linkage type
163     mTYnear         = 0x0800,
164     mTYfar          = 0x1000,        // seg:offset style pointer
165     mTYcs           = 0x2000,        // in code segment
166     mTYthread       = 0x4000,
167 
168     // Used for symbols going in the __thread_data section for TLS variables for Mach-O 64bit
169     mTYthreadData   = 0x5000,
170 
171     // Used in combination with SCcomdat to output symbols with weak linkage.
172     // Compared to a symbol with only SCcomdat, this allows the symbol to be put
173     // in any section in the object file.
174     mTYweakLinkage  = 0x6000,
175     mTYLINK         = 0x7800,        // all linkage bits
176 
177     mTYloadds       = 0x08000,       // 16 bit Windows LOADDS attribute
178     mTYexport       = 0x10000,
179     mTYweak         = 0x00000,
180     mTYimport       = 0x20000,
181     mTYnaked        = 0x40000,
182     mTYMOD          = 0x78000,       // all modifier bits
183 
184     // Modifiers to basic types
185 
186     mTYarrayhandle  = 0x0,
187     mTYconst        = 0x100,
188     mTYvolatile     = 0x200,
189     mTYrestrict     = 0,             // BUG: add for C99
190     mTYmutable      = 0,             // need to add support
191     mTYunaligned    = 0,             // non-zero for PowerPC
192 
193     mTYimmutable    = 0x00080000,    // immutable data
194     mTYshared       = 0x00100000,    // shared data
195     mTYnothrow      = 0x00200000,    // nothrow function
196 
197     // SROA types
198     mTYxmmgpr       = 0x00400000,    // first slice in XMM register, the other in GPR
199     mTYgprxmm       = 0x00800000,    // first slice in GPR register, the other in XMM
200 
201     mTYnoret        = 0x01000000,    // function has no return
202     mTYtransu       = 0x01000000,    // transparent union
203     mTYfar16        = 0x01000000,
204     mTYstdcall      = 0x02000000,
205     mTYfastcall     = 0x04000000,
206     mTYinterrupt    = 0x08000000,
207     mTYcdecl        = 0x10000000,
208     mTYpascal       = 0x20000000,
209     mTYsyscall      = 0x40000000,
210     mTYjava         = 0x80000000,
211 
212     mTYTFF          = 0xFF000000,
213 }
214 
215 pure
216 tym_t tybasic(tym_t ty) { return ty & mTYbasic; }
217 
218 enum
219 {
220     TYFLptr         = 1,
221     TYFLreal        = 2,
222     TYFLintegral    = 4,
223     TYFLcomplex     = 8,
224     TYFLimaginary   = 0x10,
225     TYFLuns         = 0x20,
226     TYFLmptr        = 0x40,
227     TYFLfv          = 0x80,       // TYfptr || TYvptr
228 
229     TYFLpascal      = 0x200,      // callee cleans up stack
230     TYFLrevparam    = 0x400,      // function parameters are reversed
231     TYFLnullptr     = 0x800,
232     TYFLshort       = 0x1000,
233     TYFLaggregate   = 0x2000,
234     TYFLfunc        = 0x4000,
235     TYFLref         = 0x8000,
236     TYFLsimd        = 0x20000,    // SIMD vector type
237     TYFLfarfunc     = 0x100,      // __far functions (for segmented architectures)
238     TYFLxmmreg      = 0x10000,    // can be put in XMM register
239 }
240 
241 // Give size of type
242 @trusted
243 byte tysize(tym_t ty)      { return _tysize[ty & 0xFF]; }
244 @trusted
245 byte tyalignsize(tym_t ty) { return _tyalignsize[ty & 0xFF]; }
246 
247 
248 /* Groupings of types   */
249 
250 @trusted
251 uint tyintegral(tym_t ty) { return tytab[ty & 0xFF] & TYFLintegral; }
252 
253 @trusted
254 uint tyarithmetic(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex); }
255 
256 @trusted
257 uint tyaggregate(tym_t ty) { return tytab[ty & 0xFF] & TYFLaggregate; }
258 
259 @trusted
260 uint tyscalar(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr | TYFLref); }
261 
262 @trusted
263 uint tyfloating(tym_t ty) { return tytab[ty & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex); }
264 
265 @trusted
266 uint tyimaginary(tym_t ty) { return tytab[ty & 0xFF] & TYFLimaginary; }
267 
268 @trusted
269 uint tycomplex(tym_t ty) { return tytab[ty & 0xFF] & TYFLcomplex; }
270 
271 @trusted
272 uint tyreal(tym_t ty) { return tytab[ty & 0xFF] & TYFLreal; }
273 
274 // Fits into 64 bit register
275 @trusted
276 bool ty64reg(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLptr | TYFLref) && tysize(ty) <= _tysize[TYnptr]; }
277 
278 // Can go in XMM floating point register
279 @trusted
280 uint tyxmmreg(tym_t ty) { return tytab[ty & 0xFF] & TYFLxmmreg; }
281 
282 // Is a vector type
283 @trusted
284 bool tyvector(tym_t ty) { return tybasic(ty) >= TYfloat4 && tybasic(ty) <= TYullong4; }
285 
286 /* Types that are chars or shorts       */
287 @trusted
288 uint tyshort(tym_t ty) { return tytab[ty & 0xFF] & TYFLshort; }
289 
290 /* Detect TYlong or TYulong     */
291 @trusted
292 bool tylong(tym_t ty) { return tybasic(ty) == TYlong || tybasic(ty) == TYulong; }
293 
294 /* Use to detect a pointer type */
295 @trusted
296 uint typtr(tym_t ty) { return tytab[ty & 0xFF] & TYFLptr; }
297 
298 /* Use to detect a reference type */
299 @trusted
300 uint tyref(tym_t ty) { return tytab[ty & 0xFF] & TYFLref; }
301 
302 /* Use to detect a pointer type or a member pointer     */
303 @trusted
304 uint tymptr(tym_t ty) { return tytab[ty & 0xFF] & (TYFLptr | TYFLmptr); }
305 
306 // Use to detect a nullptr type or a member pointer
307 @trusted
308 uint tynullptr(tym_t ty) { return tytab[ty & 0xFF] & TYFLnullptr; }
309 
310 /* Detect TYfptr or TYvptr      */
311 @trusted
312 uint tyfv(tym_t ty) { return tytab[ty & 0xFF] & TYFLfv; }
313 
314 /* All data types that fit in exactly 8 bits    */
315 @trusted
316 bool tybyte(tym_t ty) { return tysize(ty) == 1; }
317 
318 /* Types that fit into a single machine register        */
319 @trusted
320 bool tyreg(tym_t ty) { return tysize(ty) <= _tysize[TYnptr]; }
321 
322 /* Detect function type */
323 @trusted
324 uint tyfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfunc; }
325 
326 /* Detect function type where parameters are pushed left to right    */
327 @trusted
328 uint tyrevfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLrevparam; }
329 
330 /* Detect uint types */
331 @trusted
332 uint tyuns(tym_t ty) { return tytab[ty & 0xFF] & (TYFLuns | TYFLptr); }
333 
334 /* Target dependent info        */
335 alias TYoffset = TYuint;         // offset to an address
336 
337 /* Detect cpp function type (callee cleans up stack)    */
338 @trusted
339 uint typfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLpascal; }
340 
341 /* Array to convert a type to its unsigned equivalent   */
342 @trusted
343 tym_t touns(tym_t ty) { return tytouns[ty & 0xFF]; }
344 
345 /* Determine if TYffunc or TYfpfunc (a far function) */
346 @trusted
347 uint tyfarfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfarfunc; }
348 
349 // Determine if parameter is a SIMD vector type
350 @trusted
351 uint tysimd(tym_t ty) { return tytab[ty & 0xFF] & TYFLsimd; }
352 
353 @trusted
354 uint tyrelax(tym_t ty) { return _tyrelax[tybasic(ty)]; }
355 
356 @trusted
357 bool I16() { return _tysize[TYnptr] == 2; }
358 @trusted
359 bool I32() { return _tysize[TYnptr] == 4; }
360 @trusted
361 bool I64() { return _tysize[TYnptr] == 8; }