mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-10-28 10:45:48 +08:00
1 parent
092f019be9
commit
703baa4cd6
3 files changed
+220
No files matched your search
@@ -358,6 +358,7 @@ set(ZIG_STAGE2_SOURCES
|
||||
src/codegen/c/type/render_defs.zig
|
||||
src/codegen/llvm.zig
|
||||
src/codegen/llvm/bindings.zig
|
||||
src/codegen/loongarch/abi.zig
|
||||
src/codegen/s390x/abi.zig
|
||||
src/crash_report.zig
|
||||
src/dev.zig
|
||||
|
||||
@@ -7016,6 +7016,71 @@ const ParamTypeIterator = struct {
|
||||
.i64_array => |size| return .{ .i64_array = size },
|
||||
}
|
||||
},
|
||||
.loongarch32_ilp32, .loongarch64_lp64 => switch (loongarch_c_abi.classifyType(ty, zcu)) {
|
||||
.ignored => {
|
||||
it.zig_index += 1;
|
||||
return .no_bits;
|
||||
},
|
||||
.gar, .far => {
|
||||
it.zig_index += 1;
|
||||
it.llvm_index += 1;
|
||||
return .byval;
|
||||
},
|
||||
.member => |member_ty| {
|
||||
it.types_buffer[0..1].* = .{
|
||||
try it.object.lowerType(member_ty, .as_value),
|
||||
};
|
||||
it.offsets_buffer[0..2].* = .{ 0, member_ty.abiSize(zcu) };
|
||||
it.types_len = 1;
|
||||
it.zig_index += 1;
|
||||
it.llvm_index += 1;
|
||||
return .multiple_llvm_types;
|
||||
},
|
||||
.member_pair => |member_tys| {
|
||||
it.types_buffer[0..2].* = .{
|
||||
try it.object.lowerType(member_tys[0], .as_value),
|
||||
try it.object.lowerType(member_tys[1], .as_value),
|
||||
};
|
||||
const first_size = member_tys[0].abiSize(zcu);
|
||||
const second_size = member_tys[0].abiSize(zcu);
|
||||
it.offsets_buffer[0..3].* = .{ 0, first_size, first_size + second_size };
|
||||
it.types_len = 2;
|
||||
it.zig_index += 1;
|
||||
it.llvm_index += 2;
|
||||
return .multiple_llvm_types;
|
||||
},
|
||||
.memory_gar => {
|
||||
switch (it.cc) {
|
||||
else => unreachable,
|
||||
.loongarch32_ilp32 => {
|
||||
it.types_buffer[0..1].* = .{.i32};
|
||||
it.offsets_buffer[0..2].* = .{ 0, 4 };
|
||||
},
|
||||
.loongarch64_lp64 => {
|
||||
it.types_buffer[0..1].* = .{.i64};
|
||||
it.offsets_buffer[0..2].* = .{ 0, 8 };
|
||||
},
|
||||
}
|
||||
it.types_len = 1;
|
||||
it.zig_index += 1;
|
||||
it.llvm_index += 1;
|
||||
return .multiple_llvm_types;
|
||||
},
|
||||
.memory_gar_pair => {
|
||||
it.zig_index += 1;
|
||||
it.llvm_index += 1;
|
||||
return switch (it.cc) {
|
||||
else => unreachable,
|
||||
.loongarch32_ilp32 => .{ .i32_array = 2 },
|
||||
.loongarch64_lp64 => .{ .i64_array = 2 },
|
||||
};
|
||||
},
|
||||
.address => {
|
||||
it.zig_index += 1;
|
||||
it.llvm_index += 1;
|
||||
return .byref;
|
||||
},
|
||||
},
|
||||
.mips_o32 => {
|
||||
it.zig_index += 1;
|
||||
it.llvm_index += 1;
|
||||
@@ -7330,6 +7395,26 @@ pub fn fnReturnStrat(o: *Object, cc: std.lang.CallingConvention, ret_ty: Type) A
|
||||
.i32_array => |len| if (len == 1) .{ .mem_cast = .i32 } else .sret,
|
||||
.byval => .forceByVal(o, ret_ty),
|
||||
},
|
||||
.loongarch32_ilp32, .loongarch64_lp64 => switch (loongarch_c_abi.classifyType(ret_ty, zcu)) {
|
||||
.ignored => .void,
|
||||
.gar, .far => .by_val,
|
||||
.member => |member_ty| .{ .mem_cast = try o.lowerType(member_ty, .as_value) },
|
||||
.member_pair => |member_tys| .{ .mem_cast = try o.builder.structType(.normal, &.{
|
||||
try o.lowerType(member_tys[0], .as_value),
|
||||
try o.lowerType(member_tys[1], .as_value),
|
||||
}) },
|
||||
.memory_gar => .{ .mem_cast = switch (cc) {
|
||||
else => unreachable,
|
||||
.loongarch32_ilp32 => .i32,
|
||||
.loongarch64_lp64 => .i64,
|
||||
} },
|
||||
.memory_gar_pair => .{ .mem_cast = try o.builder.arrayType(2, switch (cc) {
|
||||
else => unreachable,
|
||||
.loongarch32_ilp32 => .i32,
|
||||
.loongarch64_lp64 => .i64,
|
||||
}) },
|
||||
.address => .sret,
|
||||
},
|
||||
.mips_o32 => switch (mips_c_abi.classifyType(ret_ty, zcu, .ret)) {
|
||||
.memory, .i32_array => .sret,
|
||||
.byval => .forceByVal(o, ret_ty),
|
||||
@@ -8124,6 +8209,7 @@ const math = std.math;
|
||||
|
||||
const aarch64_c_abi = @import("../aarch64/abi.zig");
|
||||
const arm_c_abi = @import("../arm/abi.zig");
|
||||
const loongarch_c_abi = @import("../loongarch/abi.zig");
|
||||
const mips_c_abi = @import("../mips/abi.zig");
|
||||
const riscv_c_abi = @import("../riscv64/abi.zig");
|
||||
const s390x_c_abi = @import("../s390x/abi.zig");
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
const std = @import("std");
|
||||
const InternPool = @import("../../InternPool.zig");
|
||||
const Type = @import("../../Type.zig");
|
||||
const Zcu = @import("../../Zcu.zig");
|
||||
|
||||
pub const Class = union(enum) {
|
||||
ignored,
|
||||
gar,
|
||||
far,
|
||||
member: Type,
|
||||
member_pair: [2]Type,
|
||||
memory_gar,
|
||||
memory_gar_pair,
|
||||
address,
|
||||
|
||||
fn combineMember(container_class: Class, member_class: Class, member_ty: Type) Class {
|
||||
const second_member_ty = switch (member_class) {
|
||||
.ignored => return container_class,
|
||||
.gar, .far => member_ty,
|
||||
.member => |second_member_ty| second_member_ty,
|
||||
.member_pair, .memory_gar, .memory_gar_pair, .address => return .address,
|
||||
};
|
||||
return switch (container_class) {
|
||||
.ignored => .{ .member = second_member_ty },
|
||||
.gar, .far, .memory_gar, .memory_gar_pair => unreachable,
|
||||
.member => |first_member_ty| .{ .member_pair = .{ first_member_ty, second_member_ty } },
|
||||
.member_pair, .address => .address,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn classifyType(ty: Type, zcu: *Zcu) Class {
|
||||
return Classifier.init(zcu).classifyType(ty);
|
||||
}
|
||||
|
||||
const Classifier = struct {
|
||||
zcu: *Zcu,
|
||||
target: *const std.Target,
|
||||
grlen: u8,
|
||||
frlen: u8,
|
||||
|
||||
fn init(zcu: *Zcu) Classifier {
|
||||
const target = zcu.getTarget();
|
||||
return .{
|
||||
.zcu = zcu,
|
||||
.target = target,
|
||||
.grlen = switch (target.cpu.arch) {
|
||||
else => unreachable,
|
||||
.loongarch32 => 32,
|
||||
.loongarch64 => 64,
|
||||
},
|
||||
.frlen = if (target.cpu.has(.loongarch, .d))
|
||||
64
|
||||
else if (target.cpu.has(.loongarch, .f))
|
||||
32
|
||||
else
|
||||
0,
|
||||
};
|
||||
}
|
||||
|
||||
fn classifyType(c: Classifier, ty: Type) Class {
|
||||
switch (ty.zigTypeTag(c.zcu)) {
|
||||
.type,
|
||||
.comptime_float,
|
||||
.comptime_int,
|
||||
.undefined,
|
||||
.null,
|
||||
.error_union,
|
||||
.error_set,
|
||||
.@"fn",
|
||||
.@"opaque",
|
||||
.frame,
|
||||
.@"anyframe",
|
||||
.enum_literal,
|
||||
.spirv,
|
||||
=> unreachable,
|
||||
.void, .noreturn => return .ignored,
|
||||
.bool => return .gar,
|
||||
.int, .@"enum" => {
|
||||
const bits = ty.intInfo(c.zcu).bits;
|
||||
if (bits == 0) return .ignored;
|
||||
if (bits <= c.grlen) return .gar;
|
||||
if (bits <= 2 * c.grlen) return .memory_gar_pair;
|
||||
return .address;
|
||||
},
|
||||
.float => {
|
||||
const bits = ty.floatBits(c.target);
|
||||
if (bits <= c.frlen) return .far;
|
||||
if (bits <= c.grlen) return .gar;
|
||||
if (bits <= 2 * c.grlen) return .memory_gar_pair;
|
||||
return .address;
|
||||
},
|
||||
.pointer, .optional => return .gar,
|
||||
.array => {
|
||||
var class: Class = .ignored;
|
||||
const elem_ty = ty.childType(c.zcu);
|
||||
const elem_class = c.classifyType(elem_ty);
|
||||
for (0..std.math.lossyCast(usize, ty.arrayLen(c.zcu))) |_| {
|
||||
class = class.combineMember(elem_class, elem_ty);
|
||||
if (class == .address) break;
|
||||
}
|
||||
if (class != .address) return class;
|
||||
},
|
||||
.@"struct" => switch (ty.containerLayout(c.zcu)) {
|
||||
.auto => unreachable,
|
||||
.@"extern" => {
|
||||
var class: Class = .ignored;
|
||||
var field_it: InternPool.LoadedStructType.RuntimeOrderIterator = if (c.zcu.typeToStruct(ty)) |loaded_struct|
|
||||
loaded_struct.iterateRuntimeOrder(&c.zcu.intern_pool)
|
||||
else
|
||||
.{ .runtime_order = null, .fields_len = ty.structFieldCount(c.zcu), .next_index = 0 };
|
||||
while (field_it.next()) |field_index| {
|
||||
const field_ty = ty.fieldType(field_index, c.zcu);
|
||||
class = class.combineMember(c.classifyType(field_ty), field_ty);
|
||||
if (class == .address) break;
|
||||
}
|
||||
if (class != .address) return class;
|
||||
},
|
||||
.@"packed" => return c.classifyType(ty.backingIntType(c.zcu)),
|
||||
},
|
||||
.@"union" => switch (ty.containerLayout(c.zcu)) {
|
||||
.auto => unreachable,
|
||||
.@"extern" => {},
|
||||
.@"packed" => return c.classifyType(ty.backingIntType(c.zcu)),
|
||||
},
|
||||
.vector => {},
|
||||
}
|
||||
const size = ty.abiSize(c.zcu);
|
||||
if (size <= @divExact(c.grlen, 8)) return .memory_gar;
|
||||
if (size <= @divExact(2 * c.grlen, 8)) return .memory_gar_pair;
|
||||
return .address;
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user