-int
-smaller_mode(const ir_mode *sm, const ir_mode *lm)
-{
- int sm_bits, lm_bits;
-
- ANNOUNCE();
- assert(sm);
- assert(lm);
-
- if (sm == lm) return 1;
-
- sm_bits = get_mode_size_bits(sm);
- lm_bits = get_mode_size_bits(lm);
-
- switch(get_mode_sort(sm))
- {
- case irms_int_number:
- switch(get_mode_sort(lm))
- {
- case irms_int_number:
- /* integers are convertable if
- * - both have the same sign and lm is the larger one
- * - lm is the signed one and is at least two bits larger
- * (one for the sign, one for the highest bit of sm)
- * - sm & lm are two_complement and lm has greater or equal number of bits
- */
- if ( get_mode_arithmetic(sm) == get_mode_arithmetic(lm)
- && get_mode_arithmetic(sm) == irma_twos_complement) {
- return lm_bits >= sm_bits;
- }
- else if (mode_is_signed(sm))
- {
- if ( mode_is_signed(lm) && (lm_bits >= sm_bits) )
- return 1;
- }
- else if (mode_is_signed(lm))
- {
- if (lm_bits > sm_bits + 1)
- return 1;
- }
- else if (lm_bits >= sm_bits)
- {
- return 1;
- }
- break;
-
- case irms_float_number:
- /* int to float works if the float is large enough */
- return 0;
-
- default:
- break;
- }
- break;
-
- case irms_float_number:
- if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
- if ( (get_mode_sort(lm) == irms_float_number)
- && (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
- return 1;
- }
- break;
-
- case irms_reference:
- /* do exist machines out there with different pointer lenghts ?*/
- return 0;
-
- default:
- break;
- }
-
- /* else */
- return 0;
-}
-
-/* ** initialization ** */
-void
-init_mode (void)
-{
- ir_mode newmode;
- ANNOUNCE();
- /* init flexible array */
+int smaller_mode(const ir_mode *sm, const ir_mode *lm) {
+ int sm_bits, lm_bits;
+
+ assert(sm);
+ assert(lm);
+
+ if (sm == lm) return 1;
+
+ sm_bits = get_mode_size_bits(sm);
+ lm_bits = get_mode_size_bits(lm);
+
+ switch (get_mode_sort(sm)) {
+ case irms_int_number:
+ switch (get_mode_sort(lm)) {
+ case irms_int_number:
+ if (get_mode_arithmetic(sm) != get_mode_arithmetic(lm))
+ return 0;
+
+ /* only two complement implemented */
+ assert(get_mode_arithmetic(sm) == irma_twos_complement);
+
+ /* integers are convertable if
+ * - both have the same sign and lm is the larger one
+ * - lm is the signed one and is at least two bits larger
+ * (one for the sign, one for the highest bit of sm)
+ * - sm & lm are two_complement and lm has greater or equal number of bits
+ */
+ if (mode_is_signed(sm)) {
+ if (!mode_is_signed(lm))
+ return 0;
+ return sm_bits <= lm_bits;
+ } else {
+ if (mode_is_signed(lm)) {
+ return sm_bits < lm_bits;
+ }
+ return sm_bits <= lm_bits;
+ }
+ break;
+
+ case irms_float_number:
+ /* int to float works if the float is large enough */
+ return 0;
+
+ default:
+ break;
+ }
+ break;
+
+ case irms_float_number:
+ if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
+ if ( (get_mode_sort(lm) == irms_float_number)
+ && (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
+ return 1;
+ }
+ break;
+
+ case irms_reference:
+ /* do exist machines out there with different pointer lenghts ?*/
+ return 0;
+
+ case irms_internal_boolean:
+ return mode_is_int(lm);
+
+ default:
+ break;
+ }
+
+ /* else */
+ return 0;
+}
+
+/* Returns true if a value of mode sm can be converted into mode lm
+ and backwards without loss. */
+int values_in_mode(const ir_mode *sm, const ir_mode *lm) {
+ int sm_bits, lm_bits;
+ ir_mode_arithmetic arith;
+
+ assert(sm);
+ assert(lm);
+
+ if (sm == lm) return 1;
+
+ if (sm == mode_b)
+ return mode_is_int(lm);
+
+ sm_bits = get_mode_size_bits(sm);
+ lm_bits = get_mode_size_bits(lm);
+
+ arith = get_mode_arithmetic(sm);
+ if (arith != get_mode_arithmetic(lm))
+ return 0;
+
+ switch (arith) {
+ case irma_twos_complement:
+ case irma_ieee754:
+ return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
+
+ default:
+ return 0;
+ }
+}
+
+/* Return the signed integer equivalent mode for an reference mode. */
+ir_mode *get_reference_mode_signed_eq(ir_mode *mode) {
+ assert(mode_is_reference(mode));
+ return mode->eq_signed;
+}
+
+/* Sets the signed integer equivalent mode for an reference mode. */
+void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode) {
+ assert(mode_is_reference(ref_mode));
+ assert(mode_is_int(int_mode));
+ ref_mode->eq_signed = int_mode;
+}
+
+/* Return the unsigned integer equivalent mode for an reference mode. */
+ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode) {
+ assert(mode_is_reference(mode));
+ return mode->eq_unsigned;
+}
+
+/* Sets the unsigned integer equivalent mode for an reference mode. */
+void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode) {
+ assert(mode_is_reference(ref_mode));
+ assert(mode_is_int(int_mode));
+ ref_mode->eq_unsigned = int_mode;
+}
+
+/* initialization, build the default modes */
+void init_mode(void) {
+ ir_mode newmode;
+
+ obstack_init(&modes);
+ mode_list = NEW_ARR_F(ir_mode*, 0);
+
+ num_modes = 0;
+ /* initialize predefined modes */
+
+ /* Internal Modes */
+ newmode.arithmetic = irma_none;
+ newmode.size = 0;
+ newmode.sign = 0;
+ newmode.modulo_shift = 0;
+ newmode.vector_elem = 0;
+ newmode.eq_signed = NULL;
+ newmode.eq_unsigned = NULL;
+ newmode.link = NULL;
+ newmode.tv_priv = NULL;
+
+ /* Control Flow Modes*/
+ newmode.sort = irms_control_flow;
+
+ /* Basic Block */
+ newmode.name = new_id_from_chars("BB", 2);
+ newmode.code = irm_BB;
+
+ mode_BB = register_mode(&newmode);
+
+ /* eXecution */
+ newmode.name = new_id_from_chars("X", 1);
+ newmode.code = irm_X;
+
+ mode_X = register_mode(&newmode);
+
+ /* Memory Modes */
+ newmode.sort = irms_memory;
+
+ /* Memory */
+ newmode.name = new_id_from_chars("M", 1);
+ newmode.code = irm_M;
+
+ mode_M = register_mode(&newmode);
+
+ /* Auxiliary Modes */
+ newmode.sort = irms_auxiliary,
+
+ /* Tuple */
+ newmode.name = new_id_from_chars("T", 1);
+ newmode.code = irm_T;
+
+ mode_T = register_mode(&newmode);
+
+ /* ANY */
+ newmode.name = new_id_from_chars("ANY", 3);
+ newmode.code = irm_ANY;
+
+ mode_ANY = register_mode(&newmode);
+
+ /* BAD */
+ newmode.name = new_id_from_chars("BAD", 3);
+ newmode.code = irm_BAD;