authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-11-22 23:33:58-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-11-22 23:33:58-07:00
log4ec27a4e2508049ce0d9b6e3cc149c0403c7014b
tree381f694dba4cd63b6de67ef3902e2bf54826fc85
parent0b28133ec239d62fc0df7460ac8b8e12b08ee88f

C backend: implement vector reduce and overflow intrinsics


5 files changed, 375 insertions(+), 80 deletions(-)

lib/zig.h+146
...@@ -344,6 +344,12 @@ static inline zig_bool zig_addo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_...@@ -344,6 +344,12 @@ static inline zig_bool zig_addo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_
344#endif344#endif
345}345}
346346
347static inline void zig_vaddo_u32(zig_u8 *ov, zig_u32 *res, int n,
348 const zig_u32 *lhs, const zig_u32 *rhs, zig_u8 bits)
349{
350 for (int i = 0; i < n; ++i) ov[i] = zig_addo_u32(&res[i], lhs[i], rhs[i], bits);
351}
352
347zig_extern zig_i32 __addosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);353zig_extern zig_i32 __addosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
348static inline zig_bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {354static inline zig_bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
349#if zig_has_builtin(add_overflow)355#if zig_has_builtin(add_overflow)
...@@ -358,6 +364,12 @@ static inline zig_bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_...@@ -358,6 +364,12 @@ static inline zig_bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_
358 return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits);364 return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits);
359}365}
360366
367static inline void zig_vaddo_i32(zig_u8 *ov, zig_i32 *res, int n,
368 const zig_i32 *lhs, const zig_i32 *rhs, zig_u8 bits)
369{
370 for (int i = 0; i < n; ++i) ov[i] = zig_addo_i32(&res[i], lhs[i], rhs[i], bits);
371}
372
361static inline zig_bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {373static inline zig_bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {
362#if zig_has_builtin(add_overflow)374#if zig_has_builtin(add_overflow)
363 zig_u64 full_res;375 zig_u64 full_res;
...@@ -370,6 +382,12 @@ static inline zig_bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_...@@ -370,6 +382,12 @@ static inline zig_bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_
370#endif382#endif
371}383}
372384
385static inline void zig_vaddo_u64(zig_u8 *ov, zig_u64 *res, int n,
386 const zig_u64 *lhs, const zig_u64 *rhs, zig_u8 bits)
387{
388 for (int i = 0; i < n; ++i) ov[i] = zig_addo_u64(&res[i], lhs[i], rhs[i], bits);
389}
390
373zig_extern zig_i64 __addodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);391zig_extern zig_i64 __addodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
374static inline zig_bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {392static inline zig_bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
375#if zig_has_builtin(add_overflow)393#if zig_has_builtin(add_overflow)
...@@ -384,6 +402,12 @@ static inline zig_bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_...@@ -384,6 +402,12 @@ static inline zig_bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_
384 return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits);402 return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits);
385}403}
386404
405static inline void zig_vaddo_i64(zig_u8 *ov, zig_i64 *res, int n,
406 const zig_i64 *lhs, const zig_i64 *rhs, zig_u8 bits)
407{
408 for (int i = 0; i < n; ++i) ov[i] = zig_addo_i64(&res[i], lhs[i], rhs[i], bits);
409}
410
387static inline zig_bool zig_addo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {411static inline zig_bool zig_addo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {
388#if zig_has_builtin(add_overflow)412#if zig_has_builtin(add_overflow)
389 zig_u8 full_res;413 zig_u8 full_res;
...@@ -395,6 +419,12 @@ static inline zig_bool zig_addo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 b...@@ -395,6 +419,12 @@ static inline zig_bool zig_addo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 b
395#endif419#endif
396}420}
397421
422static inline void zig_vaddo_u8(zig_u8 *ov, zig_u8 *res, int n,
423 const zig_u8 *lhs, const zig_u8 *rhs, zig_u8 bits)
424{
425 for (int i = 0; i < n; ++i) ov[i] = zig_addo_u8(&res[i], lhs[i], rhs[i], bits);
426}
427
398static inline zig_bool zig_addo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {428static inline zig_bool zig_addo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {
399#if zig_has_builtin(add_overflow)429#if zig_has_builtin(add_overflow)
400 zig_i8 full_res;430 zig_i8 full_res;
...@@ -406,6 +436,12 @@ static inline zig_bool zig_addo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 b...@@ -406,6 +436,12 @@ static inline zig_bool zig_addo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 b
406#endif436#endif
407}437}
408438
439static inline void zig_vaddo_i8(zig_u8 *ov, zig_i8 *res, int n,
440 const zig_i8 *lhs, const zig_i8 *rhs, zig_u8 bits)
441{
442 for (int i = 0; i < n; ++i) ov[i] = zig_addo_i8(&res[i], lhs[i], rhs[i], bits);
443}
444
409static inline zig_bool zig_addo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {445static inline zig_bool zig_addo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {
410#if zig_has_builtin(add_overflow)446#if zig_has_builtin(add_overflow)
411 zig_u16 full_res;447 zig_u16 full_res;
...@@ -417,6 +453,12 @@ static inline zig_bool zig_addo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_...@@ -417,6 +453,12 @@ static inline zig_bool zig_addo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_
417#endif453#endif
418}454}
419455
456static inline void zig_vaddo_u16(zig_u8 *ov, zig_u16 *res, int n,
457 const zig_u16 *lhs, const zig_u16 *rhs, zig_u8 bits)
458{
459 for (int i = 0; i < n; ++i) ov[i] = zig_addo_u16(&res[i], lhs[i], rhs[i], bits);
460}
461
420static inline zig_bool zig_addo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {462static inline zig_bool zig_addo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {
421#if zig_has_builtin(add_overflow)463#if zig_has_builtin(add_overflow)
422 zig_i16 full_res;464 zig_i16 full_res;
...@@ -428,6 +470,12 @@ static inline zig_bool zig_addo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_...@@ -428,6 +470,12 @@ static inline zig_bool zig_addo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_
428#endif470#endif
429}471}
430472
473static inline void zig_vaddo_i16(zig_u8 *ov, zig_i16 *res, int n,
474 const zig_i16 *lhs, const zig_i16 *rhs, zig_u8 bits)
475{
476 for (int i = 0; i < n; ++i) ov[i] = zig_addo_i16(&res[i], lhs[i], rhs[i], bits);
477}
478
431static inline zig_bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {479static inline zig_bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {
432#if zig_has_builtin(sub_overflow)480#if zig_has_builtin(sub_overflow)
433 zig_u32 full_res;481 zig_u32 full_res;
...@@ -440,6 +488,12 @@ static inline zig_bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_...@@ -440,6 +488,12 @@ static inline zig_bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_
440#endif488#endif
441}489}
442490
491static inline void zig_vsubo_u32(zig_u8 *ov, zig_u32 *res, int n,
492 const zig_u32 *lhs, const zig_u32 *rhs, zig_u8 bits)
493{
494 for (int i = 0; i < n; ++i) ov[i] = zig_subo_u32(&res[i], lhs[i], rhs[i], bits);
495}
496
443zig_extern zig_i32 __subosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);497zig_extern zig_i32 __subosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
444static inline zig_bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {498static inline zig_bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
445#if zig_has_builtin(sub_overflow)499#if zig_has_builtin(sub_overflow)
...@@ -454,6 +508,12 @@ static inline zig_bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_...@@ -454,6 +508,12 @@ static inline zig_bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_
454 return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits);508 return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits);
455}509}
456510
511static inline void zig_vsubo_i32(zig_u8 *ov, zig_i32 *res, int n,
512 const zig_i32 *lhs, const zig_i32 *rhs, zig_u8 bits)
513{
514 for (int i = 0; i < n; ++i) ov[i] = zig_subo_i32(&res[i], lhs[i], rhs[i], bits);
515}
516
457static inline zig_bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {517static inline zig_bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {
458#if zig_has_builtin(sub_overflow)518#if zig_has_builtin(sub_overflow)
459 zig_u64 full_res;519 zig_u64 full_res;
...@@ -466,6 +526,12 @@ static inline zig_bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_...@@ -466,6 +526,12 @@ static inline zig_bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_
466#endif526#endif
467}527}
468528
529static inline void zig_vsubo_u64(zig_u8 *ov, zig_u64 *res, int n,
530 const zig_u64 *lhs, const zig_u64 *rhs, zig_u8 bits)
531{
532 for (int i = 0; i < n; ++i) ov[i] = zig_subo_u64(&res[i], lhs[i], rhs[i], bits);
533}
534
469zig_extern zig_i64 __subodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);535zig_extern zig_i64 __subodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
470static inline zig_bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {536static inline zig_bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
471#if zig_has_builtin(sub_overflow)537#if zig_has_builtin(sub_overflow)
...@@ -480,6 +546,12 @@ static inline zig_bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_...@@ -480,6 +546,12 @@ static inline zig_bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_
480 return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits);546 return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits);
481}547}
482548
549static inline void zig_vsubo_i64(zig_u8 *ov, zig_i64 *res, int n,
550 const zig_i64 *lhs, const zig_i64 *rhs, zig_u8 bits)
551{
552 for (int i = 0; i < n; ++i) ov[i] = zig_subo_i64(&res[i], lhs[i], rhs[i], bits);
553}
554
483static inline zig_bool zig_subo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {555static inline zig_bool zig_subo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {
484#if zig_has_builtin(sub_overflow)556#if zig_has_builtin(sub_overflow)
485 zig_u8 full_res;557 zig_u8 full_res;
...@@ -491,6 +563,12 @@ static inline zig_bool zig_subo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 b...@@ -491,6 +563,12 @@ static inline zig_bool zig_subo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 b
491#endif563#endif
492}564}
493565
566static inline void zig_vsubo_u8(zig_u8 *ov, zig_u8 *res, int n,
567 const zig_u8 *lhs, const zig_u8 *rhs, zig_u8 bits)
568{
569 for (int i = 0; i < n; ++i) ov[i] = zig_subo_u8(&res[i], lhs[i], rhs[i], bits);
570}
571
494static inline zig_bool zig_subo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {572static inline zig_bool zig_subo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {
495#if zig_has_builtin(sub_overflow)573#if zig_has_builtin(sub_overflow)
496 zig_i8 full_res;574 zig_i8 full_res;
...@@ -502,6 +580,13 @@ static inline zig_bool zig_subo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 b...@@ -502,6 +580,13 @@ static inline zig_bool zig_subo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 b
502#endif580#endif
503}581}
504582
583static inline void zig_vsubo_i8(zig_u8 *ov, zig_i8 *res, int n,
584 const zig_i8 *lhs, const zig_i8 *rhs, zig_u8 bits)
585{
586 for (int i = 0; i < n; ++i) ov[i] = zig_subo_i8(&res[i], lhs[i], rhs[i], bits);
587}
588
589
505static inline zig_bool zig_subo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {590static inline zig_bool zig_subo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {
506#if zig_has_builtin(sub_overflow)591#if zig_has_builtin(sub_overflow)
507 zig_u16 full_res;592 zig_u16 full_res;
...@@ -513,6 +598,13 @@ static inline zig_bool zig_subo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_...@@ -513,6 +598,13 @@ static inline zig_bool zig_subo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_
513#endif598#endif
514}599}
515600
601static inline void zig_vsubo_u16(zig_u8 *ov, zig_u16 *res, int n,
602 const zig_u16 *lhs, const zig_u16 *rhs, zig_u8 bits)
603{
604 for (int i = 0; i < n; ++i) ov[i] = zig_subo_u16(&res[i], lhs[i], rhs[i], bits);
605}
606
607
516static inline zig_bool zig_subo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {608static inline zig_bool zig_subo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {
517#if zig_has_builtin(sub_overflow)609#if zig_has_builtin(sub_overflow)
518 zig_i16 full_res;610 zig_i16 full_res;
...@@ -524,6 +616,12 @@ static inline zig_bool zig_subo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_...@@ -524,6 +616,12 @@ static inline zig_bool zig_subo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_
524#endif616#endif
525}617}
526618
619static inline void zig_vsubo_i16(zig_u8 *ov, zig_i16 *res, int n,
620 const zig_i16 *lhs, const zig_i16 *rhs, zig_u8 bits)
621{
622 for (int i = 0; i < n; ++i) ov[i] = zig_subo_i16(&res[i], lhs[i], rhs[i], bits);
623}
624
527static inline zig_bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {625static inline zig_bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) {
528#if zig_has_builtin(mul_overflow)626#if zig_has_builtin(mul_overflow)
529 zig_u32 full_res;627 zig_u32 full_res;
...@@ -536,6 +634,12 @@ static inline zig_bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_...@@ -536,6 +634,12 @@ static inline zig_bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_
536#endif634#endif
537}635}
538636
637static inline void zig_vmulo_u32(zig_u8 *ov, zig_u32 *res, int n,
638 const zig_u32 *lhs, const zig_u32 *rhs, zig_u8 bits)
639{
640 for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u32(&res[i], lhs[i], rhs[i], bits);
641}
642
539zig_extern zig_i32 __mulosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);643zig_extern zig_i32 __mulosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
540static inline zig_bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {644static inline zig_bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
541#if zig_has_builtin(mul_overflow)645#if zig_has_builtin(mul_overflow)
...@@ -550,6 +654,12 @@ static inline zig_bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_...@@ -550,6 +654,12 @@ static inline zig_bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_
550 return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits);654 return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits);
551}655}
552656
657static inline void zig_vmulo_i32(zig_u8 *ov, zig_i32 *res, int n,
658 const zig_i32 *lhs, const zig_i32 *rhs, zig_u8 bits)
659{
660 for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i32(&res[i], lhs[i], rhs[i], bits);
661}
662
553static inline zig_bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {663static inline zig_bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) {
554#if zig_has_builtin(mul_overflow)664#if zig_has_builtin(mul_overflow)
555 zig_u64 full_res;665 zig_u64 full_res;
...@@ -562,6 +672,12 @@ static inline zig_bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_...@@ -562,6 +672,12 @@ static inline zig_bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_
562#endif672#endif
563}673}
564674
675static inline void zig_vmulo_u64(zig_u8 *ov, zig_u64 *res, int n,
676 const zig_u64 *lhs, const zig_u64 *rhs, zig_u8 bits)
677{
678 for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u64(&res[i], lhs[i], rhs[i], bits);
679}
680
565zig_extern zig_i64 __mulodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);681zig_extern zig_i64 __mulodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
566static inline zig_bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {682static inline zig_bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
567#if zig_has_builtin(mul_overflow)683#if zig_has_builtin(mul_overflow)
...@@ -576,6 +692,12 @@ static inline zig_bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_...@@ -576,6 +692,12 @@ static inline zig_bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_
576 return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits);692 return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits);
577}693}
578694
695static inline void zig_vmulo_i64(zig_u8 *ov, zig_i64 *res, int n,
696 const zig_i64 *lhs, const zig_i64 *rhs, zig_u8 bits)
697{
698 for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i64(&res[i], lhs[i], rhs[i], bits);
699}
700
579static inline zig_bool zig_mulo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {701static inline zig_bool zig_mulo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) {
580#if zig_has_builtin(mul_overflow)702#if zig_has_builtin(mul_overflow)
581 zig_u8 full_res;703 zig_u8 full_res;
...@@ -587,6 +709,12 @@ static inline zig_bool zig_mulo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 b...@@ -587,6 +709,12 @@ static inline zig_bool zig_mulo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 b
587#endif709#endif
588}710}
589711
712static inline void zig_vmulo_u8(zig_u8 *ov, zig_u8 *res, int n,
713 const zig_u8 *lhs, const zig_u8 *rhs, zig_u8 bits)
714{
715 for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u8(&res[i], lhs[i], rhs[i], bits);
716}
717
590static inline zig_bool zig_mulo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {718static inline zig_bool zig_mulo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) {
591#if zig_has_builtin(mul_overflow)719#if zig_has_builtin(mul_overflow)
592 zig_i8 full_res;720 zig_i8 full_res;
...@@ -598,6 +726,12 @@ static inline zig_bool zig_mulo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 b...@@ -598,6 +726,12 @@ static inline zig_bool zig_mulo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 b
598#endif726#endif
599}727}
600728
729static inline void zig_vmulo_i8(zig_u8 *ov, zig_i8 *res, int n,
730 const zig_i8 *lhs, const zig_i8 *rhs, zig_u8 bits)
731{
732 for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i8(&res[i], lhs[i], rhs[i], bits);
733}
734
601static inline zig_bool zig_mulo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {735static inline zig_bool zig_mulo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) {
602#if zig_has_builtin(mul_overflow)736#if zig_has_builtin(mul_overflow)
603 zig_u16 full_res;737 zig_u16 full_res;
...@@ -609,6 +743,12 @@ static inline zig_bool zig_mulo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_...@@ -609,6 +743,12 @@ static inline zig_bool zig_mulo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_
609#endif743#endif
610}744}
611745
746static inline void zig_vmulo_u16(zig_u8 *ov, zig_u16 *res, int n,
747 const zig_u16 *lhs, const zig_u16 *rhs, zig_u8 bits)
748{
749 for (int i = 0; i < n; ++i) ov[i] = zig_mulo_u16(&res[i], lhs[i], rhs[i], bits);
750}
751
612static inline zig_bool zig_mulo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {752static inline zig_bool zig_mulo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) {
613#if zig_has_builtin(mul_overflow)753#if zig_has_builtin(mul_overflow)
614 zig_i16 full_res;754 zig_i16 full_res;
...@@ -620,6 +760,12 @@ static inline zig_bool zig_mulo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_...@@ -620,6 +760,12 @@ static inline zig_bool zig_mulo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_
620#endif760#endif
621}761}
622762
763static inline void zig_vmulo_i16(zig_u8 *ov, zig_i16 *res, int n,
764 const zig_i16 *lhs, const zig_i16 *rhs, zig_u8 bits)
765{
766 for (int i = 0; i < n; ++i) ov[i] = zig_mulo_i16(&res[i], lhs[i], rhs[i], bits);
767}
768
623#define zig_int_builtins(w) \769#define zig_int_builtins(w) \
624 static inline zig_u##w zig_shlw_u##w(zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \770 static inline zig_u##w zig_shlw_u##w(zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \
625 return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \771 return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \
src/codegen/c.zig+182-24
...@@ -18,6 +18,12 @@ const Air = @import("../Air.zig");...@@ -18,6 +18,12 @@ const Air = @import("../Air.zig");
18const Liveness = @import("../Liveness.zig");18const Liveness = @import("../Liveness.zig");
19const CType = @import("../type.zig").CType;19const CType = @import("../type.zig").CType;
2020
21const target_util = @import("../target.zig");
22const libcFloatPrefix = target_util.libcFloatPrefix;
23const libcFloatSuffix = target_util.libcFloatSuffix;
24const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev;
25const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;
26
21const Mutability = enum { Const, ConstArgument, Mut };27const Mutability = enum { Const, ConstArgument, Mut };
22const BigIntLimb = std.math.big.Limb;28const BigIntLimb = std.math.big.Limb;
23const BigInt = std.math.big.int;29const BigInt = std.math.big.int;
...@@ -733,7 +739,7 @@ pub const DeclGen = struct {...@@ -733,7 +739,7 @@ pub const DeclGen = struct {
733 try dg.fmtIntLiteral(ty.errorUnionSet(), val),739 try dg.fmtIntLiteral(ty.errorUnionSet(), val),
734 });740 });
735 },741 },
736 .Array => {742 .Array, .Vector => {
737 if (location != .Initializer) {743 if (location != .Initializer) {
738 try writer.writeByte('(');744 try writer.writeByte('(');
739 try dg.renderTypecast(writer, ty);745 try dg.renderTypecast(writer, ty);
...@@ -770,10 +776,10 @@ pub const DeclGen = struct {...@@ -770,10 +776,10 @@ pub const DeclGen = struct {
770 .BoundFn,776 .BoundFn,
771 .Opaque,777 .Opaque,
772 => unreachable,778 => unreachable,
779
773 .Fn,780 .Fn,
774 .Frame,781 .Frame,
775 .AnyFrame,782 .AnyFrame,
776 .Vector,
777 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{783 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{
778 @tagName(tag),784 @tagName(tag),
779 }),785 }),
...@@ -922,7 +928,7 @@ pub const DeclGen = struct {...@@ -922,7 +928,7 @@ pub const DeclGen = struct {
922 => try dg.renderParentPtr(writer, val, ty),928 => try dg.renderParentPtr(writer, val, ty),
923 else => unreachable,929 else => unreachable,
924 },930 },
925 .Array => {931 .Array, .Vector => {
926 if (location == .FunctionArgument) {932 if (location == .FunctionArgument) {
927 try writer.writeByte('(');933 try writer.writeByte('(');
928 try dg.renderTypecast(writer, ty);934 try dg.renderTypecast(writer, ty);
...@@ -1200,7 +1206,6 @@ pub const DeclGen = struct {...@@ -1200,7 +1206,6 @@ pub const DeclGen = struct {
12001206
1201 .Frame,1207 .Frame,
1202 .AnyFrame,1208 .AnyFrame,
1203 .Vector,
1204 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{1209 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{
1205 @tagName(tag),1210 @tagName(tag),
1206 }),1211 }),
...@@ -1746,7 +1751,7 @@ pub const DeclGen = struct {...@@ -1746,7 +1751,7 @@ pub const DeclGen = struct {
1746 if (t.isVolatilePtr()) try w.writeAll(" volatile");1751 if (t.isVolatilePtr()) try w.writeAll(" volatile");
1747 return w.writeAll(" *");1752 return w.writeAll(" *");
1748 },1753 },
1749 .Array => {1754 .Array, .Vector => {
1750 var array_pl = Type.Payload.Array{ .base = .{ .tag = .array }, .data = .{1755 var array_pl = Type.Payload.Array{ .base = .{ .tag = .array }, .data = .{
1751 .len = t.arrayLenIncludingSentinel(),1756 .len = t.arrayLenIncludingSentinel(),
1752 .elem_type = t.childType(),1757 .elem_type = t.childType(),
...@@ -1859,7 +1864,6 @@ pub const DeclGen = struct {...@@ -1859,7 +1864,6 @@ pub const DeclGen = struct {
18591864
1860 .Frame,1865 .Frame,
1861 .AnyFrame,1866 .AnyFrame,
1862 .Vector,
1863 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{1867 => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{
1864 @tagName(tag),1868 @tagName(tag),
1865 }),1869 }),
...@@ -3180,25 +3184,43 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -3180,25 +3184,43 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
3180 const rhs = try f.resolveInst(bin_op.rhs);3184 const rhs = try f.resolveInst(bin_op.rhs);
31813185
3182 const inst_ty = f.air.typeOfIndex(inst);3186 const inst_ty = f.air.typeOfIndex(inst);
3183 const scalar_ty = f.air.typeOf(bin_op.lhs).scalarType();3187 const vector_ty = f.air.typeOf(bin_op.lhs);
3188 const scalar_ty = vector_ty.scalarType();
3184 const w = f.object.writer();3189 const w = f.object.writer();
31853190
3186 const local = try f.allocLocal(inst_ty, .Mut);3191 const local = try f.allocLocal(inst_ty, .Mut);
3187 try w.writeAll(";\n");3192 try w.writeAll(";\n");
31883193
3189 try f.writeCValueMember(w, local, .{ .field = 1 });3194 switch (vector_ty.zigTypeTag()) {
3190 try w.writeAll(" = zig_");3195 .Vector => {
3191 try w.writeAll(operation);3196 try w.writeAll("zig_v");
3192 try w.writeAll("o_");3197 try w.writeAll(operation);
3193 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);3198 try w.writeAll("o_");
3194 try w.writeAll("(&");3199 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3195 try f.writeCValueMember(w, local, .{ .field = 0 });3200 try w.writeAll("(");
3196 try w.writeAll(", ");3201 try f.writeCValueMember(w, local, .{ .field = 1 });
3202 try w.writeAll(", ");
3203 try f.writeCValueMember(w, local, .{ .field = 0 });
3204 try w.print(", {d}, ", .{vector_ty.vectorLen()});
3205 },
3206 else => {
3207 try f.writeCValueMember(w, local, .{ .field = 1 });
3208 try w.writeAll(" = zig_");
3209 try w.writeAll(operation);
3210 try w.writeAll("o_");
3211 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3212 try w.writeAll("(&");
3213 try f.writeCValueMember(w, local, .{ .field = 0 });
3214 try w.writeAll(", ");
3215 },
3216 }
3217
3197 try f.writeCValue(w, lhs, .FunctionArgument);3218 try f.writeCValue(w, lhs, .FunctionArgument);
3198 try w.writeAll(", ");3219 try w.writeAll(", ");
3199 try f.writeCValue(w, rhs, .FunctionArgument);3220 try f.writeCValue(w, rhs, .FunctionArgument);
3200 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);3221 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
3201 try w.writeAll(");\n");3222 try w.writeAll(");\n");
3223
3202 return local;3224 return local;
3203}3225}
32043226
...@@ -5206,16 +5228,153 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5206,16 +5228,153 @@ fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue {
5206fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {5228fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
5207 if (f.liveness.isUnused(inst)) return CValue.none;5229 if (f.liveness.isUnused(inst)) return CValue.none;
52085230
5209 const inst_ty = f.air.typeOfIndex(inst);5231 const target = f.object.dg.module.getTarget();
5232 const scalar_ty = f.air.typeOfIndex(inst);
5210 const reduce = f.air.instructions.items(.data)[inst].reduce;5233 const reduce = f.air.instructions.items(.data)[inst].reduce;
5211 const operand = try f.resolveInst(reduce.operand);5234 const operand = try f.resolveInst(reduce.operand);
5235 const operand_ty = f.air.typeOf(reduce.operand);
5236 const vector_len = operand_ty.vectorLen();
5212 const writer = f.object.writer();5237 const writer = f.object.writer();
5213 const local = try f.allocLocal(inst_ty, .Const);5238
5239 const Op = union(enum) {
5240 call_fn: []const u8,
5241 infix: []const u8,
5242 ternary: []const u8,
5243 };
5244 var fn_name_buf: [64]u8 = undefined;
5245 const op: Op = switch (reduce.operation) {
5246 .And => .{ .infix = " &= " },
5247 .Or => .{ .infix = " |= " },
5248 .Xor => .{ .infix = " ^= " },
5249 .Min => switch (scalar_ty.zigTypeTag()) {
5250 .Int => .{ .ternary = " < " },
5251 .Float => op: {
5252 const float_bits = scalar_ty.floatBits(target);
5253 break :op .{
5254 .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "{s}fmin{s}", .{
5255 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),
5256 }) catch unreachable,
5257 };
5258 },
5259 else => unreachable,
5260 },
5261 .Max => switch (scalar_ty.zigTypeTag()) {
5262 .Int => .{ .ternary = " > " },
5263 .Float => op: {
5264 const float_bits = scalar_ty.floatBits(target);
5265 break :op .{
5266 .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "{s}fmax{s}", .{
5267 libcFloatPrefix(float_bits), libcFloatSuffix(float_bits),
5268 }) catch unreachable,
5269 };
5270 },
5271 else => unreachable,
5272 },
5273 .Add => switch (scalar_ty.zigTypeTag()) {
5274 .Int => .{ .infix = " += " },
5275 .Float => op: {
5276 const float_bits = scalar_ty.floatBits(target);
5277 break :op .{
5278 .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "__add{s}f3", .{
5279 compilerRtFloatAbbrev(float_bits),
5280 }) catch unreachable,
5281 };
5282 },
5283 else => unreachable,
5284 },
5285 .Mul => switch (scalar_ty.zigTypeTag()) {
5286 .Int => .{ .infix = " *= " },
5287 .Float => op: {
5288 const float_bits = scalar_ty.floatBits(target);
5289 break :op .{
5290 .call_fn = std.fmt.bufPrintZ(&fn_name_buf, "__mul{s}f3", .{
5291 compilerRtFloatAbbrev(float_bits),
5292 }) catch unreachable,
5293 };
5294 },
5295 else => unreachable,
5296 },
5297 };
5298
5299 // Reduce a vector by repeatedly applying a function to produce an
5300 // accumulated result.
5301 //
5302 // Equivalent to:
5303 // reduce: {
5304 // var i: usize = 0;
5305 // var accum: T = init;
5306 // while (i < vec.len) : (i += 1) {
5307 // accum = func(accum, vec[i]);
5308 // }
5309 // break :reduce accum;
5310 // }
5311 const it = try f.allocLocal(Type.usize, .Mut);
5312 try writer.writeAll(" = 0;\n");
5313
5314 const accum = try f.allocLocal(scalar_ty, .Mut);
5214 try writer.writeAll(" = ");5315 try writer.writeAll(" = ");
52155316
5216 _ = operand;5317 const init_val = switch (reduce.operation) {
5217 _ = local;5318 .And, .Or, .Xor, .Add => "0",
5218 return f.fail("TODO: C backend: implement airReduce", .{});5319 .Min => switch (scalar_ty.zigTypeTag()) {
5320 .Int => "TODO_intmax",
5321 .Float => "TODO_nan",
5322 else => unreachable,
5323 },
5324 .Max => switch (scalar_ty.zigTypeTag()) {
5325 .Int => "TODO_intmin",
5326 .Float => "TODO_nan",
5327 else => unreachable,
5328 },
5329 .Mul => "1",
5330 };
5331 try writer.writeAll(init_val);
5332 try writer.writeAll(";");
5333 try f.object.indent_writer.insertNewline();
5334 try writer.writeAll("for(;");
5335 try f.writeCValue(writer, it, .Other);
5336 try writer.print("<{d};++", .{vector_len});
5337 try f.writeCValue(writer, it, .Other);
5338 try writer.writeAll(") ");
5339 try f.writeCValue(writer, accum, .Other);
5340
5341 switch (op) {
5342 .call_fn => |fn_name| {
5343 try writer.print(" = {s}(", .{fn_name});
5344 try f.writeCValue(writer, accum, .FunctionArgument);
5345 try writer.writeAll(", ");
5346 try f.writeCValue(writer, operand, .Other);
5347 try writer.writeAll("[");
5348 try f.writeCValue(writer, it, .Other);
5349 try writer.writeAll("])");
5350 },
5351 .infix => |ass| {
5352 try writer.writeAll(ass);
5353 try f.writeCValue(writer, operand, .Other);
5354 try writer.writeAll("[");
5355 try f.writeCValue(writer, it, .Other);
5356 try writer.writeAll("]");
5357 },
5358 .ternary => |cmp| {
5359 try writer.writeAll(" = ");
5360 try f.writeCValue(writer, accum, .Other);
5361 try writer.writeAll(cmp);
5362 try f.writeCValue(writer, operand, .Other);
5363 try writer.writeAll("[");
5364 try f.writeCValue(writer, it, .Other);
5365 try writer.writeAll("] ? ");
5366 try f.writeCValue(writer, accum, .Other);
5367 try writer.writeAll(" : ");
5368 try f.writeCValue(writer, operand, .Other);
5369 try writer.writeAll("[");
5370 try f.writeCValue(writer, it, .Other);
5371 try writer.writeAll("]");
5372 },
5373 }
5374
5375 try writer.writeAll(";\n");
5376
5377 return accum;
5219}5378}
52205379
5221fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {5380fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -5234,7 +5393,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5234,7 +5393,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
5234 const local = try f.allocLocal(inst_ty, mutability);5393 const local = try f.allocLocal(inst_ty, mutability);
5235 try writer.writeAll(" = ");5394 try writer.writeAll(" = ");
5236 switch (inst_ty.zigTypeTag()) {5395 switch (inst_ty.zigTypeTag()) {
5237 .Array => {5396 .Array, .Vector => {
5238 const elem_ty = inst_ty.childType();5397 const elem_ty = inst_ty.childType();
5239 try writer.writeByte('{');5398 try writer.writeByte('{');
5240 var empty = true;5399 var empty = true;
...@@ -5354,7 +5513,6 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5354,7 +5513,6 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
5354 try writer.writeAll(";\n");5513 try writer.writeAll(";\n");
5355 },5514 },
5356 },5515 },
5357 .Vector => return f.fail("TODO: C backend: implement airAggregateInit for vectors", .{}),
5358 else => unreachable,5516 else => unreachable,
5359 }5517 }
53605518
...@@ -5868,7 +6026,7 @@ fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) T...@@ -5868,7 +6026,7 @@ fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) T
58686026
5869fn lowersToArray(ty: Type, target: std.Target) bool {6027fn lowersToArray(ty: Type, target: std.Target) bool {
5870 return switch (ty.zigTypeTag()) {6028 return switch (ty.zigTypeTag()) {
5871 .Array => return true,6029 .Array, .Vector => return true,
5872 else => return ty.isAbiInt() and toCIntBits(@intCast(u32, ty.bitSize(target))) == null,6030 else => return ty.isAbiInt() and toCIntBits(@intCast(u32, ty.bitSize(target))) == null,
5873 };6031 };
5874}6032}
...@@ -5877,7 +6035,7 @@ fn loweredArrayInfo(ty: Type, target: std.Target) ?Type.ArrayInfo {...@@ -5877,7 +6035,7 @@ fn loweredArrayInfo(ty: Type, target: std.Target) ?Type.ArrayInfo {
5877 if (!lowersToArray(ty, target)) return null;6035 if (!lowersToArray(ty, target)) return null;
58786036
5879 switch (ty.zigTypeTag()) {6037 switch (ty.zigTypeTag()) {
5880 .Array => return ty.arrayInfo(),6038 .Array, .Vector => return ty.arrayInfo(),
5881 else => {6039 else => {
5882 const abi_size = ty.abiSize(target);6040 const abi_size = ty.abiSize(target);
5883 const abi_align = ty.abiAlignment(target);6041 const abi_align = ty.abiAlignment(target);
src/codegen/llvm.zig+7-44
...@@ -16,7 +16,6 @@ const Package = @import("../Package.zig");...@@ -16,7 +16,6 @@ const Package = @import("../Package.zig");
16const TypedValue = @import("../TypedValue.zig");16const TypedValue = @import("../TypedValue.zig");
17const Air = @import("../Air.zig");17const Air = @import("../Air.zig");
18const Liveness = @import("../Liveness.zig");18const Liveness = @import("../Liveness.zig");
19const target_util = @import("../target.zig");
20const Value = @import("../value.zig").Value;19const Value = @import("../value.zig").Value;
21const Type = @import("../type.zig").Type;20const Type = @import("../type.zig").Type;
22const LazySrcLoc = Module.LazySrcLoc;21const LazySrcLoc = Module.LazySrcLoc;
...@@ -27,6 +26,12 @@ const aarch64_c_abi = @import("../arch/aarch64/abi.zig");...@@ -27,6 +26,12 @@ const aarch64_c_abi = @import("../arch/aarch64/abi.zig");
27const arm_c_abi = @import("../arch/arm/abi.zig");26const arm_c_abi = @import("../arch/arm/abi.zig");
28const riscv_c_abi = @import("../arch/riscv64/abi.zig");27const riscv_c_abi = @import("../arch/riscv64/abi.zig");
2928
29const target_util = @import("../target.zig");
30const libcFloatPrefix = target_util.libcFloatPrefix;
31const libcFloatSuffix = target_util.libcFloatSuffix;
32const compilerRtFloatAbbrev = target_util.compilerRtFloatAbbrev;
33const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev;
34
30const Error = error{ OutOfMemory, CodegenFail };35const Error = error{ OutOfMemory, CodegenFail };
3136
32pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {37pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 {
...@@ -7328,46 +7333,6 @@ pub const FuncGen = struct {...@@ -7328,46 +7333,6 @@ pub const FuncGen = struct {
7328 };7333 };
7329 }7334 }
73307335
7331 fn libcFloatPrefix(float_bits: u16) []const u8 {
7332 return switch (float_bits) {
7333 16, 80 => "__",
7334 32, 64, 128 => "",
7335 else => unreachable,
7336 };
7337 }
7338
7339 fn libcFloatSuffix(float_bits: u16) []const u8 {
7340 return switch (float_bits) {
7341 16 => "h", // Non-standard
7342 32 => "f",
7343 64 => "",
7344 80 => "x", // Non-standard
7345 128 => "q", // Non-standard (mimics convention in GCC libquadmath)
7346 else => unreachable,
7347 };
7348 }
7349
7350 fn compilerRtFloatAbbrev(float_bits: u16) []const u8 {
7351 return switch (float_bits) {
7352 16 => "h",
7353 32 => "s",
7354 64 => "d",
7355 80 => "x",
7356 128 => "t",
7357 else => unreachable,
7358 };
7359 }
7360
7361 fn compilerRtIntAbbrev(bits: u16) []const u8 {
7362 return switch (bits) {
7363 16 => "h",
7364 32 => "s",
7365 64 => "d",
7366 128 => "t",
7367 else => "o", // Non-standard
7368 };
7369 }
7370
7371 /// Creates a floating point comparison by lowering to the appropriate7336 /// Creates a floating point comparison by lowering to the appropriate
7372 /// hardware instruction or softfloat routine for the target7337 /// hardware instruction or softfloat routine for the target
7373 fn buildFloatCmp(7338 fn buildFloatCmp(
...@@ -9034,12 +8999,10 @@ pub const FuncGen = struct {...@@ -9034,12 +8999,10 @@ pub const FuncGen = struct {
9034 const target = self.dg.module.getTarget();8999 const target = self.dg.module.getTarget();
90359000
9036 const reduce = self.air.instructions.items(.data)[inst].reduce;9001 const reduce = self.air.instructions.items(.data)[inst].reduce;
9037 var operand = try self.resolveInst(reduce.operand);9002 const operand = try self.resolveInst(reduce.operand);
9038 const operand_ty = self.air.typeOf(reduce.operand);9003 const operand_ty = self.air.typeOf(reduce.operand);
9039 const scalar_ty = self.air.typeOfIndex(inst);9004 const scalar_ty = self.air.typeOfIndex(inst);
90409005
9041 // TODO handle the fast math setting
9042
9043 switch (reduce.operation) {9006 switch (reduce.operation) {
9044 .And => return self.builder.buildAndReduce(operand),9007 .And => return self.builder.buildAndReduce(operand),
9045 .Or => return self.builder.buildOrReduce(operand),9008 .Or => return self.builder.buildOrReduce(operand),
src/target.zig+40
...@@ -729,3 +729,43 @@ pub fn supportsTailCall(target: std.Target, backend: std.builtin.CompilerBackend...@@ -729,3 +729,43 @@ pub fn supportsTailCall(target: std.Target, backend: std.builtin.CompilerBackend
729 else => return false,729 else => return false,
730 }730 }
731}731}
732
733pub fn libcFloatPrefix(float_bits: u16) []const u8 {
734 return switch (float_bits) {
735 16, 80 => "__",
736 32, 64, 128 => "",
737 else => unreachable,
738 };
739}
740
741pub fn libcFloatSuffix(float_bits: u16) []const u8 {
742 return switch (float_bits) {
743 16 => "h", // Non-standard
744 32 => "f",
745 64 => "",
746 80 => "x", // Non-standard
747 128 => "q", // Non-standard (mimics convention in GCC libquadmath)
748 else => unreachable,
749 };
750}
751
752pub fn compilerRtFloatAbbrev(float_bits: u16) []const u8 {
753 return switch (float_bits) {
754 16 => "h",
755 32 => "s",
756 64 => "d",
757 80 => "x",
758 128 => "t",
759 else => unreachable,
760 };
761}
762
763pub fn compilerRtIntAbbrev(bits: u16) []const u8 {
764 return switch (bits) {
765 16 => "h",
766 32 => "s",
767 64 => "d",
768 128 => "t",
769 else => "o", // Non-standard
770 };
771}
test/behavior/vector.zig-12
...@@ -13,7 +13,6 @@ test "implicit cast vector to array - bool" {...@@ -13,7 +13,6 @@ test "implicit cast vector to array - bool" {
13 }13 }
1414
15 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
19 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO18 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -294,7 +293,6 @@ test "vector @splat" {...@@ -294,7 +293,6 @@ test "vector @splat" {
294293
295test "load vector elements via comptime index" {294test "load vector elements via comptime index" {
296 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO295 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
297 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
298 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO296 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
299 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO297 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
300 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO298 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -317,7 +315,6 @@ test "load vector elements via comptime index" {...@@ -317,7 +315,6 @@ test "load vector elements via comptime index" {
317315
318test "store vector elements via comptime index" {316test "store vector elements via comptime index" {
319 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO317 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
320 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
321 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO318 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
322 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO319 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
323 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO320 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -346,7 +343,6 @@ test "store vector elements via comptime index" {...@@ -346,7 +343,6 @@ test "store vector elements via comptime index" {
346343
347test "load vector elements via runtime index" {344test "load vector elements via runtime index" {
348 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO345 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
349 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
350 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO346 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
351 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO347 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
352 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO348 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -369,7 +365,6 @@ test "load vector elements via runtime index" {...@@ -369,7 +365,6 @@ test "load vector elements via runtime index" {
369365
370test "store vector elements via runtime index" {366test "store vector elements via runtime index" {
371 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO367 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
372 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
373 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO368 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
374 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO369 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
375 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO370 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -393,7 +388,6 @@ test "store vector elements via runtime index" {...@@ -393,7 +388,6 @@ test "store vector elements via runtime index" {
393388
394test "initialize vector which is a struct field" {389test "initialize vector which is a struct field" {
395 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO390 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
396 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
397 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO391 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
398 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO392 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
399 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO393 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -975,7 +969,6 @@ test "@addWithOverflow" {...@@ -975,7 +969,6 @@ test "@addWithOverflow" {
975 return error.SkipZigTest;969 return error.SkipZigTest;
976 }970 }
977 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO971 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
978 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
979 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO972 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
980 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO973 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
981 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO974 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1018,7 +1011,6 @@ test "@subWithOverflow" {...@@ -1018,7 +1011,6 @@ test "@subWithOverflow" {
1018 return error.SkipZigTest;1011 return error.SkipZigTest;
1019 }1012 }
1020 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1013 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1021 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1022 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1014 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1023 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1015 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1024 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1016 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1049,7 +1041,6 @@ test "@mulWithOverflow" {...@@ -1049,7 +1041,6 @@ test "@mulWithOverflow" {
1049 return error.SkipZigTest;1041 return error.SkipZigTest;
1050 }1042 }
1051 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1043 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1052 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1053 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1044 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1054 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1045 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1055 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1046 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1072,7 +1063,6 @@ test "@shlWithOverflow" {...@@ -1072,7 +1063,6 @@ test "@shlWithOverflow" {
1072 return error.SkipZigTest;1063 return error.SkipZigTest;
1073 }1064 }
1074 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1065 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1075 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1076 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1066 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1077 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1067 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1078 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1068 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1098,7 +1088,6 @@ test "alignment of vectors" {...@@ -1098,7 +1088,6 @@ test "alignment of vectors" {
10981088
1099test "loading the second vector from a slice of vectors" {1089test "loading the second vector from a slice of vectors" {
1100 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1090 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1101 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1102 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1091 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1103 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1092 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1104 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1093 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
...@@ -1115,7 +1104,6 @@ test "loading the second vector from a slice of vectors" {...@@ -1115,7 +1104,6 @@ test "loading the second vector from a slice of vectors" {
11151104
1116test "array of vectors is copied" {1105test "array of vectors is copied" {
1117 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1106 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1118 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
1119 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO1107 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1120 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1108 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1121 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1109 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO