mesa: include mtypes.h less
[mesa.git] / src / mesa / program / program_parse.y
index 784ea28c17a7275d8e6ceef28cd16154ce38e68d..415ff2a28ecc3920570a488f11c3b90971d97d1a 100644 (file)
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
+
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "main/errors.h"
 #include "main/mtypes.h"
 #include "main/imports.h"
 #include "program/program.h"
@@ -43,13 +46,13 @@ static struct asm_symbol *declare_variable(struct asm_parser_state *state,
     char *name, enum asm_type t, struct YYLTYPE *locp);
 
 static int add_state_reference(struct gl_program_parameter_list *param_list,
-    const gl_state_index tokens[STATE_LENGTH]);
+    const gl_state_index16 tokens[STATE_LENGTH]);
 
 static int initialize_symbol_from_state(struct gl_program *prog,
-    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+    struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]);
 
 static int initialize_symbol_from_param(struct gl_program *prog,
-    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+    struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]);
 
 static int initialize_symbol_from_const(struct gl_program *prog,
     struct asm_symbol *param_var, const struct asm_vector *vec,
@@ -82,7 +85,7 @@ static void asm_instruction_set_operands(struct asm_instruction *inst,
     const struct prog_dst_register *dst, const struct asm_src_register *src0,
     const struct asm_src_register *src1, const struct asm_src_register *src2);
 
-static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
+static struct asm_instruction *asm_instruction_ctor(enum prog_opcode op,
     const struct prog_dst_register *dst, const struct asm_src_register *src0,
     const struct asm_src_register *src1, const struct asm_src_register *src2);
 
@@ -98,7 +101,7 @@ static struct asm_instruction *asm_instruction_copy_ctor(
 
 #define YYLLOC_DEFAULT(Current, Rhs, N)                                        \
    do {                                                                        \
-      if (YYID(N)) {                                                   \
+      if (N) {                                                 \
         (Current).first_line = YYRHSLOC(Rhs, 1).first_line;            \
         (Current).first_column = YYRHSLOC(Rhs, 1).first_column;        \
         (Current).position = YYRHSLOC(Rhs, 1).position;                \
@@ -112,16 +115,14 @@ static struct asm_instruction *asm_instruction_copy_ctor(
         (Current).position = YYRHSLOC(Rhs, 0).position                 \
            + (Current).first_column;                                   \
       }                                                                        \
-   } while(YYID(0))
-
-#define YYLEX_PARAM state->scanner
+   } while(0)
 %}
 
 %pure-parser
 %locations
+%lex-param   { struct asm_parser_state *state }
 %parse-param { struct asm_parser_state *state }
 %error-verbose
-%lex-param { void *scanner }
 
 %union {
    struct asm_instruction *inst;
@@ -136,10 +137,10 @@ static struct asm_instruction *asm_instruction_copy_ctor(
    unsigned attrib;
    int integer;
    float real;
-   gl_state_index state[STATE_LENGTH];
+   gl_state_index16 state[STATE_LENGTH];
    int negate;
    struct asm_vector vector;
-   gl_inst_opcode opcode;
+   enum prog_opcode opcode;
 
    struct {
       unsigned swz;
@@ -186,7 +187,6 @@ static struct asm_instruction *asm_instruction_copy_ctor(
 %token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
 %token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D 
 %token VERTEX VTXATTRIB
-%token WEIGHT
 
 %token <string> IDENTIFIER USED_IDENTIFIER
 %type <string> string
@@ -212,8 +212,6 @@ static struct asm_instruction *asm_instruction_copy_ctor(
 %type <sym> addrReg
 %type <swiz_mask> addrComponent addrWriteMask
 
-%type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
-
 %type <result> resultBinding resultColBinding
 %type <integer> optFaceType optColorType
 %type <integer> optResultFaceType optResultColorType
@@ -269,8 +267,16 @@ static struct asm_instruction *asm_instruction_copy_ctor(
 %type <negate> optionalSign
 
 %{
-extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
-    void *yyscanner);
+extern int
+_mesa_program_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+                        void *yyscanner);
+
+static int
+yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+      struct asm_parser_state *state)
+{
+   return _mesa_program_lexer_lex(yylval_param, yylloc_param, state->scanner);
+}
 %}
 
 %%
@@ -342,7 +348,7 @@ statement: instruction ';'
              state->inst_tail = $1;
              $1->next = NULL;
 
-             state->prog->NumInstructions++;
+              state->prog->arb.NumInstructions++;
           }
        }
        | namingStatement ';'
@@ -351,12 +357,12 @@ statement: instruction ';'
 instruction: ALU_instruction
        {
           $$ = $1;
-          state->prog->NumAluInstructions++;
+           state->prog->arb.NumAluInstructions++;
        }
        | TexInstruction
        {
           $$ = $1;
-          state->prog->NumTexInstructions++;
+           state->prog->arb.NumTexInstructions++;
        }
        ;
 
@@ -461,14 +467,6 @@ KIL_instruction: KIL swizzleSrcReg
           $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
           state->fragment.UsesKill = 1;
        }
-       | KIL ccTest
-       {
-          $$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
-          $$->Base.DstReg.CondMask = $2.CondMask;
-          $$->Base.DstReg.CondSwizzle = $2.CondSwizzle;
-          $$->Base.DstReg.CondSrc = $2.CondSrc;
-          state->fragment.UsesKill = 1;
-       }
        ;
 
 TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
@@ -555,21 +553,6 @@ scalarSrcReg: optionalSign scalarUse
              $$.Base.Negate = ~$$.Base.Negate;
           }
        }
