| ... | @@ -3201,14 +3201,23 @@ pub const FuncGen = struct { | ... | @@ -3201,14 +3201,23 @@ pub const FuncGen = struct { |
| 3201 | const operand = try self.resolveInst(ty_op.operand); | 3201 | const operand = try self.resolveInst(ty_op.operand); |
| 3202 | const operand_ty = self.air.typeOf(ty_op.operand); | 3202 | const operand_ty = self.air.typeOf(ty_op.operand); |
| 3203 | const inst_ty = self.air.typeOfIndex(inst); | 3203 | const inst_ty = self.air.typeOfIndex(inst); |
| | 3204 | const operand_is_ref = isByRef(operand_ty); |
| | 3205 | const result_is_ref = isByRef(inst_ty); |
| 3204 | const llvm_dest_ty = try self.dg.llvmType(inst_ty); | 3206 | const llvm_dest_ty = try self.dg.llvmType(inst_ty); |
| 3205 | | 3207 | |
| | 3208 | if (operand_is_ref and result_is_ref) { |
| | 3209 | // They are both pointers; just do a bitcast on the pointers :) |
| | 3210 | return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), ""); |
| | 3211 | } |
| | 3212 | |
| 3206 | if (operand_ty.zigTypeTag() == .Int and inst_ty.zigTypeTag() == .Pointer) { | 3213 | if (operand_ty.zigTypeTag() == .Int and inst_ty.zigTypeTag() == .Pointer) { |
| 3207 | return self.builder.buildIntToPtr(operand, llvm_dest_ty, ""); | 3214 | return self.builder.buildIntToPtr(operand, llvm_dest_ty, ""); |
| 3208 | } else if (operand_ty.zigTypeTag() == .Vector and inst_ty.zigTypeTag() == .Array) { | 3215 | } |
| | 3216 | |
| | 3217 | if (operand_ty.zigTypeTag() == .Vector and inst_ty.zigTypeTag() == .Array) { |
| 3209 | const target = self.dg.module.getTarget(); | 3218 | const target = self.dg.module.getTarget(); |
| 3210 | const elem_ty = operand_ty.childType(); | 3219 | const elem_ty = operand_ty.childType(); |
| 3211 | if (!isByRef(inst_ty)) { | 3220 | if (!result_is_ref) { |
| 3212 | return self.dg.todo("implement bitcast vector to non-ref array", .{}); | 3221 | return self.dg.todo("implement bitcast vector to non-ref array", .{}); |
| 3213 | } | 3222 | } |
| 3214 | const array_ptr = self.buildAlloca(llvm_dest_ty); | 3223 | const array_ptr = self.buildAlloca(llvm_dest_ty); |
| ... | @@ -3239,7 +3248,7 @@ pub const FuncGen = struct { | ... | @@ -3239,7 +3248,7 @@ pub const FuncGen = struct { |
| 3239 | const target = self.dg.module.getTarget(); | 3248 | const target = self.dg.module.getTarget(); |
| 3240 | const elem_ty = operand_ty.childType(); | 3249 | const elem_ty = operand_ty.childType(); |
| 3241 | const llvm_vector_ty = try self.dg.llvmType(inst_ty); | 3250 | const llvm_vector_ty = try self.dg.llvmType(inst_ty); |
| 3242 | if (!isByRef(operand_ty)) { | 3251 | if (!operand_is_ref) { |
| 3243 | return self.dg.todo("implement bitcast non-ref array to vector", .{}); | 3252 | return self.dg.todo("implement bitcast non-ref array to vector", .{}); |
| 3244 | } | 3253 | } |
| 3245 | | 3254 | |
| ... | @@ -3274,6 +3283,21 @@ pub const FuncGen = struct { | ... | @@ -3274,6 +3283,21 @@ pub const FuncGen = struct { |
| 3274 | } | 3283 | } |
| 3275 | } | 3284 | } |
| 3276 | | 3285 | |
| | 3286 | if (operand_is_ref) { |
| | 3287 | // Bitcast the operand pointer, then load. |
| | 3288 | const casted_ptr = self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), ""); |
| | 3289 | return self.builder.buildLoad(casted_ptr, ""); |
| | 3290 | } |
| | 3291 | |
| | 3292 | if (result_is_ref) { |
| | 3293 | // Bitcast the result pointer, then store. |
| | 3294 | const result_ptr = self.buildAlloca(llvm_dest_ty); |
| | 3295 | const operand_llvm_ty = try self.dg.llvmType(operand_ty); |
| | 3296 | const casted_ptr = self.builder.buildBitCast(result_ptr, operand_llvm_ty.pointerType(0), ""); |
| | 3297 | _ = self.builder.buildStore(operand, casted_ptr); |
| | 3298 | return result_ptr; |
| | 3299 | } |
| | 3300 | |
| 3277 | return self.builder.buildBitCast(operand, llvm_dest_ty, ""); | 3301 | return self.builder.buildBitCast(operand, llvm_dest_ty, ""); |
| 3278 | } | 3302 | } |
| 3279 | | 3303 | |