rosenberg: handle bit fields better
[smatch.git] / target-riscv.c
blob6d9113c125eee0379e56183f247d482951f8832b
1 #include "lib.h"
2 #include "symbol.h"
3 #include "target.h"
4 #include "machine.h"
5 #include <string.h>
7 #define RISCV_32BIT (1 << 0)
8 #define RISCV_64BIT (1 << 1)
9 #define RISCV_MUL (1 << 2)
10 #define RISCV_DIV (1 << 3)
11 #define RISCV_ATOMIC (1 << 4)
12 #define RISCV_FLOAT (1 << 5)
13 #define RISCV_DOUBLE (1 << 6)
14 #define RISCV_FDIV (1 << 7)
15 #define RISCV_COMP (1 << 8)
16 #define RISCV_EMBD (1 << 9)
17 #define RISCV_FPU (RISCV_FLOAT|RISCV_DOUBLE|RISCV_FDIV)
18 #define RISCV_GENERIC (RISCV_MUL|RISCV_DIV|RISCV_ATOMIC|RISCV_FPU)
20 static unsigned int riscv_flags;
22 static void parse_march_riscv(const char *arg)
24 static struct {
25 const char *pattern;
26 unsigned int flags;
27 } basic_sets[] = {
28 { "rv32i", RISCV_32BIT },
29 { "rv32e", RISCV_32BIT|RISCV_EMBD },
30 { "rv32g", RISCV_32BIT|RISCV_GENERIC },
31 { "rv64i", RISCV_64BIT },
32 { "rv64g", RISCV_64BIT|RISCV_GENERIC },
33 }, extensions[] = {
34 { "m", RISCV_MUL|RISCV_DIV },
35 { "a", RISCV_ATOMIC },
36 { "f", RISCV_FLOAT|RISCV_FDIV },
37 { "d", RISCV_DOUBLE|RISCV_FDIV },
38 { "g", RISCV_GENERIC },
39 { "q", 0 },
40 { "l", 0 },
41 { "c", RISCV_COMP },
42 { "b", 0 },
43 { "j", 0 },
44 { "t", 0 },
45 { "p", 0 },
46 { "v", 0 },
47 { "n", 0 },
48 { "h", 0 },
49 { "s", 0 },
51 int i;
53 for (i = 0; i < ARRAY_SIZE(basic_sets); i++) {
54 const char *pat = basic_sets[i].pattern;
55 size_t len = strlen(pat);
57 if (!strncmp(arg, pat, len)) {
58 riscv_flags |= basic_sets[i].flags;
59 arg += len;
60 goto ext;
63 die("invalid argument to '-march': '%s'\n", arg);
65 ext:
66 for (i = 0; i < ARRAY_SIZE(extensions); i++) {
67 const char *pat = extensions[i].pattern;
68 size_t len = strlen(pat);
70 if (!strncmp(arg, pat, len)) {
71 riscv_flags |= extensions[i].flags;
72 arg += len;
75 if (arg[0])
76 die("invalid argument to '-march': '%s'\n", arg);
79 static void init_riscv(const struct target *self)
81 if (arch_cmodel == CMODEL_UNKNOWN)
82 arch_cmodel = CMODEL_MEDLOW;
83 if (fpic)
84 arch_cmodel = CMODEL_PIC;
86 if (riscv_flags == 0)
87 riscv_flags = self->flags;
90 static void init_riscv32(const struct target *self)
92 fast16_ctype = &int_ctype;
93 ufast16_ctype = &uint_ctype;
94 fast32_ctype = &int_ctype;
95 ufast32_ctype = &uint_ctype;
97 init_riscv(self);
100 static void predefine_riscv(const struct target *self)
102 static const char *cmodels[CMODEL_LAST] = {
103 [CMODEL_MEDANY] = "medany",
104 [CMODEL_MEDLOW] = "medlow",
105 [CMODEL_PIC] = "pic",
107 const char *cmodel = cmodels[arch_cmodel];
109 predefine("__riscv", 1, "1");
110 predefine("__riscv_xlen", 1, "%d", ptr_ctype.bit_size);
112 if (riscv_flags & RISCV_ATOMIC)
113 predefine("__riscv_atomic", 1, "1");
114 if (riscv_flags & RISCV_COMP)
115 predefine("__riscv_compressed", 1, "1");
116 if (riscv_flags & RISCV_DIV)
117 predefine("__riscv_div", 1, "1");
118 if (riscv_flags & RISCV_EMBD)
119 predefine("__riscv_32e", 1, "1");
120 if (riscv_flags & RISCV_FPU)
121 predefine("__riscv_flen", 1, "%d", (riscv_flags & RISCV_DOUBLE) ? 64 : 32);
122 if (riscv_flags & RISCV_FDIV)
123 predefine("__riscv_fdiv", 1, "1");
124 if (riscv_flags & RISCV_FDIV)
125 predefine("__riscv_fsqrt", 1, "1");
126 if (riscv_flags & RISCV_MUL)
127 predefine("__riscv_mul", 1, "1");
128 if ((riscv_flags & RISCV_MUL) && (riscv_flags & RISCV_DIV))
129 predefine("__riscv_muldiv", 1, "1");
131 if (cmodel)
132 predefine_strong("__riscv_cmodel_%s", cmodel);
135 const struct target target_riscv32 = {
136 .mach = MACH_RISCV32,
137 .bitness = ARCH_LP32,
138 .big_endian = 0,
139 .unsigned_char = 1,
140 .flags = RISCV_32BIT|RISCV_GENERIC|RISCV_COMP,
142 .target_64bit = &target_riscv64,
144 .init = init_riscv32,
145 .predefine = predefine_riscv,
146 .parse_march = parse_march_riscv,
149 const struct target target_riscv64 = {
150 .mach = MACH_RISCV64,
151 .bitness = ARCH_LP64,
152 .big_endian = 0,
153 .unsigned_char = 1,
154 .has_int128 = 1,
155 .flags = RISCV_64BIT|RISCV_GENERIC|RISCV_COMP,
157 .target_32bit = &target_riscv32,
159 .init = init_riscv,
160 .predefine = predefine_riscv,
161 .parse_march = parse_march_riscv,