/* d-port.cc -- D frontend interface to the gcc back-end. Copyright (C) 2013-2023 Free Software Foundation, Inc. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "config.h" #include "system.h" #include "coretypes.h" #include "dmd/root/port.h" #include "dmd/target.h" #include "tree.h" /* Implements the Port interface defined by the frontend. A mini library for doing compiler/system specific things. */ /* Compare the first N bytes of S1 and S2 without regard to the case. */ int Port::memicmp (const char *s1, const char *s2, d_size_t n) { int result = 0; for (d_size_t i = 0; i < n; i++) { char c1 = s1[i]; char c2 = s2[i]; result = c1 - c2; if (result) { result = TOUPPER (c1) - TOUPPER (c2); if (result) break; } } return result; } /* Convert all characters in S to uppercase. */ char * Port::strupr (char *s) { char *t = s; while (*s) { *s = TOUPPER (*s); s++; } return t; } /* Return true if the real_t value from string BUFFER overflows as a result of rounding down to float mode. */ bool Port::isFloat32LiteralOutOfRange (const char *buffer) { real_t r; real_from_string3 (&r.rv (), buffer, TYPE_MODE (float_type_node)); return r == target.RealProperties.infinity; } /* Return true if the real_t value from string BUFFER overflows as a result of rounding down to double mode. */ bool Port::isFloat64LiteralOutOfRange (const char *buffer) { real_t r; real_from_string3 (&r.rv (), buffer, TYPE_MODE (double_type_node)); return r == target.RealProperties.infinity; } /* Fetch a little-endian 16-bit value from BUFFER. */ unsigned Port::readwordLE (const void *buffer) { const unsigned char *p = (const unsigned char *) buffer; return ((unsigned) p[1] << 8) | (unsigned) p[0]; } /* Fetch a big-endian 16-bit value from BUFFER. */ unsigned Port::readwordBE (const void *buffer) { const unsigned char *p = (const unsigned char *) buffer; return ((unsigned) p[0] << 8) | (unsigned) p[1]; } /* Fetch a little-endian 32-bit value from BUFFER. */ unsigned Port::readlongLE (const void *buffer) { const unsigned char *p = (const unsigned char *) buffer; return (((unsigned) p[3] << 24) | ((unsigned) p[2] << 16) | ((unsigned) p[1] << 8) | (unsigned) p[0]); } /* Fetch a big-endian 32-bit value from BUFFER. */ unsigned Port::readlongBE (const void *buffer) { const unsigned char *p = (const unsigned char *) buffer; return (((unsigned) p[0] << 24) | ((unsigned) p[1] << 16) | ((unsigned) p[2] << 8) | (unsigned) p[3]); } /* Write an SZ-byte sized VALUE to BUFFER, ignoring endian-ness. */ void Port::valcpy (void *buffer, uint64_t value, d_size_t sz) { gcc_assert (((d_size_t) buffer) % sz == 0); switch (sz) { case 1: *(uint8_t *) buffer = (uint8_t) value; break; case 2: *(uint16_t *) buffer = (uint16_t) value; break; case 4: *(uint32_t *) buffer = (uint32_t) value; break; case 8: *(uint64_t *) buffer = (uint64_t) value; break; default: gcc_unreachable (); } }