fprintf(ctx->out, " (pad0=%x, pad3=%x, mustbe0=%x)", cat6->ldgb.pad0, cat6->ldgb.pad3, cat6->ldgb.mustbe0);
return;
+ } else if (_OPC(6, cat6->opc) == OPC_LDG && cat6->a.src1_im && cat6->a.src2_im) {
+ struct reginfo src3;
+
+ memset(&src3, 0, sizeof(src3));
+ src1.reg = (reg_t)(cat6->a.src1);
+ src2.reg = (reg_t)(cat6->a.src2);
+ src2.im = cat6->a.src2_im;
+ src3.reg = (reg_t)(cat6->a.off);
+ src3.full = true;
+ dst.reg = (reg_t)(cat6->d.dst);
+
+ print_src(ctx, &dst);
+ fprintf(ctx->out, ", g[");
+ print_src(ctx, &src1);
+ fprintf(ctx->out, "+");
+ print_src(ctx, &src3);
+ fprintf(ctx->out, "], ");
+ print_src(ctx, &src2);
+
+ return;
}
if (cat6->dst_off) {
dst.reg = (reg_t)(cat6->c.dst);
fprintf(ctx->out, "%c[", sd);
/* note: dst might actually be a src (ie. address to store to) */
print_src(ctx, &dst);
- if (dstoff)
+ if (cat6->dst_off && cat6->g) {
+ struct reginfo dstoff_reg = {};
+ dstoff_reg.reg = (reg_t) cat6->c.off;
+ dstoff_reg.full = true;
+ fprintf(ctx->out, "+");
+ print_src(ctx, &dstoff_reg);
+ } else if (dstoff) {
fprintf(ctx->out, "%+d", dstoff);
+ }
if (sd)
fprintf(ctx->out, "]");
fprintf(ctx->out, ", ");
print_src(ctx, &src1);
}
- if (src1off)
+ if (cat6->src_off && cat6->g)
+ print_src(ctx, &src2);
+ else if (src1off)
fprintf(ctx->out, "%+d", src1off);
if (ss)
fprintf(ctx->out, "]");
cat6->src_off = true;
- cat6a->src1 = reg(src1, info, instr->repeat, IR3_REG_IMMED);
- cat6a->src1_im = !!(src1->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);
+ }
/* Num components */
cat6a->src2 = reg(src2, info, instr->repeat, IR3_REG_IMMED);
cat6a->src2_im = true;
-
- /* Offset */
- iassert(src3->flags & IR3_REG_IMMED);
- cat6a->off = reg(src3, info, instr->repeat, IR3_REG_IMMED);
} else {
instr_cat6b_t *cat6b = ptr;
if (instr->cat6.dst_offset || (instr->opc == OPC_STG) ||
(instr->opc == OPC_STL) || (instr->opc == OPC_STLW)) {
instr_cat6c_t *cat6c = ptr;
+ struct ir3_register *src3 = instr->regs[4];
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) {
+ 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;