Skip to content

Commit 1bf49ce

Browse files
committed
s390x: implement & test smul_overflow
1 parent 6ddc878 commit 1bf49ce

3 files changed

Lines changed: 119 additions & 0 deletions

File tree

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4426,6 +4426,29 @@
44264426
(intcc_as_cond (IntCC.Equal)))))))
44274427
(output_pair result of)))
44284428

4429+
;;;; Rules for `smul_overflow` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4430+
4431+
;; For fit-in-16 bit integers, we shift just the rhs into the most
4432+
;; significant positions of its 32-bit register, use the codition
4433+
;; codes for the overflow, and shifting back into the expected
4434+
;; least-significant position to generate the result.
4435+
(rule 1 (lower (has_type (fits_in_16 ty) (smul_overflow x y)))
4436+
(let ((y_ext Reg (sext32_reg ty y))
4437+
(x_shifted Reg (lshl_imm $I32 x (type_shift_up ty)))
4438+
(producer ProducesFlags
4439+
(mul_reg_with_flags_paired $I32 x_shifted y_ext))
4440+
(overflow Reg (lower_bool $I8 (bool
4441+
(produces_flags_ignore producer)
4442+
(mask_as_cond 1))))
4443+
(out Reg (lshr_imm $I32
4444+
(produces_flags_get_reg producer)
4445+
(type_shift_up ty))))
4446+
(output_pair out overflow)))
4447+
4448+
;; Use flags generated by the add instruction to handle overflow
4449+
(rule 0 (lower (has_type (ty_32_or_64 ty) (smul_overflow x y)))
4450+
(overflow_and_result_from_producer (mul_reg_with_flags_paired ty x y) (mask_as_cond 1)))
4451+
44294452
;;;; Rules for `return` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
44304453

44314454
(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)