x64: Refactor and fill out some gpr-vs-xmm bits (#6058)
* x64: Add instruction helpers for `mov{d,q}`
These will soon grow AVX-equivalents so move them to instruction helpers
to have clauses for AVX in the future.
* x64: Don't auto-convert between RegMemImm and XmmMemImm
The previous conversion, `mov_rmi_to_xmm`, would move from GPR registers
to XMM registers which isn't what many of the other `convert` statements
between these newtypes do. This seemed like a possible footgun so I've
removed the auto-conversion and added an explicit helper to go from a
`u32` to an `XmmMemImm`.
* x64: Add AVX encodings of some more GPR-related insns
This commit adds some more support for AVX instructions where GPRs are
in use mixed in with XMM registers. This required a few more variants of
`Inst` to handle the new instructions.
* Fix vpmovmskb encoding
* Fix xmm-to-gpr encoding of vmovd/vmovq
* Fix typo
* Fix rebase conflict
* Fix rebase conflict with tests
This commit is contained in:
@@ -320,6 +320,21 @@
|
||||
(dst WritableGpr)
|
||||
(imm u8))
|
||||
|
||||
;; XMM (scalar) unary op (from integer to float reg): vmovd, vmovq,
|
||||
;; vcvtsi2s{s,d}
|
||||
(GprToXmmVex (op AvxOpcode)
|
||||
(src GprMem)
|
||||
(dst WritableXmm)
|
||||
(src_size OperandSize))
|
||||
|
||||
;; XMM (scalar) unary op (from xmm to integer reg): vmovd, vmovq,
|
||||
;; vcvtts{s,d}2si
|
||||
(XmmToGprVex (op AvxOpcode)
|
||||
(src Xmm)
|
||||
(dst WritableGpr)
|
||||
(dst_size OperandSize))
|
||||
|
||||
|
||||
;; XMM (scalar or vector) binary op that relies on the EVEX
|
||||
;; prefix. Takes two inputs.
|
||||
(XmmRmREvex (op Avx512Opcode)
|
||||
@@ -1277,6 +1292,13 @@
|
||||
Vpbroadcastw
|
||||
Vpbroadcastd
|
||||
Vbroadcastss
|
||||
Vmovd
|
||||
Vmovq
|
||||
Vmovmskps
|
||||
Vmovmskpd
|
||||
Vpmovmskb
|
||||
Vcvtsi2ss
|
||||
Vcvtsi2sd
|
||||
))
|
||||
|
||||
(type Avx512Opcode extern
|
||||
@@ -1539,6 +1561,10 @@
|
||||
(decl lo_gpr (Value) Gpr)
|
||||
(rule (lo_gpr regs) (gpr_new (lo_reg regs)))
|
||||
|
||||
;; Construct a new `XmmMemImm` from a 32-bit immediate.
|
||||
(decl xmi_imm (u32) XmmMemImm)
|
||||
(extern constructor xmi_imm xmi_imm)
|
||||
|
||||
;;;; Helpers for Working With Integer Comparison Codes ;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
|
||||
@@ -1818,10 +1844,7 @@
|
||||
(decl mov_rmi_to_xmm (RegMemImm) XmmMemImm)
|
||||
(rule (mov_rmi_to_xmm rmi @ (RegMemImm.Mem _)) (xmm_mem_imm_new rmi))
|
||||
(rule (mov_rmi_to_xmm rmi @ (RegMemImm.Imm _)) (xmm_mem_imm_new rmi))
|
||||
(rule (mov_rmi_to_xmm (RegMemImm.Reg r))
|
||||
(gpr_to_xmm (SseOpcode.Movd)
|
||||
r
|
||||
(OperandSize.Size32)))
|
||||
(rule (mov_rmi_to_xmm (RegMemImm.Reg r)) (x64_movd_to_xmm r))
|
||||
|
||||
;;;; Helpers for Emitting Calls ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@@ -1941,9 +1964,37 @@
|
||||
(if-let $true (use_avx_simd))
|
||||
(xmm_movrm_vex (AvxOpcode.Vmovupd) addr data))
|
||||
|
||||
(decl x64_movd (Xmm) Gpr)
|
||||
(rule (x64_movd from)
|
||||
;; Helper for creating `movd` instructions.
|
||||
(decl x64_movd_to_gpr (Xmm) Gpr)
|
||||
(rule (x64_movd_to_gpr from)
|
||||
(xmm_to_gpr (SseOpcode.Movd) from (OperandSize.Size32)))
|
||||
(rule 1 (x64_movd_to_gpr from)
|
||||
(if-let $true (use_avx_simd))
|
||||
(xmm_to_gpr_vex (AvxOpcode.Vmovd) from (OperandSize.Size32)))
|
||||
|
||||
;; Helper for creating `movd` instructions.
|
||||
(decl x64_movd_to_xmm (GprMem) Xmm)
|
||||
(rule (x64_movd_to_xmm from)
|
||||
(gpr_to_xmm (SseOpcode.Movd) from (OperandSize.Size32)))
|
||||
(rule 1 (x64_movd_to_xmm from)
|
||||
(if-let $true (use_avx_simd))
|
||||
(gpr_to_xmm_vex (AvxOpcode.Vmovd) from (OperandSize.Size32)))
|
||||
|
||||
;; Helper for creating `movq` instructions.
|
||||
(decl x64_movq_to_xmm (GprMem) Xmm)
|
||||
(rule (x64_movq_to_xmm src)
|
||||
(gpr_to_xmm (SseOpcode.Movq) src (OperandSize.Size64)))
|
||||
(rule 1 (x64_movq_to_xmm from)
|
||||
(if-let $true (use_avx_simd))
|
||||
(gpr_to_xmm_vex (AvxOpcode.Vmovq) from (OperandSize.Size64)))
|
||||
|
||||
;; Helper for creating `movq` instructions.
|
||||
(decl x64_movq_to_gpr (Xmm) Gpr)
|
||||
(rule (x64_movq_to_gpr src)
|
||||
(xmm_to_gpr (SseOpcode.Movq) src (OperandSize.Size64)))
|
||||
(rule 1 (x64_movq_to_gpr from)
|
||||
(if-let $true (use_avx_simd))
|
||||
(xmm_to_gpr_vex (AvxOpcode.Vmovq) from (OperandSize.Size64)))
|
||||
|
||||
(decl x64_movdqu_load (XmmMem) Xmm)
|
||||
(rule (x64_movdqu_load from)
|
||||
@@ -2186,15 +2237,11 @@
|
||||
|
||||
;; `f32` immediates.
|
||||
(rule 2 (imm $F32 (u64_nonzero bits))
|
||||
(gpr_to_xmm (SseOpcode.Movd)
|
||||
(imm $I32 bits)
|
||||
(OperandSize.Size32)))
|
||||
(x64_movd_to_xmm (imm $I32 bits)))
|
||||
|
||||
;; `f64` immediates.
|
||||
(rule 2 (imm $F64 (u64_nonzero bits))
|
||||
(gpr_to_xmm (SseOpcode.Movq)
|
||||
(imm $I64 bits)
|
||||
(OperandSize.Size64)))
|
||||
(x64_movq_to_xmm (imm $I64 bits)))
|
||||
|
||||
;; Special case for when a 64-bit immediate fits into 32-bits. We can use a
|
||||
;; 32-bit move that zero-extends the value, which has a smaller encoding.
|
||||
@@ -3663,20 +3710,44 @@
|
||||
(_ Unit (emit (MInst.XmmToGprImmVex op src dst imm))))
|
||||
dst))
|
||||
|
||||
;; Helper for creating `MInst.XmmToGprVex` instructions.
|
||||
(decl xmm_to_gpr_vex (AvxOpcode Xmm OperandSize) Gpr)
|
||||
(rule (xmm_to_gpr_vex op src size)
|
||||
(let ((dst WritableGpr (temp_writable_gpr))
|
||||
(_ Unit (emit (MInst.XmmToGprVex op src dst size))))
|
||||
dst))
|
||||
|
||||
;; Helper for creating `MInst.GprToXmmVex` instructions.
|
||||
(decl gpr_to_xmm_vex (AvxOpcode GprMem OperandSize) Xmm)
|
||||
(rule (gpr_to_xmm_vex op src size)
|
||||
(let ((dst WritableXmm (temp_writable_xmm))
|
||||
(_ Unit (emit (MInst.GprToXmmVex op src dst size))))
|
||||
dst))
|
||||
|
||||
|
||||
;; Helper for creating `pmovmskb` instructions.
|
||||
(decl x64_pmovmskb (OperandSize Xmm) Gpr)
|
||||
(rule (x64_pmovmskb size src)
|
||||
(xmm_to_gpr (SseOpcode.Pmovmskb) src size))
|
||||
(rule 1 (x64_pmovmskb size src)
|
||||
(if-let $true (use_avx_simd))
|
||||
(xmm_to_gpr_vex (AvxOpcode.Vpmovmskb) src size))
|
||||
|
||||
;; Helper for creating `movmskps` instructions.
|
||||
(decl x64_movmskps (OperandSize Xmm) Gpr)
|
||||
(rule (x64_movmskps size src)
|
||||
(xmm_to_gpr (SseOpcode.Movmskps) src size))
|
||||
(rule 1 (x64_movmskps size src)
|
||||
(if-let $true (use_avx_simd))
|
||||
(xmm_to_gpr_vex (AvxOpcode.Vmovmskps) src size))
|
||||
|
||||
;; Helper for creating `movmskpd` instructions.
|
||||
(decl x64_movmskpd (OperandSize Xmm) Gpr)
|
||||
(rule (x64_movmskpd size src)
|
||||
(xmm_to_gpr (SseOpcode.Movmskpd) src size))
|
||||
(rule 1 (x64_movmskpd size src)
|
||||
(if-let $true (use_avx_simd))
|
||||
(xmm_to_gpr_vex (AvxOpcode.Vmovmskpd) src size))
|
||||
|
||||
;; Helper for creating `MInst.GprToXmm` instructions.
|
||||
(decl gpr_to_xmm (SseOpcode GprMem OperandSize) Xmm)
|
||||
@@ -3973,11 +4044,17 @@
|
||||
(decl x64_cvtsi2ss (Type GprMem) Xmm)
|
||||
(rule (x64_cvtsi2ss ty x)
|
||||
(gpr_to_xmm (SseOpcode.Cvtsi2ss) x (raw_operand_size_of_type ty)))
|
||||
(rule 1 (x64_cvtsi2ss ty x)
|
||||
(if-let $true (use_avx_simd))
|
||||
(gpr_to_xmm_vex (AvxOpcode.Vcvtsi2ss) x (raw_operand_size_of_type ty)))
|
||||
|
||||
;; Helper for creating `cvtsi2sd` instructions.
|
||||
(decl x64_cvtsi2sd (Type GprMem) Xmm)
|
||||
(rule (x64_cvtsi2sd ty x)
|
||||
(gpr_to_xmm (SseOpcode.Cvtsi2sd) x (raw_operand_size_of_type ty)))
|
||||
(rule 1 (x64_cvtsi2sd ty x)
|
||||
(if-let $true (use_avx_simd))
|
||||
(gpr_to_xmm_vex (AvxOpcode.Vcvtsi2sd) x (raw_operand_size_of_type ty)))
|
||||
|
||||
;; Helper for creating `cvttps2dq` instructions.
|
||||
(decl x64_cvttps2dq (XmmMem) Xmm)
|
||||
@@ -4486,15 +4563,15 @@
|
||||
|
||||
(decl bitcast_xmm_to_gpr (Type Xmm) Gpr)
|
||||
(rule (bitcast_xmm_to_gpr $F32 src)
|
||||
(xmm_to_gpr (SseOpcode.Movd) src (OperandSize.Size32)))
|
||||
(x64_movd_to_gpr src))
|
||||
(rule (bitcast_xmm_to_gpr $F64 src)
|
||||
(xmm_to_gpr (SseOpcode.Movq) src (OperandSize.Size64)))
|
||||
(x64_movq_to_gpr src))
|
||||
|
||||
(decl bitcast_gpr_to_xmm (Type Gpr) Xmm)
|
||||
(rule (bitcast_gpr_to_xmm $I32 src)
|
||||
(gpr_to_xmm (SseOpcode.Movd) src (OperandSize.Size32)))
|
||||
(x64_movd_to_xmm src))
|
||||
(rule (bitcast_gpr_to_xmm $I64 src)
|
||||
(gpr_to_xmm (SseOpcode.Movq) src (OperandSize.Size64)))
|
||||
(x64_movq_to_xmm src))
|
||||
|
||||
;;;; Stack Addresses ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@@ -4678,7 +4755,6 @@
|
||||
(convert Reg XmmMem reg_to_xmm_mem)
|
||||
(convert Reg RegMemImm reg_to_reg_mem_imm)
|
||||
(convert RegMem XmmMem reg_mem_to_xmm_mem)
|
||||
(convert RegMemImm XmmMemImm mov_rmi_to_xmm)
|
||||
(convert Xmm XmmMem xmm_to_xmm_mem)
|
||||
(convert Xmm XmmMemImm xmm_to_xmm_mem_imm)
|
||||
(convert Xmm XmmMemAligned xmm_to_xmm_mem_aligned)
|
||||
|
||||
Reference in New Issue
Block a user