mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 08:33:06 +00:00
stage2: partially implement intcast on x86_64
* fix violating encoding invariant for memory encoding * enable some cast tests for x86_64 and arm
This commit is contained in:
parent
aaa641feba
commit
8c233687b4
@ -877,10 +877,26 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
|
||||
if (info_a.signedness != info_b.signedness)
|
||||
return self.fail("TODO gen intcast sign safety in semantic analysis", .{});
|
||||
|
||||
if (info_a.bits == info_b.bits)
|
||||
return self.finishAir(inst, operand, .{ ty_op.operand, .none, .none });
|
||||
const operand_abi_size = operand_ty.abiSize(self.target.*);
|
||||
const dest_ty = self.air.typeOfIndex(inst);
|
||||
const dest_abi_size = dest_ty.abiSize(self.target.*);
|
||||
const dst_mcv: MCValue = blk: {
|
||||
if (info_a.bits == info_b.bits) {
|
||||
break :blk operand;
|
||||
}
|
||||
if (operand_abi_size > 8 or dest_abi_size > 8) {
|
||||
return self.fail("TODO implement intCast for abi sizes larger than 8", .{});
|
||||
}
|
||||
const reg = switch (operand) {
|
||||
.register => |src_reg| try self.register_manager.allocReg(inst, &.{src_reg}),
|
||||
else => try self.register_manager.allocReg(inst, &.{}),
|
||||
};
|
||||
try self.genSetReg(dest_ty, reg, .{ .immediate = 0 });
|
||||
try self.genSetReg(dest_ty, reg, operand);
|
||||
break :blk .{ .register = registerAlias(reg, @intCast(u32, dest_abi_size)) };
|
||||
};
|
||||
|
||||
return self.fail("TODO implement intCast for {}", .{self.target.cpu.arch});
|
||||
return self.finishAir(inst, dst_mcv, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
|
||||
|
@ -1320,7 +1320,7 @@ const Memory = struct {
|
||||
encoder.disp32(@bitCast(i32, mem_op.disp));
|
||||
}
|
||||
} else {
|
||||
if (mem_op.disp == 0) {
|
||||
if (mem_op.disp == 0 and dst != 5) {
|
||||
encoder.modRm_indirectDisp0(src, dst);
|
||||
} else if (immOpSize(mem_op.disp) == 8) {
|
||||
encoder.modRm_indirectDisp8(src, dst);
|
||||
|
@ -18,6 +18,7 @@ test {
|
||||
_ = @import("behavior/bool.zig");
|
||||
_ = @import("behavior/align.zig");
|
||||
_ = @import("behavior/array.zig");
|
||||
_ = @import("behavior/cast.zig");
|
||||
|
||||
if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64) {
|
||||
// Tests that pass for stage1, llvm backend, C backend, wasm backend.
|
||||
@ -36,7 +37,6 @@ test {
|
||||
_ = @import("behavior/bugs/4954.zig");
|
||||
_ = @import("behavior/byval_arg_var.zig");
|
||||
_ = @import("behavior/call.zig");
|
||||
_ = @import("behavior/cast.zig");
|
||||
_ = @import("behavior/defer.zig");
|
||||
_ = @import("behavior/enum.zig");
|
||||
_ = @import("behavior/error.zig");
|
||||
|
@ -5,6 +5,8 @@ const maxInt = std.math.maxInt;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
test "int to ptr cast" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
|
||||
const x = @as(usize, 13);
|
||||
const y = @intToPtr(*u8, x);
|
||||
const z = @ptrToInt(y);
|
||||
@ -12,11 +14,15 @@ test "int to ptr cast" {
|
||||
}
|
||||
|
||||
test "integer literal to pointer cast" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
|
||||
const vga_mem = @intToPtr(*u16, 0xB8000);
|
||||
try expect(@ptrToInt(vga_mem) == 0xB8000);
|
||||
}
|
||||
|
||||
test "peer type resolution: ?T and T" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
try expect(peerTypeTAndOptionalT(true, false).? == 0);
|
||||
try expect(peerTypeTAndOptionalT(false, false).? == 3);
|
||||
comptime {
|
||||
@ -33,6 +39,8 @@ fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
|
||||
}
|
||||
|
||||
test "resolve undefined with integer" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
try testResolveUndefWithInt(true, 1234);
|
||||
comptime try testResolveUndefWithInt(true, 1234);
|
||||
}
|
||||
@ -88,6 +96,8 @@ test "comptime_int @intToFloat" {
|
||||
}
|
||||
|
||||
test "@floatToInt" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
try testFloatToInts();
|
||||
comptime try testFloatToInts();
|
||||
}
|
||||
@ -107,6 +117,8 @@ fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
|
||||
}
|
||||
|
||||
test "implicitly cast indirect pointer to maybe-indirect pointer" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
const Self = @This();
|
||||
x: u8,
|
||||
@ -163,6 +175,8 @@ test "@floatCast comptime_int and comptime_float" {
|
||||
}
|
||||
|
||||
test "coerce undefined to optional" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
try expect(MakeType(void).getNull() == null);
|
||||
try expect(MakeType(void).getNonNull() != null);
|
||||
}
|
||||
@ -180,6 +194,8 @@ fn MakeType(comptime T: type) type {
|
||||
}
|
||||
|
||||
test "implicit cast from *[N]T to [*c]T" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
var x: [4]u16 = [4]u16{ 0, 1, 2, 3 };
|
||||
var y: [*c]u16 = &x;
|
||||
|
||||
@ -190,6 +206,8 @@ test "implicit cast from *[N]T to [*c]T" {
|
||||
}
|
||||
|
||||
test "*usize to *void" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
var i = @as(usize, 0);
|
||||
var v = @ptrCast(*void, &i);
|
||||
v.* = {};
|
||||
@ -202,6 +220,8 @@ test "@intToEnum passed a comptime_int to an enum with one item" {
|
||||
}
|
||||
|
||||
test "@intCast to u0 and use the result" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest(zero: u1, one: u1, bigzero: i32) !void {
|
||||
try expect((one << @intCast(u0, bigzero)) == 1);
|
||||
@ -213,6 +233,8 @@ test "@intCast to u0 and use the result" {
|
||||
}
|
||||
|
||||
test "peer result null and comptime_int" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn blah(n: i32) ?i32 {
|
||||
if (n == 0) {
|
||||
@ -234,6 +256,8 @@ test "peer result null and comptime_int" {
|
||||
}
|
||||
|
||||
test "*const ?[*]const T to [*c]const [*c]const T" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
var array = [_]u8{ 'o', 'k' };
|
||||
const opt_array_ptr: ?[*]const u8 = &array;
|
||||
const a: *const ?[*]const u8 = &opt_array_ptr;
|
||||
@ -243,6 +267,8 @@ test "*const ?[*]const T to [*c]const [*c]const T" {
|
||||
}
|
||||
|
||||
test "array coersion to undefined at runtime" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
@setRuntimeSafety(true);
|
||||
|
||||
// TODO implement @setRuntimeSafety in stage2
|
||||
@ -270,6 +296,8 @@ fn implicitIntLitToOptional() void {
|
||||
}
|
||||
|
||||
test "return u8 coercing into ?u32 return type" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
try expect(foo(123).? == 123);
|
||||
@ -288,6 +316,8 @@ test "cast from ?[*]T to ??[*]T" {
|
||||
}
|
||||
|
||||
test "peer type unsigned int to signed" {
|
||||
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
var w: u31 = 5;
|
||||
var x: u8 = 7;
|
||||
var y: i32 = -5;
|
||||
|
Loading…
Reference in New Issue
Block a user