• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "lib.h"
2 #include "symbol.h"
3 #include "target.h"
4 #include "machine.h"
5 #include <string.h>
6 
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)
19 
20 static unsigned int riscv_flags;
21 
parse_march_riscv(const char * arg)22 static void parse_march_riscv(const char *arg)
23 {
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 },
50 	};
51 	int i;
52 
53 	for (i = 0; i < ARRAY_SIZE(basic_sets); i++) {
54 		const char *pat = basic_sets[i].pattern;
55 		size_t len = strlen(pat);
56 
57 		if (!strncmp(arg, pat, len)) {
58 			riscv_flags |= basic_sets[i].flags;
59 			arg += len;
60 			goto ext;
61 		}
62 	}
63 	die("invalid argument to '-march': '%s'\n", arg);
64 
65 ext:
66 	for (i = 0; i < ARRAY_SIZE(extensions); i++) {
67 		const char *pat = extensions[i].pattern;
68 		size_t len = strlen(pat);
69 
70 		if (!strncmp(arg, pat, len)) {
71 			riscv_flags |= extensions[i].flags;
72 			arg += len;
73 		}
74 	}
75 	if (arg[0])
76 		die("invalid argument to '-march': '%s'\n", arg);
77 }
78 
init_riscv(const struct target * self)79 static void init_riscv(const struct target *self)
80 {
81 	if (arch_cmodel == CMODEL_UNKNOWN)
82 		arch_cmodel = CMODEL_MEDLOW;
83 	if (fpic)
84 		arch_cmodel = CMODEL_PIC;
85 
86 	if (riscv_flags == 0)
87 		riscv_flags = self->flags;
88 }
89 
init_riscv32(const struct target * self)90 static void init_riscv32(const struct target *self)
91 {
92 	fast16_ctype = &int_ctype;
93 	ufast16_ctype = &uint_ctype;
94 	fast32_ctype = &int_ctype;
95 	ufast32_ctype = &uint_ctype;
96 
97 	init_riscv(self);
98 }
99 
predefine_riscv(const struct target * self)100 static void predefine_riscv(const struct target *self)
101 {
102 	static const char *cmodels[CMODEL_LAST] = {
103 		[CMODEL_MEDANY] = "medany",
104 		[CMODEL_MEDLOW] = "medlow",
105 		[CMODEL_PIC]    = "pic",
106 	};
107 	const char *cmodel = cmodels[arch_cmodel];
108 
109 	predefine("__riscv", 1, "1");
110 	predefine("__riscv_xlen", 1, "%d", ptr_ctype.bit_size);
111 
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");
130 
131 	if (cmodel)
132 		predefine_strong("__riscv_cmodel_%s", cmodel);
133 }
134 
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,
141 
142 	.target_64bit = &target_riscv64,
143 
144 	.init = init_riscv32,
145 	.predefine = predefine_riscv,
146 	.parse_march = parse_march_riscv,
147 };
148 
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,
156 
157 	.target_32bit = &target_riscv32,
158 
159 	.init = init_riscv,
160 	.predefine = predefine_riscv,
161 	.parse_march = parse_march_riscv,
162 };
163