cat0->sync = !!(instr->flags & IR3_INSTR_SY);
cat0->opc_cat = 0;
+ if (instr->opc == OPC_CONDEND || instr->opc == OPC_ENDPATCH)
+ cat0->dummy4 = 16;
+
return 0;
}
} else if (src1->flags & IR3_REG_CONST) {
iassert(src1->num < (1 << 12));
cat2->c1.src1 = reg(src1, info, instr->repeat,
- IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF);
+ IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF |
+ absneg);
cat2->c1.src1_c = 1;
} else {
iassert(src1->num < (1 << 11));
} else if (src2->flags & IR3_REG_CONST) {
iassert(src2->num < (1 << 12));
cat2->c2.src2 = reg(src2, info, instr->repeat,
- IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF);
+ IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF |
+ absneg);
cat2->c2.src2_c = 1;
} else {
iassert(src2->num < (1 << 11));
} else if (src1->flags & IR3_REG_CONST) {
iassert(src1->num < (1 << 12));
cat3->c1.src1 = reg(src1, info, instr->repeat,
- IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF);
+ IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF | absneg);
cat3->c1.src1_c = 1;
} else {
iassert(src1->num < (1 << 11));
} else if (src3->flags & IR3_REG_CONST) {
iassert(src3->num < (1 << 12));
cat3->c2.src3 = reg(src3, info, instr->repeat,
- IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF);
+ IR3_REG_CONST | IR3_REG_R | IR3_REG_HALF | absneg);
cat3->c2.src3_c = 1;
} else {
iassert(src3->num < (1 << 11));
return 0;
} else if (instr->cat6.src_offset || (instr->opc == OPC_LDG) ||
- (instr->opc == OPC_LDL)) {
+ (instr->opc == OPC_LDL) || (instr->opc == OPC_LDLW)) {
+ struct ir3_register *src3 = instr->regs[3];
instr_cat6a_t *cat6a = ptr;
cat6->src_off = true;
- cat6a->src1 = reg(src1, info, instr->repeat, IR3_REG_IMMED);
- cat6a->src1_im = !!(src1->flags & IR3_REG_IMMED);
- if (src2) {
- cat6a->src2 = reg(src2, info, instr->repeat, IR3_REG_IMMED);
- cat6a->src2_im = !!(src2->flags & IR3_REG_IMMED);
+ if (instr->opc == OPC_LDG) {
+ /* For LDG src1 can not be immediate, so src1_imm is redundant and
+ * instead used to signal whether (when true) 'off' is a 32 bit
+ * register or an immediate offset.
+ */
+ cat6a->src1 = reg(src1, info, instr->repeat, 0);
+ cat6a->src1_im = !(src3->flags & IR3_REG_IMMED);
+ cat6a->off = reg(src3, info, instr->repeat, IR3_REG_IMMED);
+ } else {
+ cat6a->src1 = reg(src1, info, instr->repeat, IR3_REG_IMMED);
+ cat6a->src1_im = !!(src1->flags & IR3_REG_IMMED);
+ cat6a->off = reg(src3, info, instr->repeat, IR3_REG_IMMED);
+ iassert(src3->flags & IR3_REG_IMMED);
}
- cat6a->off = instr->cat6.src_offset;
+
+ /* Num components */
+ cat6a->src2 = reg(src2, info, instr->repeat, IR3_REG_IMMED);
+ cat6a->src2_im = true;
} else {
instr_cat6b_t *cat6b = ptr;
}
if (instr->cat6.dst_offset || (instr->opc == OPC_STG) ||
- (instr->opc == OPC_STL)) {
+ (instr->opc == OPC_STL) || (instr->opc == OPC_STLW)) {
instr_cat6c_t *cat6c = ptr;
cat6->dst_off = true;
cat6c->dst = reg(dst, info, instr->repeat, IR3_REG_R | IR3_REG_HALF);
- cat6c->off = instr->cat6.dst_offset;
+
+ if (instr->flags & IR3_INSTR_G) {
+ struct ir3_register *src3 = instr->regs[4];
+ cat6c->off = reg(src3, info, instr->repeat, IR3_REG_R | IR3_REG_HALF);
+ if (src3->flags & IR3_REG_IMMED) {
+ /* Immediate offsets are in bytes... */
+ cat6->g = false;
+ cat6c->off *= 4;
+ }
+ } else {
+ cat6c->off = instr->cat6.dst_offset;
+ }
} else {
instr_cat6d_t *cat6d = ptr;
cat6->dst_off = false;
if (ret)
goto fail;
info->instrs_count += 1 + instr->repeat + instr->nop;
+ info->nops_count += instr->nop;
+ if (instr->opc == OPC_NOP)
+ info->nops_count += 1 + instr->repeat;
dwords += 2;
if (instr->flags & IR3_INSTR_SS)
{
unsigned cnt = 0;
list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+ block->start_ip = cnt;
+ block->end_ip = cnt;
list_for_each_entry (struct ir3_instruction, instr, &block->instr_list, node) {
instr->ip = cnt++;
+ block->end_ip = instr->ip;
}
- block->start_ip = list_first_entry(&block->instr_list, struct ir3_instruction, node)->ip;
- block->end_ip = list_last_entry(&block->instr_list, struct ir3_instruction, node)->ip;
}
return cnt;
}