Home | History | Annotate | Line # | Download | only in d
      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