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