Emit instructions to produce a zero value in the given type.
(ty: Type, mut cur: FuncCursor)
| 146 | |
| 147 | /// Emit instructions to produce a zero value in the given type. |
| 148 | fn emit_zero(ty: Type, mut cur: FuncCursor) -> Value { |
| 149 | match ty { |
| 150 | I128 => { |
| 151 | let zero = cur.ins().iconst(I64, 0); |
| 152 | cur.ins().uextend(I128, zero) |
| 153 | } |
| 154 | ty if ty.is_int() => cur.ins().iconst(ty, 0), |
| 155 | F16 => cur.ins().f16const(Ieee16::with_bits(0)), |
| 156 | F32 => cur.ins().f32const(Ieee32::with_bits(0)), |
| 157 | F64 => cur.ins().f64const(Ieee64::with_bits(0)), |
| 158 | F128 => { |
| 159 | let zero = cur.func.dfg.constants.insert(Ieee128::with_bits(0).into()); |
| 160 | cur.ins().f128const(zero) |
| 161 | } |
| 162 | ty if ty.is_vector() => match ty.lane_type() { |
| 163 | scalar_ty if scalar_ty.is_int() => { |
| 164 | let zero = cur |
| 165 | .func |
| 166 | .dfg |
| 167 | .constants |
| 168 | .insert(vec![0; ty.bytes().try_into().unwrap()].into()); |
| 169 | cur.ins().vconst(ty, zero) |
| 170 | } |
| 171 | F16 => { |
| 172 | let scalar = cur.ins().f16const(Ieee16::with_bits(0)); |
| 173 | cur.ins().splat(ty, scalar) |
| 174 | } |
| 175 | F32 => { |
| 176 | let scalar = cur.ins().f32const(Ieee32::with_bits(0)); |
| 177 | cur.ins().splat(ty, scalar) |
| 178 | } |
| 179 | F64 => { |
| 180 | let scalar = cur.ins().f64const(Ieee64::with_bits(0)); |
| 181 | cur.ins().splat(ty, scalar) |
| 182 | } |
| 183 | F128 => { |
| 184 | let zero = cur.func.dfg.constants.insert(Ieee128::with_bits(0).into()); |
| 185 | let scalar = cur.ins().f128const(zero); |
| 186 | cur.ins().splat(ty, scalar) |
| 187 | } |
| 188 | _ => panic!("unimplemented scalar type: {ty:?}"), |
| 189 | }, |
| 190 | ty => panic!("unimplemented type: {ty:?}"), |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | /// The following methods are the API of the SSA builder. Here is how it should be used when |
| 195 | /// translating to Cranelift IR: |