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 }