#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; }