1template = """/* 2 * Copyright 2021 Alyssa Rosenzweig 3 * SPDX-License-Identifier: MIT 4 */ 5 6#ifndef _AGX_BUILDER_ 7#define _AGX_BUILDER_ 8 9#include "agx_compiler.h" 10 11static inline agx_instr * 12agx_alloc_instr(agx_builder *b, enum agx_opcode op, uint8_t nr_dests, uint8_t nr_srcs) 13{ 14 size_t size = sizeof(agx_instr); 15 size += sizeof(agx_index) * nr_dests; 16 size += sizeof(agx_index) * nr_srcs; 17 18 agx_instr *I = (agx_instr *) rzalloc_size(b->shader, size); 19 I->dest = (agx_index *) (I + 1); 20 I->src = I->dest + nr_dests; 21 22 I->op = op; 23 I->nr_dests = nr_dests; 24 I->nr_srcs = nr_srcs; 25 return I; 26} 27 28% for opcode in opcodes: 29<% 30 op = opcodes[opcode] 31 dests = op.dests 32 srcs = op.srcs 33 imms = [x for x in op.imms if (x.name != 'scoreboard' or opcode == 'wait')] 34 suffix = "_to" if dests > 0 else "" 35 nr_dests = "nr_dests" if op.variable_dests else str(dests) 36 nr_srcs = "nr_srcs" if op.variable_srcs else str(srcs) 37%> 38 39static inline agx_instr * 40agx_${opcode}${suffix}(agx_builder *b 41 42% if op.variable_dests: 43 , unsigned nr_dests 44% endif 45 46% for dest in range(dests): 47 , agx_index dst${dest} 48% endfor 49 50% if op.variable_srcs: 51 , unsigned nr_srcs 52% endif 53 54% for src in range(srcs): 55 , agx_index src${src} 56% endfor 57 58% for imm in imms: 59 , ${imm.ctype} ${imm.name} 60% endfor 61 62) { 63 agx_instr *I = agx_alloc_instr(b, AGX_OPCODE_${opcode.upper()}, ${nr_dests}, ${nr_srcs}); 64 65% for dest in range(dests): 66 I->dest[${dest}] = dst${dest}; 67% endfor 68 69% for src in range(srcs): 70 I->src[${src}] = src${src}; 71% endfor 72 73% for imm in imms: 74 I->${imm.name} = ${imm.name}; 75% endfor 76 77 agx_builder_insert(&b->cursor, I); 78 return I; 79} 80 81% if dests == 1 and not op.variable_srcs and not op.variable_dests: 82static inline agx_index 83agx_${opcode}(agx_builder *b 84 85% if srcs == 0: 86 , unsigned size 87% endif 88 89% for src in range(srcs): 90 , agx_index src${src} 91% endfor 92 93% for imm in imms: 94 , ${imm.ctype} ${imm.name} 95% endfor 96 97) { 98<% 99 args = ["tmp"] 100 args += ["src" + str(i) for i in range(srcs)] 101 args += [imm.name for imm in imms] 102%> 103% if srcs == 0: 104 agx_index tmp = agx_temp(b->shader, agx_size_for_bits(size)); 105% else: 106 agx_index tmp = agx_temp(b->shader, src0.size); 107% endif 108 agx_${opcode}_to(b, ${", ".join(args)}); 109 return tmp; 110} 111% endif 112 113% endfor 114 115/* Convenience methods */ 116 117enum agx_bitop_table { 118 AGX_BITOP_NOR = 0x1, 119 AGX_BITOP_ANDN2 = 0x2, 120 AGX_BITOP_ANDN1 = 0x4, 121 AGX_BITOP_NOT = 0x5, 122 AGX_BITOP_XOR = 0x6, 123 AGX_BITOP_NAND = 0x7, 124 AGX_BITOP_AND = 0x8, 125 AGX_BITOP_XNOR = 0x9, 126 AGX_BITOP_MOV = 0xA, 127 AGX_BITOP_ORN2 = 0xB, 128 AGX_BITOP_ORN1 = 0xD, 129 AGX_BITOP_OR = 0xE 130}; 131 132#define BINOP_BITOP(name, table) \ 133 static inline agx_instr * \ 134 agx_## name ##_to(agx_builder *b, agx_index dst0, agx_index src0, agx_index src1) \ 135 { \ 136 return agx_bitop_to(b, dst0, src0, src1, AGX_BITOP_ ## table); \ 137 } \ 138 \ 139 static inline agx_index \ 140 agx_## name (agx_builder *b, agx_index src0, agx_index src1) \ 141 { \ 142 agx_index tmp = agx_temp(b->shader, src0.size); \ 143 agx_##name##_to(b, tmp, src0, src1); \ 144 return tmp; \ 145 } 146 147BINOP_BITOP(nor, NOR) 148BINOP_BITOP(andn2, ANDN2) 149BINOP_BITOP(andn1, ANDN1) 150BINOP_BITOP(xor, XOR) 151BINOP_BITOP(nand, NAND) 152BINOP_BITOP(and, AND) 153BINOP_BITOP(xnor, XNOR) 154BINOP_BITOP(orn2, ORN2) 155BINOP_BITOP(orn1, ORN1) 156BINOP_BITOP(or, OR) 157 158#undef BINOP_BITOP 159 160static inline agx_instr * 161agx_fmov_to(agx_builder *b, agx_index dst0, agx_index src0) 162{ 163 return agx_fadd_to(b, dst0, src0, agx_negzero()); 164} 165 166static inline agx_instr * 167agx_push_exec(agx_builder *b, unsigned n) 168{ 169 return agx_if_fcmp(b, agx_zero(), agx_zero(), n, AGX_FCOND_EQ, false, NULL); 170} 171 172static inline agx_instr * 173agx_ushr_to(agx_builder *b, agx_index dst, agx_index s0, agx_index s1) 174{ 175 return agx_bfeil_to(b, dst, agx_zero(), s0, s1, 0); 176} 177 178static inline agx_index 179agx_ushr(agx_builder *b, agx_index s0, agx_index s1) 180{ 181 agx_index tmp = agx_temp(b->shader, s0.size); 182 agx_ushr_to(b, tmp, s0, s1); 183 return tmp; 184} 185 186#endif 187""" 188 189from mako.template import Template 190from agx_opcodes import opcodes 191 192print(Template(template).render(opcodes=opcodes)) 193