r600g: fix dp2, dp3, dp4 tokens
[mesa.git] / src / gallium / drivers / r600 / r600_shader.c
index 6729fdd0e5c1b8b4a7c8124c274bd00f50962160..d788ab88be0138d8a0dcf4478e1818dd6212c95f 100644 (file)
  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *      Jerome Glisse
  */
-#include <stdio.h>
-#include <errno.h>
-#include <util/u_inlines.h>
-#include <util/u_format.h>
-#include <util/u_memory.h>
-#include <tgsi/tgsi_dump.h>
+#include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_scan.h"
+#include "util/u_format.h"
 #include "r600_screen.h"
 #include "r600_context.h"
+#include "r600_shader.h"
+#include "r600_asm.h"
+#include "r600_sq.h"
 #include "r600d.h"
+#include <stdio.h>
+#include <errno.h>
+
+static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader);
+
+static int r600_shader_update(struct pipe_context *ctx, struct r600_shader *shader)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       const struct util_format_description *desc;
+       enum pipe_format resource_format[160];
+       unsigned i, nresources = 0;
+       struct r600_bc *bc = &shader->bc;
+       struct r600_bc_cf *cf;
+       struct r600_bc_vtx *vtx;
+
+       if (shader->processor_type != TGSI_PROCESSOR_VERTEX)
+               return 0;
+       for (i = 0; i < rctx->vertex_elements->count; i++) {
+               resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format;
+       }
+       LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
+               switch (cf->inst) {
+               case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+               case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+                       LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
+                               desc = util_format_description(resource_format[vtx->buffer_id]);
+                               if (desc == NULL) {
+                                       R600_ERR("unknown format %d\n", resource_format[vtx->buffer_id]);
+                                       return -EINVAL;
+                               }
+                               vtx->dst_sel_x = desc->swizzle[0];
+                               vtx->dst_sel_y = desc->swizzle[1];
+                               vtx->dst_sel_z = desc->swizzle[2];
+                               vtx->dst_sel_w = desc->swizzle[3];
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+       return r600_bc_build(&shader->bc);
+}
+
+struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx,
+                                               const struct tgsi_token *tokens)
+{
+       struct r600_screen *rscreen = r600_screen(ctx->screen);
+       struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
+       int r;
+
+fprintf(stderr, "--------------------------------------------------------------\n");
+tgsi_dump(tokens, 0);
+       if (rpshader == NULL)
+               return NULL;
+       rpshader->shader.family = radeon_get_family(rscreen->rw);
+       r = r600_shader_from_tgsi(tokens, &rpshader->shader);
+       if (r) {
+               R600_ERR("translation from TGSI failed !\n");
+               goto out_err;
+       }
+       r = r600_bc_build(&rpshader->shader.bc);
+       if (r) {
+               R600_ERR("building bytecode failed !\n");
+               goto out_err;
+       }
+fprintf(stderr, "______________________________________________________________\n");
+       return rpshader;
+out_err:
+       free(rpshader);
+       return NULL;
+}
 
 static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
 {
-       struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+       struct r600_screen *rscreen = r600_screen(ctx->screen);
        struct r600_shader *rshader = &rpshader->shader;
        struct radeon_state *state;
-       unsigned i, tmp;
+       unsigned i, j, tmp;
 
        rpshader->state = radeon_state_decref(rpshader->state);
        state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER);
        if (state == NULL)
                return -ENOMEM;
-       for (i = 0; i < rshader->noutput; i += 4) {
-               tmp = rshader->output[i].sid;
-               tmp |= rshader->output[i + 1].sid << 8;
-               tmp |= rshader->output[i + 2].sid << 16;
-               tmp |= rshader->output[i + 3].sid << 24;
-               state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] = tmp;
-       }
-       state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 1);
-       state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->ngpr);
+       for (i = 0; i < 10; i++) {
+               state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i] = 0;
+       }
+       for (i = 0, j = 0; i < rshader->noutput; i++) {
+               if (rshader->output[i].name != TGSI_SEMANTIC_POSITION) {
+                       tmp = rshader->output[i].sid << ((j & 3) * 8);
+                       state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + j / 4] |= tmp;
+                       j++;
+               }
+       }
+       state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2);
+       state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->bc.ngpr);
        rpshader->state = state;
        rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
        rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
