xref: /openbmc/qemu/tests/tcg/mips/include/wrappers_mips64r6.h (revision a56ac09f5c37f57059c2a2c5ae6aeff7f7241a84)
1 /*
2  *  Header file for wrappers around MIPS64R6 instructions assembler
3  *  invocations
4  *
5  *  Copyright (C) 2019  Wave Computing, Inc.
6  *  Copyright (C) 2019  Aleksandar Markovic <amarkovic@wavecomp.com>
7  *
8  *  This program is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation, either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #ifndef WRAPPERS_MIPS64R6_H
24 #define WRAPPERS_MIPS64R6_H
25 
26 #include <string.h>
27 
28 #define DO_MIPS64R6__RD__RS(suffix, mnemonic)                          \
29 static inline void do_mips64r6_##suffix(const void *input,             \
30                                         void *output)                  \
31 {                                                                      \
32    __asm__ volatile (                                                  \
33       "ld $t1, 0(%0)\n\t"                                              \
34       #mnemonic " $t0, $t1\n\t"                                        \
35       "sd $t0, 0(%1)\n\t"                                              \
36       :                                                                \
37       : "r" (input), "r" (output)                                      \
38       : "t0", "t1", "memory"                                           \
39    );                                                                  \
40 }
41 
42 DO_MIPS64R6__RD__RS(CLO, clo)
43 DO_MIPS64R6__RD__RS(CLZ, clz)
44 DO_MIPS64R6__RD__RS(DCLO, dclo)
45 DO_MIPS64R6__RD__RS(DCLZ, dclz)
46 
47 DO_MIPS64R6__RD__RS(BITSWAP, bitswap)
48 DO_MIPS64R6__RD__RS(DBITSWAP, dbitswap)
49 
50 
51 #define DO_MIPS64R6__RD__RS_RT(suffix, mnemonic)                       \
52 static inline void do_mips64r6_##suffix(const void *input1,            \
53                                         const void *input2,            \
54                                         void *output)                  \
55 {                                                                      \
56    __asm__ volatile (                                                  \
57       "ld $t1, 0(%0)\n\t"                                              \
58       "ld $t2, 0(%1)\n\t"                                              \
59       #mnemonic " $t0, $t1, $t2\n\t"                                   \
60       "sd $t0, 0(%2)\n\t"                                              \
61       :                                                                \
62       : "r" (input1), "r" (input2), "r" (output)                       \
63       : "t0", "t1", "memory"                                           \
64    );                                                                  \
65 }
66 
67 DO_MIPS64R6__RD__RS_RT(SLLV, sllv)
68 DO_MIPS64R6__RD__RS_RT(SRLV, srlv)
69 DO_MIPS64R6__RD__RS_RT(SRAV, srav)
70 DO_MIPS64R6__RD__RS_RT(DSLLV, dsllv)
71 DO_MIPS64R6__RD__RS_RT(DSRLV, dsrlv)
72 DO_MIPS64R6__RD__RS_RT(DSRAV, dsrav)
73 
74 DO_MIPS64R6__RD__RS_RT(MUL, mul)
75 DO_MIPS64R6__RD__RS_RT(MUH, muh)
76 DO_MIPS64R6__RD__RS_RT(MULU, mulu)
77 DO_MIPS64R6__RD__RS_RT(MUHU, muhu)
78 DO_MIPS64R6__RD__RS_RT(DMUL, dmul)
79 DO_MIPS64R6__RD__RS_RT(DMUH, dmuh)
80 DO_MIPS64R6__RD__RS_RT(DMULU, dmulu)
81 DO_MIPS64R6__RD__RS_RT(DMUHU, dmuhu)
82 
83 
84 #define DO_MIPS64R6__RT__RS_RT(suffix, mnemonic)                       \
85 static inline void do_mips64r6_##suffix(const void *input1,            \
86                                         const void *input2,            \
87                                         void *output)                  \
88 {                                                                      \
89     if (strncmp(#mnemonic, "crc32", 5) == 0)                           \
90         __asm__ volatile (                                             \
91            ".set crc\n\t"                                              \
92         );                                                             \
93                                                                        \
94    __asm__ volatile (                                                  \
95       "ld $t1, 0(%0)\n\t"                                              \
96       "ld $t2, 0(%1)\n\t"                                              \
97       #mnemonic " $t2, $t1, $t2\n\t"                                   \
98       "sd $t2, 0(%2)\n\t"                                              \
99       :                                                                \
100       : "r" (input1), "r" (input2), "r" (output)                       \
101       : "t0", "t1", "t2", "memory"                                     \
102    );                                                                  \
103 }
104 
105 DO_MIPS64R6__RT__RS_RT(CRC32B, crc32b)
106 DO_MIPS64R6__RT__RS_RT(CRC32H, crc32h)
107 DO_MIPS64R6__RT__RS_RT(CRC32W, crc32w)
108 DO_MIPS64R6__RT__RS_RT(CRC32D, crc32d)
109 
110 DO_MIPS64R6__RT__RS_RT(CRC32CB, crc32cb)
111 DO_MIPS64R6__RT__RS_RT(CRC32CH, crc32ch)
112 DO_MIPS64R6__RT__RS_RT(CRC32CW, crc32cw)
113 DO_MIPS64R6__RT__RS_RT(CRC32CD, crc32cd)
114 
115 #endif
116