summaryrefslogtreecommitdiffhomepage
path: root/ir/be/machine_triple.c
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2017-01-04 20:12:21 +0100
committerMatthias Braun <matze@braunis.de>2017-02-20 04:48:18 +0100
commit1ffc842f8bb13ed098eeaf2382ba473f9e154466 (patch)
treecd4c1c9ca57400975db74b7212ac237166359704 /ir/be/machine_triple.c
parent845e655dac11bc5eba82b9fc6d36a6f4fec23eb6 (diff)
Rework target initialization and query
- Moves machine triple handling code form cparser into libfirm - Create new APIs to set the target and query information about it - Move backend_params into the new target API - Backends initialize ir_target instead of backend_params now - Add new API to get information about the target platform: - Mangle a name for the target platform (and remove compilerlib mangling callback) - Can query size and alignment of basic C types for the platform - Move some constant target information into arch_isa_if_t (we move it to target_info_t later when we realize it needs to be dynamic) - Redo backend initialization. Examples: Simple case: Initialize for host: ir_init(); Complex case: cross-compile to sparc with PIC enabled: ir_init_library(); ir_target_set("sparc-leon-linux-gnu"); ir_target_option("pic"); ir_target_init();
Diffstat (limited to 'ir/be/machine_triple.c')
-rw-r--r--ir/be/machine_triple.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/ir/be/machine_triple.c b/ir/be/machine_triple.c
new file mode 100644
index 0000000..6922e0f
--- /dev/null
+++ b/ir/be/machine_triple.c
@@ -0,0 +1,164 @@
+/*
+ * This file is part of cparser.
+ * Copyright (C) 2012 Matthias Braun <matze@braunis.de>
+ */
+#include "target.h"
+
+#include <assert.h>
+#include <stdbool.h>
+#include "xmalloc.h"
+#include "util.h"
+
+struct ir_machine_triple_t {
+ char *cpu_type;
+ char *manufacturer;
+ char *operating_system;
+};
+
+const char *ir_triple_get_cpu_type(const ir_machine_triple_t *machine)
+{
+ return machine->cpu_type;
+}
+
+const char *ir_triple_get_manufacturer(const ir_machine_triple_t *machine)
+{
+ return machine->manufacturer;
+}
+
+const char *ir_triple_get_operating_system(const ir_machine_triple_t *machine)
+{
+ return machine->operating_system;
+}
+
+void ir_triple_set_cpu_type(ir_machine_triple_t *machine, const char *cpu_type)
+{
+ free(machine->cpu_type);
+ machine->cpu_type = xstrdup(cpu_type);
+}
+
+void ir_free_machine_triple(ir_machine_triple_t *machine)
+{
+ free(machine->cpu_type);
+ free(machine->manufacturer);
+ free(machine->operating_system);
+ free(machine);
+}
+
+static char *extract_strdup(const char *src, size_t len)
+{
+ char *result = XMALLOCN(char, len+1);
+ memcpy(result, src, len);
+ result[len] = '\0';
+ return result;
+}
+
+ir_machine_triple_t *ir_parse_machine_triple(const char *string)
+{
+ /* Split string into 'first-second-third' components */
+ const char *first = string;
+ const char *second = strchr(string, '-');
+ const char *third = NULL;
+ if (second != NULL) {
+ second += 1;
+ third = strchr(second, '-');
+ if (third != NULL)
+ third += 1;
+ }
+
+ /* Figure out what is what */
+ char *cpu_type;
+ char *manufacturer;
+ char *os;
+ if (second == NULL) {
+ cpu_type = xstrdup(string);
+ manufacturer = xstrdup("unknown");
+ os = xstrdup("unknown");
+ } else {
+ size_t cpu_type_len = second - first - 1;
+ cpu_type = extract_strdup(first, cpu_type_len);
+ if (third == NULL || strstart(second, "linux")) {
+ manufacturer = xstrdup("unknown");
+ os = xstrdup(second);
+ } else {
+ size_t manufacturer_len = third - second - 1;
+ manufacturer = extract_strdup(second, manufacturer_len);
+ os = xstrdup(third);
+ if (streq(manufacturer, "none") || manufacturer[0] == '\0') {
+ free(manufacturer);
+ manufacturer = xstrdup("unknown");
+ }
+ }
+ if (streq(os, "none") || os[0] == '\0') {
+ free(os);
+ os = xstrdup("unknown");
+ }
+ }
+
+ /* Create triple */
+ ir_machine_triple_t *triple = XMALLOCZ(ir_machine_triple_t);
+ triple->cpu_type = cpu_type;
+ triple->manufacturer = manufacturer;
+ triple->operating_system = os;
+ return triple;
+}
+
+ir_machine_triple_t *ir_get_host_machine_triple(void)
+{
+#ifdef HOST_TRIPLE
+ /* a triple for the host machine was defined in the Makefile
+ * or config.mak */
+ ir_machine_triple_t *triple = parse_machine_triple(HOST_TRIPLE);
+ if (triple == NULL)
+ panic("Cannot parse configured HOST_TRIPLE '%s'", HOST_TRIPLE);
+ return triple;
+#else
+ const char *cpu =
+#if defined(__x86_64__) || defined(__amd64__)
+ "x86_64";
+#elif defined(__i686__)
+ "i686";
+#elif defined(__i386__)
+ "i386";
+#elif defined(__sparc__)
+ "sparc";
+#elif defined(__arm__)
+ "arm";
+#else
+#error Could not determine host CPU. Consider defining HOST_TRIPLE.
+#endif
+
+ const char *manufacturer =
+#if defined(__leon__)
+ "leon";
+#elif defined(__APPLE__)
+ "apple";
+#else
+ "unknown";
+#endif
+
+ const char *operating_system =
+#if defined(_WIN32) || defined(__CYGWIN__)
+ "win32";
+#elif defined(__APPLE__)
+ "darwin";
+#elif defined(__FreeBSD__)
+ "freebsd";
+#elif defined(__gnu_linux__)
+ "linux-gnu";
+#elif defined(__linux__)
+ "linux";
+#elif defined(__midipix__)
+ "midipix";
+#elif defined(__ELF__)
+ "elf";
+#else
+ "unknown";
+#endif
+
+ ir_machine_triple_t *triple = XMALLOCZ(ir_machine_triple_t);
+ triple->cpu_type = xstrdup(cpu);
+ triple->manufacturer = xstrdup(manufacturer);
+ triple->operating_system = xstrdup(operating_system);
+ return triple;
+#endif
+}