qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

preg_alias.c (5675B)


      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 
     20 static 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 
     34 static 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 
     48 typedef 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 
     58 static 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 
     71 int err;
     72 
     73 static 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 
     81 static 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 
    100 static 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 
    136 int 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 }