-       | optionalSign '|' scalarUse '|'
-       {
-          $$ = $3;
-
-          if (!state->option.NV_fragment) {
-             yyerror(& @2, state, "unexpected character '|'");
-             YYERROR;
-          }
-
-          if ($1) {
-             $$.Base.Negate = ~$$.Base.Negate;
-          }
-
-          $$.Base.Abs = 1;
-       }
        ;
 
 scalarUse:  srcReg scalarSuffix
@@ -579,23 +562,6 @@ scalarUse:  srcReg scalarSuffix
           $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
                                                    $2.swizzle);
        }
-       | paramConstScalarUse
-       {
-          struct asm_symbol temp_sym;
-
-          if (!state->option.NV_fragment) {
-             yyerror(& @1, state, "expected scalar suffix");
-             YYERROR;
-          }
-
-          memset(& temp_sym, 0, sizeof(temp_sym));
-          temp_sym.param_binding_begin = ~0;
-          initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE);
-
-          set_src_reg_swz(& $$, PROGRAM_CONSTANT,
-                           temp_sym.param_binding_begin,
-                           temp_sym.param_binding_swizzle);
-       }
        ;
 
 swizzleSrcReg: optionalSign srcReg swizzleSuffix
@@ -609,33 +575,12 @@ swizzleSrcReg: optionalSign srcReg swizzleSuffix
           $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
                                                    $3.swizzle);
        }
-       | optionalSign '|' srcReg swizzleSuffix '|'
-       {
-          $$ = $3;
-
-          if (!state->option.NV_fragment) {
-             yyerror(& @2, state, "unexpected character '|'");
-             YYERROR;
-          }
-
-          if ($1) {
-             $$.Base.Negate = ~$$.Base.Negate;
-          }
-
-          $$.Base.Abs = 1;
-          $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
-                                                   $4.swizzle);
-       }
-
        ;
 
-maskedDstReg: dstReg optionalMask optionalCcMask
+maskedDstReg: dstReg optionalMask
        {
           $$ = $1;
           $$.WriteMask = $2.mask;
-          $$.CondMask = $3.CondMask;
-          $$.CondSwizzle = $3.CondSwizzle;
-          $$.CondSrc = $3.CondSrc;
 
           if ($$.File == PROGRAM_OUTPUT) {
              /* Technically speaking, this should check that it is in
@@ -643,13 +588,13 @@ maskedDstReg: dstReg optionalMask optionalCcMask
               * set in fragment program mode, so it is somewhat irrelevant.
               */
              if (state->option.PositionInvariant
-              && ($$.Index == VERT_RESULT_HPOS)) {
+              && ($$.Index == VARYING_SLOT_POS)) {
                 yyerror(& @1, state, "position-invariant programs cannot "
                         "write position");
                 YYERROR;
              }
 
-             state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
+              state->prog->info.outputs_written |= BITFIELD64_BIT($$.Index);
           }
        }
        ;
