ISLE: Allow shadowing in let expressions (#4562)
* Support shadowing in isle * Re-run the isle build.rs if the examples change * Print error messages when isle tests fail * Move run tests * Refactor `let` uses that don't need to introduce unique names
This commit is contained in:
@@ -1644,8 +1644,8 @@
|
||||
(decl vec_rrrr_long (VecRRRLongOp Reg Reg Reg bool) Reg)
|
||||
(rule (vec_rrrr_long op src1 src2 src3 high_half)
|
||||
(let ((dst WritableReg (temp_writable_reg $I8X16))
|
||||
(_1 Unit (emit (MInst.FpuMove128 dst src1)))
|
||||
(_2 Unit (emit (MInst.VecRRRLong op dst src2 src3 high_half))))
|
||||
(_ Unit (emit (MInst.FpuMove128 dst src1)))
|
||||
(_ Unit (emit (MInst.VecRRRLong op dst src2 src3 high_half))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.VecRRNarrow` instructions.
|
||||
@@ -1660,8 +1660,8 @@
|
||||
(decl vec_rr_narrow_high (VecRRNarrowOp Reg Reg ScalarSize) Reg)
|
||||
(rule (vec_rr_narrow_high op mod src size)
|
||||
(let ((dst WritableReg (temp_writable_reg $I8X16))
|
||||
(_1 Unit (emit (MInst.FpuMove128 dst mod)))
|
||||
(_2 Unit (emit (MInst.VecRRNarrow op dst src $true size))))
|
||||
(_ Unit (emit (MInst.FpuMove128 dst mod)))
|
||||
(_ Unit (emit (MInst.VecRRNarrow op dst src $true size))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.VecRRLong` instructions.
|
||||
@@ -1704,16 +1704,16 @@
|
||||
(decl mov_to_vec (Reg Reg u8 VectorSize) Reg)
|
||||
(rule (mov_to_vec src1 src2 lane size)
|
||||
(let ((dst WritableReg (temp_writable_reg $I8X16))
|
||||
(_1 Unit (emit (MInst.FpuMove128 dst src1)))
|
||||
(_2 Unit (emit (MInst.MovToVec dst src2 lane size))))
|
||||
(_ Unit (emit (MInst.FpuMove128 dst src1)))
|
||||
(_ Unit (emit (MInst.MovToVec dst src2 lane size))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.VecMovElement` instructions.
|
||||
(decl mov_vec_elem (Reg Reg u8 u8 VectorSize) Reg)
|
||||
(rule (mov_vec_elem src1 src2 dst_idx src_idx size)
|
||||
(let ((dst WritableReg (temp_writable_reg $I8X16))
|
||||
(_1 Unit (emit (MInst.FpuMove128 dst src1)))
|
||||
(_2 Unit (emit (MInst.VecMovElement dst src2 dst_idx src_idx size))))
|
||||
(_ Unit (emit (MInst.FpuMove128 dst src1)))
|
||||
(_ Unit (emit (MInst.VecMovElement dst src2 dst_idx src_idx size))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.MovFromVec` instructions.
|
||||
@@ -2091,8 +2091,8 @@
|
||||
(decl bsl (Type Reg Reg Reg) Reg)
|
||||
(rule (bsl ty c x y)
|
||||
(let ((dst WritableReg (temp_writable_reg ty))
|
||||
(_1 Unit (emit (MInst.FpuMove128 dst c)))
|
||||
(_2 Unit (emit (MInst.VecRRR (VecALUOp.Bsl) dst x y (vector_size ty)))))
|
||||
(_ Unit (emit (MInst.FpuMove128 dst c)))
|
||||
(_ Unit (emit (MInst.VecRRR (VecALUOp.Bsl) dst x y (vector_size ty)))))
|
||||
dst))
|
||||
|
||||
;; Helper for generating a `udf` instruction.
|
||||
@@ -2188,16 +2188,16 @@
|
||||
(rule (trap_if_div_overflow ty x y)
|
||||
(let (
|
||||
;; Check RHS is -1.
|
||||
(_1 Unit (emit (MInst.AluRRImm12 (ALUOp.AddS) (operand_size ty) (writable_zero_reg) y (u8_into_imm12 1))))
|
||||
(_ Unit (emit (MInst.AluRRImm12 (ALUOp.AddS) (operand_size ty) (writable_zero_reg) y (u8_into_imm12 1))))
|
||||
|
||||
;; Check LHS is min_value, by subtracting 1 and branching if
|
||||
;; there is overflow.
|
||||
(_2 Unit (emit (MInst.CCmpImm (size_from_ty ty)
|
||||
x
|
||||
(u8_into_uimm5 1)
|
||||
(nzcv $false $false $false $false)
|
||||
(Cond.Eq))))
|
||||
(_3 Unit (emit (MInst.TrapIf (cond_br_cond (Cond.Vs))
|
||||
(_ Unit (emit (MInst.CCmpImm (size_from_ty ty)
|
||||
x
|
||||
(u8_into_uimm5 1)
|
||||
(nzcv $false $false $false $false)
|
||||
(Cond.Eq))))
|
||||
(_ Unit (emit (MInst.TrapIf (cond_br_cond (Cond.Vs))
|
||||
(trap_code_integer_overflow))))
|
||||
)
|
||||
x))
|
||||
@@ -2371,8 +2371,8 @@
|
||||
(rule (lse_atomic_cas addr expect replace ty)
|
||||
(let (
|
||||
(dst WritableReg (temp_writable_reg ty))
|
||||
(_1 Unit (emit (MInst.Mov (operand_size ty) dst expect)))
|
||||
(_2 Unit (emit (MInst.AtomicCAS dst replace addr ty)))
|
||||
(_ Unit (emit (MInst.Mov (operand_size ty) dst expect)))
|
||||
(_ Unit (emit (MInst.AtomicCAS dst replace addr ty)))
|
||||
)
|
||||
dst))
|
||||
|
||||
|
||||
@@ -1840,8 +1840,8 @@
|
||||
(decl umul_wide (Reg Reg) RegPair)
|
||||
(rule (umul_wide src1 src2)
|
||||
(let ((dst WritableRegPair (temp_writable_regpair))
|
||||
(_1 Unit (emit (MInst.Mov64 (writable_regpair_lo dst) src2)))
|
||||
(_2 Unit (emit (MInst.UMulWide src1))))
|
||||
(_ Unit (emit (MInst.Mov64 (writable_regpair_lo dst) src2)))
|
||||
(_ Unit (emit (MInst.UMulWide src1))))
|
||||
dst))
|
||||
|
||||
;; Helper for emitting `MInst.SDivMod32` instructions.
|
||||
@@ -2425,8 +2425,8 @@
|
||||
;; Push instructions to break out of the loop if condition is met.
|
||||
(decl push_break_if (VecMInstBuilder ProducesFlags Cond) Reg)
|
||||
(rule (push_break_if ib (ProducesFlags.ProducesFlagsSideEffect inst) cond)
|
||||
(let ((_1 Unit (inst_builder_push ib inst))
|
||||
(_2 Unit (inst_builder_push ib (MInst.CondBreak cond))))
|
||||
(let ((_ Unit (inst_builder_push ib inst))
|
||||
(_ Unit (inst_builder_push ib (MInst.CondBreak cond))))
|
||||
(invalid_reg)))
|
||||
|
||||
;; Emit a `MInst.Loop` instruction holding a loop body instruction sequence.
|
||||
@@ -2985,12 +2985,12 @@
|
||||
|
||||
(decl trap_if (ProducesFlags Cond TrapCode) Reg)
|
||||
(rule (trap_if (ProducesFlags.ProducesFlagsReturnsReg inst result) cond trap_code)
|
||||
(let ((_1 Unit (emit inst))
|
||||
(_2 Unit (emit (MInst.TrapIf cond trap_code))))
|
||||
(let ((_ Unit (emit inst))
|
||||
(_ Unit (emit (MInst.TrapIf cond trap_code))))
|
||||
result))
|
||||
(rule (trap_if (ProducesFlags.ProducesFlagsSideEffect inst) cond trap_code)
|
||||
(let ((_1 Unit (emit inst))
|
||||
(_2 Unit (emit (MInst.TrapIf cond trap_code))))
|
||||
(let ((_ Unit (emit inst))
|
||||
(_ Unit (emit (MInst.TrapIf cond trap_code))))
|
||||
(invalid_reg)))
|
||||
|
||||
(decl icmps_reg_and_trap (Type Reg Reg Cond TrapCode) Reg)
|
||||
@@ -3058,18 +3058,18 @@
|
||||
(decl select_bool_reg (Type ProducesBool Reg Reg) Reg)
|
||||
(rule (select_bool_reg ty (ProducesBool.ProducesBool producer cond) reg_true reg_false)
|
||||
(let ((dst WritableReg (temp_writable_reg ty))
|
||||
(_1 Unit (emit_producer producer))
|
||||
(_2 Unit (emit_mov ty dst reg_false))
|
||||
(_3 Unit (emit_consumer (emit_cmov_reg ty dst cond reg_true))))
|
||||
(_ Unit (emit_producer producer))
|
||||
(_ Unit (emit_mov ty dst reg_false))
|
||||
(_ Unit (emit_consumer (emit_cmov_reg ty dst cond reg_true))))
|
||||
dst))
|
||||
|
||||
;; Use a boolean condition to select between two immediate values.
|
||||
(decl select_bool_imm (Type ProducesBool i16 u64) Reg)
|
||||
(rule (select_bool_imm ty (ProducesBool.ProducesBool producer cond) imm_true imm_false)
|
||||
(let ((dst WritableReg (temp_writable_reg ty))
|
||||
(_1 Unit (emit_producer producer))
|
||||
(_2 Unit (emit_imm ty dst imm_false))
|
||||
(_3 Unit (emit_consumer (emit_cmov_imm ty dst cond imm_true))))
|
||||
(_ Unit (emit_producer producer))
|
||||
(_ Unit (emit_imm ty dst imm_false))
|
||||
(_ Unit (emit_consumer (emit_cmov_imm ty dst cond imm_true))))
|
||||
dst))
|
||||
|
||||
;; Lower a boolean condition to a boolean type. The value used to represent
|
||||
@@ -3129,8 +3129,8 @@
|
||||
(result Reg (push_atomic_cas ib (ty_ext32 ty)
|
||||
(casloop_val_reg) val aligned_mem))
|
||||
;; Emit initial load followed by compare-and-swap loop.
|
||||
(_1 Unit (emit_load (ty_ext32 ty) (casloop_val_reg) aligned_mem))
|
||||
(_2 Unit (emit_loop ib (intcc_as_cond (IntCC.NotEqual)))))
|
||||
(_ Unit (emit_load (ty_ext32 ty) (casloop_val_reg) aligned_mem))
|
||||
(_ Unit (emit_loop ib (intcc_as_cond (IntCC.NotEqual)))))
|
||||
result))
|
||||
|
||||
;; Compute the previous memory value after a (fullword) compare-and-swap loop.
|
||||
@@ -3345,8 +3345,8 @@
|
||||
;; conditional move, and because flogr returns a register pair.
|
||||
(rule (clz_reg zeroval x)
|
||||
(let ((dst WritableRegPair (temp_writable_regpair))
|
||||
(_1 Unit (emit (MInst.Flogr x)))
|
||||
(_2 Unit (emit (MInst.CMov64SImm16 (writable_regpair_hi dst)
|
||||
(_ Unit (emit (MInst.Flogr x)))
|
||||
(_ Unit (emit (MInst.CMov64SImm16 (writable_regpair_hi dst)
|
||||
(intcc_as_cond (IntCC.Equal)) zeroval))))
|
||||
dst))
|
||||
|
||||
|
||||
@@ -573,9 +573,9 @@
|
||||
(ext_y Reg (put_in_reg_sext32 y))
|
||||
(ext_ty Type (ty_ext32 ty))
|
||||
;; Perform division-by-zero check (same as for `udiv`).
|
||||
(_1 Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y))
|
||||
(_ Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y))
|
||||
;; Perform integer-overflow check if necessary.
|
||||
(_2 Reg (maybe_trap_if_sdiv_overflow OFcheck ext_ty ty ext_x ext_y))
|
||||
(_ Reg (maybe_trap_if_sdiv_overflow OFcheck ext_ty ty ext_x ext_y))
|
||||
;; Emit the actual divide instruction.
|
||||
(pair RegPair (sdivmod ext_ty ext_x ext_y)))
|
||||
;; The quotient can be found in the low half of the result.
|
||||
@@ -1504,16 +1504,16 @@
|
||||
(fcvt_to_uint x @ (value_type src_ty))))
|
||||
(let ((src Reg (put_in_reg x))
|
||||
;; First, check whether the input is a NaN, and trap if so.
|
||||
(_1 Reg (trap_if (fcmp_reg src_ty src src)
|
||||
(floatcc_as_cond (FloatCC.Unordered))
|
||||
(trap_code_bad_conversion_to_integer)))
|
||||
(_ Reg (trap_if (fcmp_reg src_ty src src)
|
||||
(floatcc_as_cond (FloatCC.Unordered))
|
||||
(trap_code_bad_conversion_to_integer)))
|
||||
;; Now check whether the input is out of range for the target type.
|
||||
(_2 Reg (trap_if (fcmp_reg src_ty src (fcvt_to_uint_ub src_ty dst_ty))
|
||||
(floatcc_as_cond (FloatCC.GreaterThanOrEqual))
|
||||
(trap_code_integer_overflow)))
|
||||
(_3 Reg (trap_if (fcmp_reg src_ty src (fcvt_to_uint_lb src_ty))
|
||||
(floatcc_as_cond (FloatCC.LessThanOrEqual))
|
||||
(trap_code_integer_overflow)))
|
||||
(_ Reg (trap_if (fcmp_reg src_ty src (fcvt_to_uint_ub src_ty dst_ty))
|
||||
(floatcc_as_cond (FloatCC.GreaterThanOrEqual))
|
||||
(trap_code_integer_overflow)))
|
||||
(_ Reg (trap_if (fcmp_reg src_ty src (fcvt_to_uint_lb src_ty))
|
||||
(floatcc_as_cond (FloatCC.LessThanOrEqual))
|
||||
(trap_code_integer_overflow)))
|
||||
;; Perform the conversion using the larger type size.
|
||||
(flt_ty Type (fcvt_flt_ty dst_ty src_ty))
|
||||
(src_ext Reg (fpromote_reg flt_ty src_ty src)))
|
||||
@@ -1528,16 +1528,16 @@
|
||||
(fcvt_to_sint x @ (value_type src_ty))))
|
||||
(let ((src Reg (put_in_reg x))
|
||||
;; First, check whether the input is a NaN, and trap if so.
|
||||
(_1 Reg (trap_if (fcmp_reg src_ty src src)
|
||||
(floatcc_as_cond (FloatCC.Unordered))
|
||||
(trap_code_bad_conversion_to_integer)))
|
||||
(_ Reg (trap_if (fcmp_reg src_ty src src)
|
||||
(floatcc_as_cond (FloatCC.Unordered))
|
||||
(trap_code_bad_conversion_to_integer)))
|
||||
;; Now check whether the input is out of range for the target type.
|
||||
(_2 Reg (trap_if (fcmp_reg src_ty src (fcvt_to_sint_ub src_ty dst_ty))
|
||||
(floatcc_as_cond (FloatCC.GreaterThanOrEqual))
|
||||
(trap_code_integer_overflow)))
|
||||
(_3 Reg (trap_if (fcmp_reg src_ty src (fcvt_to_sint_lb src_ty dst_ty))
|
||||
(floatcc_as_cond (FloatCC.LessThanOrEqual))
|
||||
(trap_code_integer_overflow)))
|
||||
(_ Reg (trap_if (fcmp_reg src_ty src (fcvt_to_sint_ub src_ty dst_ty))
|
||||
(floatcc_as_cond (FloatCC.GreaterThanOrEqual))
|
||||
(trap_code_integer_overflow)))
|
||||
(_ Reg (trap_if (fcmp_reg src_ty src (fcvt_to_sint_lb src_ty dst_ty))
|
||||
(floatcc_as_cond (FloatCC.LessThanOrEqual))
|
||||
(trap_code_integer_overflow)))
|
||||
;; Perform the conversion using the larger type size.
|
||||
(flt_ty Type (fcvt_flt_ty dst_ty src_ty))
|
||||
(src_ext Reg (fpromote_reg flt_ty src_ty src)))
|
||||
@@ -3571,27 +3571,27 @@
|
||||
;; Direct call to an in-range function.
|
||||
(rule (lower (call (func_ref_data sig_ref name (reloc_distance_near)) args))
|
||||
(let ((abi ABISig (abi_sig sig_ref))
|
||||
(_1 Unit (abi_accumulate_outgoing_args_size abi))
|
||||
(_2 InstOutput (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(_3 InstOutput (side_effect (abi_call abi name (Opcode.Call)))))
|
||||
(_ Unit (abi_accumulate_outgoing_args_size abi))
|
||||
(_ InstOutput (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(_ InstOutput (side_effect (abi_call abi name (Opcode.Call)))))
|
||||
(lower_call_rets abi (range 0 (abi_num_rets abi)) (output_builder_new))))
|
||||
|
||||
;; Direct call to an out-of-range function (implicitly via pointer).
|
||||
(rule (lower (call (func_ref_data sig_ref name _) args))
|
||||
(let ((abi ABISig (abi_sig sig_ref))
|
||||
(_1 Unit (abi_accumulate_outgoing_args_size abi))
|
||||
(_2 InstOutput (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(_ Unit (abi_accumulate_outgoing_args_size abi))
|
||||
(_ InstOutput (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(target Reg (load_ext_name_far name 0))
|
||||
(_3 InstOutput (side_effect (abi_call_ind abi target (Opcode.Call)))))
|
||||
(_ InstOutput (side_effect (abi_call_ind abi target (Opcode.Call)))))
|
||||
(lower_call_rets abi (range 0 (abi_num_rets abi)) (output_builder_new))))
|
||||
|
||||
;; Indirect call.
|
||||
(rule (lower (call_indirect sig_ref ptr args))
|
||||
(let ((abi ABISig (abi_sig sig_ref))
|
||||
(target Reg (put_in_reg ptr))
|
||||
(_1 Unit (abi_accumulate_outgoing_args_size abi))
|
||||
(_2 InstOutput (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(_3 InstOutput (side_effect (abi_call_ind abi target (Opcode.CallIndirect)))))
|
||||
(_ Unit (abi_accumulate_outgoing_args_size abi))
|
||||
(_ InstOutput (lower_call_args abi (range 0 (abi_num_args abi)) args))
|
||||
(_ InstOutput (side_effect (abi_call_ind abi target (Opcode.CallIndirect)))))
|
||||
(lower_call_rets abi (range 0 (abi_num_rets abi)) (output_builder_new))))
|
||||
|
||||
;; Lower function arguments by loading them into registers / stack slots.
|
||||
|
||||
@@ -1492,19 +1492,19 @@
|
||||
(rule (make_i64x2_from_lanes lo hi)
|
||||
(let ((dst_xmm WritableXmm (temp_writable_xmm))
|
||||
(dst_reg WritableReg dst_xmm)
|
||||
(_0 Unit (emit (MInst.XmmUninitializedValue dst_xmm)))
|
||||
(_1 Unit (emit (MInst.XmmRmRImm (SseOpcode.Pinsrd)
|
||||
dst_reg
|
||||
lo
|
||||
dst_reg
|
||||
0
|
||||
(OperandSize.Size64))))
|
||||
(_2 Unit (emit (MInst.XmmRmRImm (SseOpcode.Pinsrd)
|
||||
dst_reg
|
||||
hi
|
||||
dst_reg
|
||||
1
|
||||
(OperandSize.Size64)))))
|
||||
(_ Unit (emit (MInst.XmmUninitializedValue dst_xmm)))
|
||||
(_ Unit (emit (MInst.XmmRmRImm (SseOpcode.Pinsrd)
|
||||
dst_reg
|
||||
lo
|
||||
dst_reg
|
||||
0
|
||||
(OperandSize.Size64))))
|
||||
(_ Unit (emit (MInst.XmmRmRImm (SseOpcode.Pinsrd)
|
||||
dst_reg
|
||||
hi
|
||||
dst_reg
|
||||
1
|
||||
(OperandSize.Size64)))))
|
||||
dst_xmm))
|
||||
|
||||
;; Move a `RegMemImm.Reg` operand to an XMM register, if necessary.
|
||||
|
||||
@@ -551,8 +551,8 @@
|
||||
(let ((_ Unit (emit inst)))
|
||||
(output_none)))
|
||||
(rule (side_effect (SideEffectNoResult.Inst2 inst1 inst2))
|
||||
(let ((_1 Unit (emit inst1))
|
||||
(_2 Unit (emit inst2)))
|
||||
(let ((_ Unit (emit inst1))
|
||||
(_ Unit (emit inst2)))
|
||||
(output_none)))
|
||||
|
||||
(decl side_effect_concat (SideEffectNoResult SideEffectNoResult) SideEffectNoResult)
|
||||
|
||||
Reference in New Issue
Block a user