Esempio n. 1
0
static void determine_target_machine(void)
{
	if (target.machine == NULL)
		target.machine = ir_get_host_machine_triple();
	/* adjust for -m32/-m64 flag */
	const char *cpu = ir_triple_get_cpu_type(target.machine);
	if (is_ia32_cpu(cpu) && target_size_override == 64) {
		ir_triple_set_cpu_type(target.machine, "x86_64");
	} else if (is_amd64_cpu(cpu) && target_size_override == 32) {
		ir_triple_set_cpu_type(target.machine, "i686");
	}
}
Esempio n. 2
0
static void determine_target_machine(void)
{
	if (target.machine == NULL)
		target.machine = get_host_machine_triple();
	/* adjust for -m32/-m64 flag */
	const char *cpu = target.machine->cpu_type;
	if (is_ia32_cpu(cpu) && target_size_override == 64) {
		free(target.machine->cpu_type);
		target.machine->cpu_type = xstrdup("x86_64");
	} else if (is_amd64_cpu(cpu) && target_size_override == 32) {
		free(target.machine->cpu_type);
		target.machine->cpu_type = xstrdup("i686");
	}
}
Esempio n. 3
0
static void set_options_for_machine(machine_triple_t const *const machine)
{
	/* Note: Code here should only check the target triple! Querying other
	 * target features is not allowed as subsequent commandline options may
	 * change those. Example:
	 * ppdefc("X", "Y", cond_not_strict); // Correct: cond_not_strict is
	 *                                    // evaluated later
	 * if (dialect.gnu)
	 *    ppdef("X", "Y"); // Wrong: language dialect/target is not final yet
	 */
	const char *const cpu          = machine->cpu_type;
	const char *const manufacturer = machine->manufacturer;
	const char *const os           = machine->operating_system;
	unsigned                              pointer_size;
	unsigned                              long_double_size;
	unsigned                              modulo_shift;
	float_int_conversion_overflow_style_t float_int_overflow;
	const char                           *firm_isa;
	if (target.firm_isa_specified) {
		/* Firm ISA was specified on the commandline, this may be used to
		 * experiment with new firm backends. */
		firm_isa = target.firm_isa;
		unsigned size = target_size_override != 0
		              ? target_size_override/BITS_PER_BYTE : 4;
		pointer_size       = size;
		long_double_size   = 8;
		modulo_shift       = size * BITS_PER_BYTE;
		float_int_overflow = ir_overflow_indefinite;

	/* i386, i486, i586, i686, i786 */
	} else if (is_ia32_cpu(cpu)) {
		ppdefc("i386",     "1", cond_not_strict);
		ppdef( "__i386",   "1");
		ppdef( "__i386__", "1");
		switch (cpu[1]) {
		case '4':
			ppdef("__i486",   "1");
			ppdef("__i486__", "1");
			break;
		case '5':
			ppdef("__i586",      "1");
			ppdef("__i586__",    "1");
			ppdef("__pentium",   "1");
			ppdef("__pentium__", "1");
			//ppdef("__pentium_mmx__", "1");
			break;
		case '6':
			ppdef("__pentiumpro",   "1");
			ppdef("__pentiumpro__", "1");
			ppdef("__i686",         "1");
			ppdef("__i686__",       "1");
			break;
		case '7':
			ppdef("__pentium4",     "1");
			ppdef("__pentium4__",   "1");
			break;
		}
		firm_isa           = "ia32";
		pointer_size       = 4;
		modulo_shift       = 32;
		long_double_size   = 12;
		float_int_overflow = ir_overflow_indefinite;
		target.firm_arch   = cpu;
		/* long long and double has a 4 byte alignment inside structs, this odd
		 * mode is everywhere except for windows OSes (they will revert it
		 * below) */
		dialect.long_long_and_double_struct_align = 4;
		dialect.long_double_x87_80bit_float       = true;
	} else if (streq(cpu, "sparc")) {
		ppdefc("sparc",     "1", cond_not_strict);
		ppdef( "__sparc",   "1");
		ppdef( "__sparc__", "1");
		/* we always produce sparc V8 code at the moment */
		ppdef( "__sparc_v8__", "1");
		if (strstr(manufacturer, "leon") != NULL
		 || streq(manufacturer, "invasic")) {
			ppdef("__leon__", "1");
			set_be_option("sparc-cpu=leon");
		}
		firm_isa           = "sparc";
		pointer_size       = 4;
		modulo_shift       = 32;
		long_double_size   = 16;
		float_int_overflow = ir_overflow_min_max;
		target.byte_order_big_endian = true;
	} else if (streq(cpu, "arm")) {
		/* TODO: test, what about
		 * ARM_FEATURE_UNALIGNED, ARMEL, ARM_ARCH_7A, ARM_FEATURE_DSP, ... */
		ppdef("__arm__",   "1");
		if (strstr(os, "eabi") != NULL)
			ppdef("__ARM_EABI__", "1");
		firm_isa           = "arm";
		pointer_size       = 4;
		modulo_shift       = 256;
		long_double_size   = 8;
		float_int_overflow = ir_overflow_min_max;
	} else if (is_amd64_cpu(cpu)) {
		ppdef("__x86_64",   "1");
		ppdef("__x86_64__", "1");
		ppdef("__amd64",    "1");
		ppdef("__amd64__",  "1");
		firm_isa           = "amd64";
		pointer_size       = 8;
		modulo_shift       = 32;
		long_double_size   = 16;
		float_int_overflow = ir_overflow_indefinite;
		dialect.long_double_x87_80bit_float = true;
	} else {
		errorf(NULL, "unknown cpu '%s' in target-triple", cpu);
		exit(EXIT_FAILURE);
	}

	target.firm_isa            = firm_isa;
	target.modulo_shift        = modulo_shift;
	target.float_int_overflow  = float_int_overflow;
	dialect.pointer_size       = pointer_size;
	dialect.int_size           = MIN(pointer_size, 4);
	dialect.long_size          = MIN(pointer_size, 8);
	dialect.long_double_size   = long_double_size;
	dialect.wchar_atomic_kind  = ATOMIC_TYPE_INT;
	dialect.pointer_sized_int  = ATOMIC_TYPE_LONG;
	dialect.pointer_sized_uint = ATOMIC_TYPE_ULONG;

	set_compilerlib_name_mangle(compilerlib_name_mangle);

	if (strstr(os, "linux") != NULL) {
		init_generic_elf();
		init_unix();
		ppdef( "__linux",   "1");
		ppdef( "__linux__", "1");
		ppdefc("linux",     "1", cond_not_strict);
		if (strstr(os, "gnu") != NULL)
			ppdef("__gnu_linux__", "1");
	} else if (strstr(os, "bsd") != NULL) {
		init_generic_elf();
		init_unix();
	} else if (streq(os, "elf") || streq(os, "octopos") || streq(os, "irtss")) {
		init_generic_elf();
	} else if (strstart(os, "darwin")) {
		driver_default_exe_output = "a.out";
		set_create_ld_ident(create_name_macho);
		target.user_label_prefix = "_";
		target.object_format = OBJECT_FORMAT_MACH_O;
		target.pic_mode = 2;
		set_be_option("ia32-stackalign=4");
		set_be_option("ia32-struct_in_reg=yes");
		dialect.long_double_size = 16;
		ppdef( "__MACH__",               "1");
		ppdef( "__APPLE__",              "1");
		ppdef( "__APPLE_CC__",           "1");
		ppdef( "__weak",                 "");
		ppdef( "__strong",               "");
		ppdef( "__CONSTANT_CFSTRINGS__", "1");
		ppdef( "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", "1050");
		ppdef( "__DYNAMIC__",            "1");
		ppdefc("__LITTLE_ENDIAN__",      "1", cond_is_little_endian);
	} else if (strstart(os, "mingw")) {
		dialect.wchar_atomic_kind = ATOMIC_TYPE_USHORT;
		driver_default_exe_output = "a.exe";
		target.object_format = OBJECT_FORMAT_PE_COFF;
		set_be_option("ia32-struct_in_reg=no");
		dialect.enable_main_collect2_hack = true;
		ppdef("__MINGW32__", "1");
		dialect.long_long_and_double_struct_align = 0;
		ppdef( "__MSVCRT__", "1");
		ppdef( "_WINNT",     "1");
		ppdef( "__WINNT",    "1");
		ppdef( "__WINNT__",  "1");
		ppdefc("WINNT",      "1", cond_not_strict);
		ppdef( "_WIN32",     "1");
		ppdef( "__WIN32",    "1");
		ppdef( "__WIN32__",  "1");
		ppdefc("WIN32",      "1", cond_not_strict);
		if (pointer_size == 8) {
			set_be_option("amd64-x64abi=yes");
			set_create_ld_ident(create_name_win64);
			ppdef( "_WIN64",    "1");
			ppdef( "__WIN64",   "1");
			ppdef( "__WIN64__", "1");
			ppdefc("WIN64",     "1", cond_not_strict);
			ppdef( "__MINGW64__", "1");
			/* to ease porting of old c-code microsoft decided to use 32bits
			 * even for long */
			dialect.long_size = 4;
			dialect.pointer_sized_int  = ATOMIC_TYPE_LONGLONG;
			dialect.pointer_sized_uint = ATOMIC_TYPE_ULONGLONG;
		} else {
			assert(pointer_size == 4);
			set_create_ld_ident(create_name_win32);
			target.user_label_prefix = "_";
			dialect.pointer_sized_int  = ATOMIC_TYPE_INT;
			dialect.pointer_sized_uint = ATOMIC_TYPE_UINT;
		}
	} else if (strstart(os, "midipix")) {
		driver_default_exe_output = "a.out";
		target.object_format = OBJECT_FORMAT_PE_COFF;
		set_be_option("ia32-struct_in_reg=no");
		dialect.long_long_and_double_struct_align = 0;
		ppdef("__midipix__", "1");
		if (pointer_size == 8) {
			set_be_option("amd64-x64abi=yes");
			set_create_ld_ident(create_name_win64);
			ppdef("__NT64", "1");
		} else {
			assert(pointer_size == 4);
			set_create_ld_ident(create_name_win32);
			target.user_label_prefix = "_";
			ppdef("__NT32", "1");
		}
	} else {
		errorf(NULL, "unknown operating system '%s' in target-triple", os);
		exit(EXIT_FAILURE);
	}
}