2 * Copyright © 2014 Broadcom
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:
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
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 set_src_raddr(uint64_t inst
, struct qpu_reg src
)
30 if (src
.mux
== QPU_MUX_A
) {
31 /* These asserts could be better, checking to be sure we're
32 * not overwriting an actual use of a raddr of 0.
34 assert(QPU_GET_FIELD(inst
, QPU_RADDR_A
) == 0 ||
35 QPU_GET_FIELD(inst
, QPU_RADDR_A
) == src
.addr
);
36 return inst
| QPU_SET_FIELD(src
.addr
, QPU_RADDR_A
);
39 if (src
.mux
== QPU_MUX_B
) {
40 assert(QPU_GET_FIELD(inst
, QPU_RADDR_B
) == 0 ||
41 QPU_GET_FIELD(inst
, QPU_RADDR_B
) == src
.addr
);
42 return inst
| QPU_SET_FIELD(src
.addr
, QPU_RADDR_B
);
53 inst
|= QPU_SET_FIELD(QPU_A_NOP
, QPU_OP_ADD
);
54 inst
|= QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_ADD
);
55 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
65 inst
|= QPU_SET_FIELD(QPU_M_NOP
, QPU_OP_MUL
);
66 inst
|= QPU_SET_FIELD(QPU_W_NOP
, QPU_WADDR_MUL
);
67 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
73 qpu_a_dst(struct qpu_reg dst
)
77 if (dst
.mux
<= QPU_MUX_R5
) {
78 /* Translate the mux to the ACCn values. */
79 inst
|= QPU_SET_FIELD(32 + dst
.mux
, QPU_WADDR_ADD
);
81 inst
|= QPU_SET_FIELD(dst
.addr
, QPU_WADDR_ADD
);
82 if (dst
.mux
== QPU_MUX_B
)
90 qpu_m_dst(struct qpu_reg dst
)
94 if (dst
.mux
<= QPU_MUX_R5
) {
95 /* Translate the mux to the ACCn values. */
96 inst
|= QPU_SET_FIELD(32 + dst
.mux
, QPU_WADDR_MUL
);
98 inst
|= QPU_SET_FIELD(dst
.addr
, QPU_WADDR_MUL
);
99 if (dst
.mux
== QPU_MUX_A
)
107 qpu_a_MOV(struct qpu_reg dst
, struct qpu_reg src
)
111 inst
|= QPU_SET_FIELD(QPU_A_OR
, QPU_OP_ADD
);
112 inst
|= qpu_a_dst(dst
);
113 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_ADD
);
114 inst
|= QPU_SET_FIELD(src
.mux
, QPU_ADD_A
);
115 inst
|= QPU_SET_FIELD(src
.mux
, QPU_ADD_B
);
116 inst
|= set_src_raddr(inst
, src
);
117 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
123 qpu_m_MOV(struct qpu_reg dst
, struct qpu_reg src
)
127 inst
|= QPU_SET_FIELD(QPU_M_V8MIN
, QPU_OP_MUL
);
128 inst
|= qpu_m_dst(dst
);
129 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_MUL
);
130 inst
|= QPU_SET_FIELD(src
.mux
, QPU_MUL_A
);
131 inst
|= QPU_SET_FIELD(src
.mux
, QPU_MUL_B
);
132 inst
|= set_src_raddr(inst
, src
);
133 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
139 qpu_load_imm_ui(struct qpu_reg dst
, uint32_t val
)
143 inst
|= qpu_a_dst(dst
);
144 inst
|= qpu_m_dst(qpu_rb(QPU_W_NOP
));
145 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_ADD
);
146 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_MUL
);
147 inst
|= QPU_SET_FIELD(QPU_SIG_LOAD_IMM
, QPU_SIG
);
154 qpu_a_alu2(enum qpu_op_add op
,
155 struct qpu_reg dst
, struct qpu_reg src0
, struct qpu_reg src1
)
159 inst
|= QPU_SET_FIELD(op
, QPU_OP_ADD
);
160 inst
|= qpu_a_dst(dst
);
161 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_ADD
);
162 inst
|= QPU_SET_FIELD(src0
.mux
, QPU_ADD_A
);
163 inst
|= set_src_raddr(inst
, src0
);
164 inst
|= QPU_SET_FIELD(src1
.mux
, QPU_ADD_B
);
165 inst
|= set_src_raddr(inst
, src1
);
166 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
172 qpu_m_alu2(enum qpu_op_mul op
,
173 struct qpu_reg dst
, struct qpu_reg src0
, struct qpu_reg src1
)
177 set_src_raddr(inst
, src0
);
178 set_src_raddr(inst
, src1
);
180 inst
|= QPU_SET_FIELD(op
, QPU_OP_MUL
);
181 inst
|= qpu_m_dst(dst
);
182 inst
|= QPU_SET_FIELD(QPU_COND_ALWAYS
, QPU_COND_MUL
);
183 inst
|= QPU_SET_FIELD(src0
.mux
, QPU_MUL_A
);
184 inst
|= set_src_raddr(inst
, src0
);
185 inst
|= QPU_SET_FIELD(src1
.mux
, QPU_MUL_B
);
186 inst
|= set_src_raddr(inst
, src1
);
187 inst
|= QPU_SET_FIELD(QPU_SIG_NONE
, QPU_SIG
);
193 qpu_inst(uint64_t add
, uint64_t mul
)
195 uint64_t merge
= add
| mul
;
197 /* If either one has no signal field, then use the other's signal field.
198 * (since QPU_SIG_NONE != 0).
200 if (QPU_GET_FIELD(add
, QPU_SIG
) == QPU_SIG_NONE
)
201 merge
= (merge
& ~QPU_SIG_MASK
) | (mul
& QPU_SIG_MASK
);
202 else if (QPU_GET_FIELD(mul
, QPU_SIG
) == QPU_SIG_NONE
)
203 merge
= (merge
& ~QPU_SIG_MASK
) | (add
& QPU_SIG_MASK
);
205 assert(QPU_GET_FIELD(add
, QPU_SIG
) ==
206 QPU_GET_FIELD(mul
, QPU_SIG
));
213 qpu_set_sig(uint64_t inst
, uint32_t sig
)
215 assert(QPU_GET_FIELD(inst
, QPU_SIG
) == QPU_SIG_NONE
);
216 return (inst
& ~QPU_SIG_MASK
) | QPU_SET_FIELD(sig
, QPU_SIG
);