2010-03-10 21:58:12 +00:00
|
|
|
/* -*- c++ -*- */
|
2010-02-22 21:19:34 +00:00
|
|
|
/*
|
|
|
|
* Copyright © 2010 Intel Corporation
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
* Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2010-03-15 22:20:15 +00:00
|
|
|
#pragma once
|
|
|
|
#ifndef IR_H
|
|
|
|
#define IR_H
|
|
|
|
|
2010-03-09 07:44:00 +00:00
|
|
|
#include "list.h"
|
2010-03-10 00:23:37 +00:00
|
|
|
#include "ir_visitor.h"
|
2010-05-14 20:39:23 +01:00
|
|
|
#include "ir_hierarchical_visitor.h"
|
2010-03-09 07:44:00 +00:00
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
struct ir_program {
|
|
|
|
void *bong_hits;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Base class of all IR instructions
|
|
|
|
*/
|
2010-03-09 07:44:00 +00:00
|
|
|
class ir_instruction : public exec_node {
|
2010-02-22 21:19:34 +00:00
|
|
|
public:
|
|
|
|
const struct glsl_type *type;
|
|
|
|
|
2010-03-31 00:56:50 +01:00
|
|
|
class ir_constant *constant_expression_value();
|
2010-03-10 00:23:37 +00:00
|
|
|
virtual void accept(ir_visitor *) = 0;
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0;
|
2010-03-10 00:23:37 +00:00
|
|
|
|
2010-03-26 06:30:28 +00:00
|
|
|
/**
|
|
|
|
* \name IR instruction downcast functions
|
|
|
|
*
|
|
|
|
* These functions either cast the object to a derived class or return
|
|
|
|
* \c NULL if the object's type does not match the specified derived class.
|
|
|
|
* Additional downcast functions will be added as needed.
|
|
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
virtual class ir_variable * as_variable() { return NULL; }
|
2010-04-22 00:02:15 +01:00
|
|
|
virtual class ir_function * as_function() { return NULL; }
|
2010-03-26 06:30:28 +00:00
|
|
|
virtual class ir_dereference * as_dereference() { return NULL; }
|
2010-05-11 19:31:09 +01:00
|
|
|
virtual class ir_dereference_array * as_dereference_array() { return NULL; }
|
2010-03-26 07:25:36 +00:00
|
|
|
virtual class ir_rvalue * as_rvalue() { return NULL; }
|
2010-04-17 00:43:47 +01:00
|
|
|
virtual class ir_label * as_label() { return NULL; }
|
2010-04-06 01:13:14 +01:00
|
|
|
virtual class ir_loop * as_loop() { return NULL; }
|
2010-04-07 19:46:26 +01:00
|
|
|
virtual class ir_assignment * as_assignment() { return NULL; }
|
|
|
|
virtual class ir_call * as_call() { return NULL; }
|
|
|
|
virtual class ir_return * as_return() { return NULL; }
|
2010-04-15 01:03:03 +01:00
|
|
|
virtual class ir_if * as_if() { return NULL; }
|
2010-04-17 00:43:47 +01:00
|
|
|
virtual class ir_swizzle * as_swizzle() { return NULL; }
|
2010-05-04 21:04:40 +01:00
|
|
|
virtual class ir_constant * as_constant() { return NULL; }
|
2010-03-26 06:30:28 +00:00
|
|
|
/*@}*/
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
protected:
|
2010-03-26 06:30:28 +00:00
|
|
|
ir_instruction()
|
2010-03-11 22:23:41 +00:00
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
2010-02-22 21:19:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
class ir_rvalue : public ir_instruction {
|
|
|
|
public:
|
|
|
|
virtual ir_rvalue * as_rvalue()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool is_lvalue()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-05-15 01:35:42 +01:00
|
|
|
/**
|
|
|
|
* Get the variable that is ultimately referenced by an r-value
|
|
|
|
*/
|
|
|
|
virtual ir_variable *variable_referenced()
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-05-26 19:32:52 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* If an r-value is a reference to a whole variable, get that variable
|
|
|
|
*
|
|
|
|
* \return
|
|
|
|
* Pointer to a variable that is completely dereferenced by the r-value. If
|
|
|
|
* the r-value is not a dereference or the dereference does not access the
|
|
|
|
* entire variable (i.e., it's just one array element, struct field), \c NULL
|
|
|
|
* is returned.
|
|
|
|
*/
|
|
|
|
virtual ir_variable *whole_variable_referenced()
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
protected:
|
2010-04-08 02:03:50 +01:00
|
|
|
ir_rvalue()
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
2010-03-26 07:25:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
enum ir_variable_mode {
|
|
|
|
ir_var_auto = 0,
|
|
|
|
ir_var_uniform,
|
|
|
|
ir_var_in,
|
|
|
|
ir_var_out,
|
|
|
|
ir_var_inout
|
|
|
|
};
|
|
|
|
|
|
|
|
enum ir_varaible_interpolation {
|
|
|
|
ir_var_smooth = 0,
|
|
|
|
ir_var_flat,
|
|
|
|
ir_var_noperspective
|
|
|
|
};
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
class ir_variable : public ir_instruction {
|
|
|
|
public:
|
|
|
|
ir_variable(const struct glsl_type *, const char *);
|
|
|
|
|
2010-03-26 06:30:28 +00:00
|
|
|
virtual ir_variable *as_variable()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-03-10 00:23:37 +00:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-04-01 01:52:44 +01:00
|
|
|
/**
|
|
|
|
* Duplicate an IR variable
|
|
|
|
*
|
|
|
|
* \note
|
|
|
|
* This will probably be made \c virtual and moved to the base class
|
|
|
|
* eventually.
|
|
|
|
*/
|
|
|
|
ir_variable *clone() const
|
|
|
|
{
|
|
|
|
ir_variable *var = new ir_variable(type, name);
|
|
|
|
|
2010-04-02 02:31:11 +01:00
|
|
|
var->max_array_access = this->max_array_access;
|
2010-04-01 01:52:44 +01:00
|
|
|
var->read_only = this->read_only;
|
|
|
|
var->centroid = this->centroid;
|
|
|
|
var->invariant = this->invariant;
|
|
|
|
var->mode = this->mode;
|
|
|
|
var->interpolation = this->interpolation;
|
|
|
|
|
|
|
|
return var;
|
|
|
|
}
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
const char *name;
|
|
|
|
|
2010-04-02 02:31:11 +01:00
|
|
|
/**
|
|
|
|
* Highest element accessed with a constant expression array index
|
|
|
|
*
|
|
|
|
* Not used for non-array variables.
|
|
|
|
*/
|
|
|
|
unsigned max_array_access;
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
unsigned read_only:1;
|
|
|
|
unsigned centroid:1;
|
|
|
|
unsigned invariant:1;
|
2010-04-19 19:10:37 +01:00
|
|
|
/** If the variable is initialized outside of the scope of the shader */
|
|
|
|
unsigned shader_in:1;
|
|
|
|
/**
|
|
|
|
* If the variable value is later used outside of the scope of the shader.
|
|
|
|
*/
|
|
|
|
unsigned shader_out:1;
|
2010-02-22 21:19:34 +00:00
|
|
|
|
|
|
|
unsigned mode:3;
|
|
|
|
unsigned interpolation:2;
|
2010-04-03 01:17:47 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Flag that the whole array is assignable
|
|
|
|
*
|
|
|
|
* In GLSL 1.20 and later whole arrays are assignable (and comparable for
|
|
|
|
* equality). This flag enables this behavior.
|
|
|
|
*/
|
|
|
|
unsigned array_lvalue:1;
|
2010-04-06 18:30:54 +01:00
|
|
|
|
2010-04-08 00:53:54 +01:00
|
|
|
/**
|
|
|
|
* Emit a warning if this variable is accessed.
|
|
|
|
*/
|
|
|
|
const char *warn_extension;
|
|
|
|
|
2010-04-06 18:30:54 +01:00
|
|
|
/**
|
|
|
|
* Value assigned in the initializer of a variable declared "const"
|
|
|
|
*/
|
|
|
|
ir_constant *constant_value;
|
2010-02-22 21:19:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*@{*/
|
2010-04-21 20:30:22 +01:00
|
|
|
/**
|
|
|
|
* The representation of a function instance; may be the full definition or
|
|
|
|
* simply a prototype.
|
|
|
|
*/
|
2010-02-22 21:19:34 +00:00
|
|
|
class ir_function_signature : public ir_instruction {
|
2010-04-07 21:19:11 +01:00
|
|
|
/* An ir_function_signature will be part of the list of signatures in
|
|
|
|
* an ir_function.
|
|
|
|
*/
|
2010-02-22 21:19:34 +00:00
|
|
|
public:
|
2010-03-23 19:19:13 +00:00
|
|
|
ir_function_signature(const glsl_type *return_type);
|
2010-02-22 21:19:34 +00:00
|
|
|
|
2010-03-10 00:23:37 +00:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-04-01 00:44:12 +01:00
|
|
|
/**
|
|
|
|
* Get the name of the function for which this is a signature
|
|
|
|
*/
|
|
|
|
const char *function_name() const;
|
|
|
|
|
2010-04-28 19:49:12 +01:00
|
|
|
/**
|
|
|
|
* Check whether the qualifiers match between this signature's parameters
|
|
|
|
* and the supplied parameter list. If not, returns the name of the first
|
|
|
|
* parameter with mismatched qualifiers (for use in error messages).
|
|
|
|
*/
|
|
|
|
const char *qualifiers_match(exec_list *params);
|
|
|
|
|
2010-04-28 20:44:24 +01:00
|
|
|
/**
|
|
|
|
* Replace the current parameter list with the given one. This is useful
|
|
|
|
* if the current information came from a prototype, and either has invalid
|
|
|
|
* or missing parameter names.
|
|
|
|
*/
|
|
|
|
void replace_parameters(exec_list *new_params);
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
/**
|
|
|
|
* Function return type.
|
|
|
|
*
|
|
|
|
* \note This discards the optional precision qualifier.
|
|
|
|
*/
|
|
|
|
const struct glsl_type *return_type;
|
|
|
|
|
|
|
|
/**
|
2010-04-07 20:35:34 +01:00
|
|
|
* List of ir_variable of function parameters.
|
|
|
|
*
|
|
|
|
* This represents the storage. The paramaters passed in a particular
|
|
|
|
* call will be in ir_call::actual_paramaters.
|
2010-02-22 21:19:34 +00:00
|
|
|
*/
|
2010-03-09 07:44:00 +00:00
|
|
|
struct exec_list parameters;
|
2010-02-22 21:19:34 +00:00
|
|
|
|
2010-04-21 20:30:22 +01:00
|
|
|
/** Whether or not this function has a body (which may be empty). */
|
|
|
|
unsigned is_defined:1;
|
2010-04-01 00:37:10 +01:00
|
|
|
|
2010-04-07 21:19:11 +01:00
|
|
|
/** Body of instructions in the function. */
|
|
|
|
struct exec_list body;
|
|
|
|
|
2010-04-01 00:37:10 +01:00
|
|
|
private:
|
|
|
|
/** Function of which this signature is one overload. */
|
|
|
|
class ir_function *function;
|
|
|
|
|
|
|
|
friend class ir_function;
|
2010-02-22 21:19:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2010-04-21 20:30:22 +01:00
|
|
|
* Header for tracking multiple overloaded functions with the same name.
|
|
|
|
* Contains a list of ir_function_signatures representing each of the
|
|
|
|
* actual functions.
|
2010-02-22 21:19:34 +00:00
|
|
|
*/
|
|
|
|
class ir_function : public ir_instruction {
|
|
|
|
public:
|
2010-03-24 00:42:04 +00:00
|
|
|
ir_function(const char *name);
|
2010-02-22 21:19:34 +00:00
|
|
|
|
2010-04-22 00:02:15 +01:00
|
|
|
virtual ir_function *as_function()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-03-10 00:23:37 +00:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-04-01 00:37:10 +01:00
|
|
|
void add_signature(ir_function_signature *sig)
|
|
|
|
{
|
|
|
|
sig->function = this;
|
|
|
|
signatures.push_tail(sig);
|
|
|
|
}
|
|
|
|
|
2010-04-01 00:40:26 +01:00
|
|
|
/**
|
|
|
|
* Get an iterator for the set of function signatures
|
|
|
|
*/
|
|
|
|
exec_list_iterator iterator()
|
|
|
|
{
|
|
|
|
return signatures.iterator();
|
|
|
|
}
|
|
|
|
|
2010-03-11 22:50:30 +00:00
|
|
|
/**
|
2010-04-28 20:04:23 +01:00
|
|
|
* Find a signature that matches a set of actual parameters, taking implicit
|
|
|
|
* conversions into account.
|
2010-03-11 22:50:30 +00:00
|
|
|
*/
|
|
|
|
const ir_function_signature *matching_signature(exec_list *actual_param);
|
|
|
|
|
2010-04-28 20:04:23 +01:00
|
|
|
/**
|
|
|
|
* Find a signature that exactly matches a set of actual parameters without
|
|
|
|
* any implicit type conversions.
|
|
|
|
*/
|
|
|
|
ir_function_signature *exact_matching_signature(exec_list *actual_ps);
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
/**
|
|
|
|
* Name of the function.
|
|
|
|
*/
|
|
|
|
const char *name;
|
|
|
|
|
2010-04-01 00:40:58 +01:00
|
|
|
private:
|
2010-03-11 22:50:30 +00:00
|
|
|
/**
|
2010-04-07 20:35:34 +01:00
|
|
|
* List of ir_function_signature for each overloaded function with this name.
|
2010-03-11 22:50:30 +00:00
|
|
|
*/
|
2010-03-09 07:44:00 +00:00
|
|
|
struct exec_list signatures;
|
2010-02-22 21:19:34 +00:00
|
|
|
};
|
2010-04-01 00:44:12 +01:00
|
|
|
|
|
|
|
inline const char *ir_function_signature::function_name() const
|
|
|
|
{
|
|
|
|
return function->name;
|
|
|
|
}
|
2010-02-22 21:19:34 +00:00
|
|
|
/*@}*/
|
|
|
|
|
|
|
|
|
2010-03-29 22:11:25 +01:00
|
|
|
/**
|
|
|
|
* IR instruction representing high-level if-statements
|
|
|
|
*/
|
|
|
|
class ir_if : public ir_instruction {
|
|
|
|
public:
|
|
|
|
ir_if(ir_rvalue *condition)
|
|
|
|
: condition(condition)
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
2010-04-15 01:03:03 +01:00
|
|
|
virtual ir_if *as_if()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-03-29 22:11:25 +01:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-03-29 22:11:25 +01:00
|
|
|
ir_rvalue *condition;
|
2010-04-07 20:35:34 +01:00
|
|
|
/** List of ir_instruction for the body of the then branch */
|
2010-03-29 22:11:25 +01:00
|
|
|
exec_list then_instructions;
|
2010-04-07 20:35:34 +01:00
|
|
|
/** List of ir_instruction for the body of the else branch */
|
2010-03-29 22:11:25 +01:00
|
|
|
exec_list else_instructions;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-04-06 00:16:07 +01:00
|
|
|
/**
|
|
|
|
* IR instruction representing a high-level loop structure.
|
|
|
|
*/
|
|
|
|
class ir_loop : public ir_instruction {
|
|
|
|
public:
|
|
|
|
ir_loop() : from(NULL), to(NULL), increment(NULL), counter(NULL)
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-04-06 01:13:14 +01:00
|
|
|
virtual ir_loop *as_loop()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-04-06 00:16:07 +01:00
|
|
|
/**
|
|
|
|
* Get an iterator for the instructions of the loop body
|
|
|
|
*/
|
|
|
|
exec_list_iterator iterator()
|
|
|
|
{
|
|
|
|
return body_instructions.iterator();
|
|
|
|
}
|
|
|
|
|
2010-04-07 20:35:34 +01:00
|
|
|
/** List of ir_instruction that make up the body of the loop. */
|
2010-04-06 00:16:07 +01:00
|
|
|
exec_list body_instructions;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Loop counter and controls
|
|
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
ir_rvalue *from;
|
|
|
|
ir_rvalue *to;
|
|
|
|
ir_rvalue *increment;
|
|
|
|
ir_variable *counter;
|
|
|
|
/*@}*/
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
class ir_assignment : public ir_rvalue {
|
2010-02-22 21:19:34 +00:00
|
|
|
public:
|
2010-03-26 07:25:36 +00:00
|
|
|
ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
|
2010-02-22 21:19:34 +00:00
|
|
|
|
2010-03-10 00:23:37 +00:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-04-07 19:46:26 +01:00
|
|
|
virtual ir_assignment * as_assignment()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
/**
|
|
|
|
* Left-hand side of the assignment.
|
|
|
|
*/
|
2010-03-26 07:25:36 +00:00
|
|
|
ir_rvalue *lhs;
|
2010-02-22 21:19:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Value being assigned
|
|
|
|
*/
|
2010-03-26 07:25:36 +00:00
|
|
|
ir_rvalue *rhs;
|
2010-02-22 21:19:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Optional condition for the assignment.
|
|
|
|
*/
|
2010-03-26 07:25:36 +00:00
|
|
|
ir_rvalue *condition;
|
2010-02-22 21:19:34 +00:00
|
|
|
};
|
|
|
|
|
2010-04-08 01:18:29 +01:00
|
|
|
/* Update ir_expression::num_operands() and operator_strs when
|
2010-04-02 05:07:08 +01:00
|
|
|
* updating this list.
|
2010-04-08 01:18:29 +01:00
|
|
|
*/
|
2010-02-22 21:19:34 +00:00
|
|
|
enum ir_expression_operation {
|
|
|
|
ir_unop_bit_not,
|
|
|
|
ir_unop_logic_not,
|
|
|
|
ir_unop_neg,
|
|
|
|
ir_unop_abs,
|
2010-05-04 04:05:57 +01:00
|
|
|
ir_unop_sign,
|
2010-02-22 21:19:34 +00:00
|
|
|
ir_unop_rcp,
|
|
|
|
ir_unop_rsq,
|
2010-03-27 20:01:51 +00:00
|
|
|
ir_unop_sqrt,
|
2010-02-22 21:19:34 +00:00
|
|
|
ir_unop_exp,
|
|
|
|
ir_unop_log,
|
2010-03-27 20:56:35 +00:00
|
|
|
ir_unop_exp2,
|
|
|
|
ir_unop_log2,
|
2010-02-22 21:19:34 +00:00
|
|
|
ir_unop_f2i, /**< Float-to-integer conversion. */
|
|
|
|
ir_unop_i2f, /**< Integer-to-float conversion. */
|
2010-04-02 13:13:43 +01:00
|
|
|
ir_unop_f2b, /**< Float-to-boolean conversion */
|
|
|
|
ir_unop_b2f, /**< Boolean-to-float conversion */
|
2010-04-02 13:17:08 +01:00
|
|
|
ir_unop_i2b, /**< int-to-boolean conversion */
|
|
|
|
ir_unop_b2i, /**< Boolean-to-int conversion */
|
2010-03-26 23:11:48 +00:00
|
|
|
ir_unop_u2f, /**< Unsigned-to-float conversion. */
|
2010-02-22 21:19:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Unary floating-point rounding operations.
|
|
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
ir_unop_trunc,
|
|
|
|
ir_unop_ceil,
|
|
|
|
ir_unop_floor,
|
|
|
|
/*@}*/
|
|
|
|
|
2010-05-04 06:11:17 +01:00
|
|
|
/**
|
|
|
|
* \name Trigonometric operations.
|
|
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
ir_unop_sin,
|
|
|
|
ir_unop_cos,
|
|
|
|
/*@}*/
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
ir_binop_add,
|
|
|
|
ir_binop_sub,
|
|
|
|
ir_binop_mul,
|
|
|
|
ir_binop_div,
|
|
|
|
ir_binop_mod,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Binary comparison operators
|
|
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
ir_binop_less,
|
|
|
|
ir_binop_greater,
|
|
|
|
ir_binop_lequal,
|
|
|
|
ir_binop_gequal,
|
|
|
|
ir_binop_equal,
|
|
|
|
ir_binop_nequal,
|
|
|
|
/*@}*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \name Bit-wise binary operations.
|
|
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
ir_binop_lshift,
|
|
|
|
ir_binop_rshift,
|
|
|
|
ir_binop_bit_and,
|
|
|
|
ir_binop_bit_xor,
|
|
|
|
ir_binop_bit_or,
|
|
|
|
/*@}*/
|
|
|
|
|
|
|
|
ir_binop_logic_and,
|
|
|
|
ir_binop_logic_xor,
|
|
|
|
ir_binop_logic_or,
|
|
|
|
|
|
|
|
ir_binop_dot,
|
|
|
|
ir_binop_min,
|
|
|
|
ir_binop_max,
|
|
|
|
|
|
|
|
ir_binop_pow
|
|
|
|
};
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
class ir_expression : public ir_rvalue {
|
2010-02-22 21:19:34 +00:00
|
|
|
public:
|
|
|
|
ir_expression(int op, const struct glsl_type *type,
|
2010-03-26 07:25:36 +00:00
|
|
|
ir_rvalue *, ir_rvalue *);
|
2010-02-22 21:19:34 +00:00
|
|
|
|
2010-04-08 00:56:57 +01:00
|
|
|
static unsigned int get_num_operands(ir_expression_operation);
|
|
|
|
unsigned int get_num_operands()
|
|
|
|
{
|
|
|
|
return get_num_operands(operation);
|
|
|
|
}
|
2010-04-02 05:07:08 +01:00
|
|
|
|
2010-04-08 01:18:29 +01:00
|
|
|
/**
|
|
|
|
* Return a string representing this expression's operator.
|
|
|
|
*/
|
|
|
|
const char *operator_string();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Do a reverse-lookup to translate the given string into an operator.
|
|
|
|
*/
|
|
|
|
static ir_expression_operation get_operator(const char *);
|
|
|
|
|
2010-03-10 00:23:37 +00:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-04-07 19:46:26 +01:00
|
|
|
ir_expression *clone();
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
ir_expression_operation operation;
|
2010-03-26 07:25:36 +00:00
|
|
|
ir_rvalue *operands[2];
|
2010-02-22 21:19:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-03-11 22:34:27 +00:00
|
|
|
/**
|
|
|
|
* IR instruction representing a function call
|
|
|
|
*/
|
2010-03-26 07:25:36 +00:00
|
|
|
class ir_call : public ir_rvalue {
|
2010-03-11 22:34:27 +00:00
|
|
|
public:
|
2010-03-11 22:50:30 +00:00
|
|
|
ir_call(const ir_function_signature *callee, exec_list *actual_parameters)
|
2010-04-08 02:03:50 +01:00
|
|
|
: callee(callee)
|
2010-03-11 22:34:27 +00:00
|
|
|
{
|
2010-03-23 19:21:18 +00:00
|
|
|
assert(callee->return_type != NULL);
|
|
|
|
type = callee->return_type;
|
2010-03-11 22:50:30 +00:00
|
|
|
actual_parameters->move_nodes_to(& this->actual_parameters);
|
2010-03-11 22:34:27 +00:00
|
|
|
}
|
|
|
|
|
2010-04-07 19:46:26 +01:00
|
|
|
virtual ir_call *as_call()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-03-11 22:34:27 +00:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-03-11 22:34:27 +00:00
|
|
|
/**
|
|
|
|
* Get a generic ir_call object when an error occurs
|
|
|
|
*/
|
|
|
|
static ir_call *get_error_instruction();
|
|
|
|
|
2010-03-27 00:19:47 +00:00
|
|
|
/**
|
|
|
|
* Get an iterator for the set of acutal parameters
|
|
|
|
*/
|
|
|
|
exec_list_iterator iterator()
|
|
|
|
{
|
|
|
|
return actual_parameters.iterator();
|
|
|
|
}
|
|
|
|
|
2010-03-27 00:29:29 +00:00
|
|
|
/**
|
|
|
|
* Get the name of the function being called.
|
|
|
|
*/
|
|
|
|
const char *callee_name() const
|
|
|
|
{
|
2010-04-01 00:44:12 +01:00
|
|
|
return callee->function_name();
|
2010-03-27 00:29:29 +00:00
|
|
|
}
|
|
|
|
|
2010-04-07 19:46:26 +01:00
|
|
|
const ir_function_signature *get_callee()
|
|
|
|
{
|
|
|
|
return callee;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generates an inline version of the function before @ir,
|
|
|
|
* returning the return value of the function.
|
|
|
|
*/
|
|
|
|
ir_rvalue *generate_inline(ir_instruction *ir);
|
|
|
|
|
2010-03-11 22:34:27 +00:00
|
|
|
private:
|
2010-03-11 22:50:30 +00:00
|
|
|
ir_call()
|
2010-04-08 02:03:50 +01:00
|
|
|
: callee(NULL)
|
2010-03-11 22:50:30 +00:00
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
const ir_function_signature *callee;
|
2010-04-07 20:35:34 +01:00
|
|
|
|
|
|
|
/* List of ir_rvalue of paramaters passed in this call. */
|
2010-03-11 22:34:27 +00:00
|
|
|
exec_list actual_parameters;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-03-19 23:44:52 +00:00
|
|
|
/**
|
|
|
|
* \name Jump-like IR instructions.
|
|
|
|
*
|
|
|
|
* These include \c break, \c continue, \c return, and \c discard.
|
|
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
class ir_jump : public ir_instruction {
|
|
|
|
protected:
|
|
|
|
ir_jump()
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class ir_return : public ir_jump {
|
|
|
|
public:
|
|
|
|
ir_return()
|
|
|
|
: value(NULL)
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
ir_return(ir_rvalue *value)
|
2010-03-19 23:44:52 +00:00
|
|
|
: value(value)
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
2010-04-07 19:46:26 +01:00
|
|
|
virtual ir_return *as_return()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
ir_rvalue *get_value() const
|
2010-03-19 23:44:52 +00:00
|
|
|
{
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
ir_rvalue *value;
|
2010-03-19 23:44:52 +00:00
|
|
|
};
|
2010-04-06 00:28:15 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Jump instructions used inside loops
|
|
|
|
*
|
|
|
|
* These include \c break and \c continue. The \c break within a loop is
|
|
|
|
* different from the \c break within a switch-statement.
|
|
|
|
*
|
|
|
|
* \sa ir_switch_jump
|
|
|
|
*/
|
|
|
|
class ir_loop_jump : public ir_jump {
|
|
|
|
public:
|
|
|
|
enum jump_mode {
|
|
|
|
jump_break,
|
|
|
|
jump_continue
|
|
|
|
};
|
|
|
|
|
|
|
|
ir_loop_jump(ir_loop *loop, jump_mode mode)
|
|
|
|
: loop(loop), mode(mode)
|
|
|
|
{
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-04-06 00:28:15 +01:00
|
|
|
bool is_break() const
|
|
|
|
{
|
|
|
|
return mode == jump_break;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool is_continue() const
|
|
|
|
{
|
|
|
|
return mode == jump_continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
/** Loop containing this break instruction. */
|
|
|
|
ir_loop *loop;
|
|
|
|
|
|
|
|
/** Mode selector for the jump instruction. */
|
|
|
|
enum jump_mode mode;
|
|
|
|
};
|
2010-03-19 23:44:52 +00:00
|
|
|
/*@}*/
|
|
|
|
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
struct ir_swizzle_mask {
|
|
|
|
unsigned x:2;
|
|
|
|
unsigned y:2;
|
|
|
|
unsigned z:2;
|
|
|
|
unsigned w:2;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Number of components in the swizzle.
|
|
|
|
*/
|
2010-03-25 18:22:42 +00:00
|
|
|
unsigned num_components:3;
|
2010-02-22 21:19:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Does the swizzle contain duplicate components?
|
|
|
|
*
|
|
|
|
* L-value swizzles cannot contain duplicate components.
|
|
|
|
*/
|
|
|
|
unsigned has_duplicates:1;
|
|
|
|
};
|
|
|
|
|
2010-03-26 08:20:08 +00:00
|
|
|
|
|
|
|
class ir_swizzle : public ir_rvalue {
|
|
|
|
public:
|
|
|
|
ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w,
|
|
|
|
unsigned count);
|
2010-05-04 01:08:01 +01:00
|
|
|
ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
|
2010-04-07 19:46:26 +01:00
|
|
|
|
2010-04-17 00:43:47 +01:00
|
|
|
virtual ir_swizzle *as_swizzle()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-04-07 19:46:26 +01:00
|
|
|
ir_swizzle *clone()
|
|
|
|
{
|
|
|
|
return new ir_swizzle(this->val, this->mask);
|
|
|
|
}
|
|
|
|
|
2010-03-26 08:20:08 +00:00
|
|
|
/**
|
|
|
|
* Construct an ir_swizzle from the textual representation. Can fail.
|
|
|
|
*/
|
|
|
|
static ir_swizzle *create(ir_rvalue *, const char *, unsigned vector_length);
|
|
|
|
|
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-03-26 08:20:08 +00:00
|
|
|
bool is_lvalue()
|
|
|
|
{
|
2010-03-28 09:29:18 +01:00
|
|
|
return val->is_lvalue() && !mask.has_duplicates;
|
2010-03-26 08:20:08 +00:00
|
|
|
}
|
|
|
|
|
2010-05-15 01:35:42 +01:00
|
|
|
/**
|
|
|
|
* Get the variable that is ultimately referenced by an r-value
|
|
|
|
*/
|
|
|
|
virtual ir_variable *variable_referenced();
|
|
|
|
|
2010-03-26 08:20:08 +00:00
|
|
|
ir_rvalue *val;
|
|
|
|
ir_swizzle_mask mask;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
class ir_dereference : public ir_rvalue {
|
2010-02-22 21:19:34 +00:00
|
|
|
public:
|
2010-03-26 06:30:28 +00:00
|
|
|
virtual ir_dereference *as_dereference()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-04-02 07:27:35 +01:00
|
|
|
bool is_lvalue();
|
2010-03-26 07:25:36 +00:00
|
|
|
|
2010-05-15 01:35:42 +01:00
|
|
|
/**
|
|
|
|
* Get the variable that is ultimately referenced by an r-value
|
|
|
|
*/
|
2010-05-19 10:37:35 +01:00
|
|
|
virtual ir_variable *variable_referenced() = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ir_dereference_variable : public ir_dereference {
|
|
|
|
public:
|
|
|
|
ir_dereference_variable(ir_variable *var);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the variable that is ultimately referenced by an r-value
|
|
|
|
*/
|
|
|
|
virtual ir_variable *variable_referenced()
|
|
|
|
{
|
2010-05-19 12:52:29 +01:00
|
|
|
return this->var;
|
2010-05-19 10:37:35 +01:00
|
|
|
}
|
2010-05-19 11:02:19 +01:00
|
|
|
|
2010-05-26 19:32:52 +01:00
|
|
|
virtual ir_variable *whole_variable_referenced()
|
|
|
|
{
|
|
|
|
/* ir_dereference_variable objects always dereference the entire
|
|
|
|
* variable. However, if this dereference is dereferenced by anything
|
|
|
|
* else, the complete deferefernce chain is not a whole-variable
|
|
|
|
* dereference. This method should only be called on the top most
|
|
|
|
* ir_rvalue in a dereference chain.
|
|
|
|
*/
|
|
|
|
return this->var;
|
|
|
|
}
|
|
|
|
|
2010-05-19 12:20:12 +01:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-19 11:02:19 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
2010-05-19 12:52:29 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Object being dereferenced.
|
|
|
|
*/
|
|
|
|
ir_variable *var;
|
2010-05-19 10:37:35 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ir_dereference_array : public ir_dereference {
|
|
|
|
public:
|
|
|
|
ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index);
|
|
|
|
|
|
|
|
ir_dereference_array(ir_variable *var, ir_rvalue *array_index);
|
|
|
|
|
2010-05-11 19:31:09 +01:00
|
|
|
virtual ir_dereference_array *as_dereference_array()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-05-19 10:37:35 +01:00
|
|
|
/**
|
|
|
|
* Get the variable that is ultimately referenced by an r-value
|
|
|
|
*/
|
|
|
|
virtual ir_variable *variable_referenced()
|
|
|
|
{
|
2010-05-19 12:52:29 +01:00
|
|
|
return this->array->variable_referenced();
|
2010-05-19 10:37:35 +01:00
|
|
|
}
|
|
|
|
|
2010-05-19 12:20:12 +01:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-19 11:02:19 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
2010-05-19 10:37:35 +01:00
|
|
|
|
2010-05-19 12:52:29 +01:00
|
|
|
ir_rvalue *array;
|
|
|
|
ir_rvalue *array_index;
|
|
|
|
|
2010-05-19 10:37:35 +01:00
|
|
|
private:
|
|
|
|
void set_array(ir_rvalue *value);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ir_dereference_record : public ir_dereference {
|
|
|
|
public:
|
|
|
|
ir_dereference_record(ir_rvalue *value, const char *field);
|
|
|
|
|
|
|
|
ir_dereference_record(ir_variable *var, const char *field);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the variable that is ultimately referenced by an r-value
|
|
|
|
*/
|
|
|
|
virtual ir_variable *variable_referenced()
|
|
|
|
{
|
2010-05-19 12:52:29 +01:00
|
|
|
return this->record->variable_referenced();
|
2010-05-19 10:37:35 +01:00
|
|
|
}
|
2010-05-19 11:02:19 +01:00
|
|
|
|
2010-05-19 12:20:12 +01:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-19 11:02:19 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
2010-05-19 12:52:29 +01:00
|
|
|
|
|
|
|
ir_rvalue *record;
|
|
|
|
const char *field;
|
2010-02-22 21:19:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-03-26 07:25:36 +00:00
|
|
|
class ir_constant : public ir_rvalue {
|
2010-02-22 21:19:34 +00:00
|
|
|
public:
|
|
|
|
ir_constant(const struct glsl_type *type, const void *data);
|
2010-03-26 19:07:44 +00:00
|
|
|
ir_constant(bool b);
|
|
|
|
ir_constant(unsigned int u);
|
|
|
|
ir_constant(int i);
|
|
|
|
ir_constant(float f);
|
2010-02-22 21:19:34 +00:00
|
|
|
|
2010-05-04 21:04:40 +01:00
|
|
|
virtual ir_constant *as_constant()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2010-03-10 00:23:37 +00:00
|
|
|
virtual void accept(ir_visitor *v)
|
|
|
|
{
|
|
|
|
v->visit(this);
|
|
|
|
}
|
|
|
|
|
2010-05-14 20:39:23 +01:00
|
|
|
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
|
|
|
|
|
2010-04-07 19:46:26 +01:00
|
|
|
ir_constant *clone()
|
|
|
|
{
|
|
|
|
return new ir_constant(this->type, &this->value);
|
|
|
|
}
|
|
|
|
|
2010-02-22 21:19:34 +00:00
|
|
|
/**
|
|
|
|
* Value of the constant.
|
|
|
|
*
|
|
|
|
* The field used to back the values supplied by the constant is determined
|
|
|
|
* by the type associated with the \c ir_instruction. Constants may be
|
|
|
|
* scalars, vectors, or matrices.
|
|
|
|
*/
|
|
|
|
union {
|
|
|
|
unsigned u[16];
|
|
|
|
int i[16];
|
|
|
|
float f[16];
|
|
|
|
bool b[16];
|
|
|
|
} value;
|
|
|
|
};
|
|
|
|
|
2010-04-06 19:52:09 +01:00
|
|
|
void
|
|
|
|
visit_exec_list(exec_list *list, ir_visitor *visitor);
|
2010-03-10 18:43:16 +00:00
|
|
|
|
|
|
|
extern void
|
|
|
|
_mesa_glsl_initialize_variables(exec_list *instructions,
|
|
|
|
struct _mesa_glsl_parse_state *state);
|
2010-03-15 22:20:15 +00:00
|
|
|
|
2010-03-27 01:20:30 +00:00
|
|
|
extern void
|
|
|
|
_mesa_glsl_initialize_functions(exec_list *instructions,
|
|
|
|
struct _mesa_glsl_parse_state *state);
|
|
|
|
|
2010-03-15 22:20:15 +00:00
|
|
|
#endif /* IR_H */
|