@@ -63,7 +135,7 @@ static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader
 
 static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
 {
-       struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+       struct r600_screen *rscreen = r600_screen(ctx->screen);
        struct r600_shader *rshader = &rpshader->shader;
        struct radeon_state *state;
        unsigned i, tmp;
@@ -81,7 +153,7 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
        state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) |
                                                        S_0286CC_PERSP_GRADIENT_ENA(1);
        state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000;
-       state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->ngpr);
+       state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->bc.ngpr);
        state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
        rpshader->state = state;
        rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
@@ -92,29 +164,29 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
 
 static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
 {
-       struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
-       struct r600_context *rctx = (struct r600_context*)ctx;
+       struct r600_screen *rscreen = r600_screen(ctx->screen);
+       struct r600_context *rctx = r600_context(ctx);
        struct r600_shader *rshader = &rpshader->shader;
        int r;
 
        /* copy new shader */
        radeon_bo_decref(rscreen->rw, rpshader->bo);
        rpshader->bo = NULL;
-       rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->ndw * 4,
+       rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->bc.ndw * 4,
                                4096, NULL);
        if (rpshader->bo == NULL) {
                return -ENOMEM;
        }
        radeon_bo_map(rscreen->rw, rpshader->bo);
-       memcpy(rpshader->bo->data, rshader->bcode, rshader->ndw * 4);
+       memcpy(rpshader->bo->data, rshader->bc.bytecode, rshader->bc.ndw * 4);
        radeon_bo_unmap(rscreen->rw, rpshader->bo);
        /* build state */
        rshader->flat_shade = rctx->flat_shade;
