X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fcompiler%2Faco_ir.h;h=661b6982df984202af3a1aa4d78a269a59ab787e;hb=2694a34aa2c32aeb32d7d70af91db56c6eaaa23b;hp=68d0b9bf4ceed9fce26c16e512fb6edff352818a;hpb=1b10764e50998a556e000323c77d4a1632a80dfc;p=mesa.git diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index 68d0b9bf4ce..661b6982df9 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -142,6 +142,10 @@ struct float_mode { unsigned denorm32:2; unsigned denorm16_64:2; }; + struct { + uint8_t round:4; + uint8_t denorm:4; + }; uint8_t val = 0; }; /* if false, optimizations which may remove infs/nan/-0.0 can be done */ @@ -307,7 +311,7 @@ struct PhysReg { constexpr bool operator==(PhysReg other) const { return reg_b == other.reg_b; } constexpr bool operator!=(PhysReg other) const { return reg_b != other.reg_b; } constexpr bool operator <(PhysReg other) const { return reg_b < other.reg_b; } - constexpr PhysReg advance(unsigned bytes) const { PhysReg res = *this; res.reg_b += bytes; return res; } + constexpr PhysReg advance(int bytes) const { PhysReg res = *this; res.reg_b += bytes; return res; } uint16_t reg_b = 0; }; @@ -337,7 +341,7 @@ class Operand final public: constexpr Operand() : reg_(PhysReg{128}), isTemp_(false), isFixed_(true), isConstant_(false), - isKill_(false), isUndef_(true), isFirstKill_(false), is64BitConst_(false), + isKill_(false), isUndef_(true), isFirstKill_(false), constSize(0), isLateKill_(false) {} explicit Operand(Temp r) noexcept @@ -350,11 +354,51 @@ public: setFixed(PhysReg{128}); } }; + explicit Operand(uint8_t v) noexcept + { + /* 8-bit constants are only used for copies and copies from any 8-bit + * constant can be implemented with a SDWA v_mul_u32_u24. So consider all + * to be inline constants. */ + data_.i = v; + isConstant_ = true; + constSize = 0; + setFixed(PhysReg{0u}); + }; + explicit Operand(uint16_t v) noexcept + { + data_.i = v; + isConstant_ = true; + constSize = 1; + if (v <= 64) + setFixed(PhysReg{128u + v}); + else if (v >= 0xFFF0) /* [-16 .. -1] */ + setFixed(PhysReg{192u + (0xFFFF - v)}); + else if (v == 0x3800) /* 0.5 */ + setFixed(PhysReg{240}); + else if (v == 0xB800) /* -0.5 */ + setFixed(PhysReg{241}); + else if (v == 0x3C00) /* 1.0 */ + setFixed(PhysReg{242}); + else if (v == 0xBC00) /* -1.0 */ + setFixed(PhysReg{243}); + else if (v == 0x4000) /* 2.0 */ + setFixed(PhysReg{244}); + else if (v == 0xC000) /* -2.0 */ + setFixed(PhysReg{245}); + else if (v == 0x4400) /* 4.0 */ + setFixed(PhysReg{246}); + else if (v == 0xC400) /* -4.0 */ + setFixed(PhysReg{247}); + else if (v == 0x3118) /* 1/2 PI */ + setFixed(PhysReg{248}); + else /* Literal Constant */ + setFixed(PhysReg{255}); + }; explicit Operand(uint32_t v, bool is64bit = false) noexcept { data_.i = v; isConstant_ = true; - is64BitConst_ = is64bit; + constSize = is64bit ? 3 : 2; if (v <= 64) setFixed(PhysReg{128 + v}); else if (v >= 0xFFFFFFF0) /* [-16 .. -1] */ @@ -383,7 +427,7 @@ public: explicit Operand(uint64_t v) noexcept { isConstant_ = true; - is64BitConst_ = true; + constSize = 3; if (v <= 64) { data_.i = (uint32_t) v; setFixed(PhysReg{128 + (uint32_t) v}); @@ -465,7 +509,7 @@ public: constexpr unsigned bytes() const noexcept { if (isConstant()) - return is64BitConst_ ? 8 : 4; //TODO: sub-dword constants + return 1 << constSize; else return data_.temp.bytes(); } @@ -473,7 +517,7 @@ public: constexpr unsigned size() const noexcept { if (isConstant()) - return is64BitConst_ ? 2 : 1; + return constSize > 2 ? 2 : 1; else return data_.temp.size(); } @@ -521,7 +565,7 @@ public: constexpr uint64_t constantValue64(bool signext=false) const noexcept { - if (is64BitConst_) { + if (constSize == 3) { if (reg_ <= 192) return reg_ - 128; else if (reg_ <= 208) @@ -545,6 +589,10 @@ public: case 247: return 0xC010000000000000; } + } else if (constSize == 1) { + return (signext && (data_.i & 0x8000u) ? 0xffffffffffff0000ull : 0ull) | data_.i; + } else if (constSize == 0) { + return (signext && (data_.i & 0x80u) ? 0xffffffffffffff00ull : 0ull) | data_.i; } return (signext && (data_.i & 0x80000000u) ? 0xffffffff00000000ull : 0ull) | data_.i; } @@ -635,11 +683,11 @@ private: uint8_t isKill_:1; uint8_t isUndef_:1; uint8_t isFirstKill_:1; - uint8_t is64BitConst_:1; + uint8_t constSize:2; uint8_t isLateKill_:1; }; /* can't initialize bit-fields in c++11, so work around using a union */ - uint8_t control_ = 0; + uint16_t control_ = 0; }; }; @@ -652,7 +700,8 @@ private: class Definition final { public: - constexpr Definition() : temp(Temp(0, s1)), reg_(0), isFixed_(0), hasHint_(0), isKill_(0), isPrecise_(0) {} + constexpr Definition() : temp(Temp(0, s1)), reg_(0), isFixed_(0), hasHint_(0), + isKill_(0), isPrecise_(0), isNUW_(0) {} Definition(uint32_t index, RegClass type) noexcept : temp(index, type) {} explicit Definition(Temp tmp) noexcept @@ -749,6 +798,17 @@ public: return isPrecise_; } + /* No Unsigned Wrap */ + constexpr void setNUW(bool nuw) noexcept + { + isNUW_ = nuw; + } + + constexpr bool isNUW() const noexcept + { + return isNUW_; + } + private: Temp temp = Temp(0, s1); PhysReg reg_; @@ -758,6 +818,7 @@ private: uint8_t hasHint_:1; uint8_t isKill_:1; uint8_t isPrecise_:1; + uint8_t isNUW_:1; }; /* can't initialize bit-fields in c++11, so work around using a union */ uint8_t control_ = 0; @@ -876,7 +937,8 @@ struct SMEM_instruction : public Instruction { bool nv : 1; /* VEGA only: Non-volatile */ bool can_reorder : 1; bool disable_wqm : 1; - uint32_t padding: 19; + bool prevent_overflow : 1; /* avoid overflow when combining additions */ + uint32_t padding: 18; }; static_assert(sizeof(SMEM_instruction) == sizeof(Instruction) + 4, "Unexpected padding"); @@ -1030,7 +1092,8 @@ struct MUBUF_instruction : public Instruction { bool lds : 1; /* Return read-data to LDS instead of VGPRs */ bool disable_wqm : 1; /* Require an exec mask without helper invocations */ bool can_reorder : 1; - uint8_t padding : 2; + bool swizzled:1; + uint8_t padding : 1; barrier_interaction barrier; }; static_assert(sizeof(MUBUF_instruction) == sizeof(Instruction) + 4, "Unexpected padding");