static bool setup_firm_isa(void) { const char *isa = target.firm_isa; char buf[64]; snprintf(buf, sizeof(buf), "isa=%s", isa); if (!be_parse_arg(buf)) { errorf(NULL, "Couldn't select firm isa '%s'", isa); return false; } const char *arch = target.firm_arch; /* only pass down for ia32 for now */ if (arch != NULL && streq(isa, "ia32")) { snprintf(buf, sizeof(buf), "%s-arch=%s", isa, arch); if (!be_parse_arg(buf)) { errorf(NULL, "Couldn't select firm arch '%s-arch=%s'", isa, arch); return false; } } if (streq(isa, "amd64")) { experimental_backend = "the x86_64 backend is highly experimental and unfinished (consider the -m32 switch)"; } else if (streq(isa, "arm")) { experimental_backend = "the arm backend is highly experimental and unfinished"; } return true; }
static bool pass_options_to_firm_be(void) { switch (target.object_format) { case OBJECT_FORMAT_ELF: set_be_option("objectformat=elf"); break; case OBJECT_FORMAT_MACH_O: set_be_option("objectformat=mach-o"); break; case OBJECT_FORMAT_PE_COFF: set_be_option("objectformat=coff"); break; } if (profile_generate) { driver_add_flag(&ldflags_obst, "-lfirmprof"); set_be_option("profilegenerate"); } if (profile_use) { set_be_option("profileuse"); } bool res = true; const char *pic_option; if (target.pic_mode > 0) { /* Select correct PIC mode */ if (target.object_format == OBJECT_FORMAT_MACH_O) { pic_option = "pic=mach-o"; } else { pic_option = target.pic_no_plt ? "pic=elf-noplt" : "pic=elf"; } } else { pic_option = "pic=none"; } set_be_option(pic_option); /* pass options to firm backend (this happens delayed because we first * had to decide which backend is actually used) */ for (codegen_option_t *option = codegen_options; option != NULL; option = option->next) { char buf[256]; const char *opt = option->option; /* pass option along to firm backend (except the -m32, -m64 stuff) */ snprintf(buf, sizeof(buf), "%s-%s", target.firm_isa, opt); if (be_parse_arg(buf) == 0) { errorf(NULL, "Unknown codegen option '-m%s'", opt); res = false; continue; } /* hack to emulate the behaviour of some gcc spec files which filter * flags to pass to cpp/ld/as */ static char const *const pass_to_cpp_and_ld[] = { "soft-float" }; for (size_t i = 0; i < ARRAY_SIZE(pass_to_cpp_and_ld); ++i) { if (streq(pass_to_cpp_and_ld[i], option->option)) { snprintf(buf, sizeof(buf), "-m%s", option->option); driver_add_flag(&cppflags_obst, buf); driver_add_flag(&asflags_obst, buf); driver_add_flag(&ldflags_obst, buf); break; } } } /* We can initialize the backend at this point and call be_get_backend_param() */ if (target.pic_mode > 0 && !be_get_backend_param()->pic_supported) { errorf(NULL, "Selected backend '%s' does not support position independent code (PIC)", target.firm_isa); res = false; } return res; }
bool options_parse_codegen(options_state_t *s) { const char *full_option = s->argv[s->i]; if (full_option[0] != '-') return false; const char *option = &full_option[1]; const char *arg; if ((arg = equals_arg("falign-loops", s)) != NULL || (arg = equals_arg("falign-jumps", s)) != NULL || (arg = equals_arg("falign-functions", s)) != NULL) { warningf(WARN_COMPAT_OPTION, NULL, "ignoring gcc option '%s'", full_option); } else if ((arg = equals_arg("fvisibility", s)) != NULL) { elf_visibility_t visibility = get_elf_visibility_from_string(arg); if (visibility == ELF_VISIBILITY_ERROR) { errorf(NULL, "invalid visibility '%s' specified", arg); s->argument_errors = true; } else { set_default_visibility(visibility); } } else if (accept_prefix(s, "-b", true, &arg)) { if (!be_parse_arg(arg)) { errorf(NULL, "invalid backend option '%s' (unknown option or invalid argument)", full_option); s->argument_errors = true; } else if ((arg = equals_arg("bisa", s)) != NULL) { /* This is a quick and dirty option to try out new firm targets. * Sooner rather than later the new target should be added properly * to target.c! */ target.firm_isa_specified = true; target.firm_isa = arg; } } else if (simple_arg("-unroll-loops", s)) { /* ignore (gcc compatibility) */ } else if (simple_arg("fexcess-precision=standard", s)) { /* ignore (gcc compatibility) we always adhere to the C99 standard * anyway in this respect */ } else if (accept_prefix(s, "-g", false, &arg)) { if (streq(arg, "0")) { set_be_option("debug=none"); set_be_option("ia32-optcc=true"); } else { set_be_option("debug=frameinfo"); set_be_option("ia32-optcc=false"); } } else if (accept_prefix(s, "-m", false, &arg)) { arg = &option[1]; /* remember option for backend */ assert(obstack_object_size(&codegenflags_obst) == 0); obstack_blank(&codegenflags_obst, sizeof(codegen_option_t)); size_t len = strlen(arg); obstack_grow(&codegenflags_obst, arg, len); codegen_option_t *const cg_option = obstack_nul_finish(&codegenflags_obst); cg_option->next = NULL; *codegen_options_anchor = cg_option; codegen_options_anchor = &cg_option->next; } else { bool truth_value; const char *fopt; if ((fopt = f_no_arg(&truth_value, s)) != NULL) { if (f_yesno_arg("-ffast-math", s)) { ir_allow_imprecise_float_transforms(truth_value); } else if (f_yesno_arg("-fomit-frame-pointer", s)) { set_be_option(truth_value ? "omitfp" : "omitfp=no"); } else if (f_yesno_arg("-fstrength-reduce", s)) { /* does nothing, for gcc compatibility (even gcc does * nothing for this switch anymore) */ } else if (!truth_value && (f_yesno_arg("-fasynchronous-unwind-tables", s) || f_yesno_arg("-funwind-tables", s))) { /* do nothing: a gcc feature which we do not support * anyway was deactivated */ } else if (f_yesno_arg("-frounding-math", s)) { /* ignore for gcc compatibility: we don't have any unsafe * optimizations in that area */ } else if (f_yesno_arg("-fverbose-asm", s)) { set_be_option(truth_value ? "verboseasm" : "verboseasm=no"); } else if (f_yesno_arg("-fPIC", s)) { target.pic_mode = truth_value ? 2 : 0; } else if (f_yesno_arg("-fpic", s)) { target.pic_mode = truth_value ? 1 : 0; } else if (f_yesno_arg("-fplt", s)) { target.pic_no_plt = !truth_value; } else if (f_yesno_arg("-fjump-tables", s) || f_yesno_arg("-fexpensive-optimizations", s) || f_yesno_arg("-fcommon", s) || f_yesno_arg("-foptimize-sibling-calls", s) || f_yesno_arg("-falign-loops", s) || f_yesno_arg("-falign-jumps", s) || f_yesno_arg("-falign-functions", s) || f_yesno_arg("-fstack-protector", s) || f_yesno_arg("-fstack-protector-all", s)) { /* better warn the user for these as he might have expected * that something happens */ warningf(WARN_COMPAT_OPTION, NULL, "ignoring gcc option '-f%s'", fopt); } else if (firm_option(&option[1])) { /* parsed a firm option */ } else { return false; } } else { return false; } } return true; }