Home | History | Annotate | Download | only in r600
      1 /*
      2  * Copyright 2010 Jerome Glisse <glisse (at) freedesktop.org>
      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  * on the rights to use, copy, modify, merge, publish, distribute, sub
      8  * license, and/or sell copies of the Software, and to permit persons to whom
      9  * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
     18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     22  */
     23 #include "r600_pipe.h"
     24 #include "r600_opcodes.h"
     25 
     26 #include "util/u_memory.h"
     27 #include "eg_sq.h"
     28 #include <errno.h>
     29 
     30 int eg_bytecode_cf_build(struct r600_bytecode *bc, struct r600_bytecode_cf *cf)
     31 {
     32 	unsigned id = cf->id;
     33 
     34 	switch (cf->inst) {
     35 	case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU:
     36 	case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER:
     37 	case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER:
     38 	case EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE:
     39 		/* prepend ALU_EXTENDED if we need more than 2 kcache sets */
     40 		if (cf->eg_alu_extended) {
     41 			bc->bytecode[id++] =
     42 				S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE0(V_SQ_CF_INDEX_NONE) |
     43 				S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE1(V_SQ_CF_INDEX_NONE) |
     44 				S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE2(V_SQ_CF_INDEX_NONE) |
     45 				S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK_INDEX_MODE3(V_SQ_CF_INDEX_NONE) |
     46 				S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK2(cf->kcache[2].bank) |
     47 				S_SQ_CF_ALU_WORD0_EXT_KCACHE_BANK3(cf->kcache[3].bank) |
     48 				S_SQ_CF_ALU_WORD0_EXT_KCACHE_MODE2(cf->kcache[2].mode);
     49 			bc->bytecode[id++] = EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_EXTENDED |
     50 				S_SQ_CF_ALU_WORD1_EXT_KCACHE_MODE3(cf->kcache[3].mode) |
     51 				S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR2(cf->kcache[2].addr) |
     52 				S_SQ_CF_ALU_WORD1_EXT_KCACHE_ADDR3(cf->kcache[3].addr) |
     53 				S_SQ_CF_ALU_WORD1_EXT_BARRIER(1);
     54 		}
     55 
     56 		bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) |
     57 			S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) |
     58 			S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache[0].bank) |
     59 			S_SQ_CF_ALU_WORD0_KCACHE_BANK1(cf->kcache[1].bank);
     60 		bc->bytecode[id++] = cf->inst |
     61 			S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache[1].mode) |
     62 			S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache[0].addr) |
     63 			S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache[1].addr) |
     64 					S_SQ_CF_ALU_WORD1_BARRIER(1) |
     65 					S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
     66 		break;
     67 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX:
     68 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX:
     69 		bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
     70 		bc->bytecode[id++] = cf->inst |
     71 					S_SQ_CF_WORD1_BARRIER(1) |
     72 					S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
     73 		break;
     74 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
     75 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
     76 		bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
     77 			S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
     78 			S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
     79 			S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
     80 		bc->bytecode[id] = S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
     81 			S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) |
     82 			S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
     83 			S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) |
     84 			S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) |
     85 			S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
     86 			cf->output.inst;
     87 		if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
     88 			bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
     89 		id++;
     90 		break;
     91 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF0:
     92 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF1:
     93 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF2:
     94 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0_BUF3:
     95 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF0:
     96 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF1:
     97 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF2:
     98 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1_BUF3:
     99 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF0:
    100 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF1:
    101 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF2:
    102 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2_BUF3:
    103 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF0:
    104 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF1:
    105 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF2:
    106 	case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3_BUF3:
    107 		bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
    108 			S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
    109 			S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
    110 			S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
    111 		bc->bytecode[id] = S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(cf->output.burst_count - 1) |
    112 			S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
    113 			cf->output.inst |
    114 			S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(cf->output.comp_mask) |
    115 			S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(cf->output.array_size);
    116 		if (bc->chip_class == EVERGREEN) /* no EOP on cayman */
    117 			bc->bytecode[id] |= S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
    118 		id++;
    119 		break;
    120 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
    121 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
    122 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_POP:
    123 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
    124 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_DX10:
    125 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
    126 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
    127 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
    128 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
    129 	case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
    130 	case CM_V_SQ_CF_WORD1_SQ_CF_INST_END:
    131 		bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
    132 		bc->bytecode[id++] = cf->inst |
    133 					S_SQ_CF_WORD1_BARRIER(1) |
    134 					S_SQ_CF_WORD1_COND(cf->cond) |
    135 					S_SQ_CF_WORD1_POP_COUNT(cf->pop_count);
    136 		break;
    137 	case CF_NATIVE:
    138 		bc->bytecode[id++] = cf->isa[0];
    139 		bc->bytecode[id++] = cf->isa[1];
    140 		break;
    141 	default:
    142 		R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
    143 		return -EINVAL;
    144 	}
    145 	return 0;
    146 }
    147