|
32 | 32 | (AluRmRVex (size OperandSize)
|
33 | 33 | (op AluRmROpcode)
|
34 | 34 | (src1 Gpr)
|
35 |
| - (src2 Gpr) |
| 35 | + (src2 GprMem) |
36 | 36 | (dst WritableGpr))
|
37 | 37 |
|
38 | 38 | ;; Production of a zero value into a register of the specified size.
|
|
53 | 53 | (src GprMem)
|
54 | 54 | (dst WritableGpr))
|
55 | 55 |
|
| 56 | + ;; Same as `UnaryRmRVex` but with an immediate |
| 57 | + (UnaryRmRImmVex (size OperandSize) |
| 58 | + (op UnaryRmRImmVexOpcode) |
| 59 | + (src GprMem) |
| 60 | + (dst WritableGpr) |
| 61 | + (imm u8)) |
| 62 | + |
56 | 63 | ;; Bitwise not.
|
57 | 64 | (Not (size OperandSize) ;; 1, 2, 4, or 8
|
58 | 65 | (src Gpr)
|
|
746 | 753 | Xor
|
747 | 754 | Mul))
|
748 | 755 |
|
749 |
| -(type AluRmROpcode extern |
750 |
| - (enum Andn)) |
| 756 | +(type AluRmROpcode |
| 757 | + (enum Andn |
| 758 | + Sarx |
| 759 | + Shrx |
| 760 | + Shlx |
| 761 | + Bzhi)) |
751 | 762 |
|
752 | 763 | (type UnaryRmROpcode extern
|
753 | 764 | (enum Bsr
|
|
761 | 772 | Blsmsk
|
762 | 773 | Blsr))
|
763 | 774 |
|
| 775 | +(type UnaryRmRImmVexOpcode |
| 776 | + (enum Rorx)) |
| 777 | + |
764 | 778 | (type SseOpcode extern
|
765 | 779 | (enum Addps
|
766 | 780 | Addpd
|
|
1433 | 1447 | (decl imm8_reg_to_imm8_gpr (Imm8Reg) Imm8Gpr)
|
1434 | 1448 | (extern constructor imm8_reg_to_imm8_gpr imm8_reg_to_imm8_gpr)
|
1435 | 1449 |
|
| 1450 | +;; Convert an `Imm8Gpr` into a `Gpr`. |
| 1451 | +(decl gpr_from_imm8_gpr (Gpr) Imm8Gpr) |
| 1452 | +(extern extractor gpr_from_imm8_gpr gpr_from_imm8_gpr) |
| 1453 | + |
| 1454 | +;; Convert an `Imm8Gpr` into an `Imm8`. |
| 1455 | +(decl imm8_from_imm8_gpr (u8) Imm8Gpr) |
| 1456 | +(extern extractor imm8_from_imm8_gpr imm8_from_imm8_gpr) |
| 1457 | + |
1436 | 1458 | ;; Convert a `WritableGpr` to a `WritableReg`.
|
1437 | 1459 | (decl writable_gpr_to_reg (WritableGpr) WritableReg)
|
1438 | 1460 | (extern constructor writable_gpr_to_reg writable_gpr_to_reg)
|
|
1703 | 1725 | (decl pure use_bmi1 () bool)
|
1704 | 1726 | (extern constructor use_bmi1 use_bmi1)
|
1705 | 1727 |
|
| 1728 | +(decl pure use_bmi2 () bool) |
| 1729 | +(extern constructor use_bmi2 use_bmi2) |
| 1730 | + |
1706 | 1731 | (decl pure use_popcnt () bool)
|
1707 | 1732 | (extern constructor use_popcnt use_popcnt)
|
1708 | 1733 |
|
|
1836 | 1861 | dst))
|
1837 | 1862 |
|
1838 | 1863 | ;; Helper for emitting `MInst.AluRmRVex` instructions.
|
1839 |
| -(decl alu_rm_r_vex (Type AluRmROpcode Gpr Gpr) Gpr) |
| 1864 | +(decl alu_rm_r_vex (Type AluRmROpcode Gpr GprMem) Gpr) |
1840 | 1865 | (rule (alu_rm_r_vex ty opcode src1 src2)
|
1841 | 1866 | (let ((dst WritableGpr (temp_writable_gpr))
|
1842 | 1867 | (size OperandSize (operand_size_of_type_32_64 ty))
|
|
2060 | 2085 | (_ Unit (emit (MInst.UnaryRmRVex size op src dst))))
|
2061 | 2086 | dst))
|
2062 | 2087 |
|
| 2088 | +;; Helper for creating `MInst.UnaryRmRImmVex` instructions. |
| 2089 | +(decl unary_rm_r_imm_vex (UnaryRmRImmVexOpcode GprMem OperandSize u8) Gpr) |
| 2090 | +(rule (unary_rm_r_imm_vex op src size imm) |
| 2091 | + (let ((dst WritableGpr (temp_writable_gpr)) |
| 2092 | + (_ Unit (emit (MInst.UnaryRmRImmVex size op src dst imm)))) |
| 2093 | + dst)) |
| 2094 | + |
2063 | 2095 | (decl cvt_u64_to_float_seq (Type Gpr) Xmm)
|
2064 | 2096 | (rule (cvt_u64_to_float_seq ty src)
|
2065 | 2097 | (let ((size OperandSize (raw_operand_size_of_type ty))
|
|
2584 | 2616 | src1
|
2585 | 2617 | src2))
|
2586 | 2618 |
|
2587 |
| -(decl x64_andn (Type Gpr Gpr) Gpr) |
| 2619 | +(decl x64_andn (Type Gpr GprMem) Gpr) |
2588 | 2620 | (rule (x64_andn ty src1 src2)
|
2589 | 2621 | (alu_rm_r_vex ty (AluRmROpcode.Andn) src1 src2))
|
2590 | 2622 |
|
|
2669 | 2701 | (decl x64_rotl (Type Gpr Imm8Gpr) Gpr)
|
2670 | 2702 | (rule (x64_rotl ty src1 src2)
|
2671 | 2703 | (shift_r ty (ShiftKind.RotateLeft) src1 src2))
|
| 2704 | +(rule 1 (x64_rotl (ty_32_or_64 ty) src (imm8_from_imm8_gpr imm)) |
| 2705 | + (if-let $true (use_bmi2)) |
| 2706 | + (x64_rorx ty src (u8_sub (ty_bits ty) imm))) |
2672 | 2707 |
|
2673 | 2708 | ;; Helper for creating `rotr` instructions.
|
2674 | 2709 | (decl x64_rotr (Type Gpr Imm8Gpr) Gpr)
|
2675 | 2710 | (rule (x64_rotr ty src1 src2)
|
2676 | 2711 | (shift_r ty (ShiftKind.RotateRight) src1 src2))
|
| 2712 | +(rule 1 (x64_rotr (ty_32_or_64 ty) src (imm8_from_imm8_gpr imm)) |
| 2713 | + (if-let $true (use_bmi2)) |
| 2714 | + (x64_rorx ty src imm)) |
2677 | 2715 |
|
2678 | 2716 | ;; Helper for creating `shl` instructions.
|
2679 | 2717 | (decl x64_shl (Type Gpr Imm8Gpr) Gpr)
|
2680 | 2718 | (rule (x64_shl ty src1 src2)
|
2681 | 2719 | (shift_r ty (ShiftKind.ShiftLeft) src1 src2))
|
| 2720 | +;; With BMI2 the `shlx` instruction is also available, and it's unconditionally |
| 2721 | +;; used for registers shifted by registers since it provides more freedom |
| 2722 | +;; in regalloc since nothing is constrained. Note that the `shlx` instruction |
| 2723 | +;; doesn't encode an immediate so any immediate-based shift still uses `shl`. |
| 2724 | +(rule 1 (x64_shl (ty_32_or_64 ty) src1 (gpr_from_imm8_gpr src2)) |
| 2725 | + (if-let $true (use_bmi2)) |
| 2726 | + (x64_shlx ty src1 src2)) |
2682 | 2727 |
|
2683 | 2728 | ;; Helper for creating logical shift-right instructions.
|
2684 | 2729 | (decl x64_shr (Type Gpr Imm8Gpr) Gpr)
|
2685 | 2730 | (rule (x64_shr ty src1 src2)
|
2686 | 2731 | (shift_r ty (ShiftKind.ShiftRightLogical) src1 src2))
|
| 2732 | +;; see `x64_shl` for more info about this rule |
| 2733 | +(rule 1 (x64_shr (ty_32_or_64 ty) src1 (gpr_from_imm8_gpr src2)) |
| 2734 | + (if-let $true (use_bmi2)) |
| 2735 | + (x64_shrx ty src1 src2)) |
2687 | 2736 |
|
2688 | 2737 | ;; Helper for creating arithmetic shift-right instructions.
|
2689 | 2738 | (decl x64_sar (Type Gpr Imm8Gpr) Gpr)
|
2690 | 2739 | (rule (x64_sar ty src1 src2)
|
2691 | 2740 | (shift_r ty (ShiftKind.ShiftRightArithmetic) src1 src2))
|
| 2741 | +;; see `x64_shl` for more info about this rule |
| 2742 | +(rule 1 (x64_sar (ty_32_or_64 ty) src1 (gpr_from_imm8_gpr src2)) |
| 2743 | + (if-let $true (use_bmi2)) |
| 2744 | + (x64_sarx ty src1 src2)) |
| 2745 | + |
| 2746 | +;; Helper for creating zeroing-of-high-bits instructions bzhi |
| 2747 | +;; |
| 2748 | +;; Note that the `src` operands are swapped here. The amount-to-shift-by |
| 2749 | +;; is stored in `vvvv` which is `src1` in the `AluRmRVex` instruction shape. |
| 2750 | +(decl x64_bzhi (Type GprMem Gpr) Gpr) |
| 2751 | +(rule (x64_bzhi ty src1 src2) |
| 2752 | + (alu_rm_r_vex ty (AluRmROpcode.Bzhi) src2 src1)) |
2692 | 2753 |
|
2693 | 2754 | ;; Helper for creating byteswap instructions.
|
2694 | 2755 | ;; In x64, 32- and 64-bit registers use BSWAP instruction, and
|
|
4096 | 4157 | (rule (x64_blsr ty src)
|
4097 | 4158 | (unary_rm_r_vex (UnaryRmRVexOpcode.Blsr) src (operand_size_of_type_32_64 ty)))
|
4098 | 4159 |
|
| 4160 | +;; Helper for creating `sarx` instructions. |
| 4161 | +(decl x64_sarx (Type GprMem Gpr) Gpr) |
| 4162 | +(rule (x64_sarx ty val amt) |
| 4163 | + (alu_rm_r_vex ty (AluRmROpcode.Sarx) amt val)) |
| 4164 | + |
| 4165 | +;; Helper for creating `shrx` instructions. |
| 4166 | +(decl x64_shrx (Type GprMem Gpr) Gpr) |
| 4167 | +(rule (x64_shrx ty val amt) |
| 4168 | + (alu_rm_r_vex ty (AluRmROpcode.Shrx) amt val)) |
| 4169 | + |
| 4170 | +;; Helper for creating `shlx` instructions. |
| 4171 | +(decl x64_shlx (Type GprMem Gpr) Gpr) |
| 4172 | +(rule (x64_shlx ty val amt) |
| 4173 | + (alu_rm_r_vex ty (AluRmROpcode.Shlx) amt val)) |
| 4174 | + |
| 4175 | +;; Helper for creating `rorx` instructions. |
| 4176 | +(decl x64_rorx (Type GprMem u8) Gpr) |
| 4177 | +(rule (x64_rorx ty src imm) |
| 4178 | + (unary_rm_r_imm_vex (UnaryRmRImmVexOpcode.Rorx) |
| 4179 | + src |
| 4180 | + (operand_size_of_type_32_64 ty) |
| 4181 | + imm)) |
| 4182 | + |
4099 | 4183 | ;; Helper for creating `popcnt` instructions.
|
4100 | 4184 | (decl x64_popcnt (Type Gpr) Gpr)
|
4101 | 4185 | (rule (x64_popcnt ty src)
|
|
0 commit comments