Merge pull request #11192 from joachimschmidt557/stage2-arm
stage2 ARM: misc improvements
This commit is contained in:
@@ -530,13 +530,13 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
switch (air_tags[inst]) {
|
||||
// zig fmt: off
|
||||
.add, .ptr_add => try self.airBinOp(inst),
|
||||
.addwrap => try self.airAddWrap(inst),
|
||||
.addwrap => try self.airBinOp(inst),
|
||||
.add_sat => try self.airAddSat(inst),
|
||||
.sub, .ptr_sub => try self.airBinOp(inst),
|
||||
.subwrap => try self.airSubWrap(inst),
|
||||
.subwrap => try self.airBinOp(inst),
|
||||
.sub_sat => try self.airSubSat(inst),
|
||||
.mul => try self.airBinOp(inst),
|
||||
.mulwrap => try self.airMulWrap(inst),
|
||||
.mulwrap => try self.airBinOp(inst),
|
||||
.mul_sat => try self.airMulSat(inst),
|
||||
.rem => try self.airRem(inst),
|
||||
.mod => try self.airMod(inst),
|
||||
@@ -939,63 +939,85 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
|
||||
// return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
fn truncRegister(
|
||||
self: *Self,
|
||||
operand_reg: Register,
|
||||
dest_reg: Register,
|
||||
int_signedness: std.builtin.Signedness,
|
||||
int_bits: u16,
|
||||
) !void {
|
||||
// TODO check if sxtb/uxtb/sxth/uxth are more efficient
|
||||
_ = try self.addInst(.{
|
||||
.tag = switch (int_signedness) {
|
||||
.signed => .sbfx,
|
||||
.unsigned => .ubfx,
|
||||
},
|
||||
.data = .{ .rr_lsb_width = .{
|
||||
.rd = dest_reg,
|
||||
.rn = operand_reg,
|
||||
.lsb = 0,
|
||||
.width = @intCast(u6, int_bits),
|
||||
} },
|
||||
});
|
||||
}
|
||||
|
||||
fn trunc(
|
||||
self: *Self,
|
||||
maybe_inst: ?Air.Inst.Index,
|
||||
operand: MCValue,
|
||||
operand_ty: Type,
|
||||
dest_ty: Type,
|
||||
) !MCValue {
|
||||
const info_a = operand_ty.intInfo(self.target.*);
|
||||
const info_b = dest_ty.intInfo(self.target.*);
|
||||
|
||||
if (info_b.bits <= 32) {
|
||||
const operand_reg = switch (operand) {
|
||||
.register => |r| r,
|
||||
else => operand_reg: {
|
||||
if (info_a.bits <= 32) {
|
||||
break :operand_reg try self.copyToTmpRegister(operand_ty, operand);
|
||||
} else {
|
||||
return self.fail("TODO load least significant word into register", .{});
|
||||
}
|
||||
},
|
||||
};
|
||||
self.register_manager.freezeRegs(&.{operand_reg});
|
||||
defer self.register_manager.unfreezeRegs(&.{operand_reg});
|
||||
|
||||
const dest_reg = if (maybe_inst) |inst| blk: {
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
|
||||
if (operand == .register and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
|
||||
break :blk operand_reg;
|
||||
} else {
|
||||
break :blk try self.register_manager.allocReg(inst);
|
||||
}
|
||||
} else try self.register_manager.allocReg(null);
|
||||
|
||||
switch (info_b.bits) {
|
||||
32 => {
|
||||
try self.genSetReg(operand_ty, dest_reg, .{ .register = operand_reg });
|
||||
return MCValue{ .register = dest_reg };
|
||||
},
|
||||
else => {
|
||||
try self.truncRegister(operand_reg, dest_reg, info_b.signedness, info_b.bits);
|
||||
return MCValue{ .register = dest_reg };
|
||||
},
|
||||
}
|
||||
} else {
|
||||
return self.fail("TODO: truncate to ints > 32 bits", .{});
|
||||
}
|
||||
}
|
||||
|
||||
fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
if (self.liveness.isUnused(inst))
|
||||
return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
|
||||
|
||||
const operand_ty = self.air.typeOf(ty_op.operand);
|
||||
const operand = try self.resolveInst(ty_op.operand);
|
||||
const info_a = operand_ty.intInfo(self.target.*);
|
||||
const info_b = self.air.typeOfIndex(inst).intInfo(self.target.*);
|
||||
const operand_ty = self.air.typeOf(ty_op.operand);
|
||||
const dest_ty = self.air.typeOfIndex(inst);
|
||||
|
||||
const result: MCValue = blk: {
|
||||
if (info_b.bits <= 32) {
|
||||
const operand_reg = switch (operand) {
|
||||
.register => |r| r,
|
||||
else => operand_reg: {
|
||||
if (info_a.bits <= 32) {
|
||||
break :operand_reg try self.copyToTmpRegister(operand_ty, operand);
|
||||
} else {
|
||||
return self.fail("TODO load least significant word into register", .{});
|
||||
}
|
||||
},
|
||||
};
|
||||
self.register_manager.freezeRegs(&.{operand_reg});
|
||||
defer self.register_manager.unfreezeRegs(&.{operand_reg});
|
||||
|
||||
const dest_reg = dest_reg: {
|
||||
if (operand == .register and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
|
||||
break :dest_reg operand_reg;
|
||||
}
|
||||
|
||||
break :dest_reg try self.register_manager.allocReg(null);
|
||||
};
|
||||
|
||||
switch (info_b.bits) {
|
||||
32 => {
|
||||
try self.genSetReg(operand_ty, dest_reg, .{ .register = operand_reg });
|
||||
break :blk MCValue{ .register = dest_reg };
|
||||
},
|
||||
else => {
|
||||
_ = try self.addInst(.{
|
||||
.tag = switch (info_b.signedness) {
|
||||
.signed => .sbfx,
|
||||
.unsigned => .ubfx,
|
||||
},
|
||||
.data = .{ .rr_lsb_width = .{
|
||||
.rd = dest_reg,
|
||||
.rn = operand_reg,
|
||||
.lsb = 0,
|
||||
.width = @intCast(u6, info_b.bits),
|
||||
} },
|
||||
});
|
||||
break :blk MCValue{ .register = dest_reg };
|
||||
},
|
||||
}
|
||||
} else {
|
||||
return self.fail("TODO: truncate to ints > 32 bits", .{});
|
||||
}
|
||||
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
|
||||
break :blk try self.trunc(inst, operand, operand_ty, dest_ty);
|
||||
};
|
||||
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
@@ -1099,6 +1121,10 @@ fn airNot(self: *Self, inst: Air.Inst.Index) !void {
|
||||
} },
|
||||
});
|
||||
|
||||
if (int_info.bits < 32) {
|
||||
try self.truncRegister(dest_reg, dest_reg, int_info.signedness, int_info.bits);
|
||||
}
|
||||
|
||||
break :result MCValue{ .register = dest_reg };
|
||||
} else {
|
||||
return self.fail("TODO ARM not on integers > u32/i32", .{});
|
||||
@@ -1957,8 +1983,8 @@ fn binOpRegister(
|
||||
if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs);
|
||||
|
||||
const mir_tag: Mir.Inst.Tag = switch (tag) {
|
||||
.add, .ptr_add => .add,
|
||||
.sub, .ptr_sub => .sub,
|
||||
.add => .add,
|
||||
.sub => .sub,
|
||||
.cmp_eq => .cmp,
|
||||
.mul => .mul,
|
||||
.bit_and,
|
||||
@@ -1967,12 +1993,8 @@ fn binOpRegister(
|
||||
.bit_or,
|
||||
.bool_or,
|
||||
=> .orr,
|
||||
.shl,
|
||||
.shl_exact,
|
||||
=> .lsl,
|
||||
.shr,
|
||||
.shr_exact,
|
||||
=> switch (lhs_ty.intInfo(self.target.*).signedness) {
|
||||
.shl_exact => .lsl,
|
||||
.shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) {
|
||||
.signed => Mir.Inst.Tag.asr,
|
||||
.unsigned => Mir.Inst.Tag.lsr,
|
||||
},
|
||||
@@ -1988,16 +2010,12 @@ fn binOpRegister(
|
||||
.bit_or,
|
||||
.bool_or,
|
||||
.xor,
|
||||
.ptr_add,
|
||||
.ptr_sub,
|
||||
=> .{ .rr_op = .{
|
||||
.rd = dest_reg,
|
||||
.rn = lhs_reg,
|
||||
.op = Instruction.Operand.reg(rhs_reg, Instruction.Operand.Shift.none),
|
||||
} },
|
||||
.shl,
|
||||
.shl_exact,
|
||||
.shr,
|
||||
.shr_exact,
|
||||
=> .{ .rr_shift = .{
|
||||
.rd = dest_reg,
|
||||
@@ -2094,12 +2112,8 @@ fn binOpImmediate(
|
||||
.bit_or,
|
||||
.bool_or,
|
||||
=> .orr,
|
||||
.shl,
|
||||
.shl_exact,
|
||||
=> .lsl,
|
||||
.shr,
|
||||
.shr_exact,
|
||||
=> switch (lhs_ty.intInfo(self.target.*).signedness) {
|
||||
.shl_exact => .lsl,
|
||||
.shr_exact => switch (lhs_ty.intInfo(self.target.*).signedness) {
|
||||
.signed => Mir.Inst.Tag.asr,
|
||||
.unsigned => Mir.Inst.Tag.lsr,
|
||||
},
|
||||
@@ -2120,9 +2134,7 @@ fn binOpImmediate(
|
||||
.rn = lhs_reg,
|
||||
.op = Instruction.Operand.fromU32(rhs.immediate).?,
|
||||
} },
|
||||
.shl,
|
||||
.shl_exact,
|
||||
.shr,
|
||||
.shr_exact,
|
||||
=> .{ .rr_shift = .{
|
||||
.rd = dest_reg,
|
||||
@@ -2225,6 +2237,39 @@ fn binOp(
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
.addwrap,
|
||||
.subwrap,
|
||||
.mulwrap,
|
||||
=> {
|
||||
const base_tag: Air.Inst.Tag = switch (tag) {
|
||||
.addwrap => .add,
|
||||
.subwrap => .sub,
|
||||
.mulwrap => .mul,
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
// Generate an add/sub/mul
|
||||
const result = try self.binOp(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
|
||||
|
||||
// Truncate if necessary
|
||||
switch (lhs_ty.zigTypeTag()) {
|
||||
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
|
||||
.Int => {
|
||||
const int_info = lhs_ty.intInfo(self.target.*);
|
||||
if (int_info.bits <= 32) {
|
||||
const result_reg = result.register;
|
||||
|
||||
if (int_info.bits < 32) {
|
||||
try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
|
||||
return result;
|
||||
} else return result;
|
||||
} else {
|
||||
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
.bit_and,
|
||||
.bit_or,
|
||||
.xor,
|
||||
@@ -2253,8 +2298,8 @@ fn binOp(
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
.shl,
|
||||
.shr,
|
||||
.shl_exact,
|
||||
.shr_exact,
|
||||
=> {
|
||||
switch (lhs_ty.zigTypeTag()) {
|
||||
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
|
||||
@@ -2275,6 +2320,41 @@ fn binOp(
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
.shl,
|
||||
.shr,
|
||||
=> {
|
||||
const base_tag: Air.Inst.Tag = switch (tag) {
|
||||
.shl => .shl_exact,
|
||||
.shr => .shr_exact,
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
// Generate a shl_exact/shr_exact
|
||||
const result = try self.binOp(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
|
||||
|
||||
// Truncate if necessary
|
||||
switch (tag) {
|
||||
.shr => return result,
|
||||
.shl => switch (lhs_ty.zigTypeTag()) {
|
||||
.Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
|
||||
.Int => {
|
||||
const int_info = lhs_ty.intInfo(self.target.*);
|
||||
if (int_info.bits <= 32) {
|
||||
const result_reg = result.register;
|
||||
|
||||
if (int_info.bits < 32) {
|
||||
try self.truncRegister(result_reg, result_reg, int_info.signedness, int_info.bits);
|
||||
return result;
|
||||
} else return result;
|
||||
} else {
|
||||
return self.fail("TODO ARM binary operations on integers > u32/i32", .{});
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
},
|
||||
.bool_and,
|
||||
.bool_or,
|
||||
=> {
|
||||
@@ -2308,7 +2388,13 @@ fn binOp(
|
||||
const elem_size = @intCast(u32, elem_ty.abiSize(self.target.*));
|
||||
|
||||
if (elem_size == 1) {
|
||||
return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
|
||||
const base_tag: Air.Inst.Tag = switch (tag) {
|
||||
.ptr_add => .add,
|
||||
.ptr_sub => .sub,
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
return try self.binOpRegister(base_tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty);
|
||||
} else {
|
||||
// convert the offset into a byte offset by
|
||||
// multiplying it with elem_size
|
||||
@@ -2876,7 +2962,12 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const condition = Condition.fromCompareOperatorUnsigned(cmp_op);
|
||||
break :blk condition.negate();
|
||||
},
|
||||
.register => |reg| blk: {
|
||||
else => blk: {
|
||||
const reg = switch (cond) {
|
||||
.register => |r| r,
|
||||
else => try self.copyToTmpRegister(Type.bool, cond),
|
||||
};
|
||||
|
||||
try self.spillCompareFlagsIfOccupied();
|
||||
|
||||
// cmp reg, 1
|
||||
@@ -2893,28 +2984,6 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
|
||||
break :blk .ne;
|
||||
},
|
||||
.stack_offset,
|
||||
.memory,
|
||||
.stack_argument_offset,
|
||||
=> blk: {
|
||||
try self.spillCompareFlagsIfOccupied();
|
||||
|
||||
const reg = try self.copyToTmpRegister(Type.initTag(.bool), cond);
|
||||
|
||||
// cmp reg, 1
|
||||
// bne ...
|
||||
_ = try self.addInst(.{
|
||||
.tag = .cmp,
|
||||
.data = .{ .rr_op = .{
|
||||
.rd = .r0,
|
||||
.rn = reg,
|
||||
.op = Instruction.Operand.imm(1, 0),
|
||||
} },
|
||||
});
|
||||
|
||||
break :blk .ne;
|
||||
},
|
||||
else => return self.fail("TODO implement condbr {} when condition is {s}", .{ self.target.cpu.arch, @tagName(cond) }),
|
||||
};
|
||||
|
||||
break :reloc try self.addInst(.{
|
||||
@@ -3603,9 +3672,18 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
|
||||
try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off });
|
||||
},
|
||||
.memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }),
|
||||
.embedded_in_code,
|
||||
.stack_argument_offset,
|
||||
=> return self.fail("TODO genSetStack with src={}", .{mcv}),
|
||||
.stack_argument_offset => |unadjusted_off| {
|
||||
const adj_off = unadjusted_off + abi_size;
|
||||
|
||||
_ = try self.addInst(.{
|
||||
.tag = .ldr_ptr_stack_argument,
|
||||
.data = .{ .r_stack_offset = .{
|
||||
.rt = src_reg,
|
||||
.stack_offset = adj_off,
|
||||
} },
|
||||
});
|
||||
},
|
||||
.embedded_in_code => return self.fail("TODO genSetStack with src={}", .{mcv}),
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ pub fn emitMir(
|
||||
.str => try emit.mirLoadStore(inst),
|
||||
.strb => try emit.mirLoadStore(inst),
|
||||
|
||||
.ldr_ptr_stack_argument => try emit.mirLoadStackArgument(inst),
|
||||
.ldr_stack_argument => try emit.mirLoadStackArgument(inst),
|
||||
.ldrb_stack_argument => try emit.mirLoadStackArgument(inst),
|
||||
.ldrh_stack_argument => try emit.mirLoadStackArgument(inst),
|
||||
@@ -597,6 +598,12 @@ fn mirLoadStackArgument(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
|
||||
const raw_offset = emit.prologue_stack_space - r_stack_offset.stack_offset;
|
||||
switch (tag) {
|
||||
.ldr_ptr_stack_argument => {
|
||||
const operand = Instruction.Operand.fromU32(raw_offset) orelse
|
||||
return emit.fail("TODO mirLoadStack larger offsets", .{});
|
||||
|
||||
try emit.writeInstruction(Instruction.add(cond, r_stack_offset.rt, .fp, operand));
|
||||
},
|
||||
.ldr_stack_argument,
|
||||
.ldrb_stack_argument,
|
||||
=> {
|
||||
|
||||
@@ -54,6 +54,8 @@ pub const Inst = struct {
|
||||
eor,
|
||||
/// Load Register
|
||||
ldr,
|
||||
/// Pseudo-instruction: Load pointer to stack argument offset
|
||||
ldr_ptr_stack_argument,
|
||||
/// Load Register
|
||||
ldr_stack_argument,
|
||||
/// Load Register Byte
|
||||
|
||||
@@ -202,7 +202,6 @@ fn doSomeMangling(array: *[4]u8) void {
|
||||
|
||||
test "implicit cast zero sized array ptr to slice" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
{
|
||||
var b = "".*;
|
||||
|
||||
@@ -269,7 +269,6 @@ test "bitcast passed as tuple element" {
|
||||
|
||||
test "triple level result location with bitcast sandwich passed as tuple element" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn foo(args: anytype) !void {
|
||||
|
||||
@@ -2,7 +2,6 @@ const builtin = @import("builtin");
|
||||
|
||||
test "const inferred array of slices" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const T = struct { v: bool };
|
||||
@@ -17,7 +16,6 @@ test "const inferred array of slices" {
|
||||
|
||||
test "var inferred array of slices" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const T = struct { v: bool };
|
||||
|
||||
@@ -9,7 +9,6 @@ const S = struct {
|
||||
};
|
||||
|
||||
test "functions with return type required to be comptime are generic" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
|
||||
@@ -6,7 +6,6 @@ fn foo(a: []u8) void {
|
||||
|
||||
test "address of 0 length array" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
|
||||
var pt: [0]u8 = undefined;
|
||||
|
||||
@@ -49,15 +49,11 @@ fn constant() !void {
|
||||
}
|
||||
|
||||
test "pointer-to-array constness for zero-size elements, var" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try mutable();
|
||||
comptime try mutable();
|
||||
}
|
||||
|
||||
test "pointer-to-array constness for zero-size elements, const" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try constant();
|
||||
comptime try constant();
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ fn constCount(comptime cb: *const CountBy, comptime unused: u32) void {
|
||||
}
|
||||
|
||||
test "comptime struct return should not return the same instance" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
|
||||
//the first parameter must be passed by reference to trigger the bug
|
||||
|
||||
@@ -1080,7 +1080,6 @@ test "compile time int to ptr of function" {
|
||||
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
@@ -1129,7 +1128,6 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
|
||||
test "peer type resolution: [0]u8 and []const u8" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
|
||||
try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
|
||||
@@ -1278,8 +1276,6 @@ test "assignment to optional pointer result loc" {
|
||||
}
|
||||
|
||||
test "cast between *[N]void and []void" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
var a: [4]void = undefined;
|
||||
var b: []void = &a;
|
||||
try expect(b.len == 4);
|
||||
|
||||
@@ -389,7 +389,6 @@ test "ability to give comptime types and non comptime types to same parameter" {
|
||||
test "function with inferred error set but returning no error" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn foo() !void {}
|
||||
|
||||
@@ -367,7 +367,6 @@ test "binary not" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(comptime x: {
|
||||
break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
|
||||
@@ -488,7 +487,6 @@ fn mod(comptime T: type, a: T, b: T) T {
|
||||
test "unsigned wrapping" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testUnsignedWrappingEval(maxInt(u32));
|
||||
comptime try testUnsignedWrappingEval(maxInt(u32));
|
||||
@@ -503,7 +501,6 @@ fn testUnsignedWrappingEval(x: u32) !void {
|
||||
test "signed wrapping" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testSignedWrappingEval(maxInt(i32));
|
||||
comptime try testSignedWrappingEval(maxInt(i32));
|
||||
@@ -518,7 +515,6 @@ fn testSignedWrappingEval(x: i32) !void {
|
||||
test "signed negation wrapping" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testSignedNegationWrappingEval(minInt(i16));
|
||||
comptime try testSignedNegationWrappingEval(minInt(i16));
|
||||
@@ -532,7 +528,6 @@ fn testSignedNegationWrappingEval(x: i16) !void {
|
||||
test "unsigned negation wrapping" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testUnsignedNegationWrappingEval(1);
|
||||
comptime try testUnsignedNegationWrappingEval(1);
|
||||
@@ -868,7 +863,6 @@ test "quad hex float literal parsing accurate" {
|
||||
|
||||
test "truncating shift left" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testShlTrunc(maxInt(u16));
|
||||
@@ -881,7 +875,6 @@ fn testShlTrunc(x: u16) !void {
|
||||
|
||||
test "exact shift left" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testShlExact(0b00110101);
|
||||
@@ -894,7 +887,6 @@ fn testShlExact(x: u8) !void {
|
||||
|
||||
test "exact shift right" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testShrExact(0b10110100);
|
||||
|
||||
@@ -26,7 +26,6 @@ pub const EmptyStruct = struct {};
|
||||
|
||||
test "optional pointer to size zero struct" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
var e = EmptyStruct{};
|
||||
var o: ?*EmptyStruct = &e;
|
||||
|
||||
@@ -59,7 +59,6 @@ fn testReinterpretStructWrappedBytesAsInteger() !void {
|
||||
}
|
||||
|
||||
test "reinterpret bytes of an array into an extern struct" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
|
||||
@@ -186,7 +186,6 @@ test "@sizeOf(T) == 0 doesn't force resolving struct size" {
|
||||
}
|
||||
|
||||
test "@TypeOf() has no runtime side effects" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
const S = struct {
|
||||
|
||||
@@ -70,7 +70,6 @@ test "comptime slice of undefined pointer of length 0" {
|
||||
test "implicitly cast array of size 0 to slice" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
var msg = [_]u8{};
|
||||
try assertLenIsZero(&msg);
|
||||
@@ -206,7 +205,6 @@ const y = x[0x100..];
|
||||
test "compile time slice of pointer to hard coded address" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
|
||||
|
||||
@@ -926,7 +926,6 @@ test "anonymous struct literal syntax" {
|
||||
|
||||
test "fully anonymous struct" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@@ -951,7 +950,6 @@ test "fully anonymous struct" {
|
||||
|
||||
test "fully anonymous list literal" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
|
||||
@@ -3,7 +3,6 @@ const expect = std.testing.expect;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
test "struct contains null pointer which contains original struct" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
|
||||
@@ -468,7 +468,6 @@ test "Type.Union from Type.Enum" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const Tag = @Type(.{
|
||||
@@ -500,7 +499,6 @@ test "Type.Union from regular enum" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const E = enum { working_as_expected };
|
||||
|
||||
@@ -385,7 +385,6 @@ extern fn foo(a: usize, b: bool, ...) callconv(.C) usize;
|
||||
extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize;
|
||||
|
||||
test "type info: generic function types" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ fn add(args: anytype) i32 {
|
||||
|
||||
test "add arbitrary args" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
|
||||
try expect(add(.{@as(i32, 1234)}) == 1234);
|
||||
@@ -27,14 +26,12 @@ fn readFirstVarArg(args: anytype) void {
|
||||
|
||||
test "send void arg to var args" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
readFirstVarArg(.{{}});
|
||||
}
|
||||
|
||||
test "pass args directly" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
|
||||
@@ -89,7 +86,6 @@ fn foo2(args: anytype) bool {
|
||||
|
||||
test "array of var args functions" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(foos[0](.{}));
|
||||
try expect(!foos[1](.{}));
|
||||
@@ -97,7 +93,6 @@ test "array of var args functions" {
|
||||
|
||||
test "pass zero length array to var args param" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
doNothingWithFirstArg(.{""});
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ test "compare void with void compile time known" {
|
||||
}
|
||||
|
||||
test "iterate over a void slice" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
|
||||
var j: usize = 0;
|
||||
|
||||
Reference in New Issue
Block a user