authorgravatar for myclevorname@gmail.comSam Connelly <myclevorname@gmail.com> 2026-03-12 09:04:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-16 19:21:16+02:00
log17e0afd0e5d8850171bdfeba9456ebfd38d11e3a
treeb07bd9d85134bc610c35621dea2d6a5d4a1ab36d
parentd092c752f3e2e0e162e9bab57d3f84de6ccde7c9

feat: init eZ80 arch via CBE


10 files changed, 465 insertions(+), 7 deletions(-)

lib/compiler/translate-c/Translator.zig+4
......@@ -475,8 +475,12 @@ pub const builtin_typedef_map = std.StaticStringMap([]const u8).initComptime(.{
475475 .{ "int8_t", "i8" },
476476 .{ "uint16_t", "u16" },
477477 .{ "int16_t", "i16" },
478 .{ "uint24_t", "u24" },
479 .{ "int24_t", "i24" },
478480 .{ "uint32_t", "u32" },
479481 .{ "int32_t", "i32" },
482 .{ "uint48_t", "u48" },
483 .{ "int48_t", "i48" },
480484 .{ "uint64_t", "u64" },
481485 .{ "int64_t", "i64" },
482486 .{ "intptr_t", "isize" },
lib/std/Target.zig+50-3
......@@ -68,6 +68,8 @@ pub const Os = struct {
6868 opengl,
6969 vulkan,
7070
71 tios,
72
7173 // LLVM tags deliberately omitted:
7274 // - bridgeos
7375 // - cheriotrtos
......@@ -207,6 +209,8 @@ pub const Os = struct {
207209 .opencl,
208210 .opengl,
209211 .vulkan,
212
213 .tios,
210214 => .semver,
211215
212216 .hurd => .hurd,
......@@ -670,6 +674,12 @@ pub const Os = struct {
670674 .max = .{ .major = 4, .minor = 6, .patch = 0 },
671675 },
672676 },
677 .tios => .{
678 .semver = .{
679 .min = .{ .major = 5, .minor = 0, .patch = 0 },
680 .max = .{ .major = 5, .minor = 8, .patch = 4 },
681 },
682 },
673683 .vulkan => .{
674684 .semver = .{
675685 .min = .{ .major = 1, .minor = 2, .patch = 0 },
......@@ -758,6 +768,7 @@ pub const wasm = @import("Target/wasm.zig");
758768pub const x86 = @import("Target/x86.zig");
759769pub const xcore = @import("Target/xcore.zig");
760770pub const xtensa = @import("Target/xtensa.zig");
771pub const z80 = @import("Target/generic.zig");
761772
762773pub const Abi = enum {
763774 none,
......@@ -942,6 +953,7 @@ pub const Abi = enum {
942953 .opencl,
943954 .opengl,
944955 .vulkan,
956 .tios,
945957 => .none,
946958 };
947959 }
......@@ -1068,6 +1080,7 @@ pub fn toElfMachine(target: *const Target) std.elf.EM {
10681080 .avr => .AVR,
10691081 .bpfeb, .bpfel => .BPF,
10701082 .csky => .CSKY,
1083 .ez80 => .Z80,
10711084 .hexagon => .QDSP6,
10721085 .hppa, .hppa64 => .PARISC,
10731086 .kalimba => .CSR_KALIMBA,
......@@ -1130,6 +1143,7 @@ pub fn toCoffMachine(target: *const Target) std.coff.IMAGE.FILE.MACHINE {
11301143 .bpfeb,
11311144 .bpfel,
11321145 .csky,
1146 .ez80,
11331147 .hexagon,
11341148 .hppa,
11351149 .hppa64,
......@@ -1336,6 +1350,7 @@ pub const Cpu = struct {
13361350 bpfeb,
13371351 bpfel,
13381352 csky,
1353 ez80,
13391354 hexagon,
13401355 hppa,
13411356 hppa64,
......@@ -1437,6 +1452,7 @@ pub const Cpu = struct {
14371452 x86,
14381453 xcore,
14391454 xtensa,
1455 z80,
14401456 };
14411457
14421458 pub inline fn family(arch: Arch) Family {
......@@ -1449,6 +1465,7 @@ pub const Cpu = struct {
14491465 .avr => .avr,
14501466 .bpfeb, .bpfel => .bpf,
14511467 .csky => .csky,
1468 .ez80 => .z80,
14521469 .hexagon => .hexagon,
14531470 .hppa, .hppa64 => .hppa,
14541471 .kalimba => .kalimba,
......@@ -1678,6 +1695,7 @@ pub const Cpu = struct {
16781695 .x86_64,
16791696 .xcore,
16801697 .xtensa,
1698 .ez80,
16811699 => .little,
16821700
16831701 .aarch64_be,
......@@ -1948,6 +1966,10 @@ pub const Cpu = struct {
19481966 .spirv_fragment,
19491967 .spirv_vertex,
19501968 => &.{ .spirv32, .spirv64 },
1969
1970 .ez80_cet,
1971 .ez80_tiflags,
1972 => &.{.ez80},
19511973 };
19521974 }
19531975 };
......@@ -2236,6 +2258,7 @@ pub fn requiresLibC(target: *const Target) bool {
22362258 .plan9,
22372259 .other,
22382260 .@"3ds",
2261 .tios,
22392262 => false,
22402263 };
22412264}
......@@ -2398,6 +2421,8 @@ pub const DynamicLinker = struct {
23982421 .ps5,
23992422 .psp,
24002423 .vita,
2424
2425 .tios,
24012426 => .none,
24022427 };
24032428 }
......@@ -2815,6 +2840,8 @@ pub const DynamicLinker = struct {
28152840 .opencl,
28162841 .opengl,
28172842 .vulkan,
2843
2844 .tios,
28182845 => none,
28192846
28202847 // 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 {
28492876 .x86_16,
28502877 => 16,
28512878
2879 .ez80,
2880 => 24,
2881
28522882 .arc,
28532883 .arceb,
28542884 .arm,
......@@ -2917,6 +2947,8 @@ pub fn ptrBitWidth(target: *const Target) u16 {
29172947pub fn stackAlignment(target: *const Target) u16 {
29182948 // Overrides for when the stack alignment is not equal to the pointer width.
29192949 switch (target.cpu.arch) {
2950 .ez80,
2951 => return 1,
29202952 .m68k,
29212953 => return 2,
29222954 .amdgcn,
......@@ -2997,6 +3029,7 @@ pub fn cCharSignedness(target: *const Target) std.builtin.Signedness {
29973029 .arc,
29983030 .arceb,
29993031 .csky,
3032 .ez80,
30003033 .hexagon,
30013034 .msp430,
30023035 .powerpc,
......@@ -3364,6 +3397,13 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
33643397 .long, .ulong => return 64,
33653398 .longlong, .ulonglong, .double, .longdouble => return 64,
33663399 },
3400 .tios => switch (c_type) {
3401 .char => return 8,
3402 .short, .ushort => return 16,
3403 .int, .uint => return 24,
3404 .long, .ulong, .float, .double => return 32,
3405 .longlong, .ulonglong, .longdouble => return 64,
3406 },
33673407
33683408 .ps3,
33693409 .contiki,
......@@ -3376,7 +3416,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
33763416pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
33773417 // Overrides for unusual alignments
33783418 switch (target.cpu.arch) {
3379 .avr => return 1,
3419 .avr, .ez80 => return 1,
33803420 .x86 => switch (target.os.tag) {
33813421 .windows, .uefi => switch (c_type) {
33823422 .longlong, .ulonglong, .double => return 8,
......@@ -3406,6 +3446,8 @@ pub fn cTypeAlignment(target: *const Target, c_type: CType) u16 {
34063446 return @min(
34073447 std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8),
34083448 @as(u16, switch (target.cpu.arch) {
3449 .ez80 => 1,
3450
34093451 .msp430,
34103452 .x86_16,
34113453 => 2,
......@@ -3484,7 +3526,7 @@ pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 {
34843526 .longdouble => return 4,
34853527 else => {},
34863528 },
3487 .avr => return 1,
3529 .avr, .ez80 => return 1,
34883530 .x86 => switch (target.os.tag) {
34893531 .windows, .uefi => switch (c_type) {
34903532 .longdouble => switch (target.abi) {
......@@ -3516,6 +3558,8 @@ pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 {
35163558 return @min(
35173559 std.math.ceilPowerOfTwoAssert(u16, (cTypeBitSize(target, c_type) + 7) / 8),
35183560 @as(u16, switch (target.cpu.arch) {
3561 .ez80 => 1,
3562
35193563 .x86_16, .msp430 => 2,
35203564
35213565 .arc,
......@@ -3587,7 +3631,9 @@ pub fn cTypePreferredAlignment(target: *const Target, c_type: CType) u16 {
35873631
35883632pub fn cMaxIntAlignment(target: *const Target) u16 {
35893633 return switch (target.cpu.arch) {
3590 .avr => 1,
3634 .avr,
3635 .ez80,
3636 => 1,
35913637
35923638 .msp430, .x86_16 => 2,
35933639
......@@ -3726,6 +3772,7 @@ pub fn cCallingConvention(target: *const Target) ?std.builtin.CallingConvention
37263772 .amdgcn => .{ .amdgcn_device = .{} },
37273773 .nvptx, .nvptx64 => .nvptx_device,
37283774 .spirv32, .spirv64 => .spirv_device,
3775 .ez80 => .ez80_cet,
37293776 };
37303777}
37313778
lib/std/builtin.zig+4
......@@ -341,6 +341,10 @@ pub const CallingConvention = union(enum(u8)) {
341341 spirv_fragment,
342342 spirv_vertex,
343343
344 // Calling conventions for the `ez80` architecture.
345 ez80_cet,
346 ez80_tiflags,
347
344348 /// Options shared across most calling conventions.
345349 pub const CommonOptions = struct {
346350 /// The boundary the stack is aligned to when the function is called.
lib/zig.h+340-1
......@@ -79,6 +79,9 @@
7979#elif defined(__I86__)
8080#define zig_x86_16
8181#define zig_x86
82#elif defined (__ez80)
83#define zig_ez80
84#define zig_z80
8285#endif
8386
8487#if defined(zig_msvc) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
......@@ -409,6 +412,8 @@
409412#define zig_trap() __asm__ volatile("int $0x3")
410413#elif defined(zig_x86)
411414#define zig_trap() __asm__ volatile("ud2")
415#elif defined(zig_z80)
416#define zig_trap() __asm__ volatile("rst 00h")
412417#else
413418#define zig_trap() zig_trap_unavailable
414419#endif
......@@ -511,7 +516,7 @@ zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);
511516zig_extern void *memset (void *, int, size_t);
512517zig_extern void *memmove (void *, void const *, size_t);
513518
514/* ================ Bool and 8/16/32/64-bit Integer Support ================= */
519/* ================ Bool and 8/16/24/32/48/64-bit Integer Support ================= */
515520
516521#include <limits.h>
517522
......@@ -590,6 +595,16 @@ typedef signed long long int16_t;
590595#define INT16_MAX ( INT16_C(0x7FFF))
591596#define UINT16_MAX ( INT16_C(0xFFFF))
592597
598#if defined(zig_ez80)
599typedef unsigned int uint24_t;
600typedef signed int int24_t;
601#define INT24_C(c) c
602#define UINT24_C(c) c##U
603#endif
604#define INT24_MIN (~INT24_C(0x7FFF))
605#define INT24_MAX ( INT24_C(0x7FFF))
606#define UINT24_MAX ( INT24_C(0xFFFF))
607
593608#if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF
594609typedef unsigned char uint32_t;
595610typedef signed char int32_t;
......@@ -620,6 +635,17 @@ typedef signed long long int32_t;
620635#define INT32_MAX ( INT32_C(0x7FFFFFFF))
621636#define UINT32_MAX ( INT32_C(0xFFFFFFFF))
622637
638#if defined(zig_ez80)
639typedef unsigned __int48 uint48_t;
640typedef signed __int48 int48_t;
641#define INT48_C(c) c
642/* no suffix */
643#define UINT48_C(c) ((uint48_t)(c))
644#endif
645#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF))
646#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF))
647#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF))
648
623649#if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF
624650typedef unsigned char uint64_t;
625651typedef signed char int64_t;
......@@ -663,10 +689,18 @@ typedef ptrdiff_t intptr_t;
663689#define zig_maxInt_i16 INT16_MAX
664690#define zig_minInt_u16 UINT16_C(0)
665691#define zig_maxInt_u16 UINT16_MAX
692#define zig_minInt_i24 INT24_MIN
693#define zig_maxInt_i24 INT24_MAX
694#define zig_minInt_u24 UINT24_C(0)
695#define zig_maxInt_u24 UINT24_MAX
666696#define zig_minInt_i32 INT32_MIN
667697#define zig_maxInt_i32 INT32_MAX
668698#define zig_minInt_u32 UINT32_C(0)
669699#define zig_maxInt_u32 UINT32_MAX
700#define zig_minInt_i48 INT48_MIN
701#define zig_maxInt_i48 INT48_MAX
702#define zig_minInt_u48 UINT48_C(0)
703#define zig_maxInt_u48 UINT48_MAX
670704#define zig_minInt_i64 INT64_MIN
671705#define zig_maxInt_i64 INT64_MAX
672706#define zig_minInt_u64 UINT64_C(0)
......@@ -786,6 +820,17 @@ zig_int_helpers(16, unsigned long long)
786820#else
787821zig_int_helpers(16, uint16_t)
788822#endif
823#if defined(zig_ez80)
824#if UINT24_MAX <= UINT_MAX
825zig_int_helpers(24, unsigned int)
826#elif UINT24_MAX <= ULONG_MAX
827zig_int_helpers(24, unsigned long)
828#elif UINT24_MAX <= ULLONG_MAX
829zig_int_helpers(24, unsigned long long)
830#else
831zig_int_helpers(24, uint24_t)
832#endif
833#endif
789834#if UINT32_MAX <= UINT_MAX
790835zig_int_helpers(32, unsigned int)
791836#elif UINT32_MAX <= ULONG_MAX
......@@ -795,6 +840,17 @@ zig_int_helpers(32, unsigned long long)
795840#else
796841zig_int_helpers(32, uint32_t)
797842#endif
843#if defined(zig_ez80)
844#if UINT24_MAX <= UINT_MAX
845zig_int_helpers(48, unsigned int)
846#elif UINT24_MAX <= ULONG_MAX
847zig_int_helpers(48, unsigned long)
848#elif UINT24_MAX <= ULLONG_MAX
849zig_int_helpers(48, unsigned long long)
850#else
851zig_int_helpers(48, uint48_t)
852#endif
853#endif
798854#if UINT64_MAX <= UINT_MAX
799855zig_int_helpers(64, unsigned int)
800856#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
909965#endif
910966}
911967
968#if defined(zig_ez80)
969static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
970#if zig_has_builtin(add_overflow) || defined(zig_gcc)
971 uint24_t full_res;
972 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
973 *res = zig_wrap_u24(full_res, bits);
974 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
975#else
976 uint32_t full_res;
977 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
978 *res = (uint24_t)full_res;
979 return overflow;
980#endif
981}
982
983static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) {
984#if zig_has_builtin(add_overflow) || defined(zig_gcc)
985 int24_t full_res;
986 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
987 *res = zig_wrap_i24(full_res, bits);
988 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
989#else
990 int32_t full_res;
991 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
992 *res = (int24_t)full_res;
993 return overflow;
994#endif
995}
996#endif
997
998#if defined(zig_ez80)
999static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1000#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1001 uint48_t full_res;
1002 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1003 *res = zig_wrap_u48(full_res, bits);
1004 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1005#else
1006 uint64_t full_res;
1007 bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits);
1008 *res = (uint48_t)full_res;
1009 return overflow;
1010#endif
1011}
1012
1013static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) {
1014#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1015 int48_t full_res;
1016 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1017 *res = zig_wrap_i48(full_res, bits);
1018 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1019#else
1020 int64_t full_res;
1021 bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits);
1022 *res = (int48_t)full_res;
1023 return overflow;
1024#endif
1025}
1026#endif
1027
9121028static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
9131029#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
9141030 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
9331049 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
9341050}
9351051
1052
9361053static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
9371054#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
9381055 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
10131130#endif
10141131}
10151132
1133#if defined(zig_ez80)
1134static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1135#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1136 uint24_t full_res;
1137 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1138 *res = zig_wrap_u24(full_res, bits);
1139 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1140#else
1141 uint32_t full_res;
1142 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1143 *res = (uint24_t)full_res;
1144 return overflow;
1145#endif
1146}
1147
1148static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) {
1149#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1150 int24_t full_res;
1151 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1152 *res = zig_wrap_i24(full_res, bits);
1153 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1154#else
1155 int32_t full_res;
1156 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1157 *res = (int24_t)full_res;
1158 return overflow;
1159#endif
1160}
1161#endif
1162
1163#if defined(zig_ez80)
1164static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1165#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1166 uint48_t full_res;
1167 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1168 *res = zig_wrap_u48(full_res, bits);
1169 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1170#else
1171 uint64_t full_res;
1172 bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits);
1173 *res = (uint48_t)full_res;
1174 return overflow;
1175#endif
1176}
1177
1178static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) {
1179#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1180 int48_t full_res;
1181 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1182 *res = zig_wrap_i48(full_res, bits);
1183 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1184#else
1185 int64_t full_res;
1186 bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits);
1187 *res = (int48_t)full_res;
1188 return overflow;
1189#endif
1190}
1191#endif
1192
10161193static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
10171194#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
10181195 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
11211298#endif
11221299}
11231300
1301#if defined(zig_ez80)
1302static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1303#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1304 uint24_t full_res;
1305 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1306 *res = zig_wrap_u24(full_res, bits);
1307 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1308#else
1309 uint32_t full_res;
1310 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1311 *res = (uint24_t)full_res;
1312 return overflow;
1313#endif
1314}
1315
1316static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) {
1317#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1318 int24_t full_res;
1319 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1320 *res = zig_wrap_i24(full_res, bits);
1321 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1322#else
1323 int32_t full_res;
1324 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1325 *res = (int24_t)full_res;
1326 return overflow;
1327#endif
1328}
1329#endif
1330
1331#if defined(zig_ez80)
1332static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1333#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1334 uint48_t full_res;
1335 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1336 *res = zig_wrap_u48(full_res, bits);
1337 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1338#else
1339 uint64_t full_res;
1340 bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits);
1341 *res = (uint48_t)full_res;
1342 return overflow;
1343#endif
1344}
1345
1346static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) {
1347#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1348 int48_t full_res;
1349 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1350 *res = zig_wrap_i48(full_res, bits);
1351 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1352#else
1353 int64_t full_res;
1354 bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits);
1355 *res = (int48_t)full_res;
1356 return overflow;
1357#endif
1358}
1359#endif
1360
11241361#define zig_int_builtins(w) \
11251362 static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
11261363 *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
11801417 }
11811418zig_int_builtins(8)
11821419zig_int_builtins(16)
1420#if defined(zig_ez80)
1421zig_int_builtins(24)
1422#endif
11831423zig_int_builtins(32)
1424#if defined(zig_ez80)
1425zig_int_builtins(48)
1426#endif
11841427zig_int_builtins(64)
11851428
11861429#define zig_builtin8(name, val) __builtin_##name(val)
......@@ -1189,6 +1432,11 @@ typedef unsigned int zig_Builtin8;
11891432#define zig_builtin16(name, val) __builtin_##name(val)
11901433typedef unsigned int zig_Builtin16;
11911434
1435#if defined(zig_ez80)
1436#define zig_builtin24(name, val) __builtin_##name(val)
1437typedef unsigned int zig_Builtin24;
1438#endif
1439
11921440#if INT_MIN <= INT32_MIN
11931441#define zig_builtin32(name, val) __builtin_##name(val)
11941442typedef unsigned int zig_Builtin32;
......@@ -1197,6 +1445,11 @@ typedef unsigned int zig_Builtin32;
11971445typedef unsigned long zig_Builtin32;
11981446#endif
11991447
1448#if defined(zig_ez80)
1449#define zig_builtin48(name, val) __builtin_##name(val)
1450typedef unsigned long long zig_Builtin48;
1451#endif
1452
12001453#if INT_MIN <= INT64_MIN
12011454#define zig_builtin64(name, val) __builtin_##name(val)
12021455typedef unsigned int zig_Builtin64;
......@@ -1231,6 +1484,23 @@ static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) {
12311484 return zig_wrap_i16((int16_t)zig_byte_swap_u16((uint16_t)val, bits), bits);
12321485}
12331486
1487#if defined(zig_ez80)
1488static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) {
1489 uint24_t full_res;
1490#if zig_has_builtin(bswap24) || defined(zig_gcc)
1491 full_res = __builtin_bswap24(val);
1492#else
1493 full_res = (uint24_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 16 |
1494 (uint24_t)zig_byte_swap_u16((uint16_t)(val >> 8), 16) >> 0;
1495#endif
1496 return zig_wrap_u24(full_res >> (24 - bits), bits);
1497}
1498
1499static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) {
1500 return zig_wrap_i24((int24_t)zig_byte_swap_u24((uint24_t)val, bits), bits);
1501}
1502#endif
1503
12341504static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) {
12351505 uint32_t full_res;
12361506#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) {
12461516 return zig_wrap_i32((int32_t)zig_byte_swap_u32((uint32_t)val, bits), bits);
12471517}
12481518
1519#if defined(zig_ez80)
1520static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) {
1521 uint48_t full_res;
1522#if zig_has_builtin(bswap48) || defined(zig_gcc)
1523 full_res = __builtin_bswap48(val);
1524#else
1525 full_res = (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 0), 24) << 24 |
1526 (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 24), 24) >> 0;
1527#endif
1528 return zig_wrap_u48(full_res >> (48 - bits), bits);
1529}
1530
1531static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) {
1532 return zig_wrap_i48((int48_t)zig_byte_swap_u48((uint48_t)val, bits), bits);
1533}
1534#endif
1535
12491536static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) {
12501537 uint64_t full_res;
12511538#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) {
12941581 return zig_wrap_i16((int16_t)zig_bit_reverse_u16((uint16_t)val, bits), bits);
12951582}
12961583
1584#if defined(zig_ez80)
1585static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) {
1586 uint24_t full_res;
1587#if zig_has_builtin(bitreverse24)
1588 full_res = __builtin_bitreverse24(val);
1589#else
1590 full_res = (uint24_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 16 |
1591 (uint24_t)zig_bit_reverse_u16((uint16_t)(val >> 8), 16) >> 0;
1592#endif
1593 return zig_wrap_u24(full_res >> (24 - bits), bits);
1594}
1595
1596static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) {
1597 return zig_wrap_i24((int24_t)zig_bit_reverse_u24((uint24_t)val, bits), bits);
1598}
1599#endif
1600
12971601static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) {
12981602 uint32_t full_res;
12991603#if zig_has_builtin(bitreverse32)
......@@ -1309,6 +1613,23 @@ static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) {
13091613 return zig_wrap_i32((int32_t)zig_bit_reverse_u32((uint32_t)val, bits), bits);
13101614}
13111615
1616#if defined(zig_ez80)
1617static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) {
1618 uint48_t full_res;
1619#if zig_has_builtin(bitreverse48)
1620 full_res = __builtin_bitreverse48(val);
1621#else
1622 full_res = (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 0), 24) << 24 |
1623 (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 24), 24) >> 0;
1624#endif
1625 return zig_wrap_u32(full_res >> (48 - bits), bits);
1626}
1627
1628static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) {
1629 return zig_wrap_i48((int48_t)zig_bit_reverse_u48((uint48_t)val, bits), bits);
1630}
1631#endif
1632
13121633static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) {
13131634 uint64_t full_res;
13141635#if zig_has_builtin(bitreverse64)
......@@ -1350,7 +1671,13 @@ static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) {
13501671#endif
13511672zig_builtin_popcount(8)
13521673zig_builtin_popcount(16)
1674#if defined(zig_ez80)
1675zig_builtin_popcount(24)
1676#endif
13531677zig_builtin_popcount(32)
1678#if defined(zig_ez80)
1679zig_builtin_popcount(48)
1680#endif
13541681zig_builtin_popcount(64)
13551682
13561683#define zig_builtin_ctz_common(w) \
......@@ -1375,7 +1702,13 @@ zig_builtin_popcount(64)
13751702#endif
13761703zig_builtin_ctz(8)
13771704zig_builtin_ctz(16)
1705#if defined(zig_ez80)
1706zig_builtin_ctz(24)
1707#endif
13781708zig_builtin_ctz(32)
1709#if defined(zig_ez80)
1710zig_builtin_ctz(48)
1711#endif
13791712zig_builtin_ctz(64)
13801713
13811714#define zig_builtin_clz_common(w) \
......@@ -1400,7 +1733,13 @@ zig_builtin_ctz(64)
14001733#endif
14011734zig_builtin_clz(8)
14021735zig_builtin_clz(16)
1736#if defined(zig_ez80)
1737zig_builtin_clz(24)
1738#endif
14031739zig_builtin_clz(32)
1740#if defined(zig_ez80)
1741zig_builtin_clz(48)
1742#endif
14041743zig_builtin_clz(64)
14051744
14061745/* ======================== 128-bit Integer Support ========================= */
src/Type.zig+3
......@@ -1204,6 +1204,9 @@ pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
12041204}
12051205
12061206pub fn ptrAbiAlignment(target: *const Target) Alignment {
1207 // The eZ80 has 24-bit pointers, which aren't exact powers of two, tripping
1208 // the assert. The alignment of eZ80 pointers is 1, so we bypass the check.
1209 if (target.cpu.arch == .ez80) return .@"1";
12071210 return .fromNonzeroByteUnits(@divExact(target.ptrBitWidth(), 8));
12081211}
12091212pub fn ptrAbiSize(target: *const Target) u64 {
src/Zcu.zig+5
......@@ -4022,6 +4022,9 @@ pub fn atomicPtrAlignment(
40224022) AtomicPtrAlignmentError!Alignment {
40234023 const target = zcu.getTarget();
40244024 const max_atomic_bits: u16 = switch (target.cpu.arch) {
4025 .ez80,
4026 => 8,
4027
40254028 .aarch64,
40264029 .aarch64_be,
40274030 => 128,
......@@ -4615,6 +4618,8 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
46154618 .avr_signal,
46164619 => true,
46174620
4621 .ez80_tiflags => true,
4622
46184623 .naked => true,
46194624
46204625 else => false,
src/codegen/c.zig+23
......@@ -248,7 +248,9 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
248248 .{ "inline", {} },
249249 .{ "int", {} },
250250 .{ "int16_t", {} },
251 .{ "int24_t", {} },
251252 .{ "int32_t", {} },
253 .{ "int48_t", {} },
252254 .{ "int64_t", {} },
253255 .{ "int8_t", {} },
254256 .{ "intptr_t", {} },
......@@ -270,7 +272,9 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
270272 .{ "typedef", {} },
271273 .{ "typeof", {} },
272274 .{ "uint16_t", {} },
275 .{ "uint24_t", {} },
273276 .{ "uint32_t", {} },
277 .{ "uint48_t", {} },
274278 .{ "uint64_t", {} },
275279 .{ "uint8_t", {} },
276280 .{ "uintptr_t", {} },
......@@ -6992,6 +6996,9 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
69926996 .x86_64_interrupt,
69936997 => "interrupt",
69946998
6999 .ez80_tiflags,
7000 => "__tiflags__",
7001
69957002 else => unreachable, // `Zcu.callconvSupported`
69967003 };
69977004}
......@@ -7285,7 +7292,9 @@ const FormatInt128 = struct {
72857292 switch (data.int_cty) {
72867293 .uint8_t,
72877294 .uint16_t,
7295 .uint24_t,
72887296 .uint32_t,
7297 .uint48_t,
72897298 .uint64_t,
72907299 .@"unsigned short",
72917300 .@"unsigned int",
......@@ -7298,6 +7307,8 @@ const FormatInt128 = struct {
72987307
72997308 .int8_t,
73007309 .int16_t,
7310 .int24_t,
7311 .int48_t,
73017312 .int32_t,
73027313 .int64_t,
73037314 .char,
......@@ -7443,13 +7454,17 @@ fn minMaxMacroPrefix(int_cty: CType.Int) []const u8 {
74437454
74447455 .uint8_t => "UINT8",
74457456 .uint16_t => "UINT16",
7457 .uint24_t => "UINT24",
74467458 .uint32_t => "UINT32",
7459 .uint48_t => "UINT48",
74477460 .uint64_t => "UINT64",
74487461 .zig_u128 => unreachable,
74497462
74507463 .int8_t => "INT8",
74517464 .int16_t => "INT16",
7465 .int24_t => "INT24",
74527466 .int32_t => "INT32",
7467 .int48_t => "INT48",
74537468 .int64_t => "INT64",
74547469 .zig_i128 => unreachable,
74557470
......@@ -7475,13 +7490,17 @@ fn intLiteralPrefix(cty: CType.Int, is_global: bool) []const u8 {
74757490
74767491 .uint8_t => "UINT8_C(",
74777492 .uint16_t => "UINT16_C(",
7493 .uint24_t => "UINT24_C(",
74787494 .uint32_t => "UINT32_C(",
7495 .uint48_t => "UINT48_C(",
74797496 .uint64_t => "UINT64_C(",
74807497 .zig_u128 => unreachable,
74817498
74827499 .int8_t => "INT8_C(",
74837500 .int16_t => "INT16_C(",
7501 .int24_t => "INT24_C(",
74847502 .int32_t => "INT32_C(",
7503 .int48_t => "INT48_C(",
74857504 .int64_t => "INT64_C(",
74867505 .zig_i128 => unreachable,
74877506
......@@ -7507,13 +7526,17 @@ fn intLiteralSuffix(cty: CType.Int) []const u8 {
75077526
75087527 .uint8_t => ")",
75097528 .uint16_t => ")",
7529 .uint24_t => ")",
75107530 .uint32_t => ")",
7531 .uint48_t => ")",
75117532 .uint64_t => ")",
75127533 .zig_u128 => unreachable,
75137534
75147535 .int8_t => ")",
75157536 .int16_t => ")",
7537 .int24_t => ")",
75167538 .int32_t => ")",
7539 .int48_t => ")",
75177540 .int64_t => ")",
75187541 .zig_i128 => unreachable,
75197542
src/codegen/c/type.zig+25-2
......@@ -106,13 +106,21 @@ pub const CType = union(enum) {
106106
107107 uint8_t,
108108 uint16_t,
109 /// eZ80-specific
110 uint24_t,
109111 uint32_t,
112 /// eZ80-specific
113 uint48_t,
110114 uint64_t,
111115 zig_u128,
112116
113117 int8_t,
114118 int16_t,
119 /// eZ80-specific
120 int24_t,
115121 int32_t,
122 /// eZ80-specific
123 int48_t,
116124 int64_t,
117125 zig_i128,
118126
......@@ -138,7 +146,9 @@ pub const CType = union(enum) {
138146
139147 .uint8_t, .int8_t => 8,
140148 .uint16_t, .int16_t => 16,
149 .uint24_t, .int24_t => 24,
141150 .uint32_t, .int32_t => 32,
151 .uint48_t, .int48_t => 48,
142152 .uint64_t, .int64_t => 64,
143153 .zig_u128, .zig_i128 => 128,
144154 // zig fmt: on
......@@ -154,6 +164,7 @@ pub const CType = union(enum) {
154164 pub const LimbSize = enum {
155165 @"8",
156166 @"16",
167 @"24",
157168 @"32",
158169 @"64",
159170 @"128",
......@@ -161,6 +172,7 @@ pub const CType = union(enum) {
161172 return switch (s) {
162173 .@"8" => 8,
163174 .@"16" => 16,
175 .@"24" => 24,
164176 .@"32" => 32,
165177 .@"64" => 64,
166178 .@"128" => 128,
......@@ -170,6 +182,7 @@ pub const CType = union(enum) {
170182 return switch (s) {
171183 .@"8" => .uint8_t,
172184 .@"16" => .uint16_t,
185 .@"24" => .uint24_t,
173186 .@"32" => .uint32_t,
174187 .@"64" => .uint64_t,
175188 .@"128" => .zig_u128,
......@@ -179,6 +192,7 @@ pub const CType = union(enum) {
179192 return switch (s) {
180193 .@"8" => .int8_t,
181194 .@"16" => .int16_t,
195 .@"24" => .int24_t,
182196 .@"32" => .int32_t,
183197 .@"64" => .int64_t,
184198 .@"128" => .zig_i128,
......@@ -499,6 +513,7 @@ pub const CType = union(enum) {
499513 }
500514 }
501515 fn classifyBitInt(signedness: std.builtin.Signedness, bits: u16, zcu: *const Zcu) IntClass {
516 const is_ez80 = zcu.getTarget().cpu.arch == .ez80;
502517 return switch (bits) {
503518 0 => .void,
504519 1...8 => switch (signedness) {
......@@ -509,11 +524,19 @@ pub const CType = union(enum) {
509524 .unsigned => .{ .small = .uint16_t },
510525 .signed => .{ .small = .int16_t },
511526 },
512 17...32 => switch (signedness) {
527 17...24 => switch (signedness) {
528 .unsigned => .{ .small = if (is_ez80) .uint24_t else .uint32_t },
529 .signed => .{ .small = if (is_ez80) .int24_t else .int32_t },
530 },
531 25...32 => switch (signedness) {
513532 .unsigned => .{ .small = .uint32_t },
514533 .signed => .{ .small = .int32_t },
515534 },
516 33...64 => switch (signedness) {
535 33...48 => switch (signedness) {
536 .unsigned => .{ .small = if (is_ez80) .uint48_t else .uint64_t },
537 .signed => .{ .small = if (is_ez80) .int48_t else .int64_t },
538 },
539 49...64 => switch (signedness) {
517540 .unsigned => .{ .small = .uint64_t },
518541 .signed => .{ .small = .int64_t },
519542 },
src/codegen/llvm.zig+7-1
......@@ -107,6 +107,7 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
107107
108108 .alpha,
109109 .arceb,
110 .ez80,
110111 .hppa,
111112 .hppa64,
112113 .kalimba,
......@@ -244,6 +245,7 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
244245 .other,
245246 .plan9,
246247 .psp,
248 .tios,
247249 .vita,
248250 => "unknown",
249251 };
......@@ -473,6 +475,7 @@ pub fn dataLayout(target: *const std.Target) []const u8 {
473475
474476 .alpha,
475477 .arceb,
478 .ez80,
476479 .hppa,
477480 .hppa64,
478481 .kalimba,
......@@ -1365,7 +1368,7 @@ pub const Object = struct {
13651368 for (0..field_types.len, llvm_args_start..) |field_i, llvm_arg_index| {
13661369 const param = wip.arg(@intCast(llvm_arg_index));
13671370 const field_ptr = try wip.gepStruct(llvm_ty, arg_ptr, field_i, "");
1368 const alignment: Builder.Alignment = .fromByteUnits(@divExact(target.ptrBitWidth(), 8));
1371 const alignment = Type.ptrAbiAlignment(target).toLlvm();
13691372 _ = try wip.store(.normal, param, field_ptr, alignment);
13701373 }
13711374
......@@ -4506,6 +4509,8 @@ pub fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *con
45064509 .avr_gnu,
45074510 .bpf_std,
45084511 .csky_sysv,
4512 .ez80_cet,
4513 .ez80_tiflags,
45094514 .hexagon_sysv,
45104515 .hexagon_sysv_hvx,
45114516 .hppa_elf,
......@@ -4903,6 +4908,7 @@ pub fn initializeLLVMTarget(arch: std.Target.Cpu.Arch) void {
49034908 // LLVM does does not have a backend for these.
49044909 .alpha,
49054910 .arceb,
4911 .ez80,
49064912 .hppa,
49074913 .hppa64,
49084914 .kalimba,
src/target.zig+4
......@@ -234,6 +234,10 @@ pub fn hasLlvmSupport(target: *const std.Target, ofmt: std.Target.ObjectFormat)
234234 .xtensa,
235235 => false,
236236
237 // Third-party LLVM backend exists.
238 .ez80,
239 => false,
240
237241 // No LLVM backend exists.
238242 .alpha,
239243 .arceb,