From 5ff0de76045b273712a3a8a7310e6d49fc4671ce Mon Sep 17 00:00:00 2001 From: Sebastian Buchwald Date: Thu, 11 Aug 2011 15:26:39 +0200 Subject: [PATCH] Added soft float support for IA32 backend. --- ir/be/ia32/bearch_ia32.c | 15 +++++++++++---- ir/be/ia32/bearch_ia32_t.h | 1 + ir/be/ia32/ia32_architecture.c | 14 ++++++++------ ir/be/ia32/ia32_architecture.h | 10 ++++++++++ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index b2c07d4c4..534c4b630 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -53,6 +53,7 @@ #include "iropt_t.h" #include "lower_dw.h" #include "lower_calls.h" +#include "lower_softfloat.h" #include "../beabi.h" #include "../beirg.h" @@ -1455,6 +1456,7 @@ static ia32_isa_t ia32_isa_template = { NULL, /* types */ NULL, /* tv_ents */ NULL, /* abstract machine */ + IA32_FPU_ARCH_X87, /* FPU architecture */ }; static void init_asm_constraints(void) @@ -2024,6 +2026,11 @@ static void ia32_lower_for_target(void) /* lower compound param handling */ lower_calls_with_compounds(LF_RETURN_HIDDEN); + /* replace floating point operations by function calls */ + if (ia32_cg_config.use_softfloat) { + lower_floating_point(); + } + ir_prepare_dw_lowering(&lower_dw_params); ir_lower_dw_ops(); @@ -2116,7 +2123,10 @@ static const backend_params *ia32_get_libfirm_params(void) 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 || ia32_cg_config.use_softfloat) { + p.mode_float_arithmetic = NULL; + p.type_long_double = NULL; + } else { p.mode_float_arithmetic = mode_E; ir_mode *mode = new_ir_mode("long double", irms_float_number, 80, 1, irma_ieee754, 0); @@ -2124,9 +2134,6 @@ static const backend_params *ia32_get_libfirm_params(void) set_type_size_bytes(type, 12); set_type_alignment_bytes(type, 4); p.type_long_double = type; - } else { - p.mode_float_arithmetic = NULL; - p.type_long_double = NULL; } return &p; } diff --git a/ir/be/ia32/bearch_ia32_t.h b/ir/be/ia32/bearch_ia32_t.h index 91514bbfa..4fa7c0840 100644 --- a/ir/be/ia32/bearch_ia32_t.h +++ b/ir/be/ia32/bearch_ia32_t.h @@ -68,6 +68,7 @@ struct ia32_isa_t { pmap *types; /**< A map of modes to primitivetypes */ pmap *tv_ent; /**< A map of entities that store const tarvals */ const be_machine_t *cpu; /**< the abstract machine */ + int fpu_arch; /**< FPU architecture */ }; /** diff --git a/ir/be/ia32/ia32_architecture.c b/ir/be/ia32/ia32_architecture.c index 798a88dd2..0e9307734 100644 --- a/ir/be/ia32/ia32_architecture.c +++ b/ir/be/ia32/ia32_architecture.c @@ -150,7 +150,7 @@ static int opt_size = 0; static int emit_machcode = 0; static cpu_support arch = cpu_generic; static cpu_support opt_arch = cpu_generic; -static int use_sse2 = 0; +static int fpu_arch = 0; static int opt_cc = 1; static int opt_unsafe_floatconv = 0; @@ -222,13 +222,14 @@ static lc_opt_enum_int_var_t opt_arch_var = { }; static const lc_opt_enum_int_items_t fp_unit_items[] = { - { "x87" , 0 }, - { "sse2", 1 }, - { NULL, 0 } + { "x87" , IA32_FPU_ARCH_X87 }, + { "sse2", IA32_FPU_ARCH_SSE2 }, + { "softfloat", IA32_FPU_ARCH_SOFTFLOAT }, + { NULL, IA32_FPU_ARCH_NONE } }; static lc_opt_enum_int_var_t fp_unit_var = { - &use_sse2, fp_unit_items + &fpu_arch, fp_unit_items }; static const lc_opt_table_entry_t ia32_architecture_options[] = { @@ -881,7 +882,8 @@ void ia32_setup_cg_config(void) /* P4s don't like inc/decs because they only partially write the flags * register which produces false dependencies */ c->use_incdec = !FLAGS(opt_arch, arch_netburst | arch_nocona | arch_core2 | arch_geode) || opt_size; - c->use_sse2 = use_sse2 && FLAGS(arch, arch_feature_sse2); + c->use_softfloat = FLAGS(fpu_arch, IA32_FPU_ARCH_SOFTFLOAT); + c->use_sse2 = FLAGS(fpu_arch, IA32_FPU_ARCH_SSE2) && FLAGS(arch, arch_feature_sse2); c->use_ffreep = FLAGS(opt_arch, arch_athlon_plus); c->use_ftst = !FLAGS(arch, arch_feature_p6_insn); /* valgrind can't cope with femms yet and the usefulness of the optimization diff --git a/ir/be/ia32/ia32_architecture.h b/ir/be/ia32/ia32_architecture.h index 84c0938df..2b65043d5 100644 --- a/ir/be/ia32/ia32_architecture.h +++ b/ir/be/ia32/ia32_architecture.h @@ -33,6 +33,8 @@ typedef struct { unsigned use_leave:1; /** use inc, dec instead of add $1, reg and add $-1, reg */ unsigned use_incdec:1; + /** use soft float library */ + unsigned use_softfloat:1; /** use sse2 instructions (instead of x87) */ unsigned use_sse2:1; /** use ffreep instead of fpop */ @@ -104,6 +106,14 @@ typedef struct { extern ia32_code_gen_config_t ia32_cg_config; +typedef enum ia32_fp_architectures { + IA32_FPU_ARCH_NONE = 0, + IA32_FPU_ARCH_X87 = 0x00000001, + IA32_FPU_ARCH_SSE2 = 0x00000002, + IA32_FPU_ARCH_SOFTFLOAT = 0x00000004, +} +ia32_fp_architectures; + /** Initialize the ia32 architecture module. */ void ia32_init_architecture(void); -- 2.20.1