Skip to content

Commit c65de1f

Browse files
authored
x64: Remove conditional SseOpcode::uses_src1 (#5842)
This is a follow-up to comments in #5795 to remove some cruft in the x64 instruction model to ensure that the shape of an `Inst` reflects what's going to happen in regalloc and encoding. This accessor was used to handle `round*`, `pextr*`, and `pshufb` instructions. The `round*` ones had already moved to the appropriate `XmmUnary*` variant and `pshufb` was additionally moved over to that variant as well. The `pextr*` instructions got a new `Inst` variant and additionally had their constructors slightly modified to no longer require the type as input. The encoding for these instructions now automatically handles the various type-related operands through a new `SseOpcode::Pextrq` operand to represent 64-bit movements.
1 parent e6a5ec3 commit c65de1f

File tree

7 files changed

+98
-141
lines changed

7 files changed

+98
-141
lines changed

cranelift/codegen/src/isa/x64/inst.isle

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,12 @@
331331
(dst WritableGpr)
332332
(dst_size OperandSize))
333333

334+
;; XMM (scalar) unary op (from xmm to integer reg): pextr{w,b,d,q}
335+
(XmmToGprImm (op SseOpcode)
336+
(src Xmm)
337+
(dst WritableGpr)
338+
(imm u8))
339+
334340
;; XMM (scalar) unary op (from integer to float reg): movd, movq,
335341
;; cvtsi2s{s,d}
336342
(GprToXmm (op SseOpcode)
@@ -749,6 +755,7 @@
749755
Pextrb
750756
Pextrw
751757
Pextrd
758+
Pextrq
752759
Pinsrb
753760
Pinsrw
754761
Pinsrd
@@ -3110,16 +3117,9 @@
31103117
(xmm_rmr_imm_vex (AvxOpcode.Vinsertps) src1 src2 lane))
31113118

31123119
;; Helper for creating `pshufd` instructions.
3113-
(decl x64_pshufd (XmmMem u8 OperandSize) Xmm)
3114-
(rule (x64_pshufd src imm size)
3115-
(let ((dst WritableXmm (temp_writable_xmm))
3116-
(_ Unit (emit (MInst.XmmRmRImm (SseOpcode.Pshufd)
3117-
dst
3118-
src
3119-
dst
3120-
imm
3121-
size))))
3122-
dst))
3120+
(decl x64_pshufd (XmmMem u8) Xmm)
3121+
(rule (x64_pshufd src imm)
3122+
(xmm_unary_rm_r_imm (SseOpcode.Pshufd) src imm))
31233123

31243124
;; Helper for creating `pshufb` instructions.
31253125
(decl x64_pshufb (Xmm XmmMem) Xmm)
@@ -3314,40 +3314,24 @@
33143314
(xmm_rmir_vex (AvxOpcode.Vpsrad) src1 src2))
33153315

33163316
;; Helper for creating `pextrb` instructions.
3317-
(decl x64_pextrb (Type Xmm u8) Gpr)
3318-
(rule (x64_pextrb ty src lane)
3319-
(let ((dst WritableGpr (temp_writable_gpr))
3320-
(_ Unit (emit (MInst.XmmRmRImm (SseOpcode.Pextrb)
3321-
dst
3322-
src
3323-
dst
3324-
lane
3325-
(operand_size_of_type_32_64 (lane_type ty))))))
3326-
dst))
3317+
(decl x64_pextrb (Xmm u8) Gpr)
3318+
(rule (x64_pextrb src lane)
3319+
(xmm_to_gpr_imm (SseOpcode.Pextrb) src lane))
33273320

33283321
;; Helper for creating `pextrw` instructions.
3329-
(decl x64_pextrw (Type Xmm u8) Gpr)
3330-
(rule (x64_pextrw ty src lane)
3331-
(let ((dst WritableGpr (temp_writable_gpr))
3332-
(_ Unit (emit (MInst.XmmRmRImm (SseOpcode.Pextrw)
3333-
dst
3334-
src
3335-
dst
3336-
lane
3337-
(operand_size_of_type_32_64 (lane_type ty))))))
3338-
dst))
3322+
(decl x64_pextrw (Xmm u8) Gpr)
3323+
(rule (x64_pextrw src lane)
3324+
(xmm_to_gpr_imm (SseOpcode.Pextrw) src lane))
33393325

