1 /* d-port.cc -- D frontend interface to the gcc back-end. 2 Copyright (C) 2013-2022 Free Software Foundation, Inc. 3 4 GCC is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3, or (at your option) 7 any later version. 8 9 GCC is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with GCC; see the file COPYING3. If not see 16 <http://www.gnu.org/licenses/>. */ 17 18 #include "config.h" 19 #include "system.h" 20 #include "coretypes.h" 21 22 #include "dmd/root/port.h" 23 #include "dmd/target.h" 24 25 #include "tree.h" 26 27 28 /* Implements the Port interface defined by the frontend. 29 A mini library for doing compiler/system specific things. */ 30 31 /* Compare the first N bytes of S1 and S2 without regard to the case. */ 32 33 int 34 Port::memicmp (const char *s1, const char *s2, d_size_t n) 35 { 36 int result = 0; 37 38 for (d_size_t i = 0; i < n; i++) 39 { 40 char c1 = s1[i]; 41 char c2 = s2[i]; 42 43 result = c1 - c2; 44 if (result) 45 { 46 result = TOUPPER (c1) - TOUPPER (c2); 47 if (result) 48 break; 49 } 50 } 51 52 return result; 53 } 54 55 /* Convert all characters in S to uppercase. */ 56 57 char * 58 Port::strupr (char *s) 59 { 60 char *t = s; 61 62 while (*s) 63 { 64 *s = TOUPPER (*s); 65 s++; 66 } 67 68 return t; 69 } 70 71 /* Return true if the real_t value from string BUFFER overflows 72 as a result of rounding down to float mode. */ 73 74 bool 75 Port::isFloat32LiteralOutOfRange (const char *buffer) 76 { 77 real_t r = {}; 78 79 real_from_string3 (&r.rv (), buffer, TYPE_MODE (float_type_node)); 80 81 return r == target.RealProperties.infinity; 82 } 83 84 /* Return true if the real_t value from string BUFFER overflows 85 as a result of rounding down to double mode. */ 86 87 bool 88 Port::isFloat64LiteralOutOfRange (const char *buffer) 89 { 90 real_t r = {}; 91 92 real_from_string3 (&r.rv (), buffer, TYPE_MODE (double_type_node)); 93 94 return r == target.RealProperties.infinity; 95 } 96 97 /* Fetch a little-endian 16-bit value from BUFFER. */ 98 99 unsigned 100 Port::readwordLE (const void *buffer) 101 { 102 const unsigned char *p = (const unsigned char *) buffer; 103 104 return ((unsigned) p[1] << 8) | (unsigned) p[0]; 105 } 106 107 /* Fetch a big-endian 16-bit value from BUFFER. */ 108 109 unsigned 110 Port::readwordBE (const void *buffer) 111 { 112 const unsigned char *p = (const unsigned char *) buffer; 113 114 return ((unsigned) p[0] << 8) | (unsigned) p[1]; 115 } 116 117 /* Fetch a little-endian 32-bit value from BUFFER. */ 118 119 unsigned 120 Port::readlongLE (const void *buffer) 121 { 122 const unsigned char *p = (const unsigned char *) buffer; 123 124 return (((unsigned) p[3] << 24) 125 | ((unsigned) p[2] << 16) 126 | ((unsigned) p[1] << 8) 127 | (unsigned) p[0]); 128 } 129 130 /* Fetch a big-endian 32-bit value from BUFFER. */ 131 132 unsigned 133 Port::readlongBE (const void *buffer) 134 { 135 const unsigned char *p = (const unsigned char *) buffer; 136 137 return (((unsigned) p[0] << 24) 138 | ((unsigned) p[1] << 16) 139 | ((unsigned) p[2] << 8) 140 | (unsigned) p[3]); 141 } 142 143 /* Write an SZ-byte sized VALUE to BUFFER, ignoring endian-ness. */ 144 145 void 146 Port::valcpy (void *buffer, uint64_t value, d_size_t sz) 147 { 148 gcc_assert (((d_size_t) buffer) % sz == 0); 149 150 switch (sz) 151 { 152 case 1: 153 *(uint8_t *) buffer = (uint8_t) value; 154 break; 155 156 case 2: 157 *(uint16_t *) buffer = (uint16_t) value; 158 break; 159 160 case 4: 161 *(uint32_t *) buffer = (uint32_t) value; 162 break; 163 164 case 8: 165 *(uint64_t *) buffer = (uint64_t) value; 166 break; 167 168 default: 169 gcc_unreachable (); 170 } 171 } 172