| ... | @@ -3465,34 +3465,40 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3465,34 +3465,40 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3465 | const operand = try f.resolveInst(ty_op.operand); | 3465 | const operand = try f.resolveInst(ty_op.operand); |
| 3466 | try reap(f, inst, &.{ty_op.operand}); | 3466 | try reap(f, inst, &.{ty_op.operand}); |
| 3467 | const inst_ty = f.air.typeOfIndex(inst); | 3467 | const inst_ty = f.air.typeOfIndex(inst); |
| 3468 | const writer = f.object.writer(); | 3468 | const inst_scalar_ty = inst_ty.scalarType(); |
| 3469 | const local = try f.allocLocal(inst, inst_ty); | | |
| 3470 | const target = f.object.dg.module.getTarget(); | 3469 | const target = f.object.dg.module.getTarget(); |
| 3471 | const dest_int_info = inst_ty.intInfo(target); | 3470 | const dest_int_info = inst_scalar_ty.intInfo(target); |
| 3472 | const dest_bits = dest_int_info.bits; | 3471 | const dest_bits = dest_int_info.bits; |
| 3473 | const dest_c_bits = toCIntBits(dest_int_info.bits) orelse | 3472 | const dest_c_bits = toCIntBits(dest_int_info.bits) orelse |
| 3474 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | 3473 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); |
| 3475 | const operand_ty = f.air.typeOf(ty_op.operand); | 3474 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 3476 | const operand_int_info = operand_ty.intInfo(target); | 3475 | const scalar_ty = operand_ty.scalarType(); |
| | 3476 | const scalar_int_info = scalar_ty.intInfo(target); |
| | 3477 | |
| | 3478 | const writer = f.object.writer(); |
| | 3479 | const local = try f.allocLocal(inst, inst_ty); |
| | 3480 | const v = try Vectorizer.start(f, inst, writer, operand_ty); |
| 3477 | | 3481 | |
| 3478 | try f.writeCValue(writer, local, .Other); | 3482 | try f.writeCValue(writer, local, .Other); |
| | 3483 | try v.elem(f, writer); |
| 3479 | try writer.writeAll(" = "); | 3484 | try writer.writeAll(" = "); |
| 3480 | | 3485 | |
| 3481 | if (dest_c_bits < 64) { | 3486 | if (dest_c_bits < 64) { |
| 3482 | try writer.writeByte('('); | 3487 | try writer.writeByte('('); |
| 3483 | try f.renderType(writer, inst_ty); | 3488 | try f.renderType(writer, inst_scalar_ty); |
| 3484 | try writer.writeByte(')'); | 3489 | try writer.writeByte(')'); |
| 3485 | } | 3490 | } |
| 3486 | | 3491 | |
| 3487 | const needs_lo = operand_int_info.bits > 64 and dest_bits <= 64; | 3492 | const needs_lo = scalar_int_info.bits > 64 and dest_bits <= 64; |
| 3488 | if (needs_lo) { | 3493 | if (needs_lo) { |
| 3489 | try writer.writeAll("zig_lo_"); | 3494 | try writer.writeAll("zig_lo_"); |
| 3490 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | 3495 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); |
| 3491 | try writer.writeByte('('); | 3496 | try writer.writeByte('('); |
| 3492 | } | 3497 | } |
| 3493 | | 3498 | |
| 3494 | if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) { | 3499 | if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) { |
| 3495 | try f.writeCValue(writer, operand, .Other); | 3500 | try f.writeCValue(writer, operand, .Other); |
| | 3501 | try v.elem(f, writer); |
| 3496 | } else switch (dest_int_info.signedness) { | 3502 | } else switch (dest_int_info.signedness) { |
| 3497 | .unsigned => { | 3503 | .unsigned => { |
| 3498 | var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa); | 3504 | var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa); |
| ... | @@ -3502,15 +3508,16 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3502,15 +3508,16 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3502 | var stack align(@alignOf(ExpectedContents)) = | 3508 | var stack align(@alignOf(ExpectedContents)) = |
| 3503 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); | 3509 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); |
| 3504 | | 3510 | |
| 3505 | const mask_val = try inst_ty.maxInt(stack.get(), target); | 3511 | const mask_val = try inst_scalar_ty.maxInt(stack.get(), target); |
| 3506 | try writer.writeAll("zig_and_"); | 3512 | try writer.writeAll("zig_and_"); |
| 3507 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | 3513 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); |
| 3508 | try writer.writeByte('('); | 3514 | try writer.writeByte('('); |
| 3509 | try f.writeCValue(writer, operand, .FunctionArgument); | 3515 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 3510 | try writer.print(", {x})", .{try f.fmtIntLiteral(operand_ty, mask_val)}); | 3516 | try v.elem(f, writer); |
| | 3517 | try writer.print(", {x})", .{try f.fmtIntLiteral(scalar_ty, mask_val)}); |
| 3511 | }, | 3518 | }, |
| 3512 | .signed => { | 3519 | .signed => { |
| 3513 | const c_bits = toCIntBits(operand_int_info.bits) orelse | 3520 | const c_bits = toCIntBits(scalar_int_info.bits) orelse |
| 3514 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | 3521 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); |
| 3515 | var shift_pl = Value.Payload.U64{ | 3522 | var shift_pl = Value.Payload.U64{ |
| 3516 | .base = .{ .tag = .int_u64 }, | 3523 | .base = .{ .tag = .int_u64 }, |
| ... | @@ -3519,7 +3526,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3519,7 +3526,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3519 | const shift_val = Value.initPayload(&shift_pl.base); | 3526 | const shift_val = Value.initPayload(&shift_pl.base); |
| 3520 | | 3527 | |
| 3521 | try writer.writeAll("zig_shr_"); | 3528 | try writer.writeAll("zig_shr_"); |
| 3522 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | 3529 | try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty); |
| 3523 | if (c_bits == 128) { | 3530 | if (c_bits == 128) { |
| 3524 | try writer.print("(zig_bitcast_i{d}(", .{c_bits}); | 3531 | try writer.print("(zig_bitcast_i{d}(", .{c_bits}); |
| 3525 | } else { | 3532 | } else { |
| ... | @@ -3532,6 +3539,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3532,6 +3539,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3532 | try writer.print("(uint{d}_t)", .{c_bits}); | 3539 | try writer.print("(uint{d}_t)", .{c_bits}); |
| 3533 | } | 3540 | } |
| 3534 | try f.writeCValue(writer, operand, .FunctionArgument); | 3541 | try f.writeCValue(writer, operand, .FunctionArgument); |
| | 3542 | try v.elem(f, writer); |
| 3535 | if (c_bits == 128) try writer.writeByte(')'); | 3543 | if (c_bits == 128) try writer.writeByte(')'); |
| 3536 | try writer.print(", {})", .{try f.fmtIntLiteral(Type.u8, shift_val)}); | 3544 | try writer.print(", {})", .{try f.fmtIntLiteral(Type.u8, shift_val)}); |
| 3537 | if (c_bits == 128) try writer.writeByte(')'); | 3545 | if (c_bits == 128) try writer.writeByte(')'); |
| ... | @@ -3541,6 +3549,8 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3541,6 +3549,8 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3541 | | 3549 | |
| 3542 | if (needs_lo) try writer.writeByte(')'); | 3550 | if (needs_lo) try writer.writeByte(')'); |
| 3543 | try writer.writeAll(";\n"); | 3551 | try writer.writeAll(";\n"); |
| | 3552 | try v.end(f, inst, writer); |
| | 3553 | |
| 3544 | return local; | 3554 | return local; |
| 3545 | } | 3555 | } |
| 3546 | | 3556 | |