/*
** dotgnu.ops
*/
#include "parrot/method_util.h"

VERSION = PARROT_VERSION;

=head1 NAME

dotgnu.ops

=cut

=head1 DESCRIPTION

Additional opcodes for C# compilation needed by cscc PM codegen

=cut

inline op conv_i1(inout INT) {
  $1 = (INTVAL)((signed char)($1));
  goto NEXT();
}

inline op conv_i1_ovf(inout INT) {
  if($1 >= -128 && $1 <= 127) {
    $1 = (INTVAL)((signed char)($1));
  }
  else {
    internal_exception(1, "Overflow exception for conv_i1_ovf\n");
  }
  goto NEXT();
}

inline op conv_u1(inout INT) {
  $1 = (INTVAL)((unsigned char)($1));
  goto NEXT();
}

inline op conv_u1_ovf(inout INT) {
  if($1 >= 0 && $1 <= 255 ) {
    $1 = (INTVAL)((unsigned char)($1));
  }
  else {
    internal_exception(1, "Overflow exception for conv_u1_ovf\n");
  }
  goto NEXT();
}

inline op conv_i2(inout INT) {
  $1 = (INTVAL)((Parrot_Int2)($1));
  goto NEXT();
}

inline op conv_i2_ovf(inout INT) {
  if($1 >= -32768 && $1 <= 32767 ) {
    $1 = (INTVAL)((Parrot_Int2)($1));
  }
  else
  {
    internal_exception(1, "Overflow exception for conv_i2_ovf\n");
  }
  goto NEXT();
}

inline op conv_u2(inout INT) {
  $1 = (INTVAL)((Parrot_UInt2)($1));
  goto NEXT();
}

inline op conv_u2_ovf(inout INT) {
  if($1 >= 0 && $1 <= 65535) {
    $1 = (INTVAL)((Parrot_UInt2)($1));
  }
  else
  {
    internal_exception(1, "Overflow exception for conv_u2_ovf\n");
  }
  goto NEXT();
}

inline op conv_i4(out INT, in NUM) {
  $1 = (INTVAL)((Parrot_Int4)($2));
  goto NEXT();
}

inline op conv_i4(out INT, in PMC) {
  $1 = (INTVAL)(Parrot_Int4)($2->vtable->get_integer(interpreter, $2));
  goto NEXT();
}

inline op conv_u4(out INT, in NUM) {
  $1 = (UINTVAL)((Parrot_UInt4)($2));
  goto NEXT();
}

inline op conv_u4(out INT, in PMC) {
  $1 = (UINTVAL)(Parrot_UInt4) ($2->vtable->get_integer(interpreter, $2));
  goto NEXT();
}

inline op conv_i8(in PMC, in INT) {
  $1->vtable->set_integer_native(interpreter, $1,$2);
  goto NEXT();
}

inline op conv_i8(in PMC, in PMC) {
  $1->vtable->set_integer_same(interpreter, $1,$2);
  goto NEXT();
}

inline op conv_i8(in PMC, in NUM) {
  $1->vtable->set_integer_native(interpreter, $1, (INTVAL)$2);
  goto NEXT();
}

inline op conv_r4(out NUM, in INT) {
  $1 =  (FLOATVAL)((Parrot_Float4)($2));
  goto NEXT();
}

inline op conv_r4(inout NUM) {
  $1 =  (FLOATVAL)((Parrot_Float4)($1));
  goto NEXT();
}

inline op conv_r4(out NUM, in PMC) {
  $1 = (FLOATVAL)(Parrot_Float4)($2->vtable->get_number(interpreter, $2));
  goto NEXT();
}

inline op conv_r8(out NUM, in INT) {
  $1 =  (FLOATVAL)(Parrot_Float8)($2);
  goto NEXT();
}

inline op conv_r8(inout NUM) {
  $1 =  (FLOATVAL)(Parrot_Float8)($1);
  goto NEXT();
}

inline op conv_r8(out NUM, in PMC) {
  $1 = (FLOATVAL)(Parrot_Float8)($2->vtable->get_number(interpreter, $2));
  goto NEXT();
}