-       switch (rpshader->type) {
-       case C_PROGRAM_TYPE_VS:
+       switch (rshader->processor_type) {
+       case TGSI_PROCESSOR_VERTEX:
                r = r600_pipe_shader_vs(ctx, rpshader);
                break;
-       case C_PROGRAM_TYPE_FS:
+       case TGSI_PROCESSOR_FRAGMENT:
                r = r600_pipe_shader_ps(ctx, rpshader);
                break;
        default:
@@ -124,94 +196,677 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r
        return r;
 }
 
-struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens)
+int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
 {
-       struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
-       struct r600_shader *rshader = &rpshader->shader;
+       struct r600_context *rctx = r600_context(ctx);
        int r;
 
        if (rpshader == NULL)
-               return NULL;
-       rpshader->type = type;
-       c_list_init(&rshader->nodes);
-       fprintf(stderr, "<<\n");
-       tgsi_dump(tokens, 0);
-       fprintf(stderr, "--------------------------------------------------------------\n");
-       r = c_shader_from_tgsi(&rshader->cshader, type, tokens);
-       if (r) {
-               r600_pipe_shader_destroy(ctx, rpshader);
-               fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
-               return NULL;
+               return -EINVAL;
+       /* there should be enough input */
+       if (rctx->vertex_elements->count < rpshader->shader.bc.nresource) {
+               R600_ERR("%d resources provided, expecting %d\n",
+                       rctx->vertex_elements->count, rpshader->shader.bc.nresource);
+               return -EINVAL;
        }
-       r = r600_shader_insert_fetch(&rshader->cshader);
-       if (r) {
-               r600_pipe_shader_destroy(ctx, rpshader);
-               fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
-               return NULL;
+       r = r600_shader_update(ctx, &rpshader->shader);
+       if (r)
+               return r;
+       return r600_pipe_shader(ctx, rpshader);
+}
+
+struct r600_shader_tgsi_instruction;
+
+struct r600_shader_ctx {
+       struct tgsi_shader_info                 info;
+       struct tgsi_parse_context               parse;
+       const struct tgsi_token                 *tokens;
+       unsigned                                type;
+       unsigned                                file_offset[TGSI_FILE_COUNT];
+       unsigned                                temp_reg;
+       struct r600_shader_tgsi_instruction     *inst_info;
+       struct r600_bc                          *bc;
+       struct r600_shader                      *shader;
+};
+
+struct r600_shader_tgsi_instruction {
+       unsigned        tgsi_opcode;
+       unsigned        is_op3;
+       unsigned        r600_opcode;
+       int (*process)(struct r600_shader_ctx *ctx);
+};
+
+static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[];
+
+static int tgsi_is_supported(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *i = &ctx->parse.FullToken.FullInstruction;
+       int j;
+
+       if (i->Instruction.NumDstRegs > 1) {
+               R600_ERR("too many dst (%d)\n", i->Instruction.NumDstRegs);
+               return -EINVAL;
        }
-       r = c_shader_build_dominator_tree(&rshader->cshader);
-       if (r) {
-               r600_pipe_shader_destroy(ctx, rpshader);
-               fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
-               return NULL;
+       if (i->Instruction.Saturate) {
+               R600_ERR("staturate unsupported\n");
+               return -EINVAL;
        }
-       c_shader_dump(&rshader->cshader);
-       r = r700_shader_translate(rshader);
-       if (r) {
-               r600_pipe_shader_destroy(ctx, rpshader);
-               fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
-               return NULL;
+       if (i->Instruction.Predicate) {
+               R600_ERR("predicate unsupported\n");
+               return -EINVAL;
        }
-#if 1
-#if 0
-       fprintf(stderr, "--------------------------------------------------------------\n");
-       for (int i = 0; i < rshader->ndw; i++) {
-               fprintf(stderr, "0x%08X\n", rshader->bcode[i]);
+       if (i->Instruction.Label) {
+               R600_ERR("label unsupported\n");
+               return -EINVAL;
        }
-#endif
-       fprintf(stderr, ">>\n\n");
-#endif
-       return rpshader;
+       if (i->Instruction.Texture) {
+               R600_ERR("texture unsupported\n");
+               return -EINVAL;
+       }
+       for (j = 0; j < i->Instruction.NumSrcRegs; j++) {
+               if (i->Src[j].Register.Indirect ||
+                       i->Src[j].Register.Dimension ||
+                       i->Src[j].Register.Absolute) {
+                       R600_ERR("unsupported src (indirect|dimension|absolute)\n");
+                       return -EINVAL;
+               }
+       }
+       for (j = 0; j < i->Instruction.NumDstRegs; j++) {
+               if (i->Dst[j].Register.Indirect || i->Dst[j].Register.Dimension) {
+                       R600_ERR("unsupported dst (indirect|dimension)\n");
+                       return -EINVAL;
+               }
+       }
+       return 0;
 }
 
-void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+static int tgsi_declaration(struct r600_shader_ctx *ctx)
 {
-       struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+       struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration;
+       struct r600_bc_vtx vtx;
+       unsigned i;
+       int r;
 
-       if (rpshader == NULL)
-               return;
-       radeon_bo_decref(rscreen->rw, rpshader->bo);
-       rpshader->bo = NULL;
-       r600_shader_cleanup(&rpshader->shader);
-       FREE(rpshader);
+       switch (d->Declaration.File) {
+       case TGSI_FILE_INPUT:
+               i = ctx->shader->ninput++;
+               ctx->shader->input[i].name = d->Semantic.Name;
+               ctx->shader->input[i].sid = d->Semantic.Index;
+               ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + i;
+               if (ctx->type == TGSI_PROCESSOR_VERTEX) {
+                       /* turn input into fetch */
+                       memset(&vtx, 0, sizeof(struct r600_bc_vtx));
+                       vtx.inst = 0;
+                       vtx.fetch_type = 0;
+                       vtx.buffer_id = i;
+                       /* register containing the index into the buffer */
+                       vtx.src_gpr = 0;
+                       vtx.src_sel_x = 0;
+                       vtx.mega_fetch_count = 0x1F;
+                       vtx.dst_gpr = ctx->shader->input[i].gpr;
+                       vtx.dst_sel_x = 0;
+                       vtx.dst_sel_y = 1;
+                       vtx.dst_sel_z = 2;
+                       vtx.dst_sel_w = 3;
+                       r = r600_bc_add_vtx(ctx->bc, &vtx);
+                       if (r)
+                               return r;
+               }
+               break;
+       case TGSI_FILE_OUTPUT:
+               i = ctx->shader->noutput++;
+               ctx->shader->output[i].name = d->Semantic.Name;
+               ctx->shader->output[i].sid = d->Semantic.Index;
+               ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + i;
+               break;
+       case TGSI_FILE_CONSTANT:
+       case TGSI_FILE_TEMPORARY:
+               break;
+       default:
+               R600_ERR("unsupported file %d declaration\n", d->Declaration.File);
+               return -EINVAL;
+       }
+       return 0;
 }
 
-int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader)
 {
-       struct r600_context *rctx = (struct r600_context*)ctx;
-       struct r600_shader *rshader;
-       enum pipe_format resource_format[160];
-       unsigned i, nresources = 0;
-       int r;
+       struct tgsi_full_immediate *immediate;
+       struct r600_shader_ctx ctx;
+       struct r600_bc_output output;
+       unsigned opcode;
+       int i, r = 0, pos0;
+       u32 value[4];
 
-       if (rpshader == NULL)
-               return -EINVAL;
-       rshader = &rpshader->shader;
-       switch (rpshader->type) {
-       case C_PROGRAM_TYPE_VS:
-               for (i = 0; i < rctx->vertex_elements->count; i++) {
-                       resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format;
+       ctx.bc = &shader->bc;
+       ctx.shader = shader;
+       r = r600_bc_init(ctx.bc, shader->family);
+       if (r)
+               return r;
+       ctx.tokens = tokens;
+       tgsi_scan_shader(tokens, &ctx.info);
+       tgsi_parse_init(&ctx.parse, tokens);
+       ctx.type = ctx.parse.FullHeader.Processor.Processor;
+       shader->processor_type = ctx.type;
+
+       /* register allocations */
+       /* Values [0,127] correspond to GPR[0..127]. 
+        * Values [256,511] correspond to cfile constants c[0..255]. 
+        * Other special values are shown in the list below.
+        * 248  SQ_ALU_SRC_0: special constant 0.0.
+        * 249  SQ_ALU_SRC_1: special constant 1.0 float.
+        * 250  SQ_ALU_SRC_1_INT: special constant 1 integer.
+        * 251  SQ_ALU_SRC_M_1_INT: special constant -1 integer.
+        * 252  SQ_ALU_SRC_0_5: special constant 0.5 float.
+        * 253  SQ_ALU_SRC_LITERAL: literal constant.
+        * 254  SQ_ALU_SRC_PV: previous vector result.
+        * 255  SQ_ALU_SRC_PS: previous scalar result.
+        */
+       for (i = 0; i < TGSI_FILE_COUNT; i++) {
+               ctx.file_offset[i] = 0;
+       }
+       if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+               ctx.file_offset[TGSI_FILE_INPUT] = 1;
+       }
+       ctx.file_offset[TGSI_FILE_OUTPUT] = ctx.file_offset[TGSI_FILE_INPUT] +
+                                               ctx.info.file_count[TGSI_FILE_INPUT];
+       ctx.file_offset[TGSI_FILE_TEMPORARY] = ctx.file_offset[TGSI_FILE_OUTPUT] +
+                                               ctx.info.file_count[TGSI_FILE_OUTPUT];
+       ctx.file_offset[TGSI_FILE_CONSTANT] = 256;
+       ctx.file_offset[TGSI_FILE_IMMEDIATE] = 253;
+       ctx.temp_reg = ctx.file_offset[TGSI_FILE_TEMPORARY] +
+                       ctx.info.file_count[TGSI_FILE_TEMPORARY];
+
+       while (!tgsi_parse_end_of_tokens(&ctx.parse)) {
+               tgsi_parse_token(&ctx.parse);
+               switch (ctx.parse.FullToken.Token.Type) {
+               case TGSI_TOKEN_TYPE_IMMEDIATE:
+//                     R600_ERR("TGSI_TOKEN_TYPE_IMMEDIATE unsupported\n");
+                       immediate = &ctx.parse.FullToken.FullImmediate;
+                       value[0] = immediate->u[0].Uint;
+                       value[1] = immediate->u[1].Uint;
+                       value[2] = immediate->u[2].Uint;
+                       value[3] = immediate->u[3].Uint;
+                       break;
+               case TGSI_TOKEN_TYPE_DECLARATION:
+                       r = tgsi_declaration(&ctx);
+                       if (r)
+                               goto out_err;
+                       break;
+               case TGSI_TOKEN_TYPE_INSTRUCTION:
+                       r = tgsi_is_supported(&ctx);
+                       if (r)
+                               goto out_err;
+                       opcode = ctx.parse.FullToken.FullInstruction.Instruction.Opcode;
+                       ctx.inst_info = &r600_shader_tgsi_instruction[opcode];
+                       r = ctx.inst_info->process(&ctx);
+                       if (r)
+                               goto out_err;
+                       r = r600_bc_add_literal(ctx.bc, value);
+                       if (r)
+                               goto out_err;
+                       break;
+               default:
+                       R600_ERR("unsupported token type %d\n", ctx.parse.FullToken.Token.Type);
+                       r = -EINVAL;
+                       goto out_err;
                }
+       }
+       /* export output */
+       for (i = 0, pos0 = 0; i < shader->noutput; i++) {
+               memset(&output, 0, sizeof(struct r600_bc_output));
+               output.gpr = shader->output[i].gpr;
+               output.elem_size = 3;
+               output.swizzle_x = 0;
+               output.swizzle_y = 1;
+               output.swizzle_z = 2;
+               output.swizzle_w = 3;
+               output.barrier = 1;
+               output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
+               output.array_base = i - pos0;
+               output.inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE;
+               switch (ctx.type == TGSI_PROCESSOR_VERTEX) {
+               case TGSI_PROCESSOR_VERTEX:
+                       if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
+                               output.array_base = 60;
+                               output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+                               /* position doesn't count in array_base */
+                               pos0 = 1;
+                       }
+                       break;
+               case TGSI_PROCESSOR_FRAGMENT:
+                       if (shader->output[i].name == TGSI_SEMANTIC_COLOR) {
+                               output.array_base = 0;
+                               output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+                       } else {
+                               R600_ERR("unsupported fragment output name %d\n", shader->output[i].name);
+                               r = -EINVAL;
+                               goto out_err;
+                       }
+                       break;
+               default:
+                       R600_ERR("unsupported processor type %d\n", ctx.type);
+                       r = -EINVAL;
+                       goto out_err;
+               }
+               if (i == (shader->noutput - 1)) {
+                       output.end_of_program = 1;
+               }
+               r = r600_bc_add_output(ctx.bc, &output);
+               if (r)
+                       goto out_err;
+       }
+       tgsi_parse_free(&ctx.parse);
+       return 0;
+out_err:
+       tgsi_parse_free(&ctx.parse);
+       return r;
+}
+
+static int tgsi_unsupported(struct r600_shader_ctx *ctx)
+{
+       R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode);
+       return -EINVAL;
+}
+
+static int tgsi_end(struct r600_shader_ctx *ctx)
+{
+       return 0;
+}
+
+static int tgsi_src(struct r600_shader_ctx *ctx,
+                       const struct tgsi_full_src_register *tgsi_src,
+                       unsigned swizzle,
+                       struct r600_bc_alu_src *r600_src)
+{
+       r600_src->sel = tgsi_src->Register.Index;
+       if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) {
+               r600_src->sel = 0;
+       }
+       r600_src->sel += ctx->file_offset[tgsi_src->Register.File];
+       switch (swizzle) {
+       case 0:
+               r600_src->chan = tgsi_src->Register.SwizzleX;
                break;
-       default:
+       case 1:
+               r600_src->chan = tgsi_src->Register.SwizzleY;
                break;
-       }
-       /* there should be enough input */
-       if (nresources < rshader->nresource)
+       case 2:
+               r600_src->chan = tgsi_src->Register.SwizzleZ;
+               break;
+       case 3:
+               r600_src->chan = tgsi_src->Register.SwizzleW;
+               break;
+       default:
                return -EINVAL;
-       /* FIXME compare resources */
-       r = r600_shader_update(rshader, resource_format);
-       if (r)
-               return r;
-       return r600_pipe_shader(ctx, rpshader);
+       }
+       return 0;
+}
+
+static int tgsi_dst(struct r600_shader_ctx *ctx,
+                       const struct tgsi_full_dst_register *tgsi_dst,
+                       unsigned swizzle,
+                       struct r600_bc_alu_dst *r600_dst)
+{
+       r600_dst->sel = tgsi_dst->Register.Index;
+       r600_dst->sel += ctx->file_offset[tgsi_dst->Register.File];
+       r600_dst->chan = swizzle;
+       r600_dst->write = 1;
+       return 0;
+}
+
+static int tgsi_op2(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, j, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               if (!(inst->Dst[0].Register.WriteMask & (1 << i))) {
+                       alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+               } else {
+                       alu.inst = ctx->inst_info->r600_opcode;
+                       for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+                               r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]);
+                               if (r)
+                                       return r;
+                       }
+                       r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+                       if (r)
+                               return r;
+               }
+               /* handle some special cases */
+               switch (ctx->inst_info->tgsi_opcode) {
+               case TGSI_OPCODE_SUB:
+                       alu.src[1].neg = 1;
+                       break;
+               default:
+                       break;
+               }
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return 0;
 }
