@@ -32,6 +32,9 @@ def_simple_binary_operation!(DivUOp, "comb.divu");
32
32
def_simple_binary_operation ! ( DivSOp , "comb.divs" ) ;
33
33
def_simple_binary_operation ! ( ModUOp , "comb.modu" ) ;
34
34
def_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" ) ;
35
38
def_operation_single_result ! ( ICmpOp , "comb.icmp" ) ;
36
39
def_operation_single_result ! ( MuxOp , "comb.mux" ) ;
37
40
def_operation_single_result ! ( ExtractOp , "comb.extract" ) ;
@@ -106,22 +109,52 @@ impl ConcatOp {
106
109
}
107
110
}
108
111
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
+
109
133
pub ( crate ) fn clog2 ( value : usize ) -> usize {
110
134
usize:: BITS as usize - value. next_power_of_two ( ) . leading_zeros ( ) as usize - 1
111
135
}
112
136
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) {
115
139
array_type_size ( ty)
116
140
} else if is_integer_type ( ty) {
117
141
integer_type_width ( ty)
118
142
} else {
119
143
panic ! ( "unsupported indexing target type {}" , ty)
120
- } )
144
+ }
145
+ }
146
+
147
+ pub ( crate ) fn type_clog2 ( ty : Type ) -> usize {
148
+ clog2 ( type_width ( ty) )
121
149
}
122
150
123
151
pub ( crate ) fn trunc_or_zext_to_clog2 ( builder : & mut Builder , index : Value , into_ty : Type ) -> Value {
124
152
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) ;
125
158
let actual_width = integer_type_width ( index. ty ( ) ) ;
126
159
if target_width < actual_width {
127
160
ExtractOp :: with_sizes ( builder, index, 0 , target_width) . into ( )
0 commit comments