Fix OperandSize: need clamp-to-32-bit behavior in most cases, but true-width for shifts.

This commit is contained in:
Chris Fallin
2021-12-16 12:32:28 -08:00
parent 1323ae417e
commit fd171ca063
5 changed files with 178 additions and 162 deletions

View File

@@ -77,9 +77,13 @@
Size32
Size64))
;; Get the `OperandSize` for a given `Type`.
(decl operand_size_of_type (Type) OperandSize)
(extern constructor operand_size_of_type operand_size_of_type)
;; Get the `OperandSize` for a given `Type`, rounding smaller types up to 32 bits.
(decl operand_size_of_type_32_64 (Type) OperandSize)
(extern constructor operand_size_of_type_32_64 operand_size_of_type_32_64)
;; Get the true `OperandSize` for a given `Type`, with no rounding.
(decl raw_operand_size_of_type (Type) OperandSize)
(extern constructor raw_operand_size_of_type raw_operand_size_of_type)
;; Get the bit width of an `OperandSize`.
(decl operand_size_bits (OperandSize) u16)
@@ -430,7 +434,7 @@
(let ((from_bits u16 (ty_bits_u16 from_ty))
;; Use `operand_size_of_type` so that the we clamp the output to 32-
;; or 64-bit width types.
(to_bits u16 (operand_size_bits (operand_size_of_type to_ty))))
(to_bits u16 (operand_size_bits (operand_size_of_type_32_64 to_ty))))
(extend kind
to_ty
(ext_mode from_bits to_bits)
@@ -507,7 +511,7 @@
(decl alu_rmi_r (Type AluRmiROpcode Reg RegMemImm) Reg)
(rule (alu_rmi_r ty opcode src1 src2)
(let ((dst WritableReg (temp_writable_reg ty))
(size OperandSize (operand_size_of_type ty))
(size OperandSize (operand_size_of_type_32_64 ty))
(_ Unit (emit (MInst.AluRmiR size opcode src1 src2 dst))))
(writable_reg_to_reg dst)))
@@ -523,7 +527,7 @@
(decl add_with_flags (Type Reg RegMemImm) ProducesFlags)
(rule (add_with_flags ty src1 src2)
(let ((dst WritableReg (temp_writable_reg ty)))
(ProducesFlags.ProducesFlags (MInst.AluRmiR (operand_size_of_type ty)
(ProducesFlags.ProducesFlags (MInst.AluRmiR (operand_size_of_type_32_64 ty)
(AluRmiROpcode.Add)
src1
src2
@@ -534,7 +538,7 @@
(decl adc (Type Reg RegMemImm) ConsumesFlags)
(rule (adc ty src1 src2)
(let ((dst WritableReg (temp_writable_reg ty)))
(ConsumesFlags.ConsumesFlags (MInst.AluRmiR (operand_size_of_type ty)
(ConsumesFlags.ConsumesFlags (MInst.AluRmiR (operand_size_of_type_32_64 ty)
(AluRmiROpcode.Adc)
src1
src2
@@ -553,7 +557,7 @@
(decl sub_with_flags (Type Reg RegMemImm) ProducesFlags)
(rule (sub_with_flags ty src1 src2)
(let ((dst WritableReg (temp_writable_reg ty)))
(ProducesFlags.ProducesFlags (MInst.AluRmiR (operand_size_of_type ty)
(ProducesFlags.ProducesFlags (MInst.AluRmiR (operand_size_of_type_32_64 ty)
(AluRmiROpcode.Sub)
src1
src2
@@ -564,7 +568,7 @@
(decl sbb (Type Reg RegMemImm) ConsumesFlags)
(rule (sbb ty src1 src2)
(let ((dst WritableReg (temp_writable_reg ty)))
(ConsumesFlags.ConsumesFlags (MInst.AluRmiR (operand_size_of_type ty)
(ConsumesFlags.ConsumesFlags (MInst.AluRmiR (operand_size_of_type_32_64 ty)
(AluRmiROpcode.Sbb)
src1
src2
@@ -612,7 +616,7 @@
;; Integer immediates.
(rule (imm ty simm64)
(let ((dst WritableReg (temp_writable_reg ty))
(size OperandSize (operand_size_of_type ty))
(size OperandSize (operand_size_of_type_32_64 ty))
(_ Unit (emit (MInst.Imm size simm64 dst))))
(writable_reg_to_reg dst)))
@@ -638,7 +642,7 @@
(rule (imm ty 0)
(let ((wr WritableReg (temp_writable_reg ty))
(r Reg (writable_reg_to_reg wr))
(size OperandSize (operand_size_of_type ty))
(size OperandSize (operand_size_of_type_32_64 ty))
(_ Unit (emit (MInst.AluRmiR size
(AluRmiROpcode.Xor)
r
@@ -685,7 +689,9 @@
(decl shift_r (Type ShiftKind Reg Imm8Reg) Reg)
(rule (shift_r ty kind src1 src2)
(let ((dst WritableReg (temp_writable_reg ty))
(size OperandSize (operand_size_of_type ty))
;; Use actual 8/16-bit instructions when appropriate: we
;; rely on their shift-amount-masking semantics.
(size OperandSize (raw_operand_size_of_type ty))
(_ Unit (emit (MInst.ShiftR size kind src1 src2 dst))))
(writable_reg_to_reg dst)))
@@ -733,7 +739,7 @@
(decl cmove (Type CC RegMem Reg) ConsumesFlags)
(rule (cmove ty cc consequent alternative)
(let ((dst WritableReg (temp_writable_reg ty))
(size OperandSize (operand_size_of_type ty)))
(size OperandSize (operand_size_of_type_32_64 ty)))
(ConsumesFlags.ConsumesFlags (MInst.Cmove size cc consequent alternative dst)
(writable_reg_to_reg dst))))
@@ -1159,7 +1165,7 @@
(rule (mul_hi ty signed src1 src2)
(let ((dst_lo WritableReg (temp_writable_reg ty))
(dst_hi WritableReg (temp_writable_reg ty))
(size OperandSize (operand_size_of_type ty))
(size OperandSize (operand_size_of_type_32_64 ty))
(_ Unit (emit (MInst.MulHi size
signed
src1
@@ -1228,6 +1234,6 @@
(decl not (Type Reg) Reg)
(rule (not ty src)
(let ((dst WritableReg (temp_writable_reg ty))
(size OperandSize (operand_size_of_type ty))
(size OperandSize (operand_size_of_type_32_64 ty))
(_ Unit (emit (MInst.Not size src dst))))
(writable_reg_to_reg dst)))