Unary operators

#ifndef UNARYOPS
#define UNARYOPS
 
// Notice we don't have the # sign in front of the include like we do in C++
include "setup.td"
 
def UnaryOps {
  // !repr(value)
  // Represents value as a string. 
  // String format for the value might change over TableGen versions,
  // so don't rely on it being exact.
  // Intended for debugging purposes only.
  string addOp_s = !repr(addOp); 
  // "addOp {       // Op
  //  string name = "add";
  // }
  //";
  
  // Base 2 log 
  int logtwo_v = !logtwo(2); // 1
  assert !eq(logtwo_v, 1), errorStr;
    
  // logical shift performed on a 64-bit integer
  // value undefined if count < 0 or count > 63
  // The shift function naming convention is a bit odd.
  // SHift Left logical -> shl
  int shl_v = !shl(1, 3); // 8
  assert !eq(shl_v, 8), errorStr;
 
  // Shift Right Logical -> srl
  int srl_v = !srl(8, 3); // 1
  assert !eq(srl_v, 1), errorStr; 
 
  // Shift Right Arithmetic -> sra
  int sra_v = !sra(-8, 3); // -1
  assert !eq(sra_v, -1), errorStr; 
    
  // !not(a)
  bit not_t = !not(true); // 0
  assert !eq(not_t, 0), errorStr;
 
  bit not_f = !not(false); // 1
  assert !eq(not_f, 1), errorStr;
 
  // works on 0 and 1 like it would on true/false
  bit not_1 = !not(1); // 0
  assert !eq(not_1, 0), errorStr;
 
  // any non-zero number (positive or negative) is true. 
  // so !not(non_zero_number) = 0 ie false.
  bit not_2 = !not(-2); 
  assert !eq(not_2, 0), errorStr;
  
  // !empty(a)
  // This operator produces 1 if the string, list, or DAG a is empty; 0 otherwise. 
  // A dag is empty if it has no arguments; the operator does not count.
  bit empty_string = !empty("");  
  assert empty_string, errorStr; 
  
  // size(a)
  int size_hello = !size("Hello, World!"); // 13
  assert !eq(size_hello, 13), errorStr;
 
  int size_list = !size([1, 2, 3]); // 3
  assert !eq(size_list, 3), errorStr;
}
 
#endif // UNARYOPS