14a49301eSmrg/**************************************************************************
24a49301eSmrg *
34a49301eSmrg * Copyright 2009 VMware, Inc.
44a49301eSmrg * All Rights Reserved.
54a49301eSmrg *
64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a
74a49301eSmrg * copy of this software and associated documentation files (the
84a49301eSmrg * "Software"), to deal in the Software without restriction, including
94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish,
104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to
114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to
124a49301eSmrg * the following conditions:
134a49301eSmrg *
144a49301eSmrg * The above copyright notice and this permission notice (including the
154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions
164a49301eSmrg * of the Software.
174a49301eSmrg *
184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
214a49301eSmrg * IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR
224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
254a49301eSmrg *
264a49301eSmrg **************************************************************************/
274a49301eSmrg
284a49301eSmrg#ifndef TGSI_UREG_H
294a49301eSmrg#define TGSI_UREG_H
304a49301eSmrg
317ec681f3Smrg#include "pipe/p_defines.h"
3201e04c3fSmrg#include "pipe/p_format.h"
334a49301eSmrg#include "pipe/p_compiler.h"
344a49301eSmrg#include "pipe/p_shader_tokens.h"
35cdc920a0Smrg#include "util/u_debug.h"
364a49301eSmrg
374a49301eSmrg#ifdef __cplusplus
384a49301eSmrgextern "C" {
394a49301eSmrg#endif
404a49301eSmrg
4101e04c3fSmrgstruct pipe_screen;
424a49301eSmrgstruct ureg_program;
43af69d88dSmrgstruct pipe_stream_output_info;
447ec681f3Smrgstruct shader_info;
454a49301eSmrg
464a49301eSmrg/* Almost a tgsi_src_register, but we need to pull in the Absolute
474a49301eSmrg * flag from the _ext token.  Indirect flag always implies ADDR[0].
484a49301eSmrg */
494a49301eSmrgstruct ureg_src
504a49301eSmrg{
513464ebd5Sriastradh   unsigned File             : 4;  /* TGSI_FILE_ */
523464ebd5Sriastradh   unsigned SwizzleX         : 2;  /* TGSI_SWIZZLE_ */
533464ebd5Sriastradh   unsigned SwizzleY         : 2;  /* TGSI_SWIZZLE_ */
543464ebd5Sriastradh   unsigned SwizzleZ         : 2;  /* TGSI_SWIZZLE_ */
553464ebd5Sriastradh   unsigned SwizzleW         : 2;  /* TGSI_SWIZZLE_ */
563464ebd5Sriastradh   unsigned Indirect         : 1;  /* BOOL */
573464ebd5Sriastradh   unsigned DimIndirect      : 1;  /* BOOL */
583464ebd5Sriastradh   unsigned Dimension        : 1;  /* BOOL */
593464ebd5Sriastradh   unsigned Absolute         : 1;  /* BOOL */
603464ebd5Sriastradh   unsigned Negate           : 1;  /* BOOL */
613464ebd5Sriastradh   unsigned IndirectFile     : 4;  /* TGSI_FILE_ */
623464ebd5Sriastradh   unsigned IndirectSwizzle  : 2;  /* TGSI_SWIZZLE_ */
633464ebd5Sriastradh   unsigned DimIndFile       : 4;  /* TGSI_FILE_ */
643464ebd5Sriastradh   unsigned DimIndSwizzle    : 2;  /* TGSI_SWIZZLE_ */
653464ebd5Sriastradh   int      Index            : 16; /* SINT */
663464ebd5Sriastradh   int      IndirectIndex    : 16; /* SINT */
673464ebd5Sriastradh   int      DimensionIndex   : 16; /* SINT */
683464ebd5Sriastradh   int      DimIndIndex      : 16; /* SINT */
69af69d88dSmrg   unsigned ArrayID          : 10; /* UINT */
704a49301eSmrg};
714a49301eSmrg
724a49301eSmrg/* Very similar to a tgsi_dst_register, removing unsupported fields
734a49301eSmrg * and adding a Saturate flag.  It's easier to push saturate into the
743464ebd5Sriastradh * destination register than to try and create a _SAT variant of each
754a49301eSmrg * instruction function.
764a49301eSmrg */
774a49301eSmrgstruct ureg_dst
784a49301eSmrg{
79af69d88dSmrg   unsigned File            : 4;  /* TGSI_FILE_ */
80af69d88dSmrg   unsigned WriteMask       : 4;  /* TGSI_WRITEMASK_ */
81af69d88dSmrg   unsigned Indirect        : 1;  /* BOOL */
8201e04c3fSmrg   unsigned DimIndirect     : 1;  /* BOOL */
8301e04c3fSmrg   unsigned Dimension       : 1;  /* BOOL */
84af69d88dSmrg   unsigned Saturate        : 1;  /* BOOL */
8501e04c3fSmrg   unsigned Invariant       : 1;  /* BOOL */
86af69d88dSmrg   int      Index           : 16; /* SINT */
874a49301eSmrg   int      IndirectIndex   : 16; /* SINT */
88af69d88dSmrg   unsigned IndirectFile    : 4;  /* TGSI_FILE_ */
894a49301eSmrg   int      IndirectSwizzle : 2;  /* TGSI_SWIZZLE_ */
9001e04c3fSmrg   unsigned DimIndFile      : 4;  /* TGSI_FILE_ */
9101e04c3fSmrg   unsigned DimIndSwizzle   : 2;  /* TGSI_SWIZZLE_ */
9201e04c3fSmrg   int      DimensionIndex  : 16; /* SINT */
9301e04c3fSmrg   int      DimIndIndex     : 16; /* SINT */
94af69d88dSmrg   unsigned ArrayID         : 10; /* UINT */
954a49301eSmrg};
964a49301eSmrg
974a49301eSmrgstruct pipe_context;
984a49301eSmrg
994a49301eSmrgstruct ureg_program *
10001e04c3fSmrgureg_create(enum pipe_shader_type processor);
10101e04c3fSmrg
10201e04c3fSmrgstruct ureg_program *
10301e04c3fSmrgureg_create_with_screen(enum pipe_shader_type processor,
10401e04c3fSmrg                        struct pipe_screen *screen);
1054a49301eSmrg
1064a49301eSmrgconst struct tgsi_token *
1074a49301eSmrgureg_finalize( struct ureg_program * );
1084a49301eSmrg
1094a49301eSmrg/* Create and return a shader:
1104a49301eSmrg */
1114a49301eSmrgvoid *
1124a49301eSmrgureg_create_shader( struct ureg_program *,
113af69d88dSmrg                    struct pipe_context *pipe,
114af69d88dSmrg		    const struct pipe_stream_output_info *so );
1154a49301eSmrg
11601e04c3fSmrgvoid
11701e04c3fSmrgureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor);
1184a49301eSmrg
1194a49301eSmrg/* Alternately, return the built token stream and hand ownership of
1204a49301eSmrg * that memory to the caller:
1214a49301eSmrg */
1224a49301eSmrgconst struct tgsi_token *
1234a49301eSmrgureg_get_tokens( struct ureg_program *ureg,
1244a49301eSmrg                 unsigned *nr_tokens );
1254a49301eSmrg
126af69d88dSmrg/*
127af69d88dSmrg * Returns the number of currently declared outputs.
128af69d88dSmrg */
129af69d88dSmrgunsigned
130af69d88dSmrgureg_get_nr_outputs( const struct ureg_program *ureg );
131af69d88dSmrg
1324a49301eSmrg
1333464ebd5Sriastradh/* Free the tokens created by ureg_get_tokens() */
1343464ebd5Sriastradhvoid ureg_free_tokens( const struct tgsi_token *tokens );
1353464ebd5Sriastradh
1363464ebd5Sriastradh
1374a49301eSmrgvoid
1384a49301eSmrgureg_destroy( struct ureg_program * );
1394a49301eSmrg
1404a49301eSmrg
1414a49301eSmrg/***********************************************************************
1424a49301eSmrg * Convenience routine:
1434a49301eSmrg */
14401e04c3fSmrgstatic inline void *
145af69d88dSmrgureg_create_shader_with_so_and_destroy( struct ureg_program *p,
146af69d88dSmrg			struct pipe_context *pipe,
147af69d88dSmrg			const struct pipe_stream_output_info *so )
1484a49301eSmrg{
149af69d88dSmrg   void *result = ureg_create_shader( p, pipe, so );
1504a49301eSmrg   ureg_destroy( p );
1514a49301eSmrg   return result;
1524a49301eSmrg}
1534a49301eSmrg
15401e04c3fSmrgstatic inline void *
155af69d88dSmrgureg_create_shader_and_destroy( struct ureg_program *p,
156af69d88dSmrg                                struct pipe_context *pipe )
157af69d88dSmrg{
158af69d88dSmrg   return ureg_create_shader_with_so_and_destroy(p, pipe, NULL);
159af69d88dSmrg}
160af69d88dSmrg
1614a49301eSmrg
162cdc920a0Smrg/***********************************************************************
163cdc920a0Smrg * Build shader properties:
164cdc920a0Smrg */
165cdc920a0Smrg
166cdc920a0Smrgvoid
16701e04c3fSmrgureg_property(struct ureg_program *ureg, unsigned name, unsigned value);
168af69d88dSmrg
169af69d88dSmrg
1704a49301eSmrg/***********************************************************************
1714a49301eSmrg * Build shader declarations:
1724a49301eSmrg */
1734a49301eSmrg
17401e04c3fSmrgstruct ureg_src
1757ec681f3Smrgureg_DECL_fs_input_centroid_layout(struct ureg_program *,
17601e04c3fSmrg                       enum tgsi_semantic semantic_name,
17701e04c3fSmrg                       unsigned semantic_index,
17801e04c3fSmrg                       enum tgsi_interpolate_mode interp_mode,
17901e04c3fSmrg                       enum tgsi_interpolate_loc interp_location,
18001e04c3fSmrg                       unsigned index,
18101e04c3fSmrg                       unsigned usage_mask,
18201e04c3fSmrg                       unsigned array_id,
18301e04c3fSmrg                       unsigned array_size);
18401e04c3fSmrg
1854a49301eSmrgstruct ureg_src
1867ec681f3Smrgureg_DECL_fs_input_centroid(struct ureg_program *,
18701e04c3fSmrg                       enum tgsi_semantic semantic_name,
188cdc920a0Smrg                       unsigned semantic_index,
18901e04c3fSmrg                       enum tgsi_interpolate_mode interp_mode,
19001e04c3fSmrg                       enum tgsi_interpolate_loc interp_location,
19101e04c3fSmrg                       unsigned array_id,
19201e04c3fSmrg                       unsigned array_size);
1933464ebd5Sriastradh
19401e04c3fSmrgstatic inline struct ureg_src
195cdc920a0Smrgureg_DECL_fs_input(struct ureg_program *ureg,
19601e04c3fSmrg                   enum tgsi_semantic semantic_name,
197cdc920a0Smrg                   unsigned semantic_index,
19801e04c3fSmrg                   enum tgsi_interpolate_mode interp_mode)
199cdc920a0Smrg{
2007ec681f3Smrg   return ureg_DECL_fs_input_centroid(ureg,
201cdc920a0Smrg                                 semantic_name,
202cdc920a0Smrg                                 semantic_index,
203cdc920a0Smrg                                 interp_mode,
2047ec681f3Smrg                                 TGSI_INTERPOLATE_LOC_CENTER, 0, 1);
205cdc920a0Smrg}
2064a49301eSmrg
2074a49301eSmrgstruct ureg_src
2084a49301eSmrgureg_DECL_vs_input( struct ureg_program *,
2094a49301eSmrg                    unsigned index );
2104a49301eSmrg
211cdc920a0Smrgstruct ureg_src
21201e04c3fSmrgureg_DECL_input_layout(struct ureg_program *,
21301e04c3fSmrg                enum tgsi_semantic semantic_name,
21401e04c3fSmrg                unsigned semantic_index,
21501e04c3fSmrg                unsigned index,
21601e04c3fSmrg                unsigned usage_mask,
21701e04c3fSmrg                unsigned array_id,
21801e04c3fSmrg                unsigned array_size);
21901e04c3fSmrg
22001e04c3fSmrgstruct ureg_src
22101e04c3fSmrgureg_DECL_input(struct ureg_program *,
22201e04c3fSmrg                enum tgsi_semantic semantic_name,
22301e04c3fSmrg                unsigned semantic_index,
22401e04c3fSmrg                unsigned array_id,
22501e04c3fSmrg                unsigned array_size);
226cdc920a0Smrg
227cdc920a0Smrgstruct ureg_src
228cdc920a0Smrgureg_DECL_system_value(struct ureg_program *,
22901e04c3fSmrg                       enum tgsi_semantic semantic_name,
230cdc920a0Smrg                       unsigned semantic_index);
231cdc920a0Smrg
232af69d88dSmrgstruct ureg_dst
23301e04c3fSmrgureg_DECL_output_layout(struct ureg_program *,
23401e04c3fSmrg                        enum tgsi_semantic semantic_name,
23501e04c3fSmrg                        unsigned semantic_index,
23601e04c3fSmrg                        unsigned streams,
23701e04c3fSmrg                        unsigned index,
23801e04c3fSmrg                        unsigned usage_mask,
23901e04c3fSmrg                        unsigned array_id,
24001e04c3fSmrg                        unsigned array_size,
24101e04c3fSmrg                        boolean invariant);
24201e04c3fSmrg
24301e04c3fSmrgstruct ureg_dst
24401e04c3fSmrgureg_DECL_output_masked(struct ureg_program *,
24501e04c3fSmrg                        enum tgsi_semantic semantic_name,
24601e04c3fSmrg                        unsigned semantic_index,
24701e04c3fSmrg                        unsigned usage_mask,
24801e04c3fSmrg                        unsigned array_id,
24901e04c3fSmrg                        unsigned array_size);
25001e04c3fSmrg
25101e04c3fSmrgstruct ureg_dst
25201e04c3fSmrgureg_DECL_output(struct ureg_program *,
25301e04c3fSmrg                 enum tgsi_semantic semantic_name,
25401e04c3fSmrg                 unsigned semantic_index);
255af69d88dSmrg
2564a49301eSmrgstruct ureg_dst
25701e04c3fSmrgureg_DECL_output_array(struct ureg_program *ureg,
25801e04c3fSmrg                       enum tgsi_semantic semantic_name,
25901e04c3fSmrg                       unsigned semantic_index,
26001e04c3fSmrg                       unsigned array_id,
26101e04c3fSmrg                       unsigned array_size);
2624a49301eSmrg
2634a49301eSmrgstruct ureg_src
2644a49301eSmrgureg_DECL_immediate( struct ureg_program *,
2654a49301eSmrg                     const float *v,
2664a49301eSmrg                     unsigned nr );
2674a49301eSmrg
26801e04c3fSmrgstruct ureg_src
26901e04c3fSmrgureg_DECL_immediate_f64( struct ureg_program *,
27001e04c3fSmrg                         const double *v,
27101e04c3fSmrg                         unsigned nr );
27201e04c3fSmrg
273cdc920a0Smrgstruct ureg_src
274cdc920a0Smrgureg_DECL_immediate_uint( struct ureg_program *,
275cdc920a0Smrg                          const unsigned *v,
276cdc920a0Smrg                          unsigned nr );
277cdc920a0Smrg
278cdc920a0Smrgstruct ureg_src
279cdc920a0Smrgureg_DECL_immediate_block_uint( struct ureg_program *,
280cdc920a0Smrg                                const unsigned *v,
281cdc920a0Smrg                                unsigned nr );
282cdc920a0Smrg
283cdc920a0Smrgstruct ureg_src
284cdc920a0Smrgureg_DECL_immediate_int( struct ureg_program *,
285cdc920a0Smrg                         const int *v,
286cdc920a0Smrg                         unsigned nr );
287cdc920a0Smrg
28801e04c3fSmrgstruct ureg_src
28901e04c3fSmrgureg_DECL_immediate_uint64( struct ureg_program *,
29001e04c3fSmrg                            const uint64_t *v,
29101e04c3fSmrg                            unsigned nr );
29201e04c3fSmrg
29301e04c3fSmrgstruct ureg_src
29401e04c3fSmrgureg_DECL_immediate_int64( struct ureg_program *,
29501e04c3fSmrg                           const int64_t *v,
29601e04c3fSmrg                           unsigned nr );
29701e04c3fSmrg
298cdc920a0Smrgvoid
299cdc920a0Smrgureg_DECL_constant2D(struct ureg_program *ureg,
300cdc920a0Smrg                     unsigned first,
301cdc920a0Smrg                     unsigned last,
302cdc920a0Smrg                     unsigned index2D);
303cdc920a0Smrg
3044a49301eSmrgstruct ureg_src
3054a49301eSmrgureg_DECL_constant( struct ureg_program *,
3064a49301eSmrg                    unsigned index );
3074a49301eSmrg
30801e04c3fSmrgvoid
30901e04c3fSmrgureg_DECL_hw_atomic(struct ureg_program *ureg,
31001e04c3fSmrg                    unsigned first,
31101e04c3fSmrg                    unsigned last,
31201e04c3fSmrg                    unsigned buffer_id,
31301e04c3fSmrg                    unsigned array_id);
31401e04c3fSmrg
3154a49301eSmrgstruct ureg_dst
3164a49301eSmrgureg_DECL_temporary( struct ureg_program * );
3174a49301eSmrg
318af69d88dSmrg/**
319af69d88dSmrg * Emit a temporary with the LOCAL declaration flag set.  For use when
320af69d88dSmrg * the register value is not required to be preserved across
321af69d88dSmrg * subroutine boundaries.
322af69d88dSmrg */
323af69d88dSmrgstruct ureg_dst
324af69d88dSmrgureg_DECL_local_temporary( struct ureg_program * );
325af69d88dSmrg
326af69d88dSmrg/**
327af69d88dSmrg * Declare "size" continuous temporary registers.
328af69d88dSmrg */
329af69d88dSmrgstruct ureg_dst
330af69d88dSmrgureg_DECL_array_temporary( struct ureg_program *,
331af69d88dSmrg                           unsigned size,
332af69d88dSmrg                           boolean local );
333af69d88dSmrg
3344a49301eSmrgvoid
3354a49301eSmrgureg_release_temporary( struct ureg_program *ureg,
3364a49301eSmrg                        struct ureg_dst tmp );
3374a49301eSmrg
3384a49301eSmrgstruct ureg_dst
3394a49301eSmrgureg_DECL_address( struct ureg_program * );
3404a49301eSmrg
3414a49301eSmrg/* Supply an index to the sampler declaration as this is the hook to
3424a49301eSmrg * the external pipe_sampler state.  Users of this function probably
3434a49301eSmrg * don't want just any sampler, but a specific one which they've set
3444a49301eSmrg * up state for in the context.
3454a49301eSmrg */
3464a49301eSmrgstruct ureg_src
3474a49301eSmrgureg_DECL_sampler( struct ureg_program *,
3484a49301eSmrg                   unsigned index );
3494a49301eSmrg
3503464ebd5Sriastradhstruct ureg_src
351af69d88dSmrgureg_DECL_sampler_view(struct ureg_program *,
352af69d88dSmrg                       unsigned index,
35301e04c3fSmrg                       enum tgsi_texture_type target,
35401e04c3fSmrg                       enum tgsi_return_type return_type_x,
35501e04c3fSmrg                       enum tgsi_return_type return_type_y,
35601e04c3fSmrg                       enum tgsi_return_type return_type_z,
35701e04c3fSmrg                       enum tgsi_return_type return_type_w );
3583464ebd5Sriastradh
35901e04c3fSmrgstruct ureg_src
36001e04c3fSmrgureg_DECL_image(struct ureg_program *ureg,
36101e04c3fSmrg                unsigned index,
36201e04c3fSmrg                enum tgsi_texture_type target,
36301e04c3fSmrg                enum pipe_format format,
36401e04c3fSmrg                boolean wr,
36501e04c3fSmrg                boolean raw);
36601e04c3fSmrg
36701e04c3fSmrgstruct ureg_src
36801e04c3fSmrgureg_DECL_buffer(struct ureg_program *ureg, unsigned nr, bool atomic);
3694a49301eSmrg
37001e04c3fSmrgstruct ureg_src
37101e04c3fSmrgureg_DECL_memory(struct ureg_program *ureg, unsigned memory_type);
37201e04c3fSmrg
37301e04c3fSmrgstatic inline struct ureg_src
3744a49301eSmrgureg_imm4f( struct ureg_program *ureg,
3754a49301eSmrg                       float a, float b,
3764a49301eSmrg                       float c, float d)
3774a49301eSmrg{
3784a49301eSmrg   float v[4];
3794a49301eSmrg   v[0] = a;
3804a49301eSmrg   v[1] = b;
3814a49301eSmrg   v[2] = c;
3824a49301eSmrg   v[3] = d;
3834a49301eSmrg   return ureg_DECL_immediate( ureg, v, 4 );
3844a49301eSmrg}
3854a49301eSmrg
38601e04c3fSmrgstatic inline struct ureg_src
3874a49301eSmrgureg_imm3f( struct ureg_program *ureg,
3884a49301eSmrg                       float a, float b,
3894a49301eSmrg                       float c)
3904a49301eSmrg{
3914a49301eSmrg   float v[3];
3924a49301eSmrg   v[0] = a;
3934a49301eSmrg   v[1] = b;
3944a49301eSmrg   v[2] = c;
3954a49301eSmrg   return ureg_DECL_immediate( ureg, v, 3 );
3964a49301eSmrg}
3974a49301eSmrg
39801e04c3fSmrgstatic inline struct ureg_src
3994a49301eSmrgureg_imm2f( struct ureg_program *ureg,
4004a49301eSmrg                       float a, float b)
4014a49301eSmrg{
4024a49301eSmrg   float v[2];
4034a49301eSmrg   v[0] = a;
4044a49301eSmrg   v[1] = b;
4054a49301eSmrg   return ureg_DECL_immediate( ureg, v, 2 );
4064a49301eSmrg}
4074a49301eSmrg
40801e04c3fSmrgstatic inline struct ureg_src
4094a49301eSmrgureg_imm1f( struct ureg_program *ureg,
4104a49301eSmrg                       float a)
4114a49301eSmrg{
4124a49301eSmrg   float v[1];
4134a49301eSmrg   v[0] = a;
4144a49301eSmrg   return ureg_DECL_immediate( ureg, v, 1 );
4154a49301eSmrg}
4164a49301eSmrg
41701e04c3fSmrgstatic inline struct ureg_src
418cdc920a0Smrgureg_imm4u( struct ureg_program *ureg,
419cdc920a0Smrg            unsigned a, unsigned b,
420cdc920a0Smrg            unsigned c, unsigned d)
421cdc920a0Smrg{
422cdc920a0Smrg   unsigned v[4];
423cdc920a0Smrg   v[0] = a;
424cdc920a0Smrg   v[1] = b;
425cdc920a0Smrg   v[2] = c;
426cdc920a0Smrg   v[3] = d;
427cdc920a0Smrg   return ureg_DECL_immediate_uint( ureg, v, 4 );
428cdc920a0Smrg}
429cdc920a0Smrg
43001e04c3fSmrgstatic inline struct ureg_src
431cdc920a0Smrgureg_imm3u( struct ureg_program *ureg,
432cdc920a0Smrg            unsigned a, unsigned b,
433cdc920a0Smrg            unsigned c)
434cdc920a0Smrg{
435cdc920a0Smrg   unsigned v[3];
436cdc920a0Smrg   v[0] = a;
437cdc920a0Smrg   v[1] = b;
438cdc920a0Smrg   v[2] = c;
439cdc920a0Smrg   return ureg_DECL_immediate_uint( ureg, v, 3 );
440cdc920a0Smrg}
441cdc920a0Smrg
44201e04c3fSmrgstatic inline struct ureg_src
443cdc920a0Smrgureg_imm2u( struct ureg_program *ureg,
444cdc920a0Smrg            unsigned a, unsigned b)
445cdc920a0Smrg{
446cdc920a0Smrg   unsigned v[2];
447cdc920a0Smrg   v[0] = a;
448cdc920a0Smrg   v[1] = b;
449cdc920a0Smrg   return ureg_DECL_immediate_uint( ureg, v, 2 );
450cdc920a0Smrg}
451cdc920a0Smrg
45201e04c3fSmrgstatic inline struct ureg_src
453cdc920a0Smrgureg_imm1u( struct ureg_program *ureg,
454cdc920a0Smrg            unsigned a)
455cdc920a0Smrg{
456cdc920a0Smrg   return ureg_DECL_immediate_uint( ureg, &a, 1 );
457cdc920a0Smrg}
458cdc920a0Smrg
45901e04c3fSmrgstatic inline struct ureg_src
460cdc920a0Smrgureg_imm4i( struct ureg_program *ureg,
461cdc920a0Smrg            int a, int b,
462cdc920a0Smrg            int c, int d)
463cdc920a0Smrg{
464cdc920a0Smrg   int v[4];
465cdc920a0Smrg   v[0] = a;
466cdc920a0Smrg   v[1] = b;
467cdc920a0Smrg   v[2] = c;
468cdc920a0Smrg   v[3] = d;
469cdc920a0Smrg   return ureg_DECL_immediate_int( ureg, v, 4 );
470cdc920a0Smrg}
471cdc920a0Smrg
47201e04c3fSmrgstatic inline struct ureg_src
473cdc920a0Smrgureg_imm3i( struct ureg_program *ureg,
474cdc920a0Smrg            int a, int b,
475cdc920a0Smrg            int c)
476cdc920a0Smrg{
477cdc920a0Smrg   int v[3];
478cdc920a0Smrg   v[0] = a;
479cdc920a0Smrg   v[1] = b;
480cdc920a0Smrg   v[2] = c;
481cdc920a0Smrg   return ureg_DECL_immediate_int( ureg, v, 3 );
482cdc920a0Smrg}
483cdc920a0Smrg
48401e04c3fSmrgstatic inline struct ureg_src
485cdc920a0Smrgureg_imm2i( struct ureg_program *ureg,
486cdc920a0Smrg            int a, int b)
487cdc920a0Smrg{
488cdc920a0Smrg   int v[2];
489cdc920a0Smrg   v[0] = a;
490cdc920a0Smrg   v[1] = b;
491cdc920a0Smrg   return ureg_DECL_immediate_int( ureg, v, 2 );
492cdc920a0Smrg}
493cdc920a0Smrg
49401e04c3fSmrgstatic inline struct ureg_src
495cdc920a0Smrgureg_imm1i( struct ureg_program *ureg,
496cdc920a0Smrg            int a)
497cdc920a0Smrg{
498cdc920a0Smrg   return ureg_DECL_immediate_int( ureg, &a, 1 );
499cdc920a0Smrg}
500cdc920a0Smrg
501af69d88dSmrg/* Where the destination register has a valid file, but an empty
502af69d88dSmrg * writemask.
503af69d88dSmrg */
50401e04c3fSmrgstatic inline boolean
505af69d88dSmrgureg_dst_is_empty( struct ureg_dst dst )
506af69d88dSmrg{
507af69d88dSmrg   return dst.File != TGSI_FILE_NULL &&
508af69d88dSmrg          dst.WriteMask == 0;
509af69d88dSmrg}
510af69d88dSmrg
5114a49301eSmrg/***********************************************************************
5124a49301eSmrg * Functions for patching up labels
5134a49301eSmrg */
5144a49301eSmrg
5154a49301eSmrg
5164a49301eSmrg/* Will return a number which can be used in a label to point to the
5174a49301eSmrg * next instruction to be emitted.
5184a49301eSmrg */
5194a49301eSmrgunsigned
5204a49301eSmrgureg_get_instruction_number( struct ureg_program *ureg );
5214a49301eSmrg
5224a49301eSmrg
5234a49301eSmrg/* Patch a given label (expressed as a token number) to point to a
5244a49301eSmrg * given instruction (expressed as an instruction number).
5254a49301eSmrg *
5264a49301eSmrg * Labels are obtained from instruction emitters, eg ureg_CAL().
5274a49301eSmrg * Instruction numbers are obtained from ureg_get_instruction_number(),
5284a49301eSmrg * above.
5294a49301eSmrg */
5304a49301eSmrgvoid
5314a49301eSmrgureg_fixup_label(struct ureg_program *ureg,
5324a49301eSmrg                 unsigned label_token,
5334a49301eSmrg                 unsigned instruction_number );
5344a49301eSmrg
5354a49301eSmrg
5364a49301eSmrg/* Generic instruction emitter.  Use if you need to pass the opcode as
5373464ebd5Sriastradh * a parameter, rather than using the emit_OP() variants below.
5384a49301eSmrg */
5394a49301eSmrgvoid
5404a49301eSmrgureg_insn(struct ureg_program *ureg,
54101e04c3fSmrg          enum tgsi_opcode opcode,
5424a49301eSmrg          const struct ureg_dst *dst,
5434a49301eSmrg          unsigned nr_dst,
5444a49301eSmrg          const struct ureg_src *src,
54501e04c3fSmrg          unsigned nr_src,
54601e04c3fSmrg          unsigned precise );
5474a49301eSmrg
5484a49301eSmrg
5494a49301eSmrgvoid
5504a49301eSmrgureg_tex_insn(struct ureg_program *ureg,
55101e04c3fSmrg              enum tgsi_opcode opcode,
5524a49301eSmrg              const struct ureg_dst *dst,
5534a49301eSmrg              unsigned nr_dst,
55401e04c3fSmrg              enum tgsi_texture_type target,
55501e04c3fSmrg              enum tgsi_return_type return_type,
556af69d88dSmrg              const struct tgsi_texture_offset *texoffsets,
557af69d88dSmrg              unsigned nr_offset,
5584a49301eSmrg              const struct ureg_src *src,
5594a49301eSmrg              unsigned nr_src );
5604a49301eSmrg
5614a49301eSmrg
5624a49301eSmrgvoid
56301e04c3fSmrgureg_memory_insn(struct ureg_program *ureg,
56401e04c3fSmrg                 enum tgsi_opcode opcode,
56501e04c3fSmrg                 const struct ureg_dst *dst,
56601e04c3fSmrg                 unsigned nr_dst,
56701e04c3fSmrg                 const struct ureg_src *src,
56801e04c3fSmrg                 unsigned nr_src,
56901e04c3fSmrg                 unsigned qualifier,
57001e04c3fSmrg                 enum tgsi_texture_type texture,
57101e04c3fSmrg                 enum pipe_format format);
5724a49301eSmrg
5734a49301eSmrg/***********************************************************************
5744a49301eSmrg * Internal instruction helpers, don't call these directly:
5754a49301eSmrg */
5764a49301eSmrg
5774a49301eSmrgstruct ureg_emit_insn_result {
5784a49301eSmrg   unsigned insn_token;       /*< Used to fixup insn size. */
5794a49301eSmrg   unsigned extended_token;   /*< Used to set the Extended bit, usually the same as insn_token. */
5804a49301eSmrg};
5814a49301eSmrg
5824a49301eSmrgstruct ureg_emit_insn_result
5834a49301eSmrgureg_emit_insn(struct ureg_program *ureg,
58401e04c3fSmrg               enum tgsi_opcode opcode,
5854a49301eSmrg               boolean saturate,
58601e04c3fSmrg               unsigned precise,
5874a49301eSmrg               unsigned num_dst,
58801e04c3fSmrg               unsigned num_src);
5894a49301eSmrg
5904a49301eSmrgvoid
5914a49301eSmrgureg_emit_label(struct ureg_program *ureg,
5924a49301eSmrg                unsigned insn_token,
5934a49301eSmrg                unsigned *label_token );
5944a49301eSmrg
5954a49301eSmrgvoid
5964a49301eSmrgureg_emit_texture(struct ureg_program *ureg,
5974a49301eSmrg                  unsigned insn_token,
59801e04c3fSmrg                  enum tgsi_texture_type target,
59901e04c3fSmrg                  enum tgsi_return_type return_type,
60001e04c3fSmrg                  unsigned num_offsets);
601af69d88dSmrg
602af69d88dSmrgvoid
603af69d88dSmrgureg_emit_texture_offset(struct ureg_program *ureg,
604af69d88dSmrg                         const struct tgsi_texture_offset *offset);
6054a49301eSmrg
60601e04c3fSmrgvoid
60701e04c3fSmrgureg_emit_memory(struct ureg_program *ureg,
60801e04c3fSmrg                 unsigned insn_token,
60901e04c3fSmrg                 unsigned qualifier,
61001e04c3fSmrg                 enum tgsi_texture_type texture,
61101e04c3fSmrg                 enum pipe_format format);
61201e04c3fSmrg
6134a49301eSmrgvoid
6144a49301eSmrgureg_emit_dst( struct ureg_program *ureg,
6154a49301eSmrg               struct ureg_dst dst );
6164a49301eSmrg
6174a49301eSmrgvoid
6184a49301eSmrgureg_emit_src( struct ureg_program *ureg,
6194a49301eSmrg               struct ureg_src src );
6204a49301eSmrg
6214a49301eSmrgvoid
6224a49301eSmrgureg_fixup_insn_size(struct ureg_program *ureg,
6234a49301eSmrg                     unsigned insn );
6244a49301eSmrg
6254a49301eSmrg
6264a49301eSmrg#define OP00( op )                                              \
62701e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg )       \
6284a49301eSmrg{                                                               \
62901e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                  \
630af69d88dSmrg   struct ureg_emit_insn_result insn;                           \
631af69d88dSmrg   insn = ureg_emit_insn(ureg,                                  \
632af69d88dSmrg                         opcode,                                \
633af69d88dSmrg                         FALSE,                                 \
63401e04c3fSmrg                         0,                                     \
635af69d88dSmrg                         0,                                     \
636af69d88dSmrg                         0);                                    \
637af69d88dSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );               \
6384a49301eSmrg}
6394a49301eSmrg
6404a49301eSmrg#define OP01( op )                                              \
64101e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg,        \
6424a49301eSmrg                              struct ureg_src src )             \
6434a49301eSmrg{                                                               \
64401e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                  \
645af69d88dSmrg   struct ureg_emit_insn_result insn;                           \
646af69d88dSmrg   insn = ureg_emit_insn(ureg,                                  \
647af69d88dSmrg                         opcode,                                \
648af69d88dSmrg                         FALSE,                                 \
64901e04c3fSmrg                         0,                                     \
650af69d88dSmrg                         0,                                     \
651af69d88dSmrg                         1);                                    \
6524a49301eSmrg   ureg_emit_src( ureg, src );                                  \
653af69d88dSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );               \
6544a49301eSmrg}
6554a49301eSmrg
6564a49301eSmrg#define OP00_LBL( op )                                          \
65701e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg,        \
6584a49301eSmrg                              unsigned *label_token )           \
6594a49301eSmrg{                                                               \
66001e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                  \
6614a49301eSmrg   struct ureg_emit_insn_result insn;                           \
6624a49301eSmrg   insn = ureg_emit_insn(ureg,                                  \
6634a49301eSmrg                         opcode,                                \
6644a49301eSmrg                         FALSE,                                 \
66501e04c3fSmrg                         0,                                     \
6664a49301eSmrg                         0,                                     \
6674a49301eSmrg                         0);                                    \
6684a49301eSmrg   ureg_emit_label( ureg, insn.extended_token, label_token );   \
6694a49301eSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );               \
6704a49301eSmrg}
6714a49301eSmrg
6724a49301eSmrg#define OP01_LBL( op )                                          \
67301e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg,        \
6744a49301eSmrg                              struct ureg_src src,              \
6754a49301eSmrg                              unsigned *label_token )          \
6764a49301eSmrg{                                                               \
67701e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                  \
6784a49301eSmrg   struct ureg_emit_insn_result insn;                           \
6794a49301eSmrg   insn = ureg_emit_insn(ureg,                                  \
6804a49301eSmrg                         opcode,                                \
6814a49301eSmrg                         FALSE,                                 \
68201e04c3fSmrg                         0,                                     \
6834a49301eSmrg                         0,                                     \
6844a49301eSmrg                         1);                                    \
6854a49301eSmrg   ureg_emit_label( ureg, insn.extended_token, label_token );   \
6864a49301eSmrg   ureg_emit_src( ureg, src );                                  \
6874a49301eSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );               \
6884a49301eSmrg}
6894a49301eSmrg
6904a49301eSmrg#define OP10( op )                                                      \
69101e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg,                \
6924a49301eSmrg                              struct ureg_dst dst )                     \
6934a49301eSmrg{                                                                       \
69401e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                          \
695af69d88dSmrg   struct ureg_emit_insn_result insn;                                   \
696af69d88dSmrg   if (ureg_dst_is_empty(dst))                                          \
697af69d88dSmrg      return;                                                           \
698af69d88dSmrg   insn = ureg_emit_insn(ureg,                                          \
699af69d88dSmrg                         opcode,                                        \
700af69d88dSmrg                         dst.Saturate,                                  \
70101e04c3fSmrg                         0,                                             \
702af69d88dSmrg                         1,                                             \
703af69d88dSmrg                         0);                                            \
7044a49301eSmrg   ureg_emit_dst( ureg, dst );                                          \
705af69d88dSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );                       \
7064a49301eSmrg}
7074a49301eSmrg
7084a49301eSmrg
7094a49301eSmrg#define OP11( op )                                                      \
71001e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg,                \
7114a49301eSmrg                              struct ureg_dst dst,                      \
7124a49301eSmrg                              struct ureg_src src )                     \
7134a49301eSmrg{                                                                       \
71401e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                          \
715af69d88dSmrg   struct ureg_emit_insn_result insn;                                   \
716af69d88dSmrg   if (ureg_dst_is_empty(dst))                                          \
717af69d88dSmrg      return;                                                           \
718af69d88dSmrg   insn = ureg_emit_insn(ureg,                                          \
719af69d88dSmrg                         opcode,                                        \
720af69d88dSmrg                         dst.Saturate,                                  \
72101e04c3fSmrg                         0,                                             \
722af69d88dSmrg                         1,                                             \
723af69d88dSmrg                         1);                                            \
7244a49301eSmrg   ureg_emit_dst( ureg, dst );                                          \
7254a49301eSmrg   ureg_emit_src( ureg, src );                                          \
726af69d88dSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );                       \
7274a49301eSmrg}
7284a49301eSmrg
7294a49301eSmrg#define OP12( op )                                                      \
73001e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg,                \
7314a49301eSmrg                              struct ureg_dst dst,                      \
7324a49301eSmrg                              struct ureg_src src0,                     \
7334a49301eSmrg                              struct ureg_src src1 )                    \
7344a49301eSmrg{                                                                       \
73501e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                          \
736af69d88dSmrg   struct ureg_emit_insn_result insn;                                   \
737af69d88dSmrg   if (ureg_dst_is_empty(dst))                                          \
738af69d88dSmrg      return;                                                           \
739af69d88dSmrg   insn = ureg_emit_insn(ureg,                                          \
740af69d88dSmrg                         opcode,                                        \
741af69d88dSmrg                         dst.Saturate,                                  \
74201e04c3fSmrg                         0,                                             \
743af69d88dSmrg                         1,                                             \
744af69d88dSmrg                         2);                                            \
7454a49301eSmrg   ureg_emit_dst( ureg, dst );                                          \
7464a49301eSmrg   ureg_emit_src( ureg, src0 );                                         \
7474a49301eSmrg   ureg_emit_src( ureg, src1 );                                         \
748af69d88dSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );                       \
7494a49301eSmrg}
7504a49301eSmrg
7514a49301eSmrg#define OP12_TEX( op )                                                  \
75201e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg,                \
7534a49301eSmrg                              struct ureg_dst dst,                      \
75401e04c3fSmrg                              enum tgsi_texture_type target,            \
7554a49301eSmrg                              struct ureg_src src0,                     \
7564a49301eSmrg                              struct ureg_src src1 )                    \
7574a49301eSmrg{                                                                       \
75801e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                          \
75901e04c3fSmrg   enum tgsi_return_type return_type = TGSI_RETURN_TYPE_UNKNOWN;        \
7604a49301eSmrg   struct ureg_emit_insn_result insn;                                   \
761af69d88dSmrg   if (ureg_dst_is_empty(dst))                                          \
762af69d88dSmrg      return;                                                           \
7634a49301eSmrg   insn = ureg_emit_insn(ureg,                                          \
7644a49301eSmrg                         opcode,                                        \
7654a49301eSmrg                         dst.Saturate,                                  \
76601e04c3fSmrg                         0,                                             \
7674a49301eSmrg                         1,                                             \
7684a49301eSmrg                         2);                                            \
76901e04c3fSmrg   ureg_emit_texture( ureg, insn.extended_token, target,                \
77001e04c3fSmrg                      return_type, 0 );                                 \
7714a49301eSmrg   ureg_emit_dst( ureg, dst );                                          \
7724a49301eSmrg   ureg_emit_src( ureg, src0 );                                         \
7734a49301eSmrg   ureg_emit_src( ureg, src1 );                                         \
7744a49301eSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );                       \
7754a49301eSmrg}
7764a49301eSmrg
7774a49301eSmrg#define OP13( op )                                                      \
77801e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg,                \
779af69d88dSmrg                              struct ureg_dst dst,                      \
780af69d88dSmrg                              struct ureg_src src0,                     \
781af69d88dSmrg                              struct ureg_src src1,                     \
782af69d88dSmrg                              struct ureg_src src2 )                    \
783af69d88dSmrg{                                                                       \
78401e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                          \
785af69d88dSmrg   struct ureg_emit_insn_result insn;                                   \
786af69d88dSmrg   if (ureg_dst_is_empty(dst))                                          \
787af69d88dSmrg      return;                                                           \
788af69d88dSmrg   insn = ureg_emit_insn(ureg,                                          \
789af69d88dSmrg                         opcode,                                        \
790af69d88dSmrg                         dst.Saturate,                                  \
79101e04c3fSmrg                         0,                                             \
792af69d88dSmrg                         1,                                             \
793af69d88dSmrg                         3);                                            \
7944a49301eSmrg   ureg_emit_dst( ureg, dst );                                          \
7954a49301eSmrg   ureg_emit_src( ureg, src0 );                                         \
7964a49301eSmrg   ureg_emit_src( ureg, src1 );                                         \
7974a49301eSmrg   ureg_emit_src( ureg, src2 );                                         \
798af69d88dSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );                       \
7994a49301eSmrg}
8004a49301eSmrg
8017ec681f3Smrg#define OP14( op )                                                      \
8027ec681f3Smrgstatic inline void ureg_##op( struct ureg_program *ureg,                \
8037ec681f3Smrg                              struct ureg_dst dst,                      \
8047ec681f3Smrg                              struct ureg_src src0,                     \
8057ec681f3Smrg                              struct ureg_src src1,                     \
8067ec681f3Smrg                              struct ureg_src src2,                     \
8077ec681f3Smrg                              struct ureg_src src3 )                    \
8087ec681f3Smrg{                                                                       \
8097ec681f3Smrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                          \
8107ec681f3Smrg   struct ureg_emit_insn_result insn;                                   \
8117ec681f3Smrg   if (ureg_dst_is_empty(dst))                                          \
8127ec681f3Smrg      return;                                                           \
8137ec681f3Smrg   insn = ureg_emit_insn(ureg,                                          \
8147ec681f3Smrg                         opcode,                                        \
8157ec681f3Smrg                         dst.Saturate,                                  \
8167ec681f3Smrg                         0,                                             \
8177ec681f3Smrg                         1,                                             \
8187ec681f3Smrg                         4);                                            \
8197ec681f3Smrg   ureg_emit_dst( ureg, dst );                                          \
8207ec681f3Smrg   ureg_emit_src( ureg, src0 );                                         \
8217ec681f3Smrg   ureg_emit_src( ureg, src1 );                                         \
8227ec681f3Smrg   ureg_emit_src( ureg, src2 );                                         \
8237ec681f3Smrg   ureg_emit_src( ureg, src3 );                                         \
8247ec681f3Smrg   ureg_fixup_insn_size( ureg, insn.insn_token );                       \
8257ec681f3Smrg}
8267ec681f3Smrg
8274a49301eSmrg#define OP14_TEX( op )                                                  \
82801e04c3fSmrgstatic inline void ureg_##op( struct ureg_program *ureg,                \
8293464ebd5Sriastradh                              struct ureg_dst dst,                      \
83001e04c3fSmrg                              enum tgsi_texture_type target,            \
8313464ebd5Sriastradh                              struct ureg_src src0,                     \
8323464ebd5Sriastradh                              struct ureg_src src1,                     \
8333464ebd5Sriastradh                              struct ureg_src src2,                     \
8343464ebd5Sriastradh                              struct ureg_src src3 )                    \
8353464ebd5Sriastradh{                                                                       \
83601e04c3fSmrg   enum tgsi_opcode opcode = TGSI_OPCODE_##op;                          \
83701e04c3fSmrg   enum tgsi_return_type return_type = TGSI_RETURN_TYPE_UNKNOWN;        \
838af69d88dSmrg   struct ureg_emit_insn_result insn;                                   \
839af69d88dSmrg   if (ureg_dst_is_empty(dst))                                          \
840af69d88dSmrg      return;                                                           \
841af69d88dSmrg   insn = ureg_emit_insn(ureg,                                          \
842af69d88dSmrg                         opcode,                                        \
843af69d88dSmrg                         dst.Saturate,                                  \
84401e04c3fSmrg                         0,                                             \
845af69d88dSmrg                         1,                                             \
846af69d88dSmrg                         4);                                            \
84701e04c3fSmrg   ureg_emit_texture( ureg, insn.extended_token, target,                \
84801e04c3fSmrg                      return_type, 0 );                                 \
8493464ebd5Sriastradh   ureg_emit_dst( ureg, dst );                                          \
8503464ebd5Sriastradh   ureg_emit_src( ureg, src0 );                                         \
8513464ebd5Sriastradh   ureg_emit_src( ureg, src1 );                                         \
8523464ebd5Sriastradh   ureg_emit_src( ureg, src2 );                                         \
8533464ebd5Sriastradh   ureg_emit_src( ureg, src3 );                                         \
854af69d88dSmrg   ureg_fixup_insn_size( ureg, insn.insn_token );                       \
8553464ebd5Sriastradh}
8563464ebd5Sriastradh
8574a49301eSmrg/* Use a template include to generate a correctly-typed ureg_OP()
8584a49301eSmrg * function for each TGSI opcode:
8594a49301eSmrg */
8604a49301eSmrg#include "tgsi_opcode_tmp.h"
8614a49301eSmrg
8624a49301eSmrg
8634a49301eSmrg/***********************************************************************
8644a49301eSmrg * Inline helpers for manipulating register structs:
8654a49301eSmrg */
86601e04c3fSmrgstatic inline struct ureg_src
8674a49301eSmrgureg_negate( struct ureg_src reg )
8684a49301eSmrg{
8694a49301eSmrg   assert(reg.File != TGSI_FILE_NULL);
8704a49301eSmrg   reg.Negate ^= 1;
8714a49301eSmrg   return reg;
8724a49301eSmrg}
8734a49301eSmrg
87401e04c3fSmrgstatic inline struct ureg_src
8754a49301eSmrgureg_abs( struct ureg_src reg )
8764a49301eSmrg{
8774a49301eSmrg   assert(reg.File != TGSI_FILE_NULL);
8784a49301eSmrg   reg.Absolute = 1;
8794a49301eSmrg   reg.Negate = 0;
8804a49301eSmrg   return reg;
8814a49301eSmrg}
8824a49301eSmrg
88301e04c3fSmrgstatic inline struct ureg_src
8844a49301eSmrgureg_swizzle( struct ureg_src reg,
8854a49301eSmrg              int x, int y, int z, int w )
8864a49301eSmrg{
8874a49301eSmrg   unsigned swz = ( (reg.SwizzleX << 0) |
8884a49301eSmrg                    (reg.SwizzleY << 2) |
8894a49301eSmrg                    (reg.SwizzleZ << 4) |
8904a49301eSmrg                    (reg.SwizzleW << 6));
8914a49301eSmrg
8924a49301eSmrg   assert(reg.File != TGSI_FILE_NULL);
8934a49301eSmrg   assert(x < 4);
8944a49301eSmrg   assert(y < 4);
8954a49301eSmrg   assert(z < 4);
8964a49301eSmrg   assert(w < 4);
8974a49301eSmrg
8984a49301eSmrg   reg.SwizzleX = (swz >> (x*2)) & 0x3;
8994a49301eSmrg   reg.SwizzleY = (swz >> (y*2)) & 0x3;
9004a49301eSmrg   reg.SwizzleZ = (swz >> (z*2)) & 0x3;
9014a49301eSmrg   reg.SwizzleW = (swz >> (w*2)) & 0x3;
9024a49301eSmrg   return reg;
9034a49301eSmrg}
9044a49301eSmrg
90501e04c3fSmrgstatic inline struct ureg_src
9064a49301eSmrgureg_scalar( struct ureg_src reg, int x )
9074a49301eSmrg{
9084a49301eSmrg   return ureg_swizzle(reg, x, x, x, x);
9094a49301eSmrg}
9104a49301eSmrg
91101e04c3fSmrgstatic inline struct ureg_dst
9124a49301eSmrgureg_writemask( struct ureg_dst reg,
9134a49301eSmrg                unsigned writemask )
9144a49301eSmrg{
9154a49301eSmrg   assert(reg.File != TGSI_FILE_NULL);
9164a49301eSmrg   reg.WriteMask &= writemask;
9174a49301eSmrg   return reg;
9184a49301eSmrg}
9194a49301eSmrg
92001e04c3fSmrgstatic inline struct ureg_dst
9214a49301eSmrgureg_saturate( struct ureg_dst reg )
9224a49301eSmrg{
9234a49301eSmrg   assert(reg.File != TGSI_FILE_NULL);
9244a49301eSmrg   reg.Saturate = 1;
9254a49301eSmrg   return reg;
9264a49301eSmrg}
9274a49301eSmrg
92801e04c3fSmrgstatic inline struct ureg_dst
9294a49301eSmrgureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
9304a49301eSmrg{
9314a49301eSmrg   assert(reg.File != TGSI_FILE_NULL);
9324a49301eSmrg   reg.Indirect = 1;
933af69d88dSmrg   reg.IndirectFile = addr.File;
9344a49301eSmrg   reg.IndirectIndex = addr.Index;
9354a49301eSmrg   reg.IndirectSwizzle = addr.SwizzleX;
9364a49301eSmrg   return reg;
9374a49301eSmrg}
9384a49301eSmrg
93901e04c3fSmrgstatic inline struct ureg_src
9404a49301eSmrgureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
9414a49301eSmrg{
9424a49301eSmrg   assert(reg.File != TGSI_FILE_NULL);
9434a49301eSmrg   reg.Indirect = 1;
944cdc920a0Smrg   reg.IndirectFile = addr.File;
9454a49301eSmrg   reg.IndirectIndex = addr.Index;
9464a49301eSmrg   reg.IndirectSwizzle = addr.SwizzleX;
9474a49301eSmrg   return reg;
9484a49301eSmrg}
9494a49301eSmrg
95001e04c3fSmrgstatic inline struct ureg_dst
95101e04c3fSmrgureg_dst_dimension( struct ureg_dst reg, int index )
95201e04c3fSmrg{
95301e04c3fSmrg   assert(reg.File != TGSI_FILE_NULL);
95401e04c3fSmrg   reg.Dimension = 1;
95501e04c3fSmrg   reg.DimIndirect = 0;
95601e04c3fSmrg   reg.DimensionIndex = index;
95701e04c3fSmrg   return reg;
95801e04c3fSmrg}
95901e04c3fSmrg
96001e04c3fSmrgstatic inline struct ureg_src
961cdc920a0Smrgureg_src_dimension( struct ureg_src reg, int index )
962cdc920a0Smrg{
963cdc920a0Smrg   assert(reg.File != TGSI_FILE_NULL);
964cdc920a0Smrg   reg.Dimension = 1;
9653464ebd5Sriastradh   reg.DimIndirect = 0;
966cdc920a0Smrg   reg.DimensionIndex = index;
967cdc920a0Smrg   return reg;
968cdc920a0Smrg}
969cdc920a0Smrg
97001e04c3fSmrgstatic inline struct ureg_dst
97101e04c3fSmrgureg_dst_dimension_indirect( struct ureg_dst reg, struct ureg_src addr,
97201e04c3fSmrg                             int index )
97301e04c3fSmrg{
97401e04c3fSmrg   assert(reg.File != TGSI_FILE_NULL);
97501e04c3fSmrg   reg.Dimension = 1;
97601e04c3fSmrg   reg.DimIndirect = 1;
97701e04c3fSmrg   reg.DimensionIndex = index;
97801e04c3fSmrg   reg.DimIndFile = addr.File;
97901e04c3fSmrg   reg.DimIndIndex = addr.Index;
98001e04c3fSmrg   reg.DimIndSwizzle = addr.SwizzleX;
98101e04c3fSmrg   return reg;
98201e04c3fSmrg}
9833464ebd5Sriastradh
98401e04c3fSmrgstatic inline struct ureg_src
9853464ebd5Sriastradhureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
9863464ebd5Sriastradh                             int index )
9873464ebd5Sriastradh{
9883464ebd5Sriastradh   assert(reg.File != TGSI_FILE_NULL);
9893464ebd5Sriastradh   reg.Dimension = 1;
9903464ebd5Sriastradh   reg.DimIndirect = 1;
9913464ebd5Sriastradh   reg.DimensionIndex = index;
9923464ebd5Sriastradh   reg.DimIndFile = addr.File;
9933464ebd5Sriastradh   reg.DimIndIndex = addr.Index;
9943464ebd5Sriastradh   reg.DimIndSwizzle = addr.SwizzleX;
9953464ebd5Sriastradh   return reg;
9963464ebd5Sriastradh}
9973464ebd5Sriastradh
99801e04c3fSmrgstatic inline struct ureg_src
99901e04c3fSmrgureg_src_array_offset(struct ureg_src reg, int offset)
100001e04c3fSmrg{
100101e04c3fSmrg   reg.Index += offset;
100201e04c3fSmrg   return reg;
100301e04c3fSmrg}
100401e04c3fSmrg
100501e04c3fSmrgstatic inline struct ureg_dst
1006af69d88dSmrgureg_dst_array_offset( struct ureg_dst reg, int offset )
1007af69d88dSmrg{
1008af69d88dSmrg   reg.Index += offset;
1009af69d88dSmrg   return reg;
1010af69d88dSmrg}
1011af69d88dSmrg
101201e04c3fSmrgstatic inline struct ureg_dst
101301e04c3fSmrgureg_dst_array_register(unsigned file,
101401e04c3fSmrg                        unsigned index,
101501e04c3fSmrg                        unsigned array_id)
10164a49301eSmrg{
10174a49301eSmrg   struct ureg_dst dst;
10184a49301eSmrg
101901e04c3fSmrg   dst.File      = file;
102001e04c3fSmrg   dst.WriteMask = TGSI_WRITEMASK_XYZW;
102101e04c3fSmrg   dst.Indirect  = 0;
102201e04c3fSmrg   dst.IndirectFile = TGSI_FILE_NULL;
102301e04c3fSmrg   dst.IndirectIndex = 0;
102401e04c3fSmrg   dst.IndirectSwizzle = 0;
102501e04c3fSmrg   dst.Saturate  = 0;
102601e04c3fSmrg   dst.Index     = index;
102701e04c3fSmrg   dst.Dimension = 0;
102801e04c3fSmrg   dst.DimensionIndex = 0;
102901e04c3fSmrg   dst.DimIndirect = 0;
103001e04c3fSmrg   dst.DimIndFile = TGSI_FILE_NULL;
103101e04c3fSmrg   dst.DimIndIndex = 0;
103201e04c3fSmrg   dst.DimIndSwizzle = 0;
103301e04c3fSmrg   dst.ArrayID = array_id;
103401e04c3fSmrg   dst.Invariant = 0;
103501e04c3fSmrg
103601e04c3fSmrg   return dst;
103701e04c3fSmrg}
103801e04c3fSmrg
103901e04c3fSmrgstatic inline struct ureg_dst
104001e04c3fSmrgureg_dst_register(unsigned file,
104101e04c3fSmrg                  unsigned index)
104201e04c3fSmrg{
104301e04c3fSmrg   return ureg_dst_array_register(file, index, 0);
104401e04c3fSmrg}
104501e04c3fSmrg
104601e04c3fSmrgstatic inline struct ureg_dst
104701e04c3fSmrgureg_dst( struct ureg_src src )
104801e04c3fSmrg{
104901e04c3fSmrg   struct ureg_dst dst;
1050cdc920a0Smrg
10514a49301eSmrg   dst.File      = src.File;
10524a49301eSmrg   dst.WriteMask = TGSI_WRITEMASK_XYZW;
1053af69d88dSmrg   dst.IndirectFile = src.IndirectFile;
10544a49301eSmrg   dst.Indirect  = src.Indirect;
10554a49301eSmrg   dst.IndirectIndex = src.IndirectIndex;
10564a49301eSmrg   dst.IndirectSwizzle = src.IndirectSwizzle;
10574a49301eSmrg   dst.Saturate  = 0;
10584a49301eSmrg   dst.Index     = src.Index;
105901e04c3fSmrg   dst.Dimension = src.Dimension;
106001e04c3fSmrg   dst.DimensionIndex = src.DimensionIndex;
106101e04c3fSmrg   dst.DimIndirect = src.DimIndirect;
106201e04c3fSmrg   dst.DimIndFile = src.DimIndFile;
106301e04c3fSmrg   dst.DimIndIndex = src.DimIndIndex;
106401e04c3fSmrg   dst.DimIndSwizzle = src.DimIndSwizzle;
1065af69d88dSmrg   dst.ArrayID = src.ArrayID;
106601e04c3fSmrg   dst.Invariant = 0;
10674a49301eSmrg
10684a49301eSmrg   return dst;
10694a49301eSmrg}
10704a49301eSmrg
107101e04c3fSmrgstatic inline struct ureg_src
107201e04c3fSmrgureg_src_array_register(unsigned file,
107301e04c3fSmrg                        unsigned index,
107401e04c3fSmrg                        unsigned array_id)
1075cdc920a0Smrg{
1076cdc920a0Smrg   struct ureg_src src;
1077cdc920a0Smrg
1078cdc920a0Smrg   src.File = file;
1079cdc920a0Smrg   src.SwizzleX = TGSI_SWIZZLE_X;
1080cdc920a0Smrg   src.SwizzleY = TGSI_SWIZZLE_Y;
1081cdc920a0Smrg   src.SwizzleZ = TGSI_SWIZZLE_Z;
1082cdc920a0Smrg   src.SwizzleW = TGSI_SWIZZLE_W;
1083cdc920a0Smrg   src.Indirect = 0;
1084cdc920a0Smrg   src.IndirectFile = TGSI_FILE_NULL;
1085cdc920a0Smrg   src.IndirectIndex = 0;
1086cdc920a0Smrg   src.IndirectSwizzle = 0;
1087cdc920a0Smrg   src.Absolute = 0;
1088cdc920a0Smrg   src.Index = index;
1089cdc920a0Smrg   src.Negate = 0;
1090cdc920a0Smrg   src.Dimension = 0;
1091cdc920a0Smrg   src.DimensionIndex = 0;
10923464ebd5Sriastradh   src.DimIndirect = 0;
10933464ebd5Sriastradh   src.DimIndFile = TGSI_FILE_NULL;
10943464ebd5Sriastradh   src.DimIndIndex = 0;
10953464ebd5Sriastradh   src.DimIndSwizzle = 0;
109601e04c3fSmrg   src.ArrayID = array_id;
1097cdc920a0Smrg
1098cdc920a0Smrg   return src;
1099cdc920a0Smrg}
1100cdc920a0Smrg
110101e04c3fSmrgstatic inline struct ureg_src
110201e04c3fSmrgureg_src_register(unsigned file,
110301e04c3fSmrg                  unsigned index)
110401e04c3fSmrg{
110501e04c3fSmrg   return ureg_src_array_register(file, index, 0);
110601e04c3fSmrg}
110701e04c3fSmrg
110801e04c3fSmrgstatic inline struct ureg_src
11094a49301eSmrgureg_src( struct ureg_dst dst )
11104a49301eSmrg{
11114a49301eSmrg   struct ureg_src src;
11124a49301eSmrg
11134a49301eSmrg   src.File      = dst.File;
11144a49301eSmrg   src.SwizzleX  = TGSI_SWIZZLE_X;
11154a49301eSmrg   src.SwizzleY  = TGSI_SWIZZLE_Y;
11164a49301eSmrg   src.SwizzleZ  = TGSI_SWIZZLE_Z;
11174a49301eSmrg   src.SwizzleW  = TGSI_SWIZZLE_W;
11184a49301eSmrg   src.Indirect  = dst.Indirect;
1119af69d88dSmrg   src.IndirectFile = dst.IndirectFile;
11204a49301eSmrg   src.IndirectIndex = dst.IndirectIndex;
11214a49301eSmrg   src.IndirectSwizzle = dst.IndirectSwizzle;
11224a49301eSmrg   src.Absolute  = 0;
11234a49301eSmrg   src.Index     = dst.Index;
11244a49301eSmrg   src.Negate    = 0;
112501e04c3fSmrg   src.Dimension = dst.Dimension;
112601e04c3fSmrg   src.DimensionIndex = dst.DimensionIndex;
112701e04c3fSmrg   src.DimIndirect = dst.DimIndirect;
112801e04c3fSmrg   src.DimIndFile = dst.DimIndFile;
112901e04c3fSmrg   src.DimIndIndex = dst.DimIndIndex;
113001e04c3fSmrg   src.DimIndSwizzle = dst.DimIndSwizzle;
1131af69d88dSmrg   src.ArrayID = dst.ArrayID;
11324a49301eSmrg
11334a49301eSmrg   return src;
11344a49301eSmrg}
11354a49301eSmrg
11364a49301eSmrg
11374a49301eSmrg
113801e04c3fSmrgstatic inline struct ureg_dst
11394a49301eSmrgureg_dst_undef( void )
11404a49301eSmrg{
11414a49301eSmrg   struct ureg_dst dst;
11424a49301eSmrg
11434a49301eSmrg   dst.File      = TGSI_FILE_NULL;
11444a49301eSmrg   dst.WriteMask = 0;
11454a49301eSmrg   dst.Indirect  = 0;
1146af69d88dSmrg   dst.IndirectFile = TGSI_FILE_NULL;
11474a49301eSmrg   dst.IndirectIndex = 0;
11484a49301eSmrg   dst.IndirectSwizzle = 0;
11494a49301eSmrg   dst.Saturate  = 0;
11504a49301eSmrg   dst.Index     = 0;
115101e04c3fSmrg   dst.Dimension = 0;
115201e04c3fSmrg   dst.DimensionIndex = 0;
115301e04c3fSmrg   dst.DimIndirect = 0;
115401e04c3fSmrg   dst.DimIndFile = TGSI_FILE_NULL;
115501e04c3fSmrg   dst.DimIndIndex = 0;
115601e04c3fSmrg   dst.DimIndSwizzle = 0;
1157af69d88dSmrg   dst.ArrayID = 0;
115801e04c3fSmrg   dst.Invariant = 0;
11594a49301eSmrg
11604a49301eSmrg   return dst;
11614a49301eSmrg}
11624a49301eSmrg
116301e04c3fSmrgstatic inline struct ureg_src
11644a49301eSmrgureg_src_undef( void )
11654a49301eSmrg{
11664a49301eSmrg   struct ureg_src src;
11674a49301eSmrg
11684a49301eSmrg   src.File      = TGSI_FILE_NULL;
11694a49301eSmrg   src.SwizzleX  = 0;
11704a49301eSmrg   src.SwizzleY  = 0;
11714a49301eSmrg   src.SwizzleZ  = 0;
11724a49301eSmrg   src.SwizzleW  = 0;
11734a49301eSmrg   src.Indirect  = 0;
1174cdc920a0Smrg   src.IndirectFile = TGSI_FILE_NULL;
11754a49301eSmrg   src.IndirectIndex = 0;
11764a49301eSmrg   src.IndirectSwizzle = 0;
11774a49301eSmrg   src.Absolute  = 0;
11784a49301eSmrg   src.Index     = 0;
11794a49301eSmrg   src.Negate    = 0;
1180cdc920a0Smrg   src.Dimension = 0;
1181cdc920a0Smrg   src.DimensionIndex = 0;
11823464ebd5Sriastradh   src.DimIndirect = 0;
11833464ebd5Sriastradh   src.DimIndFile = TGSI_FILE_NULL;
11843464ebd5Sriastradh   src.DimIndIndex = 0;
11853464ebd5Sriastradh   src.DimIndSwizzle = 0;
1186af69d88dSmrg   src.ArrayID = 0;
11873464ebd5Sriastradh
11884a49301eSmrg   return src;
11894a49301eSmrg}
11904a49301eSmrg
119101e04c3fSmrgstatic inline boolean
11924a49301eSmrgureg_src_is_undef( struct ureg_src src )
11934a49301eSmrg{
11944a49301eSmrg   return src.File == TGSI_FILE_NULL;
11954a49301eSmrg}
11964a49301eSmrg
119701e04c3fSmrgstatic inline boolean
11984a49301eSmrgureg_dst_is_undef( struct ureg_dst dst )
11994a49301eSmrg{
12004a49301eSmrg   return dst.File == TGSI_FILE_NULL;
12014a49301eSmrg}
12024a49301eSmrg
12037ec681f3Smrgvoid
12047ec681f3Smrgureg_setup_shader_info(struct ureg_program *ureg,
12057ec681f3Smrg                       const struct shader_info *info);
12064a49301eSmrg
12074a49301eSmrg#ifdef __cplusplus
12084a49301eSmrg}
12094a49301eSmrg#endif
12104a49301eSmrg
12114a49301eSmrg#endif
1212