File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 10991099 (SubLogical64)
11001100 (SubLogical64Ext32)
11011101 (Mul32)
1102+ (Mul32CC)
11021103 (Mul32Ext16)
11031104 (Mul64)
1105+ (Mul64CC)
11041106 (Mul64Ext16)
11051107 (Mul64Ext32)
11061108 (And32)
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))
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
Original file line number Diff line number Diff 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
Original file line number Diff line number Diff 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 ) ,
Original file line number Diff line number Diff line change 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))
Original file line number Diff line number Diff line change 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+
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ test interpret
22test run
33target x86_64
44target x86_64 has_bmi2
5+ target s390x
56target aarch64
67
78function %smulof_i64(i64, i64) -> i64, i8 {
You can’t perform that action at this time.
0 commit comments