@@ -709,6 +654,7 @@ extSwizSel: INTEGER
           }
 
           $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+           $$.negate = 0;
 
           /* 0 and 1 are valid for both RGBA swizzle names and XYZW
            * swizzle names.
@@ -728,6 +674,10 @@ extSwizSel: INTEGER
           s = $1[0];
           free($1);
 
+           $$.rgba_valid = 0;
+           $$.xyzw_valid = 0;
+           $$.negate = 0;
+
           switch (s) {
           case 'x':
              $$.swz = SWIZZLE_X;
@@ -774,7 +724,7 @@ extSwizSel: INTEGER
 srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
        {
           struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $1);
+              _mesa_symbol_table_find_symbol(state->st, $1);
 
           free($1);
 
@@ -802,7 +752,7 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
              break;
           case at_attrib:
              set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
-             state->prog->InputsRead |= (1U << $$.Base.Index);
+              state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index);
 
              if (!validate_inputs(& @1, state)) {
                 YYERROR;
@@ -817,7 +767,7 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
        | attribBinding
        {
           set_src_reg(& $$, PROGRAM_INPUT, $1);
-          state->prog->InputsRead |= (1U << $$.Base.Index);
+           state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index);
 
           if (!validate_inputs(& @1, state)) {
              YYERROR;
@@ -835,7 +785,7 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
           $$.Base.File = $1->param_binding_type;
 
           if ($3.Base.RelAddr) {
-              state->prog->IndirectRegisterFiles |= (1 << $$.Base.File);
+              state->prog->arb.IndirectRegisterFiles |= (1 << $$.Base.File);
              $1->param_accessed_indirectly = 1;
 
              $$.Base.RelAddr = 1;
@@ -862,7 +812,7 @@ dstReg: resultBinding
        | USED_IDENTIFIER /* temporaryReg | vertexResultReg */
        {
           struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $1);
+              _mesa_symbol_table_find_symbol(state->st, $1);
 
           free($1);
 
@@ -891,7 +841,7 @@ dstReg: resultBinding
 progParamArray: USED_IDENTIFIER
        {
           struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $1);
+              _mesa_symbol_table_find_symbol(state->st, $1);
 
           free($1);
 
