#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#include <time.h>



int decimal_to_binary(char* p, int32_t n)
{
  int32_t c, d, t;

  t = 0;

  if (p == NULL)
    exit(EXIT_FAILURE);

  for (c = 31 ; c >= 0 ; c--)
  {
    d = n >> c;

    if (d & 1)
      *(p+t) = 1 + '0';
    else
      *(p+t) = 0 + '0';

    t++;
  }
  *(p+t) = '\n';
  *(p+t+1) = '\0';

  return 0;
}

int unsigned_decimal_to_binary(char* p, uint32_t n)
{
	int c;
  uint32_t  d, t;

  t = 0;

  if (p == NULL)
    exit(EXIT_FAILURE);

  for (c = 31 ; c >= 0 ; c--)
  {
    d = n >> c;

    if (d & 1)
      *(p+t) = 1 + '0';
    else
      *(p+t) = 0 + '0';

    t++;
  }
  *(p+t) = '\n';
  *(p+t+1) = '\0';

  return 0;
}

int main (int argc, char ** argv) {
	int i;
	int32_t r, s;
	uint32_t ur, us;	
	FILE* output;
	FILE* input;
	char str[40];
	output = fopen("./testdata/output.txt", "w");
	input = fopen("./testdata/input.txt", "w"); 	
	srand(time(NULL));
	for (i = 0; i < 5; i++) {
		r = ((int32_t) rand()+rand());
		s = ((int32_t) rand()+rand());
		
		fputs("ALU_NOP\n", input);
		decimal_to_binary(str, r);
		fputs(str, input);
		decimal_to_binary(str, s);
		fputs(str, input);
		fputs("\n", input);

	
		decimal_to_binary(str, s);
		fputs(str, output);
		fputs("-\n\n", output);
	}


	for (i = 0; i < 5; i++) {
		r = ((int32_t) rand()+rand());
		s = ((int32_t) rand()+rand());
		fputs("ALU_SLT\n", input);
		decimal_to_binary(str, r);
		fputs(str, input);
		decimal_to_binary(str, s);
		fputs(str, input);
		fputs("\n", input);

	
		if (r < s)
			fputs("00000000000000000000000000000001\n", output);			
		else 
			fputs("00000000000000000000000000000000\n", output);
		if (r < s)
			fputs("0\n\n", output);			
		else 
			fputs("1\n\n", output);
		
		
	}
	for (i = 0; i < 50; i++) {
		ur = (uint32_t) ((int32_t) rand()+rand());
		us = (uint32_t) ((int32_t) rand()+rand());
		fputs("ALU_SLTU\n", input);

		unsigned_decimal_to_binary(str,  ur);
		fputs(str, input);
		unsigned_decimal_to_binary(str, us);
		fputs(str, input);
		fputs("\n", input);
	
		
		if (ur < us)
			fputs("00000000000000000000000000000001\n", output);			
		else 
			fputs("00000000000000000000000000000000\n", output);
		if (ur < us)
			fputs("0\n\n", output);			
		else 
			fputs("1\n\n", output);
	}
	for (i = 0; i < 50; i++) {
		ur = (uint32_t) ((int32_t) rand()+rand());
		us = (uint32_t) ((int32_t) rand()+rand());
		fputs("ALU_SLL\n", input);
		

		unsigned_decimal_to_binary(str,  ur);
		fputs(str, input);
		unsigned_decimal_to_binary(str, us);
		fputs(str, input);
		fputs("\n", input);
		
		unsigned_decimal_to_binary(str, ur << us);
		fputs(str, output);
		fputs("-\n\n", output);
	}
	for (i = 0; i < 50; i++) {
		ur = (uint32_t) ((int32_t) rand()+rand());
		us = (uint32_t) ((int32_t) rand()+rand());
		fputs("ALU_SRL\n", input);

		unsigned_decimal_to_binary(str,  ur);
		fputs(str, input);
		unsigned_decimal_to_binary(str, us);
		fputs(str, input);
		fputs("\n", input);
	
		unsigned_decimal_to_binary(str, ur >> us);
		fputs(str, output);
		fputs("-\n\n", output);
	}
	for (i = 0; i < 50; i++) {
		r = ((int32_t) rand()+rand());
		us = (uint32_t) ((int32_t) rand()+rand());
		fputs("ALU_SRA\n", input);

		decimal_to_binary(str,  r);
		fputs(str, input);
		unsigned_decimal_to_binary(str, us);
		fputs(str, input);
		fputs("\n", input);
	
		
		unsigned_decimal_to_binary(str, r >> us);
		fputs(str, output);
		fputs("-\n\n", output);
	}
	for (i = 0; i < 50; i++) {
		r = ((int32_t) rand()+rand());
		s = ((int32_t) rand()+rand());
		fputs("ALU_ADD\n", input);

		decimal_to_binary(str,  r);
		fputs(str, input);
		decimal_to_binary(str, s);
		fputs(str, input);
		fputs("\n", input);
	
		
		decimal_to_binary(str, r + s);
		fputs(str, output);
		fputs("-\n\n", output);
	}
	for (i = 0; i < 50; i++) {
		r = ((int32_t) rand()+rand());
		s = ((int32_t) rand()+rand());
		fputs("ALU_SUB\n", input);

		decimal_to_binary(str,  r);
		fputs(str, input);
		decimal_to_binary(str, s);
		fputs(str, input);
		fputs("\n", input);
	
		
		decimal_to_binary(str, r - s);
		fputs(str, output);
		if (r == s)
			fputs("1\n\n", output);			
		else 
			fputs("0\n\n", output);
	}
	for (i = 0; i < 50; i++) {
		r = ((int32_t) rand()+rand());
		s = ((int32_t) rand()+rand());
		fputs("ALU_AND\n", input);

		decimal_to_binary(str,  r);
		fputs(str, input);
		decimal_to_binary(str, s);
		fputs(str, input);
		fputs("\n", input);
	
		
		decimal_to_binary(str, r & s);
		fputs(str, output);
		fputs("-\n\n", output);
	}
	for (i = 0; i < 50; i++) {
		r = ((int32_t) rand()+rand());
		s = ((int32_t) rand()+rand());
		fputs("ALU_OR\n", input);

		decimal_to_binary(str,  r);
		fputs(str, input);
		decimal_to_binary(str, s);
		fputs(str, input);
		fputs("\n", input);
	
		
		decimal_to_binary(str, r | s);
		fputs(str, output);
		fputs("-\n\n", output);
	}
	for (i = 0; i < 50; i++) {
		r = ((int32_t) rand()+rand()) ;
		s = ((int32_t) rand()+rand()) ;
		fputs("ALU_XOR\n", input);

		decimal_to_binary(str,  r);
		fputs(str, input);
		decimal_to_binary(str, s);
		fputs(str, input);
		if (i != 49) {
			fputs("\n", input);
		}
		
		decimal_to_binary(str, r ^ s);
		fputs(str, output);
		fputs("-\n", output);
		if (i != 49) {
			fputs("\n", input);
		}
	}
	fclose(output);
	fclose(input);
}
