1d934c16dSTaylor Simpson /* 2d934c16dSTaylor Simpson * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. 3d934c16dSTaylor Simpson * 4d934c16dSTaylor Simpson * This program is free software; you can redistribute it and/or modify 5d934c16dSTaylor Simpson * it under the terms of the GNU General Public License as published by 6d934c16dSTaylor Simpson * the Free Software Foundation; either version 2 of the License, or 7d934c16dSTaylor Simpson * (at your option) any later version. 8d934c16dSTaylor Simpson * 9d934c16dSTaylor Simpson * This program is distributed in the hope that it will be useful, 10d934c16dSTaylor Simpson * but WITHOUT ANY WARRANTY; without even the implied warranty of 11d934c16dSTaylor Simpson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12d934c16dSTaylor Simpson * GNU General Public License for more details. 13d934c16dSTaylor Simpson * 14d934c16dSTaylor Simpson * You should have received a copy of the GNU General Public License 15d934c16dSTaylor Simpson * along with this program; if not, see <http://www.gnu.org/licenses/>. 16d934c16dSTaylor Simpson */ 17d934c16dSTaylor Simpson 18d934c16dSTaylor Simpson #include <stdio.h> 19d934c16dSTaylor Simpson 20d934c16dSTaylor Simpson static int sfrecipa(int Rs, int Rt, int *pred_result) 21d934c16dSTaylor Simpson { 22d934c16dSTaylor Simpson int result; 23d934c16dSTaylor Simpson int predval; 24d934c16dSTaylor Simpson 25d934c16dSTaylor Simpson asm volatile("%0,p0 = sfrecipa(%2, %3)\n\t" 26d934c16dSTaylor Simpson "%1 = p0\n\t" 27d934c16dSTaylor Simpson : "+r"(result), "=r"(predval) 28d934c16dSTaylor Simpson : "r"(Rs), "r"(Rt) 29d934c16dSTaylor Simpson : "p0"); 30d934c16dSTaylor Simpson *pred_result = predval; 31d934c16dSTaylor Simpson return result; 32d934c16dSTaylor Simpson } 33d934c16dSTaylor Simpson 34dd8705bdSTaylor Simpson static int sfinvsqrta(int Rs, int *pred_result) 35dd8705bdSTaylor Simpson { 36dd8705bdSTaylor Simpson int result; 37dd8705bdSTaylor Simpson int predval; 38dd8705bdSTaylor Simpson 39dd8705bdSTaylor Simpson asm volatile("%0,p0 = sfinvsqrta(%2)\n\t" 40dd8705bdSTaylor Simpson "%1 = p0\n\t" 41dd8705bdSTaylor Simpson : "+r"(result), "=r"(predval) 42dd8705bdSTaylor Simpson : "r"(Rs) 43dd8705bdSTaylor Simpson : "p0"); 44dd8705bdSTaylor Simpson *pred_result = predval; 45dd8705bdSTaylor Simpson return result; 46dd8705bdSTaylor Simpson } 47dd8705bdSTaylor Simpson 48da74cd2dSTaylor Simpson static long long vacsh(long long Rxx, long long Rss, long long Rtt, 49da74cd2dSTaylor Simpson int *pred_result, int *ovf_result) 50da74cd2dSTaylor Simpson { 51da74cd2dSTaylor Simpson long long result = Rxx; 52da74cd2dSTaylor Simpson int predval; 53da74cd2dSTaylor Simpson int usr; 54da74cd2dSTaylor Simpson 55da74cd2dSTaylor Simpson /* 56da74cd2dSTaylor Simpson * This instruction can set bit 0 (OVF/overflow) in usr 57da74cd2dSTaylor Simpson * Clear the bit first, then return that bit to the caller 58da74cd2dSTaylor Simpson */ 59da74cd2dSTaylor Simpson asm volatile("r2 = usr\n\t" 60da74cd2dSTaylor Simpson "r2 = clrbit(r2, #0)\n\t" /* clear overflow bit */ 61da74cd2dSTaylor Simpson "usr = r2\n\t" 62da74cd2dSTaylor Simpson "%0,p0 = vacsh(%3, %4)\n\t" 63da74cd2dSTaylor Simpson "%1 = p0\n\t" 64da74cd2dSTaylor Simpson "%2 = usr\n\t" 65da74cd2dSTaylor Simpson : "+r"(result), "=r"(predval), "=r"(usr) 66da74cd2dSTaylor Simpson : "r"(Rss), "r"(Rtt) 67da74cd2dSTaylor Simpson : "r2", "p0", "usr"); 68da74cd2dSTaylor Simpson *pred_result = predval; 69da74cd2dSTaylor Simpson *ovf_result = (usr & 1); 70da74cd2dSTaylor Simpson return result; 71da74cd2dSTaylor Simpson } 72da74cd2dSTaylor Simpson 73*0a65d286STaylor Simpson static long long vminub(long long Rtt, long long Rss, 74*0a65d286STaylor Simpson int *pred_result) 75*0a65d286STaylor Simpson { 76*0a65d286STaylor Simpson long long result; 77*0a65d286STaylor Simpson int predval; 78*0a65d286STaylor Simpson 79*0a65d286STaylor Simpson asm volatile("%0,p0 = vminub(%2, %3)\n\t" 80*0a65d286STaylor Simpson "%1 = p0\n\t" 81*0a65d286STaylor Simpson : "=r"(result), "=r"(predval) 82*0a65d286STaylor Simpson : "r"(Rtt), "r"(Rss) 83*0a65d286STaylor Simpson : "p0"); 84*0a65d286STaylor Simpson *pred_result = predval; 85*0a65d286STaylor Simpson return result; 86*0a65d286STaylor Simpson } 87*0a65d286STaylor Simpson 88d934c16dSTaylor Simpson int err; 89d934c16dSTaylor Simpson 90da74cd2dSTaylor Simpson static void check_ll(long long val, long long expect) 91da74cd2dSTaylor Simpson { 92da74cd2dSTaylor Simpson if (val != expect) { 93da74cd2dSTaylor Simpson printf("ERROR: 0x%016llx != 0x%016llx\n", val, expect); 94da74cd2dSTaylor Simpson err++; 95da74cd2dSTaylor Simpson } 96da74cd2dSTaylor Simpson } 97da74cd2dSTaylor Simpson 98d934c16dSTaylor Simpson static void check(int val, int expect) 99d934c16dSTaylor Simpson { 100d934c16dSTaylor Simpson if (val != expect) { 101d934c16dSTaylor Simpson printf("ERROR: 0x%08x != 0x%08x\n", val, expect); 102d934c16dSTaylor Simpson err++; 103d934c16dSTaylor Simpson } 104d934c16dSTaylor Simpson } 105d934c16dSTaylor Simpson 106d934c16dSTaylor Simpson static void check_p(int val, int expect) 107d934c16dSTaylor Simpson { 108d934c16dSTaylor Simpson if (val != expect) { 109d934c16dSTaylor Simpson printf("ERROR: 0x%02x != 0x%02x\n", val, expect); 110d934c16dSTaylor Simpson err++; 111d934c16dSTaylor Simpson } 112d934c16dSTaylor Simpson } 113d934c16dSTaylor Simpson 114d934c16dSTaylor Simpson static void test_sfrecipa() 115d934c16dSTaylor Simpson { 116d934c16dSTaylor Simpson int res; 117d934c16dSTaylor Simpson int pred_result; 118d934c16dSTaylor Simpson 119d934c16dSTaylor Simpson res = sfrecipa(0x04030201, 0x05060708, &pred_result); 120d934c16dSTaylor Simpson check(res, 0x59f38001); 121d934c16dSTaylor Simpson check_p(pred_result, 0x00); 122d934c16dSTaylor Simpson } 123d934c16dSTaylor Simpson 124dd8705bdSTaylor Simpson static void test_sfinvsqrta() 125dd8705bdSTaylor Simpson { 126dd8705bdSTaylor Simpson int res; 127dd8705bdSTaylor Simpson int pred_result; 128dd8705bdSTaylor Simpson 129dd8705bdSTaylor Simpson res = sfinvsqrta(0x04030201, &pred_result); 130dd8705bdSTaylor Simpson check(res, 0x4d330000); 131dd8705bdSTaylor Simpson check_p(pred_result, 0xe0); 132dd8705bdSTaylor Simpson 133dd8705bdSTaylor Simpson res = sfinvsqrta(0x0, &pred_result); 134dd8705bdSTaylor Simpson check(res, 0x3f800000); 135dd8705bdSTaylor Simpson check_p(pred_result, 0x0); 136dd8705bdSTaylor Simpson } 137dd8705bdSTaylor Simpson 138da74cd2dSTaylor Simpson static void test_vacsh() 139da74cd2dSTaylor Simpson { 140da74cd2dSTaylor Simpson long long res64; 141da74cd2dSTaylor Simpson int pred_result; 142da74cd2dSTaylor Simpson int ovf_result; 143da74cd2dSTaylor Simpson 144da74cd2dSTaylor Simpson res64 = vacsh(0x0004000300020001LL, 145da74cd2dSTaylor Simpson 0x0001000200030004LL, 146da74cd2dSTaylor Simpson 0x0000000000000000LL, &pred_result, &ovf_result); 147da74cd2dSTaylor Simpson check_ll(res64, 0x0004000300030004LL); 148da74cd2dSTaylor Simpson check_p(pred_result, 0xf0); 149da74cd2dSTaylor Simpson check(ovf_result, 0); 150da74cd2dSTaylor Simpson 151da74cd2dSTaylor Simpson res64 = vacsh(0x0004000300020001LL, 152da74cd2dSTaylor Simpson 0x0001000200030004LL, 153da74cd2dSTaylor Simpson 0x000affff000d0000LL, &pred_result, &ovf_result); 154da74cd2dSTaylor Simpson check_ll(res64, 0x000e0003000f0004LL); 155da74cd2dSTaylor Simpson check_p(pred_result, 0xcc); 156da74cd2dSTaylor Simpson check(ovf_result, 0); 157da74cd2dSTaylor Simpson 158da74cd2dSTaylor Simpson res64 = vacsh(0x00047fff00020001LL, 159da74cd2dSTaylor Simpson 0x00017fff00030004LL, 160da74cd2dSTaylor Simpson 0x000a0fff000d0000LL, &pred_result, &ovf_result); 161da74cd2dSTaylor Simpson check_ll(res64, 0x000e7fff000f0004LL); 162da74cd2dSTaylor Simpson check_p(pred_result, 0xfc); 163da74cd2dSTaylor Simpson check(ovf_result, 1); 164da74cd2dSTaylor Simpson 165da74cd2dSTaylor Simpson res64 = vacsh(0x0004000300020001LL, 166da74cd2dSTaylor Simpson 0x0001000200030009LL, 167da74cd2dSTaylor Simpson 0x000affff000d0001LL, &pred_result, &ovf_result); 168da74cd2dSTaylor Simpson check_ll(res64, 0x000e0003000f0008LL); 169da74cd2dSTaylor Simpson check_p(pred_result, 0xcc); 170da74cd2dSTaylor Simpson check(ovf_result, 0); 171da74cd2dSTaylor Simpson } 172da74cd2dSTaylor Simpson 173*0a65d286STaylor Simpson static void test_vminub() 174*0a65d286STaylor Simpson { 175*0a65d286STaylor Simpson long long res64; 176*0a65d286STaylor Simpson int pred_result; 177*0a65d286STaylor Simpson 178*0a65d286STaylor Simpson res64 = vminub(0x0807060504030201LL, 179*0a65d286STaylor Simpson 0x0102030405060708LL, 180*0a65d286STaylor Simpson &pred_result); 181*0a65d286STaylor Simpson check_ll(res64, 0x0102030404030201LL); 182*0a65d286STaylor Simpson check_p(pred_result, 0xf0); 183*0a65d286STaylor Simpson 184*0a65d286STaylor Simpson res64 = vminub(0x0802060405030701LL, 185*0a65d286STaylor Simpson 0x0107030504060208LL, 186*0a65d286STaylor Simpson &pred_result); 187*0a65d286STaylor Simpson check_ll(res64, 0x0102030404030201LL); 188*0a65d286STaylor Simpson check_p(pred_result, 0xaa); 189*0a65d286STaylor Simpson } 190*0a65d286STaylor Simpson 191d934c16dSTaylor Simpson int main() 192d934c16dSTaylor Simpson { 193d934c16dSTaylor Simpson test_sfrecipa(); 194dd8705bdSTaylor Simpson test_sfinvsqrta(); 195da74cd2dSTaylor Simpson test_vacsh(); 196*0a65d286STaylor Simpson test_vminub(); 197d934c16dSTaylor Simpson 198d934c16dSTaylor Simpson puts(err ? "FAIL" : "PASS"); 199d934c16dSTaylor Simpson return err; 200d934c16dSTaylor Simpson } 201