this is it! With this tcctest.c works, as well as compiling TCC with itself. abitest.c doesn't yet work due to known problems, all the rest does. There are still warnings during linking.
Unified · Split
| @@ -184,7 +184,7 @@ ST_FUNC void load(int r, SValue *sv) · 183 unmodified lines | |||
| 184 | sv->c.i = 0; | 184 | sv->c.i = 0; |
| 185 | } else { | 185 | } else { |
| 186 | if (((unsigned)fc + (1 << 11)) >> 12) | 186 | if (((unsigned)fc + (1 << 11)) >> 12) |
| 187 | tcc_error("unimp: large addend for global address"); | 187 | tcc_error("unimp: large addend for global address (0x%llx)", sv->c.i); |
| 188 | greloca(cur_text_section, sv->sym, ind, | 188 | greloca(cur_text_section, sv->sym, ind, |
| 189 | R_RISCV_GOT_HI20, 0); | 189 | R_RISCV_GOT_HI20, 0); |
| 190 | doload = 1; | 190 | doload = 1; |
| @@ -233,7 +233,7 @@ ST_FUNC void load(int r, SValue *sv) · 42 unmodified lines | |||
| 233 | sv->c.i = 0; | 233 | sv->c.i = 0; |
| 234 | } else { | 234 | } else { |
| 235 | if (((unsigned)fc + (1 << 11)) >> 12) | 235 | if (((unsigned)fc + (1 << 11)) >> 12) |
| 236 | tcc_error("unimp: large addend for global address"); | 236 | tcc_error("unimp: large addend for global address (0x%llx)", sv->c.i); |
| 237 | greloca(cur_text_section, sv->sym, ind, | 237 | greloca(cur_text_section, sv->sym, ind, |
| 238 | R_RISCV_GOT_HI20, 0); | 238 | R_RISCV_GOT_HI20, 0); |
| 239 | doload = 1; | 239 | doload = 1; |
| @@ -383,7 +383,7 @@ ST_FUNC void store(int r, SValue *sv) · 143 unmodified lines | |||
| 383 | sv->c.i = 0; | 383 | sv->c.i = 0; |
| 384 | } else { | 384 | } else { |
| 385 | if (((unsigned)fc + (1 << 11)) >> 12) | 385 | if (((unsigned)fc + (1 << 11)) >> 12) |
| 386 | tcc_error("unimp: large addend for global address"); | 386 | tcc_error("unimp: large addend for global address (0x%llx)", sv->c.i); |
| 387 | greloca(cur_text_section, sv->sym, ind, | 387 | greloca(cur_text_section, sv->sym, ind, |
| 388 | R_RISCV_GOT_HI20, 0); | 388 | R_RISCV_GOT_HI20, 0); |
| 389 | doload = 1; | 389 | doload = 1; |
| @@ -569,6 +569,7 @@ ST_FUNC void gfunc_call(int nb_args) · 179 unmodified lines | |||
| 569 | } | 569 | } |
| 570 | } | 570 | } |
| 571 | vrotb(nb_args + 1); | 571 | vrotb(nb_args + 1); |
| 572 | save_regs(nb_args + 1); | ||
| 572 | gcall_or_jmp(1); | 573 | gcall_or_jmp(1); |
| 573 | vtop -= nb_args + 1; | 574 | vtop -= nb_args + 1; |
| 574 | if (stack_adj + tempspace) | 575 | if (stack_adj + tempspace) |
| @@ -1081,9 +1082,24 @@ ST_FUNC void gen_cvt_ftof(int dt) · 506 unmodified lines | |||
| 1081 | int func = (dt == VT_LDOUBLE) ? | 1082 | int func = (dt == VT_LDOUBLE) ? |
| 1082 | (st == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) : | 1083 | (st == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) : |
| 1083 | (dt == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2); | 1084 | (dt == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2); |
| 1085 | /* We can't use gfunc_call, as func_old_type works like vararg | ||
| 1086 | functions, and on riscv unnamed float args are passed like | ||
| 1087 | integers. But we really need them in the float argument registers | ||
| 1088 | for extendsftf2/extenddftf2. So, do it explicitely. */ | ||
| 1089 | save_regs(1); | ||
| 1090 | if (dt == VT_LDOUBLE) | ||
| 1091 | gv(RC_F(0)); | ||
| 1092 | else { | ||
| 1093 | gv(RC_R(0)); | ||
| 1094 | assert(vtop->r2 < 7); | ||
| 1095 | if (vtop->r2 != 1 + vtop->r) { | ||
| 1096 | EI(0x13, 0, ireg(vtop->r) + 1, ireg(vtop->r2), 0); // mv Ra+1, RR2 | ||
| 1097 | vtop->r2 = 1 + vtop->r; | ||
| 1098 | } | ||
| 1099 | } | ||
| 1084 | vpush_global_sym(&func_old_type, func); | 1100 | vpush_global_sym(&func_old_type, func); |
| 1085 | vrott(2); | 1101 | gcall_or_jmp(1); |
| 1086 | gfunc_call(1); | 1102 | vtop -= 2; |
| 1087 | vpushi(0); | 1103 | vpushi(0); |
| 1088 | vtop->type.t = dt; | 1104 | vtop->type.t = dt; |
| 1089 | if (dt == VT_LDOUBLE) | 1105 | if (dt == VT_LDOUBLE) |