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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include "antcc.h"
#include "c_type.h"
extern const struct MCTarg t_x86_64_sysv, t_aarch64_aapcs;
static const struct Targ {
struct { enum mcarch arch; uint oss, abis; };
struct { uchar longsize, vlongsize, ptrsize, valistsize; };
struct { uchar longalign, vlongalign, doublealign, ptralign; };
bool charsigned;
uchar sizetype, ptrdifftype, wchartype;
const struct MCTarg *mctarg;
} targs[] = {
{ {ISx86_64, -1, -1}, {8,8,8,24}, {8,8,8,8}, 1, TYULONG, TYLONG, TYINT, &t_x86_64_sysv },
{ {ISaarch64, -1, -1}, {8,8,8,32}, {8,8,8,8}, 0, TYULONG, TYLONG, TYUINT, &t_aarch64_aapcs },
};
TargTriple target;
uchar targ_primsizes[TYPTR+1];
uchar targ_primalign[TYPTR+1];
uint targ_valistsize;
enum typetag targ_sizetype, targ_ptrdifftype, targ_wchartype;
bool targ_charsigned, targ_bigendian, targ_64bit;
enum mcarch targ_arch;
const struct MCTarg *mctarg;
static bool
matchstr(const char **s, const char *pat)
{
const char *p;
for (p = *s; *pat; ++p, ++pat) {
if (*pat == '$') { if (*p) return 0; else break; }
else if (*p != *pat) return 0;
}
*s = p;
return 1;
}
static bool
parsetriple(TargTriple *trg, const char *str)
{
if (matchstr(&str, "x86_64-") || matchstr(&str, "amd64-"))
trg->arch = ISx86_64;
else if (matchstr(&str, "aarch64-") || matchstr(&str, "arm64-"))
trg->arch = ISaarch64;
else return 0;
if (matchstr(&str, "unknown-") || matchstr(&str, "pc-")) {}
if (matchstr(&str, "linux$")) {
trg->os = OSlinux;
trg->abi = ABIgnu;
return 1;
} else if (matchstr(&str, "linux")) {
trg->os = OSlinux;
} else if (matchstr(&str, "openbsd")) {
trg->os = OSopenbsd;
} else return 0;
if (trg->os == OSlinux && matchstr(&str, "-gnu")) {
trg->abi = ABIgnu;
} else if (trg->os == OSlinux && matchstr(&str, "-musl")) {
trg->abi = ABImusl;
} else if (matchstr(&str, "-")) {
return 0;
}
return 1;
}
#include "hostconfig.h" /* run ./configure */
void
targ_init(const char *starg)
{
const struct Targ *t = NULL;
uchar *sizes = targ_primsizes, *align = targ_primalign;
if (!starg) {
target.arch = HOST_ARCH;
target.os = HOST_OS;
target.abi = HOST_ABI;
} else if (!parsetriple(&target, starg)) {
fatal(NULL, "unrecognized target: %s", starg);
}
for (size_t i = 0; i < countof(targs); ++i) {
if (targs[i].arch == target.arch)
if (targs[i].oss & (1 << target.os))
if (targs[i].abis & (1 << target.abi)) {
t = &targs[i];
break;
}
}
if (!t) fatal(NULL, "unsupported target: %s", starg ? starg : HOST_TRIPLE);
sizes[TYBOOL] = sizes[TYCHAR] = sizes[TYSCHAR] = sizes[TYUCHAR] = 1;
sizes[TYSHORT] = sizes[TYUSHORT] = 2;
sizes[TYUINT] = sizes[TYINT] = 4;
sizes[TYFLOAT] = 4;
sizes[TYDOUBLE] = 8;
sizes[TYLDOUBLE] = 8;
memcpy(align, sizes, sizeof targ_primalign);
sizes[TYULONG] = sizes[TYLONG] = t->longsize;
sizes[TYUVLONG] = sizes[TYVLONG] = t->vlongsize;
sizes[TYPTR] = t->ptrsize;
align[TYULONG] = align[TYLONG] = t->longalign;
align[TYUVLONG] = align[TYVLONG] = t->vlongalign;
align[TYDOUBLE] = t->doublealign;
align[TYLDOUBLE] = t->doublealign;
align[TYPTR] = t->ptralign;
sizes[TYCOMPLEXF] = sizes[TYFLOAT]*2;
sizes[TYCOMPLEX] = sizes[TYDOUBLE]*2;
sizes[TYCOMPLEXL] = sizes[TYLDOUBLE]*2;
align[TYCOMPLEXF] = align[TYFLOAT];
align[TYCOMPLEX] = align[TYDOUBLE];
align[TYCOMPLEXL] = align[TYLDOUBLE];
targ_valistsize = t->valistsize;
targ_sizetype = t->sizetype;
targ_ptrdifftype = t->ptrdifftype;
targ_wchartype = t->wchartype;
targ_charsigned = t->charsigned;
targ_bigendian = 0;
targ_64bit = t->ptrsize == 8;
mctarg = t->mctarg;
targ_arch = ISx86_64;
}
|