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
3333
3434 #define XLEN 8
3535
36+#define TREG_RA 17
37+
3638 ST_DATA const int reg_classes[NB_REGS] = {
3739 RC_INT | RC_R(0),
3840 RC_INT | RC_R(1),
@@ -54,13 +56,15 @@ ST_DATA const int reg_classes[NB_REGS] = { · 15 unmodified lines
5456
5557 static int ireg(int r)
5658 {
59+ if (r == TREG_RA)
60+ return 1; // ra
5761 assert(r >= 0 && r < 8);
5862 return r + 10; // tccrX --> aX == x(10+X)
5963 }
6064
6165 static int is_ireg(int r)
6266 {
63− return r < 8;
67+ return r < 8 || r == TREG_RA;
6468 }
6569
6670 static int is_freg(int r)
@@ -121,20 +125,22 @@ ST_FUNC void load(int r, SValue *sv) · 54 unmodified lines
121125 int rr = ireg(r);
122126 int fc = sv->c.i;
123127 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;
124138 if (v == VT_LOCAL) {
125− int bt = sv->type.t & VT_BTYPE;
126− int align, size = type_size(&sv->type, &align);
127− int func3;
128139 if (((unsigned)fc + (1 << 11)) >> 12)
129140 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;
137141 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)
138144 } else {
139145 tcc_error("unimp: load(non-local lval)");
140146 }
@@ -162,6 +168,10 @@ ST_FUNC void load(int r, SValue *sv) · 21 unmodified lines
162168 if (is_float(sv->type.t))
163169 tcc_error("unimp: load(float)");
164170 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
165175 } else if (v < VT_CONST) {
166176 /* reg-reg */
167177 if (is_freg(r) && is_freg(v))
@@ -195,6 +205,10 @@ ST_FUNC void store(int r, SValue *sv) · 27 unmodified lines
195205 tcc_error("unimp: large sized store");
196206 ES(0x23, size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3,
197207 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)
198212 } else
199213 tcc_error("implement me: %s(!local)", __FUNCTION__);
200214 }
@@ -208,8 +222,14 @@ static void gcall(void) · 7 unmodified lines
208222 R_RISCV_CALL_PLT, (int)vtop->c.i);
209223 o(0x17 | (1 << 7)); // auipc ra, 0 %call(func)
210224 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)
211228 } 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)
213233 }
214234 }
215235
@@ -401,6 +421,7 @@ static void gen_opil(int op, int ll) · 185 unmodified lines
401421 {
402422 int a, b, d;
403423 int inv = 0;
424+ int func3 = 0, func7 = 0;
404425 /* XXX We could special-case some constant args. */
405426 gv2(RC_INT, RC_INT);
406427 a = ireg(vtop[-1].r);
@@ -413,13 +434,10 @@ static void gen_opil(int op, int ll) · 6 unmodified lines
413434 switch (op) {
414435 case '%':
415436 case '&':
416− case '*':
417− case '-':
418437 case '/':
419438 case '^':
420439 case '|':
421440 case TOK_SAR:
422− case TOK_SHL:
423441 case TOK_SHR:
424442 case TOK_UDIV:
425443 case TOK_PDIV:
@@ -430,6 +448,15 @@ static void gen_opil(int op, int ll) · 4 unmodified lines
430448 case '+':
431449 o(0x33 | (d << 7) | (a << 15) | (b << 20)); // add d, a, b
432450 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;
433460
434461 case TOK_ULT:
435462 case TOK_UGE:
@@ -483,7 +510,8 @@ ST_FUNC void gen_opf(int op) · 47 unmodified lines
483510
484511 ST_FUNC void gen_cvt_sxtw(void)
485512 {
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. */
487515 }
488516
489517 ST_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