/*========================== begin_copyright_notice ============================

Copyright (C) 2017-2021 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

#ifndef _IGA_IMMVAL_HPP_
#define _IGA_IMMVAL_HPP_

#include <stdint.h>

namespace iga {
struct ImmVal {
  enum class Kind {
    UNDEF,
    F16,
    F32,
    F64,

    S8,
    S16,
    S32,
    S64,

    U8,
    U16,
    U32,
    U64
  };

  union {
    // TODO: may be able to reduce to 32-bits and 64-bits
    uint16_t f16;
    float f32;
    double f64;

    int8_t s8;
    int16_t s16;
    int32_t s32;
    int64_t s64;

    uint8_t u8;
    uint16_t u16;
    uint32_t u32;
    uint64_t u64 = 0;
  };
  Kind kind = Kind::UNDEF;

  bool isS64() const { return kind == Kind::S64; }
  bool isU64() const { return kind == Kind::U64; }
  bool isI64() const { return isS64() || isU64(); }

  ImmVal &operator=(uint8_t x);
  ImmVal &operator=(int8_t x);
  ImmVal &operator=(uint16_t x);
  ImmVal &operator=(int16_t x);
  ImmVal &operator=(uint32_t x);
  ImmVal &operator=(int32_t x);
  ImmVal &operator=(uint64_t x);
  ImmVal &operator=(int64_t x);
  ImmVal &operator=(float x);
  ImmVal &operator=(double x);

  void Abs();
  void Negate();
}; // class ImmVal
} // namespace iga
#endif // _IGA_IMMVAL_HPP_
