qemu/tests/tcg/hexagon/multi_result.c
<<
>>
Prefs
   1/*
   2 *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
   3 *
   4 *  This program is free software; you can redistribute it and/or modify
   5 *  it under the terms of the GNU General Public License as published by
   6 *  the Free Software Foundation; either version 2 of the License, or
   7 *  (at your option) any later version.
   8 *
   9 *  This program is distributed in the hope that it will be useful,
  10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 *  GNU General Public License for more details.
  13 *
  14 *  You should have received a copy of the GNU General Public License
  15 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  16 */
  17
  18#include <stdio.h>
  19
  20static int sfrecipa(int Rs, int Rt, int *pred_result)
  21{
  22  int result;
  23  int predval;
  24
  25  asm volatile("%0,p0 = sfrecipa(%2, %3)\n\t"
  26               "%1 = p0\n\t"
  27               : "+r"(result), "=r"(predval)
  28               : "r"(Rs), "r"(Rt)
  29               : "p0");
  30  *pred_result = predval;
  31  return result;
  32}
  33
  34static int sfinvsqrta(int Rs, int *pred_result)
  35{
  36  int result;
  37  int predval;
  38
  39  asm volatile("%0,p0 = sfinvsqrta(%2)\n\t"
  40               "%1 = p0\n\t"
  41               : "+r"(result), "=r"(predval)
  42               : "r"(Rs)
  43               : "p0");
  44  *pred_result = predval;
  45  return result;
  46}
  47
  48static long long vacsh(long long Rxx, long long Rss, long long Rtt,
  49                       int *pred_result, int *ovf_result)
  50{
  51  long long result = Rxx;
  52  int predval;
  53  int usr;
  54
  55  /*
  56   * This instruction can set bit 0 (OVF/overflow) in usr
  57   * Clear the bit first, then return that bit to the caller
  58   */
  59  asm volatile("r2 = usr\n\t"
  60               "r2 = clrbit(r2, #0)\n\t"        /* clear overflow bit */
  61               "usr = r2\n\t"
  62               "%0,p0 = vacsh(%3, %4)\n\t"
  63               "%1 = p0\n\t"
  64               "%2 = usr\n\t"
  65               : "+r"(result), "=r"(predval), "=r"(usr)
  66               : "r"(Rss), "r"(Rtt)
  67               : "r2", "p0", "usr");
  68  *pred_result = predval;
  69  *ovf_result = (usr & 1);
  70  return result;
  71}
  72
  73static long long vminub(long long Rtt, long long Rss,
  74                        int *pred_result)
  75{
  76  long long result;
  77  int predval;
  78
  79  asm volatile("%0,p0 = vminub(%2, %3)\n\t"
  80               "%1 = p0\n\t"
  81               : "=r"(result), "=r"(predval)
  82               : "r"(Rtt), "r"(Rss)
  83               : "p0");
  84  *pred_result = predval;
  85  return result;
  86}
  87
  88static long long add_carry(long long Rss, long long Rtt,
  89                           int pred_in, int *pred_result)
  90{
  91  long long result;
  92  int predval = pred_in;
  93
  94  asm volatile("p0 = %1\n\t"
  95               "%0 = add(%2, %3, p0):carry\n\t"
  96               "%1 = p0\n\t"
  97               : "=r"(result), "+r"(predval)
  98               : "r"(Rss), "r"(Rtt)
  99               : "p0");
 100  *pred_result = predval;
 101  return result;
 102}
 103
 104static long long sub_carry(long long Rss, long long Rtt,
 105                           int pred_in, int *pred_result)
 106{
 107  long long result;
 108  int predval = pred_in;
 109
 110  asm volatile("p0 = !cmp.eq(%1, #0)\n\t"
 111               "%0 = sub(%2, %3, p0):carry\n\t"
 112               "%1 = p0\n\t"
 113               : "=r"(result), "+r"(predval)
 114               : "r"(Rss), "r"(Rtt)
 115               : "p0");
 116  *pred_result = predval;
 117  return result;
 118}
 119
 120int err;
 121
 122static void check_ll(long long val, long long expect)
 123{
 124    if (val != expect) {
 125        printf("ERROR: 0x%016llx != 0x%016llx\n", val, expect);
 126        err++;
 127    }
 128}
 129
 130static void check(int val, int expect)
 131{
 132    if (val != expect) {
 133        printf("ERROR: 0x%08x != 0x%08x\n", val, expect);
 134        err++;
 135    }
 136}
 137
 138static void check_p(int val, int expect)
 139{
 140    if (val != expect) {
 141        printf("ERROR: 0x%02x != 0x%02x\n", val, expect);
 142        err++;
 143    }
 144}
 145
 146static void test_sfrecipa()
 147{
 148    int res;
 149    int pred_result;
 150
 151    res = sfrecipa(0x04030201, 0x05060708, &pred_result);
 152    check(res, 0x59f38001);
 153    check_p(pred_result, 0x00);
 154}
 155
 156static void test_sfinvsqrta()
 157{
 158    int res;
 159    int pred_result;
 160
 161    res = sfinvsqrta(0x04030201, &pred_result);
 162    check(res, 0x4d330000);
 163    check_p(pred_result, 0xe0);
 164
 165    res = sfinvsqrta(0x0, &pred_result);
 166    check(res, 0x3f800000);
 167    check_p(pred_result, 0x0);
 168}
 169
 170static void test_vacsh()
 171{
 172    long long res64;
 173    int pred_result;
 174    int ovf_result;
 175
 176    res64 = vacsh(0x0004000300020001LL,
 177                  0x0001000200030004LL,
 178                  0x0000000000000000LL, &pred_result, &ovf_result);
 179    check_ll(res64, 0x0004000300030004LL);
 180    check_p(pred_result, 0xf0);
 181    check(ovf_result, 0);
 182
 183    res64 = vacsh(0x0004000300020001LL,
 184                  0x0001000200030004LL,
 185                  0x000affff000d0000LL, &pred_result, &ovf_result);
 186    check_ll(res64, 0x000e0003000f0004LL);
 187    check_p(pred_result, 0xcc);
 188    check(ovf_result, 0);
 189
 190    res64 = vacsh(0x00047fff00020001LL,
 191                  0x00017fff00030004LL,
 192                  0x000a0fff000d0000LL, &pred_result, &ovf_result);
 193    check_ll(res64, 0x000e7fff000f0004LL);
 194    check_p(pred_result, 0xfc);
 195    check(ovf_result, 1);
 196
 197    res64 = vacsh(0x0004000300020001LL,
 198                  0x0001000200030009LL,
 199                  0x000affff000d0001LL, &pred_result, &ovf_result);
 200    check_ll(res64, 0x000e0003000f0008LL);
 201    check_p(pred_result, 0xcc);
 202    check(ovf_result, 0);
 203}
 204
 205static void test_vminub()
 206{
 207    long long res64;
 208    int pred_result;
 209
 210    res64 = vminub(0x0807060504030201LL,
 211                   0x0102030405060708LL,
 212                   &pred_result);
 213    check_ll(res64, 0x0102030404030201LL);
 214    check_p(pred_result, 0xf0);
 215
 216    res64 = vminub(0x0802060405030701LL,
 217                   0x0107030504060208LL,
 218                   &pred_result);
 219    check_ll(res64, 0x0102030404030201LL);
 220    check_p(pred_result, 0xaa);
 221}
 222
 223static void test_add_carry()
 224{
 225    long long res64;
 226    int pred_result;
 227
 228    res64 = add_carry(0x0000000000000000LL,
 229                      0xffffffffffffffffLL,
 230                      1, &pred_result);
 231    check_ll(res64, 0x0000000000000000LL);
 232    check_p(pred_result, 0xff);
 233
 234    res64 = add_carry(0x0000000100000000LL,
 235                      0xffffffffffffffffLL,
 236                      0, &pred_result);
 237    check_ll(res64, 0x00000000ffffffffLL);
 238    check_p(pred_result, 0xff);
 239
 240    res64 = add_carry(0x0000000100000000LL,
 241                      0xffffffffffffffffLL,
 242                      0, &pred_result);
 243    check_ll(res64, 0x00000000ffffffffLL);
 244    check_p(pred_result, 0xff);
 245}
 246
 247static void test_sub_carry()
 248{
 249    long long res64;
 250    int pred_result;
 251
 252    res64 = sub_carry(0x0000000000000000LL,
 253                      0x0000000000000000LL,
 254                      1, &pred_result);
 255    check_ll(res64, 0x0000000000000000LL);
 256    check_p(pred_result, 0xff);
 257
 258    res64 = sub_carry(0x0000000100000000LL,
 259                      0x0000000000000000LL,
 260                      0, &pred_result);
 261    check_ll(res64, 0x00000000ffffffffLL);
 262    check_p(pred_result, 0xff);
 263
 264    res64 = sub_carry(0x0000000100000000LL,
 265                      0x0000000000000000LL,
 266                      0, &pred_result);
 267    check_ll(res64, 0x00000000ffffffffLL);
 268    check_p(pred_result, 0xff);
 269}
 270
 271int main()
 272{
 273    test_sfrecipa();
 274    test_sfinvsqrta();
 275    test_vacsh();
 276    test_vminub();
 277    test_add_carry();
 278    test_sub_carry();
 279
 280    puts(err ? "FAIL" : "PASS");
 281    return err;
 282}
 283