# Language-specific object files for D.
D_OBJS = \
- d/d-attribs.o d/d-builtins.o d/d-codegen.o d/d-convert.o \
- d/d-diagnostic.o d/d-frontend.o d/d-incpath.o d/d-lang.o \
- d/d-longdouble.o d/d-target.o d/decl.o d/expr.o d/imports.o \
- d/intrinsics.o d/modules.o d/runtime.o d/toir.o d/typeinfo.o d/types.o
+ d/d-attribs.o \
+ d/d-builtins.o \
+ d/d-codegen.o \
+ d/d-compiler.o \
+ d/d-convert.o \
+ d/d-ctfloat.o \
+ d/d-diagnostic.o \
+ d/d-frontend.o \
+ d/d-incpath.o \
+ d/d-lang.o \
+ d/d-longdouble.o \
+ d/d-port.o \
+ d/d-target.o \
+ d/decl.o \
+ d/expr.o \
+ d/imports.o \
+ d/intrinsics.o \
+ d/modules.o \
+ d/runtime.o \
+ d/toir.o \
+ d/typeinfo.o \
+ d/types.o
# All language-specific object files for D.
D_ALL_OBJS = $(D_FRONTEND_OBJS) $(D_GENERATED_OBJS) $(D_OBJS) $(D_TARGET_OBJS)
--- /dev/null
+/* d-compiler.cc -- D frontend interface to the gcc back-end.
+ Copyright (C) 2020 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
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+
+#include "dmd/compiler.h"
+#include "dmd/scope.h"
+#include "dmd/expression.h"
+#include "dmd/identifier.h"
+#include "dmd/module.h"
+#include "dmd/mtype.h"
+
+#include "tree.h"
+#include "fold-const.h"
+
+#include "d-tree.h"
+
+
+/* Implements the Compiler interface used by the frontend. */
+
+/* Generate C main() in response to seeing D main(). This used to be in
+ libdruntime, but contained a reference to _Dmain which didn't work when
+ druntime was made into a shared library and was linked to a program, such
+ as a C++ program, that didn't have a _Dmain. */
+
+void
+Compiler::genCmain (Scope *sc)
+{
+ static bool initialized = false;
+
+ if (initialized)
+ return;
+
+ /* The D code to be generated is provided by __entrypoint.di, try to load it,
+ but don't fail if unfound. */
+ unsigned errors = global.startGagging ();
+ Module *m = Module::load (Loc (), NULL, Identifier::idPool ("__entrypoint"));
+
+ if (global.endGagging (errors))
+ m = NULL;
+
+ if (m != NULL)
+ {
+ m->importedFrom = m;
+ m->importAll (NULL);
+ m->semantic (NULL);
+ m->semantic2 (NULL);
+ m->semantic3 (NULL);
+ d_add_entrypoint_module (m, sc->_module);
+ }
+
+ initialized = true;
+}
+
+/* Perform a reinterpret cast of EXPR to type TYPE for use in CTFE.
+ The front end should have already ensured that EXPR is a constant,
+ so we just lower the value to GCC and return the converted CST. */
+
+Expression *
+Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
+{
+ /* We support up to 512-bit values. */
+ unsigned char buffer[64];
+ tree cst;
+
+ Type *tb = type->toBasetype ();
+
+ if (expr->type->isintegral ())
+ cst = build_integer_cst (expr->toInteger (), build_ctype (expr->type));
+ else if (expr->type->isfloating ())
+ cst = build_float_cst (expr->toReal (), expr->type);
+ else if (expr->op == TOKarrayliteral)
+ {
+ /* Build array as VECTOR_CST, assumes EXPR is constant. */
+ Expressions *elements = ((ArrayLiteralExp *) expr)->elements;
+ vec<constructor_elt, va_gc> *elms = NULL;
+
+ vec_safe_reserve (elms, elements->dim);
+ for (size_t i = 0; i < elements->dim; i++)
+ {
+ Expression *e = (*elements)[i];
+ if (e->type->isintegral ())
+ {
+ tree value = build_integer_cst (e->toInteger (),
+ build_ctype (e->type));
+ CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
+ }
+ else if (e->type->isfloating ())
+ {
+ tree value = build_float_cst (e->toReal (), e->type);
+ CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
+ }
+ else
+ gcc_unreachable ();
+ }
+
+ /* Build vector type. */
+ int nunits = ((TypeSArray *) expr->type)->dim->toUInteger ();
+ Type *telem = expr->type->nextOf ();
+ tree vectype = build_vector_type (build_ctype (telem), nunits);
+
+ cst = build_vector_from_ctor (vectype, elms);
+ }
+ else
+ gcc_unreachable ();
+
+ /* Encode CST to buffer. */
+ int len = native_encode_expr (cst, buffer, sizeof (buffer));
+
+ if (tb->ty == Tsarray)
+ {
+ /* Interpret value as a vector of the same size,
+ then return the array literal. */
+ int nunits = ((TypeSArray *) type)->dim->toUInteger ();
+ Type *elem = type->nextOf ();
+ tree vectype = build_vector_type (build_ctype (elem), nunits);
+
+ cst = native_interpret_expr (vectype, buffer, len);
+
+ Expression *e = d_eval_constant_expression (cst);
+ gcc_assert (e != NULL && e->op == TOKvector);
+
+ return ((VectorExp *) e)->e1;
+ }
+ else
+ {
+ /* Normal interpret cast. */
+ cst = native_interpret_expr (build_ctype (type), buffer, len);
+
+ Expression *e = d_eval_constant_expression (cst);
+ gcc_assert (e != NULL);
+
+ return e;
+ }
+}
+
+/* Check imported module M for any special processing.
+ Modules we look out for are:
+ - object: For D runtime type information.
+ - gcc.builtins: For all gcc builtins.
+ - core.stdc.*: For all gcc library builtins. */
+
+void
+Compiler::loadModule (Module *m)
+{
+ ModuleDeclaration *md = m->md;
+
+ if (!md || !md->id || !md->packages)
+ {
+ Identifier *id = (md && md->id) ? md->id : m->ident;
+ if (!strcmp (id->toChars (), "object"))
+ create_tinfo_types (m);
+ }
+ else if (md->packages->dim == 1)
+ {
+ if (!strcmp ((*md->packages)[0]->toChars (), "gcc")
+ && !strcmp (md->id->toChars (), "builtins"))
+ d_build_builtins_module (m);
+ }
+ else if (md->packages->dim == 2)
+ {
+ if (!strcmp ((*md->packages)[0]->toChars (), "core")
+ && !strcmp ((*md->packages)[1]->toChars (), "stdc"))
+ d_add_builtin_module (m);
+ }
+}
--- /dev/null
+/* d-ctfloat.cc -- D frontend interface to the gcc back-end.
+ Copyright (C) 2020 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
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+
+#include "dmd/root/ctfloat.h"
+#include "dmd/target.h"
+
+#include "tree.h"
+
+
+/* Implements the CTFloat interface defined by the frontend.
+ Compile-time floating-pointer helper functions. */
+
+/* Return the absolute value of R. */
+
+real_t
+CTFloat::fabs (real_t r)
+{
+ real_t x;
+ real_arithmetic (&x.rv (), ABS_EXPR, &r.rv (), NULL);
+ return x.normalize ();
+}
+
+/* Return the value of R * 2 ^^ EXP. */
+
+real_t
+CTFloat::ldexp (real_t r, int exp)
+{
+ real_t x;
+ real_ldexp (&x.rv (), &r.rv (), exp);
+ return x.normalize ();
+}
+
+/* Return true if longdouble value X is identical to Y. */
+
+bool
+CTFloat::isIdentical (real_t x, real_t y)
+{
+ real_value rx = x.rv ();
+ real_value ry = y.rv ();
+ return (REAL_VALUE_ISNAN (rx) && REAL_VALUE_ISNAN (ry))
+ || real_identical (&rx, &ry);
+}
+
+/* Return true if real_t value R is NaN. */
+
+bool
+CTFloat::isNaN (real_t r)
+{
+ return REAL_VALUE_ISNAN (r.rv ());
+}
+
+/* Same as isNaN, but also check if is signalling. */
+
+bool
+CTFloat::isSNaN (real_t r)
+{
+ return REAL_VALUE_ISSIGNALING_NAN (r.rv ());
+}
+
+/* Return true if real_t value is +Inf. */
+
+bool
+CTFloat::isInfinity (real_t r)
+{
+ return REAL_VALUE_ISINF (r.rv ());
+}
+
+/* Return a real_t value from string BUFFER rounded to long double mode. */
+
+real_t
+CTFloat::parse (const char *buffer, bool *overflow)
+{
+ real_t r;
+ real_from_string3 (&r.rv (), buffer, TYPE_MODE (long_double_type_node));
+
+ /* Front-end checks overflow to see if the value is representable. */
+ if (overflow && r == Target::RealProperties::infinity)
+ *overflow = true;
+
+ return r;
+}
+
+/* Format the real_t value R to string BUFFER as a decimal or hexadecimal,
+ converting the result to uppercase if FMT requests it. */
+
+int
+CTFloat::sprint (char *buffer, char fmt, real_t r)
+{
+ if (fmt == 'a' || fmt == 'A')
+ {
+ /* Converting to a hexadecimal string. */
+ real_to_hexadecimal (buffer, &r.rv (), 32, 0, 1);
+ int buflen;
+
+ switch (fmt)
+ {
+ case 'A':
+ buflen = strlen (buffer);
+ for (int i = 0; i < buflen; i++)
+ buffer[i] = TOUPPER (buffer[i]);
+
+ return buflen;
+
+ case 'a':
+ return strlen (buffer);
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ {
+ /* Note: restricting the precision of significant digits to 18. */
+ real_to_decimal (buffer, &r.rv (), 32, 18, 1);
+ return strlen (buffer);
+ }
+}
+
+/* Return a hash value for real_t value R. */
+
+size_t
+CTFloat::hash (real_t r)
+{
+ return real_hash (&r.rv ());
+}
#include "coretypes.h"
#include "dmd/aggregate.h"
-#include "dmd/compiler.h"
#include "dmd/declaration.h"
-#include "dmd/errors.h"
#include "dmd/expression.h"
-#include "dmd/identifier.h"
#include "dmd/module.h"
#include "dmd/mtype.h"
#include "dmd/scope.h"
-#include "dmd/statement.h"
-#include "dmd/target.h"
#include "tree.h"
#include "options.h"
#include "fold-const.h"
#include "diagnostic.h"
-#include "stor-layout.h"
#include "d-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, size_t n)
-{
- int result = 0;
-
- for (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 (void *buffer)
-{
- unsigned char *p = (unsigned char*) buffer;
-
- return ((unsigned) p[1] << 8) | (unsigned) p[0];
-}
-
-/* Fetch a big-endian 16-bit value from BUFFER. */
-
-unsigned
-Port::readwordBE (void *buffer)
-{
- unsigned char *p = (unsigned char*) buffer;
-
- return ((unsigned) p[0] << 8) | (unsigned) p[1];
-}
-
-/* Fetch a little-endian 32-bit value from BUFFER. */
-
-unsigned
-Port::readlongLE (void *buffer)
-{
- unsigned char *p = (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 (void *buffer)
-{
- unsigned char *p = (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, size_t sz)
-{
- 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 ();
- }
-}
-
-
-/* Implements the CTFloat interface defined by the frontend.
- Compile-time floating-pointer helper functions. */
-
-/* Return the absolute value of R. */
-
-real_t
-CTFloat::fabs (real_t r)
-{
- real_t x;
- real_arithmetic (&x.rv (), ABS_EXPR, &r.rv (), NULL);
- return x.normalize ();
-}
-
-/* Return the value of R * 2 ^^ EXP. */
-
-real_t
-CTFloat::ldexp (real_t r, int exp)
-{
- real_t x;
- real_ldexp (&x.rv (), &r.rv (), exp);
- return x.normalize ();
-}
-
-/* Return true if longdouble value X is identical to Y. */
-
-bool
-CTFloat::isIdentical (real_t x, real_t y)
-{
- real_value rx = x.rv ();
- real_value ry = y.rv ();
- return (REAL_VALUE_ISNAN (rx) && REAL_VALUE_ISNAN (ry))
- || real_identical (&rx, &ry);
-}
-
-/* Return true if real_t value R is NaN. */
-
-bool
-CTFloat::isNaN (real_t r)
-{
- return REAL_VALUE_ISNAN (r.rv ());
-}
-
-/* Same as isNaN, but also check if is signalling. */
-
-bool
-CTFloat::isSNaN (real_t r)
-{
- return REAL_VALUE_ISSIGNALING_NAN (r.rv ());
-}
-
-/* Return true if real_t value is +Inf. */
-
-bool
-CTFloat::isInfinity (real_t r)
-{
- return REAL_VALUE_ISINF (r.rv ());
-}
-
-/* Return a real_t value from string BUFFER rounded to long double mode. */
-
-real_t
-CTFloat::parse (const char *buffer, bool *overflow)
-{
- real_t r;
- real_from_string3 (&r.rv (), buffer, TYPE_MODE (long_double_type_node));
-
- /* Front-end checks overflow to see if the value is representable. */
- if (overflow && r == Target::RealProperties::infinity)
- *overflow = true;
-
- return r;
-}
-
-/* Format the real_t value R to string BUFFER as a decimal or hexadecimal,
- converting the result to uppercase if FMT requests it. */
-
-int
-CTFloat::sprint (char *buffer, char fmt, real_t r)
-{
- if (fmt == 'a' || fmt == 'A')
- {
- /* Converting to a hexadecimal string. */
- real_to_hexadecimal (buffer, &r.rv (), 32, 0, 1);
- int buflen;
-
- switch (fmt)
- {
- case 'A':
- buflen = strlen (buffer);
- for (int i = 0; i < buflen; i++)
- buffer[i] = TOUPPER (buffer[i]);
-
- return buflen;
-
- case 'a':
- return strlen (buffer);
-
- default:
- gcc_unreachable ();
- }
- }
- else
- {
- /* Note: restricting the precision of significant digits to 18. */
- real_to_decimal (buffer, &r.rv (), 32, 18, 1);
- return strlen (buffer);
- }
-}
-
-/* Return a hash value for real_t value R. */
-
-size_t
-CTFloat::hash (real_t r)
-{
- return real_hash (&r.rv ());
-}
-
-/* Implements the Compiler interface used by the frontend. */
-
-/* Generate C main() in response to seeing D main(). This used to be in
- libdruntime, but contained a reference to _Dmain which didn't work when
- druntime was made into a shared library and was linked to a program, such
- as a C++ program, that didn't have a _Dmain. */
-
-void
-Compiler::genCmain (Scope *sc)
-{
- static bool initialized = false;
-
- if (initialized)
- return;
-
- /* The D code to be generated is provided by __entrypoint.di, try to load it,
- but don't fail if unfound. */
- unsigned errors = global.startGagging ();
- Module *m = Module::load (Loc (), NULL, Identifier::idPool ("__entrypoint"));
-
- if (global.endGagging (errors))
- m = NULL;
-
- if (m != NULL)
- {
- m->importedFrom = m;
- m->importAll (NULL);
- m->semantic (NULL);
- m->semantic2 (NULL);
- m->semantic3 (NULL);
- d_add_entrypoint_module (m, sc->_module);
- }
-
- initialized = true;
-}
-
-/* Perform a reinterpret cast of EXPR to type TYPE for use in CTFE.
- The front end should have already ensured that EXPR is a constant,
- so we just lower the value to GCC and return the converted CST. */
-
-Expression *
-Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
-{
- /* We support up to 512-bit values. */
- unsigned char buffer[64];
- tree cst;
-
- Type *tb = type->toBasetype ();
-
- if (expr->type->isintegral ())
- cst = build_integer_cst (expr->toInteger (), build_ctype (expr->type));
- else if (expr->type->isfloating ())
- cst = build_float_cst (expr->toReal (), expr->type);
- else if (expr->op == TOKarrayliteral)
- {
- /* Build array as VECTOR_CST, assumes EXPR is constant. */
- Expressions *elements = ((ArrayLiteralExp *) expr)->elements;
- vec<constructor_elt, va_gc> *elms = NULL;
-
- vec_safe_reserve (elms, elements->dim);
- for (size_t i = 0; i < elements->dim; i++)
- {
- Expression *e = (*elements)[i];
- if (e->type->isintegral ())
- {
- tree value = build_integer_cst (e->toInteger (),
- build_ctype (e->type));
- CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
- }
- else if (e->type->isfloating ())
- {
- tree value = build_float_cst (e->toReal (), e->type);
- CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
- }
- else
- gcc_unreachable ();
- }
-
- /* Build vector type. */
- int nunits = ((TypeSArray *) expr->type)->dim->toUInteger ();
- Type *telem = expr->type->nextOf ();
- tree vectype = build_vector_type (build_ctype (telem), nunits);
-
- cst = build_vector_from_ctor (vectype, elms);
- }
- else
- gcc_unreachable ();
-
- /* Encode CST to buffer. */
- int len = native_encode_expr (cst, buffer, sizeof (buffer));
-
- if (tb->ty == Tsarray)
- {
- /* Interpret value as a vector of the same size,
- then return the array literal. */
- int nunits = ((TypeSArray *) type)->dim->toUInteger ();
- Type *elem = type->nextOf ();
- tree vectype = build_vector_type (build_ctype (elem), nunits);
-
- cst = native_interpret_expr (vectype, buffer, len);
-
- Expression *e = d_eval_constant_expression (cst);
- gcc_assert (e != NULL && e->op == TOKvector);
-
- return ((VectorExp *) e)->e1;
- }
- else
- {
- /* Normal interpret cast. */
- cst = native_interpret_expr (build_ctype (type), buffer, len);
-
- Expression *e = d_eval_constant_expression (cst);
- gcc_assert (e != NULL);
-
- return e;
- }
-}
-
-/* Check imported module M for any special processing.
- Modules we look out for are:
- - object: For D runtime type information.
- - gcc.builtins: For all gcc builtins.
- - core.stdc.*: For all gcc library builtins. */
-
-void
-Compiler::loadModule (Module *m)
-{
- ModuleDeclaration *md = m->md;
-
- if (!md || !md->id || !md->packages)
- {
- Identifier *id = (md && md->id) ? md->id : m->ident;
- if (!strcmp (id->toChars (), "object"))
- create_tinfo_types (m);
- }
- else if (md->packages->dim == 1)
- {
- if (!strcmp ((*md->packages)[0]->toChars (), "gcc")
- && !strcmp (md->id->toChars (), "builtins"))
- d_build_builtins_module (m);
- }
- else if (md->packages->dim == 2)
- {
- if (!strcmp ((*md->packages)[0]->toChars (), "core")
- && !strcmp ((*md->packages)[1]->toChars (), "stdc"))
- d_add_builtin_module (m);
- }
-}
-
/* Implements back-end specific interfaces used by the frontend. */
/* Determine return style of function - whether in registers or through a
--- /dev/null
+/* d-port.cc -- D frontend interface to the gcc back-end.
+ Copyright (C) 2013-2020 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
+<http://www.gnu.org/licenses/>. */
+
+#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, size_t n)
+{
+ int result = 0;
+
+ for (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 (void *buffer)
+{
+ unsigned char *p = (unsigned char*) buffer;
+
+ return ((unsigned) p[1] << 8) | (unsigned) p[0];
+}
+
+/* Fetch a big-endian 16-bit value from BUFFER. */
+
+unsigned
+Port::readwordBE (void *buffer)
+{
+ unsigned char *p = (unsigned char*) buffer;
+
+ return ((unsigned) p[0] << 8) | (unsigned) p[1];
+}
+
+/* Fetch a little-endian 32-bit value from BUFFER. */
+
+unsigned
+Port::readlongLE (void *buffer)
+{
+ unsigned char *p = (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 (void *buffer)
+{
+ unsigned char *p = (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, size_t sz)
+{
+ 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 ();
+ }
+}