feat: init eZ80 arch via CBE

This commit is contained in:
Sam Connelly
2026-03-12 09:04:39 -04:00
committed by Andrew Kelley
parent d092c752f3
commit 17e0afd0e5
10 changed files with 465 additions and 7 deletions
+4
View File
@@ -475,8 +475,12 @@ pub const builtin_typedef_map = std.StaticStringMap([]const u8).initComptime(.{
.{ "int8_t", "i8" },
.{ "uint16_t", "u16" },
.{ "int16_t", "i16" },
.{ "uint24_t", "u24" },
.{ "int24_t", "i24" },
.{ "uint32_t", "u32" },
.{ "int32_t", "i32" },
.{ "uint48_t", "u48" },
.{ "int48_t", "i48" },
.{ "uint64_t", "u64" },
.{ "int64_t", "i64" },
.{ "intptr_t", "isize" },
+50 -3
View File
@@ -68,6 +68,8 @@ pub const Os = struct {
opengl,
vulkan,
tios,
// LLVM tags deliberately omitted:
// - bridgeos
// - cheriotrtos
@@ -207,6 +209,8 @@ pub const Os = struct {
.opencl,
.opengl,
.vulkan,
.tios,
=> .semver,
.hurd => .hurd,
@@ -670,6 +674,12 @@ pub const Os = struct {
.max = .{ .major = 4, .minor = 6, .patch = 0 },
},
},
.tios => .{
.semver = .{
.min = .{ .major = 5, .minor = 0, .patch = 0 },
.max = .{ .major = 5, .minor = 8, .patch = 4 },
},
},
.vulkan => .{
.semver = .{
.min = .{ .major = 1, .minor = 2, .patch = 0 },
@@ -758,6 +768,7 @@ pub const wasm = @import("Target/wasm.zig");
pub const x86 = @import("Target/x86.zig");
pub const xcore = @import("Target/xcore.zig");
pub const xtensa = @import("Target/xtensa.zig");
pub const z80 = @import("Target/generic.zig");
pub const Abi = enum {
none,
@@ -942,6 +953,7 @@ pub const Abi = enum {
.opencl,
.opengl,
.vulkan,
.tios,
=> .none,
};
}
@@ -1068,6 +1080,7 @@ pub fn toElfMachine(target: *const Target) std.elf.EM {
.avr => .AVR,
.bpfeb, .bpfel => .BPF,
.csky => .CSKY,
.ez80 => .Z80,
.hexagon => .QDSP6,
.hppa, .hppa64 => .PARISC,
.kalimba => .CSR_KALIMBA,
@@ -1130,6 +1143,7 @@ pub fn toCoffMachine(target: *const Target) std.coff.IMAGE.FILE.MACHINE {
.bpfeb,
.bpfel,
.csky,
.ez80,
.hexagon,
.hppa,
.hppa64,
@@ -1336,6 +1350,7 @@ pub const Cpu = struct {
bpfeb,
bpfel,
csky,
ez80,
hexagon,
hppa,
hppa64,
@@ -1437,6 +1452,7 @@ pub const Cpu = struct {
x86,
xcore,
xtensa,
z80,
};
pub inline fn family(arch: Arch) Family {
@@ -1449,6 +1465,7 @@ pub const Cpu = struct {
.avr => .avr,
.bpfeb, .bpfel => .bpf,
.csky => .csky,
.ez80 => .z80,
.hexagon => .hexagon,
.hppa, .hppa64 => .hppa,
.kalimba => .kalimba,
@@ -1678,6 +1695,7 @@ pub const Cpu = struct {
.x86_64,
.xcore,
.xtensa,
.ez80,
=> .little,
.aarch64_be,
@@ -1948,6 +1966,10 @@ pub const Cpu = struct {
.spirv_fragment,
.spirv_vertex,
=> &.{ .spirv32, .spirv64 },
.ez80_cet,
.ez80_tiflags,
=> &.{.ez80},
};
}
};
@@ -2236,6 +2258,7 @@ pub fn requiresLibC(target: *const Target) bool {
.plan9,
.other,
.@"3ds",
.tios,
=> false,
};
}
@@ -2398,6 +2421,8 @@ pub const DynamicLinker = struct {
.ps5,
.psp,
.vita,
.tios,
=> .none,
};
}
@@ -2815,6 +2840,8 @@ pub const DynamicLinker = struct {
.opencl,
.opengl,
.vulkan,
.tios,
=> none,
// TODO go over each item in this list and either move it to the above list, or
@@ -2849,6 +2876,9 @@ pub fn ptrBitWidth_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) u16 {
.x86_16,
=> 16,
.ez80,
=> 24,
.arc,
.arceb,
.arm,
@@ -2917,6 +2947,8 @@ pub fn ptrBitWidth(target: *const Target) u16 {
pub fn stackAlignment(target: *const Target) u16 {
// Overrides for when the stack alignment is not equal to the pointer width.
switch (target.cpu.arch) {
.ez80,
=> return 1,
.m68k,
=> return 2,
.amdgcn,
@@ -2997,6 +3029,7 @@ pub fn cCharSignedness(target: *const Target) std.builtin.Signedness {
.arc,
.arceb,
.csky,
.ez80,
.hexagon,
.msp430,
.powerpc,
@@ -3364,6 +3397,13 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
.long, .ulong => return 64,
.longlong, .ulonglong, .double, .longdouble => return 64,
},
.tios => switch (c_type) {
.char => return 8,
.short, .ushort => return 16,
.int, .uint => return 24,
.long, .ulong, .float, .double => return 32,
.longlong, .ulonglong, .longdouble => return 64,
},
.ps3,
.contiki,
@@ -3376,7 +3416,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
// Overrides for unusual alignments
switch (target.cpu.arch) {
.avr => return 1,
.avr, .ez80 => return 1,
.x86 => switch (target.os.tag) {
.windows, .uefi => switch (c_type) {
.longlong, .ulonglong, .double => return 8,
@@ -3406,6 +3446,8 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
return @min(
std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8),
@as(u16, switch (target.cpu.arch) {
.ez80 => 1,
.msp430,
.x86_16,
=> 2,
@@ -3484,7 +3526,7 @@ pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 {
.longdouble => return 4,
else => {},
},
.avr => return 1,
.avr, .ez80 => return 1,
.x86 => switch (target.os.tag) {
.windows, .uefi => switch (c_type) {
.longdouble => switch (target.abi) {
@@ -3516,6 +3558,8 @@ pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 {
return @min(
std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8),
@as(u16, switch (target.cpu.arch) {
.ez80 => 1,
.x86_16, .msp430 => 2,
.arc,
@@ -3587,7 +3631,9 @@ pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 {
pub fn cMaxIntAlignment(target: *const Target) u16 {
return switch (target.cpu.arch) {
.avr => 1,
.avr,
.ez80,
=> 1,
.msp430, .x86_16 => 2,
@@ -3726,6 +3772,7 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention
.amdgcn => .{ .amdgcn_device = .{} },
.nvptx, .nvptx64 => .nvptx_device,
.spirv32, .spirv64 => .spirv_device,
.ez80 => .ez80_cet,
};
}
+4
View File
@@ -341,6 +341,10 @@ pub const CallingConvention = union(enum(u8)) {
spirv_fragment,
spirv_vertex,
// Calling conventions for the `ez80` architecture.
ez80_cet,
ez80_tiflags,
/// Options shared across most calling conventions.
pub const CommonOptions = struct {
/// The boundary the stack is aligned to when the function is called.
+340 -1
View File
@@ -79,6 +79,9 @@
#elif defined(__I86__)
#define zig_x86_16
#define zig_x86
#elif defined (__ez80)
#define zig_ez80
#define zig_z80
#endif
#if defined(zig_msvc) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
@@ -409,6 +412,8 @@
#define zig_trap() __asm__ volatile("int $0x3")
#elif defined(zig_x86)
#define zig_trap() __asm__ volatile("ud2")
#elif defined(zig_z80)
#define zig_trap() __asm__ volatile("rst 00h")
#else
#define zig_trap() zig_trap_unavailable
#endif
@@ -511,7 +516,7 @@ zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);
zig_extern void *memset (void *, int, size_t);
zig_extern void *memmove (void *, void const *, size_t);
/* ================ Bool and 8/16/32/64-bit Integer Support ================= */
/* ================ Bool and 8/16/24/32/48/64-bit Integer Support ================= */
#include <limits.h>
@@ -590,6 +595,16 @@ typedef signed long long int16_t;
#define INT16_MAX ( INT16_C(0x7FFF))
#define UINT16_MAX ( INT16_C(0xFFFF))
#if defined(zig_ez80)
typedef unsigned int uint24_t;
typedef signed int int24_t;
#define INT24_C(c) c
#define UINT24_C(c) c##U
#endif
#define INT24_MIN (~INT24_C(0x7FFF))
#define INT24_MAX ( INT24_C(0x7FFF))
#define UINT24_MAX ( INT24_C(0xFFFF))
#if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF
typedef unsigned char uint32_t;
typedef signed char int32_t;
@@ -620,6 +635,17 @@ typedef signed long long int32_t;
#define INT32_MAX ( INT32_C(0x7FFFFFFF))
#define UINT32_MAX ( INT32_C(0xFFFFFFFF))
#if defined(zig_ez80)
typedef unsigned __int48 uint48_t;
typedef signed __int48 int48_t;
#define INT48_C(c) c
/* no suffix */
#define UINT48_C(c) ((uint48_t)(c))
#endif
#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF))
#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF))
#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF))
#if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF
typedef unsigned char uint64_t;
typedef signed char int64_t;
@@ -663,10 +689,18 @@ typedef ptrdiff_t intptr_t;
#define zig_maxInt_i16 INT16_MAX
#define zig_minInt_u16 UINT16_C(0)
#define zig_maxInt_u16 UINT16_MAX
#define zig_minInt_i24 INT24_MIN
#define zig_maxInt_i24 INT24_MAX
#define zig_minInt_u24 UINT24_C(0)
#define zig_maxInt_u24 UINT24_MAX
#define zig_minInt_i32 INT32_MIN
#define zig_maxInt_i32 INT32_MAX
#define zig_minInt_u32 UINT32_C(0)
#define zig_maxInt_u32 UINT32_MAX
#define zig_minInt_i48 INT48_MIN
#define zig_maxInt_i48 INT48_MAX
#define zig_minInt_u48 UINT48_C(0)
#define zig_maxInt_u48 UINT48_MAX
#define zig_minInt_i64 INT64_MIN
#define zig_maxInt_i64 INT64_MAX
#define zig_minInt_u64 UINT64_C(0)
@@ -786,6 +820,17 @@ zig_int_helpers(16, unsigned long long)
#else
zig_int_helpers(16, uint16_t)
#endif
#if defined(zig_ez80)
#if UINT24_MAX <= UINT_MAX
zig_int_helpers(24, unsigned int)
#elif UINT24_MAX <= ULONG_MAX
zig_int_helpers(24, unsigned long)
#elif UINT24_MAX <= ULLONG_MAX
zig_int_helpers(24, unsigned long long)
#else
zig_int_helpers(24, uint24_t)
#endif
#endif
#if UINT32_MAX <= UINT_MAX
zig_int_helpers(32, unsigned int)
#elif UINT32_MAX <= ULONG_MAX
@@ -795,6 +840,17 @@ zig_int_helpers(32, unsigned long long)
#else
zig_int_helpers(32, uint32_t)
#endif
#if defined(zig_ez80)
#if UINT24_MAX <= UINT_MAX
zig_int_helpers(48, unsigned int)
#elif UINT24_MAX <= ULONG_MAX
zig_int_helpers(48, unsigned long)
#elif UINT24_MAX <= ULLONG_MAX
zig_int_helpers(48, unsigned long long)
#else
zig_int_helpers(48, uint48_t)
#endif
#endif
#if UINT64_MAX <= UINT_MAX
zig_int_helpers(64, unsigned int)
#elif UINT64_MAX <= ULONG_MAX
@@ -909,6 +965,66 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
#endif
}
#if defined(zig_ez80)
static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
uint24_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u24(full_res, bits);
return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
#else
uint32_t full_res;
bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
*res = (uint24_t)full_res;
return overflow;
#endif
}
static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
int24_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i24(full_res, bits);
return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
#else
int32_t full_res;
bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
*res = (int24_t)full_res;
return overflow;
#endif
}
#endif
#if defined(zig_ez80)
static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
uint48_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u48(full_res, bits);
return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
#else
uint64_t full_res;
bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits);
*res = (uint48_t)full_res;
return overflow;
#endif
}
static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) {
#if zig_has_builtin(add_overflow) || defined(zig_gcc)
int48_t full_res;
bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i48(full_res, bits);
return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
#else
int64_t full_res;
bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits);
*res = (int48_t)full_res;
return overflow;
#endif
}
#endif
static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
uint32_t full_res;
@@ -933,6 +1049,7 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t
return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
}
static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
uint64_t full_res;
@@ -1013,6 +1130,66 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
#endif
}
#if defined(zig_ez80)
static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
uint24_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u24(full_res, bits);
return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
#else
uint32_t full_res;
bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
*res = (uint24_t)full_res;
return overflow;
#endif
}
static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
int24_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i24(full_res, bits);
return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
#else
int32_t full_res;
bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
*res = (int24_t)full_res;
return overflow;
#endif
}
#endif
#if defined(zig_ez80)
static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
uint48_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u48(full_res, bits);
return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
#else
uint64_t full_res;
bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits);
*res = (uint48_t)full_res;
return overflow;
#endif
}
static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) {
#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
int48_t full_res;
bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i48(full_res, bits);
return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
#else
int64_t full_res;
bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits);
*res = (int48_t)full_res;
return overflow;
#endif
}
#endif
static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
uint32_t full_res;
@@ -1121,6 +1298,66 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
#endif
}
#if defined(zig_ez80)
static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
uint24_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u24(full_res, bits);
return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
#else
uint32_t full_res;
bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
*res = (uint24_t)full_res;
return overflow;
#endif
}
static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
int24_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i24(full_res, bits);
return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
#else
int32_t full_res;
bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
*res = (int24_t)full_res;
return overflow;
#endif
}
#endif
#if defined(zig_ez80)
static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
uint48_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_u48(full_res, bits);
return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
#else
uint64_t full_res;
bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits);
*res = (uint48_t)full_res;
return overflow;
#endif
}
static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) {
#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
int48_t full_res;
bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
*res = zig_wrap_i48(full_res, bits);
return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
#else
int64_t full_res;
bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits);
*res = (int48_t)full_res;
return overflow;
#endif
}
#endif
#define zig_int_builtins(w) \
static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
*res = zig_shlw_u##w(lhs, rhs, bits); \
@@ -1180,7 +1417,13 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
}
zig_int_builtins(8)
zig_int_builtins(16)
#if defined(zig_ez80)
zig_int_builtins(24)
#endif
zig_int_builtins(32)
#if defined(zig_ez80)
zig_int_builtins(48)
#endif
zig_int_builtins(64)
#define zig_builtin8(name, val) __builtin_##name(val)
@@ -1189,6 +1432,11 @@ typedef unsigned int zig_Builtin8;
#define zig_builtin16(name, val) __builtin_##name(val)
typedef unsigned int zig_Builtin16;
#if defined(zig_ez80)
#define zig_builtin24(name, val) __builtin_##name(val)
typedef unsigned int zig_Builtin24;
#endif
#if INT_MIN <= INT32_MIN
#define zig_builtin32(name, val) __builtin_##name(val)
typedef unsigned int zig_Builtin32;
@@ -1197,6 +1445,11 @@ typedef unsigned int zig_Builtin32;
typedef unsigned long zig_Builtin32;
#endif
#if defined(zig_ez80)
#define zig_builtin48(name, val) __builtin_##name(val)
typedef unsigned long long zig_Builtin48;
#endif
#if INT_MIN <= INT64_MIN
#define zig_builtin64(name, val) __builtin_##name(val)
typedef unsigned int zig_Builtin64;
@@ -1231,6 +1484,23 @@ static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) {
return zig_wrap_i16((int16_t)zig_byte_swap_u16((uint16_t)val, bits), bits);
}
#if defined(zig_ez80)
static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) {
uint24_t full_res;
#if zig_has_builtin(bswap24) || defined(zig_gcc)
full_res = __builtin_bswap24(val);
#else
full_res = (uint24_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 16 |
(uint24_t)zig_byte_swap_u16((uint16_t)(val >> 8), 16) >> 0;
#endif
return zig_wrap_u24(full_res >> (24 - bits), bits);
}
static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) {
return zig_wrap_i24((int24_t)zig_byte_swap_u24((uint24_t)val, bits), bits);
}
#endif
static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) {
uint32_t full_res;
#if zig_has_builtin(bswap32) || defined(zig_gcc)
@@ -1246,6 +1516,23 @@ static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) {
return zig_wrap_i32((int32_t)zig_byte_swap_u32((uint32_t)val, bits), bits);
}
#if defined(zig_ez80)
static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) {
uint48_t full_res;
#if zig_has_builtin(bswap48) || defined(zig_gcc)
full_res = __builtin_bswap48(val);
#else
full_res = (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 0), 24) << 24 |
(uint48_t)zig_byte_swap_u24((uint24_t)(val >> 24), 24) >> 0;
#endif
return zig_wrap_u48(full_res >> (48 - bits), bits);
}
static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) {
return zig_wrap_i48((int48_t)zig_byte_swap_u48((uint48_t)val, bits), bits);
}
#endif
static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) {
uint64_t full_res;
#if zig_has_builtin(bswap64) || defined(zig_gcc)
@@ -1294,6 +1581,23 @@ static inline int16_t zig_bit_reverse_i16(int16_t val, uint8_t bits) {
return zig_wrap_i16((int16_t)zig_bit_reverse_u16((uint16_t)val, bits), bits);
}
#if defined(zig_ez80)
static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) {
uint24_t full_res;
#if zig_has_builtin(bitreverse24)
full_res = __builtin_bitreverse24(val);
#else
full_res = (uint24_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 16 |
(uint24_t)zig_bit_reverse_u16((uint16_t)(val >> 8), 16) >> 0;
#endif
return zig_wrap_u24(full_res >> (24 - bits), bits);
}
static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) {
return zig_wrap_i24((int24_t)zig_bit_reverse_u24((uint24_t)val, bits), bits);
}
#endif
static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) {
uint32_t full_res;
#if zig_has_builtin(bitreverse32)
@@ -1309,6 +1613,23 @@ static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) {
return zig_wrap_i32((int32_t)zig_bit_reverse_u32((uint32_t)val, bits), bits);
}
#if defined(zig_ez80)
static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) {
uint48_t full_res;
#if zig_has_builtin(bitreverse48)
full_res = __builtin_bitreverse48(val);
#else
full_res = (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 0), 24) << 24 |
(uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 24), 24) >> 0;
#endif
return zig_wrap_u32(full_res >> (48 - bits), bits);
}
static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) {
return zig_wrap_i48((int48_t)zig_bit_reverse_u48((uint48_t)val, bits), bits);
}
#endif
static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) {
uint64_t full_res;
#if zig_has_builtin(bitreverse64)
@@ -1350,7 +1671,13 @@ static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) {
#endif
zig_builtin_popcount(8)
zig_builtin_popcount(16)
#if defined(zig_ez80)
zig_builtin_popcount(24)
#endif
zig_builtin_popcount(32)
#if defined(zig_ez80)
zig_builtin_popcount(48)
#endif
zig_builtin_popcount(64)
#define zig_builtin_ctz_common(w) \
@@ -1375,7 +1702,13 @@ zig_builtin_popcount(64)
#endif
zig_builtin_ctz(8)
zig_builtin_ctz(16)
#if defined(zig_ez80)
zig_builtin_ctz(24)
#endif
zig_builtin_ctz(32)
#if defined(zig_ez80)
zig_builtin_ctz(48)
#endif
zig_builtin_ctz(64)
#define zig_builtin_clz_common(w) \
@@ -1400,7 +1733,13 @@ zig_builtin_ctz(64)
#endif
zig_builtin_clz(8)
zig_builtin_clz(16)
#if defined(zig_ez80)
zig_builtin_clz(24)
#endif
zig_builtin_clz(32)
#if defined(zig_ez80)
zig_builtin_clz(48)
#endif
zig_builtin_clz(64)
/* ======================== 128-bit Integer Support ========================= */
+3
View File
@@ -1204,6 +1204,9 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
}
pub fn ptrAbiAlignment(target: *const Target) Alignment {
// The eZ80 has 24-bit pointers, which aren't exact powers of two, tripping
// the assert. The alignment of eZ80 pointers is 1, so we bypass the check.
if (target.cpu.arch == .ez80) return .@"1";
return .fromNonzeroByteUnits(@divExact(target.ptrBitWidth(), 8));
}
pub fn ptrAbiSize(target: *const Target) u64 {
+5
View File
@@ -4022,6 +4022,9 @@ pub fn atomicPtrAlignment(
) AtomicPtrAlignmentError!Alignment {
const target = zcu.getTarget();
const max_atomic_bits: u16 = switch (target.cpu.arch) {
.ez80,
=> 8,
.aarch64,
.aarch64_be,
=> 128,
@@ -4615,6 +4618,8 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
.avr_signal,
=> true,
.ez80_tiflags => true,
.naked => true,
else => false,
+23
View File
@@ -248,7 +248,9 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
.{ "inline", {} },
.{ "int", {} },
.{ "int16_t", {} },
.{ "int24_t", {} },
.{ "int32_t", {} },
.{ "int48_t", {} },
.{ "int64_t", {} },
.{ "int8_t", {} },
.{ "intptr_t", {} },
@@ -270,7 +272,9 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
.{ "typedef", {} },
.{ "typeof", {} },
.{ "uint16_t", {} },
.{ "uint24_t", {} },
.{ "uint32_t", {} },
.{ "uint48_t", {} },
.{ "uint64_t", {} },
.{ "uint8_t", {} },
.{ "uintptr_t", {} },
@@ -6992,6 +6996,9 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
.x86_64_interrupt,
=> "interrupt",
.ez80_tiflags,
=> "__tiflags__",
else => unreachable, // `Zcu.callconvSupported`
};
}
@@ -7285,7 +7292,9 @@ const FormatInt128 = struct {
switch (data.int_cty) {
.uint8_t,
.uint16_t,
.uint24_t,
.uint32_t,
.uint48_t,
.uint64_t,
.@"unsigned short",
.@"unsigned int",
@@ -7298,6 +7307,8 @@ const FormatInt128 = struct {
.int8_t,
.int16_t,
.int24_t,
.int48_t,
.int32_t,
.int64_t,
.char,
@@ -7443,13 +7454,17 @@ fn minMaxMacroPrefix(int_cty: CType.Int) []const u8 {
.uint8_t => "UINT8",
.uint16_t => "UINT16",
.uint24_t => "UINT24",
.uint32_t => "UINT32",
.uint48_t => "UINT48",
.uint64_t => "UINT64",
.zig_u128 => unreachable,
.int8_t => "INT8",
.int16_t => "INT16",
.int24_t => "INT24",
.int32_t => "INT32",
.int48_t => "INT48",
.int64_t => "INT64",
.zig_i128 => unreachable,
@@ -7475,13 +7490,17 @@ fn intLiteralPrefix(cty: CType.Int, is_global: bool) []const u8 {
.uint8_t => "UINT8_C(",
.uint16_t => "UINT16_C(",
.uint24_t => "UINT24_C(",
.uint32_t => "UINT32_C(",
.uint48_t => "UINT48_C(",
.uint64_t => "UINT64_C(",
.zig_u128 => unreachable,
.int8_t => "INT8_C(",
.int16_t => "INT16_C(",
.int24_t => "INT24_C(",
.int32_t => "INT32_C(",
.int48_t => "INT48_C(",
.int64_t => "INT64_C(",
.zig_i128 => unreachable,
@@ -7507,13 +7526,17 @@ fn intLiteralSuffix(cty: CType.Int) []const u8 {
.uint8_t => ")",
.uint16_t => ")",
.uint24_t => ")",
.uint32_t => ")",
.uint48_t => ")",
.uint64_t => ")",
.zig_u128 => unreachable,
.int8_t => ")",
.int16_t => ")",
.int24_t => ")",
.int32_t => ")",
.int48_t => ")",
.int64_t => ")",
.zig_i128 => unreachable,
+25 -2
View File
@@ -106,13 +106,21 @@ pub const CType = union(enum) {
uint8_t,
uint16_t,
/// eZ80-specific
uint24_t,
uint32_t,
/// eZ80-specific
uint48_t,
uint64_t,
zig_u128,
int8_t,
int16_t,
/// eZ80-specific
int24_t,
int32_t,
/// eZ80-specific
int48_t,
int64_t,
zig_i128,
@@ -138,7 +146,9 @@ pub const CType = union(enum) {
.uint8_t, .int8_t => 8,
.uint16_t, .int16_t => 16,
.uint24_t, .int24_t => 24,
.uint32_t, .int32_t => 32,
.uint48_t, .int48_t => 48,
.uint64_t, .int64_t => 64,
.zig_u128, .zig_i128 => 128,
// zig fmt: on
@@ -154,6 +164,7 @@ pub const CType = union(enum) {
pub const LimbSize = enum {
@"8",
@"16",
@"24",
@"32",
@"64",
@"128",
@@ -161,6 +172,7 @@ pub const CType = union(enum) {
return switch (s) {
.@"8" => 8,
.@"16" => 16,
.@"24" => 24,
.@"32" => 32,
.@"64" => 64,
.@"128" => 128,
@@ -170,6 +182,7 @@ pub const CType = union(enum) {
return switch (s) {
.@"8" => .uint8_t,
.@"16" => .uint16_t,
.@"24" => .uint24_t,
.@"32" => .uint32_t,
.@"64" => .uint64_t,
.@"128" => .zig_u128,
@@ -179,6 +192,7 @@ pub const CType = union(enum) {
return switch (s) {
.@"8" => .int8_t,
.@"16" => .int16_t,
.@"24" => .int24_t,
.@"32" => .int32_t,
.@"64" => .int64_t,
.@"128" => .zig_i128,
@@ -499,6 +513,7 @@ pub const CType = union(enum) {
}
}
fn classifyBitInt(signedness: std.builtin.Signedness, bits: u16, zcu: *const Zcu) IntClass {
const is_ez80 = zcu.getTarget().cpu.arch == .ez80;
return switch (bits) {
0 => .void,
1...8 => switch (signedness) {
@@ -509,11 +524,19 @@ pub const CType = union(enum) {
.unsigned => .{ .small = .uint16_t },
.signed => .{ .small = .int16_t },
},
17...32 => switch (signedness) {
17...24 => switch (signedness) {
.unsigned => .{ .small = if (is_ez80) .uint24_t else .uint32_t },
.signed => .{ .small = if (is_ez80) .int24_t else .int32_t },
},
25...32 => switch (signedness) {
.unsigned => .{ .small = .uint32_t },
.signed => .{ .small = .int32_t },
},
33...64 => switch (signedness) {
33...48 => switch (signedness) {
.unsigned => .{ .small = if (is_ez80) .uint48_t else .uint64_t },
.signed => .{ .small = if (is_ez80) .int48_t else .int64_t },
},
49...64 => switch (signedness) {
.unsigned => .{ .small = .uint64_t },
.signed => .{ .small = .int64_t },
},
+7 -1
View File
@@ -107,6 +107,7 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
.alpha,
.arceb,
.ez80,
.hppa,
.hppa64,
.kalimba,
@@ -244,6 +245,7 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
.other,
.plan9,
.psp,
.tios,
.vita,
=> "unknown",
};
@@ -473,6 +475,7 @@ pub fn dataLayout(target: *const std.Target) []const u8 {
.alpha,
.arceb,
.ez80,
.hppa,
.hppa64,
.kalimba,
@@ -1365,7 +1368,7 @@ pub const Object = struct {
for (0..field_types.len, llvm_args_start..) |field_i, llvm_arg_index| {
const param = wip.arg(@intCast(llvm_arg_index));
const field_ptr = try wip.gepStruct(llvm_ty, arg_ptr, field_i, "");
const alignment: Builder.Alignment = .fromByteUnits(@divExact(target.ptrBitWidth(), 8));
const alignment = Type.ptrAbiAlignment(target).toLlvm();
_ = try wip.store(.normal, param, field_ptr, alignment);
}
@@ -4506,6 +4509,8 @@ pub fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *con
.avr_gnu,
.bpf_std,
.csky_sysv,
.ez80_cet,
.ez80_tiflags,
.hexagon_sysv,
.hexagon_sysv_hvx,
.hppa_elf,
@@ -4903,6 +4908,7 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
// LLVM does does not have a backend for these.
.alpha,
.arceb,
.ez80,
.hppa,
.hppa64,
.kalimba,
+4
View File
@@ -234,6 +234,10 @@ pub fn hasLlvmSupport(target: *const std.Target, ofmt: std.Target.ObjectFormat)
.xtensa,
=> false,
// Third-party LLVM backend exists.
.ez80,
=> false,
// No LLVM backend exists.
.alpha,
.arceb,