diff --git a/loongarch64-gen.c b/loongarch64-gen.c index de7dde846cc0c499f0d2ed9a85c87398a3649813..eccff83596b553cf30928dbcdd460002454066b5 100644 --- a/loongarch64-gen.c +++ b/loongarch64-gen.c @@ -94,7 +94,7 @@ static int is_freg(int r) } ST_FUNC void o(unsigned int c) -{printf("gen: %x\n", c); +{printf("%x: %x\n", ind, c); int ind1 = ind + 4; if (nocode_wanted) return; @@ -170,9 +170,9 @@ ST_FUNC void gsym_addr(int t_, int a_) tcc_error("branch out of range"); uint32_t r = (a - t) >> 2, imm; imm = ((r & 0xffff) << 10) | ((r >> 16) & 0x3ff); - write32le(ptr, (a - t == 4 ? 0x02c0018c : // nop - 0x54000000 | imm)); // bl - a - 4 == 4 ? printf("t:%x nop\n",t) : printf("t:%x bl %x\n",t,r); + write32le(ptr, (a - t == 4 ? 0x3400000 : // nop + (0x50000000 | imm))); // b + a - t == 4 ? printf("gsym_addr:%x nop\n",t) : printf("gsym_addr:%x bl %x\n",t,r); t = next; } } @@ -195,9 +195,9 @@ static int load_symofs(int r, SValue *sv, int forstore) greloca(cur_text_section, sv->sym, ind, R_LARCH_PCALA_HI20, sv->c.i); sv->c.i = 0; - } else { + } else {//ä¸çŸ¥é“对ä¸å¯¹ if (((unsigned)fc + (1 << 11)) >> 12) - tcc_error("unimp: large addend for global address (0x%lx)", (long)sv->c.i); + tcc_error("unimp: large addend for global address (0x%lx)", (long)sv->c.i); printf("rel: ind:%x R_LARCH_GOT_HI20\n", ind); greloca(cur_text_section, sv->sym, ind, R_LARCH_GOT_HI20, 0); @@ -206,31 +206,26 @@ static int load_symofs(int r, SValue *sv, int forstore) label.type.t = VT_VOID | VT_STATIC; if (!nocode_wanted) put_extern_sym(&label, cur_text_section, ind, 0); - rr = is_ireg(r) ? ireg(r) : 12; - printf("ind:%x pcalau12i $%d, 0\n",ind,rr); + rr = is_ireg(r) ? ireg(r) : 12; //rr:ç›®æ ‡å¯„å˜å™¨ç¼–å·ï¼ˆr对应或t0) + printf("load_symofs:%x pcalau12i $%d, 0\n",ind,rr); o((0xd << 25) | rr); //pcalau12i RR, 0 %pcrel_hi(sym)+addend //è¿™é‡Œæ²¡æœ‰ç»™ç«‹å³æ•°ï¼Œå¯èƒ½æ˜¯ä¸‹é¢ç»™ï¼Ÿé‚£ä¹ˆå¾—调整一下ä½ç½® - // o(0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend printf("rel: ind:%x R_LARCH_PCALA_LO12\n", ind); - greloca(cur_text_section, sv->sym, ind, R_LARCH_PCALA_LO12, 0); - // greloca(cur_text_section, &label, ind, - // R_LARCH_PCALA_LO12, 0); + greloca(cur_text_section, sv->sym, ind, + R_LARCH_PCALA_LO12, 0); // if (doload) { - // printf("ind:%x ld.d $%d, 0($%d)\n", ind,rr,rr); + // printf("load_symofs:%x ld.d $%d, 0($%d)\n", ind,rr,rr); // E2RI12(0xa3, 0, rr, rr);//ld.d RR,0(RR) - // // EI(0x03, 3, rr, rr, 0); // ld RR, 0(RR) // } } else if (v == VT_LOCAL || v == VT_LLOCAL) { - rr = 22; // s0 + rr = 22; // fp if (fc != sv->c.i) - tcc_error("unimp: store(giant local off) (0x%lx)", (long)sv->c.i); + tcc_error("unimp: store(giant local off) (0x%lx)", (long)sv->c.i); if (((unsigned)fc + (1 << 11)) >> 12) { rr = is_ireg(r) ? ireg(r) : 12; // t0 - printf("ind:%x lu12i.w $%d, %x\n", ind, rr, (0x800 + fc) >> 12); + printf("load_symofs:%x lu12i.w $%d, %x\n", ind, rr, (0x800 + fc) >> 12); o(0x14000000 | ((0x800 + fc) >> 12 << 5) | rr);//LU12I.W RR, upper(fc) - // o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc) - printf("ind:%x add.d $%d, $%d, fp",ind,rr,rr); + printf("load_symofs:%x add.d $%d, $%d, fp\n",ind,rr,rr); E3R(0x21, 22, rr, rr);//add.d RR,RR,fp - // ER(0x33, 0, rr, rr, 8, 0); // add RR, RR, s0 sv->c.i = fc << 20 >> 20; } } else @@ -240,7 +235,7 @@ static int load_symofs(int r, SValue *sv, int forstore) static void load_large_constant(int rr, int fc, uint32_t pi) { - printf("\nload_large_constant:\n"); //暂时没读懂,直接copyè¿‡æ¥ + printf("\nload_large_constant:\n"); //暂时没精读,直接copy过æ¥ï¼Œæœªç»æµ‹è¯• if (fc < 0) pi++; o((0xa << 25) | (((pi + 0x800) & 0xfffff000) >> 12 << 5) | rr); // lu12i.w RR, up(up(fc)) @@ -253,18 +248,18 @@ static void load_large_constant(int rr, int fc, uint32_t pi) E2RI8(0x10, 0x40 | 8, rr, rr); // slli.d RR, RR, 8 } -ST_FUNC void load(int r, SValue *sv) +ST_FUNC void load(int r, SValue *sv)//r:ç›®æ ‡å¯„å˜å™¨tccç¼–å· sv:需è¦åŠ è½½çš„æ•°æ® { printf("load:\n"); - int fr = sv->r; - int v = fr & VT_VALMASK; //å–å˜å‚¨ä½ç½® - int rr = is_ireg(r) ? ireg(r) : freg(r); - int fc = sv->c.i; - int bt = sv->type.t & VT_BTYPE; + int fr = sv->r; //æè¿°æ•°å€¼çš„当å‰å˜å‚¨æ–¹å¼ + int v = fr & VT_VALMASK; //å–å˜å‚¨ä½ç½®å’ŒåŠŸç”¨ + int rr = is_ireg(r) ? ireg(r) : freg(r); //rr:ç›®æ ‡å¯„å˜å™¨ç¼–å· + int fc = sv->c.i; //fc:所访问内å˜çš„åç§»é‡ï¼ˆç«‹å³æ•°ï¼‰ + int bt = sv->type.t & VT_BTYPE; //å–基本数æ®ç±»åž‹ int align, size; if (fr & VT_LVAL) { //å˜é‡æ˜¯å·¦å€¼ - int func3, opcode = is_freg(r) ? 0xac : 0xa0, br; //loongarch没有func3的概念,ä¸è¿‡ä¾ç„¶å¯ä»¥ç”¨æ¥æŒ‡ç¤ºä½å®½ï¼Œä½†æ˜¯ä¸èƒ½ç›´æŽ¥ä½¿ç”¨ - size = type_size(&sv->type, &align); + int func3, opcode = is_freg(r) ? 0xac : 0xa0, br; //br:所访问内å˜çš„基å€å¯„å˜å™¨ //func3用于指示loadçš„å—长,是riscv的表达,这里借用了其功能 + size = type_size(&sv->type, &align);// size为所需空间 assert (!is_freg(r) || bt == VT_FLOAT || bt == VT_DOUBLE); if (bt == VT_FUNC) /* XXX should be done in generic code */ size = PTR_SIZE; @@ -283,9 +278,8 @@ ST_FUNC void load(int r, SValue *sv) } else if (v == VT_LLOCAL) { br = load_symofs(r, sv, 0); fc = sv->c.i; - // EI(0x03, 3, rr, br, fc); // ld RR, fc(BR) - printf("ind:%x ld.d $%d,%d($%d)\n",ind, rr, fc, br); - E2RI12(0xa3, fc & 0xfff, br, rr); + printf("ld.d $%d,%x($%d)\n", rr, fc, br); + E2RI12(0xa3, fc & 0xfff, br, rr); // ld.d RR, fc(BR) br = rr; fc = 0; } else if (v == VT_CONST) { @@ -295,7 +289,7 @@ ST_FUNC void load(int r, SValue *sv) load_large_constant(rr, fc, si); fc &= 0xff; } else { - printf("ind:%x lu12i.w $%d, %x",ind, rr, (0x800 + fc) >> 12); + printf("lu12i.w $%d, %x",rr, (0x800 + fc) >> 12); o(0x14000000 | ((0x800 + fc) >> 12 << 5) | rr);//LU12I.W RR, upper(fc) // o(0x37 | (rr << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc) fc = fc << 20 >> 20; @@ -305,12 +299,11 @@ ST_FUNC void load(int r, SValue *sv) tcc_error("unimp: load(non-local lval)"); } if (opcode == 0xac) //fl - printf("fl[sd]\n"), + printf("fld[sd] $%d $%d %x\n",rr,br,fc&0xfff), E2RI12(opcode | ((func3 & ~8)<=2 ? 0 : 2), fc & 0xfff, br, rr);// fl[sd] RR, fc(BR) - else //l - printf("l[bhwd][u]\n"), + else //l + printf("ld[bhwd][u] $%d $%d %x\n",rr,br,fc& 0xfff), E2RI12(opcode | func3, fc & 0xfff, br, rr); // l[bhwd][u] RR, fc(BR) - // EI(opcode, func3, rr, br, fc); // l[bhwd][u] / fl[wd] RR, fc(BR) } else if (v == VT_CONST) { //常é‡ï¼Ÿ int rb = 0, do32bit = 8, zext = 0; assert((!is_float(sv->type.t) && is_ireg(r)) || bt == VT_LDOUBLE); @@ -348,26 +341,22 @@ ST_FUNC void load(int r, SValue *sv) E2RI8(0x10, 0x40 | 32, rr, rr); // slli.d RR, RR, 32 printf("srli.d\n"); E2RI8(0x11, 0x40 | 32, rr, rr); // srli.d RR, RR, 32 - // EI(0x13, 1, rr, rr, 32); // slli RR, RR, 32 - // EI(0x13, 5, rr, rr, 32); // srli RR, RR, 32 } } else if (v == VT_LOCAL) { //局部å˜é‡ï¼ˆæ ˆä¸ï¼‰ int br = load_symofs(r, sv, 0); assert(is_ireg(r)); fc = sv->c.i; printf("ind:%x addi.d $%d, $%d, %x\n",ind, rr, br, fc); - E2RI12(0xb, fc & 0xff, br, rr); + E2RI12(0xb, fc & 0xfff, br, rr); // EI(0x13, 0, rr, br, fc); // addi R, s0, FC } else if (v < VT_CONST) { /* reg-reg */ //寄å˜å™¨ä¸ //assert(!fc); XXX support offseted regs if (is_freg(r) && is_freg(v)) printf("fmov.[sd]\n"), E2R(0x4524 | (bt == VT_DOUBLE ? 2 : 1), freg(v), rr);//fmov.[sd] RR, v - // ER(0x53, 0, rr, freg(v), freg(v), bt == VT_DOUBLE ? 0x11 : 0x10); //fsgnj.[sd] RR, V, V == fmv.[sd] RR, V else if (is_ireg(r) && is_ireg(v)) printf("ind:%x addi.d $%d, $%d, 0",ind,rr,ireg(v)), - E2RI12(0xb, 0, ireg(v), rr); // addi RR, V, 0 - // EI(0x13, 0, rr, ireg(v), 0); // addi RR, V, 0 == mv RR, V + E3R(0x2a, 0, ireg(v), rr); // or RR, V, $zero == mv RR, V else { int func7 = is_ireg(r) ? 4 : 0; size = type_size(&sv->type, &align); @@ -375,8 +364,6 @@ ST_FUNC void load(int r, SValue *sv) assert(size == 4 || size == 8); E2R(0x4528 | func7, is_freg(v) ? freg(v) : ireg(v), rr); // movGR2FR.[wd] movFR2GR.[wd] RR,VR printf("movgr2fr.[wd] ...\n"); - // o(0x53 | (rr << 7) | ((is_freg(v) ? freg(v) : ireg(v)) << 15) - // | (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR } } else if (v == VT_CMP) { //æ ‡å¿—å¯„å˜å™¨ä¸ tcc_error("imcomplete VT_CMP in load"); @@ -466,20 +453,16 @@ ST_FUNC void store(int r, SValue *sv) } else { o((0xa << 25) | ((0x800 + fc) >> 12 << 5) | ptrreg);//lu12i.w RR, upper(fc) printf("ind:%x lu12i.w $%d, %x\n",ind-4, ptrreg, (0x800 + fc) >> 12); - // o(0x37 | (ptrreg << 7) | ((0x800 + fc) & 0xfffff000)); //lui RR, upper(fc) fc = fc << 20 >> 20; } } else tcc_error("implement me: %s(!local)", __FUNCTION__); if (is_freg(r)) - E2RI12(0xad | (size == 4 ? 0 : 2), fc & 0xfff, ptrreg, rr), - printf("fst.[wd]\n"); + printf("fst.[wd] $%d $%d %x\n",rr,ptrreg, fc & 0xfff), + E2RI12(0xad | (size == 4 ? 0 : 2), fc & 0xfff, ptrreg, rr); else - E2RI12(0xa4 | (size == 1 ? 0 : size ==2 ? 1 : size == 4 ? 2 : 3), fc & 0xfff, ptrreg, rr), - printf("st.[bhwd]\n"); - // ES(is_freg(r) ? 0x27 : 0x23, // fs... | s... - // size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd] - // ptrreg, rr, fc); + printf("st.[bhwd] $%d $%d %x\n",rr,ptrreg, fc & 0xfff), + E2RI12(0xa4 | (size == 1 ? 0 : size ==2 ? 1 : size == 4 ? 2 : 3), fc & 0xfff, ptrreg, rr); } static void gcall_or_jmp(int docall) @@ -495,22 +478,16 @@ static void gcall_or_jmp(int docall) o(0x15 << 26); // bl r printf("ind:%x bl 0\n", ind-4); // 这里将32ä½ç¼©åˆ°äº†26ä½ï¼Œå¦‚果超出范围,这里没有åšä»»ä½•å¤„ç† - // o((0xd << 25) | tr); //pcalau12i TR, 0 %pcall(func) //è¿™é‡Œæ²¡æœ‰ç»™ç«‹å³æ•°ï¼Œå¯èƒ½æ˜¯ä¸‹é¢ç»™ï¼Ÿé‚£ä¹ˆå¾—调整一下ä½ç½® - // E2RI16(0x13, 0, tr, tr); //jirl tr,r(R) - // o(0x17 | (tr << 7)); // auipc TR, 0 %call(func) - // EI(0x67, 0, tr, tr, 0);// jalr TR, r(TR) } else if (vtop->r < VT_CONST) { int r = ireg(vtop->r); E2RI16(0x13, 0, r, tr); //jirl tr,0(R) printf("ind:%x jirl $%d, 0($%d)\n", ind-4, tr,r); - // EI(0x67, 0, tr, r, 0); // jalr TR, 0(R) } else { int r = TREG_RA; load(r, vtop); r = ireg(r); - E2RI16(0x13, 0, r, tr); + E2RI16(0x13, 0, r, tr); //jirl tr,0(R) printf("ind:%x jalr $%d, 0($%d)\n",ind-4, tr, r); - // EI(0x67, 0, tr, r, 0); // jalr TR, 0(R) } } @@ -638,7 +615,7 @@ ST_FUNC void gfunc_call(int nb_args) /* fetch cpu flag before generating any code */ if ((vtop->r & VT_VALMASK) == VT_CMP) - gv(RC_INT); + gv(RC_INT); if (stack_add) { @@ -646,16 +623,10 @@ ST_FUNC void gfunc_call(int nb_args) unsigned int bit11 = (((unsigned int)-stack_add) >> 11) & 1; o((0xa << 25) | ((((-stack_add + (bit11 << 12)) >> 12) & 0xfffff) << 5) | 12);//lu12i.w t0, upper(v) E2RI12(0xb, ((-stack_add & 0xfff) - bit11 * (1 << 12)), 12, 12);//addi.d t0,t0,lo(v) - E3R(0x21, 12, 3, 3);//add.d? sp,sp,t0 - // o(0x37 | (5 << 7) | - // ((-stack_add + (bit11 << 12)) & 0xfffff000)); //lui t0, upper(v) - // EI(0x13, 0, 5, 5, ((-stack_add & 0xfff) - bit11 * (1 << 12))); - // // addi t0, t0, lo(v) - // ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0 + E3R(0x21, 12, 3, 3);//add.d sp,sp,t0 } else - E2RI12(0xb, -stack_add, 3, 3); //addi.d sp, sp, -adj - // EI(0x13, 0, 2, 2, -stack_add); // addi sp, sp, -adj + E2RI12(0xb, (-stack_add) & 0xfff, 3, 3); //addi.d sp, sp, -adj for (i = ofs = 0; i < nb_args; i++) { if (info[i] & (64 | 32)) { vrotb(nb_args - i); @@ -760,15 +731,13 @@ ST_FUNC void gfunc_call(int nb_args) vtop->r2 = r2; } if (info[nb_args - 1 - i] & 16) { - E2RI12(0xa7, splitofs, 3, ireg(vtop->r2)); //st.d t0, ofs(sp) - // ES(0x23, 3, 2, ireg(vtop->r2), splitofs); // sd t0, ofs(sp) + E2RI12(0xa7, splitofs & 0xfff, 3, ireg(vtop->r2)); //st.d t0, ofs(sp) vtop->r2 = VT_CONST; } else if (loadt == VT_LDOUBLE && vtop->r2 != r2) { assert(vtop->r2 <= 7 && r2 <= 7); /* XXX we'd like to have 'gv' move directly into the right class instead of us fixing it up. */ E3R(0x2a, 0, ireg(vtop->r2), ireg(r2));//move Ra+1, RR2 aka or RA+1, RR2, $zero - // EI(0x13, 0, ireg(r2), ireg(vtop->r2), 0); // mv Ra+1, RR2 vtop->r2 = r2; } done: @@ -785,15 +754,9 @@ done: o((0xa << 25) | ((((stack_add + (bit11 << 12)) >> 12) & 0xfffff) << 5) | 12);//lu12i.w t0, upper(v) E2RI12(0xb, ((stack_add & 0xfff) - bit11 * (1 << 12)), 12, 12);//addi.d t0,t0,lo(v) E3R(0x21, 12, 3, 3);//add.d? sp,sp,t0 - // o(0x37 | (5 << 7) | - // ((stack_add + (bit11 << 12)) & 0xfffff000)); //lui t0, upper(v) - // EI(0x13, 0, 5, 5, (stack_add & 0xfff) - bit11 * (1 << 12)); - // // addi t0, t0, lo(v) - // ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0 } else E2RI12(0xb, stack_add, 3, 3); //addi.d sp, sp, adj - // EI(0x13, 0, 2, 2, stack_add); // addi sp, sp, adj } tcc_free(info); } @@ -825,7 +788,6 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) func_vc = loc; E2RI12(0xa7, loc & 0xfff, 22, 4 + areg[0]++); //st.d aX, loc(fp) printf("ind:%x st.d a%d, %x(fp)\n",ind-4,areg[0]-1, loc & 0xfff); - //ES(0xa7, 3, 8, 10 + areg[0]++, loc); // sd a0, loc(s0) } /* define parameters */ while ((sym = sym->next) != NULL) { //?å–下一个返回值 @@ -857,19 +819,15 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) assert(i == 1 && regcount == 2 && !(addr & 7)); E2RI12(0xa3, addr & 0xfff, 22, 12); // ld.t t0, addr(fp) printf("ind:%x ld.d t0, %x(fp)\n",ind-4,addr); - //EI(0x03, 3, 5, 8, addr); // ld t0, addr(s0) addr += 8; E2RI12(0xa7, (loc + i*8) & 0xfff, 22, 12); //st.d t0, loc(fp) printf("ind:%x st.d t0, %x(fp)\n",ind-4,(loc+i*8) & 0xfff); - //ES(0x23, 3, 8, 5, loc + i*8); // sd t0, loc(s0) } else if (prc[1+i] == RC_FLOAT) { - E2RI12(0xac | (size / regcount == 4 ? 1 : 3), loc + (fieldofs[i+1] >> 4), 22, areg[1]++); + E2RI12(0xac | (size / regcount == 4 ? 1 : 3), (loc + (fieldofs[i+1] >> 4)) & 0xfff, 22, areg[1]++);// fst[wd] FAi, loc(s0) printf("ind:%x fs.[wd]\n",ind-4); - //ES(0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0) } else { - E2RI12(0x23, (loc + i*8) & 0xfff, 22, 4 + areg[0]++); // st.d aX, loc(fp) + E2RI12(0xa7, (loc + i*8) & 0xfff, 22, 4 + areg[0]++); // st.d aX, loc(fp) printf("ind:%x st.d a%d, %x(fp)\n",ind-4,areg[0]-1, (loc + i*8) & 0xfff); - //ES(0x23, 3, 8, 10 + areg[0]++, loc + i*8); // sd aX, loc(s0) // XXX } } } @@ -882,9 +840,8 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) if (func_var) { for (; areg[0] < 8; areg[0]++) { num_va_regs++; - E2RI12(0x23, (-8 + num_va_regs * 8) & 0xfff, 22, 4 + areg[0]); //st.d aX, loc(fp) + E2RI12(0xa7, (-8 + num_va_regs * 8) & 0xfff, 22, 4 + areg[0]); //st.d aX, loc(fp) printf("ind:%x st.d a%d, %x(fp)\n",ind-4,areg[0],(-8 + num_va_regs * 8)& 0xfff); - //ES(0x23, 3, 8, 10 + areg[0], -8 + num_va_regs * 8); // sd aX, loc(s0) } } #ifdef CONFIG_TCC_BCHECK @@ -925,51 +882,37 @@ ST_FUNC void gfunc_epilog(void) if (v >= (1 << 11)) { d = 16; - o((0xa << 25) | ((0x800 + (v-16)) >> 12 << 5) | 12); //lui t0, upper(v) + o((0xa << 25) | ((0x800 + (v-16)) >> 12 << 5) | 12); //lu12i.w t0, upper(v) E2RI12(0xb, (v-16) << 20 >> 20, 12, 12); // addi.d t0, t0, lo(v) - E3R(0x21, 12, 3, 3); // add sp, sp, t0 - // o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v) - // EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v) - // ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0 + E3R(0x21, 12, 3, 3); // add.d sp, sp, t0 } - E2RI12(0xa3, d - 8 - num_va_regs * 8, 3, 1); // ld.d ra, v-8(sp) - E2RI14(0x26, d - 16 - num_va_regs * 8, 3, 22);//E2RI12(0xa3, d - 16 - num_va_regs * 8, 3, 22); // ld.d fp, v-16(sp) - E2RI12(0xb, d, 3, 3);// addi.d sp, sp, v + E2RI12(0xa3, (d - 8 - num_va_regs * 8) & 0xfff, 3, 1); // ld.d ra, v-8(sp) + // E2RI14(0x26, d - 16 - num_va_regs * 8, 3, 22); //ldptr + E2RI12(0xa3, (d - 16 - num_va_regs * 8) & 0xfff, 3, 22); // ld.d fp, v-16(sp) + E2RI12(0xb, d & 0xfff, 3, 3);// addi.d sp, sp, v E2RI16(0x13, 0, 1, 0); // jirl r0, 0(ra), aka ret - // EI(0x03, 3, 1, 2, d - 8 - num_va_regs * 8); // ld ra, v-8(sp) - // EI(0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp) - // EI(0x13, 0, 2, 2, d); // addi sp, sp, v - // EI(0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret large_ofs_ind = ind; if (v >= (1 << 11)) { - E2RI12(0xb, d - num_va_regs * 8, 3, 22); - o((0xa << 25) | ((0x800 + (v-16)) >> 12 << 5) | 12); - E2RI12(0xb, (v-16) << 20 >> 20, 12, 12); - E3R(0x23, 12, 3, 3); - // EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d - // o(0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v) - // EI(0x13, 0, 5, 5, (v-16) << 20 >> 20); // addi t0, t0, lo(v) - // ER(0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0 + E2RI12(0xb, d - num_va_regs * 8, 3, 22); // addi.d s0, sp, d + o((0xa << 25) | ((0x800 + (v-16)) >> 12 << 5) | 12); //lu12i.w t0, upper(v) + E2RI12(0xb, (v-16) << 20 >> 20, 12, 12); // addi.d t0, t0, lo(v) + E3R(0x23, 12, 3, 3); // sub.d sp, sp, t0 gjmp_addr(func_sub_sp_offset + 5*4); } saved_ind = ind; ind = func_sub_sp_offset; - E2RI12(0xb, (-d) & 0xfff, 3, 3); + E2RI12(0xb, (-d) & 0xfff, 3, 3); // addi.d sp, sp, -d // E2RI12(0xa7, d - 8 - num_va_regs * 8, 3, 22); // st.d fp,d-8(sp) - E2RI12(0xa7, d - 8 - num_va_regs * 8, 3, 1); // st.d ra,d-8(sp) - E2RI14(0x27, d - 16 - num_va_regs * 8, 3, 22); //E2RI12(0xa7, d - 16 - num_va_regs * 8, 3, 22); - // EI(0x13, 0, 2, 2, -d); // addi sp, sp, -d - // ES(0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp) - // ES(0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp) + E2RI12(0xa7, (d - 8 - num_va_regs * 8) & 0xfff, 3, 1); // st.d ra,d-8(sp) + // E2RI14(0x27, (d - 16 - num_va_regs * 8) & 0xfff, 3, 22); //stptr + E2RI12(0xa7, (d - 16 - num_va_regs * 8) & 0xfff, 3, 22); // st.d s0, d-16(sp) if (v < (1 << 11)) - E2RI12(0xb, d - num_va_regs * 8, 3, 22); - // EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d + E2RI12(0xb, (d - num_va_regs * 8) & 0xfff, 3, 22); // addi.d s0, sp, d else gjmp_addr(large_ofs_ind); if ((ind - func_sub_sp_offset) != 5*4) - E2RI12(0xb, 0, 0, 0); - // EI(0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop + o(0x3400000); // nop == andi r0,r0,0 ind = saved_ind; } // ST_FUNC void gen_fill_nops(int bytes) @@ -1000,28 +943,85 @@ ST_FUNC void gjmp_addr(int a) r = (int)r << 20 >> 20; E2RI16(0x13, r, 12, 0); // jirl r0, r(t0) } else { - EI26(0x15, r >> 2); //bl imm //是å¦éœ€è¦ç§»ä½ï¼Ÿ + EI26(0x15, (r >> 2) & 0x3ffffff); //bl imm //是å¦éœ€è¦ç§»ä½ï¼Ÿ } } // ST_FUNC int gjmp_cond(int op, int t) // { -// tcc_error("implement me(gjmp_cond)"); +// printf("gjmp_cond:\n"); +// int tmp; +// int a = vtop->cmp_r & 0xff; +// int b = (vtop->cmp_r >> 8) & 0xff; +// switch (op) { +// case TOK_ULE: tmp = a; a = b; b = tmp; +// case TOK_UGE: E2RI16(0x1b, 8 << 7, a, b); break; //bgeu a,b,+4 +// case TOK_UGT: tmp = a; a = b; b = tmp; +// case TOK_ULT: E2RI16(0x1a, 8 << 7, a, b); break; //bltu a,b,+4 +// case TOK_LE: tmp = a; a = b; b = tmp; +// case TOK_GE: E2RI16(0x19, 8 << 7, a, b); break; //bge a,b,+4 +// case TOK_GT: tmp = a; a = b; b = tmp; +// case TOK_LT: E2RI16(0x18, 8 << 7, a, b); break; //blt a,b,+4 +// case TOK_NE: E2RI16(0x17, 8 << 7, a, b); break; //bne a,b,+4 +// case TOK_EQ: E2RI16(0x16, 8 << 7, a, b); break; //beq a,b,+4 +// } +// return gjmp(t); // } // ST_FUNC int gjmp_append(int n, int t) // { -// tcc_error("implement me(gjmp_append)"); +// printf("gjmp_append:\n"); +// void *p; +// /* insert jump list n into t */ +// if (n) { +// uint32_t n1 = n, n2; +// while ((n2 = read32le(p = cur_text_section->data + n1))) +// n1 = n2; +// write32le(p, t); +// t = n; +// } +// return t; // } ST_FUNC int gtst(int inv, int t) { - tcc_error("implement me(gtst)"); + printf("gtst:\n"); + int bt = vtop->type.t & VT_BTYPE; + if (bt == VT_LDOUBLE) { + tcc_error("implement me(gtst-VT_LDOUBLE)"); + // uint32_t a, b, f = fltr(gv(RC_FLOAT)); + // a = get_reg(RC_INT); + // vpushi(0); + // vtop[0].r = a; + // b = get_reg(RC_INT); + // a = intr(a); + // b = intr(b); + // o(0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0] + // o(0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1] + // o(0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1 + // o(0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8 + // --vtop; + } + else if (bt == VT_FLOAT || bt == VT_DOUBLE) { + tcc_error("implement me(gtst-VT_FLOAT/DOUBLE)"); + // uint32_t a = fltr(gv(RC_FLOAT)); + // o(0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp + // o(0x54000040 | !!inv); // b.eq/b.ne .+8 + } + else { + uint32_t ll = (bt == VT_PTR || bt == VT_LLONG); + uint32_t a = vtop->r; + printf("beqz/bnez $%d,+2\n",a); + E2RI16(0x10 | !!inv, 2, a, 0); //beqz/bnez aX,+2 + // o(0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8 + } + --vtop; + return gjmp(t); } static void gen_opil(int op, int ll) { + printf("gen_opil:\n"); int a, b, d; - int func3 = 0; ll = ll ? 0 : 8; if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { @@ -1031,68 +1031,81 @@ static void gen_opil(int op, int ll) int m = ll ? 31 : 63; vswap(); gv(RC_INT); - a = ireg(vtop[0].r); --vtop; d = get_reg(RC_INT); ++vtop; vswap(); - switch (op) { case '-': if (fc <= -(1 << 11)) break; fc = -fc; case '+': - func3 = 0; // addi d, a, fc cll = ll; + printf("addi $%d $%d %x\n", ireg(d), a, fc); + E2RI12(0xb, fc & 0xfff, a, ireg(d)); // addi d, a, fc + --vtop; + vtop->r = d; + return; + do_cop: + --vtop; + // if (op >= TOK_ULT && op <= TOK_GT) { + // vset_VT_CMP(TOK_NE); + // vtop->cmp_r = ireg(d) | 0 << 8; + // } else + // vtop[0].r = d; + vtop->r = d; + return; - // do_cop: - // E2RI12(0x13 | cll, func3,, ireg(d));/**/ - - // --vtop; - // // if (op >= TOK_ULT && op <= TOK_GT) { - // // vset_VT_CMP(TOK_NE); - // // vtop->cmp_r = ireg(d) | 0 << 8; - // // } else - // // vtop[0].r = d; - // vtop->r = d; - // return; - - // case TOK_LE: - // if (fc >= (1 << 11) - 1) - // break; - // ++fc; - // case TOK_LT: func3 = 2; goto do_cop; // slti d, a, fc - // case TOK_ULE: - // if (fc >= (1 << 11) - 1 || fc == -1) - // break; - // ++fc; - // case TOK_ULT: E2RI12(0x09 , fc , a , ireg(d)); goto do_cop; // sltui d, a, fc - // case '^': E2RI12(0x0f , fc , a , ireg(d)); goto do_cop; // xori d, a, fc - // case '|': E2RI12(0x0e , fc , a , ireg(d)); goto do_cop; // ori d, a, fc - // case '&': E2RI12(0x0d , fc , a , ireg(d)); goto do_cop; // andi d, a, fc - - // case TOK_SHL: - // if(ll) - // E2RI8(0x10 , (0x01 << 6) | fc , a , ireg(d)); - // else - // E2RI8(0x10 , (0x01 << 5) | fc , a , ireg(d)); - // cll = ll; fc &= m; goto do_cop; // slli d, a, fc + case TOK_LE: + if (fc >= (1 << 11) - 1) + break; + ++fc;//这里å§å°äºŽç‰äºŽåŒ–为å°äºŽï¼ˆå¯èƒ½æ˜¯ä¸å¿…è¦çš„) + case TOK_LT: + printf("slti $%d $%d %x\n",ireg(d),a,fc & 0xfff); + E2RI12(0x8, fc & 0xfff, a, ireg(d)); // slti d, a, fc + goto do_cop; + case TOK_ULE: + if (fc >= (1 << 11) - 1 || fc == -1) + break; + ++fc; + case TOK_ULT: + printf("sltui $%d $%d %x\n",ireg(d),a,fc & 0xfff); + E2RI12(0x09 , fc & 0xfff, a , ireg(d)); // sltui d, a, fc + goto do_cop; + case '^': + printf("xori $%d $%d %x\n",ireg(d),a,fc & 0xfff); + E2RI12(0x0f , fc & 0xfff, a , ireg(d)); // xori d, a, fc + goto do_cop; + case '|': + printf("ori $%d $%d %x\n",ireg(d),a,fc & 0xfff); + E2RI12(0x0e , fc & 0xfff, a , ireg(d)); // ori d, a, fc + goto do_cop; + case '&': + printf("andi $%d $%d %x\n",ireg(d),a,fc & 0xfff); + E2RI12(0x0d , fc & 0xfff, a , ireg(d)); // andi d, a, fc + goto do_cop; + case TOK_SHL: + if(ll) + E2RI8(0x10 , (0x01 << 6) | (fc & 0x3f) , a , ireg(d)); + else + E2RI8(0x10 , (0x01 << 5) | (fc & 0x1f) , a , ireg(d)); + cll = ll; fc &= m; goto do_cop; // slli d, a, fc - // case TOK_SHR: - // if(ll) - // E2RI8(0x11 , (0x01 << 6) | fc , a , ireg(d)); - // else - // E2RI8(0x11 , (0x01 << 5) | fc , a , ireg(d)); - // cll = ll; fc &= m; goto do_cop; // srli d, a, fc + case TOK_SHR: + if(ll) + E2RI8(0x11 , (0x01 << 6) | (fc & 0x3f) , a , ireg(d)); + else + E2RI8(0x11 , (0x01 << 5) | (fc & 0x1f) , a , ireg(d)); + cll = ll; fc &= m; goto do_cop; // srli d, a, fc - // case TOK_SAR: - // if(ll) - // E2RI8(0x12 , (0x01 << 6) | fc , a , ireg(d)); - // else - // E2RI8(0x12 , (0x01 << 5) | fc , a , ireg(d));// srai d, a, fc - // cll = ll; fc = fc & m; goto do_cop; + case TOK_SAR: + if(ll) + E2RI8(0x12 , (0x01 << 6) | (fc & 0x3f) , a , ireg(d)); + else + E2RI8(0x12 , (0x01 << 5) | (fc & 0x1f) , a , ireg(d));// srai d, a, fc + cll = ll; fc = fc & m; goto do_cop; case TOK_UGE: /* -> TOK_ULT */ case TOK_UGT: /* -> TOK_ULE */ @@ -1103,15 +1116,15 @@ static void gen_opil(int op, int ll) // vtop->cmp_op ^= 1; return; - // case TOK_NE: - // case TOK_EQ: - // if (fc) - // gen_opil('-', !ll), a = ireg(vtop++->r); - // --vtop; - // vset_VT_CMP(op); - // // vtop->cmp_r = a | 0 << 8; - // vtop->r = a; - // return; + case TOK_NE: + case TOK_EQ: + if (fc) + gen_opil('-', !ll), a = ireg(vtop++->r); + --vtop; + // vset_VT_CMP(op); + // vtop->cmp_r = a | 0 << 8; + vtop->r = a;//这里iregçš„ä½¿ç”¨æ˜¯å¦æ˜¯æ··ä¹±çš„(å‚考riscv) + return; } } } @@ -1125,18 +1138,9 @@ static void gen_opil(int op, int ll) d = ireg(d); switch (op) { - default: - if (op >= TOK_ULT && op <= TOK_GT) { - tcc_error("implement me(gen_opil-3rop)"); - // vset_VT_CMP(op); - // vtop->cmp_r = a | b << 8; - // break; - } - tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL)); - break; - case '+': - E3R(0x20 | !!ll, b, a, d); // add d, a, b/**/ + // E3R(0x20 | !!ll, b, a, d); // add d, a, b/**/ + E3R(0x21 | !!ll, b, a, d); // add.d d, a, b break; case '-': E3R(0x22 | !!ll, b, a, d); // sub d, a, b @@ -1150,6 +1154,42 @@ static void gen_opil(int op, int ll) case TOK_SHL: E3R(0x31 | (ll? 0 : 0x1f), b, a, d); // sll d, a, b break; + case TOK_ULT: + E3R(0x25, b, a, d); // sltu d, a, b + break; + case TOK_UGT: + E3R(0x25, a, b, d); // sltu d, b, a + break; + case TOK_UGE: + E3R(0x25, b, a, d); // sltu d, a, b + E2RI12(0xf, 1, d, d); //xori d, d, 0x1 + break; + case TOK_ULE: + E3R(0x25, a, b, d); // sltu d, b, a + E2RI12(0xf, 1, d, d); //xori d, d, 0x1 + break; + case TOK_LT: + E3R(0x24, b, a, d); // slt d, a, b + break; + case TOK_GT: + E3R(0x24, a, b, d); // slt d, b, a + break; + case TOK_GE: + E3R(0x24, b, a, d); // slt d, a, b + E2RI12(0xf, 1, d, d); //xori d, d, 0x1 + break; + case TOK_LE: + E3R(0x24, a, b, d); // slt d, b, a + E2RI12(0xf, 1, d, d); //xori d, d, 0x1 + break; + case TOK_EQ: + E3R(0x23, b, a, d); // sub.d d, a, b + E2RI12(0x9, 1, d, d); //sltui d, d, 0x1 + break; + case TOK_NE: + E3R(0x23, b, a, d); // sub.d d, a, b + E3R(0x25, d, 0, d); //sltu d, r0, d + break; case '*': E3R(0x3b | (ll? 0 : 0x03), b, a, d); // mul d, a, b break; @@ -1175,6 +1215,16 @@ static void gen_opil(int op, int ll) case TOK_UDIV: E3R(ll ? 0x46: 0x42, b, a, d); // divu d, a, b break; + default: + // if (op >= TOK_ULT && op <= TOK_GT) { + // // vset_VT_CMP(op); + // // vtop->cmp_r = a | b << 8; + // // vtop->r = VT_CMP; + // tcc_error + // break; + // } + tcc_error("implement me: %s(%s)", __FUNCTION__, get_tok_str(op, NULL)); + break; } } @@ -1289,7 +1339,8 @@ ST_FUNC void gen_opf(int op) // Generate sign extension from 32 to 64 bits: ST_FUNC void gen_cvt_sxtw(void) { - tcc_error("implement me(gen_cvt_sxtw)"); + printf("gen_cvt_sxtw(empty)\n"); + // tcc_error("implement me(gen_cvt_sxtw)"); } ST_FUNC void gen_cvt_itof(int t)