Skip to content

Commit c7dff92

Browse files
committed
s390x: implement & test smul_overflow
1 parent 0e9db97 commit c7dff92

6 files changed

Lines changed: 133 additions & 0 deletions

File tree

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,8 +1099,10 @@
10991099
(SubLogical64)
11001100
(SubLogical64Ext32)
11011101
(Mul32)
1102+
(Mul32CC)
11021103
(Mul32Ext16)
11031104
(Mul64)
1105+
(Mul64CC)
11041106
(Mul64Ext16)
11051107
(Mul64Ext32)
11061108
(And32)
@@ -4040,6 +4042,10 @@
40404042
(rule (aluop_mul $I32) (ALUOp.Mul32))
40414043
(rule (aluop_mul $I64) (ALUOp.Mul64))
40424044

4045+
(decl aluop_mul_cc (Type) ALUOp)
4046+
(rule (aluop_mul_cc $I32) (ALUOp.Mul32CC))
4047+
(rule (aluop_mul_cc $I64) (ALUOp.Mul64CC))
4048+
40434049
(decl aluop_mul_sext16 (Type) ALUOp)
40444050
(rule (aluop_mul_sext16 $I16) (ALUOp.Mul32Ext16))
40454051
(rule (aluop_mul_sext16 $I32) (ALUOp.Mul32Ext16))
@@ -4051,6 +4057,10 @@
40514057
(decl mul_reg (Type Reg Reg) Reg)
40524058
(rule (mul_reg ty x y) (alu_rrr ty (aluop_mul ty) x y))
40534059

4060+
(decl mul_reg_with_flags_paired (Type Reg Reg) ProducesFlags)
4061+
(rule (mul_reg_with_flags_paired ty x y)
4062+
(alu_rrr_with_flags_paired ty (aluop_mul_cc ty) x y))
4063+
40544064
(decl mul_reg_sext32 (Type Reg Reg) Reg)
40554065
(rule (mul_reg_sext32 ty x y) (alu_rr ty (aluop_mul_sext32 ty) x y))
40564066

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,7 +1516,9 @@ impl Inst {
15161516
ALUOp::SubLogical32 => (0xb9fb, true), // SLRK
15171517
ALUOp::SubLogical64 => (0xb9eb, true), // SLGRK
15181518
ALUOp::Mul32 => (0xb9fd, true), // MSRKC
1519+
ALUOp::Mul32CC => (0xb9fd, false), // MSRKC
15191520
ALUOp::Mul64 => (0xb9ed, true), // MSGRKC
1521+
ALUOp::Mul64CC => (0xb9ed, false), // MSGRKC
15201522
ALUOp::And32 => (0xb9f4, true), // NRK
15211523
ALUOp::And64 => (0xb9e4, true), // NGRK
15221524
ALUOp::Orr32 => (0xb9f6, true), // ORK

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,7 +1296,9 @@ impl Inst {
12961296
ALUOp::SubLogical32 => ("slrk", true),
12971297
ALUOp::SubLogical64 => ("slgrk", true),
12981298
ALUOp::Mul32 => ("msrkc", true),
1299+
ALUOp::Mul32CC => ("msrkc", false),
12991300
ALUOp::Mul64 => ("msgrkc", true),
1301+
ALUOp::Mul64CC => ("msgrkc", false),
13001302
ALUOp::And32 => ("nrk", true),
13011303
ALUOp::And64 => ("ngrk", true),
13021304
ALUOp::Orr32 => ("ork", true),

cranelift/codegen/src/isa/s390x/lower.isle

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4399,6 +4399,29 @@
43994399
(intcc_as_cond (IntCC.Equal)))))))
44004400
(output_pair result of)))
44014401

