src/codegen.c
static char *
generateBinaryOp(int op, Type *type) {
  switch (op) {
    case BINOP_ADD:
      return "add";
    case BINOP_SUB:
      return "sub";
    case BINOP_MUL:
      return "mul";
    case BINOP_DIV:
      switch (type->type) {
        case TYP_S8:
        case TYP_S16:
        case TYP_S32:
        case TYP_S64:
          return "div";
        case TYP_U8:
        case TYP_U16:
        case TYP_U32:
        case TYP_U64:
          return "udiv";
        default:
          assert(false);
          return NULL;
      }
    case BINOP_EQUAL:
      switch (type->type) {
        case SMALL_TYPES:
          return "ceqw";
        case BIG_TYPES:
          return "ceql";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_NOTEQUAL:
      switch (type->type) {
        case SMALL_TYPES:
          return "cnew";
        case BIG_TYPES:
          return "cnel";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_LESS:
      switch (type->type) {
        case SIGNED_SMALL_TYPES:
          return "csltw";
        case UNSIGNED_SMALL_TYPES:
          return "csltw";
        case SIGNED_BIG_TYPES:
          return "csltl";
        case UNSIGNED_BIG_TYPES:
          return "csltl";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_GREAT:
      switch (type->type) {
        case SIGNED_SMALL_TYPES:
          return "csgtw";
        case UNSIGNED_SMALL_TYPES:
          return "csgtw";
        case SIGNED_BIG_TYPES:
          return "csgtl";
        case UNSIGNED_BIG_TYPES:
          return "csgtl";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_LESS_EQ:
      switch (type->type) {
        case SIGNED_SMALL_TYPES:
          return "cslew";
        case UNSIGNED_SMALL_TYPES:
          return "cslew";
        case SIGNED_BIG_TYPES:
          return "cslel";
        case UNSIGNED_BIG_TYPES:
          return "cslel";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_GREAT_EQ:
      switch (type->type) {
        case SIGNED_SMALL_TYPES:
          return "csgew";
        case UNSIGNED_SMALL_TYPES:
          return "csgew";
        case SIGNED_BIG_TYPES:
          return "csgel";
        case UNSIGNED_BIG_TYPES:
          return "csgel";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    default:
      assert(false);
      exit(1);
  }
  return NULL;
}
/* Picks the correct binary op for a type */
Picks the correct binary op for a type
Picks the correct binary op for a type
static char *
generateBinaryOp(int op, Type *type) {
  switch (op) {
    case BINOP_ADD:
      return "add";
    case BINOP_SUB:
      return "sub";
    case BINOP_MUL:
      return "mul";
    case BINOP_DIV:
      switch (type->type) {
        case TYP_S8:
        case TYP_S16:
        case TYP_S32:
        case TYP_S64:
          return "div";
        case TYP_U8:
        case TYP_U16:
        case TYP_U32:
        case TYP_U64:
          return "udiv";
        default:
          assert(false);
          return NULL;
      }
    case BINOP_EQUAL:
      switch (type->type) {
        case SMALL_TYPES:
          return "ceqw";
        case BIG_TYPES:
          return "ceql";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_NOTEQUAL:
      switch (type->type) {
        case SMALL_TYPES:
          return "cnew";
        case BIG_TYPES:
          return "cnel";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_LESS:
      switch (type->type) {
        case SIGNED_SMALL_TYPES:
          return "csltw";
        case UNSIGNED_SMALL_TYPES:
          return "csltw";
        case SIGNED_BIG_TYPES:
          return "csltl";
        case UNSIGNED_BIG_TYPES:
          return "csltl";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_GREAT:
      switch (type->type) {
        case SIGNED_SMALL_TYPES:
          return "csgtw";
        case UNSIGNED_SMALL_TYPES:
          return "csgtw";
        case SIGNED_BIG_TYPES:
          return "csgtl";
        case UNSIGNED_BIG_TYPES:
          return "csgtl";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_LESS_EQ:
      switch (type->type) {
        case SIGNED_SMALL_TYPES:
          return "cslew";
        case UNSIGNED_SMALL_TYPES:
          return "cslew";
        case SIGNED_BIG_TYPES:
          return "cslel";
        case UNSIGNED_BIG_TYPES:
          return "cslel";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    case BINOP_GREAT_EQ:
      switch (type->type) {
        case SIGNED_SMALL_TYPES:
          return "csgew";
        case UNSIGNED_SMALL_TYPES:
          return "csgew";
        case SIGNED_BIG_TYPES:
          return "csgel";
        case UNSIGNED_BIG_TYPES:
          return "csgel";
        case TYP_BINDING:
          return generateBinaryOp(op, type->typeEntry->data);
        default:
          assert(false);
          return NULL;
      }
      break;
    default:
      assert(false);
      exit(1);
  }
  return NULL;
}
static char * generateBinaryOp ( int op , Type * type ) { switch ( op ) { case BINOP_ADD : return " " ; case BINOP_SUB : return " " ; case BINOP_MUL : return " " ; case BINOP_DIV : switch ( type -> type ) { case TYP_S8 : case TYP_S16 : case TYP_S32 : case TYP_S64 : return " " ; case TYP_U8 : case TYP_U16 : case TYP_U32 : case TYP_U64 : return " " ; default : assert ( false ) ; return NULL ; } case BINOP_EQUAL : switch ( type -> type ) { case SMALL_TYPES : return " " ; case BIG_TYPES : return " " ; case TYP_BINDING : return generateBinaryOp ( op , type -> typeEntry -> data ) ; default : assert ( false ) ; return NULL ; } break ; case BINOP_NOTEQUAL : switch ( type -> type ) { case SMALL_TYPES : return " " ; case BIG_TYPES : return " " ; case TYP_BINDING : return generateBinaryOp ( op , type -> typeEntry -> data ) ; default : assert ( false ) ; return NULL ; } break ; case BINOP_LESS : switch ( type -> type ) { case SIGNED_SMALL_TYPES : return " " ; case UNSIGNED_SMALL_TYPES : return " " ; case SIGNED_BIG_TYPES : return " " ; case UNSIGNED_BIG_TYPES : return " " ; case TYP_BINDING : return generateBinaryOp ( op , type -> typeEntry -> data ) ; default : assert ( false ) ; return NULL ; } break ; case BINOP_GREAT : switch ( type -> type ) { case SIGNED_SMALL_TYPES : return " " ; case UNSIGNED_SMALL_TYPES : return " " ; case SIGNED_BIG_TYPES : return " " ; case UNSIGNED_BIG_TYPES : return " " ; case TYP_BINDING : return generateBinaryOp ( op , type -> typeEntry -> data ) ; default : assert ( false ) ; return NULL ; } break ; case BINOP_LESS_EQ : switch ( type -> type ) { case SIGNED_SMALL_TYPES : return " " ; case UNSIGNED_SMALL_TYPES : return " " ; case SIGNED_BIG_TYPES : return " " ; case UNSIGNED_BIG_TYPES : return " " ; case TYP_BINDING : return generateBinaryOp ( op , type -> typeEntry -> data ) ; default : assert ( false ) ; return NULL ; } break ; case BINOP_GREAT_EQ : switch ( type -> type ) { case SIGNED_SMALL_TYPES : return " " ; case UNSIGNED_SMALL_TYPES : return " " ; case SIGNED_BIG_TYPES : return " " ; case UNSIGNED_BIG_TYPES : return " " ; case TYP_BINDING : return generateBinaryOp ( op , type -> typeEntry -> data ) ; default : assert ( false ) ; return NULL ; } break ; default : assert ( false ) ; exit ( 1 ) ; } return NULL ; }
Picks the correct binary op for a type
Picks the correct binary op for a type