예제 #1
0
static boolean
iter_instruction(
   struct tgsi_iterate_context *iter,
   struct tgsi_full_instruction *inst )
{
   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
   const struct tgsi_opcode_info *info;
   uint i;

   if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
      if (ctx->index_of_END != ~0) {
         report_error( ctx, "Too many END instructions" );
      }
      ctx->index_of_END = ctx->num_instructions;
   }

   info = tgsi_get_opcode_info( inst->Instruction.Opcode );
   if (info == NULL) {
      report_error( ctx, "(%u): Invalid instruction opcode", inst->Instruction.Opcode );
      return TRUE;
   }

   if (info->num_dst != inst->Instruction.NumDstRegs) {
      report_error( ctx, "Invalid number of destination operands, should be %u", info->num_dst );
   }
   if (info->num_src != inst->Instruction.NumSrcRegs) {
      report_error( ctx, "Invalid number of source operands, should be %u", info->num_src );
   }

   /* Check destination and source registers' validity.
    * Mark the registers as used.
    */
   for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
      check_register_usage(
         ctx,
         inst->FullDstRegisters[i].DstRegister.File,
         inst->FullDstRegisters[i].DstRegister.Index,
         "destination",
         FALSE );
   }
   for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
      check_register_usage(
         ctx,
         inst->FullSrcRegisters[i].SrcRegister.File,
         inst->FullSrcRegisters[i].SrcRegister.Index,
         "source",
         (boolean)inst->FullSrcRegisters[i].SrcRegister.Indirect );
      if (inst->FullSrcRegisters[i].SrcRegister.Indirect) {
         uint file;
         int index;

         file = inst->FullSrcRegisters[i].SrcRegisterInd.File;
         index = inst->FullSrcRegisters[i].SrcRegisterInd.Index;
         check_register_usage(
            ctx,
            file,
            index,
            "indirect",
            FALSE );
         if (file != TGSI_FILE_ADDRESS || index != 0)
            report_warning( ctx, "Indirect register not ADDR[0]" );
      }
   }

   ctx->num_instructions++;

   return TRUE;
}
예제 #2
0
static boolean
iter_instruction(
   struct tgsi_iterate_context *iter,
   struct tgsi_full_instruction *inst )
{
   struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
   const struct tgsi_opcode_info *info;
   uint i;

   if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
      if (ctx->index_of_END != ~0) {
         report_error( ctx, "Too many END instructions" );
      }
      ctx->index_of_END = ctx->num_instructions;
   }

   info = tgsi_get_opcode_info( inst->Instruction.Opcode );
   if (!info) {
      report_error( ctx, "(%u): Invalid instruction opcode", inst->Instruction.Opcode );
      return TRUE;
   }

   if (info->num_dst != inst->Instruction.NumDstRegs) {
      report_error( ctx, "%s: Invalid number of destination operands, should be %u", info->mnemonic, info->num_dst );
   }
   if (info->num_src != inst->Instruction.NumSrcRegs) {
      report_error( ctx, "%s: Invalid number of source operands, should be %u", info->mnemonic, info->num_src );
   }

   /* Check destination and source registers' validity.
    * Mark the registers as used.
    */
   for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
      scan_register *reg = create_scan_register_dst(&inst->Dst[i]);
      check_register_usage(
         ctx,
         reg,
         "destination",
         FALSE );
      if (!inst->Dst[i].Register.WriteMask) {
         report_error(ctx, "Destination register has empty writemask");
      }
   }
   for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
      scan_register *reg = create_scan_register_src(&inst->Src[i]);
      check_register_usage(
         ctx,
         reg,
         "source",
         (boolean)inst->Src[i].Register.Indirect );
      if (inst->Src[i].Register.Indirect) {
         scan_register *ind_reg = MALLOC(sizeof(scan_register));

         fill_scan_register1d(ind_reg,
                              inst->Src[i].Indirect.File,
                              inst->Src[i].Indirect.Index);
         check_register_usage(
            ctx,
            ind_reg,
            "indirect",
            FALSE );
      }
   }

   ctx->num_instructions++;

   return TRUE;
}