prcalc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "prcalc.h"
  2. #include "prc_bits.h"
  3. PRC_ERROR prc_init_context(prc_context *ctx) {
  4. ctx->registers.A = (uint64_t) 0;
  5. ctx->registers.B = (uint64_t) 0;
  6. ctx->registers.SP = (uint64_t) 0;
  7. ctx->registers.FLAGS = (uint64_t) 0;
  8. return OK;
  9. }
  10. PRC_ERROR prc_push(prc_context *ctx, uint64_t val) {
  11. if ( (ctx->registers.SP + 1) > STACK_SIZE ) {
  12. return STACK_OVERFLOW;
  13. }
  14. ctx->stack[ctx->registers.SP] = val;
  15. ctx->registers.SP +=1 ;
  16. return OK;
  17. }
  18. PRC_ERROR prc_pop(prc_context *ctx, uint64_t *val) {
  19. if ( ctx->registers.SP < 0 ) {
  20. return STACK_EMPTY;
  21. }
  22. ctx->registers.SP -= 1;
  23. *val = ctx->stack[ctx->registers.SP];
  24. return OK;
  25. }
  26. PRC_ERROR prc_set_a(prc_context *ctx, uint64_t val) {
  27. ctx->registers.A = val;
  28. return OK;
  29. }
  30. PRC_ERROR prc_set_b(prc_context *ctx, uint64_t val) {
  31. ctx->registers.B = val;
  32. return OK;
  33. }
  34. PRC_ERROR prc_swap(prc_context *ctx) {
  35. uint64_t *aux = malloc(sizeof( uint64_t));
  36. *aux = ctx->registers.A;
  37. if ( prc_push(ctx, ctx->registers.B) != OK ) {
  38. return STACK_OVERFLOW;
  39. }
  40. prc_set_b(ctx, *aux);
  41. if ( prc_pop(ctx, aux) != OK ) {
  42. return STATE_UNDEFINED;
  43. }
  44. prc_set_a(ctx, *aux);
  45. free(aux);
  46. return OK;
  47. }
  48. /* Add two values in the stack and save to register A */
  49. PRC_ERROR prc_add_stack (prc_context *ctx) {
  50. uint64_t *aux1 = malloc(sizeof( uint64_t));
  51. uint64_t *aux2 = malloc(sizeof( uint64_t));
  52. if ( prc_pop(ctx, aux1) != OK )
  53. return STACK_EMPTY;
  54. if ( prc_pop(ctx, aux2) != OK )
  55. return STACK_EMPTY;
  56. ctx->registers.FLAGS &= 0b11111001;
  57. // 00100110
  58. // 11111001
  59. // 00000000
  60. ctx->registers.A = *aux1 + *aux2;
  61. if ( __test_overflow(*aux1, *aux2, ctx->registers.A, ADD) )
  62. ctx->registers.FLAGS |= OVERFLOW;
  63. //ctx->registers.FLAGS = (__test_negative(ctx->registers.A) & ~NEGATIVE) ;
  64. if (__test_negative(ctx->registers.A)) {
  65. ctx->registers.FLAGS |= NEGATIVE;
  66. }
  67. free(aux1);
  68. free(aux2);
  69. return OK;
  70. }
  71. /* Multiply two values in the stack and save to register A */
  72. PRC_ERROR prc_mul_stack (prc_context *ctx) {
  73. uint64_t *aux1 = malloc(sizeof( uint64_t));
  74. uint64_t *aux2 = malloc(sizeof( uint64_t));
  75. ctx->registers.FLAGS &= 0b11111001;
  76. if ( prc_pop(ctx, aux1) != OK )
  77. return STACK_EMPTY;
  78. if ( prc_pop(ctx, aux2) != OK )
  79. return STACK_EMPTY;
  80. ctx->registers.A = *aux1 * *aux2;
  81. /*if ( __test_overflow(*aux1, *aux2, ctx->registers.A, MUL) )
  82. ctx->registers.FLAGS |= OVERFLOW;
  83. */
  84. if ( __test_negative(ctx->registers.A) )
  85. ctx->registers.FLAGS |= NEGATIVE;
  86. free(aux1);
  87. free(aux2);
  88. return OK;
  89. }
  90. /* Subtract two values in the stack and save to register A */
  91. PRC_ERROR SUB_STACK (prc_context *ctx) {
  92. uint64_t *aux1 = malloc(sizeof( uint64_t));
  93. uint64_t *aux2 = malloc(sizeof( uint64_t));
  94. if ( prc_pop(ctx, aux1) != OK )
  95. return STACK_EMPTY;
  96. if ( prc_pop(ctx, aux2) != OK )
  97. return STACK_EMPTY;
  98. ctx->registers.A = *aux1 - *aux2;
  99. if ( __test_negative(ctx->registers.A) )
  100. ctx->registers.FLAGS |= NEGATIVE;
  101. free(aux1);
  102. free(aux2);
  103. return OK;
  104. }
  105. /* Divide two values in the stack and save to register A */
  106. PRC_ERROR DIV_STACK (prc_context *ctx) {
  107. uint64_t *aux = malloc(sizeof( uint64_t));
  108. if ( prc_pop(ctx, aux) != OK )
  109. return STACK_EMPTY;
  110. ctx->registers.A = *aux;
  111. if ( prc_pop(ctx, aux) != OK )
  112. return STACK_EMPTY;
  113. ctx->registers.A /= *aux;
  114. free(aux);
  115. return OK;
  116. }
  117. /* Divide two values in the stack and save to register A */
  118. PRC_ERROR POW_STACK (prc_context *ctx) {
  119. uint64_t *aux = malloc( sizeof( uint64_t ) );
  120. uint64_t *power = malloc( sizeof( uint64_t ) );
  121. if ( prc_pop(ctx, power) != OK )
  122. return STACK_EMPTY;
  123. ctx->registers.A = *aux;
  124. if ( prc_pop(ctx, aux) != OK )
  125. return STACK_EMPTY;
  126. ctx->registers.A = pow(*aux, *power);
  127. free(aux);
  128. free(power);
  129. return OK;
  130. }