123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- #include "prcalc.h"
- #include "prc_bits.h"
- PRC_ERROR prc_init_context(prc_context *ctx) {
-
- ctx->registers.A = (uint64_t) 0;
- ctx->registers.B = (uint64_t) 0;
- ctx->registers.SP = (uint64_t) 0;
- ctx->registers.FLAGS = (uint64_t) 0;
- return OK;
- }
- PRC_ERROR prc_push(prc_context *ctx, uint64_t val) {
- if ( (ctx->registers.SP + 1) > STACK_SIZE ) {
- return STACK_OVERFLOW;
- }
-
-
- ctx->stack[ctx->registers.SP] = val;
- ctx->registers.SP +=1 ;
- return OK;
- }
- PRC_ERROR prc_pop(prc_context *ctx, uint64_t *val) {
- if ( ctx->registers.SP < 0 ) {
- return STACK_EMPTY;
- }
-
- ctx->registers.SP -= 1;
- *val = ctx->stack[ctx->registers.SP];
- return OK;
- }
- PRC_ERROR prc_set_a(prc_context *ctx, uint64_t val) {
- ctx->registers.A = val;
- return OK;
- }
- PRC_ERROR prc_set_b(prc_context *ctx, uint64_t val) {
- ctx->registers.B = val;
- return OK;
- }
- PRC_ERROR prc_swap(prc_context *ctx) {
- uint64_t *aux = malloc(sizeof( uint64_t));
- *aux = ctx->registers.A;
- if ( prc_push(ctx, ctx->registers.B) != OK ) {
- return STACK_OVERFLOW;
- }
- prc_set_b(ctx, *aux);
- if ( prc_pop(ctx, aux) != OK ) {
- return STATE_UNDEFINED;
- }
- prc_set_a(ctx, *aux);
- free(aux);
- return OK;
- }
- /* Add two values in the stack and save to register A */
- PRC_ERROR prc_add_stack (prc_context *ctx) {
- uint64_t *aux1 = malloc(sizeof( uint64_t));
- uint64_t *aux2 = malloc(sizeof( uint64_t));
-
- if ( prc_pop(ctx, aux1) != OK )
- return STACK_EMPTY;
-
- if ( prc_pop(ctx, aux2) != OK )
- return STACK_EMPTY;
- ctx->registers.FLAGS &= 0b11111001;
- // 00100110
- // 11111001
- // 00000000
- ctx->registers.A = *aux1 + *aux2;
- if ( __test_overflow(*aux1, *aux2, ctx->registers.A, ADD) )
- ctx->registers.FLAGS |= OVERFLOW;
- //ctx->registers.FLAGS = (__test_negative(ctx->registers.A) & ~NEGATIVE) ;
- if (__test_negative(ctx->registers.A)) {
- ctx->registers.FLAGS |= NEGATIVE;
- }
-
- free(aux1);
- free(aux2);
- return OK;
- }
- /* Multiply two values in the stack and save to register A */
- PRC_ERROR prc_mul_stack (prc_context *ctx) {
- uint64_t *aux1 = malloc(sizeof( uint64_t));
- uint64_t *aux2 = malloc(sizeof( uint64_t));
- ctx->registers.FLAGS &= 0b11111001;
- if ( prc_pop(ctx, aux1) != OK )
- return STACK_EMPTY;
-
- if ( prc_pop(ctx, aux2) != OK )
- return STACK_EMPTY;
-
- ctx->registers.A = *aux1 * *aux2;
- /*if ( __test_overflow(*aux1, *aux2, ctx->registers.A, MUL) )
- ctx->registers.FLAGS |= OVERFLOW;
- */
- if ( __test_negative(ctx->registers.A) )
- ctx->registers.FLAGS |= NEGATIVE;
-
- free(aux1);
- free(aux2);
- return OK;
- }
- /* Subtract two values in the stack and save to register A */
- PRC_ERROR SUB_STACK (prc_context *ctx) {
- uint64_t *aux1 = malloc(sizeof( uint64_t));
- uint64_t *aux2 = malloc(sizeof( uint64_t));
- if ( prc_pop(ctx, aux1) != OK )
- return STACK_EMPTY;
-
- if ( prc_pop(ctx, aux2) != OK )
- return STACK_EMPTY;
- ctx->registers.A = *aux1 - *aux2;
- if ( __test_negative(ctx->registers.A) )
- ctx->registers.FLAGS |= NEGATIVE;
-
- free(aux1);
- free(aux2);
- return OK;
- }
- /* Divide two values in the stack and save to register A */
- PRC_ERROR DIV_STACK (prc_context *ctx) {
- uint64_t *aux = malloc(sizeof( uint64_t));
- if ( prc_pop(ctx, aux) != OK )
- return STACK_EMPTY;
- ctx->registers.A = *aux;
- if ( prc_pop(ctx, aux) != OK )
- return STACK_EMPTY;
- ctx->registers.A /= *aux;
-
- free(aux);
- return OK;
- }
- /* Divide two values in the stack and save to register A */
- PRC_ERROR POW_STACK (prc_context *ctx) {
- uint64_t *aux = malloc( sizeof( uint64_t ) );
- uint64_t *power = malloc( sizeof( uint64_t ) );
- if ( prc_pop(ctx, power) != OK )
- return STACK_EMPTY;
- ctx->registers.A = *aux;
-
- if ( prc_pop(ctx, aux) != OK )
- return STACK_EMPTY;
- ctx->registers.A = pow(*aux, *power);
-
- free(aux);
- free(power);
- return OK;
- }
|