Commit 2413c901 authored by Matthias Braun's avatar Matthias Braun
Browse files

let backends specify the complete long double type

parent 9b558d63
...@@ -71,6 +71,16 @@ typedef struct backend_params { ...@@ -71,6 +71,16 @@ typedef struct backend_params {
unsigned support_rotl:1; unsigned support_rotl:1;
/** the backend uses big-endian byte ordering if set, else little endian */ /** the backend uses big-endian byte ordering if set, else little endian */
unsigned byte_order_big_endian:1; 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. */ /** Settings for architecture dependent optimizations. */
const ir_settings_arch_dep_t *dep_param; const ir_settings_arch_dep_t *dep_param;
...@@ -88,8 +98,20 @@ typedef struct backend_params { ...@@ -88,8 +98,20 @@ typedef struct backend_params {
*/ */
ir_mode *mode_float_arithmetic; 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. */ /** Size of the trampoline code. */
unsigned trampoline_size; unsigned trampoline_size;
......
...@@ -86,11 +86,17 @@ static ir_node *gen_Div(ir_node *node) ...@@ -86,11 +86,17 @@ static ir_node *gen_Div(ir_node *node)
static ir_node *gen_Shl(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); return transform_binop(node, new_bd_TEMPLATE_Shl);
} }
static ir_node *gen_Shr(ir_node *node) 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); return transform_binop(node, new_bd_TEMPLATE_Shr);
} }
......
...@@ -312,11 +312,15 @@ static const backend_params *TEMPLATE_get_backend_params(void) ...@@ -312,11 +312,15 @@ static const backend_params *TEMPLATE_get_backend_params(void)
0, /* no inline assembly */ 0, /* no inline assembly */
0, /* no support for Rotl nodes */ 0, /* no support for Rotl nodes */
0, /* 0: little-endian, 1: big-endian */ 0, /* 0: little-endian, 1: big-endian */
1, /* modulo shift efficient */
0, /* non-modulo shift efficient */
NULL, /* architecture dependent settings, will be set later */ NULL, /* architecture dependent settings, will be set later */
TEMPLATE_is_mux_allowed, /* parameter for if conversion */ TEMPLATE_is_mux_allowed, /* parameter for if conversion */
32, /* machine size - a 32bit CPU */ 32, /* machine size - a 32bit CPU */
NULL, /* float arithmetic mode */ 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: size 0 */
0, /* no trampoline support: align 0 */ 0, /* no trampoline support: align 0 */
NULL, /* no trampoline support: no trampoline builder */ NULL, /* no trampoline support: no trampoline builder */
......
...@@ -492,11 +492,15 @@ static const backend_params *amd64_get_backend_params(void) { ...@@ -492,11 +492,15 @@ static const backend_params *amd64_get_backend_params(void) {
0, /* no inline assembly */ 0, /* no inline assembly */
1, /* support Rotl nodes */ 1, /* support Rotl nodes */
0, /* little endian */ 0, /* little endian */
1, /* modulo shift is efficient */
0, /* non-modulo shift is not efficient */
NULL, /* will be set later */ NULL, /* will be set later */
amd64_is_mux_allowed, /* parameter for if conversion */ amd64_is_mux_allowed, /* parameter for if conversion */
64, /* machine size */ 64, /* machine size */
NULL, /* float arithmetic mode */ 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: size 0 */
0, /* no trampoline support: align 0 */ 0, /* no trampoline support: align 0 */
NULL, /* no trampoline support: no trampoline builder */ NULL, /* no trampoline support: no trampoline builder */
......
...@@ -738,9 +738,13 @@ static ir_node *make_shift(ir_node *node, match_flags_t flags, ...@@ -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 *op1 = get_binop_left(node);
ir_node *op2 = get_binop_right(node); ir_node *op2 = get_binop_right(node);
dbg_info *dbgi = get_irn_dbg_info(node); dbg_info *dbgi = get_irn_dbg_info(node);
ir_mode *mode = get_irn_mode(node);
ir_node *new_op1; ir_node *new_op1;
ir_node *new_op2; 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) { if (flags & MATCH_SIZE_NEUTRAL) {
op1 = arm_skip_downconv(op1); op1 = arm_skip_downconv(op1);
op2 = arm_skip_downconv(op2); op2 = arm_skip_downconv(op2);
......
...@@ -559,11 +559,15 @@ static const backend_params *arm_get_libfirm_params(void) ...@@ -559,11 +559,15 @@ static const backend_params *arm_get_libfirm_params(void)
0, /* don't support inline assembler yet */ 0, /* don't support inline assembler yet */
1, /* support Rotl nodes */ 1, /* support Rotl nodes */
1, /* big endian */ 1, /* big endian */
1, /* modulo shift efficient */
0, /* non-modulo shift not efficient */
&ad, /* will be set later */ &ad, /* will be set later */
arm_is_mux_allowed, /* allow_ifconv function */ arm_is_mux_allowed, /* allow_ifconv function */
32, /* machine size */ 32, /* machine size */
NULL, /* float arithmetic mode (TODO) */ 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: size 0 */
0, /* no trampoline support: align 0 */ 0, /* no trampoline support: align 0 */
NULL, /* no trampoline support: no trampoline builder */ NULL, /* no trampoline support: no trampoline builder */
......
...@@ -2083,16 +2083,29 @@ static const backend_params *ia32_get_libfirm_params(void) ...@@ -2083,16 +2083,29 @@ static const backend_params *ia32_get_libfirm_params(void)
1, /* support inline assembly */ 1, /* support inline assembly */
1, /* support Rotl nodes */ 1, /* support Rotl nodes */
0, /* little endian */ 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, ia32_is_mux_allowed,
32, /* machine_size */ 32, /* machine_size */
NULL, /* float arithmetic mode, will be set below */ 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 */ 12, /* size of trampoline code */
4, /* alignment of trampoline code */ 4, /* alignment of trampoline code */
ia32_create_trampoline_fkt, ia32_create_trampoline_fkt,
4 /* alignment of stack parameter */ 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(); ia32_setup_cg_config();
...@@ -2100,13 +2113,20 @@ static const backend_params *ia32_get_libfirm_params(void) ...@@ -2100,13 +2113,20 @@ static const backend_params *ia32_get_libfirm_params(void)
* is called... */ * is called... */
init_asm_constraints(); 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) { if (! ia32_cg_config.use_sse2) {
p.mode_float_arithmetic = mode_E; 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 { } else {
p.mode_float_arithmetic = NULL; p.mode_float_arithmetic = NULL;
p.long_double_size = 64; p.type_long_double = NULL;
} }
return &p; return &p;
} }
......
...@@ -1111,15 +1111,19 @@ static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2, ...@@ -1111,15 +1111,19 @@ static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
{ {
dbg_info *dbgi; dbg_info *dbgi;
ir_node *block, *new_block, *new_op1, *new_op2, *new_node; 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_immediate);
assert((flags & ~(match_mode_neutral | match_immediate)) == 0); 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) { if (flags & match_mode_neutral) {
op1 = ia32_skip_downconv(op1); op1 = ia32_skip_downconv(op1);
new_op1 = be_transform_node(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); new_op1 = create_upconv(op1, node);
} else { } else {
new_op1 = be_transform_node(op1); new_op1 = be_transform_node(op1);
......
...@@ -594,16 +594,39 @@ static const backend_params *sparc_get_backend_params(void) ...@@ -594,16 +594,39 @@ static const backend_params *sparc_get_backend_params(void)
0, /* no inline assembly */ 0, /* no inline assembly */
0, /* no support for RotL nodes */ 0, /* no support for RotL nodes */
1, /* big endian */ 1, /* big endian */
1, /* modulo shift efficient */
0, /* non-modulo shift not efficient */
&arch_dep, /* will be set later */ &arch_dep, /* will be set later */
sparc_is_mux_allowed, /* parameter for if conversion */ sparc_is_mux_allowed, /* parameter for if conversion */
32, /* machine size */ 32, /* machine size */
NULL, /* float arithmetic mode */ 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: size 0 */
0, /* no trampoline support: align 0 */ 0, /* no trampoline support: align 0 */
NULL, /* no trampoline support: no trampoline builder */ NULL, /* no trampoline support: no trampoline builder */
4 /* alignment of stack parameter: typically 4 (32bit) or 8 (64bit) */ 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; return &p;
} }
......
...@@ -938,16 +938,25 @@ static ir_node *gen_Eor(ir_node *node) ...@@ -938,16 +938,25 @@ static ir_node *gen_Eor(ir_node *node)
static ir_node *gen_Shl(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); 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) 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); 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) 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); return gen_helper_binop(node, MATCH_NONE, new_bd_sparc_Sra_reg, new_bd_sparc_Sra_imm);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment