if (inst->imm && inst->src[2].use)
return 1;
- if (!check_uniforms(inst))
+ if (!inst->halti5 && !check_uniforms(inst))
BUG("error: generating instruction that accesses two different uniforms");
assert(!(inst->opcode&~0x7f));
COND(inst->dst.use, VIV_ISA_WORD_0_DST_USE) |
VIV_ISA_WORD_0_DST_AMODE(inst->dst.amode) |
VIV_ISA_WORD_0_DST_REG(inst->dst.reg) |
- VIV_ISA_WORD_0_DST_COMPS(inst->dst.comps) |
+ VIV_ISA_WORD_0_DST_COMPS(inst->dst.write_mask) |
VIV_ISA_WORD_0_TEX_ID(inst->tex.id);
out[1] = VIV_ISA_WORD_1_TEX_AMODE(inst->tex.amode) |
VIV_ISA_WORD_1_TEX_SWIZ(inst->tex.swiz) |
COND(inst->src[2].neg, VIV_ISA_WORD_3_SRC2_NEG) |
COND(inst->src[2].abs, VIV_ISA_WORD_3_SRC2_ABS) |
VIV_ISA_WORD_3_SRC2_AMODE(inst->src[2].amode) |
- VIV_ISA_WORD_3_SRC2_RGROUP(inst->src[2].rgroup);
+ VIV_ISA_WORD_3_SRC2_RGROUP(inst->src[2].rgroup) |
+ COND(inst->sel_bit0, VIV_ISA_WORD_3_SEL_BIT0) |
+ COND(inst->sel_bit1, VIV_ISA_WORD_3_SEL_BIT1) |
+ COND(inst->dst_full, VIV_ISA_WORD_3_DST_FULL);
+
out[3] |= VIV_ISA_WORD_3_SRC2_IMM(inst->imm);
return 0;
#define H_ETNAVIV_ASM
#include <stdint.h>
+#include <stdbool.h>
#include "hw/isa.xml.h"
/* Size of an instruction in 32-bit words */
unsigned use:1; /* 0: not in use, 1: in use */
unsigned amode:3; /* INST_AMODE_* */
unsigned reg:7; /* register number 0..127 */
- unsigned comps:4; /* INST_COMPS_* */
+ unsigned write_mask:4; /* INST_COMPS_* */
};
/* texture operand */
/* source operand */
struct etna_inst_src {
unsigned use:1; /* 0: not in use, 1: in use */
- unsigned reg:9; /* register or uniform number 0..511 */
- unsigned swiz:8; /* INST_SWIZ */
- unsigned neg:1; /* negate (flip sign) if set */
- unsigned abs:1; /* absolute (remove sign) if set */
- unsigned amode:3; /* INST_AMODE_* */
unsigned rgroup:3; /* INST_RGROUP_* */
+ union {
+ struct __attribute__((__packed__)) {
+ unsigned reg:9; /* register or uniform number 0..511 */
+ unsigned swiz:8; /* INST_SWIZ */
+ unsigned neg:1; /* negate (flip sign) if set */
+ unsigned abs:1; /* absolute (remove sign) if set */
+ unsigned amode:3; /* INST_AMODE_* */
+ };
+ struct __attribute__((__packed__)) {
+ unsigned imm_val : 20;
+ unsigned imm_type : 2;
+ };
+ };
};
/*** instruction ***/
uint8_t type; /* INST_TYPE_* */
unsigned cond:5; /* INST_CONDITION_* */
unsigned sat:1; /* saturate result between 0..1 */
+ unsigned sel_bit0:1; /* select low half mediump */
+ unsigned sel_bit1:1; /* select high half mediump */
+ unsigned dst_full:1; /* write to highp register */
+ unsigned halti5:1; /* allow multiple different uniform sources */
struct etna_inst_dst dst; /* destination operand */
struct etna_inst_tex tex; /* texture operand */
struct etna_inst_src src[ETNA_NUM_SRC]; /* source operand */
INST_SWIZ_W((swz1 >> (((swz2 >> 6)&3)*2))&3);
};
+/* Compose two write_masks (computes wm1.wm2) */
+static inline uint32_t inst_write_mask_compose(uint32_t wm1, uint32_t wm2)
+{
+ unsigned wm = 0;
+ for (unsigned i = 0, j = 0; i < 4; i++) {
+ if (wm2 & (1 << i)) {
+ if (wm1 & (1 << j))
+ wm |= (1 << i);
+ j++;
+ }
+ }
+ return wm;
+};
+
/* Return whether the rgroup is one of the uniforms */
static inline int
etna_rgroup_is_uniform(unsigned rgroup)
rgroup == INST_RGROUP_UNIFORM_1;
}
+static inline struct etna_inst_src
+etna_immediate_src(unsigned type, uint32_t bits)
+{
+ return (struct etna_inst_src) {
+ .use = 1,
+ .rgroup = INST_RGROUP_IMMEDIATE,
+ .imm_val = bits,
+ .imm_type = type
+ };
+}
+
/**
* Build vivante instruction from structure with
* opcode, cond, sat, dst_use, dst_amode,