int i, limit, dir;
tree type = TREE_TYPE (value);
- int words = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type)) / 32;
+ int bits = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type));
+ int words = bits / 32;
real_to_target (target_real, &TREE_REAL_CST (value),
TYPE_MODE (type));
+ if (words == 0)
+ {
+ /* _Float16 and std::bfloat16_t are the only supported types smaller than
+ 32 bits. */
+ gcc_assert (bits == 16);
+ sprintf (buffer, "%04lx", (unsigned long) target_real[0]);
+ write_chars (buffer, 4);
+ return;
+ }
+
+ gcc_assert (bits % 32 == 0);
+
/* The value in target_real is in the target word order,
so we must write it out backward if that happens to be
little-endian. write_number cannot be used, it will
--- /dev/null
+// PR c++/121801
+// { dg-do compile { target { c++20 && float16 } } }
+// { dg-add-options float16 }
+
+template<_Float16 T> void f() {}
+
+void uses() {
+ f<_Float16(1)>();
+ f<_Float16(2)>();
+}
+
+// { dg-final { scan-assembler "_Z1fILDF16_3c00EEvv" } }
+// { dg-final { scan-assembler "_Z1fILDF16_4000EEvv" } }