xref: /netbsd-src/external/gpl3/gcc/dist/gcc/d/d-port.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
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
memicmp(const char * s1,const char * s2,d_size_t n)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 *
strupr(char * s)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
isFloat32LiteralOutOfRange(const char * buffer)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
isFloat64LiteralOutOfRange(const char * buffer)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
readwordLE(const void * buffer)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
readwordBE(const void * buffer)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
readlongLE(const void * buffer)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
readlongBE(const void * buffer)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
valcpy(void * buffer,uint64_t value,d_size_t sz)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