* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
-#include "xmalloc.h"
+#include "adt/xmalloc.h"
#include <libfirm/adt/obstack.h>
#define obstack_chunk_alloc xmalloc
+++ /dev/null
-/*
- * This file is part of cparser.
- * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/*
- * Project: libFIRM
- * File name: ir/adt/xmalloc.c
- * Purpose: Xmalloc --- never failing wrappers for malloc() & friends.
- * Author: Markus Armbruster
- * Modified by:
- * Created: 1999 by getting from fiasco
- * CVS-ID: $Id$
- * Copyright: (c) 1995, 1996 Markus Armbruster
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
- */
-
-/* @@@ ToDo: replace this file with the one from liberty.
- [reimplement xstrdup, ... ] */
-#include <config.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "xmalloc.h"
-#include "error.h"
-#include "util.h"
-
-static inline __attribute__((noreturn))
-void out_of_memory(void)
-{
- panic("out of memory");
-}
-
-void *xmalloc(size_t size)
-{
- void *res = malloc(size);
-
- if (UNLIKELY(res == NULL))
- out_of_memory();
-
- return res;
-}
-
-void *xcalloc(size_t num, size_t size)
-{
- void *res = calloc(num, size);
-
- if (UNLIKELY(res == NULL))
- out_of_memory();
-
- return res;
-}
-
-void *xrealloc(void *ptr, size_t size)
-{
- void *res = realloc (ptr, size);
-
- if (UNLIKELY(res == NULL))
- out_of_memory();
-
- return res;
-}
-
-char *xstrdup(const char *str)
-{
- size_t len = strlen(str) + 1;
- char *res = xmalloc(len);
- memcpy(res, str, len);
-
- return res;
-}
+++ /dev/null
-/*
- * This file is part of cparser.
- * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- */
-
-/**
- * @file
- * @brief More comfortable allocations.
- * @author Markus Armbruster
- * @data 1999 by getting from fiasco
- * @version $Id$
- * Copyright: (c) 1995, 1996 Markus Armbruster
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
- */
-#ifndef _XMALLOC_H_
-#define _XMALLOC_H_
-
-#include <stdlib.h>
-#include "config.h"
-
-__attribute__((malloc))
-void *xmalloc(size_t size);
-
-__attribute__((malloc))
-void *xcalloc(size_t num, size_t size);
-
-void *xrealloc(void *ptr, size_t size);
-
-__attribute__((malloc))
-char *xstrdup(const char *str);
-
-#define xfree(ptr) free(ptr)
-
-#endif
/* Calls the specified backend. */
void do_codegen(FILE *out, const char *asm_file_name);
-#endif /* FIRM_CODEGEN_H */
+#endif
--- /dev/null
+#include <config.h>
+
+#include <assert.h>
+#include <stdbool.h>
+#include "firm_os.h"
+#include "adt/strutil.h"
+#include "adt/xmalloc.h"
+#include <libfirm/firm.h>
+
+static void set_be_option(const char *arg)
+{
+ int res = be_parse_arg(arg);
+ (void) res;
+ assert(res);
+}
+
+/**
+ * Initialize firm codegeneration for a specific operating system.
+ * The argument is the operating system part of a target-triple
+ */
+static bool setup_os_support(const char *os)
+{
+ if (strstr(os, "linux") != NULL || strstr(os, "bsd") != NULL
+ || streq(os, "solaris")) {
+ set_be_option("ia32-gasmode=elf");
+ } else if (streq(os, "darwin")) {
+ set_be_option("ia32-gasmode=macho");
+ set_be_option("ia32-stackalign=4");
+ set_be_option("pic=true");
+ } else if (strstr(os, "mingw") != NULL || streq(os, "win32")) {
+ set_be_option("ia32-gasmode=mingw");
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+bool setup_firm_for_machine(const machine_triple_t *machine)
+{
+ const char *cpu = machine->cpu_type;
+
+ if (streq(cpu, "i386")) {
+ set_be_option("isa=ia32");
+ set_be_option("ia32-arch=i386");
+ } else if (streq(cpu, "i486")) {
+ set_be_option("isa=ia32");
+ set_be_option("ia32-arch=i486");
+ } else if (streq(cpu, "i586")) {
+ set_be_option("isa=ia32");
+ set_be_option("ia32-arch=i586");
+ } else if (streq(cpu, "i686")) {
+ set_be_option("isa=ia32");
+ set_be_option("ia32-arch=i686");
+ } else if (streq(cpu, "i786")) {
+ set_be_option("isa=ia32");
+ set_be_option("ia32-arch=pentium4");
+ } else if (streq(cpu, "x86_64")) {
+ set_be_option("isa=amd64");
+ } else if (streq(cpu, "sparc")) {
+ set_be_option("isa=sparc");
+ } else if (streq(cpu, "arm")) {
+ set_be_option("isa=arm");
+ } else {
+ fprintf(stderr, "Unknown cpu '%s' in target-triple\n", cpu);
+ return false;
+ }
+
+ /* process operating system */
+ if (!setup_os_support(machine->operating_system)) {
+ fprintf(stderr, "Unknown operating system '%s' in target-triple\n", machine->operating_system);
+ return false;
+ }
+ return true;
+}
+
+machine_triple_t *firm_get_host_machine(void)
+{
+ machine_triple_t *machine = XMALLOC(machine_triple_t);
+ machine->cpu_type = xstrdup("i386");
+ machine->manufacturer = xstrdup("unknown");
+#if defined(_WIN32) || defined(__CYGWIN__)
+ machine->operating_system = xstrdup("win32");
+#elif defined(__APPLE__)
+ machine->operating_system = xstrdup("darwin");
+#else
+ machine->operating_system = xstrdup("linux");
+#endif
+ return machine;
+}
+
+void firm_free_machine_triple(machine_triple_t *machine)
+{
+ free(machine->cpu_type);
+ free(machine->manufacturer);
+ free(machine->operating_system);
+ free(machine);
+}
+
+machine_triple_t *firm_parse_machine_triple(const char *triple_string)
+{
+ const char *manufacturer = strchr(triple_string, '-');
+ if (manufacturer == NULL) {
+ return NULL;
+ }
+ manufacturer += 1;
+
+ const char *os = strchr(manufacturer, '-');
+ if (os == NULL) {
+ return false;
+ }
+ os += 1;
+
+ /* Note: Triples are more or less defined by what the config.guess and
+ * config.sub scripts from GNU autoconf emit. We have to lookup there what
+ * triples are possible */
+
+ const char *cpu = triple_string;
+
+ machine_triple_t *triple = XMALLOCZ(machine_triple_t);
+
+ size_t cpu_type_len = manufacturer-cpu+1;
+ triple->cpu_type = XMALLOCN(char, cpu_type_len);
+ memcpy(triple->cpu_type, cpu, cpu_type_len-1);
+ triple->cpu_type[cpu_type_len-1] = '\0';
+
+ /* process manufacturer, alot of people incorrectly leave out the
+ * manufacturer instead of using unknown- */
+ if (strstart(manufacturer, "linux")) {
+ triple->manufacturer = xstrdup("unknown");
+ os = manufacturer;
+ } else {
+ size_t manufacturer_len = os-manufacturer+1;
+ triple->manufacturer = XMALLOCN(char, manufacturer_len);
+ memcpy(triple->manufacturer, manufacturer, manufacturer_len-1);
+ triple->manufacturer[manufacturer_len-1] = '\0';
+ }
+
+ triple->operating_system = xstrdup(os);
+ return triple;
+}
--- /dev/null
+#ifndef FIRM_OS_H
+#define FIRM_OS_H
+
+#include <stdbool.h>
+
+typedef struct machine_triple_t {
+ char *cpu_type;
+ char *manufacturer;
+ char *operating_system;
+} machine_triple_t;
+
+machine_triple_t *firm_get_host_machine(void);
+
+machine_triple_t *firm_parse_machine_triple(const char *triple_string);
+
+void firm_free_machine_triple(machine_triple_t *triple);
+
+bool setup_firm_for_machine(const machine_triple_t *triple);
+
+#endif
}
}
+static void set_be_option(const char *arg)
+{
+ int res = be_parse_arg(arg);
+ (void) res;
+ assert(res);
+}
+
+static void set_option(const char *arg)
+{
+ int res = firm_option(arg);
+ (void) res;
+ assert(res);
+}
+
+void choose_optimization_pack(int level)
+{
+ /* apply optimisation level */
+ switch(level) {
+ case 0:
+ set_option("no-opt");
+ break;
+ case 1:
+ set_option("no-inline");
+ break;
+ default:
+ case 4:
+ /* use_builtins = true; */
+ /* fallthrough */
+ case 3:
+ set_option("thread-jumps");
+ set_option("if-conversion");
+ /* fallthrough */
+ case 2:
+ set_option("strict-aliasing");
+ set_option("inline");
+ set_option("fp-vrp");
+ set_option("deconv");
+ set_be_option("omitfp");
+ break;
+ }
+}
+
/**
* Do very early initializations
*/
/** print help about optimisations options */
void firm_opt_option_help(void);
-#endif /* FIRM_OPT_H */
+/** Choose an optimization level. (Typically used to interpret the -O compiler
+ * switches) */
+void choose_optimization_pack(int level);
+
+/**
+ * Setup firm to generate code for a specific os.
+ * The parameter should be the OS-part of a machine triple
+ */
+void firm_init_os(const char *os);
+
+#endif
#include "driver/firm_opt.h"
#include "driver/firm_cmdline.h"
#include "driver/firm_timing.h"
+#include "driver/firm_os.h"
#include "adt/error.h"
#include "adt/strutil.h"
#include "wrappergen/write_fluffy.h"
/* to switch on printing of parenthesis to indicate operator precedence */
extern bool print_parenthesis;
-static const char *target_triple;
-static int verbose;
-static struct obstack cppflags_obst;
-static struct obstack ldflags_obst;
-static struct obstack asflags_obst;
-static char dep_target[1024];
-static const char *outname;
+static machine_triple_t *target_machine;
+static const char *target_triple;
+static int verbose;
+static struct obstack cppflags_obst;
+static struct obstack ldflags_obst;
+static struct obstack asflags_obst;
+static char dep_target[1024];
+static const char *outname;
typedef enum lang_standard_t {
STANDARD_DEFAULT, /* gnu99 (for C, GCC does gnu89) or gnu++98 (for C++) */
assert(res);
}
-static void set_option(const char *arg)
-{
- int res = firm_option(arg);
- (void) res;
- assert(res);
-}
-
static void copy_file(FILE *dest, FILE *input)
{
char buf[16384];
return FILETYPE_UNKNOWN;
}
-/**
- * Initialize firm codegeneration for a specific operating system.
- * The argument is the operating system part of a target-triple */
-static bool set_os_support(const char *os)
+static bool init_os_support(void)
{
+ const char *os = target_machine->operating_system;
wchar_atomic_kind = ATOMIC_TYPE_INT;
force_long_double_size = 0;
enable_main_collect2_hack = false;
if (strstr(os, "linux") != NULL || strstr(os, "bsd") != NULL
|| streq(os, "solaris")) {
- set_be_option("ia32-gasmode=elf");
set_create_ld_ident(create_name_linux_elf);
} else if (streq(os, "darwin")) {
force_long_double_size = 16;
- set_be_option("ia32-gasmode=macho");
- set_be_option("ia32-stackalign=4");
- set_be_option("pic=true");
set_create_ld_ident(create_name_macho);
} else if (strstr(os, "mingw") != NULL || streq(os, "win32")) {
wchar_atomic_kind = ATOMIC_TYPE_USHORT;
enable_main_collect2_hack = true;
- set_be_option("ia32-gasmode=mingw");
set_create_ld_ident(create_name_win32);
} else {
return false;
static bool parse_target_triple(const char *arg)
{
- const char *manufacturer = strchr(arg, '-');
- if (manufacturer == NULL) {
+ machine_triple_t *triple = firm_parse_machine_triple(arg);
+ if (triple == NULL) {
fprintf(stderr, "Target-triple is not in the form 'cpu_type-manufacturer-operating_system'\n");
return false;
}
- manufacturer += 1;
-
- const char *os = strchr(manufacturer, '-');
- if (os == NULL) {
- fprintf(stderr, "Target-triple is not in the form 'cpu_type-manufacturer-operating_system'\n");
- return false;
- }
- os += 1;
-
- /* Note: Triples are more or less defined by what the config.guess and
- * config.sub scripts from GNU autoconf emit. We have to lookup there what
- * triples are possible */
-
- /* process cpu type */
- if (strstart(arg, "i386-")) {
- be_parse_arg("isa=ia32");
- be_parse_arg("ia32-arch=i386");
- } else if (strstart(arg, "i486-")) {
- be_parse_arg("isa=ia32");
- be_parse_arg("ia32-arch=i486");
- } else if (strstart(arg, "i586-")) {
- be_parse_arg("isa=ia32");
- be_parse_arg("ia32-arch=i586");
- } else if (strstart(arg, "i686-")) {
- be_parse_arg("isa=ia32");
- be_parse_arg("ia32-arch=i686");
- } else if (strstart(arg, "i786-")) {
- be_parse_arg("isa=ia32");
- be_parse_arg("ia32-arch=pentium4");
- } else if (strstart(arg, "x86_64")) {
- be_parse_arg("isa=amd64");
- } else if (strstart(arg, "sparc-")) {
- be_parse_arg("isa=sparc");
- } else if (strstart(arg, "arm-")) {
- be_parse_arg("isa=arm");
- } else {
- fprintf(stderr, "Unknown cpu in triple '%s'\n", arg);
- return false;
- }
-
- /* process manufacturer, alot of people incorrectly leave out the
- * manufacturer instead of using unknown- */
- if (strstart(manufacturer, "linux")) {
- os = manufacturer;
- manufacturer = "unknown-";
- }
-
- /* process operating system */
- if (!set_os_support(os)) {
- fprintf(stderr, "Unknown operating system '%s' in triple '%s'\n", os, arg);
- return false;
- }
-
- target_triple = arg;
return true;
}
}
}
- /* Guess host OS */
-#if defined(_WIN32) || defined(__CYGWIN__)
- set_os_support("win32");
-#elif defined(__APPLE__)
- set_os_support("darwin");
-#else
- set_os_support("linux");
-#endif
-
- /* apply optimisation level */
- switch(opt_level) {
- case 0:
- set_option("no-opt");
- break;
- case 1:
- set_option("no-inline");
- break;
- default:
- case 4:
- /* use_builtins = true; */
- /* fallthrough */
- case 3:
- set_option("thread-jumps");
- set_option("if-conversion");
- /* fallthrough */
- case 2:
- set_option("strict-aliasing");
- set_option("inline");
- set_option("fp-vrp");
- set_option("deconv");
- set_be_option("omitfp");
- break;
- }
-
const char *target = getenv("TARGET");
if (target != NULL)
parse_target_triple(target);
+ if (target_machine == NULL) {
+ target_machine = firm_get_host_machine();
+ }
+ choose_optimization_pack(opt_level);
+ setup_firm_for_machine(target_machine);
+ init_os_support();
/* parse rest of options */
standard = STANDARD_DEFAULT;
GET_ARG_AFTER(opt, "-m");
if (strstart(opt, "target=")) {
GET_ARG_AFTER(opt, "-mtarget=");
- if (!parse_target_triple(opt))
+ if (!parse_target_triple(opt)) {
argument_errors = true;
+ } else {
+ setup_firm_for_machine(target_machine);
+ target_triple = opt;
+ }
} else if (strstart(opt, "triple=")) {
GET_ARG_AFTER(opt, "-mtriple=");
- if (!parse_target_triple(opt))
+ if (!parse_target_triple(opt)) {
argument_errors = true;
+ } else {
+ setup_firm_for_machine(target_machine);
+ target_triple = opt;
+ }
} else if (strstart(opt, "arch=")) {
GET_ARG_AFTER(opt, "-march=");
snprintf(arch_opt, sizeof(arch_opt), "%s-arch=%s", cpu_arch, opt);