33403326
;; Helper for creating `pextrd` instructions.
3341-
(decl x64_pextrd (Type Xmm u8) Gpr)
3342-
(rule (x64_pextrd ty src lane)
3343-
(let ((dst WritableGpr (temp_writable_gpr))
3344-
(_ Unit (emit (MInst.XmmRmRImm (SseOpcode.Pextrd)
3345-
dst
3346-
src
3347-
dst
3348-
lane
3349-
(operand_size_of_type_32_64 (lane_type ty))))))
3350-
dst))
3327+
(decl x64_pextrd (Xmm u8) Gpr)
3328+
(rule (x64_pextrd src lane)
3329+
(xmm_to_gpr_imm (SseOpcode.Pextrd) src lane))
3330+
3331+
;; Helper for creating `pextrq` instructions.
3332+
(decl x64_pextrq (Xmm u8) Gpr)
3333+
(rule (x64_pextrq src lane)
3334+
(xmm_to_gpr_imm (SseOpcode.Pextrq) src lane))
33513335

33523336
;; Helper for creating `MInst.XmmToGpr` instructions.
33533337
(decl xmm_to_gpr (SseOpcode Xmm OperandSize) Gpr)
@@ -3356,6 +3340,13 @@
33563340
(_ Unit (emit (MInst.XmmToGpr op src dst size))))
33573341
dst))
33583342

