1 /*
2 * Copyright (C) 2021 Collabora Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors (Collabora):
24 * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
25 */
26
27 #ifndef __VALHALL_H
28 #define __VALHALL_H
29
30 #include <stdint.h>
31 #include "bi_opcodes.h"
32 #include "valhall_enums.h"
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37
38 #define VA_NUM_GENERAL_SLOTS 3
39
40 extern const uint32_t valhall_immediates[32];
41
42 enum va_size {
43 VA_SIZE_8 = 0,
44 VA_SIZE_16 = 1,
45 VA_SIZE_32 = 2,
46 VA_SIZE_64 = 3,
47 };
48
49 enum va_unit {
50 /** Fused floating-point multiply-add */
51 VA_UNIT_FMA = 0,
52
53 /** Type conversion and basic arithmetic */
54 VA_UNIT_CVT = 1,
55
56 /** Special function unit */
57 VA_UNIT_SFU = 2,
58
59 /** Varying */
60 VA_UNIT_V = 3,
61
62 /** General load/store */
63 VA_UNIT_LS = 4,
64
65 /** Texture */
66 VA_UNIT_T = 5,
67
68 /** Fused varying and texture */
69 VA_UNIT_VT = 6,
70
71 /** Produces a message for a unit not otherwise specified */
72 VA_UNIT_NONE = 7
73 };
74
75 struct va_src_info {
76 bool absneg : 1;
77 bool swizzle : 1;
78 bool notted : 1;
79 bool lane : 1;
80 bool lanes : 1;
81 bool halfswizzle : 1;
82 bool widen : 1;
83 bool combine : 1;
84 enum va_size size : 2;
85 } __attribute__((packed));
86
87 struct va_opcode_info {
88 uint64_t exact;
89 struct va_src_info srcs[4];
90 uint8_t type_size : 8;
91 enum va_unit unit : 3;
92 unsigned nr_srcs : 3;
93 unsigned nr_staging_srcs : 2;
94 unsigned nr_staging_dests : 2;
95 bool has_dest : 1;
96 bool is_signed : 1;
97 bool clamp : 1;
98 bool round_mode : 1;
99 bool condition : 1;
100 bool result_type : 1;
101 bool vecsize : 1;
102 bool register_format : 1;
103 bool slot : 1;
104 bool sr_count : 1;
105 bool sr_write_count : 1;
106 unsigned sr_control : 2;
107 };
108
109 extern const struct va_opcode_info
110 valhall_opcodes[BI_NUM_OPCODES];
111
112 /* Bifrost specifies the source of bitwise operations as (A, B, shift), but
113 * Valhall specifies (A, shift, B). We follow Bifrost conventions in the
114 * compiler, so normalize.
115 *
116 * Bifrost specifies BLEND as staging + (coverage, blend descriptor), but
117 * Valhall specifies staging + (blend descriptor, coverage). Given we put
118 * staging sources first, this works out to the same swap as bitwise ops.
119 */
120
121 static inline bool
va_swap_12(enum bi_opcode op)122 va_swap_12(enum bi_opcode op)
123 {
124 switch (op) {
125 case BI_OPCODE_BLEND:
126 case BI_OPCODE_LSHIFT_AND_I32:
127 case BI_OPCODE_LSHIFT_AND_V2I16:
128 case BI_OPCODE_LSHIFT_AND_V4I8:
129 case BI_OPCODE_LSHIFT_OR_I32:
130 case BI_OPCODE_LSHIFT_OR_V2I16:
131 case BI_OPCODE_LSHIFT_OR_V4I8:
132 case BI_OPCODE_LSHIFT_XOR_I32:
133 case BI_OPCODE_LSHIFT_XOR_V2I16:
134 case BI_OPCODE_LSHIFT_XOR_V4I8:
135 case BI_OPCODE_RSHIFT_AND_I32:
136 case BI_OPCODE_RSHIFT_AND_V2I16:
137 case BI_OPCODE_RSHIFT_AND_V4I8:
138 case BI_OPCODE_RSHIFT_OR_I32:
139 case BI_OPCODE_RSHIFT_OR_V2I16:
140 case BI_OPCODE_RSHIFT_OR_V4I8:
141 case BI_OPCODE_RSHIFT_XOR_I32:
142 case BI_OPCODE_RSHIFT_XOR_V2I16:
143 case BI_OPCODE_RSHIFT_XOR_V4I8:
144 return true;
145 default:
146 return false;
147 }
148 }
149
150 static inline struct va_src_info
va_src_info(enum bi_opcode op,unsigned src)151 va_src_info(enum bi_opcode op, unsigned src)
152 {
153 unsigned idx = (va_swap_12(op) && (src == 1 || src == 2)) ? (3 - src) : src;
154 return valhall_opcodes[op].srcs[idx];
155 }
156
157 static inline bool
va_flow_is_wait_or_none(enum va_flow flow)158 va_flow_is_wait_or_none(enum va_flow flow)
159 {
160 return (flow <= VA_FLOW_WAIT);
161 }
162
163 #ifdef __cplusplus
164 } /* extern C */
165 #endif
166
167 #endif
168