+
+static int tgsi_slt(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               if (!(inst->Dst[0].Register.WriteMask & (1 << i))) {
+                       alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+               } else {
+                       alu.inst = ctx->inst_info->r600_opcode;
+                       r = tgsi_src(ctx, &inst->Src[0], i, &alu.src[1]);
+                       if (r)
+                               return r;
+                       r = tgsi_src(ctx, &inst->Src[1], i, &alu.src[0]);
+                       if (r)
+                               return r;
+                       r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+                       if (r)
+                               return r;
+               }
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return 0;
+}
+
+static int tgsi_trans(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, j, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               if (inst->Dst[0].Register.WriteMask & (1 << i)) {
+                       alu.inst = ctx->inst_info->r600_opcode;
+                       for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+                               r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]);
+                               if (r)
+                                       return r;
+                       }
+                       r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+                       if (r)
+                               return r;
+                       alu.last = 1;
+                       r = r600_bc_add_alu(ctx->bc, &alu);
+                       if (r)
+                               return r;
+               }
+       }
+       return 0;
+}
+
+static int tgsi_helper_copy(struct r600_shader_ctx *ctx, struct tgsi_full_instruction *inst)
+{
+       struct r600_bc_alu alu;
+       int i, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               if (!(inst->Dst[0].Register.WriteMask & (1 << i))) {
+                       alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+               } else {
+                       alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+                       r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+                       if (r)
+                               return r;
+                       alu.src[0].sel = ctx->temp_reg;
+                       alu.src[0].chan = i;
+               }
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return 0;
+}
+
+static int tgsi_op3(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, j, r;
+
+       /* do it in 2 step as op3 doesn't support writemask */
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = ctx->inst_info->r600_opcode;
+               for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+                       r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]);
+                       if (r)
+                               return r;
+               }
+               alu.dst.sel = ctx->temp_reg;
+               alu.dst.chan = i;
+               alu.dst.write = 1;
+               alu.is_op3 = 1;
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return tgsi_helper_copy(ctx, inst);
+}
+
+static int tgsi_dp(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, j, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = ctx->inst_info->r600_opcode;
+               for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+                       r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]);
+                       if (r)
+                               return r;
+               }
+               alu.dst.sel = ctx->temp_reg;
+               alu.dst.chan = i;
+               alu.dst.write = 1;
+               /* handle some special cases */
+               switch (ctx->inst_info->tgsi_opcode) {
+               case TGSI_OPCODE_DP2:
+                       if (i > 1) {
+                               alu.src[0].sel = alu.src[1].sel = 248;
+                               alu.src[0].chan = alu.src[1].chan = 0;
+                       }
+                       break;
+               case TGSI_OPCODE_DP3:
+                       if (i > 2) {
+                               alu.src[0].sel = alu.src[1].sel = 248;
+                               alu.src[0].chan = alu.src[1].chan = 0;
+                       }
+                       break;
+               default:
+                       break;
+               }
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return tgsi_helper_copy(ctx, inst);
+}
+
+static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
+       {TGSI_OPCODE_ARL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MOV,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2},
+       {TGSI_OPCODE_LIT,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_RCP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_RSQ,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans},
+       {TGSI_OPCODE_EXP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_LOG,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MUL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2},
+       {TGSI_OPCODE_ADD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2},
+       {TGSI_OPCODE_DP3,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
+       {TGSI_OPCODE_DP4,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
+       {TGSI_OPCODE_DST,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MIN,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MAX,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, tgsi_op2},
+       {TGSI_OPCODE_SLT,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, tgsi_slt},
+       {TGSI_OPCODE_SGE,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MAD,       1, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, tgsi_op3},
+       {TGSI_OPCODE_SUB,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2},
+       {TGSI_OPCODE_LRP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CND,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {20,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DP2A,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {22,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {23,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_FRC,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CLAMP,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_FLR,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ROUND,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_EX2,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_LG2,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_POW,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_XPD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {32,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ABS,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_RCC,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DPH,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_COS,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DDX,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DDY,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_KILP,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},  /* predicated kill */
+       {TGSI_OPCODE_PK2H,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_PK2US,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_PK4B,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_PK4UB,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_RFL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SEQ,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SFL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SGT,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SIN,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SLE,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SNE,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_STR,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TEX,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UP2H,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UP2US,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UP4B,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UP4UB,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_X2D,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ARA,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ARR,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BRA,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CAL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_RET,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SSG,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* SGN */
+       {TGSI_OPCODE_CMP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SCS,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXB,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_NRM,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DIV,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DP2,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
+       {TGSI_OPCODE_TXL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BRK,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IF,        0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {75,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {76,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ELSE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDIF,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {79,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {80,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_PUSHA,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_POPA,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CEIL,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_I2F,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_NOT,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TRUNC,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SHL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {88,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_AND,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_OR,        0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MOD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_XOR,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SAD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXF,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXQ,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CONT,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_EMIT,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDPRIM,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BGNLOOP,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BGNSUB,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDLOOP,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDSUB,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {103,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {104,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {105,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {106,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_NOP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {108,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {109,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {110,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {111,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_NRM4,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CALLNZ,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IFC,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BREAKC,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_KIL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},  /* conditional kill */
+       {TGSI_OPCODE_END,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_end},  /* aka HALT */
+       /* gap */
+       {118,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_F2I,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IDIV,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IMAX,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IMIN,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_INEG,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ISGE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ISHR,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ISLT,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_F2U,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_U2F,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UADD,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UDIV,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMAD,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMAX,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMIN,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMOD,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMUL,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USEQ,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USGE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USHR,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USLT,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USNE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SWITCH,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CASE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DEFAULT,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDSWITCH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_LAST,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+};