| ... | ... | @@ -3091,11 +3091,32 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3091 | 3091 | const ty_op = func.air.instructions.items(.data)[inst].ty_op; |
| 3092 | 3092 | const result = if (!func.liveness.isUnused(inst)) result: { |
| 3093 | 3093 | const operand = try func.resolveInst(ty_op.operand); |
| 3094 | const wanted_ty = func.air.typeOfIndex(inst); |
| 3095 | const given_ty = func.air.typeOf(ty_op.operand); |
| 3096 | if (given_ty.isAnyFloat() or wanted_ty.isAnyFloat()) { |
| 3097 | const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand); |
| 3098 | break :result try bitcast_result.toLocal(func, wanted_ty); |
| 3099 | } |
| 3094 | 3100 | break :result func.reuseOperand(ty_op.operand, operand); |
| 3095 | 3101 | } else WValue{ .none = {} }; |
| 3096 | 3102 | func.finishAir(inst, result, &.{}); |
| 3097 | 3103 | } |
| 3098 | 3104 | |
| 3105 | fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue { |
| 3106 | // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction |
| 3107 | if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand; |
| 3108 | assert((wanted_ty.isInt() and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt())); |
| 3109 | |
| 3110 | const opcode = buildOpcode(.{ |
| 3111 | .op = .reinterpret, |
| 3112 | .valtype1 = typeToValtype(wanted_ty, func.target), |
| 3113 | .valtype2 = typeToValtype(given_ty, func.target), |
| 3114 | }); |
| 3115 | try func.emitWValue(operand); |
| 3116 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); |
| 3117 | return WValue{ .stack = {} }; |
| 3118 | } |
| 3119 | |
| 3099 | 3120 | fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3100 | 3121 | const ty_pl = func.air.instructions.items(.data)[inst].ty_pl; |
| 3101 | 3122 | const extra = func.air.extraData(Air.StructField, ty_pl.payload); |