1af69d88dSmrg/*
2af69d88dSmrg * Copyright © 2014 Broadcom
3af69d88dSmrg *
4af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5af69d88dSmrg * copy of this software and associated documentation files (the "Software"),
6af69d88dSmrg * to deal in the Software without restriction, including without limitation
7af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the
9af69d88dSmrg * Software is furnished to do so, subject to the following conditions:
10af69d88dSmrg *
11af69d88dSmrg * The above copyright notice and this permission notice (including the next
12af69d88dSmrg * paragraph) shall be included in all copies or substantial portions of the
13af69d88dSmrg * Software.
14af69d88dSmrg *
15af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21af69d88dSmrg * IN THE SOFTWARE.
22af69d88dSmrg */
23af69d88dSmrg
24af69d88dSmrg#ifndef VC4_QPU_H
25af69d88dSmrg#define VC4_QPU_H
26af69d88dSmrg
2701e04c3fSmrg#include <stdio.h>
28af69d88dSmrg#include <stdint.h>
29af69d88dSmrg
30af69d88dSmrg#include "util/u_math.h"
31af69d88dSmrg
32af69d88dSmrg#include "vc4_qpu_defines.h"
33af69d88dSmrg
3401e04c3fSmrgstruct vc4_compile;
3501e04c3fSmrg
36af69d88dSmrgstruct qpu_reg {
37af69d88dSmrg        enum qpu_mux mux;
38af69d88dSmrg        uint8_t addr;
39af69d88dSmrg};
40af69d88dSmrg
41af69d88dSmrgstatic inline struct qpu_reg
42af69d88dSmrgqpu_rn(int n)
43af69d88dSmrg{
44af69d88dSmrg        struct qpu_reg r = {
45af69d88dSmrg                QPU_MUX_R0 + n,
46af69d88dSmrg                0,
47af69d88dSmrg        };
48af69d88dSmrg
49af69d88dSmrg        return r;
50af69d88dSmrg}
51af69d88dSmrg
52af69d88dSmrgstatic inline struct qpu_reg
53af69d88dSmrgqpu_ra(int addr)
54af69d88dSmrg{
55af69d88dSmrg        struct qpu_reg r = {
56af69d88dSmrg                QPU_MUX_A,
57af69d88dSmrg                addr,
58af69d88dSmrg        };
59af69d88dSmrg
60af69d88dSmrg        return r;
61af69d88dSmrg}
62af69d88dSmrg
63af69d88dSmrgstatic inline struct qpu_reg
64af69d88dSmrgqpu_rb(int addr)
65af69d88dSmrg{
66af69d88dSmrg        struct qpu_reg r = {
67af69d88dSmrg                QPU_MUX_B,
68af69d88dSmrg                addr,
69af69d88dSmrg        };
70af69d88dSmrg
71af69d88dSmrg        return r;
72af69d88dSmrg}
73af69d88dSmrg
74af69d88dSmrgstatic inline struct qpu_reg
75af69d88dSmrgqpu_vary()
76af69d88dSmrg{
77af69d88dSmrg        struct qpu_reg r = {
78af69d88dSmrg                QPU_MUX_A,
79af69d88dSmrg                QPU_R_VARY,
80af69d88dSmrg        };
81af69d88dSmrg
82af69d88dSmrg        return r;
83af69d88dSmrg}
84af69d88dSmrg
85af69d88dSmrgstatic inline struct qpu_reg
86af69d88dSmrgqpu_unif()
87af69d88dSmrg{
88af69d88dSmrg        struct qpu_reg r = {
89af69d88dSmrg                QPU_MUX_A,
90af69d88dSmrg                QPU_R_UNIF,
91af69d88dSmrg        };
92af69d88dSmrg
93af69d88dSmrg        return r;
94af69d88dSmrg}
95af69d88dSmrg
96af69d88dSmrgstatic inline struct qpu_reg
97af69d88dSmrgqpu_vrsetup()
98af69d88dSmrg{
99af69d88dSmrg        return qpu_ra(QPU_W_VPMVCD_SETUP);
100af69d88dSmrg}
101af69d88dSmrg
102af69d88dSmrgstatic inline struct qpu_reg
103af69d88dSmrgqpu_vwsetup()
104af69d88dSmrg{
105af69d88dSmrg        return qpu_rb(QPU_W_VPMVCD_SETUP);
106af69d88dSmrg}
107af69d88dSmrg
108af69d88dSmrgstatic inline struct qpu_reg
109af69d88dSmrgqpu_tlbc()
110af69d88dSmrg{
111af69d88dSmrg        struct qpu_reg r = {
112af69d88dSmrg                QPU_MUX_A,
113af69d88dSmrg                QPU_W_TLB_COLOR_ALL,
114af69d88dSmrg        };
115af69d88dSmrg
116af69d88dSmrg        return r;
117af69d88dSmrg}
118af69d88dSmrg
11901e04c3fSmrgstatic inline struct qpu_reg
12001e04c3fSmrgqpu_tlbc_ms()
12101e04c3fSmrg{
12201e04c3fSmrg        struct qpu_reg r = {
12301e04c3fSmrg                QPU_MUX_A,
12401e04c3fSmrg                QPU_W_TLB_COLOR_MS,
12501e04c3fSmrg        };
12601e04c3fSmrg
12701e04c3fSmrg        return r;
12801e04c3fSmrg}
12901e04c3fSmrg
130af69d88dSmrgstatic inline struct qpu_reg qpu_r0(void) { return qpu_rn(0); }
131af69d88dSmrgstatic inline struct qpu_reg qpu_r1(void) { return qpu_rn(1); }
132af69d88dSmrgstatic inline struct qpu_reg qpu_r2(void) { return qpu_rn(2); }
133af69d88dSmrgstatic inline struct qpu_reg qpu_r3(void) { return qpu_rn(3); }
134af69d88dSmrgstatic inline struct qpu_reg qpu_r4(void) { return qpu_rn(4); }
135af69d88dSmrgstatic inline struct qpu_reg qpu_r5(void) { return qpu_rn(5); }
136af69d88dSmrg
13701e04c3fSmrguint64_t qpu_NOP(void) ATTRIBUTE_CONST;
13801e04c3fSmrguint64_t qpu_a_MOV(struct qpu_reg dst, struct qpu_reg src) ATTRIBUTE_CONST;
13901e04c3fSmrguint64_t qpu_m_MOV(struct qpu_reg dst, struct qpu_reg src) ATTRIBUTE_CONST;
140af69d88dSmrguint64_t qpu_a_alu2(enum qpu_op_add op, struct qpu_reg dst,
14101e04c3fSmrg                    struct qpu_reg src0, struct qpu_reg src1) ATTRIBUTE_CONST;
142af69d88dSmrguint64_t qpu_m_alu2(enum qpu_op_mul op, struct qpu_reg dst,
14301e04c3fSmrg                    struct qpu_reg src0, struct qpu_reg src1) ATTRIBUTE_CONST;
14401e04c3fSmrguint64_t qpu_merge_inst(uint64_t a, uint64_t b) ATTRIBUTE_CONST;
14501e04c3fSmrguint64_t qpu_load_imm_ui(struct qpu_reg dst, uint32_t val) ATTRIBUTE_CONST;
14601e04c3fSmrguint64_t qpu_load_imm_u2(struct qpu_reg dst, uint32_t val) ATTRIBUTE_CONST;
14701e04c3fSmrguint64_t qpu_load_imm_i2(struct qpu_reg dst, uint32_t val) ATTRIBUTE_CONST;
14801e04c3fSmrguint64_t qpu_branch(uint32_t cond, uint32_t target) ATTRIBUTE_CONST;
14901e04c3fSmrguint64_t qpu_set_sig(uint64_t inst, uint32_t sig) ATTRIBUTE_CONST;
15001e04c3fSmrguint64_t qpu_set_cond_add(uint64_t inst, uint32_t cond) ATTRIBUTE_CONST;
15101e04c3fSmrguint64_t qpu_set_cond_mul(uint64_t inst, uint32_t cond) ATTRIBUTE_CONST;
15201e04c3fSmrguint32_t qpu_encode_small_immediate(uint32_t i) ATTRIBUTE_CONST;
15301e04c3fSmrguint64_t qpu_m_rot(struct qpu_reg dst, struct qpu_reg src, int rot) ATTRIBUTE_CONST;
15401e04c3fSmrg
15501e04c3fSmrgbool qpu_waddr_is_tlb(uint32_t waddr) ATTRIBUTE_CONST;
15601e04c3fSmrgbool qpu_inst_is_tlb(uint64_t inst) ATTRIBUTE_CONST;
15701e04c3fSmrgint qpu_num_sf_accesses(uint64_t inst) ATTRIBUTE_CONST;
15801e04c3fSmrgvoid qpu_serialize_one_inst(struct vc4_compile *c, uint64_t inst);
15901e04c3fSmrg
16001e04c3fSmrgstatic inline enum qpu_cond
16101e04c3fSmrgqpu_cond_complement(enum qpu_cond cond)
16201e04c3fSmrg{
16301e04c3fSmrg        return cond ^ 1;
16401e04c3fSmrg}
165af69d88dSmrg
166af69d88dSmrgstatic inline uint64_t
167af69d88dSmrgqpu_load_imm_f(struct qpu_reg dst, float val)
168af69d88dSmrg{
169af69d88dSmrg        return qpu_load_imm_ui(dst, fui(val));
170af69d88dSmrg}
171af69d88dSmrg
172af69d88dSmrg#define A_ALU2(op)                                                       \
173af69d88dSmrgstatic inline uint64_t                                                   \
174af69d88dSmrgqpu_a_##op(struct qpu_reg dst, struct qpu_reg src0, struct qpu_reg src1) \
175af69d88dSmrg{                                                                        \
176af69d88dSmrg        return qpu_a_alu2(QPU_A_##op, dst, src0, src1);                  \
177af69d88dSmrg}
178af69d88dSmrg
179af69d88dSmrg#define M_ALU2(op)                                                       \
180af69d88dSmrgstatic inline uint64_t                                                   \
181af69d88dSmrgqpu_m_##op(struct qpu_reg dst, struct qpu_reg src0, struct qpu_reg src1) \
182af69d88dSmrg{                                                                        \
183af69d88dSmrg        return qpu_m_alu2(QPU_M_##op, dst, src0, src1);                  \
184af69d88dSmrg}
185af69d88dSmrg
186af69d88dSmrg#define A_ALU1(op)                                                       \
187af69d88dSmrgstatic inline uint64_t                                                   \
188af69d88dSmrgqpu_a_##op(struct qpu_reg dst, struct qpu_reg src0)                      \
189af69d88dSmrg{                                                                        \
190af69d88dSmrg        return qpu_a_alu2(QPU_A_##op, dst, src0, src0);                  \
191af69d88dSmrg}
192af69d88dSmrg
193af69d88dSmrg/*A_ALU2(NOP) */
194af69d88dSmrgA_ALU2(FADD)
195af69d88dSmrgA_ALU2(FSUB)
196af69d88dSmrgA_ALU2(FMIN)
197af69d88dSmrgA_ALU2(FMAX)
198af69d88dSmrgA_ALU2(FMINABS)
199af69d88dSmrgA_ALU2(FMAXABS)
200af69d88dSmrgA_ALU1(FTOI)
201af69d88dSmrgA_ALU1(ITOF)
202af69d88dSmrgA_ALU2(ADD)
203af69d88dSmrgA_ALU2(SUB)
204af69d88dSmrgA_ALU2(SHR)
205af69d88dSmrgA_ALU2(ASR)
206af69d88dSmrgA_ALU2(ROR)
207af69d88dSmrgA_ALU2(SHL)
208af69d88dSmrgA_ALU2(MIN)
209af69d88dSmrgA_ALU2(MAX)
210af69d88dSmrgA_ALU2(AND)
211af69d88dSmrgA_ALU2(OR)
212af69d88dSmrgA_ALU2(XOR)
213af69d88dSmrgA_ALU1(NOT)
214af69d88dSmrgA_ALU1(CLZ)
215af69d88dSmrgA_ALU2(V8ADDS)
216af69d88dSmrgA_ALU2(V8SUBS)
217af69d88dSmrg
218af69d88dSmrg/* M_ALU2(NOP) */
219af69d88dSmrgM_ALU2(FMUL)
220af69d88dSmrgM_ALU2(MUL24)
221af69d88dSmrgM_ALU2(V8MULD)
222af69d88dSmrgM_ALU2(V8MIN)
223af69d88dSmrgM_ALU2(V8MAX)
224af69d88dSmrgM_ALU2(V8ADDS)
225af69d88dSmrgM_ALU2(V8SUBS)
226af69d88dSmrg
227af69d88dSmrgvoid
228af69d88dSmrgvc4_qpu_disasm(const uint64_t *instructions, int num_instructions);
229af69d88dSmrg
23001e04c3fSmrgvoid
23101e04c3fSmrgvc4_qpu_disasm_pack_mul(FILE *out, uint32_t pack);
23201e04c3fSmrg
23301e04c3fSmrgvoid
23401e04c3fSmrgvc4_qpu_disasm_pack_a(FILE *out, uint32_t pack);
23501e04c3fSmrg
23601e04c3fSmrgvoid
23701e04c3fSmrgvc4_qpu_disasm_unpack(FILE *out, uint32_t pack);
23801e04c3fSmrg
239af69d88dSmrgvoid
240af69d88dSmrgvc4_qpu_validate(uint64_t *insts, uint32_t num_inst);
241af69d88dSmrg
24201e04c3fSmrgvoid
24301e04c3fSmrgvc4_qpu_disasm_cond(FILE *out, uint32_t cond);
24401e04c3fSmrg
24501e04c3fSmrgvoid
24601e04c3fSmrgvc4_qpu_disasm_cond_branch(FILE *out, uint32_t cond);
24701e04c3fSmrg
248af69d88dSmrg#endif /* VC4_QPU_H */
249