* @file
* @brief ia32 architecture variants
* @author Michael Beck, Matthias Braun
- * @version $Id: bearch_ia32_t.h 16363 2007-10-25 23:27:07Z beck $
*/
#include "config.h"
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;
};
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[] = {
- LC_OPT_ENT_BOOL("size", "optimize for size", &opt_size),
- LC_OPT_ENT_ENUM_INT("arch", "select the instruction architecture",
- &arch_var),
- LC_OPT_ENT_ENUM_INT("opt", "optimize for instruction architecture",
- &opt_arch_var),
- LC_OPT_ENT_ENUM_INT("fpunit", "select the floating point unit",
- &fp_unit_var),
- LC_OPT_ENT_NEGBIT("nooptcc", "do not optimize calling convention",
- &opt_cc, 1),
- LC_OPT_ENT_BIT("unsafe_floatconv", "do unsafe floating point controlword "
- "optimisations", &opt_unsafe_floatconv, 1),
- LC_OPT_ENT_BOOL("machcode", "output machine code instead of assembler",
- &emit_machcode),
+ LC_OPT_ENT_BOOL ("size", "optimize for size", &opt_size),
+ LC_OPT_ENT_ENUM_INT("arch", "select the instruction architecture", &arch_var),
+ LC_OPT_ENT_ENUM_INT("opt", "optimize for instruction architecture", &opt_arch_var),
+ LC_OPT_ENT_ENUM_INT("fpunit", "select the floating point unit", &fp_unit_var),
+ LC_OPT_ENT_NEGBOOL ("nooptcc", "do not optimize calling convention", &opt_cc),
+ LC_OPT_ENT_BOOL ("unsafe_floatconv", "do unsafe floating point controlword optimisations", &opt_unsafe_floatconv),
+ LC_OPT_ENT_BOOL ("machcode", "output machine code instead of assembler", &emit_machcode),
LC_OPT_LAST
};
static void x86_cpuid(cpuid_registers *regs, unsigned level)
{
#if defined(__GNUC__)
-# ifdef __PIC__ // GCC cannot handle EBX in PIC
+# if defined(__PIC__) && !defined(__amd64) // GCC cannot handle EBX in PIC
__asm (
"pushl %%ebx\n\t"
"cpuid\n\t"
# endif
#elif defined(_MSC_VER)
__cpuid(regs->bulk, level);
+#else
+# error CPUID is missing
#endif
}
/* We use the cpuid instruction to detect the CPU features */
if (x86_toogle_cpuid()) {
cpuid_registers regs;
- unsigned highest_level;
char vendorid[13];
x86_cpu_info_t cpu_info;
/* get vendor ID */
x86_cpuid(®s, 0);
- highest_level = regs.r.eax;
memcpy(&vendorid[0], ®s.r.ebx, 4);
memcpy(&vendorid[4], ®s.r.edx, 4);
memcpy(&vendorid[8], ®s.r.ecx, 4);
/* 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
c->use_pxor = FLAGS(opt_arch, arch_netburst);
c->use_mov_0 = FLAGS(opt_arch, arch_k6) && !opt_size;
c->use_short_sex_eax = !FLAGS(opt_arch, arch_k6) && !opt_size;
- c->use_pad_return = FLAGS(opt_arch, arch_athlon_plus | arch_core2 | arch_generic32) && !opt_size;
+ c->use_pad_return = FLAGS(opt_arch, arch_athlon_plus) && !opt_size;
c->use_bt = FLAGS(opt_arch, arch_core2 | arch_athlon_plus) || opt_size;
c->use_fisttp = FLAGS(opt_arch & arch, arch_feature_sse3);
c->use_sse_prefetch = FLAGS(arch, (arch_feature_3DNowE | arch_feature_sse1));