Commit 5ff0de76 authored by yb9976's avatar yb9976
Browse files

Added soft float support for IA32 backend.

parent 1f66492d
......@@ -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;
}
......
......@@ -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 */
};
/**
......
......@@ -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
......
......@@ -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);
......
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