summaryrefslogtreecommitdiffhomepage
path: root/ir/be/amd64
diff options
context:
space:
mode:
authorJohannes Bucher <johannes.bucher2@student.kit.edu>2021-01-18 16:05:22 +0100
committerJohannes Bucher <johannes.bucher2@student.kit.edu>2021-03-22 12:04:24 +0100
commitd893d24f66b2d9ea57e70c65209e9972dfb4b64c (patch)
tree9f3458cce1e05b1e576bd5529d1460c163d7106b /ir/be/amd64
parentdf6f8a5f86fa65bb390ff8533490b9f1927960c2 (diff)
add basic cpu architecture autodetection for amd64
Existing code from the ia32 backend for cpuid autodetection is now used for both x86 backends. Similar to ia32, the -march and -mtune options are now available for amd64 (limited to 'generic' and 'native' atm) FMA3 support is now only available if the target machine supports it.
Diffstat (limited to 'ir/be/amd64')
-rw-r--r--ir/be/amd64/amd64_architecture.c69
-rw-r--r--ir/be/amd64/amd64_architecture.h28
-rw-r--r--ir/be/amd64/amd64_bearch.c10
-rw-r--r--ir/be/amd64/amd64_bearch_t.h3
-rw-r--r--ir/be/amd64/amd64_transform.c3
5 files changed, 104 insertions, 9 deletions
diff --git a/ir/be/amd64/amd64_architecture.c b/ir/be/amd64/amd64_architecture.c
new file mode 100644
index 0000000..795717d
--- /dev/null
+++ b/ir/be/amd64/amd64_architecture.c
@@ -0,0 +1,69 @@
+#include "amd64_architecture.h"
+
+#include <stdbool.h>
+#include <string.h>
+
+#include "lc_opts_enum.h"
+#include "irtools.h"
+#include "x86_architecture.h"
+
+amd64_code_gen_config_t amd64_cg_config;
+
+static cpu_arch_features arch = cpu_generic64;
+static cpu_arch_features opt_arch = 0;
+static bool use_red_zone = false;
+static bool use_scalar_fma3 = false;
+
+/* instruction set architectures. */
+static const lc_opt_enum_int_items_t arch_items[] = {
+ { "generic", cpu_generic64 },
+
+#ifdef NATIVE_X86
+ { "native", cpu_autodetect },
+#endif
+
+ { NULL, 0 }
+};
+
+static lc_opt_enum_int_var_t arch_var = {
+ (int*) &arch, arch_items
+};
+
+static lc_opt_enum_int_var_t opt_arch_var = {
+ (int*) &opt_arch, arch_items
+};
+
+static const lc_opt_table_entry_t amd64_architecture_options[] = {
+ LC_OPT_ENT_ENUM_INT("arch", "select the instruction architecture", &arch_var),
+ LC_OPT_ENT_ENUM_INT("tune", "optimize for instruction architecture", &opt_arch_var),
+ LC_OPT_ENT_BOOL ("no-red-zone", "gcc compatibility", &use_red_zone),
+ LC_OPT_ENT_BOOL ("fma", "support FMA3 code generation", &use_scalar_fma3),
+ LC_OPT_LAST
+};
+
+void amd64_setup_cg_config(void)
+{
+
+ /* auto detection code only works if we're on an x86 cpu obviously */
+#ifdef NATIVE_X86
+ if (arch == cpu_autodetect) {
+ arch = autodetect_arch();
+ opt_arch = arch;
+ }
+#endif
+ if (opt_arch == 0)
+ opt_arch = arch;
+
+ amd64_code_gen_config_t *const c = &amd64_cg_config;
+ memset(c, 0, sizeof(*c));
+ c->use_scalar_fma3 = flags(arch, arch_feature_fma) && use_scalar_fma3;
+}
+
+void amd64_init_architecture(void)
+{
+ memset(&amd64_cg_config, 0, sizeof(amd64_cg_config));
+
+ lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
+ lc_opt_entry_t *amd64_grp = lc_opt_get_grp(be_grp, "amd64");
+ lc_opt_add_table(amd64_grp, amd64_architecture_options);
+}
diff --git a/ir/be/amd64/amd64_architecture.h b/ir/be/amd64/amd64_architecture.h
new file mode 100644
index 0000000..0261efe
--- /dev/null
+++ b/ir/be/amd64/amd64_architecture.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of libFirm.
+ * Copyright (C) 2012 University of Karlsruhe.
+ */
+
+#ifndef FIRM_BE_AMD64_ARCHITECTURE_H
+#define FIRM_BE_AMD64_ARCHITECTURE_H
+
+#include <stdbool.h>
+
+#include "firm_types.h"
+#include "irarch.h"
+
+typedef struct {
+ /** gcc compatibility */
+ bool use_red_zone:1;
+ /** use FMA3 instructions */
+ bool use_scalar_fma3:1;
+} amd64_code_gen_config_t;
+
+extern amd64_code_gen_config_t amd64_cg_config;
+
+/** Initialize the amd64 architecture module. */
+void amd64_init_architecture(void);
+
+/** Setup the amd64_cg_config structure by inspecting current user settings. */
+void amd64_setup_cg_config(void);
+#endif
diff --git a/ir/be/amd64/amd64_bearch.c b/ir/be/amd64/amd64_bearch.c
index 4b9d82d..f6258f6 100644
--- a/ir/be/amd64/amd64_bearch.c
+++ b/ir/be/amd64/amd64_bearch.c
@@ -8,8 +8,8 @@
* @brief The main amd64 backend driver file.
*/
#include "amd64_abi.h"
+#include "amd64_architecture.h"
#include "amd64_bearch_t.h"
-
#include "amd64_emitter.h"
#include "amd64_finish.h"
#include "amd64_new_nodes.h"
@@ -47,8 +47,6 @@ pmap *amd64_constants;
ir_mode *amd64_mode_xmm;
-bool use_scalar_fma3 = false;
-
static ir_node *create_push(ir_node *node, ir_node *schedpoint, ir_node *sp,
ir_node *mem, ir_entity *ent, x86_insn_size_t size)
{
@@ -772,6 +770,7 @@ static void amd64_init_types(void)
static void amd64_init(void)
{
+ amd64_setup_cg_config();
amd64_init_types();
amd64_register_init();
amd64_create_opcodes();
@@ -834,14 +833,15 @@ arch_isa_if_t const amd64_isa_if = {
BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_amd64)
void be_init_arch_amd64(void)
{
- static const lc_opt_table_entry_t options[] = {
+ /*static const lc_opt_table_entry_t options[] = {
LC_OPT_ENT_BOOL("no-red-zone", "gcc compatibility", &amd64_use_red_zone),
LC_OPT_ENT_BOOL("fma", "support FMA3 code generation", &use_scalar_fma3),
LC_OPT_LAST
};
lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
lc_opt_entry_t *amd64_grp = lc_opt_get_grp(be_grp, "amd64");
- lc_opt_add_table(amd64_grp, options);
+ lc_opt_add_table(amd64_grp, options);*/
amd64_init_transform();
+ amd64_init_architecture();
}
diff --git a/ir/be/amd64/amd64_bearch_t.h b/ir/be/amd64/amd64_bearch_t.h
index 94f9cbd..05898d8 100644
--- a/ir/be/amd64/amd64_bearch_t.h
+++ b/ir/be/amd64/amd64_bearch_t.h
@@ -22,9 +22,6 @@ extern pmap *amd64_constants; /**< A map of entities that store const tarvals */
extern ir_mode *amd64_mode_xmm;
-extern bool amd64_use_red_zone;
-extern bool use_scalar_fma3;
-
#define AMD64_REGISTER_SIZE 8
/** power of two stack alignment on calls */
#define AMD64_PO2_STACK_ALIGNMENT 4
diff --git a/ir/be/amd64/amd64_transform.c b/ir/be/amd64/amd64_transform.c
index d263df1..a8048a8 100644
--- a/ir/be/amd64/amd64_transform.c
+++ b/ir/be/amd64/amd64_transform.c
@@ -11,6 +11,7 @@
#include "../ia32/x86_address_mode.h"
#include "../ia32/x86_cconv.h"
+#include "amd64_architecture.h"
#include "amd64_bearch_t.h"
#include "amd64_new_nodes.h"
#include "amd64_nodes_attr.h"
@@ -1028,7 +1029,7 @@ static x86_insn_size_t get_size_32_64_from_mode(ir_mode *const mode)
static ir_node *gen_fma(ir_node *const add, ir_node *const op1, ir_node *const op2)
{
- if (!use_scalar_fma3)
+ if (!amd64_cg_config.use_scalar_fma3)
return NULL;
ir_mode *const add_mode = get_irn_mode(add);
if (get_mode_size_bits(add_mode) != 64 && get_mode_size_bits(add_mode) != 32)