Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}