Home | History | Annotate | Download | only in etnaviv
      1 /*
      2  * Copyright (c) 2012-2015 Etnaviv Project
      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, sub license,
      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
     12  * next paragraph) shall be included in all copies or substantial portions
     13  * of the 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  *
     23  * Authors:
     24  *    Wladimir J. van der Laan <laanwj (at) gmail.com>
     25  */
     26 
     27 #include "etnaviv_asm.h"
     28 #include "etnaviv_debug.h"
     29 #include "etnaviv_util.h"
     30 
     31 /* An instruction can only read from one distinct uniform.
     32  * This function verifies this property and returns true if the instruction
     33  * is deemed correct and false otherwise.
     34  */
     35 static bool
     36 check_uniforms(const struct etna_inst *inst)
     37 {
     38    unsigned uni_rgroup = -1;
     39    unsigned uni_reg = -1;
     40    bool conflict = false;
     41 
     42    for (unsigned i = 0; i < ETNA_NUM_SRC; i++) {
     43       const struct etna_inst_src *src = &inst->src[i];
     44 
     45       if (!etna_rgroup_is_uniform(src->rgroup))
     46          continue;
     47 
     48       if (uni_reg == -1) { /* first uniform used */
     49          uni_rgroup = src->rgroup;
     50          uni_reg = src->reg;
     51       } else { /* second or later; check that it is a re-use */
     52          if (uni_rgroup != src->rgroup || uni_reg != src->reg) {
     53             conflict = true;
     54          }
     55       }
     56    }
     57 
     58    return !conflict;
     59 }
     60 
     61 int
     62 etna_assemble(uint32_t *out, const struct etna_inst *inst)
     63 {
     64    /* cannot have both src2 and imm */
     65    if (inst->imm && inst->src[2].use)
     66       return 1;
     67 
     68    if (!check_uniforms(inst))
     69       BUG("error: generating instruction that accesses two different uniforms");
     70 
     71    out[0] = VIV_ISA_WORD_0_OPCODE(inst->opcode) |
     72             VIV_ISA_WORD_0_COND(inst->cond) |
     73             COND(inst->sat, VIV_ISA_WORD_0_SAT) |
     74             COND(inst->dst.use, VIV_ISA_WORD_0_DST_USE) |
     75             VIV_ISA_WORD_0_DST_AMODE(inst->dst.amode) |
     76             VIV_ISA_WORD_0_DST_REG(inst->dst.reg) |
     77             VIV_ISA_WORD_0_DST_COMPS(inst->dst.comps) |
     78             VIV_ISA_WORD_0_TEX_ID(inst->tex.id);
     79    out[1] = VIV_ISA_WORD_1_TEX_AMODE(inst->tex.amode) |
     80             VIV_ISA_WORD_1_TEX_SWIZ(inst->tex.swiz) |
     81             COND(inst->src[0].use, VIV_ISA_WORD_1_SRC0_USE) |
     82             VIV_ISA_WORD_1_SRC0_REG(inst->src[0].reg) |
     83             COND(inst->type & 0x4, VIV_ISA_WORD_1_TYPE_BIT2) |
     84             VIV_ISA_WORD_1_SRC0_SWIZ(inst->src[0].swiz) |
     85             COND(inst->src[0].neg, VIV_ISA_WORD_1_SRC0_NEG) |
     86             COND(inst->src[0].abs, VIV_ISA_WORD_1_SRC0_ABS);
     87    out[2] = VIV_ISA_WORD_2_SRC0_AMODE(inst->src[0].amode) |
     88             VIV_ISA_WORD_2_SRC0_RGROUP(inst->src[0].rgroup) |
     89             COND(inst->src[1].use, VIV_ISA_WORD_2_SRC1_USE) |
     90             VIV_ISA_WORD_2_SRC1_REG(inst->src[1].reg) |
     91             VIV_ISA_WORD_2_SRC1_SWIZ(inst->src[1].swiz) |
     92             COND(inst->src[1].neg, VIV_ISA_WORD_2_SRC1_NEG) |
     93             COND(inst->src[1].abs, VIV_ISA_WORD_2_SRC1_ABS) |
     94             VIV_ISA_WORD_2_SRC1_AMODE(inst->src[1].amode) |
     95             VIV_ISA_WORD_2_TYPE_BIT01(inst->type & 0x3);
     96    out[3] = VIV_ISA_WORD_3_SRC1_RGROUP(inst->src[1].rgroup) |
     97             COND(inst->src[2].use, VIV_ISA_WORD_3_SRC2_USE) |
     98             VIV_ISA_WORD_3_SRC2_REG(inst->src[2].reg) |
     99             VIV_ISA_WORD_3_SRC2_SWIZ(inst->src[2].swiz) |
    100             COND(inst->src[2].neg, VIV_ISA_WORD_3_SRC2_NEG) |
    101             COND(inst->src[2].abs, VIV_ISA_WORD_3_SRC2_ABS) |
    102             VIV_ISA_WORD_3_SRC2_AMODE(inst->src[2].amode) |
    103             VIV_ISA_WORD_3_SRC2_RGROUP(inst->src[2].rgroup);
    104    out[3] |= VIV_ISA_WORD_3_SRC2_IMM(inst->imm);
    105 
    106    return 0;
    107 }
    108