tgsi: add missing functionality to support instructions with labels
authorKeith Whitwell <keithw@vmware.com>
Wed, 19 Aug 2009 10:54:06 +0000 (11:54 +0100)
committerKeith Whitwell <keithw@vmware.com>
Wed, 19 Aug 2009 10:54:26 +0000 (11:54 +0100)
Could previously emit opcodes with label arguments, but was no way to
patch them with the actual destinations of those labels.

Adds two functions:

  ureg_get_instruction_number - to get the id of the next instruction
     to be emitted

  ureg_fixup_label - to patch an emitted label to point to a given
     instruction number.

Need some more complex examples than u_simple_shader, so far this has
only been compile-tested.

src/gallium/auxiliary/tgsi/tgsi_ureg.c
src/gallium/auxiliary/tgsi/tgsi_ureg.h

index ba84a82b2b0edc7d0730bac0551c23f73188be6f..2fa1eb4c105bd456eab65339fd708b1bc9550940 100644 (file)
@@ -103,6 +103,7 @@ struct ureg_program
 
    unsigned nr_constants;
    unsigned nr_samplers;
+   unsigned nr_instructions;
 
    struct ureg_tokens domain[2];
 };
@@ -525,7 +526,9 @@ ureg_emit_insn(struct ureg_program *ureg,
    out[0].insn.NumSrcRegs = num_src;
    out[0].insn.Padding = 0;
    out[0].insn.Extended = 0;
-
+   
+   ureg->nr_instructions++;
+   
    return ureg->domain[DOMAIN_INSN].count - 1;
 }
 
@@ -544,6 +547,31 @@ ureg_emit_label(struct ureg_program *ureg,
 
    out[0].value = 0;
    out[0].insn_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL;
+   
+   *label_token = ureg->domain[DOMAIN_INSN].count - 1;
+}
+
+/* Will return a number which can be used in a label to point to the
+ * next instruction to be emitted.
+ */
+unsigned
+ureg_get_instruction_number( struct ureg_program *ureg )
+{
+   return ureg->nr_instructions;
+}
+
+/* Patch a given label (expressed as a token number) to point to a
+ * given instruction (expressed as an instruction number).
+ */
+void
+ureg_fixup_label(struct ureg_program *ureg,
+                 unsigned label_token,
+                 unsigned instruction_number )
+{
+   union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token );
+
+   assert(out->insn_ext_label.Type == TGSI_INSTRUCTION_EXT_TYPE_LABEL);
+   out->insn_ext_label.Label = instruction_number;
 }
 
 
@@ -571,6 +599,7 @@ ureg_fixup_insn_size(struct ureg_program *ureg,
 {
    union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn );
 
+   assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
    out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1;
 }
 
index 0a976fd63b7f70166d1e9c66a7bb45f5e3ec0a75..5a48bb7a35cf678b5216feb716d234e5405ac2ca 100644 (file)
@@ -174,6 +174,33 @@ ureg_DECL_immediate1f( struct ureg_program *ureg,
    return ureg_DECL_immediate( ureg, v, 1 );
 }
 
+/***********************************************************************
+ * Functions for patching up labels
+ */
+
+
+/* Will return a number which can be used in a label to point to the
+ * next instruction to be emitted.
+ */
+unsigned
+ureg_get_instruction_number( struct ureg_program *ureg );
+
+
+/* Patch a given label (expressed as a token number) to point to a
+ * given instruction (expressed as an instruction number).
+ *
+ * Labels are obtained from instruction emitters, eg ureg_CAL().
+ * Instruction numbers are obtained from ureg_get_instruction_number(),
+ * above.
+ */
+void
+ureg_fixup_label(struct ureg_program *ureg,
+                 unsigned label_token,
+                 unsigned instruction_number );
+
+
+
+
 /***********************************************************************
  * Internal instruction helpers, don't call these directly:
  */