4402+
;;;; Rules for `smul_overflow` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4403+
4404+
;; For fit-in-16 bit integers, we shift just the rhs into the most
4405+
;; significant positions of its 32-bit register, use the codition
4406+
;; codes for the overflow, and shifting back into the expected
4407+
;; least-significant position to generate the result.
4408+
(rule 1 (lower (smul_overflow (fits_in_16 ty) x y))
4409+
(let ((y_ext Reg (sext32_reg ty y))
4410+
(x_shifted Reg (lshl_imm $I32 x (type_shift_up ty)))
4411+
(producer ProducesFlags
4412+
(mul_reg_with_flags_paired $I32 x_shifted y_ext))
4413+
(overflow Reg (lower_bool $I8 (bool
4414+
(produces_flags_ignore producer)
4415+
(mask_as_cond 1))))
4416+
(out Reg (lshr_imm $I32
4417+
(produces_flags_get_reg producer)
4418+
(type_shift_up ty))))
4419+
(output_pair out overflow)))
4420+
4421+
;; Use flags generated by the add instruction to handle overflow
4422+
(rule 0 (lower (smul_overflow (ty_32_or_64 ty) x y))
4423+
(overflow_and_result_from_producer (mul_reg_with_flags_paired ty x y) (mask_as_cond 1)))
4424+
44024425
;;;; Rules for `return` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
44034426

44044427
(rule (lower (return args))
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
test compile precise-output
2+
target s390x
3+
4+
function %f2(i8, i8) -> i8, i8 {
5+
block0(v0: i8, v1: i8):
6+
v2, v3 = smul_overflow v0, v1
7+
return v2, v3
8+
}
9+
10+
; VCode:
11+
; block0:
12+
; lbr %r3, %r3
13+
; sllk %r5, %r2, 24
14+
; msrkc %r2, %r5, %r3
15+
; lhi %r3, 0
16+
; lochio %r3, 1
17+
; srlk %r2, %r2, 24
18+
; br %r14
19+
;
20+
; Disassembled:
21+
; block0: ; offset 0x0
22+
; lbr %r3, %r3
23+
; sllk %r5, %r2, 0x18
24+
; msrkc %r2, %r5, %r3
25+
; lhi %r3, 0
26+
; lochio %r3, 1
27+
; srlk %r2, %r2, 0x18
28+
; br %r14
29+
30+
function %f2(i16, i16) -> i16, i8 {
31+
block0(v0: i16, v1: i16):
32+
v2, v3 = smul_overflow v0, v1
33+
return v2, v3
34+
}
35+
36+
; VCode:
37+
; block0:
38+
; lhr %r3, %r3
39+
; sllk %r5, %r2, 16
40+
; msrkc %r2, %r5, %r3
41+
; lhi %r3, 0
42+
; lochio %r3, 1
43+
; srlk %r2, %r2, 16
44+
; br %r14
45+
;
46+
; Disassembled:
47+
; block0: ; offset 0x0
48+
; lhr %r3, %r3
49+
; sllk %r5, %r2, 0x10
50+
; msrkc %r2, %r5, %r3
51+
; lhi %r3, 0
52+
; lochio %r3, 1
53+
; srlk %r2, %r2, 0x10
54+
; br %r14
55+
56+
function %f2(i32, i32) -> i32, i8 {
57+
block0(v0: i32, v1: i32):
58+
v2, v3 = smul_overflow v0, v1
59+
return v2, v3
60+
}
61+
62+
; VCode:
63+
; block0:
64+
; msrkc %r2, %r2, %r3
65+
; lhi %r3, 0
66+
; lochio %r3, 1
67+
; br %r14
68+
;
69+
; Disassembled:
70+
; block0: ; offset 0x0
71+
; msrkc %r2, %r2, %r3
72+
; lhi %r3, 0
73+
; lochio %r3, 1
74+
; br %r14
75+
76+
function %f4(i64, i64) -> i64, i8 {
77+
block0(v0: i64, v1: i64):
78+
v2, v3 = smul_overflow v0, v1
79+
return v2, v3
80+
}
81+
82+
; VCode:
83+
; block0:
84+
; msgrkc %r2, %r2, %r3
85+
; lhi %r3, 0
86+
; lochio %r3, 1
87+
; br %r14
88+
;
89+
; Disassembled:
90+
; block0: ; offset 0x0
91+
; msgrkc %r2, %r2, %r3
92+
; lhi %r3, 0
93+
; lochio %r3, 1
94+
; br %r14
95+

cranelift/filetests/filetests/runtests/smul_overflow.clif

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ test interpret
22
test run
33
target x86_64
44
target x86_64 has_bmi2
5+
target s390x
56
target aarch64
67

78
function %smulof_i64(i64, i64) -> i64, i8 {

0 commit comments

Comments
 (0)