17ec681f3Smrg/* -*- c++ -*- */
27ec681f3Smrg/*
37ec681f3Smrg * Copyright © 2010-2016 Intel Corporation
47ec681f3Smrg *
57ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
67ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
77ec681f3Smrg * to deal in the Software without restriction, including without limitation
87ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
97ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
107ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
117ec681f3Smrg *
127ec681f3Smrg * The above copyright notice and this permission notice (including the next
137ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
147ec681f3Smrg * Software.
157ec681f3Smrg *
167ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
177ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
197ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
207ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
217ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
227ec681f3Smrg * IN THE SOFTWARE.
237ec681f3Smrg */
247ec681f3Smrg
257ec681f3Smrg#ifndef BRW_IR_H
267ec681f3Smrg#define BRW_IR_H
277ec681f3Smrg
287ec681f3Smrg#include <assert.h>
297ec681f3Smrg#include "brw_reg.h"
307ec681f3Smrg#include "compiler/glsl/list.h"
317ec681f3Smrg
327ec681f3Smrg#define MAX_SAMPLER_MESSAGE_SIZE 11
337ec681f3Smrg#define MAX_VGRF_SIZE 16
347ec681f3Smrg
357ec681f3Smrg#ifdef __cplusplus
367ec681f3Smrgstruct backend_reg : private brw_reg
377ec681f3Smrg{
387ec681f3Smrg   backend_reg() {}
397ec681f3Smrg   backend_reg(const struct brw_reg &reg) : brw_reg(reg), offset(0) {}
407ec681f3Smrg
417ec681f3Smrg   const brw_reg &as_brw_reg() const
427ec681f3Smrg   {
437ec681f3Smrg      assert(file == ARF || file == FIXED_GRF || file == MRF || file == IMM);
447ec681f3Smrg      assert(offset == 0);
457ec681f3Smrg      return static_cast<const brw_reg &>(*this);
467ec681f3Smrg   }
477ec681f3Smrg
487ec681f3Smrg   brw_reg &as_brw_reg()
497ec681f3Smrg   {
507ec681f3Smrg      assert(file == ARF || file == FIXED_GRF || file == MRF || file == IMM);
517ec681f3Smrg      assert(offset == 0);
527ec681f3Smrg      return static_cast<brw_reg &>(*this);
537ec681f3Smrg   }
547ec681f3Smrg
557ec681f3Smrg   bool equals(const backend_reg &r) const;
567ec681f3Smrg   bool negative_equals(const backend_reg &r) const;
577ec681f3Smrg
587ec681f3Smrg   bool is_zero() const;
597ec681f3Smrg   bool is_one() const;
607ec681f3Smrg   bool is_negative_one() const;
617ec681f3Smrg   bool is_null() const;
627ec681f3Smrg   bool is_accumulator() const;
637ec681f3Smrg
647ec681f3Smrg   /** Offset from the start of the (virtual) register in bytes. */
657ec681f3Smrg   uint16_t offset;
667ec681f3Smrg
677ec681f3Smrg   using brw_reg::type;
687ec681f3Smrg   using brw_reg::file;
697ec681f3Smrg   using brw_reg::negate;
707ec681f3Smrg   using brw_reg::abs;
717ec681f3Smrg   using brw_reg::address_mode;
727ec681f3Smrg   using brw_reg::subnr;
737ec681f3Smrg   using brw_reg::nr;
747ec681f3Smrg
757ec681f3Smrg   using brw_reg::swizzle;
767ec681f3Smrg   using brw_reg::writemask;
777ec681f3Smrg   using brw_reg::indirect_offset;
787ec681f3Smrg   using brw_reg::vstride;
797ec681f3Smrg   using brw_reg::width;
807ec681f3Smrg   using brw_reg::hstride;
817ec681f3Smrg
827ec681f3Smrg   using brw_reg::df;
837ec681f3Smrg   using brw_reg::f;
847ec681f3Smrg   using brw_reg::d;
857ec681f3Smrg   using brw_reg::ud;
867ec681f3Smrg   using brw_reg::d64;
877ec681f3Smrg   using brw_reg::u64;
887ec681f3Smrg};
897ec681f3Smrg
907ec681f3Smrgstruct bblock_t;
917ec681f3Smrg
927ec681f3Smrgstruct backend_instruction : public exec_node {
937ec681f3Smrg   bool is_3src(const struct intel_device_info *devinfo) const;
947ec681f3Smrg   bool is_tex() const;
957ec681f3Smrg   bool is_math() const;
967ec681f3Smrg   bool is_control_flow() const;
977ec681f3Smrg   bool is_commutative() const;
987ec681f3Smrg   bool can_do_source_mods() const;
997ec681f3Smrg   bool can_do_saturate() const;
1007ec681f3Smrg   bool can_do_cmod() const;
1017ec681f3Smrg   bool reads_accumulator_implicitly() const;
1027ec681f3Smrg   bool writes_accumulator_implicitly(const struct intel_device_info *devinfo) const;
1037ec681f3Smrg
1047ec681f3Smrg   /**
1057ec681f3Smrg    * Instructions that use indirect addressing have additional register
1067ec681f3Smrg    * regioning restrictions.
1077ec681f3Smrg    */
1087ec681f3Smrg   bool uses_indirect_addressing() const;
1097ec681f3Smrg
1107ec681f3Smrg   void remove(bblock_t *block, bool defer_later_block_ip_updates = false);
1117ec681f3Smrg   void insert_after(bblock_t *block, backend_instruction *inst);
1127ec681f3Smrg   void insert_before(bblock_t *block, backend_instruction *inst);
1137ec681f3Smrg   void insert_before(bblock_t *block, exec_list *list);
1147ec681f3Smrg
1157ec681f3Smrg   /**
1167ec681f3Smrg    * True if the instruction has side effects other than writing to
1177ec681f3Smrg    * its destination registers.  You are expected not to reorder or
1187ec681f3Smrg    * optimize these out unless you know what you are doing.
1197ec681f3Smrg    */
1207ec681f3Smrg   bool has_side_effects() const;
1217ec681f3Smrg
1227ec681f3Smrg   /**
1237ec681f3Smrg    * True if the instruction might be affected by side effects of other
1247ec681f3Smrg    * instructions.
1257ec681f3Smrg    */
1267ec681f3Smrg   bool is_volatile() const;
1277ec681f3Smrg#else
1287ec681f3Smrgstruct backend_instruction {
1297ec681f3Smrg   struct exec_node link;
1307ec681f3Smrg#endif
1317ec681f3Smrg   /** @{
1327ec681f3Smrg    * Annotation for the generated IR.  One of the two can be set.
1337ec681f3Smrg    */
1347ec681f3Smrg   const void *ir;
1357ec681f3Smrg   const char *annotation;
1367ec681f3Smrg   /** @} */
1377ec681f3Smrg
1387ec681f3Smrg   /**
1397ec681f3Smrg    * Execution size of the instruction.  This is used by the generator to
1407ec681f3Smrg    * generate the correct binary for the given instruction.  Current valid
1417ec681f3Smrg    * values are 1, 4, 8, 16, 32.
1427ec681f3Smrg    */
1437ec681f3Smrg   uint8_t exec_size;
1447ec681f3Smrg
1457ec681f3Smrg   /**
1467ec681f3Smrg    * Channel group from the hardware execution and predication mask that
1477ec681f3Smrg    * should be applied to the instruction.  The subset of channel enable
1487ec681f3Smrg    * signals (calculated from the EU control flow and predication state)
1497ec681f3Smrg    * given by [group, group + exec_size) will be used to mask GRF writes and
1507ec681f3Smrg    * any other side effects of the instruction.
1517ec681f3Smrg    */
1527ec681f3Smrg   uint8_t group;
1537ec681f3Smrg
1547ec681f3Smrg   uint32_t offset; /**< spill/unspill offset or texture offset bitfield */
1557ec681f3Smrg   uint8_t mlen; /**< SEND message length */
1567ec681f3Smrg   uint8_t ex_mlen; /**< SENDS extended message length */
1577ec681f3Smrg   int8_t base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */
1587ec681f3Smrg   uint8_t target; /**< MRT target. */
1597ec681f3Smrg   uint8_t sfid; /**< SFID for SEND instructions */
1607ec681f3Smrg   uint32_t desc; /**< SEND[S] message descriptor immediate */
1617ec681f3Smrg   uint32_t ex_desc; /**< SEND[S] extended message descriptor immediate */
1627ec681f3Smrg   unsigned size_written; /**< Data written to the destination register in bytes. */
1637ec681f3Smrg
1647ec681f3Smrg   enum opcode opcode; /* BRW_OPCODE_* or FS_OPCODE_* */
1657ec681f3Smrg   enum brw_conditional_mod conditional_mod; /**< BRW_CONDITIONAL_* */
1667ec681f3Smrg   enum brw_predicate predicate;
1677ec681f3Smrg   bool predicate_inverse:1;
1687ec681f3Smrg   bool writes_accumulator:1; /**< instruction implicitly writes accumulator */
1697ec681f3Smrg   bool force_writemask_all:1;
1707ec681f3Smrg   bool no_dd_clear:1;
1717ec681f3Smrg   bool no_dd_check:1;
1727ec681f3Smrg   bool saturate:1;
1737ec681f3Smrg   bool shadow_compare:1;
1747ec681f3Smrg   bool check_tdr:1; /**< Only valid for SEND; turns it into a SENDC */
1757ec681f3Smrg   bool send_has_side_effects:1; /**< Only valid for SHADER_OPCODE_SEND */
1767ec681f3Smrg   bool send_is_volatile:1; /**< Only valid for SHADER_OPCODE_SEND */
1777ec681f3Smrg   bool eot:1;
1787ec681f3Smrg
1797ec681f3Smrg   /* Chooses which flag subregister (f0.0 to f1.1) is used for conditional
1807ec681f3Smrg    * mod and predication.
1817ec681f3Smrg    */
1827ec681f3Smrg   unsigned flag_subreg:2;
1837ec681f3Smrg
1847ec681f3Smrg   /** The number of hardware registers used for a message header. */
1857ec681f3Smrg   uint8_t header_size;
1867ec681f3Smrg};
1877ec681f3Smrg
1887ec681f3Smrg#endif
189