mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 03:03:09 +00:00
commit
2360f8c490
@ -160,7 +160,6 @@ pub fn extract(
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "vector patterns" {
|
test "vector patterns" {
|
||||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
|
||||||
const base = @Vector(4, u32){ 10, 20, 30, 40 };
|
const base = @Vector(4, u32){ 10, 20, 30, 40 };
|
||||||
const other_base = @Vector(4, u32){ 55, 66, 77, 88 };
|
const other_base = @Vector(4, u32){ 55, 66, 77, 88 };
|
||||||
|
|
||||||
|
|||||||
@ -1024,10 +1024,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
|||||||
if (options.use_llvm) |explicit|
|
if (options.use_llvm) |explicit|
|
||||||
break :blk explicit;
|
break :blk explicit;
|
||||||
|
|
||||||
// If we are outputting .c code we must use Zig backend.
|
|
||||||
if (ofmt == .c)
|
|
||||||
break :blk false;
|
|
||||||
|
|
||||||
// If emitting to LLVM bitcode object format, must use LLVM backend.
|
// If emitting to LLVM bitcode object format, must use LLVM backend.
|
||||||
if (options.emit_llvm_ir != null or options.emit_llvm_bc != null)
|
if (options.emit_llvm_ir != null or options.emit_llvm_bc != null)
|
||||||
break :blk true;
|
break :blk true;
|
||||||
@ -1042,7 +1038,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
|||||||
break :blk true;
|
break :blk true;
|
||||||
|
|
||||||
// If LLVM does not support the target, then we can't use it.
|
// If LLVM does not support the target, then we can't use it.
|
||||||
if (!target_util.hasLlvmSupport(options.target))
|
if (!target_util.hasLlvmSupport(options.target, ofmt))
|
||||||
break :blk false;
|
break :blk false;
|
||||||
|
|
||||||
// Prefer LLVM for release builds.
|
// Prefer LLVM for release builds.
|
||||||
|
|||||||
@ -768,7 +768,11 @@ pub const Object = struct {
|
|||||||
if (ptr_info.@"align" != 0) {
|
if (ptr_info.@"align" != 0) {
|
||||||
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
|
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
|
||||||
} else {
|
} else {
|
||||||
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target));
|
const elem_align = @maximum(
|
||||||
|
ptr_info.pointee_type.abiAlignment(target),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -840,7 +844,8 @@ pub const Object = struct {
|
|||||||
if (ptr_info.@"align" != 0) {
|
if (ptr_info.@"align" != 0) {
|
||||||
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
|
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
|
||||||
} else {
|
} else {
|
||||||
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target));
|
const elem_align = @maximum(ptr_info.pointee_type.abiAlignment(target), 1);
|
||||||
|
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", elem_align);
|
||||||
}
|
}
|
||||||
const ptr_param = llvm_func.getParam(llvm_arg_i);
|
const ptr_param = llvm_func.getParam(llvm_arg_i);
|
||||||
llvm_arg_i += 1;
|
llvm_arg_i += 1;
|
||||||
@ -3401,6 +3406,13 @@ pub const DeclGen = struct {
|
|||||||
const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
|
const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
|
||||||
const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?;
|
const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?;
|
||||||
assert(union_obj.haveFieldTypes());
|
assert(union_obj.haveFieldTypes());
|
||||||
|
|
||||||
|
// Sometimes we must make an unnamed struct because LLVM does
|
||||||
|
// not support bitcasting our payload struct to the true union payload type.
|
||||||
|
// Instead we use an unnamed struct and every reference to the global
|
||||||
|
// must pointer cast to the expected type before accessing the union.
|
||||||
|
var need_unnamed: bool = layout.most_aligned_field != field_index;
|
||||||
|
|
||||||
const field_ty = union_obj.fields.values()[field_index].ty;
|
const field_ty = union_obj.fields.values()[field_index].ty;
|
||||||
const payload = p: {
|
const payload = p: {
|
||||||
if (!field_ty.hasRuntimeBitsIgnoreComptime()) {
|
if (!field_ty.hasRuntimeBitsIgnoreComptime()) {
|
||||||
@ -3408,6 +3420,7 @@ pub const DeclGen = struct {
|
|||||||
break :p dg.context.intType(8).arrayType(padding_len).getUndef();
|
break :p dg.context.intType(8).arrayType(padding_len).getUndef();
|
||||||
}
|
}
|
||||||
const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
|
const field = try lowerValue(dg, .{ .ty = field_ty, .val = tag_and_val.val });
|
||||||
|
need_unnamed = need_unnamed or dg.isUnnamedType(field_ty, field);
|
||||||
const field_size = field_ty.abiSize(target);
|
const field_size = field_ty.abiSize(target);
|
||||||
if (field_size == layout.payload_size) {
|
if (field_size == layout.payload_size) {
|
||||||
break :p field;
|
break :p field;
|
||||||
@ -3419,12 +3432,6 @@ pub const DeclGen = struct {
|
|||||||
break :p dg.context.constStruct(&fields, fields.len, .True);
|
break :p dg.context.constStruct(&fields, fields.len, .True);
|
||||||
};
|
};
|
||||||
|
|
||||||
// In this case we must make an unnamed struct because LLVM does
|
|
||||||
// not support bitcasting our payload struct to the true union payload type.
|
|
||||||
// Instead we use an unnamed struct and every reference to the global
|
|
||||||
// must pointer cast to the expected type before accessing the union.
|
|
||||||
const need_unnamed = layout.most_aligned_field != field_index;
|
|
||||||
|
|
||||||
if (layout.tag_size == 0) {
|
if (layout.tag_size == 0) {
|
||||||
const fields: [1]*const llvm.Value = .{payload};
|
const fields: [1]*const llvm.Value = .{payload};
|
||||||
if (need_unnamed) {
|
if (need_unnamed) {
|
||||||
|
|||||||
@ -204,7 +204,24 @@ pub fn hasValgrindSupport(target: std.Target) bool {
|
|||||||
/// The set of targets that LLVM has non-experimental support for.
|
/// The set of targets that LLVM has non-experimental support for.
|
||||||
/// Used to select between LLVM backend and self-hosted backend when compiling in
|
/// Used to select between LLVM backend and self-hosted backend when compiling in
|
||||||
/// release modes.
|
/// release modes.
|
||||||
pub fn hasLlvmSupport(target: std.Target) bool {
|
pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
|
||||||
|
switch (ofmt) {
|
||||||
|
// LLVM does not support these object formats:
|
||||||
|
.c,
|
||||||
|
.plan9,
|
||||||
|
=> return false,
|
||||||
|
|
||||||
|
.coff,
|
||||||
|
.elf,
|
||||||
|
.macho,
|
||||||
|
.wasm,
|
||||||
|
.spirv,
|
||||||
|
.hex,
|
||||||
|
.raw,
|
||||||
|
.nvptx,
|
||||||
|
=> {},
|
||||||
|
}
|
||||||
|
|
||||||
return switch (target.cpu.arch) {
|
return switch (target.cpu.arch) {
|
||||||
.arm,
|
.arm,
|
||||||
.armeb,
|
.armeb,
|
||||||
|
|||||||
10
src/type.zig
10
src/type.zig
@ -2906,9 +2906,13 @@ pub const Type = extern union {
|
|||||||
|
|
||||||
.array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),
|
.array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(target, strat),
|
||||||
|
|
||||||
// TODO audit this - is there any more complicated logic to determine
|
.vector => {
|
||||||
// ABI alignment of vectors?
|
const len = ty.arrayLen();
|
||||||
.vector => return AbiAlignmentAdvanced{ .scalar = 16 },
|
const bits = try bitSizeAdvanced(ty.elemType(), target, sema_kit);
|
||||||
|
const bytes = (bits + 7) / 8;
|
||||||
|
const alignment = std.math.ceilPowerOfTwoAssert(u64, bytes * len);
|
||||||
|
return AbiAlignmentAdvanced{ .scalar = @intCast(u32, alignment) };
|
||||||
|
},
|
||||||
|
|
||||||
.i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) },
|
.i16, .u16 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(16, target) },
|
||||||
.u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) },
|
.u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) },
|
||||||
|
|||||||
@ -1048,3 +1048,27 @@ test "@shlWithOverflow" {
|
|||||||
try S.doTheTest();
|
try S.doTheTest();
|
||||||
comptime try S.doTheTest();
|
comptime try S.doTheTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "alignment of vectors" {
|
||||||
|
try expect(@alignOf(@Vector(2, u8)) == 2);
|
||||||
|
try expect(@alignOf(@Vector(2, u1)) == 2);
|
||||||
|
try expect(@alignOf(@Vector(1, u1)) == 1);
|
||||||
|
try expect(@alignOf(@Vector(2, u16)) == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "loading the second vector from a slice of vectors" {
|
||||||
|
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_aarch64) return error.SkipZigTest; // TODO
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
|
|
||||||
|
@setRuntimeSafety(false);
|
||||||
|
var small_bases = [2]@Vector(2, u8){
|
||||||
|
@Vector(2, u8){ 0, 1 },
|
||||||
|
@Vector(2, u8){ 2, 3 },
|
||||||
|
};
|
||||||
|
var a: []const @Vector(2, u8) = &small_bases;
|
||||||
|
var a4 = a[1][1];
|
||||||
|
try expect(a4 == 3);
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
pub fn main() void {}
|
|
||||||
|
|
||||||
// run
|
|
||||||
// target=x86_64-plan9,aarch64-plan9
|
|
||||||
//
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
pub fn main() void {
|
|
||||||
const str = "Hello World!\n";
|
|
||||||
asm volatile (
|
|
||||||
\\push $0
|
|
||||||
\\push %%r10
|
|
||||||
\\push %%r11
|
|
||||||
\\push $1
|
|
||||||
\\push $0
|
|
||||||
\\syscall
|
|
||||||
\\pop %%r11
|
|
||||||
\\pop %%r11
|
|
||||||
\\pop %%r11
|
|
||||||
\\pop %%r11
|
|
||||||
\\pop %%r11
|
|
||||||
:
|
|
||||||
// pwrite
|
|
||||||
: [syscall_number] "{rbp}" (51),
|
|
||||||
[hey] "{r11}" (@ptrToInt(str)),
|
|
||||||
[strlen] "{r10}" (str.len),
|
|
||||||
: "rcx", "rbp", "r11", "memory"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// run
|
|
||||||
// target=x86_64-plan9
|
|
||||||
//
|
|
||||||
// Hello World
|
|
||||||
//
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
pub fn main() void {
|
|
||||||
const str = "Hello World!\n";
|
|
||||||
_ = std.os.plan9.pwrite(1, str, str.len, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// run
|
|
||||||
//
|
|
||||||
// Hello World
|
|
||||||
//
|
|
||||||
Loading…
x
Reference in New Issue
Block a user