mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
commit
2360f8c490
@ -160,7 +160,6 @@ pub fn extract(
|
||||
}
|
||||
|
||||
test "vector patterns" {
|
||||
if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest;
|
||||
const base = @Vector(4, u32){ 10, 20, 30, 40 };
|
||||
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|
|
||||
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 (options.emit_llvm_ir != null or options.emit_llvm_bc != null)
|
||||
break :blk true;
|
||||
@ -1042,7 +1038,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
||||
break :blk true;
|
||||
|
||||
// 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;
|
||||
|
||||
// Prefer LLVM for release builds.
|
||||
|
||||
@ -768,7 +768,11 @@ pub const Object = struct {
|
||||
if (ptr_info.@"align" != 0) {
|
||||
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
|
||||
} 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) {
|
||||
dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align");
|
||||
} 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);
|
||||
llvm_arg_i += 1;
|
||||
@ -3401,6 +3406,13 @@ pub const DeclGen = struct {
|
||||
const union_obj = tv.ty.cast(Type.Payload.Union).?.data;
|
||||
const field_index = union_obj.tag_ty.enumTagFieldIndex(tag_and_val.tag, dg.module).?;
|
||||
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 payload = p: {
|
||||
if (!field_ty.hasRuntimeBitsIgnoreComptime()) {
|
||||
@ -3408,6 +3420,7 @@ pub const DeclGen = struct {
|
||||
break :p dg.context.intType(8).arrayType(padding_len).getUndef();
|
||||
}
|
||||
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);
|
||||
if (field_size == layout.payload_size) {
|
||||
break :p field;
|
||||
@ -3419,12 +3432,6 @@ pub const DeclGen = struct {
|
||||
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) {
|
||||
const fields: [1]*const llvm.Value = .{payload};
|
||||
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.
|
||||
/// Used to select between LLVM backend and self-hosted backend when compiling in
|
||||
/// 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) {
|
||||
.arm,
|
||||
.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),
|
||||
|
||||
// TODO audit this - is there any more complicated logic to determine
|
||||
// ABI alignment of vectors?
|
||||
.vector => return AbiAlignmentAdvanced{ .scalar = 16 },
|
||||
.vector => {
|
||||
const len = ty.arrayLen();
|
||||
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) },
|
||||
.u29 => return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(29, target) },
|
||||
|
||||
@ -1048,3 +1048,27 @@ test "@shlWithOverflow" {
|
||||
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