pan/bit: Add swizzles to round tests
[mesa.git] / src / panfrost / bifrost / bi_special.c
1 /*
2 * Copyright (C) 2020 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 #include "compiler.h"
28
29 /* Bifrost requires special functions to be lowered in various machine specific
30 * ways. The routines in this file are used in codegen for this. */
31
32 /* New Bifrost has a FEXP2_FAST instruction but requires an auxiliary
33 * parameter. */
34
35 static void
36 bi_emit_fexp2_new(bi_context *ctx, nir_alu_instr *instr)
37 {
38 /* FMA_MSCALE T, X, 1.0, 0, 0x18 */
39
40 bi_instruction mscale = {
41 .type = BI_FMA,
42 .op = { .mscale = true },
43 .dest = bi_make_temp(ctx),
44 .dest_type = nir_type_float32,
45 .src = {
46 pan_src_index(&instr->src[0].src),
47 BIR_INDEX_CONSTANT | 0,
48 BIR_INDEX_ZERO,
49 BIR_INDEX_CONSTANT | 32,
50 },
51 .src_types = {
52 nir_type_float32,
53 nir_type_float32,
54 nir_type_float32,
55 nir_type_int32,
56 },
57 .constant = {
58 /* 0x3f80000000 = 1.0f as fp32
59 * 24 = shift to multiply by 2^24 */
60 .u64 = (0x3f800000) | (24ull << 32)
61 }
62 };
63
64 /* F2I_RTE T, T */
65
66 bi_instruction f2i = {
67 .type = BI_CONVERT,
68 .dest = bi_make_temp(ctx),
69 .dest_type = nir_type_int32,
70 .src = { mscale.dest },
71 .src_types = { nir_type_float32 },
72 .roundmode = BIFROST_RTE
73 };
74
75 /* FEXP2_FAST T, T, X */
76
77 bi_instruction fexp = {
78 .type = BI_SPECIAL,
79 .op = { .special = BI_SPECIAL_EXP2_LOW },
80 .dest = pan_dest_index(&instr->dest.dest),
81 .dest_type = nir_type_float32,
82 .src = { f2i.dest, mscale.src[0] },
83 .src_types = { nir_type_int32, nir_type_float32 },
84 };
85
86 bi_emit(ctx, mscale);
87 bi_emit(ctx, f2i);
88 bi_emit(ctx, fexp);
89 }
90
91 /* Even on new Bifrost, there are a bunch of reductions to do */
92
93 static void
94 bi_emit_flog2_new(bi_context *ctx, nir_alu_instr *instr)
95 {
96 /* LOG_FREXPE X */
97 bi_instruction frexpe = {
98 .type = BI_FREXP,
99 .op = { .frexp = BI_FREXPE_LOG },
100 .dest = bi_make_temp(ctx),
101 .dest_type = nir_type_int32,
102 .src = { pan_src_index(&instr->src[0].src) },
103 .src_types = { nir_type_float32 }
104 };
105
106 /* I32_TO_F32 m */
107 bi_instruction i2f = {
108 .type = BI_CONVERT,
109 .dest = bi_make_temp(ctx),
110 .dest_type = nir_type_float32,
111 .src = { frexpe.dest },
112 .src_types = { nir_type_int32 },
113 .roundmode = BIFROST_RTZ
114 };
115
116 /* ADD_FREXPM (x-1), -1.0, X */
117 bi_instruction x_minus_1 = {
118 .type = BI_REDUCE_FMA,
119 .op = { .reduce = BI_REDUCE_ADD_FREXPM },
120 .dest = bi_make_temp(ctx),
121 .dest_type = nir_type_float32,
122 .src = {
123 BIR_INDEX_CONSTANT,
124 pan_src_index(&instr->src[0].src),
125 },
126 .src_types = { nir_type_float32, nir_type_float32 },
127 .constant = {
128 .u64 = 0xBF800000 /* -1.0 */
129 }
130 };
131
132 /* FLOG2_HELP log2(x)/(x-1), x */
133 bi_instruction help = {
134 .type = BI_TABLE,
135 .op = { .table = BI_TABLE_LOG2_U_OVER_U_1_LOW },
136 .dest = bi_make_temp(ctx),
137 .dest_type = nir_type_float32,
138 .src = { pan_src_index(&instr->src[0].src) },
139 .src_types = { nir_type_float32 },
140 };
141
142 /* FMA log2(x)/(x - 1), (x - 1), M */
143 bi_instruction fma = {
144 .type = BI_FMA,
145 .dest = pan_dest_index(&instr->dest.dest),
146 .dest_type = nir_type_float32,
147 .src = {
148 help.dest,
149 x_minus_1.dest,
150 i2f.dest
151 },
152 .src_types = {
153 nir_type_float32,
154 nir_type_float32,
155 nir_type_float32
156 }
157 };
158
159 bi_emit(ctx, frexpe);
160 bi_emit(ctx, i2f);
161 bi_emit(ctx, x_minus_1);
162 bi_emit(ctx, help);
163 bi_emit(ctx, fma);
164 }
165
166 void
167 bi_emit_fexp2(bi_context *ctx, nir_alu_instr *instr)
168 {
169 /* TODO: G71 */
170 bi_emit_fexp2_new(ctx, instr);
171 }
172
173 void
174 bi_emit_flog2(bi_context *ctx, nir_alu_instr *instr)
175 {
176 /* TODO: G71 */
177 bi_emit_flog2_new(ctx, instr);
178 }