* 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 | 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 | 713 | ST_FUNC void gen_cvt_sxtw(void) |
| @@ -670,9 +726,21 @@ ST_FUNC void gen_cvt_ftoi(int t) · 12 unmodified lines | ||
| 670 | 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 | 746 | ST_FUNC void ggoto(void) |