History

riscv: more insns

* register indirect loads and stores * load of local addresses * indirect calls (uses ra as temporary reg if necessary) * operations *, -, << * gen_cvt_sxtw: is not needed in most cases, let's see tests2 runs until (incl) 09_do_while.

Michael Matz committed 7 years ago

Commit b1c75201 parent 16edda51 file · +44 −16Browse files

Unified · Split

riscv64-gen.c+44−16
@@ -33,6 +33,8 @@ · 32 unmodified lines
33 33
34#define XLEN 834#define XLEN 8
35 35
36#define TREG_RA 17
37
36ST_DATA const int reg_classes[NB_REGS] = {38ST_DATA const int reg_classes[NB_REGS] = {
37 RC_INT | RC_R(0),39 RC_INT | RC_R(0),
38 RC_INT | RC_R(1),40 RC_INT | RC_R(1),
@@ -54,13 +56,15 @@ ST_DATA const int reg_classes[NB_REGS] = { · 15 unmodified lines
54 56
55static int ireg(int r)57static int ireg(int r)
56{58{
59 if (r == TREG_RA)
60 return 1; // ra
57 assert(r >= 0 && r < 8);61 assert(r >= 0 && r < 8);
58 return r + 10; // tccrX --> aX == x(10+X)62 return r + 10; // tccrX --> aX == x(10+X)
59}63}
60 64
61static int is_ireg(int r)65static int is_ireg(int r)
62{66{
63 return r < 8;67 return r < 8 || r == TREG_RA;
64}68}
65 69
66static int is_freg(int r)70static int is_freg(int r)
@@ -121,20 +125,22 @@ ST_FUNC void load(int r, SValue *sv) · 54 unmodified lines
121 int rr = ireg(r);125 int rr = ireg(r);
122 int fc = sv->c.i;126 int fc = sv->c.i;
123 if (fr & VT_LVAL) {127 if (fr & VT_LVAL) {
128 int bt = sv->type.t & VT_BTYPE;
129 int align, size = type_size(&sv->type, &align);
130 int func3;
131 if (is_float(bt))
132 tcc_error("unimp: load-local(float)");
133 else if (bt == VT_FUNC)
134 size = PTR_SIZE;
135 func3 = size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3;
136 if (size < 8 && (sv->type.t & VT_UNSIGNED))
137 func3 |= 4;
124 if (v == VT_LOCAL) {138 if (v == VT_LOCAL) {
125 int bt = sv->type.t & VT_BTYPE;
126 int align, size = type_size(&sv->type, &align);
127 int func3;
128 if (((unsigned)fc + (1 << 11)) >> 12)139 if (((unsigned)fc + (1 << 11)) >> 12)
129 tcc_error("unimp: load(large local ofs) (0x%x)", fc);140 tcc_error("unimp: load(large local ofs) (0x%x)", fc);
130 if (is_float(bt))
131 tcc_error("unimp: load-local(float)");
132 else if (bt == VT_FUNC)
133 size = PTR_SIZE;
134 func3 = size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3;
135 if (size < 8 && (sv->type.t & VT_UNSIGNED))
136 func3 |= 4;
137 EI(0x03, func3, rr, 8, fc); // l[bhwd][u] RR, fc(s0)141 EI(0x03, func3, rr, 8, fc); // l[bhwd][u] RR, fc(s0)
142 } else if (v < VT_CONST) {
143 EI(0x03, func3, rr, ireg(v), 0); // l[bhwd][u] RR, 0(V)
138 } else {144 } else {
139 tcc_error("unimp: load(non-local lval)");145 tcc_error("unimp: load(non-local lval)");
140 }146 }
@@ -162,6 +168,10 @@ ST_FUNC void load(int r, SValue *sv) · 21 unmodified lines
162 if (is_float(sv->type.t))168 if (is_float(sv->type.t))
163 tcc_error("unimp: load(float)");169 tcc_error("unimp: load(float)");
164 EI(0x13, 0, rr, rb, fc); // addi R, x0|R, FC170 EI(0x13, 0, rr, rb, fc); // addi R, x0|R, FC
171 } else if (v == VT_LOCAL) {
172 if (((unsigned)fc + (1 << 11)) >> 12)
173 tcc_error("unimp: load(addr large local ofs) (0x%x)", fc);
174 EI(0x13, 0, rr, 8, fc); // addi R, s0, FC
165 } else if (v < VT_CONST) {175 } else if (v < VT_CONST) {
166 /* reg-reg */176 /* reg-reg */
167 if (is_freg(r) && is_freg(v))177 if (is_freg(r) && is_freg(v))
@@ -195,6 +205,10 @@ ST_FUNC void store(int r, SValue *sv) · 27 unmodified lines
195 tcc_error("unimp: large sized store");205 tcc_error("unimp: large sized store");
196 ES(0x23, size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3,206 ES(0x23, size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3,
197 8, rr, fc); // s[bhwd] RR, fc(s0)207 8, rr, fc); // s[bhwd] RR, fc(s0)
208 } else if (fr < VT_CONST) {
209 int ptrreg = ireg(fr);
210 ES(0x23, size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3,
211 ptrreg, rr, 0); // s[bhwd] RR, 0(PTRREG)
198 } else212 } else
199 tcc_error("implement me: %s(!local)", __FUNCTION__);213 tcc_error("implement me: %s(!local)", __FUNCTION__);
200}214}
@@ -208,8 +222,14 @@ static void gcall(void) · 7 unmodified lines
208 R_RISCV_CALL_PLT, (int)vtop->c.i);222 R_RISCV_CALL_PLT, (int)vtop->c.i);
209 o(0x17 | (1 << 7)); // auipc ra, 0 %call(func)223 o(0x17 | (1 << 7)); // auipc ra, 0 %call(func)
210 o(0x80e7); // jalr ra, 0 %call(func)224 o(0x80e7); // jalr ra, 0 %call(func)
225 } else if ((vtop->r & VT_VALMASK) < VT_CONST) {
226 int r = ireg(vtop->r & VT_VALMASK);
227 EI(0x67, 0, 1, r, 0); // jalr ra, 0(R)
211 } else {228 } else {
212 tcc_error("unimp: indirect call");229 int r = TREG_RA;
230 load(r, vtop);
231 r = ireg(r);
232 EI(0x67, 0, 1, r, 0); // jalr ra, 0(R)
213 }233 }
214}234}
215 235
@@ -401,6 +421,7 @@ static void gen_opil(int op, int ll) · 185 unmodified lines
401{421{
402 int a, b, d;422 int a, b, d;
403 int inv = 0;423 int inv = 0;
424 int func3 = 0, func7 = 0;
404 /* XXX We could special-case some constant args. */425 /* XXX We could special-case some constant args. */
405 gv2(RC_INT, RC_INT);426 gv2(RC_INT, RC_INT);
406 a = ireg(vtop[-1].r);427 a = ireg(vtop[-1].r);
@@ -413,13 +434,10 @@ static void gen_opil(int op, int ll) · 6 unmodified lines
413 switch (op) {434 switch (op) {
414 case '%':435 case '%':
415 case '&':436 case '&':
416 case '*':
417 case '-':
418 case '/':437 case '/':
419 case '^':438 case '^':
420 case '|':439 case '|':
421 case TOK_SAR:440 case TOK_SAR:
422 case TOK_SHL:
423 case TOK_SHR:441 case TOK_SHR:
424 case TOK_UDIV:442 case TOK_UDIV:
425 case TOK_PDIV:443 case TOK_PDIV:
@@ -430,6 +448,15 @@ static void gen_opil(int op, int ll) · 4 unmodified lines
430 case '+':448 case '+':
431 o(0x33 | (d << 7) | (a << 15) | (b << 20)); // add d, a, b449 o(0x33 | (d << 7) | (a << 15) | (b << 20)); // add d, a, b
432 break;450 break;
451 case '-':
452 o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x20 << 25)); //sub d, a, b
453 break;
454 case TOK_SHL:
455 o(0x33 | (d << 7) | (a << 15) | (b << 20) | (1 << 12)); //sll d, a, b
456 break;
457 case '*':
458 o(0x33 | (d << 7) | (a << 15) | (b << 20) | (0x01 << 25)); //mul d, a, b
459 break;
433 460
434 case TOK_ULT:461 case TOK_ULT:
435 case TOK_UGE:462 case TOK_UGE:
@@ -483,7 +510,8 @@ ST_FUNC void gen_opf(int op) · 47 unmodified lines
483 510
484ST_FUNC void gen_cvt_sxtw(void)511ST_FUNC void gen_cvt_sxtw(void)
485{512{
486 tcc_error("implement me: %s", __FUNCTION__);513 /* XXX on risc-v the registers are usually sign-extended already.
514 Let's try to not do anything here. */
487}515}
488 516
489ST_FUNC void gen_cvt_itof(int t)517ST_FUNC void gen_cvt_itof(int t)

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