|
1810 | 1810 | (extern extractor is_imm8_xmm is_imm8_xmm)
|
1811 | 1811 | (decl is_simm8 (i8) GprMemImm)
|
1812 | 1812 | (extern extractor is_simm8 is_simm8)
|
| 1813 | +(decl is_rust_simm8 (i8) i32) |
| 1814 | +(extern extractor is_rust_simm8 is_rust_simm8) |
1813 | 1815 | (decl is_imm16 (u16) GprMemImm)
|
1814 | 1816 | (extern extractor is_imm16 is_imm16)
|
| 1817 | +(decl is_rust_imm16 (u16) i32) |
| 1818 | +(extern extractor is_rust_imm16 is_rust_imm16) |
1815 | 1819 | (decl is_simm16 (i16) GprMemImm)
|
1816 | 1820 | (extern extractor is_simm16 is_simm16)
|
1817 | 1821 | (decl is_imm32 (u32) GprMemImm)
|
1818 | 1822 | (extern extractor is_imm32 is_imm32)
|
| 1823 | +(decl is_rust_imm32 (u32) i32) |
| 1824 | +(extern extractor is_rust_imm32 is_rust_imm32) |
1819 | 1825 | (decl is_simm32 (i32) GprMemImm)
|
1820 | 1826 | (extern extractor is_simm32 is_simm32)
|
1821 | 1827 | (decl is_gpr (Gpr) GprMemImm)
|
|
2693 | 2699 | (decl asm_produce_flags (AssemblerOutputs) ProducesFlags)
|
2694 | 2700 | (rule (asm_produce_flags (AssemblerOutputs.RetGpr inst gpr))
|
2695 | 2701 | (ProducesFlags.ProducesFlagsReturnsResultWithConsumer inst gpr))
|
| 2702 | +(rule (asm_produce_flags (AssemblerOutputs.RetValueRegs inst regs)) |
| 2703 | + (ProducesFlags.ProducesFlagsReturnsResultWithConsumer inst (value_regs_get_gpr regs 0))) |
2696 | 2704 |
|
2697 | 2705 | ;; Other operations consume _and_ produce flags--"chaining".
|
2698 | 2706 | (type ChainFlagsOp (enum (Adc) (Sbb)))
|
|
2883 | 2891 |
|
2884 | 2892 |
|
2885 | 2893 | ;; Helper for creating `mul` instructions or `imul` instructions (depending
|
2886 |
| -;; on `signed`) |
2887 |
| -(decl x64_mul (Type bool Gpr GprMem) ValueRegs) |
2888 |
| -(rule (x64_mul ty signed src1 src2) |
2889 |
| - (let ((dst_lo WritableGpr (temp_writable_gpr)) |
2890 |
| - (dst_hi WritableGpr (temp_writable_gpr)) |
2891 |
| - (size OperandSize (raw_operand_size_of_type ty)) |
2892 |
| - (_ Unit (emit (MInst.Mul size signed src1 src2 dst_lo dst_hi)))) |
2893 |
| - (value_gprs dst_lo dst_hi))) |
| 2894 | +;; on `signed`). For the 8-bit rules, see `x64_mul8`. |
| 2895 | +(decl x64_mul_raw (Type bool Gpr GprMem) AssemblerOutputs) |
| 2896 | +(rule (x64_mul_raw $I16 false src1 src2) (x64_mulw_m_raw src1 src2)) |
| 2897 | +(rule (x64_mul_raw $I32 false src1 src2) (x64_mull_m_raw src1 src2)) |
| 2898 | +(rule (x64_mul_raw $I64 false src1 src2) (x64_mulq_m_raw src1 src2)) |
| 2899 | +(rule (x64_mul_raw $I16 true src1 src2) (x64_imulw_m_raw src1 src2)) |
| 2900 | +(rule (x64_mul_raw $I32 true src1 src2) (x64_imull_m_raw src1 src2)) |
| 2901 | +(rule (x64_mul_raw $I64 true src1 src2) (x64_imulq_m_raw src1 src2)) |
2894 | 2902 |
|
| 2903 | +(decl x64_mul (Type bool Gpr GprMem) ValueRegs) |
| 2904 | +(rule 0 (x64_mul ty signed src1 src2) |
| 2905 | + (emit_ret_value_regs (x64_mul_raw ty signed src1 src2))) |
2895 | 2906 | ;; Special case the `mulx` pattern with the BMI2 instruction set.
|
2896 | 2907 | (rule 1 (x64_mul (ty_32_or_64 ty) false src1 src2)
|
2897 | 2908 | (if-let true (use_bmi2))
|
|
2908 | 2919 | (_ Unit (emit (MInst.MulX size src1 src2 (writable_invalid_gpr) dst))))
|
2909 | 2920 | dst))
|
2910 | 2921 |
|
| 2922 | +(decl x64_mul_lo_with_flags_paired (Type bool Gpr GprMem) ProducesFlags) |
| 2923 | +(rule (x64_mul_lo_with_flags_paired ty signed src1 src2) |
| 2924 | + (asm_produce_flags (x64_mul_raw ty signed src1 src2))) |
| 2925 | + |
2911 | 2926 | ;; Get the invalid register as writable
|
2912 | 2927 | (decl writable_invalid_gpr () WritableGpr)
|
2913 | 2928 | (extern constructor writable_invalid_gpr writable_invalid_gpr)
|
2914 | 2929 |
|
2915 |
| -;; Helper for creating `mul` instructions or `imul` instructions (depending |
2916 |
| -;; on `signed`) for 8-bit operands. |
2917 |
| -(decl x64_mul8 (bool Gpr GprMem) Gpr) |
2918 |
| -(rule (x64_mul8 signed src1 src2) |
2919 |
| - (let ((dst WritableGpr (temp_writable_gpr)) |
2920 |
| - (_ Unit (emit (MInst.Mul8 signed src1 src2 dst)))) |
2921 |
| - dst)) |
2922 |
| - |
2923 | 2930 | ;; Helper for creating `imul` instructions.
|
2924 | 2931 | (decl x64_imul (Type Gpr GprMem) Gpr)
|
2925 |
| -(rule (x64_imul ty src1 src2) |
2926 |
| - (let ((dst WritableGpr (temp_writable_gpr)) |
2927 |
| - (size OperandSize (raw_operand_size_of_type ty)) |
2928 |
| - (_ Unit (emit (MInst.IMul size src1 src2 dst)))) |
2929 |
| - dst)) |
| 2932 | +(rule (x64_imul $I16 src1 src2) (x64_imulw_rm src1 src2)) |
| 2933 | +(rule (x64_imul $I32 src1 src2) (x64_imull_rm src1 src2)) |
| 2934 | +(rule (x64_imul $I64 src1 src2) (x64_imulq_rm src1 src2)) |
2930 | 2935 |
|
2931 |
| -;; Helper for creating `imul` instructions with an immediate operand. |
| 2936 | +;; Helper for creating `imul` instructions with an immediate operand. Match |
| 2937 | +;; 8-bit immediates first to allow a smaller instruction encoding. |
2932 | 2938 | (decl x64_imul_imm (Type GprMem i32) Gpr)
|
2933 |
| -(rule (x64_imul_imm ty src1 src2) |
2934 |
| - (let ((dst WritableGpr (temp_writable_gpr)) |
2935 |
| - (size OperandSize (raw_operand_size_of_type ty)) |
2936 |
| - (_ Unit (emit (MInst.IMulImm size src1 src2 dst)))) |
2937 |
| - dst)) |
| 2939 | +(rule 2 (x64_imul_imm $I16 src1 (is_rust_simm8 src2)) (x64_imulw_rmi_sxb src1 src2)) |
| 2940 | +(rule 2 (x64_imul_imm $I32 src1 (is_rust_simm8 src2)) (x64_imull_rmi_sxb src1 src2)) |
| 2941 | +(rule 2 (x64_imul_imm $I64 src1 (is_rust_simm8 src2)) (x64_imulq_rmi_sxb src1 src2)) |
| 2942 | +(rule 1 (x64_imul_imm $I16 src1 (is_rust_imm16 src2)) (x64_imulw_rmi src1 src2)) |
| 2943 | +(rule 1 (x64_imul_imm $I32 src1 (is_rust_imm32 src2)) (x64_imull_rmi src1 src2)) |
| 2944 | +(rule 1 (x64_imul_imm $I64 src1 src2) (x64_imulq_rmi_sxl src1 src2)) |
| 2945 | + |
| 2946 | +;; Helper for creating `mul` instructions or `imul` instructions (depending |
| 2947 | +;; on `signed`) for 8-bit operands. |
| 2948 | +(decl x64_mul8_raw (bool Gpr GprMem) AssemblerOutputs) |
| 2949 | +(rule (x64_mul8_raw false src1 src2) (x64_mulb_m_raw src1 src2)) |
| 2950 | +(rule (x64_mul8_raw true src1 src2) (x64_imulb_m_raw src1 src2)) |
| 2951 | + |
| 2952 | +(decl x64_mul8 (bool Gpr GprMem) Gpr) |
| 2953 | +(rule (x64_mul8 signed src1 src2) |
| 2954 | + (emit_ret_gpr (x64_mul8_raw signed src1 src2))) |
2938 | 2955 |
|
2939 | 2956 | (decl x64_mul8_with_flags_paired (bool Gpr GprMem) ProducesFlags)
|
2940 | 2957 | (rule (x64_mul8_with_flags_paired signed src1 src2)
|
2941 |
| - (let ((dst WritableGpr (temp_writable_gpr))) |
2942 |
| - (ProducesFlags.ProducesFlagsReturnsResultWithConsumer |
2943 |
| - (MInst.Mul8 signed src1 src2 dst) |
2944 |
| - dst))) |
2945 |
| - |
2946 |
| -(decl x64_mul_lo_with_flags_paired (Type bool Gpr GprMem) ProducesFlags) |
2947 |
| -(rule (x64_mul_lo_with_flags_paired ty signed src1 src2) |
2948 |
| - (let ((dst_lo WritableGpr (temp_writable_gpr)) |
2949 |
| - (dst_hi WritableGpr (temp_writable_gpr)) |
2950 |
| - (size OperandSize (raw_operand_size_of_type ty))) |
2951 |
| - (ProducesFlags.ProducesFlagsReturnsResultWithConsumer |
2952 |
| - (MInst.Mul size signed src1 src2 dst_lo dst_hi) |
2953 |
| - dst_lo))) |
| 2958 | + (asm_produce_flags (x64_mul8_raw signed src1 src2))) |
2954 | 2959 |
|
2955 | 2960 |
|
2956 | 2961 |
|
|
0 commit comments