struct aout_byte* aout_create_metadata_origin(uint16_t address) { struct aout_byte* byte = malloc(sizeof(struct aout_byte)); byte->type = AOUT_TYPE_METADATA_ORIGIN; byte->opcode = address; byte->a = 0; byte->b = 0; byte->next = NULL; byte->prev = NULL; byte->expr = expr_new_number(address); byte->label = NULL; byte->raw_used = false; byte->raw = 0x0; list_init(&byte->symbols); return byte; }
static expr *create_num(expr_mngr *m, cvalue_list *l, double n) { int i; double x; // Creates the optimal numeric initialization expression // First, try standard tokens: for(i=0; 0 != (i = val_from_i(l, i, &x)); ) { if( n == x ) return expr_from_i(m, l, i-1); } // Now, try with "MINUS" and a value: for(i=0; 0 != (i = val_from_i(l, i, &x)); ) { if( n == -x ) return expr_new_uni(m, expr_from_i(m, l, i-1), TOK_UMINUS); } // Now, try with operations between two simple values: for(i=0; 0 != (i = val_from_i(l, i, &x)); ) { int j; double y; for(j=0; 0 != (j = val_from_i(l, j, &y)); ) { if( n == x + y ) return expr_new_bin(m, expr_from_i(m, l, i-1), expr_from_i(m, l, j-1), TOK_PLUS); if( n == x - y ) return expr_new_bin(m, expr_from_i(m, l, i-1), expr_from_i(m, l, j-1), TOK_MINUS); if( n == x * y ) return expr_new_bin(m, expr_from_i(m, l, i-1), expr_from_i(m, l, j-1), TOK_STAR); if( n == x / y ) return expr_new_bin(m, expr_from_i(m, l, i-1), expr_from_i(m, l, j-1), TOK_SLASH); } } // Same as before, adding "-": for(i=0; 0 != (i = val_from_i(l, i, &x)); ) { int j; double y; for(j=0; 0 != (j = val_from_i(l, j, &y)); ) { if( n == -x + y ) return expr_new_bin(m, expr_new_uni(m, expr_from_i(m, l, i-1), TOK_UMINUS), expr_from_i(m, l, j-1), TOK_PLUS); if( n == -x - y ) return expr_new_bin(m, expr_new_uni(m, expr_from_i(m, l, i-1), TOK_UMINUS), expr_from_i(m, l, j-1), TOK_MINUS); if( n == -x * y ) return expr_new_bin(m, expr_new_uni(m, expr_from_i(m, l, i-1), TOK_UMINUS), expr_from_i(m, l, j-1), TOK_STAR); if( n == -x / y ) return expr_new_bin(m, expr_new_uni(m, expr_from_i(m, l, i-1), TOK_UMINUS), expr_from_i(m, l, j-1), TOK_SLASH); } } // Now, try with operations between tree simple values: for(i=0; 0 != (i = val_from_i(l, i, &x)); ) { int j; double y; for(j=0; 0 != (j = val_from_i(l, j, &y)); ) { int k; double z; for(k=0; 0 != (k = val_from_i(l, k, &z)); ) { if( n == x + y + z ) return expr_new_bin(m, expr_new_bin(m, expr_from_i(m,l,i-1), expr_from_i(m,l,j-1), TOK_PLUS), expr_from_i(m,l,k-1), TOK_PLUS); if( n == x - y + z ) return expr_new_bin(m, expr_new_bin(m, expr_from_i(m,l,i-1), expr_from_i(m,l,j-1), TOK_MINUS), expr_from_i(m,l,k-1), TOK_PLUS); if( n == x - y - z ) return expr_new_bin(m, expr_new_bin(m, expr_from_i(m,l,i-1), expr_from_i(m,l,j-1), TOK_MINUS), expr_from_i(m,l,k-1), TOK_MINUS); if( n == x * y + z) return expr_new_bin(m, expr_new_bin(m, expr_from_i(m,l,i-1), expr_from_i(m,l,j-1), TOK_STAR), expr_from_i(m,l,k-1), TOK_PLUS); if( n == x * y - z) return expr_new_bin(m, expr_new_bin(m, expr_from_i(m,l,i-1), expr_from_i(m,l,j-1), TOK_STAR), expr_from_i(m,l,k-1), TOK_MINUS); if( n == x * y * z) return expr_new_bin(m, expr_new_bin(m, expr_from_i(m,l,i-1), expr_from_i(m,l,j-1), TOK_STAR), expr_from_i(m,l,k-1), TOK_STAR); if( n == x / y + z ) return expr_new_bin(m, expr_new_bin(m, expr_from_i(m,l,i-1), expr_from_i(m,l,j-1), TOK_SLASH), expr_from_i(m,l,k-1), TOK_PLUS); if( n == x / y - z ) return expr_new_bin(m, expr_new_bin(m, expr_from_i(m,l,i-1), expr_from_i(m,l,j-1), TOK_SLASH), expr_from_i(m,l,k-1), TOK_MINUS); } } } // Same as before, adding "-": for(i=0; 0 != (i = val_from_i(l, i, &x)); ) { int j; double y; for(j=0; 0 != (j = val_from_i(l, j, &y)); ) { int k; double z; for(k=0; 0 != (k = val_from_i(l, k, &z)); ) { if( n == -x + y + z ) return expr_new_bin(m, expr_new_bin(m, expr_new_uni(m, expr_from_i(m,l,i-1), TOK_UMINUS), expr_from_i(m,l,j-1), TOK_PLUS), expr_from_i(m,l,k-1), TOK_PLUS); if( n == -x - y + z ) return expr_new_bin(m, expr_new_bin(m, expr_new_uni(m, expr_from_i(m,l,i-1), TOK_UMINUS), expr_from_i(m,l,j-1), TOK_MINUS), expr_from_i(m,l,k-1), TOK_PLUS); if( n == -x - y - z ) return expr_new_bin(m, expr_new_bin(m, expr_new_uni(m, expr_from_i(m,l,i-1), TOK_UMINUS), expr_from_i(m,l,j-1), TOK_MINUS), expr_from_i(m,l,k-1), TOK_MINUS); if( n == -x * y + z) return expr_new_bin(m, expr_new_bin(m, expr_new_uni(m, expr_from_i(m,l,i-1), TOK_UMINUS), expr_from_i(m,l,j-1), TOK_STAR), expr_from_i(m,l,k-1), TOK_PLUS); if( n == -x * y - z) return expr_new_bin(m, expr_new_bin(m, expr_new_uni(m, expr_from_i(m,l,i-1), TOK_UMINUS), expr_from_i(m,l,j-1), TOK_STAR), expr_from_i(m,l,k-1), TOK_MINUS); if( n == -x * y * z) return expr_new_bin(m, expr_new_bin(m, expr_new_uni(m, expr_from_i(m,l,i-1), TOK_UMINUS), expr_from_i(m,l,j-1), TOK_STAR), expr_from_i(m,l,k-1), TOK_STAR); if( n == -x / y + z ) return expr_new_bin(m, expr_new_bin(m, expr_new_uni(m, expr_from_i(m,l,i-1), TOK_UMINUS), expr_from_i(m,l,j-1), TOK_SLASH), expr_from_i(m,l,k-1), TOK_PLUS); if( n == -x / y - z ) return expr_new_bin(m, expr_new_bin(m, expr_new_uni(m, expr_from_i(m,l,i-1), TOK_UMINUS), expr_from_i(m,l,j-1), TOK_SLASH), expr_from_i(m,l,k-1), TOK_MINUS); } } } // No simpler expression found: return expr_new_number(m, n); }