2 * This file is part of cparser.
3 * Copyright (C) 2012 Matthias Braun <matze@braunis.de>
9 #include "firm_machine.h"
10 #include "adt/strutil.h"
11 #include "adt/xmalloc.h"
12 #include <libfirm/firm.h>
14 static void set_be_option(const char *arg)
16 int res = be_parse_arg(arg);
21 static ir_entity *underscore_compilerlib_entity_creator(ident *id, ir_type *mt)
23 ir_entity *entity = new_entity(get_glob_type(), id, mt);
24 ident *ldname = id_mangle3("_", id, "");
26 set_entity_visibility(entity, ir_visibility_external);
27 set_entity_ld_ident(entity, ldname);
32 bool firm_is_unixish_os(const machine_triple_t *machine)
34 const char *os = machine->operating_system;
35 return strstr(os, "linux") != NULL || strstr(os, "bsd") != NULL
36 || strstart(os, "solaris");
39 bool firm_is_darwin_os(const machine_triple_t *machine)
41 const char *os = machine->operating_system;
42 return strstart(os, "darwin");
45 bool firm_is_windows_os(const machine_triple_t *machine)
47 const char *os = machine->operating_system;
48 return strstart(os, "mingw") || streq(os, "win32");
52 * Initialize firm codegeneration for a specific operating system.
53 * The argument is the operating system part of a target-triple
55 static bool setup_os_support(const machine_triple_t *machine)
57 if (firm_is_unixish_os(machine)) {
58 set_be_option("ia32-gasmode=elf");
59 } else if (firm_is_darwin_os(machine)) {
60 set_be_option("ia32-gasmode=macho");
61 set_be_option("ia32-stackalign=4");
62 set_be_option("pic=true");
63 set_compilerlib_entity_creator(underscore_compilerlib_entity_creator);
64 } else if (firm_is_windows_os(machine)) {
65 set_be_option("ia32-gasmode=mingw");
66 set_compilerlib_entity_creator(underscore_compilerlib_entity_creator);
74 bool setup_firm_for_machine(const machine_triple_t *machine)
76 const char *cpu = machine->cpu_type;
78 if (streq(cpu, "i386")) {
79 set_be_option("isa=ia32");
80 set_be_option("ia32-arch=i386");
81 } else if (streq(cpu, "i486")) {
82 set_be_option("isa=ia32");
83 set_be_option("ia32-arch=i486");
84 } else if (streq(cpu, "i586")) {
85 set_be_option("isa=ia32");
86 set_be_option("ia32-arch=i586");
87 } else if (streq(cpu, "i686")) {
88 set_be_option("isa=ia32");
89 set_be_option("ia32-arch=i686");
90 } else if (streq(cpu, "i786")) {
91 set_be_option("isa=ia32");
92 set_be_option("ia32-arch=pentium4");
93 } else if (streq(cpu, "x86_64")) {
94 set_be_option("isa=amd64");
95 } else if (streq(cpu, "sparc")) {
96 set_be_option("isa=sparc");
97 } else if (streq(cpu, "arm")) {
98 set_be_option("isa=arm");
100 fprintf(stderr, "Unknown cpu '%s' in target-triple\n", cpu);
104 /* process operating system */
105 if (!setup_os_support(machine)) {
106 fprintf(stderr, "Unknown operating system '%s' in target-triple\n", machine->operating_system);
112 machine_triple_t *firm_get_host_machine(void)
114 machine_triple_t *machine = XMALLOC(machine_triple_t);
115 machine->cpu_type = xstrdup("i386");
116 machine->manufacturer = xstrdup("unknown");
117 #if defined(_WIN32) || defined(__CYGWIN__)
118 machine->operating_system = xstrdup("win32");
119 #elif defined(__APPLE__)
120 machine->operating_system = xstrdup("darwin");
122 machine->operating_system = xstrdup("linux");
127 void firm_free_machine_triple(machine_triple_t *machine)
129 free(machine->cpu_type);
130 free(machine->manufacturer);
131 free(machine->operating_system);
135 machine_triple_t *firm_parse_machine_triple(const char *triple_string)
137 const char *manufacturer = strchr(triple_string, '-');
138 if (manufacturer == NULL) {
143 const char *os = strchr(manufacturer, '-');
149 /* Note: Triples are more or less defined by what the config.guess and
150 * config.sub scripts from GNU autoconf emit. We have to lookup there what
151 * triples are possible */
153 const char *cpu = triple_string;
155 machine_triple_t *triple = XMALLOCZ(machine_triple_t);
157 size_t cpu_type_len = manufacturer-cpu;
158 triple->cpu_type = XMALLOCN(char, cpu_type_len);
159 memcpy(triple->cpu_type, cpu, cpu_type_len-1);
160 triple->cpu_type[cpu_type_len-1] = '\0';
162 /* process manufacturer, alot of people incorrectly leave out the
163 * manufacturer instead of using unknown- */
164 if (strstart(manufacturer, "linux")) {
165 triple->manufacturer = xstrdup("unknown");
168 size_t manufacturer_len = os-manufacturer;
169 triple->manufacturer = XMALLOCN(char, manufacturer_len);
170 memcpy(triple->manufacturer, manufacturer, manufacturer_len-1);
171 triple->manufacturer[manufacturer_len-1] = '\0';
174 triple->operating_system = xstrdup(os);