@@ -32,6 +32,9 @@ def_simple_binary_operation!(DivUOp, "comb.divu");
3232def_simple_binary_operation ! ( DivSOp , "comb.divs" ) ;
3333def_simple_binary_operation ! ( ModUOp , "comb.modu" ) ;
3434def_simple_binary_operation ! ( ModSOp , "comb.mods" ) ;
35+ def_simple_binary_operation ! ( ShlOp , "comb.shl" ) ;
36+ def_simple_binary_operation ! ( ShrUOp , "comb.shru" ) ;
37+ def_simple_binary_operation ! ( ShrSOp , "comb.shrs" ) ;
3538def_operation_single_result ! ( ICmpOp , "comb.icmp" ) ;
3639def_operation_single_result ! ( MuxOp , "comb.mux" ) ;
3740def_operation_single_result ! ( ExtractOp , "comb.extract" ) ;
@@ -106,22 +109,52 @@ impl ConcatOp {
106109 }
107110}
108111
112+ impl ShrUOp {
113+ pub fn with_sizes ( builder : & mut Builder , value : Value , amount : Value ) -> Self {
114+ let amount = trunc_or_zext ( builder, amount, value. ty ( ) ) ;
115+ ShrUOp :: new ( builder, value, amount)
116+ }
117+ }
118+
119+ impl ShrSOp {
120+ pub fn with_sizes ( builder : & mut Builder , value : Value , amount : Value ) -> Self {
121+ let amount = trunc_or_zext ( builder, amount, value. ty ( ) ) ;
122+ ShrSOp :: new ( builder, value, amount)
123+ }
124+ }
125+
126+ impl ShlOp {
127+ pub fn with_sizes ( builder : & mut Builder , value : Value , amount : Value ) -> Self {
128+ let amount = trunc_or_zext ( builder, amount, value. ty ( ) ) ;
129+ ShlOp :: new ( builder, value, amount)
130+ }
131+ }
132+
109133pub ( crate ) fn clog2 ( value : usize ) -> usize {
110134 usize:: BITS as usize - value. next_power_of_two ( ) . leading_zeros ( ) as usize - 1
111135}
112136
113- pub ( crate ) fn type_clog2 ( ty : Type ) -> usize {
114- clog2 ( if is_array_type ( ty) {
137+ pub ( crate ) fn type_width ( ty : Type ) -> usize {
138+ if is_array_type ( ty) {
115139 array_type_size ( ty)
116140 } else if is_integer_type ( ty) {
117141 integer_type_width ( ty)
118142 } else {
119143 panic ! ( "unsupported indexing target type {}" , ty)
120- } )
144+ }
145+ }
146+
147+ pub ( crate ) fn type_clog2 ( ty : Type ) -> usize {
148+ clog2 ( type_width ( ty) )
121149}
122150
123151pub ( crate ) fn trunc_or_zext_to_clog2 ( builder : & mut Builder , index : Value , into_ty : Type ) -> Value {
124152 let target_width = std:: cmp:: max ( type_clog2 ( into_ty) , 1 ) ;
153+ trunc_or_zext ( builder, index, get_integer_type ( builder. cx , target_width) )
154+ }
155+
156+ pub ( crate ) fn trunc_or_zext ( builder : & mut Builder , index : Value , into_ty : Type ) -> Value {
157+ let target_width = type_width ( into_ty) ;
125158 let actual_width = integer_type_width ( index. ty ( ) ) ;
126159 if target_width < actual_width {
127160 ExtractOp :: with_sizes ( builder, index, 0 , target_width) . into ( )
0 commit comments