1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (c) 2017 Lima Project 3bf215546Sopenharmony_ci * Copyright (c) 2013 Connor Abbott 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 6bf215546Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 7bf215546Sopenharmony_ci * in the Software without restriction, including without limitation the rights 8bf215546Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9bf215546Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 13bf215546Sopenharmony_ci * all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18bf215546Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21bf215546Sopenharmony_ci * THE SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#ifndef LIMA_IR_PP_PPIR_H 26bf215546Sopenharmony_ci#define LIMA_IR_PP_PPIR_H 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "util/u_math.h" 29bf215546Sopenharmony_ci#include "util/list.h" 30bf215546Sopenharmony_ci#include "util/set.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "ir/lima_ir.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_citypedef enum { 35bf215546Sopenharmony_ci ppir_op_unsupported = 0, 36bf215546Sopenharmony_ci ppir_op_mov, 37bf215546Sopenharmony_ci ppir_op_abs, 38bf215546Sopenharmony_ci ppir_op_neg, 39bf215546Sopenharmony_ci ppir_op_sat, 40bf215546Sopenharmony_ci ppir_op_add, 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci ppir_op_ddx, 43bf215546Sopenharmony_ci ppir_op_ddy, 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci ppir_op_mul, 46bf215546Sopenharmony_ci ppir_op_rcp, 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci ppir_op_sin_lut, 49bf215546Sopenharmony_ci ppir_op_cos_lut, 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci ppir_op_sum3, 52bf215546Sopenharmony_ci ppir_op_sum4, 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci ppir_op_normalize2, 55bf215546Sopenharmony_ci ppir_op_normalize3, 56bf215546Sopenharmony_ci ppir_op_normalize4, 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci ppir_op_select, 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci ppir_op_sin, 61bf215546Sopenharmony_ci ppir_op_cos, 62bf215546Sopenharmony_ci ppir_op_tan, 63bf215546Sopenharmony_ci ppir_op_asin, 64bf215546Sopenharmony_ci ppir_op_acos, 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci ppir_op_atan, 67bf215546Sopenharmony_ci ppir_op_atan2, 68bf215546Sopenharmony_ci ppir_op_atan_pt1, 69bf215546Sopenharmony_ci ppir_op_atan2_pt1, 70bf215546Sopenharmony_ci ppir_op_atan_pt2, 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci ppir_op_exp, 73bf215546Sopenharmony_ci ppir_op_log, 74bf215546Sopenharmony_ci ppir_op_exp2, 75bf215546Sopenharmony_ci ppir_op_log2, 76bf215546Sopenharmony_ci ppir_op_sqrt, 77bf215546Sopenharmony_ci ppir_op_rsqrt, 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci ppir_op_sign, 80bf215546Sopenharmony_ci ppir_op_floor, 81bf215546Sopenharmony_ci ppir_op_ceil, 82bf215546Sopenharmony_ci ppir_op_fract, 83bf215546Sopenharmony_ci ppir_op_mod, 84bf215546Sopenharmony_ci ppir_op_min, 85bf215546Sopenharmony_ci ppir_op_max, 86bf215546Sopenharmony_ci ppir_op_trunc, 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci ppir_op_and, 89bf215546Sopenharmony_ci ppir_op_or, 90bf215546Sopenharmony_ci ppir_op_xor, 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci ppir_op_lt, 93bf215546Sopenharmony_ci ppir_op_gt, 94bf215546Sopenharmony_ci ppir_op_le, 95bf215546Sopenharmony_ci ppir_op_ge, 96bf215546Sopenharmony_ci ppir_op_eq, 97bf215546Sopenharmony_ci ppir_op_ne, 98bf215546Sopenharmony_ci ppir_op_not, 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci ppir_op_load_uniform, 101bf215546Sopenharmony_ci ppir_op_load_varying, 102bf215546Sopenharmony_ci ppir_op_load_coords, 103bf215546Sopenharmony_ci ppir_op_load_coords_reg, 104bf215546Sopenharmony_ci ppir_op_load_fragcoord, 105bf215546Sopenharmony_ci ppir_op_load_pointcoord, 106bf215546Sopenharmony_ci ppir_op_load_frontface, 107bf215546Sopenharmony_ci ppir_op_load_texture, 108bf215546Sopenharmony_ci ppir_op_load_temp, 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci ppir_op_store_temp, 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci ppir_op_const, 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci ppir_op_discard, 115bf215546Sopenharmony_ci ppir_op_branch, 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci ppir_op_undef, 118bf215546Sopenharmony_ci ppir_op_dummy, 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci ppir_op_num, 121bf215546Sopenharmony_ci} ppir_op; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_citypedef enum { 124bf215546Sopenharmony_ci ppir_node_type_alu, 125bf215546Sopenharmony_ci ppir_node_type_const, 126bf215546Sopenharmony_ci ppir_node_type_load, 127bf215546Sopenharmony_ci ppir_node_type_store, 128bf215546Sopenharmony_ci ppir_node_type_load_texture, 129bf215546Sopenharmony_ci ppir_node_type_discard, 130bf215546Sopenharmony_ci ppir_node_type_branch, 131bf215546Sopenharmony_ci} ppir_node_type; 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_citypedef struct { 134bf215546Sopenharmony_ci char *name; 135bf215546Sopenharmony_ci ppir_node_type type; 136bf215546Sopenharmony_ci int *slots; 137bf215546Sopenharmony_ci} ppir_op_info; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ciextern const ppir_op_info ppir_op_infos[]; 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_citypedef enum { 142bf215546Sopenharmony_ci ppir_dep_src, 143bf215546Sopenharmony_ci ppir_dep_write_after_read, 144bf215546Sopenharmony_ci ppir_dep_sequence, 145bf215546Sopenharmony_ci} ppir_dep_type; 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_citypedef struct { 148bf215546Sopenharmony_ci void *pred, *succ; 149bf215546Sopenharmony_ci ppir_dep_type type; 150bf215546Sopenharmony_ci struct list_head pred_link; 151bf215546Sopenharmony_ci struct list_head succ_link; 152bf215546Sopenharmony_ci} ppir_dep; 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_citypedef struct ppir_node { 155bf215546Sopenharmony_ci struct list_head list; 156bf215546Sopenharmony_ci struct list_head sched_list; 157bf215546Sopenharmony_ci ppir_op op; 158bf215546Sopenharmony_ci ppir_node_type type; 159bf215546Sopenharmony_ci int index; 160bf215546Sopenharmony_ci char name[16]; 161bf215546Sopenharmony_ci bool printed; 162bf215546Sopenharmony_ci struct ppir_instr *instr; 163bf215546Sopenharmony_ci int instr_pos; 164bf215546Sopenharmony_ci struct ppir_block *block; 165bf215546Sopenharmony_ci bool is_out; 166bf215546Sopenharmony_ci bool succ_different_block; 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci /* for scheduler */ 169bf215546Sopenharmony_ci struct list_head succ_list; 170bf215546Sopenharmony_ci struct list_head pred_list; 171bf215546Sopenharmony_ci} ppir_node; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_citypedef enum { 174bf215546Sopenharmony_ci ppir_pipeline_reg_const0, 175bf215546Sopenharmony_ci ppir_pipeline_reg_const1, 176bf215546Sopenharmony_ci ppir_pipeline_reg_sampler, 177bf215546Sopenharmony_ci ppir_pipeline_reg_uniform, 178bf215546Sopenharmony_ci ppir_pipeline_reg_vmul, 179bf215546Sopenharmony_ci ppir_pipeline_reg_fmul, 180bf215546Sopenharmony_ci ppir_pipeline_reg_discard, /* varying load */ 181bf215546Sopenharmony_ci} ppir_pipeline; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_citypedef enum { 184bf215546Sopenharmony_ci ppir_output_color0, 185bf215546Sopenharmony_ci ppir_output_color1, 186bf215546Sopenharmony_ci ppir_output_depth, 187bf215546Sopenharmony_ci ppir_output_num, 188bf215546Sopenharmony_ci ppir_output_invalid = -1, 189bf215546Sopenharmony_ci} ppir_output_type; 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_cistatic inline const char *ppir_output_type_to_str(ppir_output_type type) 192bf215546Sopenharmony_ci{ 193bf215546Sopenharmony_ci switch (type) { 194bf215546Sopenharmony_ci case ppir_output_color0: 195bf215546Sopenharmony_ci return "OUTPUT_COLOR0"; 196bf215546Sopenharmony_ci case ppir_output_color1: 197bf215546Sopenharmony_ci return "OUTPUT_COLOR1"; 198bf215546Sopenharmony_ci case ppir_output_depth: 199bf215546Sopenharmony_ci return "OUTPUT_DEPTH"; 200bf215546Sopenharmony_ci default: 201bf215546Sopenharmony_ci return "INVALID"; 202bf215546Sopenharmony_ci } 203bf215546Sopenharmony_ci} 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_cistatic inline ppir_output_type ppir_nir_output_to_ppir(gl_frag_result res, int dual_src_index) 206bf215546Sopenharmony_ci{ 207bf215546Sopenharmony_ci switch (res) { 208bf215546Sopenharmony_ci case FRAG_RESULT_COLOR: 209bf215546Sopenharmony_ci case FRAG_RESULT_DATA0: 210bf215546Sopenharmony_ci return ppir_output_color0 + dual_src_index; 211bf215546Sopenharmony_ci case FRAG_RESULT_DEPTH: 212bf215546Sopenharmony_ci return ppir_output_depth; 213bf215546Sopenharmony_ci default: 214bf215546Sopenharmony_ci return ppir_output_invalid; 215bf215546Sopenharmony_ci } 216bf215546Sopenharmony_ci} 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_citypedef struct ppir_reg { 219bf215546Sopenharmony_ci struct list_head list; 220bf215546Sopenharmony_ci int index; 221bf215546Sopenharmony_ci ppir_output_type out_type; 222bf215546Sopenharmony_ci int regalloc_index; 223bf215546Sopenharmony_ci int num_components; 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci /* whether this reg has to start from the x component 226bf215546Sopenharmony_ci * of a full physical reg, this is true for reg used 227bf215546Sopenharmony_ci * in load/store instr which has no swizzle field */ 228bf215546Sopenharmony_ci bool is_head; 229bf215546Sopenharmony_ci bool spilled; 230bf215546Sopenharmony_ci bool undef; 231bf215546Sopenharmony_ci bool out_reg; 232bf215546Sopenharmony_ci} ppir_reg; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_citypedef enum { 235bf215546Sopenharmony_ci ppir_target_ssa, 236bf215546Sopenharmony_ci ppir_target_pipeline, 237bf215546Sopenharmony_ci ppir_target_register, 238bf215546Sopenharmony_ci} ppir_target; 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_citypedef struct ppir_src { 241bf215546Sopenharmony_ci ppir_target type; 242bf215546Sopenharmony_ci ppir_node *node; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci union { 245bf215546Sopenharmony_ci ppir_reg *ssa; 246bf215546Sopenharmony_ci ppir_reg *reg; 247bf215546Sopenharmony_ci ppir_pipeline pipeline; 248bf215546Sopenharmony_ci }; 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci uint8_t swizzle[4]; 251bf215546Sopenharmony_ci bool absolute, negate; 252bf215546Sopenharmony_ci} ppir_src; 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_citypedef enum { 255bf215546Sopenharmony_ci ppir_outmod_none, 256bf215546Sopenharmony_ci ppir_outmod_clamp_fraction, 257bf215546Sopenharmony_ci ppir_outmod_clamp_positive, 258bf215546Sopenharmony_ci ppir_outmod_round, 259bf215546Sopenharmony_ci} ppir_outmod; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_citypedef struct ppir_dest { 262bf215546Sopenharmony_ci ppir_target type; 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci union { 265bf215546Sopenharmony_ci ppir_reg ssa; 266bf215546Sopenharmony_ci ppir_reg *reg; 267bf215546Sopenharmony_ci ppir_pipeline pipeline; 268bf215546Sopenharmony_ci }; 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci ppir_outmod modifier; 271bf215546Sopenharmony_ci unsigned write_mask : 4; 272bf215546Sopenharmony_ci} ppir_dest; 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_citypedef struct { 275bf215546Sopenharmony_ci ppir_node node; 276bf215546Sopenharmony_ci ppir_dest dest; 277bf215546Sopenharmony_ci ppir_src src[3]; 278bf215546Sopenharmony_ci int num_src; 279bf215546Sopenharmony_ci int shift : 3; /* Only used for ppir_op_mul */ 280bf215546Sopenharmony_ci} ppir_alu_node; 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_citypedef struct ppir_const { 283bf215546Sopenharmony_ci union fi value[4]; 284bf215546Sopenharmony_ci int num; 285bf215546Sopenharmony_ci} ppir_const; 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_citypedef struct { 288bf215546Sopenharmony_ci ppir_node node; 289bf215546Sopenharmony_ci ppir_const constant; 290bf215546Sopenharmony_ci ppir_dest dest; 291bf215546Sopenharmony_ci} ppir_const_node; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_citypedef enum { 294bf215546Sopenharmony_ci ppir_perspective_none = 0, 295bf215546Sopenharmony_ci ppir_perspective_z, 296bf215546Sopenharmony_ci ppir_perspective_w, 297bf215546Sopenharmony_ci} ppir_perspective; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_citypedef struct { 300bf215546Sopenharmony_ci ppir_node node; 301bf215546Sopenharmony_ci int index; 302bf215546Sopenharmony_ci int num_components; 303bf215546Sopenharmony_ci ppir_dest dest; 304bf215546Sopenharmony_ci ppir_src src; 305bf215546Sopenharmony_ci int num_src; 306bf215546Sopenharmony_ci ppir_perspective perspective; 307bf215546Sopenharmony_ci int sampler_dim; 308bf215546Sopenharmony_ci} ppir_load_node; 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_citypedef struct { 311bf215546Sopenharmony_ci ppir_node node; 312bf215546Sopenharmony_ci int index; 313bf215546Sopenharmony_ci int num_components; 314bf215546Sopenharmony_ci ppir_src src; 315bf215546Sopenharmony_ci} ppir_store_node; 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_citypedef struct { 318bf215546Sopenharmony_ci ppir_node node; 319bf215546Sopenharmony_ci ppir_dest dest; 320bf215546Sopenharmony_ci ppir_src src[2]; 321bf215546Sopenharmony_ci int num_src; 322bf215546Sopenharmony_ci int sampler; 323bf215546Sopenharmony_ci int sampler_dim; 324bf215546Sopenharmony_ci bool lod_bias_en; 325bf215546Sopenharmony_ci bool explicit_lod; 326bf215546Sopenharmony_ci} ppir_load_texture_node; 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_citypedef struct { 329bf215546Sopenharmony_ci ppir_node node; 330bf215546Sopenharmony_ci} ppir_discard_node; 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_cienum ppir_instr_slot { 333bf215546Sopenharmony_ci PPIR_INSTR_SLOT_VARYING, 334bf215546Sopenharmony_ci PPIR_INSTR_SLOT_TEXLD, 335bf215546Sopenharmony_ci PPIR_INSTR_SLOT_UNIFORM, 336bf215546Sopenharmony_ci PPIR_INSTR_SLOT_ALU_VEC_MUL, 337bf215546Sopenharmony_ci PPIR_INSTR_SLOT_ALU_SCL_MUL, 338bf215546Sopenharmony_ci PPIR_INSTR_SLOT_ALU_VEC_ADD, 339bf215546Sopenharmony_ci PPIR_INSTR_SLOT_ALU_SCL_ADD, 340bf215546Sopenharmony_ci PPIR_INSTR_SLOT_ALU_COMBINE, 341bf215546Sopenharmony_ci PPIR_INSTR_SLOT_STORE_TEMP, 342bf215546Sopenharmony_ci PPIR_INSTR_SLOT_BRANCH, 343bf215546Sopenharmony_ci PPIR_INSTR_SLOT_NUM, 344bf215546Sopenharmony_ci PPIR_INSTR_SLOT_END, 345bf215546Sopenharmony_ci PPIR_INSTR_SLOT_ALU_START = PPIR_INSTR_SLOT_ALU_VEC_MUL, 346bf215546Sopenharmony_ci PPIR_INSTR_SLOT_ALU_END = PPIR_INSTR_SLOT_ALU_COMBINE, 347bf215546Sopenharmony_ci}; 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_citypedef struct ppir_instr { 350bf215546Sopenharmony_ci struct list_head list; 351bf215546Sopenharmony_ci int index; 352bf215546Sopenharmony_ci bool printed; 353bf215546Sopenharmony_ci int seq; /* command sequence after schedule */ 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci ppir_node *slots[PPIR_INSTR_SLOT_NUM]; 356bf215546Sopenharmony_ci ppir_const constant[2]; 357bf215546Sopenharmony_ci bool stop; 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci /* for scheduler */ 360bf215546Sopenharmony_ci struct list_head succ_list; 361bf215546Sopenharmony_ci struct list_head pred_list; 362bf215546Sopenharmony_ci float reg_pressure; 363bf215546Sopenharmony_ci int est; /* earliest start time */ 364bf215546Sopenharmony_ci int parent_index; 365bf215546Sopenharmony_ci bool scheduled; 366bf215546Sopenharmony_ci int offset; 367bf215546Sopenharmony_ci int encode_size; 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci /* for liveness analysis */ 370bf215546Sopenharmony_ci BITSET_WORD *live_set; 371bf215546Sopenharmony_ci uint8_t *live_mask; /* mask for non-ssa registers */ 372bf215546Sopenharmony_ci /* live_internal is to mark registers only live within an 373bf215546Sopenharmony_ci * instruction, without propagation */ 374bf215546Sopenharmony_ci BITSET_WORD *live_internal; 375bf215546Sopenharmony_ci} ppir_instr; 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_citypedef struct ppir_block { 378bf215546Sopenharmony_ci struct list_head list; 379bf215546Sopenharmony_ci struct list_head node_list; 380bf215546Sopenharmony_ci struct list_head instr_list; 381bf215546Sopenharmony_ci bool stop; 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci struct ppir_block *successors[2]; 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci struct ppir_compiler *comp; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci /* for scheduler */ 388bf215546Sopenharmony_ci int sched_instr_index; 389bf215546Sopenharmony_ci int sched_instr_base; 390bf215546Sopenharmony_ci int index; 391bf215546Sopenharmony_ci} ppir_block; 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_citypedef struct { 394bf215546Sopenharmony_ci ppir_node node; 395bf215546Sopenharmony_ci ppir_src src[2]; 396bf215546Sopenharmony_ci int num_src; 397bf215546Sopenharmony_ci bool cond_gt; 398bf215546Sopenharmony_ci bool cond_eq; 399bf215546Sopenharmony_ci bool cond_lt; 400bf215546Sopenharmony_ci bool negate; 401bf215546Sopenharmony_ci ppir_block *target; 402bf215546Sopenharmony_ci} ppir_branch_node; 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_cistruct ra_regs; 405bf215546Sopenharmony_cistruct lima_fs_compiled_shader; 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_citypedef struct ppir_compiler { 408bf215546Sopenharmony_ci struct list_head block_list; 409bf215546Sopenharmony_ci struct hash_table_u64 *blocks; 410bf215546Sopenharmony_ci int cur_index; 411bf215546Sopenharmony_ci int cur_instr_index; 412bf215546Sopenharmony_ci int *out_type_to_reg; 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci struct list_head reg_list; 415bf215546Sopenharmony_ci int reg_num; 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci /* array for searching ssa/reg node */ 418bf215546Sopenharmony_ci ppir_node **var_nodes; 419bf215546Sopenharmony_ci unsigned reg_base; 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci struct ra_regs *ra; 422bf215546Sopenharmony_ci struct lima_fs_compiled_shader *prog; 423bf215546Sopenharmony_ci bool uses_discard; 424bf215546Sopenharmony_ci bool dual_source_blend; 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci /* for scheduler */ 427bf215546Sopenharmony_ci int sched_instr_base; 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci /* for regalloc spilling debug */ 430bf215546Sopenharmony_ci int force_spilling; 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci /* shaderdb */ 433bf215546Sopenharmony_ci int num_loops; 434bf215546Sopenharmony_ci int num_spills; 435bf215546Sopenharmony_ci int num_fills; 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_ci ppir_block *discard_block; 438bf215546Sopenharmony_ci ppir_block *current_block; 439bf215546Sopenharmony_ci ppir_block *loop_break_block; 440bf215546Sopenharmony_ci ppir_block *loop_cont_block; 441bf215546Sopenharmony_ci} ppir_compiler; 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_civoid *ppir_node_create(ppir_block *block, ppir_op op, int index, unsigned mask); 444bf215546Sopenharmony_civoid ppir_node_add_dep(ppir_node *succ, ppir_node *pred, ppir_dep_type type); 445bf215546Sopenharmony_civoid ppir_node_remove_dep(ppir_dep *dep); 446bf215546Sopenharmony_civoid ppir_node_delete(ppir_node *node); 447bf215546Sopenharmony_civoid ppir_node_print_prog(ppir_compiler *comp); 448bf215546Sopenharmony_civoid ppir_node_replace_child(ppir_node *parent, ppir_node *old_child, ppir_node *new_child); 449bf215546Sopenharmony_civoid ppir_node_replace_all_succ(ppir_node *dst, ppir_node *src); 450bf215546Sopenharmony_civoid ppir_node_replace_pred(ppir_dep *dep, ppir_node *new_pred); 451bf215546Sopenharmony_cippir_dep *ppir_dep_for_pred(ppir_node *node, ppir_node *pred); 452bf215546Sopenharmony_ci/* Assumes that node successors are in the same block */ 453bf215546Sopenharmony_cippir_node *ppir_node_insert_mov(ppir_node *node); 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_cistatic inline bool ppir_node_is_root(ppir_node *node) 456bf215546Sopenharmony_ci{ 457bf215546Sopenharmony_ci return list_is_empty(&node->succ_list); 458bf215546Sopenharmony_ci} 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_cistatic inline bool ppir_node_is_leaf(ppir_node *node) 461bf215546Sopenharmony_ci{ 462bf215546Sopenharmony_ci return list_is_empty(&node->pred_list); 463bf215546Sopenharmony_ci} 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_cistatic inline bool ppir_node_has_single_succ(ppir_node *node) 466bf215546Sopenharmony_ci{ 467bf215546Sopenharmony_ci return list_is_singular(&node->succ_list) 468bf215546Sopenharmony_ci && !node->succ_different_block; 469bf215546Sopenharmony_ci} 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_cibool ppir_node_has_single_src_succ(ppir_node *node); 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_cistatic inline ppir_node *ppir_node_first_succ(ppir_node *node) 474bf215546Sopenharmony_ci{ 475bf215546Sopenharmony_ci return list_first_entry(&node->succ_list, ppir_dep, succ_link)->succ; 476bf215546Sopenharmony_ci} 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_cistatic inline bool ppir_node_has_single_pred(ppir_node *node) 479bf215546Sopenharmony_ci{ 480bf215546Sopenharmony_ci return list_is_singular(&node->pred_list); 481bf215546Sopenharmony_ci} 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_cistatic inline ppir_node *ppir_node_first_pred(ppir_node *node) 484bf215546Sopenharmony_ci{ 485bf215546Sopenharmony_ci return list_first_entry(&node->pred_list, ppir_dep, pred_link)->pred; 486bf215546Sopenharmony_ci} 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci#define ppir_node_foreach_succ(node, dep) \ 489bf215546Sopenharmony_ci list_for_each_entry(ppir_dep, dep, &node->succ_list, succ_link) 490bf215546Sopenharmony_ci#define ppir_node_foreach_succ_safe(node, dep) \ 491bf215546Sopenharmony_ci list_for_each_entry_safe(ppir_dep, dep, &node->succ_list, succ_link) 492bf215546Sopenharmony_ci#define ppir_node_foreach_pred(node, dep) \ 493bf215546Sopenharmony_ci list_for_each_entry(ppir_dep, dep, &node->pred_list, pred_link) 494bf215546Sopenharmony_ci#define ppir_node_foreach_pred_safe(node, dep) \ 495bf215546Sopenharmony_ci list_for_each_entry_safe(ppir_dep, dep, &node->pred_list, pred_link) 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci#define ppir_node_to_alu(node) ((ppir_alu_node *)(node)) 498bf215546Sopenharmony_ci#define ppir_node_to_const(node) ((ppir_const_node *)(node)) 499bf215546Sopenharmony_ci#define ppir_node_to_load(node) ((ppir_load_node *)(node)) 500bf215546Sopenharmony_ci#define ppir_node_to_store(node) ((ppir_store_node *)(node)) 501bf215546Sopenharmony_ci#define ppir_node_to_load_texture(node) ((ppir_load_texture_node *)(node)) 502bf215546Sopenharmony_ci#define ppir_node_to_discard(node) ((ppir_discard_node *)(node)) 503bf215546Sopenharmony_ci#define ppir_node_to_branch(node) ((ppir_branch_node *)(node)) 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_cistatic inline ppir_dest *ppir_node_get_dest(ppir_node *node) 506bf215546Sopenharmony_ci{ 507bf215546Sopenharmony_ci assert(node); 508bf215546Sopenharmony_ci switch (node->type) { 509bf215546Sopenharmony_ci case ppir_node_type_alu: 510bf215546Sopenharmony_ci return &ppir_node_to_alu(node)->dest; 511bf215546Sopenharmony_ci case ppir_node_type_load: 512bf215546Sopenharmony_ci return &ppir_node_to_load(node)->dest; 513bf215546Sopenharmony_ci case ppir_node_type_const: 514bf215546Sopenharmony_ci return &ppir_node_to_const(node)->dest; 515bf215546Sopenharmony_ci case ppir_node_type_load_texture: 516bf215546Sopenharmony_ci return &ppir_node_to_load_texture(node)->dest; 517bf215546Sopenharmony_ci default: 518bf215546Sopenharmony_ci return NULL; 519bf215546Sopenharmony_ci } 520bf215546Sopenharmony_ci} 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_cistatic inline int ppir_node_get_src_num(ppir_node *node) 523bf215546Sopenharmony_ci{ 524bf215546Sopenharmony_ci assert(node); 525bf215546Sopenharmony_ci switch (node->type) { 526bf215546Sopenharmony_ci case ppir_node_type_alu: 527bf215546Sopenharmony_ci return ppir_node_to_alu(node)->num_src; 528bf215546Sopenharmony_ci case ppir_node_type_branch: 529bf215546Sopenharmony_ci return ppir_node_to_branch(node)->num_src; 530bf215546Sopenharmony_ci case ppir_node_type_load: 531bf215546Sopenharmony_ci return ppir_node_to_load(node)->num_src; 532bf215546Sopenharmony_ci case ppir_node_type_load_texture: 533bf215546Sopenharmony_ci return ppir_node_to_load_texture(node)->num_src; 534bf215546Sopenharmony_ci case ppir_node_type_store: 535bf215546Sopenharmony_ci return 1; 536bf215546Sopenharmony_ci default: 537bf215546Sopenharmony_ci return 0; 538bf215546Sopenharmony_ci } 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci return 0; 541bf215546Sopenharmony_ci} 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_cistatic inline ppir_src *ppir_node_get_src(ppir_node *node, int idx) 544bf215546Sopenharmony_ci{ 545bf215546Sopenharmony_ci if (idx < 0 || idx >= ppir_node_get_src_num(node)) 546bf215546Sopenharmony_ci return NULL; 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci switch (node->type) { 549bf215546Sopenharmony_ci case ppir_node_type_alu: 550bf215546Sopenharmony_ci return &ppir_node_to_alu(node)->src[idx]; 551bf215546Sopenharmony_ci case ppir_node_type_branch: 552bf215546Sopenharmony_ci return &ppir_node_to_branch(node)->src[idx]; 553bf215546Sopenharmony_ci case ppir_node_type_load_texture: 554bf215546Sopenharmony_ci return &ppir_node_to_load_texture(node)->src[idx]; 555bf215546Sopenharmony_ci case ppir_node_type_load: 556bf215546Sopenharmony_ci return &ppir_node_to_load(node)->src; 557bf215546Sopenharmony_ci case ppir_node_type_store: 558bf215546Sopenharmony_ci return &ppir_node_to_store(node)->src; 559bf215546Sopenharmony_ci default: 560bf215546Sopenharmony_ci break; 561bf215546Sopenharmony_ci } 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_ci return NULL; 564bf215546Sopenharmony_ci} 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_cistatic inline ppir_reg *ppir_src_get_reg(ppir_src *src) 567bf215546Sopenharmony_ci{ 568bf215546Sopenharmony_ci switch (src->type) { 569bf215546Sopenharmony_ci case ppir_target_ssa: 570bf215546Sopenharmony_ci return src->ssa; 571bf215546Sopenharmony_ci case ppir_target_register: 572bf215546Sopenharmony_ci return src->reg; 573bf215546Sopenharmony_ci default: 574bf215546Sopenharmony_ci return NULL; 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci} 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_cistatic inline ppir_reg *ppir_dest_get_reg(ppir_dest *dest) 579bf215546Sopenharmony_ci{ 580bf215546Sopenharmony_ci switch (dest->type) { 581bf215546Sopenharmony_ci case ppir_target_ssa: 582bf215546Sopenharmony_ci return &dest->ssa; 583bf215546Sopenharmony_ci case ppir_target_register: 584bf215546Sopenharmony_ci return dest->reg; 585bf215546Sopenharmony_ci default: 586bf215546Sopenharmony_ci return NULL; 587bf215546Sopenharmony_ci } 588bf215546Sopenharmony_ci} 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_cistatic inline void ppir_node_target_assign(ppir_src *src, ppir_node *node) 591bf215546Sopenharmony_ci{ 592bf215546Sopenharmony_ci ppir_dest *dest = ppir_node_get_dest(node); 593bf215546Sopenharmony_ci src->type = dest->type; 594bf215546Sopenharmony_ci switch (src->type) { 595bf215546Sopenharmony_ci case ppir_target_ssa: 596bf215546Sopenharmony_ci src->ssa = &dest->ssa; 597bf215546Sopenharmony_ci src->node = node; 598bf215546Sopenharmony_ci break; 599bf215546Sopenharmony_ci case ppir_target_register: 600bf215546Sopenharmony_ci src->reg = dest->reg; 601bf215546Sopenharmony_ci /* Registers can be assigned from multiple nodes, so don't keep 602bf215546Sopenharmony_ci * pointer to the node here 603bf215546Sopenharmony_ci */ 604bf215546Sopenharmony_ci src->node = NULL; 605bf215546Sopenharmony_ci break; 606bf215546Sopenharmony_ci case ppir_target_pipeline: 607bf215546Sopenharmony_ci src->pipeline = dest->pipeline; 608bf215546Sopenharmony_ci src->node = node; 609bf215546Sopenharmony_ci break; 610bf215546Sopenharmony_ci } 611bf215546Sopenharmony_ci} 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_cistatic inline bool ppir_node_target_equal(ppir_src *src, ppir_dest *dest) 614bf215546Sopenharmony_ci{ 615bf215546Sopenharmony_ci if (src->type != dest->type || 616bf215546Sopenharmony_ci (src->type == ppir_target_ssa && src->ssa != &dest->ssa) || 617bf215546Sopenharmony_ci (src->type == ppir_target_register && src->reg != dest->reg) || 618bf215546Sopenharmony_ci (src->type == ppir_target_pipeline && src->pipeline != dest->pipeline)) 619bf215546Sopenharmony_ci return false; 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci return true; 622bf215546Sopenharmony_ci} 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_cistatic inline int ppir_target_get_src_reg_index(ppir_src *src) 625bf215546Sopenharmony_ci{ 626bf215546Sopenharmony_ci switch (src->type) { 627bf215546Sopenharmony_ci case ppir_target_ssa: 628bf215546Sopenharmony_ci if (src->ssa) 629bf215546Sopenharmony_ci return src->ssa->index; 630bf215546Sopenharmony_ci break; 631bf215546Sopenharmony_ci case ppir_target_register: 632bf215546Sopenharmony_ci if (src->reg) 633bf215546Sopenharmony_ci return src->reg->index; 634bf215546Sopenharmony_ci break; 635bf215546Sopenharmony_ci case ppir_target_pipeline: 636bf215546Sopenharmony_ci if (src->pipeline == ppir_pipeline_reg_discard) 637bf215546Sopenharmony_ci return 15 * 4; 638bf215546Sopenharmony_ci return (src->pipeline + 12) * 4; 639bf215546Sopenharmony_ci } 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci return -1; 642bf215546Sopenharmony_ci} 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_cistatic inline int ppir_target_get_dest_reg_index(ppir_dest *dest) 645bf215546Sopenharmony_ci{ 646bf215546Sopenharmony_ci switch (dest->type) { 647bf215546Sopenharmony_ci case ppir_target_ssa: 648bf215546Sopenharmony_ci return dest->ssa.index; 649bf215546Sopenharmony_ci case ppir_target_register: 650bf215546Sopenharmony_ci return dest->reg->index; 651bf215546Sopenharmony_ci case ppir_target_pipeline: 652bf215546Sopenharmony_ci if (dest->pipeline == ppir_pipeline_reg_discard) 653bf215546Sopenharmony_ci return 15 * 4; 654bf215546Sopenharmony_ci return (dest->pipeline + 12) * 4; 655bf215546Sopenharmony_ci } 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci return -1; 658bf215546Sopenharmony_ci} 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_cistatic inline int ppir_src_get_mask(ppir_src *src) 661bf215546Sopenharmony_ci{ 662bf215546Sopenharmony_ci ppir_reg *reg = ppir_src_get_reg(src); 663bf215546Sopenharmony_ci int mask = 0; 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci for (int i = 0; i < reg->num_components; i++) 666bf215546Sopenharmony_ci mask |= (1 << src->swizzle[i]); 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci return mask; 669bf215546Sopenharmony_ci} 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_cistatic inline bool ppir_target_is_scalar(ppir_dest *dest) 672bf215546Sopenharmony_ci{ 673bf215546Sopenharmony_ci switch (dest->type) { 674bf215546Sopenharmony_ci case ppir_target_ssa: 675bf215546Sopenharmony_ci return dest->ssa.num_components == 1; 676bf215546Sopenharmony_ci case ppir_target_register: 677bf215546Sopenharmony_ci /* only one bit in mask is set */ 678bf215546Sopenharmony_ci if ((dest->write_mask & 0x3) == 0x3 || 679bf215546Sopenharmony_ci (dest->write_mask & 0x5) == 0x5 || 680bf215546Sopenharmony_ci (dest->write_mask & 0x9) == 0x9 || 681bf215546Sopenharmony_ci (dest->write_mask & 0x6) == 0x6 || 682bf215546Sopenharmony_ci (dest->write_mask & 0xa) == 0xa || 683bf215546Sopenharmony_ci (dest->write_mask & 0xc) == 0xc) 684bf215546Sopenharmony_ci return false; 685bf215546Sopenharmony_ci else 686bf215546Sopenharmony_ci return true; 687bf215546Sopenharmony_ci case ppir_target_pipeline: 688bf215546Sopenharmony_ci if (dest->pipeline == ppir_pipeline_reg_fmul) 689bf215546Sopenharmony_ci return true; 690bf215546Sopenharmony_ci else 691bf215546Sopenharmony_ci return false; 692bf215546Sopenharmony_ci default: 693bf215546Sopenharmony_ci return false; 694bf215546Sopenharmony_ci } 695bf215546Sopenharmony_ci} 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_cistatic inline bool ppir_node_schedulable_slot(ppir_node *node, 698bf215546Sopenharmony_ci enum ppir_instr_slot slot) 699bf215546Sopenharmony_ci{ 700bf215546Sopenharmony_ci int *slots = ppir_op_infos[node->op].slots; 701bf215546Sopenharmony_ci for (int i = 0; slots[i] != PPIR_INSTR_SLOT_END; i++) 702bf215546Sopenharmony_ci if (slots[i] == slot) 703bf215546Sopenharmony_ci return true; 704bf215546Sopenharmony_ci 705bf215546Sopenharmony_ci return false; 706bf215546Sopenharmony_ci} 707bf215546Sopenharmony_ci 708bf215546Sopenharmony_cippir_instr *ppir_instr_create(ppir_block *block); 709bf215546Sopenharmony_cibool ppir_instr_insert_node(ppir_instr *instr, ppir_node *node); 710bf215546Sopenharmony_civoid ppir_instr_add_dep(ppir_instr *succ, ppir_instr *pred); 711bf215546Sopenharmony_civoid ppir_instr_print_list(ppir_compiler *comp); 712bf215546Sopenharmony_civoid ppir_instr_print_dep(ppir_compiler *comp); 713bf215546Sopenharmony_civoid ppir_instr_insert_mul_node(ppir_node *add, ppir_node *mul); 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci#define ppir_instr_foreach_succ(instr, dep) \ 716bf215546Sopenharmony_ci list_for_each_entry(ppir_dep, dep, &instr->succ_list, succ_link) 717bf215546Sopenharmony_ci#define ppir_instr_foreach_succ_safe(instr, dep) \ 718bf215546Sopenharmony_ci list_for_each_entry_safe(ppir_dep, dep, &instr->succ_list, succ_link) 719bf215546Sopenharmony_ci#define ppir_instr_foreach_pred(instr, dep) \ 720bf215546Sopenharmony_ci list_for_each_entry(ppir_dep, dep, &instr->pred_list, pred_link) 721bf215546Sopenharmony_ci#define ppir_instr_foreach_pred_safe(instr, dep) \ 722bf215546Sopenharmony_ci list_for_each_entry_safe(ppir_dep, dep, &instr->pred_list, pred_link) 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_cistatic inline bool ppir_instr_is_root(ppir_instr *instr) 725bf215546Sopenharmony_ci{ 726bf215546Sopenharmony_ci return list_is_empty(&instr->succ_list); 727bf215546Sopenharmony_ci} 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_cistatic inline bool ppir_instr_is_leaf(ppir_instr *instr) 730bf215546Sopenharmony_ci{ 731bf215546Sopenharmony_ci return list_is_empty(&instr->pred_list); 732bf215546Sopenharmony_ci} 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_cibool ppir_lower_prog(ppir_compiler *comp); 735bf215546Sopenharmony_cibool ppir_node_to_instr(ppir_compiler *comp); 736bf215546Sopenharmony_cibool ppir_schedule_prog(ppir_compiler *comp); 737bf215546Sopenharmony_cibool ppir_regalloc_prog(ppir_compiler *comp); 738bf215546Sopenharmony_cibool ppir_codegen_prog(ppir_compiler *comp); 739bf215546Sopenharmony_civoid ppir_liveness_analysis(ppir_compiler *comp); 740bf215546Sopenharmony_ci 741bf215546Sopenharmony_cistatic inline unsigned int reg_mask_size(unsigned int num_reg) 742bf215546Sopenharmony_ci{ 743bf215546Sopenharmony_ci return (num_reg + 1) / 2; 744bf215546Sopenharmony_ci} 745bf215546Sopenharmony_ci 746bf215546Sopenharmony_cistatic inline uint8_t get_reg_mask(uint8_t *set, unsigned index) 747bf215546Sopenharmony_ci{ 748bf215546Sopenharmony_ci unsigned int i = index / 2; 749bf215546Sopenharmony_ci unsigned int shift = index % 2 ? 4 : 0; 750bf215546Sopenharmony_ci uint8_t mask = 0x0f << shift; 751bf215546Sopenharmony_ci return (set[i] & mask) >> shift; 752bf215546Sopenharmony_ci} 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_cistatic inline void set_reg_mask(uint8_t *set, unsigned int index, uint8_t bits) 755bf215546Sopenharmony_ci{ 756bf215546Sopenharmony_ci unsigned int i = index / 2; 757bf215546Sopenharmony_ci unsigned int shift = index % 2 ? 4 : 0; 758bf215546Sopenharmony_ci uint8_t mask = 0x0f << shift; 759bf215546Sopenharmony_ci set[i] &= ~mask; 760bf215546Sopenharmony_ci set[i] |= (bits << shift); 761bf215546Sopenharmony_ci} 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci#endif 764