qemu/tests/tcg/hexagon/preg_alias.c
<<
>>
Prefs
   1/*
   2 *  Copyright(c) 2019-2022 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 inline int preg_alias(int v0, int v1, int v2, int v3)
  21{
  22  int ret;
  23  asm volatile("p0 = %1\n\t"
  24               "p1 = %2\n\t"
  25               "p2 = %3\n\t"
  26               "p3 = %4\n\t"
  27               "%0 = C4\n"
  28               : "=r"(ret)
  29               : "r"(v0), "r"(v1), "r"(v2), "r"(v3)
  30               : "p0", "p1", "p2", "p3");
  31  return ret;
  32}
  33
  34static inline int preg_alias_pair(int v0, int v1, int v2, int v3)
  35{
  36  long long c54;
  37  asm volatile("p0 = %1\n\t"
  38               "p1 = %2\n\t"
  39               "p2 = %3\n\t"
  40               "p3 = %4\n\t"
  41               "%0 = C5:4\n"
  42               : "=r"(c54)
  43               : "r"(v0), "r"(v1), "r"(v2), "r"(v3)
  44               : "p0", "p1", "p2", "p3");
  45  return (int)c54;
  46}
  47
  48typedef union {
  49    int creg;
  50    struct {
  51      unsigned char p0;
  52      unsigned char p1;
  53      unsigned char p2;
  54      unsigned char p3;
  55    } pregs;
  56} PRegs;
  57
  58static inline void creg_alias(int cval, PRegs *pregs)
  59{
  60  asm("c4 = %4\n\t"
  61      "%0 = p0\n\t"
  62      "%1 = p1\n\t"
  63      "%2 = p2\n\t"
  64      "%3 = p3\n\t"
  65      : "=r"(pregs->pregs.p0), "=r"(pregs->pregs.p1),
  66        "=r"(pregs->pregs.p2), "=r"(pregs->pregs.p3)
  67      : "r"(cval)
  68      : "p0", "p1", "p2", "p3");
  69}
  70
  71int err;
  72
  73static void check(int val, int expect)
  74{
  75    if (val != expect) {
  76        printf("ERROR: 0x%08x != 0x%08x\n", val, expect);
  77        err++;
  78    }
  79}
  80
  81static inline void creg_alias_pair(unsigned int cval, PRegs *pregs)
  82{
  83  unsigned long long cval_pair = (0xdeadbeefULL << 32) | cval;
  84  int c5;
  85
  86  asm ("c5:4 = %5\n\t"
  87       "%0 = p0\n\t"
  88       "%1 = p1\n\t"
  89       "%2 = p2\n\t"
  90       "%3 = p3\n\t"
  91       "%4 = c5\n\t"
  92       : "=r"(pregs->pregs.p0), "=r"(pregs->pregs.p1),
  93         "=r"(pregs->pregs.p2), "=r"(pregs->pregs.p3), "=r"(c5)
  94       : "r"(cval_pair)
  95       : "p0", "p1", "p2", "p3");
  96
  97  check(c5, 0xdeadbeef);
  98}
  99
 100static void test_packet(void)
 101{
 102    /*
 103     * Test that setting c4 inside a packet doesn't impact the predicates
 104     * that are read during the packet.
 105     */
 106
 107    int result;
 108    int old_val = 0x0000001c;
 109
 110    /* Test a predicated register transfer */
 111    result = old_val;
 112    asm (
 113         "c4 = %1\n\t"
 114         "{\n\t"
 115         "    c4 = %2\n\t"
 116         "    if (!p2) %0 = %3\n\t"
 117         "}\n\t"
 118         : "+r"(result)
 119         : "r"(0xffffffff), "r"(0xff00ffff), "r"(0x837ed653)
 120         : "p0", "p1", "p2", "p3");
 121    check(result, old_val);
 122
 123    /* Test a predicated store */
 124    result = 0xffffffff;
 125    asm ("c4 = %0\n\t"
 126         "{\n\t"
 127         "    c4 = %1\n\t"
 128         "    if (!p2) memw(%2) = #0\n\t"
 129         "}\n\t"
 130         :
 131         : "r"(0), "r"(0xffffffff), "r"(&result)
 132         : "p0", "p1", "p2", "p3", "memory");
 133    check(result, 0x0);
 134}
 135
 136int main()
 137{
 138    int c4;
 139    PRegs pregs;
 140
 141    c4 = preg_alias(0xff, 0x00, 0xff, 0x00);
 142    check(c4, 0x00ff00ff);
 143    c4 = preg_alias(0xff, 0x00, 0x00, 0x00);
 144    check(c4, 0x000000ff);
 145    c4 = preg_alias(0x00, 0xff, 0x00, 0x00);
 146    check(c4, 0x0000ff00);
 147    c4 = preg_alias(0x00, 0x00, 0xff, 0x00);
 148    check(c4, 0x00ff0000);
 149    c4 = preg_alias(0x00, 0x00, 0x00, 0xff);
 150    check(c4, 0xff000000);
 151    c4 = preg_alias(0xff, 0xff, 0xff, 0xff);
 152    check(c4, 0xffffffff);
 153
 154    c4 = preg_alias_pair(0xff, 0x00, 0xff, 0x00);
 155    check(c4, 0x00ff00ff);
 156      c4 = preg_alias_pair(0xff, 0x00, 0x00, 0x00);
 157    check(c4, 0x000000ff);
 158    c4 = preg_alias_pair(0x00, 0xff, 0x00, 0x00);
 159    check(c4, 0x0000ff00);
 160    c4 = preg_alias_pair(0x00, 0x00, 0xff, 0x00);
 161    check(c4, 0x00ff0000);
 162    c4 = preg_alias_pair(0x00, 0x00, 0x00, 0xff);
 163    check(c4, 0xff000000);
 164    c4 = preg_alias_pair(0xff, 0xff, 0xff, 0xff);
 165    check(c4, 0xffffffff);
 166
 167    creg_alias(0x00ff00ff, &pregs);
 168    check(pregs.creg, 0x00ff00ff);
 169    creg_alias(0x00ffff00, &pregs);
 170    check(pregs.creg, 0x00ffff00);
 171    creg_alias(0x00000000, &pregs);
 172    check(pregs.creg, 0x00000000);
 173    creg_alias(0xff000000, &pregs);
 174    check(pregs.creg, 0xff000000);
 175    creg_alias(0x00ff0000, &pregs);
 176    check(pregs.creg, 0x00ff0000);
 177    creg_alias(0x0000ff00, &pregs);
 178    check(pregs.creg, 0x0000ff00);
 179    creg_alias(0x000000ff, &pregs);
 180    check(pregs.creg, 0x000000ff);
 181    creg_alias(0xffffffff, &pregs);
 182    check(pregs.creg, 0xffffffff);
 183
 184    creg_alias_pair(0x00ff00ff, &pregs);
 185    check(pregs.creg, 0x00ff00ff);
 186    creg_alias_pair(0x00ffff00, &pregs);
 187    check(pregs.creg, 0x00ffff00);
 188    creg_alias_pair(0x00000000, &pregs);
 189    check(pregs.creg, 0x00000000);
 190    creg_alias_pair(0xff000000, &pregs);
 191    check(pregs.creg, 0xff000000);
 192    creg_alias_pair(0x00ff0000, &pregs);
 193    check(pregs.creg, 0x00ff0000);
 194    creg_alias_pair(0x0000ff00, &pregs);
 195    check(pregs.creg, 0x0000ff00);
 196    creg_alias_pair(0x000000ff, &pregs);
 197    check(pregs.creg, 0x000000ff);
 198    creg_alias_pair(0xffffffff, &pregs);
 199    check(pregs.creg, 0xffffffff);
 200
 201    test_packet();
 202
 203    puts(err ? "FAIL" : "PASS");
 204    return err;
 205}
 206