| ... | @@ -5084,16 +5084,32 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal | ... | @@ -5084,16 +5084,32 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal |
| 5084 | } else operand; | 5084 | } else operand; |
| 5085 | | 5085 | |
| 5086 | const local = try f.allocLocal(null, dest_ty); | 5086 | const local = try f.allocLocal(null, dest_ty); |
| 5087 | try w.writeAll("memcpy(&"); | 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 | try f.writeCValue(w, local, .Other); | 5088 | // We need to offset the source or destination pointer appropriately and copy the right number of bytes. |
| 5089 | try w.writeAll(", &"); | 5089 | if (target.cpu.arch.endian() == .big and dest_ty.isAbiInt(zcu) and !operand_ty.isAbiInt(zcu)) { |
| 5090 | try f.writeCValue(w, operand_lval, .Other); | 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 | try w.writeAll(", sizeof("); | 5091 | const offset = dest_ty.abiSize(zcu) - operand_ty.abiSize(zcu); |
| 5092 | try f.renderType( | 5092 | try w.writeAll("memcpy((char *)&"); |
| 5093 | w, | 5093 | try f.writeCValue(w, local, .Other); |
| 5094 | if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty, | 5094 | try w.print(" + {d}, &", .{offset}); |
| 5095 | ); | 5095 | try f.writeCValue(w, operand_lval, .Other); |
| 5096 | try w.writeAll("));"); | 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 | try f.object.newline(); | 5113 | try f.object.newline(); |
| 5098 | | 5114 | |
| 5099 | // Ensure padding bits have the expected value. | 5115 | // Ensure padding bits have the expected value. |