}
/**
- * with doubles src and dst channels aren't 1:1.
+ * with 64-bit src and dst channels aren't 1:1.
* check the src/dst types for the opcode,
- * 1. if neither is double then src == dst;
- * 2. if dest is double
+ * 1. if neither is 64-bit then src == dst;
+ * 2. if dest is 64-bit
* - don't store to y or w
- * - if src is double then src == dst.
+ * - if src is 64-bit then src == dst.
* - else for f2d, d.xy = s.x
* - else for f2d, d.zw = s.y
- * 3. if dst is single, src is double
+ * 3. if dst is single, src is 64-bit
* - map dst x,z to src xy;
* - map dst y,w to src zw;
*/
-static int get_src_chan_idx(unsigned opcode,
+static int get_src_chan_idx(enum tgsi_opcode opcode,
int dst_chan_index)
{
- enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(opcode);
- enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(opcode);
+ enum tgsi_opcode_type dtype = tgsi_opcode_infer_dst_type(opcode, 0);
+ enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(opcode, 0);
- if (dtype != TGSI_TYPE_DOUBLE && stype != TGSI_TYPE_DOUBLE)
+ if (!tgsi_type_is_64bit(dtype) && !tgsi_type_is_64bit(stype))
return dst_chan_index;
- if (dtype == TGSI_TYPE_DOUBLE) {
+ if (tgsi_type_is_64bit(dtype)) {
if (dst_chan_index == 1 || dst_chan_index == 3)
return -1;
- if (stype == TGSI_TYPE_DOUBLE)
+ if (tgsi_type_is_64bit(stype))
return dst_chan_index;
if (dst_chan_index == 0)
return 0;
struct lp_build_tgsi_context * bld_base,
const struct tgsi_full_instruction * inst)
{
- unsigned tgsi_opcode = inst->Instruction.Opcode;
- const struct tgsi_opcode_info * info = tgsi_get_opcode_info(tgsi_opcode);
+ enum tgsi_opcode opcode = inst->Instruction.Opcode;
+ const struct tgsi_opcode_info * info = tgsi_get_opcode_info(opcode);
const struct lp_build_tgsi_action * action =
- &bld_base->op_actions[tgsi_opcode];
+ &bld_base->op_actions[opcode];
struct lp_build_emit_data emit_data;
unsigned chan_index;
LLVMValueRef val;
case TGSI_OPCODE_UP2US:
case TGSI_OPCODE_UP4B:
case TGSI_OPCODE_UP4UB:
- case TGSI_OPCODE_PUSHA:
- case TGSI_OPCODE_POPA:
- case TGSI_OPCODE_SAD:
/* deprecated? */
assert(0);
return FALSE;
memset(&emit_data, 0, sizeof(emit_data));
- assert(info->num_dst <= 1);
+ assert(info->num_dst <= 2);
if (info->num_dst) {
TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
emit_data.output[chan_index] = bld_base->base.undef;
}
+
+ if (info->num_dst >= 2) {
+ TGSI_FOR_EACH_DST1_ENABLED_CHANNEL( inst, chan_index ) {
+ emit_data.output1[chan_index] = bld_base->base.undef;
+ }
+ }
}
emit_data.inst = inst;
TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan_index) {
emit_data.output[chan_index] = val;
}
+
+ if (info->num_dst >= 2) {
+ val = emit_data.output1[0];
+ memset(emit_data.output1, 0, sizeof(emit_data.output1));
+ TGSI_FOR_EACH_DST1_ENABLED_CHANNEL(inst, chan_index) {
+ emit_data.output1[chan_index] = val;
+ }
+ }
}
}
if (info->num_dst > 0 && info->opcode != TGSI_OPCODE_STORE) {
- bld_base->emit_store(bld_base, inst, info, emit_data.output);
+ bld_base->emit_store(bld_base, inst, info, 0, emit_data.output);
+ if (info->num_dst >= 2)
+ bld_base->emit_store(bld_base, inst, info, 1, emit_data.output1);
}
return TRUE;
}
LLVMValueRef
-lp_build_emit_fetch(
+lp_build_emit_fetch_src(
struct lp_build_tgsi_context *bld_base,
- const struct tgsi_full_instruction *inst,
- unsigned src_op,
+ const struct tgsi_full_src_register *reg,
+ enum tgsi_opcode_type stype,
const unsigned chan_index)
{
- const struct tgsi_full_src_register *reg = &inst->Src[src_op];
unsigned swizzle;
LLVMValueRef res;
- enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(inst->Instruction.Opcode);
if (chan_index == LP_CHAN_ALL) {
- swizzle = ~0;
+ swizzle = ~0u;
} else {
swizzle = tgsi_util_get_full_src_register_swizzle(reg, chan_index);
if (swizzle > 3) {
case TGSI_TYPE_DOUBLE:
case TGSI_TYPE_UNTYPED:
/* modifiers on movs assume data is float */
- res = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ABS, res);
+ res = lp_build_abs(&bld_base->base, res);
break;
case TGSI_TYPE_UNSIGNED:
case TGSI_TYPE_SIGNED:
+ case TGSI_TYPE_UNSIGNED64:
+ case TGSI_TYPE_SIGNED64:
case TGSI_TYPE_VOID:
default:
/* abs modifier is only legal on floating point types */
case TGSI_TYPE_UNSIGNED:
res = lp_build_negate( &bld_base->int_bld, res );
break;
+ case TGSI_TYPE_SIGNED64:
+ case TGSI_TYPE_UNSIGNED64:
+ res = lp_build_negate( &bld_base->int64_bld, res );
+ break;
case TGSI_TYPE_VOID:
default:
assert(0);
* Swizzle the argument
*/
- if (swizzle == ~0) {
+ if (swizzle == ~0u) {
res = bld_base->emit_swizzle(bld_base, res,
reg->Register.SwizzleX,
reg->Register.SwizzleY,
}
return res;
+}
+
+
+LLVMValueRef
+lp_build_emit_fetch(
+ struct lp_build_tgsi_context *bld_base,
+ const struct tgsi_full_instruction *inst,
+ unsigned src_op,
+ const unsigned chan_index)
+{
+ const struct tgsi_full_src_register *reg = &inst->Src[src_op];
+ enum tgsi_opcode_type stype =
+ tgsi_opcode_infer_src_type(inst->Instruction.Opcode, src_op);
+ return lp_build_emit_fetch_src(bld_base, reg, stype, chan_index);
}
* Swizzle the argument
*/
- if (swizzle == ~0) {
+ if (swizzle == ~0u) {
res = bld_base->emit_swizzle(bld_base, res,
off->SwizzleX,
off->SwizzleY,
while (bld_base->pc != -1) {
const struct tgsi_full_instruction *instr =
bld_base->instructions + bld_base->pc;
- const struct tgsi_opcode_info *opcode_info =
- tgsi_get_opcode_info(instr->Instruction.Opcode);
if (!lp_build_tgsi_inst_llvm(bld_base, instr)) {
_debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
- opcode_info->mnemonic);
+ tgsi_get_opcode_name(instr->Instruction.Opcode));
return FALSE;
}
}