- /* unsigned short integer */
- newmode.name = id_from_str("Hu", 2);
- newmode.code = irm_Hu;
- newmode.sign = 0;
- newmode.align = 2;
- newmode.size = 16;
-
- mode_Hu = register_mode(&newmode);
-
- /* signed integer */
- newmode.name = id_from_str("Is", 2);
- newmode.code = irm_Is;
- newmode.sign = 1;
- newmode.align = 4;
- newmode.size = 32;
-
- mode_Is = register_mode(&newmode);
-
- /* unsigned integer */
- newmode.name = id_from_str("Iu", 2);
- newmode.code = irm_Iu;
- newmode.sign = 0;
- newmode.align = 4;
- newmode.size = 32;
-
- mode_Iu = register_mode(&newmode);
-
- /* signed long integer */
- newmode.name = id_from_str("Ls", 2);
- newmode.code = irm_Ls;
- newmode.sign = 1;
- newmode.align = 4;
- newmode.size = 64;
-
- mode_Ls = register_mode(&newmode);
-
- /* unsigned long integer */
- newmode.name = id_from_str("Lu", 2);
- newmode.code = irm_Lu;
- newmode.sign = 0;
- newmode.align = 4;
- newmode.size = 64;
-
- mode_Lu = register_mode(&newmode);
-
- /* Character Modes */
- newmode.sort = irms_character;
- newmode.arithmetic = irma_none;
-
- /* Character */
- newmode.name = id_from_str("C", 1);
- newmode.code = irm_C;
- newmode.sign = 0;
- newmode.align = 1;
- newmode.size = 8;
-
- mode_C = register_mode(&newmode);
-
- /* Unicode character */
- newmode.name = id_from_str("U", 1);
- newmode.code = irm_U;
- newmode.sign = 0;
- newmode.align = 2;
- newmode.size = 16;
-
- mode_U = register_mode(&newmode);
-
- /* Reference Modes */
- newmode.sort = irms_reference;
- newmode.arithmetic = irma_twos_complement;
-
- /* pointer */
- newmode.name = id_from_str("P", 1);
- newmode.code = irm_P;
- newmode.sign = 0;
- newmode.align = 4;
- newmode.size = 32;
-
- mode_P = register_mode(&newmode);
-
- /* set the machine specific modes to the predifined ones */
- mode_P_mach = mode_P;
+ /* signed integer */
+ newmode.name = new_id_from_chars("Is", 2);
+ newmode.code = irm_Is;
+ newmode.sign = 1;
+ newmode.size = 32;
+ newmode.modulo_shift = 32;
+
+ mode_Is = register_mode(&newmode);
+
+ /* unsigned integer */
+ newmode.name = new_id_from_chars("Iu", 2);
+ newmode.code = irm_Iu;
+ newmode.sign = 0;
+ newmode.size = 32;
+ newmode.modulo_shift = 32;
+
+ mode_Iu = register_mode(&newmode);
+
+ /* signed long integer */
+ newmode.name = new_id_from_chars("Ls", 2);
+ newmode.code = irm_Ls;
+ newmode.sign = 1;
+ newmode.size = 64;
+ newmode.modulo_shift = 64;
+
+ mode_Ls = register_mode(&newmode);
+
+ /* unsigned long integer */
+ newmode.name = new_id_from_chars("Lu", 2);
+ newmode.code = irm_Lu;
+ newmode.sign = 0;
+ newmode.size = 64;
+ newmode.modulo_shift = 64;
+
+ mode_Lu = register_mode(&newmode);
+
+ /* signed long long integer */
+ newmode.name = new_id_from_chars("LLs", 3);
+ newmode.code = irm_LLs;
+ newmode.sign = 1;
+ newmode.size = 128;
+ newmode.modulo_shift = 128;
+
+ mode_LLs = register_mode(&newmode);
+
+ /* unsigned long long integer */
+ newmode.name = new_id_from_chars("LLu", 3);
+ newmode.code = irm_LLu;
+ newmode.sign = 0;
+ newmode.size = 128;
+ newmode.modulo_shift = 128;
+
+ mode_LLu = register_mode(&newmode);
+
+ /* Reference Mode */
+ newmode.sort = irms_reference;
+ newmode.arithmetic = irma_twos_complement;
+
+ /* pointer */
+ newmode.name = new_id_from_chars("P", 1);
+ newmode.code = irm_P;
+ newmode.sign = 0;
+ newmode.size = 32;
+ newmode.modulo_shift = 0;
+ newmode.eq_signed = mode_Is;
+ newmode.eq_unsigned = mode_Iu;
+
+ mode_P = register_mode(&newmode);
+
+ /* set the machine specific modes to the predefined ones */
+ mode_P_code = mode_P;
+ mode_P_data = mode_P;
+}
+
+/* find a signed mode for an unsigned integer mode */
+ir_mode *find_unsigned_mode(const ir_mode *mode) {
+ ir_mode n = *mode;
+
+ /* allowed for reference mode */
+ if (mode->sort == irms_reference)
+ n.sort = irms_int_number;
+
+ assert(n.sort == irms_int_number);
+ n.sign = 0;
+ return find_mode(&n);
+}
+
+/* find an unsigned mode for a signed integer mode */
+ir_mode *find_signed_mode(const ir_mode *mode) {
+ ir_mode n = *mode;
+
+ assert(mode->sort == irms_int_number);
+ n.sign = 1;
+ return find_mode(&n);
+}
+
+/* finds a integer mode with 2*n bits for an integer mode with n bits. */
+ir_mode *find_double_bits_int_mode(const ir_mode *mode) {
+ ir_mode n = *mode;
+
+ assert(mode->sort == irms_int_number && mode->arithmetic == irma_twos_complement);
+
+ n.size = 2*mode->size;
+ return find_mode(&n);
+}
+
+/*
+ * Returns non-zero if the given mode honors signed zero's, i.e.,
+ * a +0 and a -0 exists and handled differently.
+ */
+int mode_honor_signed_zeros(const ir_mode *mode) {
+ /* for floating point, we know that IEEE 754 has +0 and -0,
+ * but always handles it identical.
+ */
+ return
+ mode->sort == irms_float_number &&
+ mode->arithmetic != irma_ieee754;
+}
+
+/*
+ * Returns non-zero if the given mode might overflow on unary Minus.
+ *
+ * This does NOT happen on IEEE 754.
+ */
+int mode_overflow_on_unary_Minus(const ir_mode *mode) {
+ if (mode->sort == irms_float_number)
+ return mode->arithmetic == irma_ieee754 ? 0 : 1;
+ return 1;
+}
+
+/*
+ * Returns non-zero if the mode has a reversed wrap-around
+ * logic, especially (a + x) - x == a.
+ *
+ * This is normally true for integer modes, not for floating
+ * point modes.
+ */
+int mode_wrap_around(const ir_mode *mode) {
+ /* FIXME: better would be an extra mode property */
+ return mode_is_int(mode);
+}
+
+void finish_mode(void) {
+ obstack_free(&modes, 0);
+ DEL_ARR_F(mode_list);
+
+ mode_T = NULL;
+ mode_X = NULL;
+ mode_M = NULL;
+ mode_BB = NULL;
+ mode_ANY = NULL;
+ mode_BAD = NULL;
+
+ mode_F = NULL;
+ mode_D = NULL;
+ mode_E = NULL;
+
+ mode_Bs = NULL;
+ mode_Bu = NULL;
+ mode_Hs = NULL;
+ mode_Hu = NULL;
+ mode_Is = NULL;
+ mode_Iu = NULL;
+ mode_Ls = NULL;
+ mode_Lu = NULL;
+
+ mode_b = NULL;
+
+ mode_P = NULL;
+ mode_P_code = NULL;
+ mode_P_data = NULL;