etnaviv: asm: new features

* Dual16 bits
* Halti5 disable multiple uniform src
* write_mask compose
* Halti2+ immediates

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
This commit is contained in:
Jonathan Marek 2019-06-27 21:52:22 -04:00
parent 98e59f0a0a
commit e9a5181ad6
3 changed files with 53 additions and 11 deletions

View File

@ -65,7 +65,7 @@ etna_assemble(uint32_t *out, const struct etna_inst *inst)
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));
@ -76,7 +76,7 @@ etna_assemble(uint32_t *out, const struct etna_inst *inst)
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) |
@ -103,7 +103,11 @@ etna_assemble(uint32_t *out, const struct etna_inst *inst)
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;

View File

@ -28,6 +28,7 @@
#define H_ETNAVIV_ASM
#include <stdint.h>
#include <stdbool.h>
#include "hw/isa.xml.h"
/* Size of an instruction in 32-bit words */
@ -57,7 +58,7 @@ struct etna_inst_dst {
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 */
@ -70,12 +71,20 @@ struct etna_inst_tex {
/* 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 ***/
@ -84,6 +93,10 @@ struct etna_inst {
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 */
@ -99,6 +112,20 @@ static inline uint32_t inst_swiz_compose(uint32_t swz1, uint32_t swz2)
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)
@ -107,6 +134,17 @@ 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,

View File

@ -763,7 +763,7 @@ etna_native_to_dst(struct etna_native_reg native, unsigned comps)
assert(native.valid && !native.is_tex && native.rgroup == INST_RGROUP_TEMP);
struct etna_inst_dst rv = {
.comps = comps,
.write_mask = comps,
.use = 1,
.reg = native.id,
};
@ -892,7 +892,7 @@ convert_dst(struct etna_compile *c, const struct tgsi_full_dst_register *in)
{
struct etna_inst_dst rv = {
/// XXX .amode
.comps = in->Register.WriteMask,
.write_mask = in->Register.WriteMask,
};
if (in->Register.File == TGSI_FILE_ADDRESS) {