#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "big_int_v_cpu.h"
#include "stack_ex.h"
#define REG_NUM 8
//define a status register
//bit0-bit31
//CF PF AF ZF SF OF
typedef struct
{
uint32_t cf:1;
uint32_t pf:1;
uint32_t af:1;
uint32_t zf:1;
uint32_t sf:1;
uint32_t of:1;
uint32_t reverse:26;
} status_register;
static status_register sta_r;
//data register
reg_basep b_cpu_reg[REG_NUM * 2] = {[0 ... REG_NUM * 2 - 1] = NULL};
#define max(a,b) (((a) < (b)) ? (b) : (a))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define debug(a) \
({ \
uint32_t i; \
printf("debug_%s:",#a); \
for(i = (a)->reg_data_top_pos;i > 0;i--) \
printf("%08lx",(a)->reg_data[i - 1]); \
printf("\n"); \
})
reg_basep
atob_int_hex(char *str)
{
if(NULL == str)
return NULL;
size_t str_len = strlen(str);
int32_t i = 0,pos = 0;
uint32_t tmp_num = 0,tmp_n = 0;
reg_basep big_num = init_b_int(0);
char tmp_c;
for(i = 0;i < str_len / 2;i++) {
pos = str_len - 1 - i;
tmp_c = str[i];
str[i] = str[pos];
str[pos] = tmp_c;
}
for(i = 0;i < str_len;i++)
if(!isdigit(str[i]) && !isalpha(str[i])) {
printf("str:%s,pos:%d,c:%c\n",str,i,str[i]);
uninit_b_int(big_num);
return NULL;
} else {
if(i % 8 == 0 && i != 0) {
big_num->reg_data[big_num->reg_data_top_pos - 1] = tmp_num;
big_num->reg_data_top_pos++;
tmp_num = 0;
if(isdigit(str[i]))
tmp_n = str[i] - 48;
else if(islower(str[i]))
tmp_n = str[i] - 87;
else if(isupper(str[i]))
tmp_n = str[i] - 55;
tmp_num |= (tmp_n << (4 * (i % 8)));
tmp_n = 0;
} else {
if(isdigit(str[i]))
tmp_n = str[i] - 48;
else if(islower(str[i]))
tmp_n = str[i] - 87;
else if(isupper(str[i]))
tmp_n = str[i] - 55;
tmp_num |= (tmp_n << (4 * (i % 8)));
tmp_n = 0;
}
}
big_num->reg_data[big_num->reg_data_top_pos - 1] = tmp_num;
return big_num;
}
reg_basep
init_b_int(uint32_t init_val)
{
reg_basep tmp = \
(reg_basep)malloc(sizeof(reg_base));
if(NULL == tmp) {
perror("malloc");
return NULL;
}
memset(tmp,0,sizeof(reg_base));
tmp->reg_data[0] = init_val;
tmp->reg_data_top_pos++;
return tmp;
}
void
uninit_b_int(reg_basep c)
{
if(NULL != c)
free(c);
}
bool
b_int_v_cpu_on(void)
{
memset(&sta_r,0,sizeof(sta_r));
uint32_t i = 0;
for(;i < REG_NUM * 2;i++)
if(NULL == b_cpu_reg[i])
b_cpu_reg[i] = init_b_int(0);
init_stack();
return true;
}
bool
b_int_v_cpu_off(void)
{
uint32_t i = 0;
for(;i < REG_NUM * 2;i++)
if(NULL != b_cpu_reg[i])
uninit_b_int(b_cpu_reg[i]);
destroy_stack();
return true;
}
//load val from memery
reg_basep
ldr_b_int(v_cpu_register dst_r,reg_basep src_mem)
{
if(NULL == src_mem || \
NULL == b_cpu_reg[dst_r])
return NULL;
memset(b_cpu_reg[dst_r],0,sizeof(reg_base));
b_cpu_reg[dst_r]->reg_data_top_pos = \
src_mem->reg_data_top_pos;
uint32_t i = 0;
for(;i < b_cpu_reg[dst_r]->reg_data_top_pos;i++)
b_cpu_reg[dst_r]->reg_data[i] = src_mem->reg_data[i];
return b_cpu_reg[dst_r];
}
//store register data to memery
reg_basep
str_b_int(v_cpu_register src_r,reg_basep dst_mem)
{
if(NULL == dst_mem || \
NULL == b_cpu_reg[src_r])
return NULL;
memset(dst_mem,0,sizeof(reg_base));
dst_mem->reg_data_top_pos = \
b_cpu_reg[src_r]->reg_data_top_pos;
uint32_t i = 0;
for(;i < dst_mem->reg_data_top_pos;i++)
dst_mem->reg_data[i] = \
b_cpu_reg[src_r]->reg_data[i];
return dst_mem;
}
//push reg data to stack
bool
push_reg_sp(v_cpu_register r)
{
//debug(b_cpu_reg[r]);
return push_stack(b_cpu_reg[r],sizeof(reg_base));
}
//pop reg data from stack
bool
pop_reg_sp(v_cpu_register r)
{
//debug(b_cpu_reg[r]);
return pop_stack(b_cpu_reg[r],sizeof(reg_base));
}
//mov
reg_basep
mov_b_int(v_cpu_register dst_r,v_cpu_register src_r)
{
if(NULL == b_cpu_reg[dst_r] || \
NULL == b_cpu_reg[src_r])
return NULL;
memset(b_cpu_reg[dst_r],0,sizeof(reg_base));
b_cpu_reg[dst_r]->reg_data_top_pos = \
b_cpu_reg[src_r]->reg_data_top_pos;
uint32_t i = 0;
for(;i < b_cpu_reg[dst_r]->reg_data_top_pos;i++)
b_cpu_reg[dst_r]->reg_data[i] = \
b_cpu_reg[src_r]->reg_data[i];
return b_cpu_reg[dst_r];
}
reg_basep
mov_u32(v_cpu_register dst_r,uint32_t src_val)
{
if(NULL == b_cpu_reg[dst_r])
return NULL;
memset(b_cpu_reg[dst_r],0,sizeof(reg_base));
b_cpu_reg[dst_r]->reg_data_top_pos = 1;
b_cpu_reg[dst_r]->reg_data[0] = src_val;
return b_cpu_reg[dst_r];
}
//cmp
int32_t
cmp_b_int(v_cpu_register r_a,v_cpu_register r_b)
{
if(NULL == b_cpu_reg[r_a] || \
NULL == b_cpu_reg[r_b])
return 0;
//debug(b_cpu_reg[r_a]);debug(b_cpu_reg[r_b]);
if(b_cpu_reg[r_a]->reg_data_top_pos > \
b_cpu_reg[r_b]->reg_data_top_pos)
return 1;
else if(b_cpu_reg[r_a]->reg_data_top_pos < \
b_cpu_reg[r_b]->reg_data_top_pos)
return -1;
else {
uint32_t i = b_cpu_reg[r_a]->reg_data_top_pos;
for(;i > 0;i--)
if(b_cpu_reg[r_a]->reg_data[i - 1] > \
b_cpu_reg[r_b]->reg_data[i - 1])
return 1;
else if(b_cpu_reg[r_a]->reg_data[i - 1] < \
b_cpu_reg[r_b]->reg_data[i - 1])
return -1;
}
return 0;
}
int32_t
cmp_u32(v_cpu_register r_a,uint32_t val)
{
if(NULL == b_cpu_reg[r_a])
return 0;
if(b_cpu_reg[r_a]->reg_data_top_pos > 1)
return 1;
if(b_cpu_reg[r_a]->reg_data[0] > val)
return 1;
else if(b_cpu_reg[r_a]->reg_data[0] == val)
return 0;
else
return -1;
}
//add
reg_basep
add_b_int(v_cpu_register dst_r,v_cpu_register src_r)
{
if(NULL == b_cpu_reg[dst_r] || \
NULL == b_cpu_reg[src_r])
return NULL;
uint32_t max_top_b = \
max(b_cpu_reg[dst_r]->reg_data_top_pos,
b_cpu_reg[src_r]->reg_data_top_pos);
uint32_t min_top_b = \
min(b_cpu_reg[dst_r]->reg_data_top_pos,
b_cpu_reg[src_r]->reg_data_top_pos);
uint32_t i = 0;
uint64_t sum = 0;
uint32_t *sum_p = (uint32_t *)(&sum);
sta_r.cf = 0;
for(i = 0;i < min_top_b;i++) {
sum = b_cpu_reg[dst_r]->reg_data[i];
sum += b_cpu_reg[src_r]->reg_data[i];
sum += sta_r.cf;
if(0 != sta_r.cf)
sta_r.cf = 0;
if(sum >> 32)
sta_r.cf = 1;
b_cpu_reg[dst_r]->reg_data[i] = sum_p[0];
sum = 0;
}
if(1 == sta_r.cf) {
if((max_top_b == min_top_b) && (max_top_b != MAX_BIG_INT_LEN)) {
b_cpu_reg[dst_r]->reg_data[i]++;
b_cpu_reg[dst_r]->reg_data_top_pos++;
} else {
for(;i < max_top_b;i++) {
if(b_cpu_reg[dst_r]->reg_data_top_pos > \
b_cpu_reg[src_r]->reg_data_top_pos)
sum = b_cpu_reg[dst_r]->reg_data[i];
else {
sum = b_cpu_reg[src_r]->reg_data[i];
b_cpu_reg[dst_r]->reg_data_top_pos++;
}
sum += sta_r.cf;
if(0 != sta_r.cf)
sta_r.cf = 0;
if(sum >> 32)
sta_r.cf = 1;
b_cpu_reg[dst_r]->reg_data[i] = sum_p[0];
sum = 0;
}
if((1 == sta_r.cf) && (max_top_b != MAX_BIG_INT_LEN)) {
b_cpu_reg[dst_r]->reg_data[i]++;
b_cpu_reg[dst_r]->reg_data_top_pos++;
}
}
} else if((max_top_b > min_top_b) && (b_cpu_reg[dst_r]->reg_data_top_pos \
< b_cpu_reg[src_r]->reg_data_top_pos))
for(;i < max_top_b;i++) {
b_cpu_reg[dst_r]->reg_data[i] += b_cpu_reg[src_r]->reg_data[i];
b_cpu_reg[dst_r]->reg_data_top_pos++;
}
//printf("add:");
//debug(b_cpu_reg[dst_r]);
return b_cpu_reg[dst_r];
}
reg_basep
add_u32(v_cpu_register dst_r,uint32_t val)
{
if(NULL == b_cpu_reg[dst_r])
return NULL;
uint32_t i = 0;
uint64_t sum = 0;
uint32_t *sum_p = (uint32_t *)∑
sum = val;
sta_r.cf = 0;
for(i = 0;i < b_cpu_reg[dst_r]->reg_data_top_pos;i++) {
sum += b_cpu_reg[dst_r]->reg_data[i];
sum += sta_r.cf;
if(1 == sta_r.cf)
sta_r.cf = 0;
if((sum >> 32) & 0x1)
sta_r.cf = 1;
b_cpu_reg[dst_r]->reg_data[i] = sum_p[0];
sum = 0;
}
if((1 == sta_r.cf) && (b_cpu_reg[dst_r]->reg_data_top_pos \
< MAX_BIG_INT_LEN)) {
b_cpu_reg[dst_r]->reg_data[i] += sta_r.cf;
b_cpu_reg[dst_r]->reg_data_top_pos++;
}
return b_cpu_reg[dst_r];
}
reg_basep
sub_b_int(v_cpu_register dst_r,v_cpu_register src_r)
{
if(NULL == b_cpu_reg[dst_r] || \
NULL == b_cpu_reg[src_r])
return NULL;
if(1 == b_cpu_reg[src_r]->reg_data_top_pos &&
0 == b_cpu_reg[src_r]->reg_data[0])