History

riscv: hacky prolog, epilog and return

this now allows to compile a simple working example: int main(void) { return 0; }

Michael Matz committed 7 years ago

Commit 35d7b591 parent 1353ccd2 files · +176 −34Browse files

Unified · Split

2 files
  1. riscv64-gen.c +172 −34
  2. riscv64-link.c +4 −0
riscv64-gen.c+172−34
@@ -4,7 +4,7 @@ · 3 unmodified lines
4#define NB_REGS 16 // x10-x17 aka a0-a7, f10-f17 aka fa0-fa74#define NB_REGS 16 // x10-x17 aka a0-a7, f10-f17 aka fa0-fa7
5 5
6#define TREG_R(x) (x) // x = 0..76#define TREG_R(x) (x) // x = 0..7
7#define TREG_F(x) (x + 10) // x = 0..77#define TREG_F(x) (x + 8) // x = 0..7
8 8
9// Register classes sorted from more general to more precise:9// Register classes sorted from more general to more precise:
10#define RC_INT (1 << 0)10#define RC_INT (1 << 0)
@@ -29,6 +29,9 @@ · 18 unmodified lines
29 29
30#else30#else
31#include "tcc.h"31#include "tcc.h"
32#include <assert.h>
33
34#define XLEN 8
32 35
33ST_DATA const int reg_classes[NB_REGS] = {36ST_DATA const int reg_classes[NB_REGS] = {
34 RC_INT | RC_R(0),37 RC_INT | RC_R(0),
@@ -49,15 +52,47 @@ ST_DATA const int reg_classes[NB_REGS] = { · 14 unmodified lines
49 RC_FLOAT | RC_F(7)52 RC_FLOAT | RC_F(7)
50};53};
51 54
55static int ireg(int r)
56{
57 assert(r >= 0 && r < 8);
58 return r + 10; // tccrX --> aX == x(10+X)
59}
60
61ST_FUNC void o(unsigned int c)
62{
63 int ind1 = ind + 4;
64 if (nocode_wanted)
65 return;
66 if (ind1 > cur_text_section->data_allocated)
67 section_realloc(cur_text_section, ind1);
68 write32le(cur_text_section->data + ind, c);
69 ind = ind1;
70}
71
72static void EI(uint32_t opcode, uint32_t func3,
73 uint32_t rd, uint32_t rs1, uint32_t imm)
74{
75 assert(! ((imm + (1 << 11)) >> 12));
76 o(opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20));
77}
78
79static void ES(uint32_t opcode, uint32_t func3,
80 uint32_t rs1, uint32_t rs2, uint32_t imm)
81{
82 assert(! ((imm + (1 << 11)) >> 12));
83 o(opcode | (func3 << 12) | ((imm & 0x1f) << 7) | (rs1 << 15)
84 | (rs2 << 20) | ((imm >> 5) << 25));
85}
86
52// Patch all branches in list pointed to by t to branch to a:87// Patch all branches in list pointed to by t to branch to a:
53ST_FUNC void gsym_addr(int t_, int a_)88ST_FUNC void gsym_addr(int t_, int a_)
54{89{
55 uint32_t t = t_;90 uint32_t t = t_;
56 uint32_t a = a_;91 uint32_t a = a_;
57 tcc_error("implement me");
58 while (t) {92 while (t) {
59 unsigned char *ptr = cur_text_section->data + t;93 unsigned char *ptr = cur_text_section->data + t;
60 uint32_t next = read32le(ptr);94 uint32_t next = read32le(ptr);
95 tcc_error("implement me: %s", __FUNCTION__);
61 if (a - t + 0x8000000 >= 0x10000000)96 if (a - t + 0x8000000 >= 0x10000000)
62 tcc_error("branch out of range");97 tcc_error("branch out of range");
63 write32le(ptr, (a - t == 4 ? 0xd503201f : // nop98 write32le(ptr, (a - t == 4 ? 0xd503201f : // nop
@@ -68,46 +103,146 @@ ST_FUNC void gsym_addr(int t_, int a_) · 4 unmodified lines
68 103
69ST_FUNC void load(int r, SValue *sv)104ST_FUNC void load(int r, SValue *sv)
70{105{
71 tcc_error("implement me");106 int fr = sv->r;
107 int v = fr & VT_VALMASK;
108 int rr = ireg(r);
109 int fc = sv->c.i;
110 if (v == VT_CONST) {
111 if (fr & VT_SYM)
112 tcc_error("unimp: load(sym)");
113 if (is_float(sv->type.t))
114 tcc_error("unimp: load(float)");
115 if (fc != sv->c.i)
116 tcc_error("unimp: load(very large const)");
117 if (((unsigned)fc + (1 << 11)) >> 12)
118 tcc_error("unimp: load(large const) (0x%x)", fc);
119 EI(0x13, 0, rr, 0, fc); // addi R, x0, FC
120 } else
121 tcc_error("unimp: load(non-const)");
72}122}
73 123
74ST_FUNC void store(int r, SValue *sv)124ST_FUNC void store(int r, SValue *sv)
75{125{
76 tcc_error("implement me");126 tcc_error("implement me: %s", __FUNCTION__);
77}127}
78 128
79ST_FUNC void gfunc_call(int nb_args)129ST_FUNC void gfunc_call(int nb_args)
80{130{
81 tcc_error("implement me");131 tcc_error("implement me: %s", __FUNCTION__);
82}132}
133
134static int func_sub_sp_offset;
135
83ST_FUNC void gfunc_prolog(CType *func_type)136ST_FUNC void gfunc_prolog(CType *func_type)
84{137{
85 tcc_error("implement me");138 int i, addr, align, size;
139 int param_addr = 0;
140 int aireg, afreg;
141 Sym *sym;
142 CType *type;
143
144 sym = func_type->ref;
145 func_vt = sym->type;
146 loc = -16; /* for saved ra, and s0 */
147 func_sub_sp_offset = ind;
148 ind += 3 * 4;
149 if (sym->f.func_type == FUNC_ELLIPSIS) {
150 tcc_error("unimp: vararg prologue");
151 }
152
153 aireg = afreg = 0;
154 addr = 0; // XXX not correct
155 /* if the function returns a structure, then add an
156 implicit pointer parameter */
157 size = type_size(&func_vt, &align);
158 if (size > 2 * XLEN) {
159 tcc_error("unimp: struct return");
160 func_vc = loc;
161 }
162 /* define parameters */
163 while ((sym = sym->next) != NULL) {
164 type = &sym->type;
165 size = type_size(type, &align);
166 if (size > 2 * XLEN) {
167 from_stack:
168 addr = (addr + align - 1) & -align;
169 param_addr = addr;
170 addr += size;
171 } else {
172 int regcount = 1;
173 if (size > XLEN)
174 regcount++;
175 if (regcount + (is_float(type->t) ? afreg : aireg) >= 8)
176 goto from_stack;
177 loc -= regcount * 8;
178 param_addr = loc;
179 for (i = 0; i < regcount; i++) {
180 if (is_float(type->t)) {
181 tcc_error("unimp: float args");
182 } else {
183 ES(0x23, 3, 2, 10 + aireg, -loc + i*8); // sd aX, loc(sp) // XXX
184 }
185 }
186 }
187 sym_push(sym->v & ~SYM_FIELD, type,
188 VT_LOCAL | lvalue_type(type->t), param_addr);
189 }
86}190}
87ST_FUNC void gen_va_start(void)191
192ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
193 int *ret_align, int *regsize)
88{194{
89 tcc_error("implement me");195 /* generic code can only deal with structs of pow(2) sizes
196 (it always deals with whole registers), so go through our own
197 code. */
198 return 0;
90}199}
91ST_FUNC void gen_va_arg(CType *t)200
201ST_FUNC void gfunc_return(CType *func_type)
92{202{
93 tcc_error("implement me");203 int align, size = type_size(func_type, &align);
204 if ((func_type->t & VT_BTYPE) == VT_STRUCT
205 || size > 2 * XLEN) {
206 tcc_error("unimp: struct or large return");
207 }
208 if (is_float(func_type->t))
209 gv(RC_FRET);
210 else
211 gv(RC_IRET);
212 vtop--;
94}213}
95ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,214
96 int *align, int *regsize)215ST_FUNC void gfunc_epilog(void)
97{216{
98 tcc_error("implement me");217 int v, saved_ind;
218
219 v = (-loc + 15) & -16;
220
221 EI(0x03, 3, 1, 2, v - 8); // ld ra, v-8(sp)
222 EI(0x03, 3, 8, 2, v - 16); // ld s0, v-16(sp)
223 EI(0x13, 0, 2, 2, v); // addi sp, sp, v
224 EI(0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret
225 saved_ind = ind;
226 ind = func_sub_sp_offset;
227 EI(0x13, 0, 2, 2, -v); // addi sp, sp, -v
228 ES(0x23, 3, 2, 1, v - 8); // sd ra, v-8(sp)
229 ES(0x23, 3, 2, 8, v - 16); // sd s0, v-16(sp)
230 ind = saved_ind;
99}231}
100ST_FUNC void gfunc_return(CType *func_type)232
233ST_FUNC void gen_va_start(void)
101{234{
102 tcc_error("implement me");235 tcc_error("implement me: %s", __FUNCTION__);
103}236}
104ST_FUNC void gfunc_epilog(void)237
238ST_FUNC void gen_va_arg(CType *t)
105{239{
106 tcc_error("implement me");240 tcc_error("implement me: %s", __FUNCTION__);
107}241}
242
108ST_FUNC void gen_fill_nops(int bytes)243ST_FUNC void gen_fill_nops(int bytes)
109{244{
110 tcc_error("implement me");245 tcc_error("implement me: %s", __FUNCTION__);
111 if ((bytes & 3))246 if ((bytes & 3))
112 tcc_error("alignment of code section not multiple of 4");247 tcc_error("alignment of code section not multiple of 4");
113}248}
@@ -115,79 +250,82 @@ ST_FUNC void gen_fill_nops(int bytes) · 1 unmodified line
115// Generate forward branch to label:250// Generate forward branch to label:
116ST_FUNC int gjmp(int t)251ST_FUNC int gjmp(int t)
117{252{
118 tcc_error("implement me");253 tcc_error("implement me: %s", __FUNCTION__);
119}254}
120 255
121// Generate branch to known address:256// Generate branch to known address:
122ST_FUNC void gjmp_addr(int a)257ST_FUNC void gjmp_addr(int a)
123{258{
124 tcc_error("implement me");259 tcc_error("implement me: %s", __FUNCTION__);
125}260}
126 261
127ST_FUNC int gjmp_cond(int op, int t)262ST_FUNC int gjmp_cond(int op, int t)
128{263{
129 tcc_error("implement me");264 tcc_error("implement me: %s", __FUNCTION__);
130}265}
131 266
132ST_FUNC int gjmp_append(int n, int t)267ST_FUNC int gjmp_append(int n, int t)
133{268{
134 tcc_error("implement me");269 tcc_error("implement me: %s", __FUNCTION__);
135}270}
136 271
137ST_FUNC int gtst(int inv, int t)272ST_FUNC int gtst(int inv, int t)
138{273{
139 tcc_error("implement me");274 tcc_error("implement me: %s", __FUNCTION__);
140}275}
276
141ST_FUNC void gen_opi(int op)277ST_FUNC void gen_opi(int op)
142{278{
143 tcc_error("implement me");279 tcc_error("implement me: %s", __FUNCTION__);
144}280}
145 281
146ST_FUNC void gen_opl(int op)282ST_FUNC void gen_opl(int op)
147{283{
148 tcc_error("implement me");284 tcc_error("implement me: %s", __FUNCTION__);
149}285}
150 286
151ST_FUNC void gen_opf(int op)287ST_FUNC void gen_opf(int op)
152{288{
153 tcc_error("implement me");289 tcc_error("implement me: %s", __FUNCTION__);
154}290}
291
155ST_FUNC void gen_cvt_sxtw(void)292ST_FUNC void gen_cvt_sxtw(void)
156{293{
157 tcc_error("implement me");294 tcc_error("implement me: %s", __FUNCTION__);
158}295}
159 296
160ST_FUNC void gen_cvt_itof(int t)297ST_FUNC void gen_cvt_itof(int t)
161{298{
162 tcc_error("implement me");299 tcc_error("implement me: %s", __FUNCTION__);
163}300}
164 301
165ST_FUNC void gen_cvt_ftoi(int t)302ST_FUNC void gen_cvt_ftoi(int t)
166{303{
167 tcc_error("implement me");304 tcc_error("implement me: %s", __FUNCTION__);
168}305}
169 306
170ST_FUNC void gen_cvt_ftof(int t)307ST_FUNC void gen_cvt_ftof(int t)
171{308{
172 tcc_error("implement me");309 tcc_error("implement me: %s", __FUNCTION__);
173}310}
174 311
175ST_FUNC void ggoto(void)312ST_FUNC void ggoto(void)
176{313{
177 tcc_error("implement me");314 tcc_error("implement me: %s", __FUNCTION__);
178}315}
316
179ST_FUNC void gen_vla_sp_save(int addr)317ST_FUNC void gen_vla_sp_save(int addr)
180{318{
181 tcc_error("implement me");319 tcc_error("implement me: %s", __FUNCTION__);
182}320}
183 321
184ST_FUNC void gen_vla_sp_restore(int addr)322ST_FUNC void gen_vla_sp_restore(int addr)
185{323{
186 tcc_error("implement me");324 tcc_error("implement me: %s", __FUNCTION__);
187}325}
188 326
189ST_FUNC void gen_vla_alloc(CType *type, int align)327ST_FUNC void gen_vla_alloc(CType *type, int align)
190{328{
191 tcc_error("implement me");329 tcc_error("implement me: %s", __FUNCTION__);
192}330}
193#endif331#endif
riscv64-link.c+4−0
@@ -205,7 +205,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 204 unmodified lines
205 | (((val - addr) & 0xfff) << 20));205 | (((val - addr) & 0xfff) << 20));
206 return;206 return;
207 case R_RISCV_PCREL_HI20:207 case R_RISCV_PCREL_HI20:
208#ifdef DEBUG_RELOC
208 printf("PCREL_HI20: val=%lx addr=%lx\n", val, addr);209 printf("PCREL_HI20: val=%lx addr=%lx\n", val, addr);
210#endif
209 off64 = (int64_t)(val - addr + 0x800) >> 12;211 off64 = (int64_t)(val - addr + 0x800) >> 12;
210 if ((off64 + ((uint64_t)1 << 20)) >> 21)212 if ((off64 + ((uint64_t)1 << 20)) >> 21)
211 tcc_error("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx",213 tcc_error("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx",
@@ -226,7 +228,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 14 unmodified lines
226 | ((off64 & 0xfffff) << 12));228 | ((off64 & 0xfffff) << 12));
227 return;229 return;
228 case R_RISCV_PCREL_LO12_I:230 case R_RISCV_PCREL_LO12_I:
231#ifdef DEBUG_RELOC
229 printf("PCREL_LO12_I: val=%lx addr=%lx\n", val, addr);232 printf("PCREL_LO12_I: val=%lx addr=%lx\n", val, addr);
233#endif
230 if (val != last_hi.addr)234 if (val != last_hi.addr)
231 tcc_error("unsupported hi/lo pcrel reloc scheme");235 tcc_error("unsupported hi/lo pcrel reloc scheme");
232 val = last_hi.val;236 val = last_hi.val;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t