1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Tests vector instruction support 4 * 5 * Copyright 2018 IBM Corp. 6 * 7 * Authors: 8 * Janosch Frank <frankja@linux.ibm.com> 9 */ 10 #include <libcflat.h> 11 #include <asm/page.h> 12 #include <asm/facility.h> 13 #include <asm/interrupt.h> 14 #include <asm-generic/barrier.h> 15 16 static uint8_t pagebuf[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); 17 18 /* Fills all vector registers with data from addr */ 19 static inline void vlm_all(unsigned long *addr) 20 { 21 asm volatile(" .machine z13\n" 22 " vlm 0, 15, %[a]\n" 23 : : [a] "Q" (*addr) 24 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", 25 "v9", "v10", "v11", "v12", "v13", "v14", "v15"); 26 asm volatile(" .machine z13\n" 27 " vlm 16, 31, %[a]\n" 28 : : [a] "Q" (*(addr+256/8)) 29 : "v16", "v17", "v18", "v19", "v20", "v21", "v22", 30 "v23", "v24", "v25", "v26", "v27", "v28", "v29", 31 "v30", "v31"); 32 } 33 34 static void test_add(void) 35 { 36 static struct prm { 37 __uint128_t a,b,c; 38 } prm __attribute__((aligned(16))); 39 40 prm.a = prm.b = prm.c = 21; 41 42 asm volatile(" .machine z13\n" 43 " vl 0, %[v1]\n" 44 " vl 1, %[v2]\n" 45 " va 2, 0, 1, 4\n" 46 " vst 2, %[v3]\n" 47 : [v3] "=Q" (prm.c) 48 : [v1] "Q" (prm.a), [v2] "Q" (prm.b) 49 : "v0", "v1", "v2", "memory"); 50 report(prm.c == 42, "adding 21"); 51 } 52 53 /* z14 vector extension test */ 54 static void test_ext1_nand(void) 55 { 56 bool has_vext = test_facility(135); 57 static struct prm { 58 __uint128_t a,b,c; 59 } prm __attribute__((aligned(16))); 60 61 if (!has_vext) { 62 report_skip("Vector extensions 1 is not available"); 63 return; 64 } 65 66 memset(&prm, 0xff, sizeof(prm)); 67 68 asm volatile(" .machine z13\n" 69 " vl 0, %[v1]\n" 70 " vl 1, %[v2]\n" 71 " .byte 0xe7, 0x20, 0x10, 0x00, 0x00, 0x6e\n" /* vnn */ 72 " vst 2, %[v3]\n" 73 : [v3] "=Q" (prm.c) 74 : [v1] "Q" (prm.a), [v2] "Q" (prm.b) 75 : "v0", "v1", "v2", "memory"); 76 report(!prm.c, "nand ff"); 77 } 78 79 /* z14 bcd extension test */ 80 static void test_bcd_add(void) 81 { 82 bool has_bcd = test_facility(134); 83 static struct prm { 84 __uint128_t a,b,c; 85 } prm __attribute__((aligned(16))); 86 87 if (!has_bcd) { 88 report_skip("Vector BCD extensions is not available"); 89 return; 90 } 91 92 prm.c = 0; 93 prm.a = prm.b = 0b001000011100; 94 95 asm volatile(" .machine z13\n" 96 " vl 0, %[v1]\n" 97 " vl 1, %[v2]\n" 98 " .byte 0xe6, 0x20, 0x10, 0x01, 0x00, 0x71\n" /* vap */ 99 " vst 2, %[v3]\n" 100 : [v3] "=Q" (prm.c) 101 : [v1] "Q" (prm.a), [v2] "Q" (prm.b) 102 : "v0", "v1", "v2", "memory"); 103 report(prm.c == 0x42c, "bcd add 21"); 104 } 105 106 static void init(void) 107 { 108 /* Enable vector instructions */ 109 ctl_set_bit(0, CTL0_VECTOR); 110 111 /* Preset vector registers to 0xff */ 112 memset(pagebuf, 0xff, PAGE_SIZE); 113 vlm_all((u64*)pagebuf); 114 } 115 116 int main(void) 117 { 118 bool has_vregs = test_facility(129); 119 120 report_prefix_push("vector"); 121 if (!has_vregs) { 122 report_skip("Basic vector facility is not available"); 123 goto done; 124 } 125 126 init(); 127 test_add(); 128 test_ext1_nand(); 129 test_bcd_add(); 130 131 done: 132 report_prefix_pop(); 133 return report_summary(); 134 } 135