summaryrefslogtreecommitdiffstats
path: root/libsyscalls_get_integer_alignment.c
blob: 1c2d10e6f639c6e36e65194a1750e43963b59eff (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* See LICENSE file for copyright and license details. */
#include "common.h"


#include "generated/integers.c"

enum libsyscalls_error
libsyscalls_get_integer_alignment(enum libsyscalls_os os, enum libsyscalls_arch arch, unsigned width_in_bits, unsigned *alignment_out)
{
	unsigned maxalign;

	if (!width_in_bits)
		return LIBSYSCALLS_E_INVAL;

	switch ((int)arch) {
	case LIBSYSCALLS_ARCH_M68K: /* https://m680x0.github.io/doc/abi.html#scalar-types
	                             * https://lists.nongnu.org/archive/html/qemu-devel/2015-02/msg04797.html */
		maxalign = 16;
		break;

	case LIBSYSCALLS_ARCH_I386:
	case LIBSYSCALLS_ARCH_ARM_OABI_LE: /* https://wiki.debian.org/ArmEabiPort#A64-bit_data_type_alignment */
	case LIBSYSCALLS_ARCH_ARM_OABI_BE:
	case LIBSYSCALLS_ARCH_SH_LE: /* https://www.st.com/resource/en/reference_manual/rm0197-sh4-generic-and-c-specific-application-binary-interface-stmicroelectronics.pdf (page 12) */
	case LIBSYSCALLS_ARCH_SH_BE:
	case LIBSYSCALLS_ARCH_MICROBLAZE_32_LE: /* https://www.ecb.torontomu.ca/~courses/ee8205/Data-Sheets/sopc/MicroBlaze_DataSheet.pdf */
	case LIBSYSCALLS_ARCH_MICROBLAZE_32_BE:
		maxalign = 32;
		break;

	case LIBSYSCALLS_ARCH_AMD64:
	case LIBSYSCALLS_ARCH_AMD64_X32:
	case LIBSYSCALLS_ARCH_ARM_EABI_LE: /* https://wiki.debian.org/ArmEabiPort#A64-bit_data_type_alignment */
	case LIBSYSCALLS_ARCH_ARM_EABI_BE:
	case LIBSYSCALLS_ARCH_ALPHA_LE: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
	case LIBSYSCALLS_ARCH_ALPHA_BE:
	case LIBSYSCALLS_ARCH_IA64_LE: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
	case LIBSYSCALLS_ARCH_IA64_BE:
	case LIBSYSCALLS_ARCH_IA64_P32_LE:
	case LIBSYSCALLS_ARCH_IA64_P32_BE:
	case LIBSYSCALLS_ARCH_MIPS_O32_LE: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
	case LIBSYSCALLS_ARCH_MIPS_O32_BE:
	case LIBSYSCALLS_ARCH_MIPS_N32_LE: /* https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00083-2B-MIPS64INT-AFP-05.04.pdf (page 40) */
	case LIBSYSCALLS_ARCH_MIPS_N32_BE:
	case LIBSYSCALLS_ARCH_MIPS_N64_LE:
	case LIBSYSCALLS_ARCH_MIPS_N64_BE:
	case LIBSYSCALLS_ARCH_PARISC_32: /* https://www.ece.lsu.edu/ee4720/doc/pa1.1.pdf (page 26) */
	case LIBSYSCALLS_ARCH_PARISC_64:
	case LIBSYSCALLS_ARCH_POWERPC_32_LE: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
	case LIBSYSCALLS_ARCH_POWERPC_32_BE:
	case LIBSYSCALLS_ARCH_POWERPC_64_LE: /* https://www.slac.stanford.edu/exp/npa/software/eabi_app.pdf */
	case LIBSYSCALLS_ARCH_POWERPC_64_BE:
	case LIBSYSCALLS_ARCH_POWERPC_NOSPU_LE:
	case LIBSYSCALLS_ARCH_POWERPC_NOSPU_BE:
	case LIBSYSCALLS_ARCH_POWERPC_SPU_LE:
	case LIBSYSCALLS_ARCH_POWERPC_SPU_BE:
	case LIBSYSCALLS_ARCH_S390_32: /* https://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_s390.html */
	case LIBSYSCALLS_ARCH_S390_64:
	case LIBSYSCALLS_ARCH_SPARC_32: /* https://www.gaisler.com/doc/sparcv8.pdf (page 46) */
	case LIBSYSCALLS_ARCH_SPARC_64_LE: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
	case LIBSYSCALLS_ARCH_SPARC_64_BE:
	case LIBSYSCALLS_ARCH_XTENSA_LE: /* https://loboris.eu/ESP32/Xtensa_lx%20Overview%20handbook.pdf (page 97) */
	case LIBSYSCALLS_ARCH_XTENSA_BE:
	case LIBSYSCALLS_ARCH_MICROBLAZE_64_LE: /* https://www.amd.com/content/dam/xilinx/support/documents/sw_manuals/xilinx2021_2/ug984-vivado-microblaze-ref.pdf */
	case LIBSYSCALLS_ARCH_MICROBLAZE_64_BE:
		maxalign = 64;
		break;

	default:
		return LIBSYSCALLS_E_ARCHNOSUP;
	}

	if (width_in_bits & (width_in_bits - 1) || width_in_bits & 7 || width_in_bits > 64)
		return LIBSYSCALLS_E_NOSUCHTYPE;
	*alignment_out = width_in_bits < maxalign ? width_in_bits : maxalign;

#define CASE(UPPERCASE, LOWERCASE)\
	case LIBSYSCALLS_OS_##UPPERCASE:\
		return get_##LOWERCASE##_integer_alignment(arch, width_in_bits, alignment_out)

	switch ((int)os) {
	LIST_OSES(CASE, ;);
	default:
		return LIBSYSCALLS_E_OSNOSUP;
	}

#undef CASE
}