X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fexpr.c;h=52eb472441cb39796a398b8a94b2ffa5c4735bfd;hb=69b8ea4abd8a894f62dade3c5bb50291c82f3e0d;hp=094141f6e3bbf2cfacf841f9bacef4074c1d538f;hpb=14610ad10e3d4b84565d3590eaa9582f9793f743;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/expr.c b/gas/expr.c index 094141f6e3..52eb472441 100644 --- a/gas/expr.c +++ b/gas/expr.c @@ -45,7 +45,6 @@ static valueT generic_bignum_to_int64 (void); #endif static void integer_constant (int radix, expressionS * expressionP); static void mri_char_constant (expressionS *); -static void current_location (expressionS *); static void clean_up_expression (expressionS * expressionP); static segT operand (expressionS *, enum expr_mode); static operatorT operatorf (int *); @@ -173,7 +172,7 @@ expr_build_dot (void) expressionS e; current_location (&e); - return make_expr_symbol (&e); + return symbol_clone_if_forward_ref (make_expr_symbol (&e)); } /* Build any floating-point literal here. @@ -695,7 +694,7 @@ mri_char_constant (expressionS *expressionP) /* Return an expression representing the current location. This handles the magic symbol `.'. */ -static void +void current_location (expressionS *expressionp) { if (now_seg == absolute_section) @@ -706,7 +705,7 @@ current_location (expressionS *expressionp) else { expressionp->X_op = O_symbol; - expressionp->X_add_symbol = symbol_temp_new_now (); + expressionp->X_add_symbol = &dot_symbol; expressionp->X_add_number = 0; } } @@ -1057,6 +1056,15 @@ operand (expressionS *expressionP, enum expr_mode mode) { for (i = 0; i < expressionP->X_add_number; ++i) generic_bignum[i] = ~generic_bignum[i]; + + /* Extend the bignum to at least the size of .octa. */ + if (expressionP->X_add_number < SIZE_OF_LARGE_NUMBER) + { + expressionP->X_add_number = SIZE_OF_LARGE_NUMBER; + for (; i < expressionP->X_add_number; ++i) + generic_bignum[i] = ~(LITTLENUM_TYPE) 0; + } + if (c == '-') for (i = 0; i < expressionP->X_add_number; ++i) { @@ -1067,14 +1075,12 @@ operand (expressionS *expressionP, enum expr_mode mode) } else if (c == '!') { - int nonzero = 0; for (i = 0; i < expressionP->X_add_number; ++i) - { - if (generic_bignum[i]) - nonzero = 1; - generic_bignum[i] = 0; - } - generic_bignum[0] = nonzero; + if (generic_bignum[i] != 0) + break; + expressionP->X_add_number = i >= expressionP->X_add_number; + expressionP->X_op = O_constant; + expressionP->X_unsigned = 1; } } else if (expressionP->X_op != O_illegal @@ -1319,7 +1325,9 @@ operand (expressionS *expressionP, enum expr_mode mode) /* If we have an absolute symbol or a reg, then we know its value now. */ segment = S_GET_SEGMENT (symbolP); - if (mode != expr_defer && segment == absolute_section) + if (mode != expr_defer + && segment == absolute_section + && !S_FORCE_RELOC (symbolP, 0)) { expressionP->X_op = O_constant; expressionP->X_add_number = S_GET_VALUE (symbolP); @@ -1367,8 +1375,13 @@ operand (expressionS *expressionP, enum expr_mode mode) if (expressionP->X_add_symbol) symbol_mark_used (expressionP->X_add_symbol); - expressionP->X_add_symbol = symbol_clone_if_forward_ref (expressionP->X_add_symbol); - expressionP->X_op_symbol = symbol_clone_if_forward_ref (expressionP->X_op_symbol); + if (mode != expr_defer) + { + expressionP->X_add_symbol + = symbol_clone_if_forward_ref (expressionP->X_add_symbol); + expressionP->X_op_symbol + = symbol_clone_if_forward_ref (expressionP->X_op_symbol); + } switch (expressionP->X_op) { @@ -1587,13 +1600,13 @@ operatorf (int *num_chars) if (is_name_beginner (c)) { char *name = input_line_pointer; - char c = get_symbol_end (); + char ec = get_symbol_end (); - ret = md_operator (name, 2, &c); + ret = md_operator (name, 2, &ec); switch (ret) { case O_absent: - *input_line_pointer = c; + *input_line_pointer = ec; input_line_pointer = name; break; case O_uminus: @@ -1603,7 +1616,7 @@ operatorf (int *num_chars) ret = O_illegal; /* FALLTHROUGH */ default: - *input_line_pointer = c; + *input_line_pointer = ec; *num_chars = input_line_pointer - name; input_line_pointer = name; return ret; @@ -1740,6 +1753,7 @@ expr (int rankarg, /* Larger # is higher rank. */ input_line_pointer += op_chars; /* -> after operator. */ + right.X_md = 0; rightseg = expr (op_rank[(int) op_left], &right, mode); if (right.X_op == O_absent) { @@ -1828,7 +1842,9 @@ expr (int rankarg, /* Larger # is higher rank. */ #ifdef md_allow_local_subtract && md_allow_local_subtract (resultP, & right, rightseg) #endif - && (SEG_NORMAL (rightseg) + && ((SEG_NORMAL (rightseg) + && !S_FORCE_RELOC (resultP->X_add_symbol, 0) + && !S_FORCE_RELOC (right.X_add_symbol, 0)) || right.X_add_symbol == resultP->X_add_symbol) && frag_offset_fixed_p (symbol_get_frag (resultP->X_add_symbol), symbol_get_frag (right.X_add_symbol), @@ -1942,7 +1958,10 @@ expr (int rankarg, /* Larger # is higher rank. */ else if (op_left == O_subtract) { resultP->X_add_number -= right.X_add_number; - if (retval == rightseg && SEG_NORMAL (retval)) + if (retval == rightseg + && SEG_NORMAL (retval) + && !S_FORCE_RELOC (resultP->X_add_symbol, 0) + && !S_FORCE_RELOC (right.X_add_symbol, 0)) { retval = absolute_section; rightseg = absolute_section; @@ -1962,16 +1981,27 @@ expr (int rankarg, /* Larger # is higher rank. */ if (retval != rightseg) { - if (! SEG_NORMAL (retval)) - { - if (retval != undefined_section || SEG_NORMAL (rightseg)) - retval = rightseg; - } - else if (SEG_NORMAL (rightseg) + if (retval == undefined_section) + ; + else if (rightseg == undefined_section) + retval = rightseg; + else if (retval == expr_section) + ; + else if (rightseg == expr_section) + retval = rightseg; + else if (retval == reg_section) + ; + else if (rightseg == reg_section) + retval = rightseg; + else if (rightseg == absolute_section) + ; + else if (retval == absolute_section) + retval = rightseg; #ifdef DIFF_EXPR_OK - && op_left != O_subtract + else if (op_left == O_subtract) + ; #endif - ) + else as_bad (_("operation combines symbols in different segments")); } @@ -2237,8 +2267,7 @@ resolve_expression (expressionS *expressionP) op = O_constant; else if (seg_left == reg_section && final_val == 0) op = O_register; - else if (seg_left == undefined_section - && add_symbol != orig_add_symbol) + else if (!symbol_same_p (add_symbol, orig_add_symbol)) final_val += left; expressionP->X_add_symbol = add_symbol; }