implied: try again in get_tf_stacks_from_pool()
[smatch.git] / target-riscv.c
blob7a1849738de8a7811127b1ff7cc11889000603f2
1 #include "lib.h"
2 #include "symbol.h"
3 #include "target.h"
4 #include "machine.h"
5 #include <string.h>
6 #include <stdio.h>
8 #define RISCV_32BIT (1 << 0)
9 #define RISCV_64BIT (1 << 1)
10 #define RISCV_MUL (1 << 2)
11 #define RISCV_DIV (1 << 3)
12 #define RISCV_ATOMIC (1 << 4)
13 #define RISCV_FLOAT (1 << 5)
14 #define RISCV_DOUBLE (1 << 6)
15 #define RISCV_FDIV (1 << 7)
16 #define RISCV_COMP (1 << 8)
17 #define RISCV_EMBD (1 << 9)
18 #define RISCV_FPU (RISCV_FLOAT|RISCV_DOUBLE|RISCV_FDIV)
19 #define RISCV_GENERIC (RISCV_MUL|RISCV_DIV|RISCV_ATOMIC|RISCV_FPU)
20 #define RISCV_ZICSR (1 << 10)
21 #define RISCV_ZIFENCEI (1 << 11)
22 #define RISCV_ZICBOM (1 << 12)
23 #define RISCV_ZIHINTPAUSE (1 << 13)
25 static unsigned int riscv_flags;
27 static void parse_march_riscv(const char *arg)
29 static struct {
30 const char *pattern;
31 unsigned int flags;
32 } basic_sets[] = {
33 { "rv32i", RISCV_32BIT },
34 { "rv32e", RISCV_32BIT|RISCV_EMBD },
35 { "rv32g", RISCV_32BIT|RISCV_GENERIC },
36 { "rv64i", RISCV_64BIT },
37 { "rv64g", RISCV_64BIT|RISCV_GENERIC },
38 }, extensions[] = {
39 { "m", RISCV_MUL|RISCV_DIV },
40 { "a", RISCV_ATOMIC },
41 { "f", RISCV_FLOAT|RISCV_FDIV|RISCV_ZICSR },
42 { "d", RISCV_DOUBLE|RISCV_FDIV|RISCV_ZICSR },
43 { "c", RISCV_COMP },
44 { "_zicsr", RISCV_ZICSR },
45 { "_zifencei", RISCV_ZIFENCEI },
46 { "_zicbom", RISCV_ZICBOM },
47 { "_zihintpause", RISCV_ZIHINTPAUSE },
49 int i;
51 // Each -march=.. options entirely overrides previous ones
52 riscv_flags = 0;
54 for (i = 0; i < ARRAY_SIZE(basic_sets); i++) {
55 const char *pat = basic_sets[i].pattern;
56 size_t len = strlen(pat);
58 if (!strncmp(arg, pat, len)) {
59 riscv_flags |= basic_sets[i].flags;
60 arg += len;
61 goto ext;
65 unknown:
66 fprintf(stderr, "WARNING: invalid argument to '-march': '%s'\n", arg);
67 return;
69 ext:
70 for (i = 0; i < ARRAY_SIZE(extensions); i++) {
71 const char *pat = extensions[i].pattern;
72 size_t len = strlen(pat);
74 if (!strncmp(arg, pat, len)) {
75 riscv_flags |= extensions[i].flags;
76 arg += len;
79 if (arg[0])
80 goto unknown;
83 static void init_riscv(const struct target *self)
85 if (arch_cmodel == CMODEL_UNKNOWN)
86 arch_cmodel = CMODEL_MEDLOW;
87 if (fpic)
88 arch_cmodel = CMODEL_PIC;
90 if (riscv_flags == 0)
91 riscv_flags = self->flags;
94 static void init_riscv32(const struct target *self)
96 fast16_ctype = &int_ctype;
97 ufast16_ctype = &uint_ctype;
98 fast32_ctype = &int_ctype;
99 ufast32_ctype = &uint_ctype;
101 init_riscv(self);
104 static void predefine_riscv(const struct target *self)
106 static const char *cmodels[CMODEL_LAST] = {
107 [CMODEL_MEDANY] = "medany",
108 [CMODEL_MEDLOW] = "medlow",
109 [CMODEL_PIC] = "pic",
111 const char *cmodel = cmodels[arch_cmodel];
113 predefine("__riscv", 1, "1");
114 predefine("__riscv_xlen", 1, "%d", ptr_ctype.bit_size);
116 if (riscv_flags & RISCV_ATOMIC)
117 predefine("__riscv_atomic", 1, "1");
118 if (riscv_flags & RISCV_COMP)
119 predefine("__riscv_compressed", 1, "1");
120 if (riscv_flags & RISCV_DIV)
121 predefine("__riscv_div", 1, "1");
122 if (riscv_flags & RISCV_EMBD)
123 predefine("__riscv_32e", 1, "1");
124 if (riscv_flags & RISCV_FPU)
125 predefine("__riscv_flen", 1, "%d", (riscv_flags & RISCV_DOUBLE) ? 64 : 32);
126 if (riscv_flags & RISCV_FDIV)
127 predefine("__riscv_fdiv", 1, "1");
128 if (riscv_flags & RISCV_FDIV)
129 predefine("__riscv_fsqrt", 1, "1");
130 if (riscv_flags & RISCV_MUL)
131 predefine("__riscv_mul", 1, "1");
132 if ((riscv_flags & RISCV_MUL) && (riscv_flags & RISCV_DIV))
133 predefine("__riscv_muldiv", 1, "1");
134 if (riscv_flags & RISCV_ZICSR)
135 predefine("__riscv_zicsr", 1, "1");
136 if (riscv_flags & RISCV_ZIFENCEI)
137 predefine("__riscv_zifencei", 1, "1");
138 if (riscv_flags & RISCV_ZICBOM)
139 predefine("__riscv_zicbom", 1, "1");
140 if (riscv_flags & RISCV_ZIHINTPAUSE)
141 predefine("__riscv_zihintpause", 1, "1");
143 if (cmodel)
144 predefine_strong("__riscv_cmodel_%s", cmodel);
147 const struct target target_riscv32 = {
148 .mach = MACH_RISCV32,
149 .bitness = ARCH_LP32,
150 .big_endian = 0,
151 .unsigned_char = 1,
152 .flags = RISCV_32BIT|RISCV_GENERIC|RISCV_COMP,
154 .target_64bit = &target_riscv64,
156 .init = init_riscv32,
157 .predefine = predefine_riscv,
158 .parse_march = parse_march_riscv,
161 const struct target target_riscv64 = {
162 .mach = MACH_RISCV64,
163 .bitness = ARCH_LP64,
164 .big_endian = 0,
165 .unsigned_char = 1,
166 .has_int128 = 1,
167 .flags = RISCV_64BIT|RISCV_GENERIC|RISCV_COMP,
169 .target_32bit = &target_riscv32,
171 .init = init_riscv,
172 .predefine = predefine_riscv,
173 .parse_march = parse_march_riscv,