* compares * add/sub/mul/div * float-float converts makes 22_floating_point work.
Unified · Split
| @@ -651,7 +651,63 @@ ST_FUNC void gen_opl(int op) · 650 unmodified lines | |||
| 651 | 651 | ||
| 652 | ST_FUNC void gen_opf(int op) | 652 | ST_FUNC void gen_opf(int op) |
| 653 | { | 653 | { |
| 654 | tcc_error("implement me: %s", __FUNCTION__); | 654 | int rs1, rs2, rd, dbl, invert; |
| 655 | gv2(RC_FLOAT, RC_FLOAT); | ||
| 656 | assert(vtop->type.t == VT_DOUBLE || vtop->type.t == VT_FLOAT); | ||
| 657 | dbl = vtop->type.t == VT_DOUBLE; | ||
| 658 | rs1 = freg(vtop[-1].r); | ||
| 659 | rs2 = freg(vtop->r); | ||
| 660 | vtop--; | ||
| 661 | invert = 0; | ||
| 662 | switch(op) { | ||
| 663 | default: | ||
| 664 | assert(0); | ||
| 665 | case '+': | ||
| 666 | op = 0; // fadd | ||
| 667 | arithop: | ||
| 668 | rd = get_reg(RC_FLOAT); | ||
| 669 | vtop->r = rd; | ||
| 670 | rd = freg(rd); | ||
| 671 | o(0x53 | (rd << 7) | (rs1 << 15) | (rs2 << 20) | (7 << 12) | (dbl << 25) | (op << 27)); // fop.[sd] RD, RS1, RS2 (dyn rm) | ||
| 672 | break; | ||
| 673 | case '-': | ||
| 674 | op = 1; // fsub | ||
| 675 | goto arithop; | ||
| 676 | case '*': | ||
| 677 | op = 2; // fmul | ||
| 678 | goto arithop; | ||
| 679 | case '/': | ||
| 680 | op = 3; // fdiv | ||
| 681 | goto arithop; | ||
| 682 | case TOK_EQ: | ||
| 683 | op = 2; // EQ | ||
| 684 | cmpop: | ||
| 685 | rd = get_reg(RC_INT); | ||
| 686 | vtop->r = rd; | ||
| 687 | rd = ireg(rd); | ||
| 688 | o(0x53 | (rd << 7) | (rs1 << 15) | (rs2 << 20) | (op << 12) | (dbl << 25) | (0x14 << 27)); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le) | ||
| 689 | if (invert) | ||
| 690 | EI(0x13, 4, rd, rd, 1); // xori RD, 1 | ||
| 691 | break; | ||
| 692 | case TOK_NE: | ||
| 693 | invert = 1; | ||
| 694 | op = 2; // EQ | ||
| 695 | goto cmpop; | ||
| 696 | case TOK_LT: | ||
| 697 | op = 1; // LT | ||
| 698 | goto cmpop; | ||
| 699 | case TOK_LE: | ||
| 700 | op = 0; // LE | ||
| 701 | goto cmpop; | ||
| 702 | case TOK_GT: | ||
| 703 | op = 1; // LT | ||
| 704 | rd = rs1, rs1 = rs2, rs2 = rd; | ||
| 705 | goto cmpop; | ||
| 706 | case TOK_GE: | ||
| 707 | op = 0; // LE | ||
| 708 | rd = rs1, rs1 = rs2, rs2 = rd; | ||
| 709 | goto cmpop; | ||
| 710 | } | ||
| 655 | } | 711 | } |
| 656 | 712 | ||
| 657 | ST_FUNC void gen_cvt_sxtw(void) | 713 | ST_FUNC void gen_cvt_sxtw(void) |
| @@ -670,9 +726,21 @@ ST_FUNC void gen_cvt_ftoi(int t) · 12 unmodified lines | |||
| 670 | tcc_error("implement me: %s", __FUNCTION__); | 726 | tcc_error("implement me: %s", __FUNCTION__); |
| 671 | } | 727 | } |
| 672 | 728 | ||
| 673 | ST_FUNC void gen_cvt_ftof(int t) | 729 | ST_FUNC void gen_cvt_ftof(int dt) |
| 674 | { | 730 | { |
| 675 | tcc_error("implement me: %s", __FUNCTION__); | 731 | int st = vtop->type.t & VT_BTYPE, rs, rd; |
| 732 | dt &= VT_BTYPE; | ||
| 733 | assert (dt == VT_FLOAT || dt == VT_DOUBLE); | ||
| 734 | assert (st == VT_FLOAT || st == VT_DOUBLE); | ||
| 735 | if (st == dt) | ||
| 736 | return; | ||
| 737 | rs = gv(RC_FLOAT); | ||
| 738 | rd = get_reg(RC_FLOAT); | ||
| 739 | if (dt == VT_DOUBLE) | ||
| 740 | EI(0x53, 7, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (dyn rm) | ||
| 741 | else | ||
| 742 | EI(0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS | ||
| 743 | vtop->r = rd; | ||
| 676 | } | 744 | } |
| 677 | 745 | ||
| 678 | ST_FUNC void ggoto(void) | 746 | ST_FUNC void ggoto(void) |