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