let backends specify the complete long double type
authorMatthias Braun <matze@braunis.de>
Tue, 9 Aug 2011 08:48:13 +0000 (10:48 +0200)
committerMatthias Braun <matze@braunis.de>
Wed, 10 Aug 2011 07:58:35 +0000 (09:58 +0200)
include/libfirm/be.h
ir/be/TEMPLATE/TEMPLATE_transform.c
ir/be/TEMPLATE/bearch_TEMPLATE.c
ir/be/amd64/bearch_amd64.c
ir/be/arm/arm_transform.c
ir/be/arm/bearch_arm.c
ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_transform.c
ir/be/sparc/bearch_sparc.c
ir/be/sparc/sparc_transform.c

index 1131763..77c952e 100644 (file)
@@ -71,6 +71,16 @@ typedef struct backend_params {
        unsigned support_rotl:1;
        /** the backend uses big-endian byte ordering if set, else little endian */
        unsigned byte_order_big_endian:1;
+       /** whether the architecure can natively handle modulo shift modes.
+        * If this is true, then you can assume that shifting in modes with
+        * module_shift==machine_size (if mode size is <= machine_size) is efficient
+        */
+       unsigned modulo_shift_efficient:1;
+       /** whether the architecure can natively handle modulo shift modes.
+        * If this is true, then you can assume that shifting without modulo shift
+        * is efficient
+        */
+       unsigned non_modulo_shift_efficient:1;
 
        /** Settings for architecture dependent optimizations. */
        const ir_settings_arch_dep_t *dep_param;
@@ -88,8 +98,20 @@ typedef struct backend_params {
         */
        ir_mode *mode_float_arithmetic;
 
-       /** size of a long double floating mode in bits (or 0 if not supported) */
-       unsigned long_double_size;
+       /**
+        * type used for long long or NULL if none available.
+        */
+       ir_type *type_long_long;
+
+       /**
+        * type used for unsigned long long or NULL if none available
+        */
+       ir_type *type_unsigned_long_long;
+
+       /**
+        * type used for long double or NULL if none available.
+        */
+       ir_type *type_long_double;
 
        /** Size of the trampoline code. */
        unsigned trampoline_size;
index cf47faf..4426fb0 100644 (file)
@@ -86,11 +86,17 @@ static ir_node *gen_Div(ir_node *node)
 
 static ir_node *gen_Shl(ir_node *node)
 {
+       ir_mode *mode = get_irn_mode(node);
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo shift!=32 not supported by TEMPLATE backend");
        return transform_binop(node, new_bd_TEMPLATE_Shl);
 }
 
 static ir_node *gen_Shr(ir_node *node)
 {
+       ir_mode *mode = get_irn_mode(node);
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo shift!=32 not supported by TEMPLATE backend");
        return transform_binop(node, new_bd_TEMPLATE_Shr);
 }
 
index af48375..be528cd 100644 (file)
@@ -312,11 +312,15 @@ static const backend_params *TEMPLATE_get_backend_params(void)
                0,     /* no inline assembly */
                0,     /* no support for Rotl nodes */
                0,     /* 0: little-endian, 1: big-endian */
+               1,     /* modulo shift efficient */
+               0,     /* non-modulo shift efficient */
                NULL,  /* architecture dependent settings, will be set later */
                TEMPLATE_is_mux_allowed,  /* parameter for if conversion */
                32,    /* machine size - a 32bit CPU */
                NULL,  /* float arithmetic mode */
-               0,     /* size of long double */
+               NULL,  /* long long type */
+               NULL,  /* unsigned long long type */
+               NULL,  /* long double type */
                0,     /* no trampoline support: size 0 */
                0,     /* no trampoline support: align 0 */
                NULL,  /* no trampoline support: no trampoline builder */
index cd63314..3280907 100644 (file)
@@ -492,11 +492,15 @@ static const backend_params *amd64_get_backend_params(void) {
                0,     /* no inline assembly */
                1,     /* support Rotl nodes */
                0,     /* little endian */
+               1,     /* modulo shift is efficient */
+               0,     /* non-modulo shift is not efficient */
                NULL,  /* will be set later */
                amd64_is_mux_allowed,  /* parameter for if conversion */
                64,    /* machine size */
                NULL,  /* float arithmetic mode */
-               0,     /* size of long double */
+               NULL,  /* long long type */
+               NULL,  /* unsigned long long type */
+               NULL,  /* long double type (not supported yet) */
                0,     /* no trampoline support: size 0 */
                0,     /* no trampoline support: align 0 */
                NULL,  /* no trampoline support: no trampoline builder */
index 65ea8e4..87624b6 100644 (file)
@@ -738,9 +738,13 @@ static ir_node *make_shift(ir_node *node, match_flags_t flags,
        ir_node  *op1   = get_binop_left(node);
        ir_node  *op2   = get_binop_right(node);
        dbg_info *dbgi  = get_irn_dbg_info(node);
+       ir_mode  *mode  = get_irn_mode(node);
        ir_node  *new_op1;
        ir_node  *new_op2;
 
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo shift!=32 not supported by arm backend");
+
        if (flags & MATCH_SIZE_NEUTRAL) {
                op1 = arm_skip_downconv(op1);
                op2 = arm_skip_downconv(op2);
index 6809ea0..ce71c03 100644 (file)
@@ -559,11 +559,15 @@ static const backend_params *arm_get_libfirm_params(void)
                0,     /* don't support inline assembler yet */
                1,     /* support Rotl nodes */
                1,     /* big endian */
+               1,     /* modulo shift efficient */
+               0,     /* non-modulo shift not efficient */
                &ad,   /* will be set later */
                arm_is_mux_allowed, /* allow_ifconv function */
                32,    /* machine size */
                NULL,  /* float arithmetic mode (TODO) */
-               0,     /* size of long double */
+               NULL,  /* long long type */
+               NULL,  /* unsigned long long type */
+               NULL,  /* long double type */
                0,     /* no trampoline support: size 0 */
                0,     /* no trampoline support: align 0 */
                NULL,  /* no trampoline support: no trampoline builder */
index 97896cc..b2c07d4 100644 (file)
@@ -2083,16 +2083,29 @@ static const backend_params *ia32_get_libfirm_params(void)
                1,     /* support inline assembly */
                1,     /* support Rotl nodes */
                0,     /* little endian */
-               NULL,  /* will be set later */
+               1,     /* modulo shift efficient */
+               0,     /* non-modulo shift not efficient */
+               &ad,   /* will be set later */
                ia32_is_mux_allowed,
                32,    /* machine_size */
                NULL,  /* float arithmetic mode, will be set below */
-               0,     /* size of long double */
+               NULL,  /* long long type */
+               NULL,  /* unsigned long long type */
+               NULL,  /* long double type */
                12,    /* size of trampoline code */
                4,     /* alignment of trampoline code */
                ia32_create_trampoline_fkt,
                4      /* alignment of stack parameter */
        };
+       ir_mode *mode_long_long
+               = new_ir_mode("long long", irms_int_number, 64, 1, irma_twos_complement,
+                             64);
+       ir_type *type_long_long = new_type_primitive(mode_long_long);
+       ir_mode *mode_unsigned_long_long
+               = new_ir_mode("unsigned long long", irms_int_number, 64, 0,
+                             irma_twos_complement, 64);
+       ir_type *type_unsigned_long_long
+               = new_type_primitive(mode_unsigned_long_long);
 
        ia32_setup_cg_config();
 
@@ -2100,13 +2113,20 @@ static const backend_params *ia32_get_libfirm_params(void)
         * is called... */
        init_asm_constraints();
 
-       p.dep_param    = &ad;
+       p.type_long_long          = type_long_long;
+       p.type_unsigned_long_long = type_unsigned_long_long;
+
        if (! ia32_cg_config.use_sse2) {
                p.mode_float_arithmetic = mode_E;
-               p.long_double_size = 96;
+               ir_mode *mode = new_ir_mode("long double", irms_float_number, 80, 1,
+                                           irma_ieee754, 0);
+               ir_type *type = new_type_primitive(mode);
+               set_type_size_bytes(type, 12);
+               set_type_alignment_bytes(type, 4);
+               p.type_long_double = type;
        } else {
                p.mode_float_arithmetic = NULL;
-               p.long_double_size = 64;
+               p.type_long_double = NULL;
        }
        return &p;
 }
index f336f80..53d0191 100644 (file)
@@ -1111,15 +1111,19 @@ static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
 {
        dbg_info *dbgi;
        ir_node  *block, *new_block, *new_op1, *new_op2, *new_node;
+       ir_mode  *mode = get_irn_mode(node);
 
-       assert(! mode_is_float(get_irn_mode(node)));
+       assert(! mode_is_float(mode));
        assert(flags & match_immediate);
        assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
 
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo shift!=32 not supported by ia32 backend");
+
        if (flags & match_mode_neutral) {
                op1     = ia32_skip_downconv(op1);
                new_op1 = be_transform_node(op1);
-       } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
+       } else if (get_mode_size_bits(mode) != 32) {
                new_op1 = create_upconv(op1, node);
        } else {
                new_op1 = be_transform_node(op1);
index 6094610..b52f0de 100644 (file)
@@ -594,16 +594,39 @@ static const backend_params *sparc_get_backend_params(void)
                0,     /* no inline assembly */
                0,     /* no support for RotL nodes */
                1,     /* big endian */
+               1,     /* modulo shift efficient */
+               0,     /* non-modulo shift not efficient */
                &arch_dep,              /* will be set later */
                sparc_is_mux_allowed,   /* parameter for if conversion */
                32,    /* machine size */
                NULL,  /* float arithmetic mode */
-               128,   /* size of long double */
+               NULL,  /* long long type */
+               NULL,  /* usigned long long type */
+               NULL,  /* long double type */
                0,     /* no trampoline support: size 0 */
                0,     /* no trampoline support: align 0 */
                NULL,  /* no trampoline support: no trampoline builder */
                4      /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */
        };
+
+       ir_mode *mode_long_long
+               = new_ir_mode("long long", irms_int_number, 64, 1, irma_twos_complement,
+                             64);
+       ir_type *type_long_long = new_type_primitive(mode_long_long);
+       ir_mode *mode_unsigned_long_long
+               = new_ir_mode("unsigned long long", irms_int_number, 64, 0,
+                             irma_twos_complement, 64);
+       ir_type *type_unsigned_long_long
+               = new_type_primitive(mode_unsigned_long_long);
+       ir_mode *mode_long_double
+               = new_ir_mode("long double", irms_float_number, 128, 1,
+                             irma_ieee754, 0);
+       ir_type *type_long_double = new_type_primitive(mode_long_double);
+
+       set_type_alignment_bytes(type_long_double, 8);
+       p.type_long_double        = type_long_double;
+       p.type_long_long          = type_long_long;
+       p.type_unsigned_long_long = type_unsigned_long_long;
        return &p;
 }
 
index b2c1aff..e4f5dd1 100644 (file)
@@ -938,16 +938,25 @@ static ir_node *gen_Eor(ir_node *node)
 
 static ir_node *gen_Shl(ir_node *node)
 {
+       ir_mode *mode = get_irn_mode(node);
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo_shift!=32 not supported by sparc backend");
        return gen_helper_binop(node, MATCH_NONE, new_bd_sparc_Sll_reg, new_bd_sparc_Sll_imm);
 }
 
 static ir_node *gen_Shr(ir_node *node)
 {
+       ir_mode *mode = get_irn_mode(node);
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo_shift!=32 not supported by sparc backend");
        return gen_helper_binop(node, MATCH_NONE, new_bd_sparc_Srl_reg, new_bd_sparc_Srl_imm);
 }
 
 static ir_node *gen_Shrs(ir_node *node)
 {
+       ir_mode *mode = get_irn_mode(node);
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo_shift!=32 not supported by sparc backend");
        return gen_helper_binop(node, MATCH_NONE, new_bd_sparc_Sra_reg, new_bd_sparc_Sra_imm);
 }