| ... | ... | @@ -5084,16 +5084,32 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal |
| 5084 | 5084 | } else operand; |
| 5085 | 5085 | |
| 5086 | 5086 | const local = try f.allocLocal(null, dest_ty); |
| 5087 | | try w.writeAll("memcpy(&"); |
| 5088 | | try f.writeCValue(w, local, .Other); |
| 5089 | | try w.writeAll(", &"); |
| 5090 | | try f.writeCValue(w, operand_lval, .Other); |
| 5091 | | try w.writeAll(", sizeof("); |
| 5092 | | try f.renderType( |
| 5093 | | w, |
| 5094 | | if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty, |
| 5095 | | ); |
| 5096 | | try w.writeAll("));"); |
| 5087 | // On big-endian targets, copying ABI integers with padding bits is awkward, because the padding bits are at the low bytes of the value. |
| 5088 | // We need to offset the source or destination pointer appropriately and copy the right number of bytes. |
| 5089 | if (target.cpu.arch.endian() == .big and dest_ty.isAbiInt(zcu) and !operand_ty.isAbiInt(zcu)) { |
| 5090 | // e.g. [10]u8 -> u80. We need to offset the destination so that we copy to the least significant bits of the integer. |
| 5091 | const offset = dest_ty.abiSize(zcu) - operand_ty.abiSize(zcu); |
| 5092 | try w.writeAll("memcpy((char *)&"); |
| 5093 | try f.writeCValue(w, local, .Other); |
| 5094 | try w.print(" + {d}, &", .{offset}); |
| 5095 | try f.writeCValue(w, operand_lval, .Other); |
| 5096 | try w.print(", {d});", .{operand_ty.abiSize(zcu)}); |
| 5097 | } else if (target.cpu.arch.endian() == .big and operand_ty.isAbiInt(zcu) and !dest_ty.isAbiInt(zcu)) { |
| 5098 | // e.g. u80 -> [10]u8. We need to offset the source so that we copy from the least significant bits of the integer. |
| 5099 | const offset = operand_ty.abiSize(zcu) - dest_ty.abiSize(zcu); |
| 5100 | try w.writeAll("memcpy(&"); |
| 5101 | try f.writeCValue(w, local, .Other); |
| 5102 | try w.writeAll(", (const char *)&"); |
| 5103 | try f.writeCValue(w, operand_lval, .Other); |
| 5104 | try w.print(" + {d}, {d});", .{ offset, dest_ty.abiSize(zcu) }); |
| 5105 | } else { |
| 5106 | try w.writeAll("memcpy(&"); |
| 5107 | try f.writeCValue(w, local, .Other); |
| 5108 | try w.writeAll(", &"); |
| 5109 | try f.writeCValue(w, operand_lval, .Other); |
| 5110 | try w.print(", {d});", .{@min(dest_ty.abiSize(zcu), operand_ty.abiSize(zcu))}); |
| 5111 | } |
| 5112 | |
| 5097 | 5113 | try f.object.newline(); |
| 5098 | 5114 | |
| 5099 | 5115 | // Ensure padding bits have the expected value. |