+/**
+ * Create a float type for the given mode and cache it.
+ *
+ * @param mode the mode for the float type (might be integer mode for SSE2 types)
+ * @param align alignment
+ */
+static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align) {
+ char buf[32];
+ ir_type *tp;
+
+ assert(align <= 16);
+
+ if (mode == mode_Iu) {
+ static ir_type *int_Iu[16] = {NULL, };
+
+ if (int_Iu[align] == NULL) {
+ snprintf(buf, sizeof(buf), "int_Iu_%u", align);
+ int_Iu[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
+ /* set the specified alignment */
+ set_type_alignment_bytes(tp, align);
+ }
+ return int_Iu[align];
+ } else if (mode == mode_Lu) {
+ static ir_type *int_Lu[16] = {NULL, };
+
+ if (int_Lu[align] == NULL) {
+ snprintf(buf, sizeof(buf), "int_Lu_%u", align);
+ int_Lu[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
+ /* set the specified alignment */
+ set_type_alignment_bytes(tp, align);
+ }
+ return int_Lu[align];
+ } else if (mode == mode_F) {
+ static ir_type *float_F[16] = {NULL, };
+
+ if (float_F[align] == NULL) {
+ snprintf(buf, sizeof(buf), "float_F_%u", align);
+ float_F[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
+ /* set the specified alignment */
+ set_type_alignment_bytes(tp, align);
+ }
+ return float_F[align];
+ } else if (mode == mode_D) {
+ static ir_type *float_D[16] = {NULL, };
+
+ if (float_D[align] == NULL) {
+ snprintf(buf, sizeof(buf), "float_D_%u", align);
+ float_D[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
+ /* set the specified alignment */
+ set_type_alignment_bytes(tp, align);
+ }
+ return float_D[align];
+ } else {
+ static ir_type *float_E[16] = {NULL, };
+
+ if (float_E[align] == NULL) {
+ snprintf(buf, sizeof(buf), "float_E_%u", align);
+ float_E[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
+ /* set the specified alignment */
+ set_type_alignment_bytes(tp, align);
+ }
+ return float_E[align];
+ }
+}
+
+/**
+ * Create a float[2] array type for the given atomic type.
+ *
+ * @param tp the atomic type
+ */
+static ir_type *ia32_create_float_array(ir_type *tp) {
+ char buf[32];
+ ir_mode *mode = get_type_mode(tp);
+ unsigned align = get_type_alignment_bytes(tp);
+ ir_type *arr;
+
+ assert(align <= 16);
+
+ if (mode == mode_F) {
+ static ir_type *float_F[16] = {NULL, };
+
+ if (float_F[align] != NULL)
+ return float_F[align];
+ snprintf(buf, sizeof(buf), "arr_float_F_%u", align);
+ arr = float_F[align] = new_type_array(new_id_from_str(buf), 1, tp);
+ } else if (mode == mode_D) {
+ static ir_type *float_D[16] = {NULL, };
+
+ if (float_D[align] != NULL)
+ return float_D[align];
+ snprintf(buf, sizeof(buf), "arr_float_D_%u", align);
+ arr = float_D[align] = new_type_array(new_id_from_str(buf), 1, tp);
+ } else {
+ static ir_type *float_E[16] = {NULL, };
+
+ if (float_E[align] != NULL)
+ return float_E[align];
+ snprintf(buf, sizeof(buf), "arr_float_E_%u", align);
+ arr = float_E[align] = new_type_array(new_id_from_str(buf), 1, tp);
+ }
+ set_type_alignment_bytes(arr, align);
+ set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
+ set_type_state(arr, layout_fixed);
+ return arr;
+}
+