|
1873 | 1873 | ;; Immediate Loading rules |
1874 | 1874 | ;; TODO: Loading the zero reg directly causes a bunch of regalloc errors, we should look into it. |
1875 | 1875 | ;; TODO: Load floats using `fld` instead of `ld` |
1876 | | -(decl imm (Type u64) Reg) |
| 1876 | +;; |
| 1877 | +;; Recursion: bounded since either float cases are reduced to integers, or the |
| 1878 | +;; shift case reduces to a smaller constant. |
| 1879 | +(decl rec imm (Type u64) Reg) |
1877 | 1880 |
|
1878 | 1881 | ;; Special-case 0.0 for floats to use the `(zero_reg)` directly. |
1879 | 1882 | ;; See #7162 for why this doesn't fall out of the rules below. |
|
2470 | 2473 | (rule 0 (load_op_reg_type _) $I64) |
2471 | 2474 |
|
2472 | 2475 | ;; Helper constructor to build a load instruction. |
2473 | | -(decl gen_load (AMode LoadOP MemFlags) Reg) |
| 2476 | +;; |
| 2477 | +;; Recursion: recursive rule can only match once, since it matches on |
| 2478 | +;; `LoadOP.Flh` and emits `LoadOP.Lh`. |
| 2479 | +(decl rec gen_load (AMode LoadOP MemFlags) Reg) |
2474 | 2480 | (rule (gen_load amode op flags) |
2475 | 2481 | (let ((dst WritableReg (temp_writable_reg (load_op_reg_type op))) |
2476 | 2482 | (_ Unit (emit (MInst.Load dst op flags amode)))) |
|
2661 | 2667 | (decl gen_stack_addr (StackSlot Offset32) Reg) |
2662 | 2668 | (extern constructor gen_stack_addr gen_stack_addr) |
2663 | 2669 |
|
2664 | | -(decl gen_select_xreg (IntegerCompare XReg XReg) XReg) |
| 2670 | +; Recursion: bounded by only matching when one of the inputs is a zero register, |
| 2671 | +; but not both. |
| 2672 | +(decl rec gen_select_xreg (IntegerCompare XReg XReg) XReg) |
2665 | 2673 |
|
2666 | 2674 | (rule 6 (gen_select_xreg (int_compare_decompose cc x y) x y) |
2667 | 2675 | (if-let (IntCC.UnsignedLessThan) (intcc_without_eq cc)) |
|
2994 | 3002 |
|
2995 | 3003 | ;; Generates a bitcast instruction. |
2996 | 3004 | ;; Args are: src, src_ty, dst_ty |
2997 | | -(decl gen_bitcast (Reg Type Type) Reg) |
| 3005 | +;; |
| 3006 | +;; Recursion: only recursive rule matches on vec-to-float, and emits vec-to-int |
| 3007 | +;; and int-to-float bitcasts, so this can only recurse once. |
| 3008 | +(decl rec gen_bitcast (Reg Type Type) Reg) |
2998 | 3009 |
|
2999 | 3010 | (rule 9 (gen_bitcast r (ty_supported_float_size $F16) (ty_supported_vec _)) (if-let false (has_zvfh)) (rv_vfmv_sf r (vstate_from_type $F32))) |
3000 | 3011 | (rule 8 (gen_bitcast r (ty_supported_vec ty) (ty_supported_float_size $F16)) (if-let false (has_zvfh)) (gen_bitcast (gen_bitcast r ty $I16) $I16 $F16)) |
|
3214 | 3225 | (convert FloatCompare IntegerCompare float_to_int_compare) |
3215 | 3226 |
|
3216 | 3227 | ;; Compare two floating point numbers and return a zero/non-zero result. |
3217 | | -(decl fcmp_to_float_compare (FloatCC Type FReg FReg) FloatCompare) |
| 3228 | +;; |
| 3229 | +;; Recursion: at most once to convert unordered comparisons into ordered comparisons. |
| 3230 | +(decl rec fcmp_to_float_compare (FloatCC Type FReg FReg) FloatCompare) |
3218 | 3231 |
|
3219 | 3232 | ;; Direct codegen for unordered comparisons is not that efficient, so invert |
3220 | 3233 | ;; the comparison to get an ordered comparison and generate that. Then invert |
|
0 commit comments