1 /**
2  * Utility subroutines
3  *
4  * Only used for DMD
5  *
6  * Compiler implementation of the
7  * $(LINK2 https://www.dlang.org, D programming language).
8  *
9  * Copyright:   Copyright (C) 1984-1998 by Symantec
10  *              Copyright (C) 2000-2023 by The D Language Foundation, All Rights Reserved
11  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
12  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
13  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/util2.d, backend/util2.d)
14  */
15 
16 module dmd.backend.util2;
17 
18 import core.stdc.stdio;
19 import core.stdc.stdlib;
20 import core.stdc.string;
21 
22 import dmd.backend.cc;
23 import dmd.backend.cdef;
24 import dmd.backend.global;
25 import dmd.backend.mem;
26 
27 
28 nothrow: @nogc:
29 @safe:
30 
31 /****************************
32  * Clean up and exit program.
33  */
34 
35 void err_exit()
36 {
37     util_exit(EXIT_FAILURE);
38 }
39 
40 /********************************
41  * Clean up and exit program.
42  */
43 
44 void err_break()
45 {
46     util_exit(255);
47 }
48 
49 
50 /****************************
51  * Clean up and exit program.
52  */
53 @trusted
54 void util_exit(int exitcode)
55 {
56     exit(exitcode);                     /* terminate abnormally         */
57 }
58 
59 /**********************************
60  * Binary string search.
61  * Input:
62  *      p .    string of characters
63  *      tab     array of pointers to strings
64  *      n =     number of pointers in the array
65  * Returns:
66  *      index (0..n-1) into tab[] if we found a string match
67  *      else -1
68  */
69 
70 version (X86) version (CRuntime_DigitalMars)
71     version = X86asm;
72 
73 @trusted
74 int binary(const(char)* p, const(char)*  *table,int high)
75 {
76 version (X86asm)
77 {
78     alias len = high;        // reuse parameter storage
79     asm nothrow
80     {
81 
82 // First find the length of the identifier.
83         xor     EAX,EAX         ; // Scan for a 0.
84         mov     EDI,p           ;
85         mov     ECX,EAX         ;
86         dec     ECX             ; // Longest possible string.
87         repne                   ;
88         scasb                   ;
89         mov     EDX,high        ; // EDX = high
90         not     ECX             ; // length of the id including '/0', stays in ECX
91         dec     EDX             ; // high--
92         js      short Lnotfound ;
93         dec     EAX             ; // EAX = -1, so that eventually EBX = low (0)
94         mov     len,ECX         ;
95 
96         even                    ;
97 L4D:    lea     EBX,[EAX + 1]   ; // low = mid + 1
98         cmp     EBX,EDX         ;
99         jg      Lnotfound       ;
100 
101         even                    ;
102 L15:    lea     EAX,[EBX + EDX] ; // EAX = low + high
103 
104 // Do the string compare.
105 
106         mov     EDI,table       ;
107         sar     EAX,1           ; // mid = (low + high) >> 1
108         mov     ESI,p           ;
109         mov     EDI,[4*EAX+EDI] ; // Load table[mid]
110         mov     ECX,len         ; // length of id
111         repe                    ;
112         cmpsb                   ;
113 
114         je      short L63       ; // return mid if equal
115         jns     short L4D       ; // if (cond < 0)
116         lea     EDX,-1[EAX]     ; // high = mid - 1
117         cmp     EBX,EDX         ;
118         jle     L15             ;
119 
120 Lnotfound:
121         mov     EAX,-1          ; // Return -1.
122 
123         even                    ;
124 L63:                            ;
125     }
126 }
127 else
128 {
129     int low = 0;
130     char cp = *p;
131     high--;
132     p++;
133 
134     while (low <= high)
135     {
136         int mid = low + ((high - low) >> 1);
137         int cond = table[mid][0] - cp;
138         if (cond == 0)
139             cond = strcmp(table[mid] + 1,p);
140         if (cond > 0)
141             high = mid - 1;
142         else if (cond < 0)
143             low = mid + 1;
144         else
145             return mid;                 /* match index                  */
146     }
147     return -1;
148 }
149 }
150 
151 
152 // search table[0 .. high] for p[0 .. len] (where p.length not necessairily equal to len)
153 @trusted
154 int binary(const(char)* p, size_t len, const(char)** table, int high)
155 {
156     int low = 0;
157     char cp = *p;
158     high--;
159     p++;
160     len--;
161 
162     while (low <= high)
163     {
164         int mid = low + ((high - low) >> 1);
165         int cond = table[mid][0] - cp;
166 
167         if (cond == 0)
168         {
169             cond = strncmp(table[mid] + 1, p, len);
170             if (cond == 0)
171                 cond = table[mid][len+1]; // same as: if (table[mid][len+1] != '\0') cond = 1;
172         }
173 
174         if (cond > 0)
175             high = mid - 1;
176         else if (cond < 0)
177             low = mid + 1;
178         else
179             return mid;                 /* match index                  */
180     }
181     return -1;
182 }
183 
184 /**********************
185  * If c is a power of 2, return that power else -1.
186  */
187 
188 int ispow2(ulong c)
189 {       int i;
190 
191         if (c == 0 || (c & (c - 1)))
192             i = -1;
193         else
194             for (i = 0; c >>= 1; i++)
195             { }
196         return i;
197 }
198 
199 /*****************************
200  */
201 void *mem_malloc2(uint size)
202 {
203     return mem_malloc(size);
204 }