3343+
;; Helper for creating `MInst.XmmToGpr` instructions.
3344+
(decl xmm_to_gpr_imm (SseOpcode Xmm u8) Gpr)
3345+
(rule (xmm_to_gpr_imm op src imm)
3346+
(let ((dst WritableGpr (temp_writable_gpr))
3347+
(_ Unit (emit (MInst.XmmToGprImm op src dst imm))))
3348+
dst))
3349+
33593350
;; Helper for creating `pmovmskb` instructions.
33603351
(decl x64_pmovmskb (OperandSize Xmm) Gpr)
33613352
(rule (x64_pmovmskb size src)

cranelift/codegen/src/isa/x64/inst/args.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,7 @@ pub enum SseOpcode {
999999
Pextrb,
10001000
Pextrw,
10011001
Pextrd,
1002+
Pextrq,
10021003
Pinsrb,
10031004
Pinsrw,
10041005
Pinsrd,
@@ -1237,6 +1238,7 @@ impl SseOpcode {
12371238
| SseOpcode::Pcmpeqq
12381239
| SseOpcode::Pextrb
12391240
| SseOpcode::Pextrd
1241+
| SseOpcode::Pextrq
12401242
| SseOpcode::Pinsrb
12411243
| SseOpcode::Pinsrd
12421244
| SseOpcode::Pmaxsb
@@ -1278,22 +1280,6 @@ impl SseOpcode {
12781280
_ => 8,
12791281
}
12801282
}
1281-
1282-
/// Does an XmmRmmRImm with this opcode use src1? FIXME: split
1283-
/// into separate instructions.
1284-
pub(crate) fn uses_src1(&self) -> bool {
1285-
match self {
1286-
SseOpcode::Pextrb => false,
1287-
SseOpcode::Pextrw => false,
1288-
SseOpcode::Pextrd => false,
1289-
SseOpcode::Pshufd => false,
1290-
SseOpcode::Roundss => false,
1291-
SseOpcode::Roundsd => false,
1292-
SseOpcode::Roundps => false,
1293-
SseOpcode::Roundpd => false,
1294-
_ => true,
1295-
}
1296-
}
12971283
}
12981284

12991285
impl fmt::Debug for SseOpcode {
@@ -1393,6 +1379,7 @@ impl fmt::Debug for SseOpcode {
13931379
SseOpcode::Pextrb => "pextrb",
13941380
SseOpcode::Pextrw => "pextrw",
13951381
SseOpcode::Pextrd => "pextrd",
1382+
SseOpcode::Pextrq => "pextrq",
13961383
SseOpcode::Pinsrb => "pinsrb",
13971384
SseOpcode::Pinsrw => "pinsrw",
13981385
SseOpcode::Pinsrd => "pinsrd",

cranelift/codegen/src/isa/x64/inst/emit.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,8 +1792,6 @@ pub(crate) fn emit(
17921792
}
17931793

17941794
Inst::XmmUnaryRmRImm { op, src, dst, imm } => {
1795-
debug_assert!(!op.uses_src1());
1796-
17971795
let dst = allocs.next(dst.to_reg().to_reg());
17981796
let src = src.clone().to_reg_mem().with_allocs(allocs);
17991797
let rex = RexFlags::clear_w();
@@ -1803,6 +1801,7 @@ pub(crate) fn emit(
18031801
SseOpcode::Roundss => (LegacyPrefixes::_66, 0x0F3A0A, 3),
18041802
SseOpcode::Roundpd => (LegacyPrefixes::_66, 0x0F3A09, 3),
18051803
SseOpcode::Roundsd => (LegacyPrefixes::_66, 0x0F3A0B, 3),
1804+
SseOpcode::Pshufd => (LegacyPrefixes::_66, 0x0F70, 2),
18061805
_ => unimplemented!("Opcode {:?} not implemented", op),
18071806
};
18081807
match src {
@@ -2458,17 +2457,10 @@ pub(crate) fn emit(
24582457
imm,
24592458
size,
24602459
} => {
2461-
let (src2, dst) = if !op.uses_src1() {
2462-
let dst = allocs.next(dst.to_reg());
2463-
let src2 = src2.with_allocs(allocs);
2464-
(src2, dst)
2465-
} else {
2466-
let src1 = allocs.next(*src1);
2467-
let dst = allocs.next(dst.to_reg());
2468-
let src2 = src2.with_allocs(allocs);
2469-
debug_assert_eq!(src1, dst);
2470-
(src2, dst)
2471-
};
2460+
let src1 = allocs.next(*src1);
2461+
let dst = allocs.next(dst.to_reg());
2462+
let src2 = src2.with_allocs(allocs);
2463+
debug_assert_eq!(src1, dst);
24722464

24732465
let (prefix, opcode, len) = match op {
24742466
SseOpcode::Cmpps => (LegacyPrefixes::None, 0x0FC2, 2),
@@ -2480,10 +2472,6 @@ pub(crate) fn emit(
24802472
SseOpcode::Pinsrb => (LegacyPrefixes::_66, 0x0F3A20, 3),
24812473
SseOpcode::Pinsrw => (LegacyPrefixes::_66, 0x0FC4, 2),
24822474
SseOpcode::Pinsrd => (LegacyPrefixes::_66, 0x0F3A22, 3),
2483-
SseOpcode::Pextrb => (LegacyPrefixes::_66, 0x0F3A14, 3),
2484-
SseOpcode::Pextrw => (LegacyPrefixes::_66, 0x0FC5, 2),
2485-
SseOpcode::Pextrd => (LegacyPrefixes::_66, 0x0F3A16, 3),
2486-
SseOpcode::Pshufd => (LegacyPrefixes::_66, 0x0F70, 2),
24872475
SseOpcode::Shufps => (LegacyPrefixes::None, 0x0FC6, 2),
24882476
_ => unimplemented!("Opcode {:?} not implemented", op),
24892477
};
@@ -2566,6 +2554,26 @@ pub(crate) fn emit(
25662554
emit_std_reg_reg(sink, prefix, opcode, 2, src, dst, rex);
25672555
}
25682556

2557+
Inst::XmmToGprImm { op, src, dst, imm } => {
2558+
use OperandSize as OS;
2559+
2560+
let src = allocs.next(src.to_reg());
2561+
let dst = allocs.next(dst.to_reg().to_reg());
2562+
2563+
let (prefix, opcode, opcode_bytes, dst_size, dst_first) = match op {
2564+
SseOpcode::Pextrb => (LegacyPrefixes::_66, 0x0F3A14, 3, OS::Size32, false),
2565+
SseOpcode::Pextrw => (LegacyPrefixes::_66, 0x0FC5, 2, OS::Size32, true),
2566+
SseOpcode::Pextrd => (LegacyPrefixes::_66, 0x0F3A16, 3, OS::Size32, false),
2567+
SseOpcode::Pextrq => (LegacyPrefixes::_66, 0x0F3A16, 3, OS::Size64, false),
2568+
_ => panic!("unexpected opcode {:?}", op),
2569+
};
2570+
let rex = RexFlags::from(dst_size);
2571+
let (src, dst) = if dst_first { (dst, src) } else { (src, dst) };
2572+
2573+
emit_std_reg_reg(sink, prefix, opcode, opcode_bytes, src, dst, rex);
2574+
sink.put1(*imm);
2575+
}
2576+
25692577
Inst::GprToXmm {
25702578
op,
25712579
src: src_e,

cranelift/codegen/src/isa/x64/inst/mod.rs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ impl Inst {
136136
| Inst::XmmRmRBlend { op, .. }
137137
| Inst::XmmRmRImm { op, .. }
138138
| Inst::XmmToGpr { op, .. }
139+
| Inst::XmmToGprImm { op, .. }
139140
| Inst::XmmUnaryRmRImm { op, .. }
140141
| Inst::XmmUnaryRmR { op, .. }
141142
| Inst::XmmConstOp { op, .. } => smallvec![op.available_from()],
@@ -1111,15 +1112,11 @@ impl PrettyPrint for Inst {
11111112
size,
11121113
..
11131114
} => {
1114-
let src1 = if op.uses_src1() {
1115-
pretty_print_reg(*src1, 8, allocs) + ", "
1116-
} else {
1117-
"".into()
1118-
};
1115+
let src1 = pretty_print_reg(*src1, 8, allocs);
11191116
let dst = pretty_print_reg(dst.to_reg(), 8, allocs);
11201117
let src2 = src2.pretty_print(8, allocs);
11211118
format!(
1122-
"{} ${}, {}{}, {}",
1119+
"{} ${imm}, {src1}, {src2}, {dst}",
11231120
ljustify(format!(
11241121
"{}{}",
11251122
op.to_string(),
@@ -1129,10 +1126,6 @@ impl PrettyPrint for Inst {
11291126
""
11301127
}
11311128
)),
1132-
imm,
1133-
src1,
1134-
src2,
1135-
dst,
11361129
)
11371130
}
11381131

@@ -1153,6 +1146,12 @@ impl PrettyPrint for Inst {
11531146
format!("{} {}, {}", ljustify(op.to_string()), src, dst)
11541147
}
11551148

1149+
Inst::XmmToGprImm { op, src, dst, imm } => {
1150+
let src = pretty_print_reg(src.to_reg(), 8, allocs);
1151+
let dst = pretty_print_reg(dst.to_reg().to_reg(), 8, allocs);
1152+
format!("{} ${imm}, {}, {}", ljustify(op.to_string()), src, dst)
1153+
}
1154+
11561155
Inst::GprToXmm {
11571156
op,
11581157
src,
@@ -1976,23 +1975,11 @@ fn x64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandCol
19761975
src1.get_operands(collector);
19771976
}
19781977
Inst::XmmRmRImm {
1979-
op,
1980-
src1,
1981-
src2,
1982-
dst,
1983-
..
1978+
src1, src2, dst, ..
19841979
} => {
1985-
if !op.uses_src1() {
1986-
// FIXME: split this instruction into two, so we don't
1987-
// need this awkward src1-is-only-sometimes-an-arg
1988-
// behavior.
1989-
collector.reg_def(*dst);
1990-
src2.get_operands(collector);
1991-
} else {
1992-
collector.reg_use(*src1);
1993-
collector.reg_reuse_def(*dst, 0);
1994-
src2.get_operands(collector);
1995-
}
1980+
collector.reg_use(*src1);
1981+
collector.reg_reuse_def(*dst, 0);
1982+
src2.get_operands(collector);
19961983
}
19971984
Inst::XmmConstOp { dst, .. } => {
19981985
collector.reg_def(dst.to_writable_reg());
@@ -2035,7 +2022,7 @@ fn x64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandCol
20352022
collector.reg_use(src.to_reg());
20362023
collector.reg_fixed_nonallocatable(*dst);
20372024
}
2038-
Inst::XmmToGpr { src, dst, .. } => {
2025+
Inst::XmmToGpr { src, dst, .. } | Inst::XmmToGprImm { src, dst, .. } => {
20392026
collector.reg_use(src.to_reg());
20402027
collector.reg_def(dst.to_writable_reg());
20412028
}

0 commit comments

Comments
 (0)