@@ -935,7 +885,7 @@ addrRegRelOffset:              { $$ = 0; }
 
 addrRegPosOffset: INTEGER
        {
-          if (($1 < 0) || ($1 > 4095)) {
+          if (($1 < 0) || ($1 > (state->limits->MaxAddressOffset - 1))) {
               char s[100];
               _mesa_snprintf(s, sizeof(s),
                              "relative address offset too large (%d)", $1);
@@ -949,7 +899,7 @@ addrRegPosOffset: INTEGER
 
 addrRegNegOffset: INTEGER
        {
-          if (($1 < 0) || ($1 > 4096)) {
+          if (($1 < 0) || ($1 > state->limits->MaxAddressOffset)) {
               char s[100];
               _mesa_snprintf(s, sizeof(s),
                              "relative address offset too large (%d)", $1);
@@ -964,7 +914,7 @@ addrRegNegOffset: INTEGER
 addrReg: USED_IDENTIFIER
        {
           struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $1);
+              _mesa_symbol_table_find_symbol(state->st, $1);
 
           free($1);
 
@@ -1016,82 +966,6 @@ optionalMask: MASK4 | MASK3 | MASK2 | MASK1
        |              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
        ;
 
-optionalCcMask: '(' ccTest ')'
-       {
-          $$ = $2;
-       }
-       | '(' ccTest2 ')'
-       {
-          $$ = $2;
-       }
-       |
-       {
-          $$.CondMask = COND_TR;
-          $$.CondSwizzle = SWIZZLE_NOOP;
-          $$.CondSrc = 0;
-       }
-       ;
-
-ccTest: ccMaskRule swizzleSuffix
-       {
-          $$ = $1;
-          $$.CondSwizzle = $2.swizzle;
-       }
-       ;
-
-ccTest2: ccMaskRule2 swizzleSuffix
-       {
-          $$ = $1;
-          $$.CondSwizzle = $2.swizzle;
-       }
-       ;
-
-ccMaskRule: IDENTIFIER
-       {
-          const int cond = _mesa_parse_cc($1);
-          if ((cond == 0) || ($1[2] != '\0')) {
-             char *const err_str =
-                make_error_string("invalid condition code \"%s\"", $1);
-
-             yyerror(& @1, state, (err_str != NULL)
-                     ? err_str : "invalid condition code");
-
-             if (err_str != NULL) {
-                free(err_str);
-             }
-
-             YYERROR;
-          }
-
-          $$.CondMask = cond;
-          $$.CondSwizzle = SWIZZLE_NOOP;
-          $$.CondSrc = 0;
-       }
-       ;
-
-ccMaskRule2: USED_IDENTIFIER
-       {
-          const int cond = _mesa_parse_cc($1);
-          if ((cond == 0) || ($1[2] != '\0')) {
-             char *const err_str =
-                make_error_string("invalid condition code \"%s\"", $1);
-
-             yyerror(& @1, state, (err_str != NULL)
-                     ? err_str : "invalid condition code");
-
-             if (err_str != NULL) {
-                free(err_str);
-             }
-
-             YYERROR;
-          }
-
-          $$.CondMask = cond;
-          $$.CondSwizzle = SWIZZLE_NOOP;
-          $$.CondSrc = 0;
-       }
-       ;
-
 namingStatement: ATTRIB_statement
        | PARAM_statement
        | TEMP_statement
@@ -1110,7 +984,7 @@ ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
              YYERROR;
           } else {
              s->attrib_binding = $4;
-             state->InputsBound |= (1U << s->attrib_binding);
+             state->InputsBound |= BITFIELD64_BIT(s->attrib_binding);
 
              if (!validate_inputs(& @4, state)) {
                 YYERROR;
@@ -1133,30 +1007,16 @@ vtxAttribItem: POSITION
        {
           $$ = VERT_ATTRIB_POS;
        }
-       | WEIGHT vtxOptWeightNum
-       {
-          $$ = VERT_ATTRIB_WEIGHT;
-       }
        | NORMAL
        {
           $$ = VERT_ATTRIB_NORMAL;
        }
        | COLOR optColorType
        {
-          if (!state->ctx->Extensions.EXT_secondary_color) {
-             yyerror(& @2, state, "GL_EXT_secondary_color not supported");
-             YYERROR;
-          }
-
           $$ = VERT_ATTRIB_COLOR0 + $2;
        }
        | FOGCOORD
        {
-          if (!state->ctx->Extensions.EXT_fog_coord) {
-             yyerror(& @1, state, "GL_EXT_fog_coord not supported");
-             YYERROR;
-          }
-
           $$ = VERT_ATTRIB_FOG;
        }
        | TEXCOORD optTexCoordUnitNum
@@ -1185,24 +1045,23 @@ vtxAttribNum: INTEGER
        }
        ;
 
-vtxOptWeightNum:  | '[' vtxWeightNum ']';
 vtxWeightNum: INTEGER;
 
 fragAttribItem: POSITION
        {
-          $$ = FRAG_ATTRIB_WPOS;
+          $$ = VARYING_SLOT_POS;
        }
        | COLOR optColorType
        {
-          $$ = FRAG_ATTRIB_COL0 + $2;
+          $$ = VARYING_SLOT_COL0 + $2;
        }
        | FOGCOORD
        {
-          $$ = FRAG_ATTRIB_FOGC;
+          $$ = VARYING_SLOT_FOGC;
        }
        | TEXCOORD optTexCoordUnitNum
        {
-          $$ = FRAG_ATTRIB_TEX0 + $2;
+          $$ = VARYING_SLOT_TEX0 + $2;
        }
        ;
 
@@ -1258,7 +1117,11 @@ optArraySize:
        | INTEGER
         {
           if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
-             yyerror(& @1, state, "invalid parameter array size");
+              char msg[100];
+              _mesa_snprintf(msg, sizeof(msg),
+                             "invalid parameter array size (size=%d max=%u)",
+                             $1, state->limits->MaxParameters);
+             yyerror(& @1, state, msg);
              YYERROR;
           } else {
              $$ = $1;
@@ -1850,64 +1713,64 @@ paramConstUse: paramConstScalarUse | paramConstVector;
 paramConstScalarDecl: signedFloatConstant
        {
           $$.count = 4;
-          $$.data[0] = $1;
-          $$.data[1] = $1;
-          $$.data[2] = $1;
-          $$.data[3] = $1;
+          $$.data[0].f = $1;
+          $$.data[1].f = $1;
+          $$.data[2].f = $1;
+          $$.data[3].f = $1;
        }
        ;
 
 paramConstScalarUse: REAL
        {
           $$.count = 1;
-          $$.data[0] = $1;
-          $$.data[1] = $1;
-          $$.data[2] = $1;
-          $$.data[3] = $1;
+          $$.data[0].f = $1;
+          $$.data[1].f = $1;
+          $$.data[2].f = $1;
+          $$.data[3].f = $1;
        }
        | INTEGER
        {
           $$.count = 1;
-          $$.data[0] = (float) $1;
-          $$.data[1] = (float) $1;
-          $$.data[2] = (float) $1;
-          $$.data[3] = (float) $1;
+          $$.data[0].f = (float) $1;
+          $$.data[1].f = (float) $1;
+          $$.data[2].f = (float) $1;
+          $$.data[3].f = (float) $1;
        }
        ;
 
 paramConstVector: '{' signedFloatConstant '}'
        {
           $$.count = 4;
-          $$.data[0] = $2;
-          $$.data[1] = 0.0f;
-          $$.data[2] = 0.0f;
-          $$.data[3] = 1.0f;
+          $$.data[0].f = $2;
+          $$.data[1].f = 0.0f;
+          $$.data[2].f = 0.0f;
+          $$.data[3].f = 1.0f;
        }
        | '{' signedFloatConstant ',' signedFloatConstant '}'
        {
           $$.count = 4;
-          $$.data[0] = $2;
-          $$.data[1] = $4;
-          $$.data[2] = 0.0f;
-          $$.data[3] = 1.0f;
+          $$.data[0].f = $2;
+          $$.data[1].f = $4;
+          $$.data[2].f = 0.0f;
+          $$.data[3].f = 1.0f;
        }
        | '{' signedFloatConstant ',' signedFloatConstant ','
               signedFloatConstant '}'
        {
           $$.count = 4;
-          $$.data[0] = $2;
-          $$.data[1] = $4;
-          $$.data[2] = $6;
-          $$.data[3] = 1.0f;
+          $$.data[0].f = $2;
+          $$.data[1].f = $4;
+          $$.data[2].f = $6;
+          $$.data[3].f = 1.0f;
        }
        | '{' signedFloatConstant ',' signedFloatConstant ','
               signedFloatConstant ',' signedFloatConstant '}'
        {
           $$.count = 4;
-          $$.data[0] = $2;
-          $$.data[1] = $4;
-          $$.data[2] = $6;
-          $$.data[3] = $8;
+          $$.data[0].f = $2;
+          $$.data[1].f = $4;
+          $$.data[2].f = $6;
+          $$.data[3].f = $8;
        }
        ;
 
@@ -1926,46 +1789,7 @@ optionalSign: '+'        { $$ = FALSE; }
        |                { $$ = FALSE; }
        ;
 
-TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList
-       ;
-
-optVarSize: string
-       {
-          /* NV_fragment_program_option defines the size qualifiers in a
-           * fairly broken way.  "SHORT" or "LONG" can optionally be used
-           * before TEMP or OUTPUT.  However, neither is a reserved word!
-           * This means that we have to parse it as an identifier, then check
-           * to make sure it's one of the valid values.  *sigh*
-           *
-           * In addition, the grammar in the extension spec does *not* allow
-           * the size specifier to be optional, but all known implementations
-           * do.
-           */
-          if (!state->option.NV_fragment) {
-             yyerror(& @1, state, "unexpected IDENTIFIER");
-             YYERROR;
-          }
-
-          if (strcmp("SHORT", $1) == 0) {
-          } else if (strcmp("LONG", $1) == 0) {
-          } else {
-             char *const err_str =
-                make_error_string("invalid storage size specifier \"%s\"",
-                                  $1);
-
-             yyerror(& @1, state, (err_str != NULL)
-                     ? err_str : "invalid storage size specifier");
-
-             if (err_str != NULL) {
-                free(err_str);
-             }
-
-             YYERROR;
-          }
-       }
-       |
-       {
-       }
+TEMP_statement: TEMP { $<integer>$ = $1; } varNameList
        ;
 
 ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
@@ -1987,16 +1811,16 @@ varNameList: varNameList ',' IDENTIFIER
        }
        ;
 
-OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
+OUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding
        {
           struct asm_symbol *const s =
-             declare_variable(state, $3, at_output, & @3);
+             declare_variable(state, $2, at_output, & @2);
 
           if (s == NULL) {
-             free($3);
+             free($2);
              YYERROR;
           } else {
-             s->output_binding = $5;
+             s->output_binding = $4;
           }
        }
        ;
@@ -2004,7 +1828,7 @@ OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
 resultBinding: RESULT POSITION
        {
           if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_HPOS;
+             $$ = VARYING_SLOT_POS;
           } else {
              yyerror(& @2, state, "invalid program result name");
              YYERROR;
@@ -2013,7 +1837,7 @@ resultBinding: RESULT POSITION
        | RESULT FOGCOORD
        {
           if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_FOGC;
+             $$ = VARYING_SLOT_FOGC;
           } else {
              yyerror(& @2, state, "invalid program result name");
              YYERROR;
@@ -2026,7 +1850,7 @@ resultBinding: RESULT POSITION
        | RESULT POINTSIZE
        {
           if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_PSIZ;
+             $$ = VARYING_SLOT_PSIZ;
           } else {
              yyerror(& @2, state, "invalid program result name");
              YYERROR;
@@ -2035,7 +1859,7 @@ resultBinding: RESULT POSITION
        | RESULT TEXCOORD optTexCoordUnitNum
        {
           if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_TEX0 + $3;
+             $$ = VARYING_SLOT_TEX0 + $3;
           } else {
              yyerror(& @2, state, "invalid program result name");
              YYERROR;
@@ -2060,14 +1884,47 @@ resultColBinding: COLOR optResultFaceType optResultColorType
 
 optResultFaceType:
        {
-          $$ = (state->mode == ARB_vertex)
-             ? VERT_RESULT_COL0
-             : FRAG_RESULT_COLOR;
+          if (state->mode == ARB_vertex) {
+             $$ = VARYING_SLOT_COL0;
+          } else {
+             if (state->option.DrawBuffers)
+                $$ = FRAG_RESULT_DATA0;
+             else
+                $$ = FRAG_RESULT_COLOR;
+          }
+       }
+       | '[' INTEGER ']'
+       {
+          if (state->mode == ARB_vertex) {
+             yyerror(& @1, state, "invalid program result name");
+             YYERROR;
+          } else {
+             if (!state->option.DrawBuffers) {
+                /* From the ARB_draw_buffers spec (same text exists
+                 * for ATI_draw_buffers):
+                 *
+                 *     If this option is not specified, a fragment
+                 *     program that attempts to bind
+                 *     "result.color[n]" will fail to load, and only
+                 *     "result.color" will be allowed.
+                 */
+                yyerror(& @1, state,
+                        "result.color[] used without "
+                        "`OPTION ARB_draw_buffers' or "
+                        "`OPTION ATI_draw_buffers'");
+                YYERROR;
+             } else if ($2 >= state->MaxDrawBuffers) {
+                yyerror(& @1, state,
+                        "result.color[] exceeds MAX_DRAW_BUFFERS_ARB");
+                YYERROR;
+             }
+             $$ = FRAG_RESULT_DATA0 + $2;
+          }
        }
        | FRONT
        {
           if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_COL0;
+             $$ = VARYING_SLOT_COL0;
           } else {
              yyerror(& @1, state, "invalid program result name");
              YYERROR;
@@ -2076,7 +1933,7 @@ optResultFaceType:
        | BACK
        {
           if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_BFC0;
+             $$ = VARYING_SLOT_BFC0;
           } else {
              yyerror(& @1, state, "invalid program result name");
              YYERROR;
@@ -2166,9 +2023,9 @@ legacyTexUnitNum: INTEGER
 ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
        {
           struct asm_symbol *exist = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $2);
+              _mesa_symbol_table_find_symbol(state->st, $2);
           struct asm_symbol *target = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $4);
+              _mesa_symbol_table_find_symbol(state->st, $4);
 
           free($4);
 
@@ -2184,7 +2041,7 @@ ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
                      "undefined variable binding in ALIAS statement");
              YYERROR;
           } else {
-             _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
+              _mesa_symbol_table_add_symbol(state->st, $2, target);
           }
        }
        ;
@@ -2211,9 +2068,6 @@ asm_instruction_set_operands(struct asm_instruction *inst,
       inst->Base.DstReg = *dst;
    }
 
-   /* The only instruction that doesn't have any source registers is the
-    * condition-code based KIL instruction added by NV_fragment_program_option.
-    */
    if (src0 != NULL) {
       inst->Base.SrcReg[0] = src0->Base;
       inst->SrcReg[0] = *src0;
@@ -2238,7 +2092,7 @@ asm_instruction_set_operands(struct asm_instruction *inst,
 
 
 struct asm_instruction *
-asm_instruction_ctor(gl_inst_opcode op,
+asm_instruction_ctor(enum prog_opcode op,
                     const struct prog_dst_register *dst,
                     const struct asm_src_register *src0,
                     const struct asm_src_register *src1,
@@ -2269,10 +2123,7 @@ asm_instruction_copy_ctor(const struct prog_instruction *base,
    if (inst) {
       _mesa_init_instructions(& inst->Base, 1);
       inst->Base.Opcode = base->Opcode;
-      inst->Base.CondUpdate = base->CondUpdate;
-      inst->Base.CondDst = base->CondDst;
-      inst->Base.SaturateMode = base->SaturateMode;
-      inst->Base.Precision = base->Precision;
+      inst->Base.Saturate = base->Saturate;
 
       asm_instruction_set_operands(inst, dst, src0, src1, src2);
    }
@@ -2287,8 +2138,6 @@ init_dst_reg(struct prog_dst_register *r)
    memset(r, 0, sizeof(*r));
    r->File = PROGRAM_UNDEFINED;
    r->WriteMask = WRITEMASK_XYZW;
-   r->CondMask = COND_TR;
-   r->CondSwizzle = SWIZZLE_NOOP;
 }
 
 
@@ -2298,19 +2147,17 @@ set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
 {
    const GLint maxIndex = 1 << INST_INDEX_BITS;
    const GLint minIndex = 0;
-   ASSERT(index >= minIndex);
+   assert(index >= minIndex);
    (void) minIndex;
-   ASSERT(index <= maxIndex);
+   assert(index <= maxIndex);
    (void) maxIndex;
-   ASSERT(file == PROGRAM_TEMPORARY ||
+   assert(file == PROGRAM_TEMPORARY ||
          file == PROGRAM_ADDRESS ||
          file == PROGRAM_OUTPUT);
    memset(r, 0, sizeof(*r));
    r->File = file;
    r->Index = index;
    r->WriteMask = WRITEMASK_XYZW;
-   r->CondMask = COND_TR;
-   r->CondSwizzle = SWIZZLE_NOOP;
 }
 
 
@@ -2340,10 +2187,10 @@ set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
 {
    const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
    const GLint minIndex = -(1 << INST_INDEX_BITS);
-   ASSERT(file < PROGRAM_FILE_MAX);
-   ASSERT(index >= minIndex);
+   assert(file < PROGRAM_FILE_MAX);
+   assert(index >= minIndex);
    (void) minIndex;
-   ASSERT(index <= maxIndex);
+   assert(index <= maxIndex);
    (void) maxIndex;
    memset(r, 0, sizeof(*r));
    r->Base.File = file;
@@ -2366,9 +2213,30 @@ set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
 int
 validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
 {
-   const int inputs = state->prog->InputsRead | state->InputsBound;
+   const GLbitfield64 inputs = state->prog->info.inputs_read | state->InputsBound;
+   GLbitfield ff_inputs = 0;
 
-   if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) {
+   /* Since Mesa internal attribute indices are different from
+    * how NV_vertex_program defines attribute aliasing, we have to construct
+    * a separate usage mask based on how the aliasing is defined.
+    *
+    * Note that attribute aliasing is optional if NV_vertex_program is
+    * unsupported.
+    */
+   if (inputs & VERT_BIT_POS)
+      ff_inputs |= 1 << 0;
+   if (inputs & VERT_BIT_NORMAL)
+      ff_inputs |= 1 << 2;
+   if (inputs & VERT_BIT_COLOR0)
+      ff_inputs |= 1 << 3;
+   if (inputs & VERT_BIT_COLOR1)
+      ff_inputs |= 1 << 4;
+   if (inputs & VERT_BIT_FOG)
+      ff_inputs |= 1 << 5;
+
+   ff_inputs |= ((inputs & VERT_BIT_TEX_ALL) >> VERT_ATTRIB_TEX0) << 8;
+
+   if ((ff_inputs & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) {
       yyerror(locp, state, "illegal use of generic attribute and name attribute");
       return 0;
    }
@@ -2383,7 +2251,7 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
 {
    struct asm_symbol *s = NULL;
    struct asm_symbol *exist = (struct asm_symbol *)
-      _mesa_symbol_table_find_symbol(state->st, 0, name);
+      _mesa_symbol_table_find_symbol(state->st, name);
 
 
    if (exist != NULL) {
@@ -2395,18 +2263,19 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
 
       switch (t) {
       case at_temp:
-        if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
+         if (state->prog->arb.NumTemporaries >= state->limits->MaxTemps) {
            yyerror(locp, state, "too many temporaries declared");
            free(s);
            return NULL;
         }
 
-        s->temp_binding = state->prog->NumTemporaries;
-        state->prog->NumTemporaries++;
+         s->temp_binding = state->prog->arb.NumTemporaries;
+         state->prog->arb.NumTemporaries++;
         break;
 
       case at_address:
-        if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
+         if (state->prog->arb.NumAddressRegs >=
+             state->limits->MaxAddressRegs) {
            yyerror(locp, state, "too many address registers declared");
            free(s);
            return NULL;
@@ -2414,14 +2283,14 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
 
         /* FINISHME: Add support for multiple address registers.
          */
-        state->prog->NumAddressRegs++;
+         state->prog->arb.NumAddressRegs++;
         break;
 
       default:
         break;
       }
 
-      _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+      _mesa_symbol_table_add_symbol(state->st, s->name, s);
       s->next = state->sym;
       state->sym = s;
    }
@@ -2431,7 +2300,7 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
 
 
 int add_state_reference(struct gl_program_parameter_list *param_list,
-                       const gl_state_index tokens[STATE_LENGTH])
+                       const gl_state_index16 tokens[STATE_LENGTH])
 {
    const GLuint size = 4; /* XXX fix */
    char *name;
@@ -2439,7 +2308,7 @@ int add_state_reference(struct gl_program_parameter_list *param_list,
 
    name = _mesa_program_state_string(tokens);
    index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
-                               size, GL_NONE, NULL, tokens, 0x0);
+                               size, GL_NONE, NULL, tokens, true);
    param_list->StateFlags |= _mesa_program_state_flags(tokens);
 
    /* free name string here since we duplicated it in add_parameter() */
@@ -2452,10 +2321,10 @@ int add_state_reference(struct gl_program_parameter_list *param_list,
 int
 initialize_symbol_from_state(struct gl_program *prog,
                             struct asm_symbol *param_var, 
-                            const gl_state_index tokens[STATE_LENGTH])
+                            const gl_state_index16 tokens[STATE_LENGTH])
 {
    int idx = -1;
-   gl_state_index state_tokens[STATE_LENGTH];
+   gl_state_index16 state_tokens[STATE_LENGTH];
 
 
    memcpy(state_tokens, tokens, sizeof(state_tokens));
@@ -2504,10 +2373,10 @@ initialize_symbol_from_state(struct gl_program *prog,
 int
 initialize_symbol_from_param(struct gl_program *prog,
                             struct asm_symbol *param_var, 
-                            const gl_state_index tokens[STATE_LENGTH])
+                            const gl_state_index16 tokens[STATE_LENGTH])
 {
    int idx = -1;
-   gl_state_index state_tokens[STATE_LENGTH];
+   gl_state_index16 state_tokens[STATE_LENGTH];
 
 
    memcpy(state_tokens, tokens, sizeof(state_tokens));
@@ -2659,7 +2528,7 @@ _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *st
 
    /* Make a copy of the program string and force it to be NUL-terminated.
     */
-   strz = (GLubyte *) malloc(len + 1);
+   strz = (GLubyte *) ralloc_size(state->mem_ctx, len + 1);
    if (strz == NULL) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
       return GL_FALSE;
@@ -2672,15 +2541,16 @@ _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *st
    state->st = _mesa_symbol_table_ctor();
 
    state->limits = (target == GL_VERTEX_PROGRAM_ARB)
-      ? & ctx->Const.VertexProgram
-      : & ctx->Const.FragmentProgram;
+      ? & ctx->Const.Program[MESA_SHADER_VERTEX]
+      : & ctx->Const.Program[MESA_SHADER_FRAGMENT];
 
-   state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
+   state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
    state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
    state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
    state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
    state->MaxLights = ctx->Const.MaxLights;
    state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
+   state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
 
    state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
       ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
@@ -2711,36 +2581,43 @@ _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *st
    
    /* Add one instruction to store the "END" instruction.
     */
-   state->prog->Instructions =
-      _mesa_alloc_instructions(state->prog->NumInstructions + 1);
+   state->prog->arb.Instructions =
+      rzalloc_array(state->mem_ctx, struct prog_instruction,
+                    state->prog->arb.NumInstructions + 1);
+
+   if (state->prog->arb.Instructions == NULL) {
+      goto error;
+   }
+
    inst = state->inst_head;
-   for (i = 0; i < state->prog->NumInstructions; i++) {
+   for (i = 0; i < state->prog->arb.NumInstructions; i++) {
       struct asm_instruction *const temp = inst->next;
 
-      state->prog->Instructions[i] = inst->Base;
+      state->prog->arb.Instructions[i] = inst->Base;
       inst = temp;
    }
 
    /* Finally, tag on an OPCODE_END instruction */
    {
-      const GLuint numInst = state->prog->NumInstructions;
-      _mesa_init_instructions(state->prog->Instructions + numInst, 1);
-      state->prog->Instructions[numInst].Opcode = OPCODE_END;
+      const GLuint numInst = state->prog->arb.NumInstructions;
+      _mesa_init_instructions(state->prog->arb.Instructions + numInst, 1);
+      state->prog->arb.Instructions[numInst].Opcode = OPCODE_END;
    }
-   state->prog->NumInstructions++;
+   state->prog->arb.NumInstructions++;
 
-   state->prog->NumParameters = state->prog->Parameters->NumParameters;
-   state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead);
+   state->prog->arb.NumParameters = state->prog->Parameters->NumParameters;
+   state->prog->arb.NumAttributes =
+      _mesa_bitcount_64(state->prog->info.inputs_read);
 
    /*
     * Initialize native counts to logical counts.  The device driver may
     * change them if program is translated into a hardware program.
     */
-   state->prog->NumNativeInstructions = state->prog->NumInstructions;
-   state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
-   state->prog->NumNativeParameters = state->prog->NumParameters;
-   state->prog->NumNativeAttributes = state->prog->NumAttributes;
-   state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
+   state->prog->arb.NumNativeInstructions = state->prog->arb.NumInstructions;
+   state->prog->arb.NumNativeTemporaries = state->prog->arb.NumTemporaries;
+   state->prog->arb.NumNativeParameters = state->prog->arb.NumParameters;
+   state->prog->arb.NumNativeAttributes = state->prog->arb.NumAttributes;
+   state->prog->arb.NumNativeAddressRegs = state->prog->arb.NumAddressRegs;
 
    result = GL_TRUE;