Add {u,s}{add,sub,mul}_overflow instructions (#5784)

* add `{u,s}{add,sub,mul}_overflow` with interpreter

* add `{u,s}{add,sub,mul}_overflow` for x64

* add `{u,s}{add,sub,mul}_overflow` for aarch64

* 128bit filetests for `{u,s}{add,sub,mul}_overflow`

* `{u,s}{add,sub,mul}_overflow` emit tests for x64

* `{u,s}{add,sub,mul}_overflow` emit tests for aarch64

* Initial review changes

* add `with_flags_extended` helper

* add `with_flags_chained` helper
This commit is contained in:
T0b1-iOS
2023-04-11 22:16:04 +02:00
committed by GitHub
parent 4c32dd7786
commit 569089e473
27 changed files with 2195 additions and 99 deletions

View File

@@ -14,14 +14,14 @@
;; Integer instructions.
;; Integer arithmetic/bit-twiddling.
(AluRmiR (size OperandSize) ;; 4 or 8
(AluRmiR (size OperandSize) ;; 1, 2, 4 or 8
(op AluRmiROpcode)
(src1 Gpr)
(src2 GprMemImm)
(dst WritableGpr))
;; Integer arithmetic read-modify-write on memory.
(AluRM (size OperandSize) ;; 4 or 8
(AluRM (size OperandSize) ;; 1, 2, 4 or 8
(op AluRmiROpcode)
(src1_dst SyntheticAmode)
(src2 Gpr))
@@ -86,6 +86,12 @@
(dst_lo WritableGpr)
(dst_hi WritableGpr))
;; x64 'mul' instruction but it only outputs the low half
(UMulLo (size OperandSize)
(src1 Gpr)
(src2 GprMem)
(dst WritableGpr))
;; A synthetic instruction sequence used as part of the lowering of the
;; `srem` instruction which returns 0 if the divisor is -1 and
;; otherwise executes an `idiv` instruction.
@@ -2118,6 +2124,29 @@
dst)
dst)))
(decl x64_alurmi_with_flags_paired (AluRmiROpcode Type Gpr GprMemImm) ProducesFlags)
(rule (x64_alurmi_with_flags_paired opc (fits_in_64 ty) src1 src2)
(let ((dst WritableGpr (temp_writable_gpr)))
(ProducesFlags.ProducesFlagsReturnsResultWithConsumer
(MInst.AluRmiR (raw_operand_size_of_type ty)
opc
src1
src2
dst)
dst)))
;; Should only be used for Adc and Sbb
(decl x64_alurmi_with_flags_chained (AluRmiROpcode Type Gpr GprMemImm) ConsumesAndProducesFlags)
(rule (x64_alurmi_with_flags_chained opc (fits_in_64 ty) src1 src2)
(let ((dst WritableGpr (temp_writable_gpr)))
(ConsumesAndProducesFlags.ReturnsReg
(MInst.AluRmiR (raw_operand_size_of_type ty)
opc
src1
src2
dst)
dst)))
;; Helper for creating `adc` instructions.
(decl x64_adc_paired (Type Gpr GprMemImm) ConsumesFlags)
(rule (x64_adc_paired ty src1 src2)
@@ -2170,6 +2199,24 @@
src1
src2))
;; Helper for creating `umullo` instructions.
(decl x64_umullo (Type Gpr GprMem) Gpr)
(rule (x64_umullo ty src1 src2)
(let ((dst WritableGpr (temp_writable_gpr))
(size OperandSize (raw_operand_size_of_type ty))
(_ Unit (emit (MInst.UMulLo size src1 src2 dst))))
dst))
(decl x64_umullo_with_flags_paired (Type Gpr GprMem) ProducesFlags)
(rule (x64_umullo_with_flags_paired ty src1 src2)
(let ((dst WritableGpr (temp_writable_gpr)))
(ProducesFlags.ProducesFlagsReturnsResultWithConsumer
(MInst.UMulLo (raw_operand_size_of_type ty)
src1
src2
dst)
dst)))
;; Helper for emitting `and` instructions.
(decl x64_and (Type Gpr GprMemImm) Gpr)
(rule (x64_and ty src1 src2)