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 "pan_ir.h" 28#include "util/macros.h" 29 30/* Converts a per-component mask to a byte mask */ 31 32uint16_t 33pan_to_bytemask(unsigned bytes, unsigned mask) 34{ 35 switch (bytes) { 36 case 0: 37 assert(mask == 0); 38 return 0; 39 40 case 8: 41 return mask; 42 43 case 16: { 44 unsigned space = 45 (mask & 0x1) | 46 ((mask & 0x2) << (2 - 1)) | 47 ((mask & 0x4) << (4 - 2)) | 48 ((mask & 0x8) << (6 - 3)) | 49 ((mask & 0x10) << (8 - 4)) | 50 ((mask & 0x20) << (10 - 5)) | 51 ((mask & 0x40) << (12 - 6)) | 52 ((mask & 0x80) << (14 - 7)); 53 54 return space | (space << 1); 55 } 56 57 case 32: { 58 unsigned space = 59 (mask & 0x1) | 60 ((mask & 0x2) << (4 - 1)) | 61 ((mask & 0x4) << (8 - 2)) | 62 ((mask & 0x8) << (12 - 3)); 63 64 return space | (space << 1) | (space << 2) | (space << 3); 65 } 66 67 case 64: { 68 unsigned A = (mask & 0x1) ? 0xFF : 0x00; 69 unsigned B = (mask & 0x2) ? 0xFF : 0x00; 70 return A | (B << 8); 71 } 72 73 default: 74 unreachable("Invalid register mode"); 75 } 76} 77 78void 79pan_block_add_successor(pan_block *block, pan_block *successor) 80{ 81 assert(block); 82 assert(successor); 83 84 /* Cull impossible edges */ 85 if (block->unconditional_jumps) 86 return; 87 88 for (unsigned i = 0; i < ARRAY_SIZE(block->successors); ++i) { 89 if (block->successors[i]) { 90 if (block->successors[i] == successor) 91 return; 92 else 93 continue; 94 } 95 96 block->successors[i] = successor; 97 _mesa_set_add(successor->predecessors, block); 98 return; 99 } 100 101 unreachable("Too many successors"); 102} 103 104/* Prints a NIR ALU type in Bifrost-style ".f32" ".i8" etc */ 105 106void 107pan_print_alu_type(nir_alu_type t, FILE *fp) 108{ 109 unsigned size = nir_alu_type_get_type_size(t); 110 nir_alu_type base = nir_alu_type_get_base_type(t); 111 112 switch (base) { 113 case nir_type_int: 114 fprintf(fp, ".i"); 115 break; 116 case nir_type_uint: 117 fprintf(fp, ".u"); 118 break; 119 case nir_type_bool: 120 fprintf(fp, ".b"); 121 break; 122 case nir_type_float: 123 fprintf(fp, ".f"); 124 break; 125 default: 126 fprintf(fp, ".unknown"); 127 break; 128 } 129 130 fprintf(fp, "%u", size); 131} 132 133/* Could optimize with a better data structure if anyone cares, TODO: profile */ 134 135unsigned 136pan_lookup_pushed_ubo(struct panfrost_ubo_push *push, unsigned ubo, unsigned offs) 137{ 138 struct panfrost_ubo_word word = { 139 .ubo = ubo, 140 .offset = offs 141 }; 142 143 for (unsigned i = 0; i < push->count; ++i) { 144 if (memcmp(push->words + i, &word, sizeof(word)) == 0) 145 return i; 146 } 147 148 unreachable("UBO not pushed"); 149 150} 151