fitzgen labeled issue #3526:
Originally https://github.com/cfallin/isle/issues/9
This example redefines
carry
andhi_shifted
:
lisp (decl shl_i128 (ValueRegs Reg) ValueRegs) (rule (shl_i128 src amt) ;; Unpack the registers that make up the 128-bit value being shifted. (let ((src_lo Reg (value_regs_get src 0)) (src_hi Reg (value_regs_get src 1)) ;; Do two 64-bit shifts. (lo_shifted Reg (shl $I64 src_lo (Imm8Reg.Reg amt))) (hi_shifted Reg (shl $I64 src_hi (Imm8Reg.Reg amt))) ;; `src_lo >> (64 - shift)` are the bits to carry over from the lo ;; into the hi. (carry Reg (shr $I64 src_lo (Imm8Reg.Reg (sub $I64 (imm $I64 64) (RegMemImm.Reg amt))))) (zero Reg (imm $I64 0)) ;; Nullify the carry if we are shifting in by a multiple of 128. (carry Reg (with_flags_1 (test (OperandSize.Size64) (RegMemImm.Imm 127) amt) (cmove $I64 (CC.Z) (RegMem.Reg zero) carry))) ;; Add the carry into the high half. (hi_shifted Reg (or $I64 carry (RegMemImm.Reg hi_shifted)))) ;; Combine the two shifted halves. However, if we are shifting by 64, ;; then the low bits are zero and the high bits are our low bits. (with_flags_2 (test (OperandSize.Size64) (RegMemImm.Imm 64) amt) (cmove $I64 (CC.Z) (RegMem.Reg lo_shifted) zero) (cmove $I64 (CC.Z) (RegMem.Reg hi_shifted) lo_shifted))))
Without the ability to redefine, we have to use names like
carry2
andhi_shifted2
or something, like Erlang.
fitzgen opened issue #3526:
Originally https://github.com/cfallin/isle/issues/9
This example redefines
carry
andhi_shifted
:
lisp (decl shl_i128 (ValueRegs Reg) ValueRegs) (rule (shl_i128 src amt) ;; Unpack the registers that make up the 128-bit value being shifted. (let ((src_lo Reg (value_regs_get src 0)) (src_hi Reg (value_regs_get src 1)) ;; Do two 64-bit shifts. (lo_shifted Reg (shl $I64 src_lo (Imm8Reg.Reg amt))) (hi_shifted Reg (shl $I64 src_hi (Imm8Reg.Reg amt))) ;; `src_lo >> (64 - shift)` are the bits to carry over from the lo ;; into the hi. (carry Reg (shr $I64 src_lo (Imm8Reg.Reg (sub $I64 (imm $I64 64) (RegMemImm.Reg amt))))) (zero Reg (imm $I64 0)) ;; Nullify the carry if we are shifting in by a multiple of 128. (carry Reg (with_flags_1 (test (OperandSize.Size64) (RegMemImm.Imm 127) amt) (cmove $I64 (CC.Z) (RegMem.Reg zero) carry))) ;; Add the carry into the high half. (hi_shifted Reg (or $I64 carry (RegMemImm.Reg hi_shifted)))) ;; Combine the two shifted halves. However, if we are shifting by 64, ;; then the low bits are zero and the high bits are our low bits. (with_flags_2 (test (OperandSize.Size64) (RegMemImm.Imm 64) amt) (cmove $I64 (CC.Z) (RegMem.Reg lo_shifted) zero) (cmove $I64 (CC.Z) (RegMem.Reg hi_shifted) lo_shifted))))
Without the ability to redefine, we have to use names like
carry2
andhi_shifted2
or something, like Erlang.
cfallin labeled issue #3526:
Originally https://github.com/cfallin/isle/issues/9
This example redefines
carry
andhi_shifted
:
lisp (decl shl_i128 (ValueRegs Reg) ValueRegs) (rule (shl_i128 src amt) ;; Unpack the registers that make up the 128-bit value being shifted. (let ((src_lo Reg (value_regs_get src 0)) (src_hi Reg (value_regs_get src 1)) ;; Do two 64-bit shifts. (lo_shifted Reg (shl $I64 src_lo (Imm8Reg.Reg amt))) (hi_shifted Reg (shl $I64 src_hi (Imm8Reg.Reg amt))) ;; `src_lo >> (64 - shift)` are the bits to carry over from the lo ;; into the hi. (carry Reg (shr $I64 src_lo (Imm8Reg.Reg (sub $I64 (imm $I64 64) (RegMemImm.Reg amt))))) (zero Reg (imm $I64 0)) ;; Nullify the carry if we are shifting in by a multiple of 128. (carry Reg (with_flags_1 (test (OperandSize.Size64) (RegMemImm.Imm 127) amt) (cmove $I64 (CC.Z) (RegMem.Reg zero) carry))) ;; Add the carry into the high half. (hi_shifted Reg (or $I64 carry (RegMemImm.Reg hi_shifted)))) ;; Combine the two shifted halves. However, if we are shifting by 64, ;; then the low bits are zero and the high bits are our low bits. (with_flags_2 (test (OperandSize.Size64) (RegMemImm.Imm 64) amt) (cmove $I64 (CC.Z) (RegMem.Reg lo_shifted) zero) (cmove $I64 (CC.Z) (RegMem.Reg hi_shifted) lo_shifted))))
Without the ability to redefine, we have to use names like
carry2
andhi_shifted2
or something, like Erlang.
elliottt commented on issue #3526:
Fixed in #4562
elliottt closed issue #3526:
Originally https://github.com/cfallin/isle/issues/9
This example redefines
carry
andhi_shifted
:
lisp (decl shl_i128 (ValueRegs Reg) ValueRegs) (rule (shl_i128 src amt) ;; Unpack the registers that make up the 128-bit value being shifted. (let ((src_lo Reg (value_regs_get src 0)) (src_hi Reg (value_regs_get src 1)) ;; Do two 64-bit shifts. (lo_shifted Reg (shl $I64 src_lo (Imm8Reg.Reg amt))) (hi_shifted Reg (shl $I64 src_hi (Imm8Reg.Reg amt))) ;; `src_lo >> (64 - shift)` are the bits to carry over from the lo ;; into the hi. (carry Reg (shr $I64 src_lo (Imm8Reg.Reg (sub $I64 (imm $I64 64) (RegMemImm.Reg amt))))) (zero Reg (imm $I64 0)) ;; Nullify the carry if we are shifting in by a multiple of 128. (carry Reg (with_flags_1 (test (OperandSize.Size64) (RegMemImm.Imm 127) amt) (cmove $I64 (CC.Z) (RegMem.Reg zero) carry))) ;; Add the carry into the high half. (hi_shifted Reg (or $I64 carry (RegMemImm.Reg hi_shifted)))) ;; Combine the two shifted halves. However, if we are shifting by 64, ;; then the low bits are zero and the high bits are our low bits. (with_flags_2 (test (OperandSize.Size64) (RegMemImm.Imm 64) amt) (cmove $I64 (CC.Z) (RegMem.Reg lo_shifted) zero) (cmove $I64 (CC.Z) (RegMem.Reg hi_shifted) lo_shifted))))
Without the ability to redefine, we have to use names like
carry2
andhi_shifted2
or something, like Erlang.
Last updated: Dec 23 2024 at 12:05 UTC