factor and cleanup the param passing code somewhat.
Unified · Split
| @@ -433,20 +433,20 @@ static void gcall_or_jmp(int docall) · 432 unmodified lines | |||
| 433 | } | 433 | } |
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | static void reg_pass(CType *type, int *rc, int *fieldofs, int ofs) | 436 | static void reg_pass_rec(CType *type, int *rc, int *fieldofs, int ofs) |
| 437 | { | 437 | { |
| 438 | if ((type->t & VT_BTYPE) == VT_STRUCT) { | 438 | if ((type->t & VT_BTYPE) == VT_STRUCT) { |
| 439 | Sym *f; | 439 | Sym *f; |
| 440 | if (type->ref->type.t == VT_UNION) | 440 | if (type->ref->type.t == VT_UNION) |
| 441 | rc[0] = -1; | 441 | rc[0] = -1; |
| 442 | else for (f = type->ref->next; f; f = f->next) | 442 | else for (f = type->ref->next; f; f = f->next) |
| 443 | reg_pass(&f->type, rc, fieldofs, ofs + f->c); | 443 | reg_pass_rec(&f->type, rc, fieldofs, ofs + f->c); |
| 444 | } else if (type->t & VT_ARRAY) { | 444 | } else if (type->t & VT_ARRAY) { |
| 445 | if (type->ref->c < 0 || type->ref->c > 2) | 445 | if (type->ref->c < 0 || type->ref->c > 2) |
| 446 | rc[0] = -1; | 446 | rc[0] = -1; |
| 447 | else { | 447 | else { |
| 448 | int a, sz = type_size(&type->ref->type, &a); | 448 | int a, sz = type_size(&type->ref->type, &a); |
| 449 | reg_pass(&type->ref->type, rc, fieldofs, ofs); | 449 | reg_pass_rec(&type->ref->type, rc, fieldofs, ofs); |
| 450 | if (rc[0] > 2 || (rc[0] == 2 && type->ref->c > 1)) | 450 | if (rc[0] > 2 || (rc[0] == 2 && type->ref->c > 1)) |
| 451 | rc[0] = -1; | 451 | rc[0] = -1; |
| 452 | else if (type->ref->c == 2 && rc[0] && rc[1] == RC_FLOAT) { | 452 | else if (type->ref->c == 2 && rc[0] && rc[1] == RC_FLOAT) { |
| @@ -465,20 +465,32 @@ static void reg_pass(CType *type, int *rc, int *fieldofs, int ofs) · 12 unmodified lines | |||
| 465 | rc[0] = -1; | 465 | rc[0] = -1; |
| 466 | } | 466 | } |
| 467 | 467 | ||
| 468 | static void reg_pass(CType *type, int *prc, int *fieldofs, int named) | ||
| 469 | { | ||
| 470 | prc[0] = 0; | ||
| 471 | reg_pass_rec(type, prc, fieldofs, 0); | ||
| 472 | if (prc[0] <= 0 || !named) { | ||
| 473 | int align, size = type_size(type, &align); | ||
| 474 | prc[0] = (size + 7) >> 3; | ||
| 475 | prc[1] = prc[2] = RC_INT; | ||
| 476 | fieldofs[1] = (0 << 4) | (size <= 1 ? VT_BYTE : size <= 2 ? VT_SHORT : size <= 4 ? VT_INT : VT_LLONG); | ||
| 477 | fieldofs[2] = (8 << 4) | (size <= 9 ? VT_BYTE : size <= 10 ? VT_SHORT : size <= 12 ? VT_INT : VT_LLONG); | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 468 | ST_FUNC void gfunc_call(int nb_args) | 481 | ST_FUNC void gfunc_call(int nb_args) |
| 469 | { | 482 | { |
| 470 | int i, align, size, aireg, afreg; | 483 | int i, align, size, areg[2]; |
| 471 | int info[nb_args ? nb_args : 1]; | 484 | int info[nb_args ? nb_args : 1]; |
| 472 | int stack_adj = 0, tempspace = 0, ofs, splitofs = 0; | 485 | int stack_adj = 0, tempspace = 0, ofs, splitofs = 0; |
| 473 | int force_stack = 0; | ||
| 474 | SValue *sv; | 486 | SValue *sv; |
| 475 | Sym *sa; | 487 | Sym *sa; |
| 476 | aireg = afreg = 0; | 488 | areg[0] = 0; /* int arg regs */ |
| 489 | areg[1] = 8; /* float arg regs */ | ||
| 477 | sa = vtop[-nb_args].type.ref->next; | 490 | sa = vtop[-nb_args].type.ref->next; |
| 478 | for (i = 0; i < nb_args; i++) { | 491 | for (i = 0; i < nb_args; i++) { |
| 479 | int *pareg, nregs, byref = 0, tempofs; | 492 | int nregs, byref = 0, tempofs; |
| 480 | int prc[3], fieldofs[3]; | 493 | int prc[3], fieldofs[3]; |
| 481 | prc[0] = 0; | ||
| 482 | sv = &vtop[1 + i - nb_args]; | 494 | sv = &vtop[1 + i - nb_args]; |
| 483 | sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c | 495 | sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c |
| 484 | size = type_size(&sv->type, &align); | 496 | size = type_size(&sv->type, &align); |
| @@ -489,53 +501,43 @@ ST_FUNC void gfunc_call(int nb_args) · 4 unmodified lines | |||
| 489 | tempofs = tempspace; | 501 | tempofs = tempspace; |
| 490 | tempspace += size; | 502 | tempspace += size; |
| 491 | size = align = 8; | 503 | size = align = 8; |
| 492 | byref = 1; | 504 | byref = 64 | (tempofs << 7); |
| 493 | } | ||
| 494 | if (size > 8) | ||
| 495 | nregs = 2; | ||
| 496 | else | ||
| 497 | nregs = 1; | ||
| 498 | if (!sa) { | ||
| 499 | prc[0] = nregs, prc[1] = prc[2] = RC_INT; | ||
| 500 | } else { | ||
| 501 | reg_pass(&sv->type, prc, fieldofs, 0); | ||
| 502 | if (prc[0] < 0) | ||
| 503 | prc[0] = nregs, prc[1] = prc[2] = RC_INT; | ||
| 504 | } | 505 | } |
| 506 | reg_pass(&sv->type, prc, fieldofs, sa != 0); | ||
| 505 | if (!sa && align == 2*XLEN && size <= 2*XLEN) | 507 | if (!sa && align == 2*XLEN && size <= 2*XLEN) |
| 506 | aireg = (aireg + 1) & ~1; | 508 | areg[0] = (areg[0] + 1) & ~1; |
| 507 | nregs = prc[0]; | 509 | nregs = prc[0]; |
| 508 | assert(nregs); | 510 | if ((prc[1] == RC_INT && areg[0] >= 8) |
| 509 | if (!nregs | 511 | || (prc[1] == RC_FLOAT && areg[1] >= 16) |
| 510 | || (prc[1] == RC_INT && aireg >= 8) | 512 | || (nregs == 2 && prc[1] == RC_FLOAT && prc[2] == RC_FLOAT |
| 511 | || (prc[1] == RC_FLOAT && afreg >= 8) | 513 | && areg[1] >= 15) |
| 512 | || (nregs == 2 && prc[2] == RC_FLOAT && afreg >= 7) | 514 | || (nregs == 2 && prc[1] != prc[2] |
| 513 | || (nregs == 2 && prc[1] != prc[2] && (afreg >= 8 || aireg >= 8)) | 515 | && (areg[1] >= 16 || areg[0] >= 8))) { |
| 514 | || force_stack) { | ||
| 515 | info[i] = 32; | 516 | info[i] = 32; |
| 516 | if (align < XLEN) | 517 | if (align < XLEN) |
| 517 | align = XLEN; | 518 | align = XLEN; |
| 518 | stack_adj += (size + align - 1) & -align; | 519 | stack_adj += (size + align - 1) & -align; |
| 519 | if (!sa) | 520 | if (!sa) /* one vararg on stack forces the rest on stack */ |
| 520 | force_stack = 1; | 521 | areg[0] = 8, areg[1] = 16; |
| 521 | } else { | 522 | } else { |
| 522 | if (prc[1] == RC_FLOAT) | 523 | info[i] = areg[prc[1] - 1]++; |
| 523 | info[i] = 8 + afreg++; | 524 | if (!byref) |
| 524 | else | 525 | info[i] |= (fieldofs[1] & VT_BTYPE) << 12; |
| 525 | info[i] = aireg++; | 526 | assert(!(fieldofs[1] >> 4)); |
| 526 | if (nregs == 2) { | 527 | if (nregs == 2) { |
| 527 | if (prc[2] == RC_FLOAT) | 528 | if (prc[2] == RC_FLOAT || areg[0] < 8) |
| 528 | info[i] |= (1 + 8 + afreg++) << 7; | 529 | info[i] |= (1 + areg[prc[2] - 1]++) << 7; |
| 529 | else if (aireg < 8) | ||
| 530 | info[i] |= (1 + aireg++) << 7; | ||
| 531 | else { | 530 | else { |
| 532 | info[i] |= 16; | 531 | info[i] |= 16; |
| 533 | stack_adj += 8; | 532 | stack_adj += 8; |
| 534 | } | 533 | } |
| 534 | if (!byref) { | ||
| 535 | assert((fieldofs[2] >> 4) < 2048); | ||
| 536 | info[i] |= fieldofs[2] << (12 + 4); // includes offset | ||
| 537 | } | ||
| 535 | } | 538 | } |
| 536 | } | 539 | } |
| 537 | if (byref) | 540 | info[i] |= byref; |
| 538 | info[i] |= 64 | (tempofs << 7); | ||
| 539 | if (sa) | 541 | if (sa) |
| 540 | sa = sa->next; | 542 | sa = sa->next; |
| 541 | } | 543 | } |
| @@ -544,7 +546,7 @@ ST_FUNC void gfunc_call(int nb_args) · 2 unmodified lines | |||
| 544 | if (stack_adj + tempspace) { | 546 | if (stack_adj + tempspace) { |
| 545 | EI(0x13, 0, 2, 2, -(stack_adj + tempspace)); // addi sp, sp, -adj | 547 | EI(0x13, 0, 2, 2, -(stack_adj + tempspace)); // addi sp, sp, -adj |
| 546 | for (i = ofs = 0; i < nb_args; i++) { | 548 | for (i = ofs = 0; i < nb_args; i++) { |
| 547 | if (info[i] >= 32) { | 549 | if (info[i] & (64 | 32)) { |
| 548 | vrotb(nb_args - i); | 550 | vrotb(nb_args - i); |
| 549 | size = type_size(&vtop->type, &align); | 551 | size = type_size(&vtop->type, &align); |
| 550 | if (info[i] & 64) { | 552 | if (info[i] & 64) { |
| @@ -587,26 +589,19 @@ ST_FUNC void gfunc_call(int nb_args) · 36 unmodified lines | |||
| 587 | } | 589 | } |
| 588 | } | 590 | } |
| 589 | for (i = 0; i < nb_args; i++) { | 591 | for (i = 0; i < nb_args; i++) { |
| 590 | int r = info[nb_args - 1 - i], r2 = r; | 592 | int ii = info[nb_args - 1 - i], r = ii, r2 = r; |
| 591 | if (!(r & 32)) { | 593 | if (!(r & 32)) { |
| 592 | CType origtype; | 594 | CType origtype; |
| 593 | int prc[3], fieldofs[3], loadt; | 595 | int loadt; |
| 594 | prc[0] = 0; | ||
| 595 | r &= 15; | 596 | r &= 15; |
| 596 | r2 = r2 & 64 ? 0 : r2 >> 7; | 597 | r2 = r2 & 64 ? 0 : (r2 >> 7) & 31; |
| 598 | assert(r2 <= 16); | ||
| 597 | vrotb(i+1); | 599 | vrotb(i+1); |
| 598 | origtype = vtop->type; | 600 | origtype = vtop->type; |
| 599 | size = type_size(&vtop->type, &align); | 601 | size = type_size(&vtop->type, &align); |
| 600 | reg_pass(&vtop->type, prc, fieldofs, 0); | ||
| 601 | if (prc[0] <= 0 || (!r2 && prc[0] > 1)) { | ||
| 602 | prc[0] = (size + 7) >> 3; | ||
| 603 | prc[1] = prc[2] = RC_INT; | ||
| 604 | fieldofs[1] = (0 << 4) | (size <= 1 ? VT_BYTE : size <= 2 ? VT_SHORT : size <= 4 ? VT_INT : VT_LLONG); | ||
| 605 | fieldofs[2] = (8 << 4) | (size <= 9 ? VT_BYTE : size <= 10 ? VT_SHORT : size <= 12 ? VT_INT : VT_LLONG); | ||
| 606 | } | ||
| 607 | loadt = vtop->type.t & VT_BTYPE; | 602 | loadt = vtop->type.t & VT_BTYPE; |
| 608 | if (loadt == VT_STRUCT) { | 603 | if (loadt == VT_STRUCT) { |
| 609 | loadt = fieldofs[1] & VT_BTYPE; | 604 | loadt = (ii >> 12) & VT_BTYPE; |
| 610 | } | 605 | } |
| 611 | if (info[nb_args - 1 - i] & 16) { | 606 | if (info[nb_args - 1 - i] & 16) { |
| 612 | assert(!r2); | 607 | assert(!r2); |
| @@ -629,13 +624,13 @@ ST_FUNC void gfunc_call(int nb_args) · 16 unmodified lines | |||
| 629 | vswap(); | 624 | vswap(); |
| 630 | gaddrof(); | 625 | gaddrof(); |
| 631 | vtop->type = char_pointer_type; | 626 | vtop->type = char_pointer_type; |
| 632 | vpushi(fieldofs[2] >> 4); | 627 | vpushi(ii >> 20); |
| 633 | gen_op('+'); | 628 | gen_op('+'); |
| 634 | indir(); | 629 | indir(); |
| 635 | vtop->type = origtype; | 630 | vtop->type = origtype; |
| 636 | loadt = vtop->type.t & VT_BTYPE; | 631 | loadt = vtop->type.t & VT_BTYPE; |
| 637 | if (loadt == VT_STRUCT) { | 632 | if (loadt == VT_STRUCT) { |
| 638 | loadt = fieldofs[2] & VT_BTYPE; | 633 | loadt = (ii >> 16) & VT_BTYPE; |
| 639 | } | 634 | } |
| 640 | save_reg_upstack(r2, 1); | 635 | save_reg_upstack(r2, 1); |
| 641 | vtop->type.t = loadt; | 636 | vtop->type.t = loadt; |
| @@ -671,7 +666,7 @@ ST_FUNC void gfunc_prolog(CType *func_type) · 29 unmodified lines | |||
| 671 | { | 666 | { |
| 672 | int i, addr, align, size; | 667 | int i, addr, align, size; |
| 673 | int param_addr = 0; | 668 | int param_addr = 0; |
| 674 | int aireg, afreg; | 669 | int areg[2]; |
| 675 | Sym *sym; | 670 | Sym *sym; |
| 676 | CType *type; | 671 | CType *type; |
| 677 | 672 | ||
| @@ -681,69 +676,51 @@ ST_FUNC void gfunc_prolog(CType *func_type) · 3 unmodified lines | |||
| 681 | func_sub_sp_offset = ind; | 676 | func_sub_sp_offset = ind; |
| 682 | ind += 5 * 4; | 677 | ind += 5 * 4; |
| 683 | 678 | ||
| 684 | aireg = afreg = 0; | 679 | areg[0] = 0, areg[1] = 0; |
| 685 | addr = 0; // XXX not correct | 680 | addr = 0; |
| 686 | /* if the function returns by reference, then add an | 681 | /* if the function returns by reference, then add an |
| 687 | implicit pointer parameter */ | 682 | implicit pointer parameter */ |
| 688 | size = type_size(&func_vt, &align); | 683 | size = type_size(&func_vt, &align); |
| 689 | if (size > 2 * XLEN) { | 684 | if (size > 2 * XLEN) { |
| 690 | loc -= 8; | 685 | loc -= 8; |
| 691 | func_vc = loc; | 686 | func_vc = loc; |
| 692 | ES(0x23, 3, 8, 10 + aireg, loc); // sd a0, loc(s0) | 687 | ES(0x23, 3, 8, 10 + areg[0]++, loc); // sd a0, loc(s0) |
| 693 | aireg++; | ||
| 694 | } | 688 | } |
| 695 | /* define parameters */ | 689 | /* define parameters */ |
| 696 | while ((sym = sym->next) != NULL) { | 690 | while ((sym = sym->next) != NULL) { |
| 697 | int byref = 0; | 691 | int byref = 0; |
| 692 | int regcount; | ||
| 693 | int prc[3], fieldofs[3]; | ||
| 698 | type = &sym->type; | 694 | type = &sym->type; |
| 699 | size = type_size(type, &align); | 695 | size = type_size(type, &align); |
| 700 | if (size > 2 * XLEN) { | 696 | if (size > 2 * XLEN) { |
| 701 | type = &char_pointer_type; | 697 | type = &char_pointer_type; |
| 702 | size = align = byref = 8; | 698 | size = align = byref = 8; |
| 703 | } | 699 | } |
| 704 | if (size > 2 * XLEN) { | 700 | reg_pass(type, prc, fieldofs, 1); |
| 705 | from_stack: | 701 | regcount = prc[0]; |
| 702 | if (areg[prc[1] - 1] >= 8 | ||
| 703 | || (regcount == 2 | ||
| 704 | && ((prc[1] == RC_FLOAT && prc[2] == RC_FLOAT && areg[1] >= 7) | ||
| 705 | || (prc[1] != prc[2] && (areg[1] >= 8 || areg[0] >= 8))))) { | ||
| 706 | if (align < XLEN) | 706 | if (align < XLEN) |
| 707 | align = XLEN; | 707 | align = XLEN; |
| 708 | addr = (addr + align - 1) & -align; | 708 | addr = (addr + align - 1) & -align; |
| 709 | param_addr = addr; | 709 | param_addr = addr; |
| 710 | addr += size; | 710 | addr += size; |
| 711 | } else { | 711 | } else { |
| 712 | int regcount, *pareg; | ||
| 713 | int prc[3], fieldofs[3]; | ||
| 714 | prc[0] = 0; | ||
| 715 | reg_pass(type, prc, fieldofs, 0); | ||
| 716 | if (prc[0] <= 0) { | ||
| 717 | prc[0] = (size + 7) >> 3; | ||
| 718 | prc[1] = prc[2] = RC_INT; | ||
| 719 | fieldofs[1] = (0 << 4) | (size <= 1 ? VT_BYTE : size <= 2 ? VT_SHORT : size <= 4 ? VT_INT : VT_LLONG); | ||
| 720 | fieldofs[2] = (8 << 4) | (size <= 9 ? VT_BYTE : size <= 10 ? VT_SHORT : size <= 12 ? VT_INT : VT_LLONG); | ||
| 721 | } | ||
| 722 | regcount = prc[0]; | ||
| 723 | if (!regcount | ||
| 724 | || (prc[1] == RC_INT && aireg >= 8) | ||
| 725 | || (prc[1] == RC_FLOAT && afreg >= 8) | ||
| 726 | || (regcount == 2 && prc[2] == RC_FLOAT && afreg >= 7) | ||
| 727 | || (regcount == 2 && prc[1] != prc[2] && (afreg >= 8 || aireg >= 8))) | ||
| 728 | goto from_stack; | ||
| 729 | if (size > XLEN) | ||
| 730 | assert(regcount == 2); | ||
| 731 | loc -= regcount * 8; // XXX could reserve only 'size' bytes | 712 | loc -= regcount * 8; // XXX could reserve only 'size' bytes |
| 732 | param_addr = loc; | 713 | param_addr = loc; |
| 733 | for (i = 0; i < regcount; i++) { | 714 | for (i = 0; i < regcount; i++) { |
| 734 | pareg = prc[1+i] == RC_INT ? &aireg : &afreg; | 715 | if (areg[prc[1+i] - 1] >= 8) { |
| 735 | if (*pareg >= 8) { | ||
| 736 | assert(i == 1 && regcount == 2 && !(addr & 7)); | 716 | assert(i == 1 && regcount == 2 && !(addr & 7)); |
| 737 | EI(0x03, 3, 5, 8, addr); // ld t0, addr(s0) | 717 | EI(0x03, 3, 5, 8, addr); // ld t0, addr(s0) |
| 738 | addr += 8; | 718 | addr += 8; |
| 739 | ES(0x23, 3, 8, 5, loc + i*8); // sd t0, loc(s0) | 719 | ES(0x23, 3, 8, 5, loc + i*8); // sd t0, loc(s0) |
| 740 | continue; | 720 | } else if (prc[1+i] == RC_FLOAT) { |
| 741 | } | 721 | ES(0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0) |
| 742 | if (pareg == &afreg) { | ||
| 743 | //assert(type->t == VT_FLOAT || type->t == VT_DOUBLE); | ||
| 744 | ES(0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + afreg++, loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0) | ||
| 745 | } else { | 722 | } else { |
| 746 | ES(0x23, 3, 8, 10 + aireg++, loc + i*8); // sd aX, loc(s0) // XXX | 723 | ES(0x23, 3, 8, 10 + areg[0]++, loc + i*8); // sd aX, loc(s0) // XXX |
| 747 | } | 724 | } |
| 748 | } | 725 | } |
| 749 | } | 726 | } |
| @@ -754,9 +731,9 @@ ST_FUNC void gfunc_prolog(CType *func_type) · 4 unmodified lines | |||
| 754 | func_va_list_ofs = addr; | 731 | func_va_list_ofs = addr; |
| 755 | num_va_regs = 0; | 732 | num_va_regs = 0; |
| 756 | if (func_type->ref->f.func_type == FUNC_ELLIPSIS) { | 733 | if (func_type->ref->f.func_type == FUNC_ELLIPSIS) { |
| 757 | for (; aireg < 8; aireg++) { | 734 | for (; areg[0] < 8; areg[0]++) { |
| 758 | num_va_regs++; | 735 | num_va_regs++; |
| 759 | ES(0x23, 3, 8, 10 + aireg, -8 + num_va_regs * 8); // sd aX, loc(s0) | 736 | ES(0x23, 3, 8, 10 + areg[0], -8 + num_va_regs * 8); // sd aX, loc(s0) |
| 760 | } | 737 | } |
| 761 | } | 738 | } |
| 762 | } | 739 | } |
| @@ -764,22 +741,14 @@ ST_FUNC void gfunc_prolog(CType *func_type) · 1 unmodified line | |||
| 764 | ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, | 741 | ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, |
| 765 | int *ret_align, int *regsize) | 742 | int *ret_align, int *regsize) |
| 766 | { | 743 | { |
| 767 | int align, size = type_size(vt, &align), infreg, nregs; | 744 | int align, size = type_size(vt, &align), nregs; |
| 768 | int prc[3], fieldofs[3]; | 745 | int prc[3], fieldofs[3]; |
| 769 | *ret_align = 1; | 746 | *ret_align = 1; |
| 770 | *regsize = 8; | 747 | *regsize = 8; |
| 771 | if (size > 16) | 748 | if (size > 16) |
| 772 | return 0; | 749 | return 0; |
| 773 | prc[0] = 0; | 750 | reg_pass(vt, prc, fieldofs, 1); |
| 774 | reg_pass(vt, prc, fieldofs, 0); | ||
| 775 | if (prc[0] <= 0) { | ||
| 776 | prc[0] = (size + 7) >> 3; | ||
| 777 | prc[1] = prc[2] = RC_INT; | ||
| 778 | fieldofs[1] = (0 << 4) | (size <= 1 ? VT_BYTE : size <= 2 ? VT_SHORT : size <= 4 ? VT_INT : VT_LLONG); | ||
| 779 | fieldofs[2] = (8 << 4) | (size <= 9 ? VT_BYTE : size <= 10 ? VT_SHORT : size <= 12 ? VT_INT : VT_LLONG); | ||
| 780 | } | ||
| 781 | nregs = prc[0]; | 751 | nregs = prc[0]; |
| 782 | assert(nregs > 0); | ||
| 783 | if (nregs == 2 && prc[1] != prc[2]) | 752 | if (nregs == 2 && prc[1] != prc[2]) |
| 784 | return -1; /* generic code can't deal with this case */ | 753 | return -1; /* generic code can't deal with this case */ |
| 785 | if (prc[1] == RC_FLOAT) { | 754 | if (prc[1] == RC_FLOAT) { |
| @@ -792,22 +761,15 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, · 6 unmodified lines | |||
| 792 | ST_FUNC void arch_transfer_ret_regs(int aftercall) | 761 | ST_FUNC void arch_transfer_ret_regs(int aftercall) |
| 793 | { | 762 | { |
| 794 | int prc[3], fieldofs[3]; | 763 | int prc[3], fieldofs[3]; |
| 795 | prc[0] = 0; | 764 | reg_pass(&vtop->type, prc, fieldofs, 1); |
| 796 | reg_pass(&vtop->type, prc, fieldofs, 0); | ||
| 797 | assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4)); | 765 | assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4)); |
| 798 | assert(vtop->r == (VT_LOCAL | VT_LVAL)); | 766 | assert(vtop->r == (VT_LOCAL | VT_LVAL)); |
| 799 | vpushv(vtop); | 767 | vpushv(vtop); |
| 800 | vtop->type.t = fieldofs[1] & VT_BTYPE; | 768 | vtop->type.t = fieldofs[1] & VT_BTYPE; |
| 801 | if (aftercall) | 769 | (aftercall ? store : load)(prc[1] == RC_INT ? REG_IRET : REG_FRET, vtop); |
| 802 | store(prc[1] == RC_INT ? REG_IRET : REG_FRET, vtop); | ||
| 803 | else | ||
| 804 | load(prc[1] == RC_INT ? REG_IRET : REG_FRET, vtop); | ||
| 805 | vtop->c.i += fieldofs[2] >> 4; | 770 | vtop->c.i += fieldofs[2] >> 4; |
| 806 | vtop->type.t = fieldofs[2] & VT_BTYPE; | 771 | vtop->type.t = fieldofs[2] & VT_BTYPE; |
| 807 | if (aftercall) | 772 | (aftercall ? store : load)(prc[2] == RC_INT ? REG_IRET : REG_FRET, vtop); |
| 808 | store(prc[2] == RC_INT ? REG_IRET : REG_FRET, vtop); | ||
| 809 | else | ||
| 810 | load(prc[2] == RC_INT ? REG_IRET : REG_FRET, vtop); | ||
| 811 | vtop--; | 773 | vtop--; |
| 812 | } | 774 | } |
| 813 | 775 | ||
| @@ -857,11 +819,6 @@ ST_FUNC void gen_va_start(void) · 43 unmodified lines | |||
| 857 | vset(&char_pointer_type, VT_LOCAL, func_va_list_ofs); | 819 | vset(&char_pointer_type, VT_LOCAL, func_va_list_ofs); |
| 858 | } | 820 | } |
| 859 | 821 | ||
| 860 | ST_FUNC void gen_va_arg(CType *t) | ||
| 861 | { | ||
| 862 | tcc_error("implement me: %s", __FUNCTION__); | ||
| 863 | } | ||
| 864 | |||
| 865 | ST_FUNC void gen_fill_nops(int bytes) | 822 | ST_FUNC void gen_fill_nops(int bytes) |
| 866 | { | 823 | { |
| 867 | if ((bytes & 3)) | 824 | if ((bytes & 3)) |
| @@ -1606,7 +1606,6 @@ ST_FUNC void gen_cvt_sxtw(void); · 1605 unmodified lines | |||
| 1606 | ST_FUNC void gen_opl(int op); | 1606 | ST_FUNC void gen_opl(int op); |
| 1607 | //ST_FUNC void gfunc_return(CType *func_type); | 1607 | //ST_FUNC void gfunc_return(CType *func_type); |
| 1608 | ST_FUNC void gen_va_start(void); | 1608 | ST_FUNC void gen_va_start(void); |
| 1609 | ST_FUNC void gen_va_arg(CType *t); | ||
| 1610 | ST_FUNC void arch_transfer_ret_regs(int); | 1609 | ST_FUNC void arch_transfer_ret_regs(int); |
| 1611 | #endif | 1610 | #endif |
| 1612 | /* ------------ c67-gen.c ------------ */ | 1611 | /* ------------ c67-gen.c ------------ */ |