|
1829 | 1829 | (extern extractor is_imm8_xmm is_imm8_xmm)
|
1830 | 1830 | (decl is_simm8 (i8) GprMemImm)
|
1831 | 1831 | (extern extractor is_simm8 is_simm8)
|
| 1832 | +(decl is_rust_simm8 (i8) i32) |
| 1833 | +(extern extractor is_rust_simm8 is_rust_simm8) |
1832 | 1834 | (decl is_imm16 (u16) GprMemImm)
|
1833 | 1835 | (extern extractor is_imm16 is_imm16)
|
| 1836 | +(decl is_rust_imm16 (u16) i32) |
| 1837 | +(extern extractor is_rust_imm16 is_rust_imm16) |
1834 | 1838 | (decl is_simm16 (i16) GprMemImm)
|
1835 | 1839 | (extern extractor is_simm16 is_simm16)
|
1836 | 1840 | (decl is_imm32 (u32) GprMemImm)
|
1837 | 1841 | (extern extractor is_imm32 is_imm32)
|
| 1842 | +(decl is_rust_imm32 (u32) i32) |
| 1843 | +(extern extractor is_rust_imm32 is_rust_imm32) |
1838 | 1844 | (decl is_simm32 (i32) GprMemImm)
|
1839 | 1845 | (extern extractor is_simm32 is_simm32)
|
1840 | 1846 | (decl is_gpr (Gpr) GprMemImm)
|
|
2718 | 2724 | (decl asm_produce_flags (AssemblerOutputs) ProducesFlags)
|
2719 | 2725 | (rule (asm_produce_flags (AssemblerOutputs.RetGpr inst gpr))
|
2720 | 2726 | (ProducesFlags.ProducesFlagsReturnsResultWithConsumer inst gpr))
|
| 2727 | +(rule (asm_produce_flags (AssemblerOutputs.RetValueRegs inst regs)) |
| 2728 | + (ProducesFlags.ProducesFlagsReturnsResultWithConsumer inst (value_regs_get_gpr regs 0))) |
2721 | 2729 |
|
2722 | 2730 | ;; Other operations consume _and_ produce flags--"chaining".
|
2723 | 2731 | (type ChainFlagsOp (enum (Adc) (Sbb)))
|
|
2908 | 2916 |
|
2909 | 2917 |
|
2910 | 2918 | ;; Helper for creating `mul` instructions or `imul` instructions (depending
|
2911 |
| -;; on `signed`) |
2912 |
| -(decl x64_mul (Type bool Gpr GprMem) ValueRegs) |
2913 |
| -(rule (x64_mul ty signed src1 src2) |
2914 |
| - (let ((dst_lo WritableGpr (temp_writable_gpr)) |
2915 |
| - (dst_hi WritableGpr (temp_writable_gpr)) |
2916 |
| - (size OperandSize (raw_operand_size_of_type ty)) |
2917 |
| - (_ Unit (emit (MInst.Mul size signed src1 src2 dst_lo dst_hi)))) |
2918 |
| - (value_gprs dst_lo dst_hi))) |
| 2919 | +;; on `signed`). For the 8-bit rules, see `x64_mul8`. |
| 2920 | +(decl x64_mul_raw (Type bool Gpr GprMem) AssemblerOutputs) |
| 2921 | +(rule (x64_mul_raw $I16 false src1 src2) (x64_mulw_m_raw src1 src2)) |
| 2922 | +(rule (x64_mul_raw $I32 false src1 src2) (x64_mull_m_raw src1 src2)) |
| 2923 | +(rule (x64_mul_raw $I64 false src1 src2) (x64_mulq_m_raw src1 src2)) |
| 2924 | +(rule (x64_mul_raw $I16 true src1 src2) (x64_imulw_m_raw src1 src2)) |
| 2925 | +(rule (x64_mul_raw $I32 true src1 src2) (x64_imull_m_raw src1 src2)) |
| 2926 | +(rule (x64_mul_raw $I64 true src1 src2) (x64_imulq_m_raw src1 src2)) |
2919 | 2927 |
|
| 2928 | +(decl x64_mul (Type bool Gpr GprMem) ValueRegs) |
| 2929 | +(rule 0 (x64_mul ty signed src1 src2) |
| 2930 | + (emit_ret_value_regs (x64_mul_raw ty signed src1 src2))) |
2920 | 2931 | ;; Special case the `mulx` pattern with the BMI2 instruction set.
|
2921 | 2932 | (rule 1 (x64_mul (ty_32_or_64 ty) false src1 src2)
|
2922 | 2933 | (if-let true (use_bmi2))
|
|
2933 | 2944 | (_ Unit (emit (MInst.MulX size src1 src2 (writable_invalid_gpr) dst))))
|
2934 | 2945 | dst))
|
2935 | 2946 |
|
| 2947 | +(decl x64_mul_lo_with_flags_paired (Type bool Gpr GprMem) ProducesFlags) |
| 2948 | +(rule (x64_mul_lo_with_flags_paired ty signed src1 src2) |
| 2949 | + (asm_produce_flags (x64_mul_raw ty signed src1 src2))) |
| 2950 | + |
2936 | 2951 | ;; Get the invalid register as writable
|
2937 | 2952 | (decl writable_invalid_gpr () WritableGpr)
|
2938 | 2953 | (extern constructor writable_invalid_gpr writable_invalid_gpr)
|
2939 | 2954 |
|
2940 |
| -;; Helper for creating `mul` instructions or `imul` instructions (depending |
2941 |
| -;; on `signed`) for 8-bit operands. |
2942 |
| -(decl x64_mul8 (bool Gpr GprMem) Gpr) |
2943 |
| -(rule (x64_mul8 signed src1 src2) |
2944 |
| - (let ((dst WritableGpr (temp_writable_gpr)) |
2945 |
| - (_ Unit (emit (MInst.Mul8 signed src1 src2 dst)))) |
2946 |
| - dst)) |
2947 |
| - |
2948 | 2955 | ;; Helper for creating `imul` instructions.
|
2949 | 2956 | (decl x64_imul (Type Gpr GprMem) Gpr)
|
2950 |
| -(rule (x64_imul ty src1 src2) |
2951 |
| - (let ((dst WritableGpr (temp_writable_gpr)) |
2952 |
| - (size OperandSize (raw_operand_size_of_type ty)) |
2953 |
| - (_ Unit (emit (MInst.IMul size src1 src2 dst)))) |
2954 |
| - dst)) |
| 2957 | +(rule (x64_imul $I16 src1 src2) (x64_imulw_rm src1 src2)) |
| 2958 | +(rule (x64_imul $I32 src1 src2) (x64_imull_rm src1 src2)) |
| 2959 | +(rule (x64_imul $I64 src1 src2) (x64_imulq_rm src1 src2)) |
2955 | 2960 |
|
2956 |
| -;; Helper for creating `imul` instructions with an immediate operand. |
| 2961 | +;; Helper for creating `imul` instructions with an immediate operand. Match |
| 2962 | +;; 8-bit immediates first to allow a smaller instruction encoding. |
2957 | 2963 | (decl x64_imul_imm (Type GprMem i32) Gpr)
|
2958 |
| -(rule (x64_imul_imm ty src1 src2) |
2959 |
| - (let ((dst WritableGpr (temp_writable_gpr)) |
2960 |
| - (size OperandSize (raw_operand_size_of_type ty)) |
2961 |
| - (_ Unit (emit (MInst.IMulImm size src1 src2 dst)))) |
2962 |
| - dst)) |
| 2964 | +(rule 2 (x64_imul_imm $I16 src1 (is_rust_simm8 src2)) (x64_imulw_rmi_sxb src1 src2)) |
| 2965 | +(rule 2 (x64_imul_imm $I32 src1 (is_rust_simm8 src2)) (x64_imull_rmi_sxb src1 src2)) |
| 2966 | +(rule 2 (x64_imul_imm $I64 src1 (is_rust_simm8 src2)) (x64_imulq_rmi_sxb src1 src2)) |
| 2967 | +(rule 1 (x64_imul_imm $I16 src1 (is_rust_imm16 src2)) (x64_imulw_rmi src1 src2)) |
| 2968 | +(rule 1 (x64_imul_imm $I32 src1 (is_rust_imm32 src2)) (x64_imull_rmi src1 src2)) |
| 2969 | +(rule 1 (x64_imul_imm $I64 src1 src2) (x64_imulq_rmi_sxl src1 src2)) |
| 2970 | + |
| 2971 | +;; Helper for creating `mul` instructions or `imul` instructions (depending |
| 2972 | +;; on `signed`) for 8-bit operands. |
| 2973 | +(decl x64_mul8_raw (bool Gpr GprMem) AssemblerOutputs) |
| 2974 | +(rule (x64_mul8_raw false src1 src2) (x64_mulb_m_raw src1 src2)) |
| 2975 | +(rule (x64_mul8_raw true src1 src2) (x64_imulb_m_raw src1 src2)) |
| 2976 | + |
| 2977 | +(decl x64_mul8 (bool Gpr GprMem) Gpr) |
| 2978 | +(rule (x64_mul8 signed src1 src2) |
| 2979 | + (emit_ret_gpr (x64_mul8_raw signed src1 src2))) |
2963 | 2980 |
|
2964 | 2981 | (decl x64_mul8_with_flags_paired (bool Gpr GprMem) ProducesFlags)
|
2965 | 2982 | (rule (x64_mul8_with_flags_paired signed src1 src2)
|
2966 |
| - (let ((dst WritableGpr (temp_writable_gpr))) |
2967 |
| - (ProducesFlags.ProducesFlagsReturnsResultWithConsumer |
2968 |
| - (MInst.Mul8 signed src1 src2 dst) |
2969 |
| - dst))) |
2970 |
| - |
2971 |
| -(decl x64_mul_lo_with_flags_paired (Type bool Gpr GprMem) ProducesFlags) |
2972 |
| -(rule (x64_mul_lo_with_flags_paired ty signed src1 src2) |
2973 |
| - (let ((dst_lo WritableGpr (temp_writable_gpr)) |
2974 |
| - (dst_hi WritableGpr (temp_writable_gpr)) |
2975 |
| - (size OperandSize (raw_operand_size_of_type ty))) |
2976 |
| - (ProducesFlags.ProducesFlagsReturnsResultWithConsumer |
2977 |
| - (MInst.Mul size signed src1 src2 dst_lo dst_hi) |
2978 |
| - dst_lo))) |
| 2983 | + (asm_produce_flags (x64_mul8_raw signed src1 src2))) |
2979 | 2984 |
|
2980 | 2985 |
|
2981 | 2986 |
|
|
0 commit comments