diff options
author | Ian Lance Taylor <ian@airs.com> | 1993-07-21 00:41:42 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1993-07-21 00:41:42 +0000 |
commit | 5ac34ac37e3786b1fbc52aa9df376fff6a1e8e1a (patch) | |
tree | bf71fb272c4a13449f3dcc4d6ac486784e909cac /gas/config | |
parent | b9b9f55a52a01203776fcd35f2870634068d683a (diff) | |
download | gdb-5ac34ac37e3786b1fbc52aa9df376fff6a1e8e1a.zip gdb-5ac34ac37e3786b1fbc52aa9df376fff6a1e8e1a.tar.gz gdb-5ac34ac37e3786b1fbc52aa9df376fff6a1e8e1a.tar.bz2 |
* Extensive changes to permit symbols to contain any expression
type and to delay the computation of the expression until the
value is actually needed. This permits setting symbols to values
calculated based on object code size. Expressions were changed to
no longer be in a section, to stop the overloading of segment and
expression type that previously occurred.
* as.c (big_section, pass1_section, diff_section, absent_section):
Removed.
(expr_section): Added (used for dummy symbols which hold
intermediate expression values).
(perform_an_assembly_pass): Create expr_section, do not create the
sections now removed.
* as.h (segT): Removed SEG_ABSENT, SEG_PASS1, SEG_BIG, and
SEG_DIFFERENCE. Added SEG_EXPR.
(SEG_NORMAL): Corresponding changes.
* subsegs.c (seg_name, subsegs_begin): Changed accordingly.
* write.c (write_object_file): Ditto.
* config/obj-aout.c (seg_N_TYPE): Ditto.
* config/obj-bout.c (seg_N_TYPE): Ditto.
* config/obj-coff.c (seg_N_TYPE): Ditto.
* config/obj-coffbfd.c (seg_N_TYPE): Ditto.
* config/obj-vms.c (seg_N_TYPE): Ditto.
* expr.h (operatorT): Moved in from expr.c, added some values.
(expressionS): Added X_op field, removed X_seg field; renamed
X_subtract_symbol to X_op_symbol.
* expr.c: Extensive changes to assign expression types rather than
sections and to simplify the parsing.
* write.c (fix_new_internal): New static function.
(fix_new): Removed sub_symbol argument.
(fix_new_exp): New function, takes expression argument.
* write.h: Prototype changes for fix_new and fix_new_exp.
* cond.c (s_if): Changed accordingly.
* read.c (s_lsym, pseudo_set, emit_expr, parse_bitfield_cons,
parse_repeat_cons, get_segmented_expression,
get_known_segmented_expression, get_absolute_expression): Ditto.
* symbols.c (resolve_symbol_value, S_GET_VALUE, S_SET_VALUE):
Ditto.
* write.c (write_object_file): Ditto.
* config/obj-coff.c (obj_coff_def, obj_coff_val): Ditto.
* config/obj-coffbfd.c (obj_coff_def, obj_coff_val,
obj_coff_endef, yank_symbols): Ditto.
* config/obj-elf.c (obj_elf_stab_generic, obj_elf_size): Ditto.
* config/tc-a29k.c (md_assemble, parse_operand, machine_ip,
print_insn, md_operand): Ditto.
* config/tc-h8300.c (parse_exp, colonmod24, check_operand,
do_a_fix_imm, build_bytes): Ditto.
* config/tc-h8500.c (parse_exp, skip_colonthing, parse_reglist,
get_specific, check, insert, md_convert_frag): Ditto.
* config/tc-hppa.c (the_insn, fix_new_hppa, cons_fix_new_hppa,
md_assemble, pa_ip, getExpression, getAbsoluteExpression,
evaluateAbsolute, pa_build_unwind_subspace, pa_entry,
process_exit): Ditto.
* config/tc-hppa.h (STAB_FIXUP, is_DP_relative, is_PC_relative,
is_complex): Ditto.
* config/tc-i386.c (pe, md_assemble, i386_operand,
md_estimate_size_before_relax, md_create_long_jump): Ditto.
* config/tc-i860.c (md_assemble, getExpression, print_insn):
Ditto.
* config/tc-i960.c (parse_expr, subs, segs, md_convert_frag,
get_cdisp, mem_fmt, parse_ldconst, relax_cobr, s_sysproc,
i960_handle_align): Ditto.
* config/tc-m68k.c (struct m68k_exp, struct m68k_it, seg, op,
subs, add_fix, isvar, m68k_ip, md_assemble, md_convert_frag_1,
md_estimate_size_before_relax, md_create_long_jump, get_num):
Ditto.
* config/tc-m88k.c (md_assemble, get_imm16, get_pcr,
md_create_short_jump, md_create_long_jump): Ditto.
* config/tc-mips.c (md_assemble, append_insn, gp_reference,
macro_build, macro, my_getExpression): Ditto. Also removed
get_optional_absolute_expression; just use get_absolute_expression
instead.
* config/tc-ns32k.c (get_addr_mode, evaluate_expr, convert_iif,
fix_new_ns32k, fix_new_ns32k_exp, cons_fix_new_ns32k): Ditto.
* config/tc-ns32k.h (fix_new_ns32k prototype): Ditto.
* config/tc-sh.c (parse_exp, check, insert, md_convert_frag):
Ditto.
* config/tc-sparc.c (md_assemble, sparc_ip, getExpression,
print_insn): Ditto.
* config/tc-tahoe.c (struct top, md_estimate_size_before_relax,
tip_op, md_assemble): Ditto.
* config/tc-vax.c (seg_of_operand, md_assemble,
md_estimate_size_before_relax, md_create_long_jump): Ditto.
* config/tc-z8k.c (parse_exp, check_operand, newfix): Ditto.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/obj-aout.c | 5 | ||||
-rw-r--r-- | gas/config/obj-bout.c | 8 | ||||
-rw-r--r-- | gas/config/obj-coffbfd.c | 16 | ||||
-rw-r--r-- | gas/config/obj-elf.c | 11 | ||||
-rw-r--r-- | gas/config/obj-vms.c | 5 | ||||
-rw-r--r-- | gas/config/tc-a29k.c | 81 | ||||
-rw-r--r-- | gas/config/tc-h8300.c | 86 | ||||
-rw-r--r-- | gas/config/tc-h8500.c | 47 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 70 | ||||
-rw-r--r-- | gas/config/tc-i960.c | 190 | ||||
-rw-r--r-- | gas/config/tc-m88k.c | 78 | ||||
-rw-r--r-- | gas/config/tc-mips.c | 82 | ||||
-rw-r--r-- | gas/config/tc-sparc.c | 51 | ||||
-rw-r--r-- | gas/config/tc-tahoe.c | 88 |
14 files changed, 342 insertions, 476 deletions
diff --git a/gas/config/obj-aout.c b/gas/config/obj-aout.c index 38fead5..9b293fc 100644 --- a/gas/config/obj-aout.c +++ b/gas/config/obj-aout.c @@ -30,11 +30,8 @@ const short seg_N_TYPE[] = N_DATA, N_BSS, N_UNDF, /* unknown */ - N_UNDF, /* absent */ - N_UNDF, /* pass1 */ N_UNDF, /* error */ - N_UNDF, /* bignum/flonum */ - N_UNDF, /* difference */ + N_UNDF, /* expression */ N_UNDF, /* debug */ N_UNDF, /* ntv */ N_UNDF, /* ptv */ diff --git a/gas/config/obj-bout.c b/gas/config/obj-bout.c index d467715..6fc5b37 100644 --- a/gas/config/obj-bout.c +++ b/gas/config/obj-bout.c @@ -28,11 +28,11 @@ const short /* in: segT out: N_TYPE bits */ N_DATA, N_BSS, N_UNDF, /* unknown */ - N_UNDF, /* absent */ - N_UNDF, /* pass1 */ N_UNDF, /* error */ - N_UNDF, /* bignum/flonum */ - N_UNDF, /* difference */ + N_UNDF, /* expression */ + N_UNDF, /* debug */ + N_UNDF, /* ntv */ + N_UNDF, /* ptv */ N_REGISTER, /* register */ }; diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c index 88f815d..adbf2ab7d 100644 --- a/gas/config/obj-coffbfd.c +++ b/gas/config/obj-coffbfd.c @@ -1,5 +1,5 @@ /* coff object file format with bfd - Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. + Copyright (C) 1989, 1990, 1991, 1993 Free Software Foundation, Inc. This file is part of GAS. @@ -68,11 +68,8 @@ const short seg_N_TYPE[] = 9, 10, C_UNDEF_SECTION, /* SEG_UNKNOWN */ - C_UNDEF_SECTION, /* SEG_ABSENT */ - C_UNDEF_SECTION, /* SEG_PASS1 */ C_UNDEF_SECTION, /* SEG_GOOF */ - C_UNDEF_SECTION, /* SEG_BIG */ - C_UNDEF_SECTION, /* SEG_DIFFERENCE */ + C_UNDEF_SECTION, /* SEG_EXPR */ C_DEBUG_SECTION, /* SEG_DEBUG */ C_NTV_SECTION, /* SEG_NTV */ C_PTV_SECTION, /* SEG_PTV */ @@ -879,6 +876,7 @@ DEFUN (obj_coff_def, (what), def_symbol_in_progress->sy_name_offset = ~0; def_symbol_in_progress->sy_number = ~0; def_symbol_in_progress->sy_frag = &zero_address_frag; + S_SET_VALUE (def_symbol_in_progress, 0); if (S_IS_STRING (def_symbol_in_progress)) { @@ -994,7 +992,7 @@ DEFUN_VOID (obj_coff_endef) || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG && !SF_GET_TAG (def_symbol_in_progress)) || S_GET_SEGMENT (def_symbol_in_progress) == SEG_ABSOLUTE - || def_symbol_in_progress->sy_value.X_seg != absolute_section + || def_symbol_in_progress->sy_value.X_op != O_constant || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))) { @@ -1242,11 +1240,11 @@ obj_coff_val () } else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name)) { + def_symbol_in_progress->sy_value.X_op = O_symbol; def_symbol_in_progress->sy_value.X_add_symbol = symbol_find_or_make (symbol_name); - def_symbol_in_progress->sy_value.X_subtract_symbol = NULL; + def_symbol_in_progress->sy_value.X_op_symbol = NULL; def_symbol_in_progress->sy_value.X_add_number = 0; - def_symbol_in_progress->sy_value.X_seg = undefined_section; /* If the segment is undefined when the forward reference is resolved, then copy the segment id from the forward @@ -1377,7 +1375,7 @@ DEFUN_VOID (yank_symbols) /* L* and C_EFCN symbols never merge. */ if (!SF_GET_LOCAL (symbolP) && S_GET_STORAGE_CLASS (symbolP) != C_LABEL - && symbolP->sy_value.X_seg == absolute_section + && symbolP->sy_value.X_op == O_constant && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP)) && real_symbolP != symbolP) { diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 5f4f181..7d99c9a 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -530,7 +530,7 @@ obj_elf_stab_generic (what, secname) subseg_new ((char *) saved_seg->name, subseg); if ((what == 's' || what == 'n') - && symbolP->sy_value.X_seg == absolute_section) + && symbolP->sy_value.X_op == O_constant) { /* symbol is not needed in the regular symbol table */ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); @@ -718,7 +718,6 @@ obj_elf_size () char c = get_symbol_end (); char *p; expressionS exp; - segT sec; symbolS *sym; p = input_line_pointer; @@ -733,17 +732,17 @@ obj_elf_size () return; } input_line_pointer++; - sec = expression (&exp); - if (sec == absent_section) + expression (&exp); + if (exp.X_op == O_absent) { as_bad ("missing expression in .size directive"); - exp.X_seg = absolute_section; + exp.X_op = O_constant; exp.X_add_number = 0; } *p = 0; sym = symbol_find_or_make (name); *p = c; - if (sec == absolute_section) + if (exp.X_op == O_constant) S_SET_SIZE (sym, exp.X_add_number); else { diff --git a/gas/config/obj-vms.c b/gas/config/obj-vms.c index 3c29d18..b8c75e2 100644 --- a/gas/config/obj-vms.c +++ b/gas/config/obj-vms.c @@ -287,11 +287,8 @@ const short seg_N_TYPE[] = N_DATA, N_BSS, N_UNDF, /* unknown */ - N_UNDF, /* absent */ - N_UNDF, /* pass1 */ N_UNDF, /* error */ - N_UNDF, /* bignum/flonum */ - N_UNDF, /* difference */ + N_UNDF, /* expression */ N_UNDF, /* debug */ N_UNDF, /* ntv */ N_UNDF, /* ptv */ diff --git a/gas/config/tc-a29k.c b/gas/config/tc-a29k.c index f14bf96..1ed07df 100644 --- a/gas/config/tc-a29k.c +++ b/gas/config/tc-a29k.c @@ -1,5 +1,5 @@ /* tc-a29k.c -- Assemble for the AMD 29000. - Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -385,16 +385,12 @@ md_assemble (str) /* put out the symbol-dependent stuff */ if (the_insn.reloc != NO_RELOC) { - fix_new ( - frag_now, /* which frag */ - (toP - frag_now->fr_literal + the_insn.reloc_offset), /* where */ - 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, - the_insn.pcrel, - the_insn.reloc - ); + fix_new_exp (frag_now, + (toP - frag_now->fr_literal + the_insn.reloc_offset), + 4, /* size */ + &the_insn.exp, + the_insn.pcrel, + the_insn.reloc); } } @@ -405,15 +401,12 @@ parse_operand (s, operandp) { char *save = input_line_pointer; char *new; - segT seg; input_line_pointer = s; - seg = expr (0, operandp); + if (expression (operandp) == O_absent) + as_bad ("missing operand"); new = input_line_pointer; input_line_pointer = save; - - if (seg == SEG_ABSENT) - as_bad ("Missing operand"); return new; } @@ -501,7 +494,7 @@ machine_ip (str) break; case 'v': /* Trap numbers (immediate field) */ - if (operand->X_seg == SEG_ABSOLUTE) + if (operand->X_op == O_constant) { if (operand->X_add_number < 256) { @@ -524,11 +517,11 @@ machine_ip (str) case 'i': /* We treat the two cases identically since we mashed them together in the opcode table. */ - if (operand->X_seg == SEG_REGISTER) + if (operand->X_op == O_register) goto general_reg; opcode |= IMMEDIATE_BIT; - if (operand->X_seg == SEG_ABSOLUTE) + if (operand->X_op == O_constant) { if (operand->X_add_number < 256) { @@ -551,10 +544,10 @@ machine_ip (str) case 'c': general_reg: /* lrNNN or grNNN or %%expr or a user-def register name */ - if (operand->X_seg != SEG_REGISTER) + if (operand->X_op != O_register) break; /* Only registers */ know (operand->X_add_symbol == 0); - know (operand->X_subtract_symbol == 0); + know (operand->X_op_symbol == 0); reg = operand->X_add_number; if (reg >= SREG) break; /* No special registers */ @@ -583,7 +576,7 @@ machine_ip (str) case 'x': /* 16 bit constant, zero-extended */ case 'X': /* 16 bit constant, one-extended */ - if (operand->X_seg == SEG_ABSOLUTE) + if (operand->X_op == O_constant) { opcode |= (operand->X_add_number & 0xFF) << 0 | ((operand->X_add_number & 0xFF00) << 8); @@ -594,7 +587,7 @@ machine_ip (str) continue; case 'h': - if (operand->X_seg == SEG_ABSOLUTE) + if (operand->X_op == O_constant) { opcode |= (operand->X_add_number & 0x00FF0000) >> 16 | (((unsigned long) operand->X_add_number @@ -608,8 +601,8 @@ machine_ip (str) case 'P': /* PC-relative jump address */ case 'A': /* Absolute jump address */ /* These two are treated together since we folded the - opcode table entries together. */ - if (operand->X_seg == SEG_ABSOLUTE) + opcode table entries together. */ + if (operand->X_op == O_constant) { opcode |= ABSOLUTE_BIT | (operand->X_add_number & 0x0003FC00) << 6 | @@ -623,7 +616,7 @@ machine_ip (str) continue; case 'e': /* Coprocessor enable bit for LOAD/STORE insn */ - if (operand->X_seg == SEG_ABSOLUTE) + if (operand->X_op == O_constant) { if (operand->X_add_number == 0) continue; @@ -636,7 +629,7 @@ machine_ip (str) break; case 'n': /* Control bits for LOAD/STORE instructions */ - if (operand->X_seg == SEG_ABSOLUTE && + if (operand->X_op == O_constant && operand->X_add_number < 128) { opcode |= (operand->X_add_number << 16); @@ -645,7 +638,7 @@ machine_ip (str) break; case 's': /* Special register number */ - if (operand->X_seg != SEG_REGISTER) + if (operand->X_op != O_register) break; /* Only registers */ if (operand->X_add_number < SREG) break; /* Not a special register */ @@ -653,7 +646,7 @@ machine_ip (str) continue; case 'u': /* UI bit of CONVERT */ - if (operand->X_seg == SEG_ABSOLUTE) + if (operand->X_op == O_constant) { if (operand->X_add_number == 0) continue; @@ -666,7 +659,7 @@ machine_ip (str) break; case 'r': /* RND bits of CONVERT */ - if (operand->X_seg == SEG_ABSOLUTE && + if (operand->X_op == O_constant && operand->X_add_number < 8) { opcode |= operand->X_add_number << 4; @@ -675,7 +668,7 @@ machine_ip (str) break; case 'd': /* FD bits of CONVERT */ - if (operand->X_seg == SEG_ABSOLUTE && + if (operand->X_op == O_constant && operand->X_add_number < 4) { opcode |= operand->X_add_number << 2; @@ -685,7 +678,7 @@ machine_ip (str) case 'f': /* FS bits of CONVERT */ - if (operand->X_seg == SEG_ABSOLUTE && + if (operand->X_op == O_constant && operand->X_add_number < 4) { opcode |= operand->X_add_number << 0; @@ -694,7 +687,7 @@ machine_ip (str) break; case 'C': - if (operand->X_seg == SEG_ABSOLUTE && + if (operand->X_op == O_constant && operand->X_add_number < 4) { opcode |= operand->X_add_number << 16; @@ -703,7 +696,7 @@ machine_ip (str) break; case 'F': - if (operand->X_seg == SEG_ABSOLUTE && + if (operand->X_op == O_constant && operand->X_add_number < 16) { opcode |= operand->X_add_number << 18; @@ -1031,10 +1024,10 @@ print_insn (insn) insn->exp.X_add_symbol ? (S_GET_NAME (insn->exp.X_add_symbol) ? S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0"); - fprintf (stderr, "\t\tX_sub_symbol = %s\n", - insn->exp.X_subtract_symbol ? - (S_GET_NAME (insn->exp.X_subtract_symbol) ? - S_GET_NAME (insn->exp.X_subtract_symbol) : "???") : "0"); + fprintf (stderr, "\t\tX_op_symbol = %s\n", + insn->exp.X_op_symbol ? + (S_GET_NAME (insn->exp.X_op_symbol) ? + S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0"); fprintf (stderr, "\t\tX_add_number = %d\n", insn->exp.X_add_number); fprintf (stderr, "}\n"); @@ -1141,22 +1134,22 @@ md_operand (expressionP) /* We have a numeric register expression. No biggy. */ input_line_pointer += 2; /* Skip %% */ (void) expression (expressionP); - if (expressionP->X_seg != SEG_ABSOLUTE + if (expressionP->X_op != O_constant || expressionP->X_add_number > 255) as_bad ("Invalid expression after %%%%\n"); - expressionP->X_seg = SEG_REGISTER; + expressionP->X_op = O_register; } else if (input_line_pointer[0] == '&') { /* We are taking the 'address' of a register...this one is not - in the manual, but it *is* in traps/fpsymbol.h! What they - seem to want is the register number, as an absolute number. */ + in the manual, but it *is* in traps/fpsymbol.h! What they + seem to want is the register number, as an absolute number. */ input_line_pointer++; /* Skip & */ (void) expression (expressionP); - if (expressionP->X_seg != SEG_REGISTER) + if (expressionP->X_op != O_register) as_bad ("Invalid register in & expression"); else - expressionP->X_seg = SEG_ABSOLUTE; + expressionP->X_op = O_constant; } } diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c index 4f31bb1..a7a1fc8 100644 --- a/gas/config/tc-h8300.c +++ b/gas/config/tc-h8300.c @@ -269,29 +269,13 @@ DEFUN (parse_exp, (s, op), { char *save = input_line_pointer; char *new; - segT seg; input_line_pointer = s; - seg = expr (0, op); + if (expression (op) == O_absent) + as_bad ("missing operand"); new = input_line_pointer; input_line_pointer = save; - if (SEG_NORMAL (seg)) - return new; - switch (seg) - { - case SEG_ABSOLUTE: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - case SEG_BIG: - case SEG_REGISTER: - return new; - case SEG_ABSENT: - as_bad ("Missing operand"); - return new; - default: - as_bad ("Don't understand operand of type %s", segment_name (seg)); - return new; - } + return new; } static char * @@ -365,7 +349,7 @@ colonmod24 (op, src) mode = L_16; } else if (op->exp.X_add_symbol - || op->exp.X_subtract_symbol) + || op->exp.X_op_symbol) mode = DSYMMODE; else mode = DMODE; @@ -722,7 +706,7 @@ DEFUN (check_operand, (operand, width, string), char *string) { if (operand->exp.X_add_symbol == 0 - && operand->exp.X_subtract_symbol == 0) + && operand->exp.X_op_symbol == 0) { /* No symbol involved, let's look at offset, it's dangerous if any of @@ -814,14 +798,13 @@ do_a_fix_imm (offset, operand, relaxing) } - fix_new (frag_now, - offset + where, - size, - operand->exp.X_add_symbol, - operand->exp.X_subtract_symbol, - (short) (operand->exp.X_add_number), - 0, - idx); + operand->exp.X_add_number = (short) operand->exp.X_add_number; + fix_new_exp (frag_now, + offset + where, + size, + &operand->exp, + 0, + idx); } } @@ -970,27 +953,25 @@ build_bytes (this_try, operand) operand->exp.X_add_number); } - fix_new (frag_now, - output - frag_now->fr_literal + where, - size, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - (char) (operand[i].exp.X_add_number - 1), - 1, - type); + oeprand[i].exp.X_add_number = + (char) (operand[i].exp.X_add_number - 1); + fix_new_exp (frag_now, + output - frag_now->fr_literal + where, + size, + &operand[i].exp, + 1, + type); } else if (x & MEMIND) { check_operand (operand + i, 0xff, "@@"); - fix_new (frag_now, - output - frag_now->fr_literal + 1, - 1, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - operand[i].exp.X_add_number, - 0, - R_RELBYTE); + fix_new_exp (frag_now, + output - frag_now->fr_literal + 1, + 1, + &operand[i].exp, + 0, + R_RELBYTE); } else if (x & ABSMOV) @@ -1009,14 +990,13 @@ build_bytes (this_try, operand) as_warn ("branch operand has odd offset (%x)\n", operand->exp.X_add_number); } - fix_new (frag_now, - output - frag_now->fr_literal, - 4, - operand[i].exp.X_add_symbol, - operand[i].exp.X_subtract_symbol, - (short) (operand[i].exp.X_add_number), - 0, - R_JMPL1); + operand[i].exp = (short) operand[i].exp.X_add_number; + fix_new_exp (frag_now, + output - frag_now->fr_literal, + 4, + &operand[i].exp, + 0, + R_JMPL1); } } diff --git a/gas/config/tc-h8500.c b/gas/config/tc-h8500.c index 4ad462e..404db3a 100644 --- a/gas/config/tc-h8500.c +++ b/gas/config/tc-h8500.c @@ -258,7 +258,6 @@ parse_exp (s, op, page) { char *save; char *new; - segT seg; save = input_line_pointer; @@ -284,26 +283,11 @@ parse_exp (s, op, page) input_line_pointer = s; - seg = expr (0, op); + if (expression (op) == O_absent) + as_bad ("missing operand"); new = input_line_pointer; input_line_pointer = save; - if (SEG_NORMAL (seg)) - return new; - switch (seg) - { - case SEG_ABSOLUTE: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: - case SEG_BIG: - case SEG_REGISTER: - return new; - case SEG_ABSENT: - as_bad ("Missing operand"); - return new; - default: - as_bad ("Don't understand operand of type %s", segment_name (seg)); - return new; - } + return new; } typedef enum @@ -366,7 +350,7 @@ skip_colonthing (sign, ptr, exp, def, size8, size16, size24) /* Let's work out the size from the context */ int n = exp->exp.X_add_number; if (size8 - && exp->exp.X_seg == SEG_ABSOLUTE + && exp->exp.X_op == O_constant && ((sign == exp_signed && (n >= -128 && n <= 127)) || (sign == exp_unsigned && (n >= 0 && (n <= 255))) || (sign == exp_sandu && (n >= -128 && (n <= 255))))) @@ -430,9 +414,9 @@ parse_reglist (src, op) } idx++; op->exp.X_add_symbol = 0; - op->exp.X_subtract_symbol = 0; + op->exp.X_op_symbol = 0; op->exp.X_add_number = mask; - op->exp.X_seg = SEG_ABSOLUTE; + op->exp.X_op = O_constant; op->type = IMM8; return idx; @@ -795,7 +779,7 @@ get_specific (opcode, operands) break; case QIM: if (user->type == IMM8 - && user->exp.X_seg == SEG_ABSOLUTE + && user->exp.X_op == O_constant && (user->exp.X_add_number == -2 || user->exp.X_add_number == -1 @@ -871,7 +855,7 @@ check (operand, low, high) int low; int high; { - if (operand->X_seg != SEG_ABSOLUTE + if (operand->X_op != O_constant || operand->X_add_number < low || operand->X_add_number > high) { @@ -889,14 +873,12 @@ insert (output, index, exp, reloc, pcrel) int reloc; int pcrel; { - fix_new (frag_now, - output - frag_now->fr_literal + index, - 4, /* always say size is 4, but we know better */ - exp->X_add_symbol, - exp->X_subtract_symbol, - exp->X_add_number, - pcrel, - reloc); + fix_new_exp (frag_now, + output - frag_now->fr_literal + index, + 4, /* always say size is 4, but we know better */ + &exp, + pcrel, + reloc); } void @@ -1399,7 +1381,6 @@ md_convert_frag (headers, fragP) fragP->fr_fix + inst_size, 4, fragP->fr_symbol, - 0, fragP->fr_offset, 0, R_H8500_PCREL16); diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 3774d93..3694ac2 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -1,5 +1,5 @@ /* i386.c -- Assemble code for the Intel 80386 - Copyright (C) 1989, 1991, 1992 Free Software Foundation. + Copyright (C) 1989, 1991, 1992, 1993 Free Software Foundation. This file is part of GAS, the GNU Assembler. @@ -522,7 +522,7 @@ static void pe (e) expressionS *e; { - fprintf (stdout, " segment %s\n", segment_name (e->X_seg)); + fprintf (stdout, " operation %d\n", e->X_op); fprintf (stdout, " add_number %d (%x)\n", e->X_add_number, e->X_add_number); if (e->X_add_symbol) @@ -531,10 +531,10 @@ pe (e) ps (e->X_add_symbol); fprintf (stdout, "\n"); } - if (e->X_subtract_symbol) + if (e->X_op_symbol) { - fprintf (stdout, " sub_symbol "); - ps (e->X_subtract_symbol); + fprintf (stdout, " op_symbol "); + ps (e->X_op_symbol); fprintf (stdout, "\n"); } } @@ -1254,10 +1254,10 @@ md_assemble (line) holds the correct displacement size. */ exp = &disp_expressions[i.disp_operands++]; i.disps[o] = exp; - exp->X_seg = absolute_section; + exp->X_op = O_constant; exp->X_add_number = 0; exp->X_add_symbol = (symbolS *) 0; - exp->X_subtract_symbol = (symbolS *) 0; + exp->X_op_symbol = (symbolS *) 0; } /* Select the correct segment for the memory operand. */ @@ -1337,11 +1337,8 @@ md_assemble (line) if (t->opcode_modifier & Jump) { int n = i.disps[0]->X_add_number; - segT seg; - seg = i.disps[0]->X_seg; - - if (seg == absolute_section) + if (i.disps[0]->X_op == O_constant) { if (fits_in_signed_byte (n)) { @@ -1417,7 +1414,7 @@ md_assemble (line) } p = frag_more (size); - if (i.disps[0]->X_seg == absolute_section) + if (i.disps[0]->X_op == O_constant) { md_number_to_chars (p, n, size); if (size == 1 && !fits_in_signed_byte (n)) @@ -1428,23 +1425,20 @@ md_assemble (line) } else { - fix_new (frag_now, p - frag_now->fr_literal, size, - i.disps[0]->X_add_symbol, i.disps[0]->X_subtract_symbol, - i.disps[0]->X_add_number, 1, NO_RELOC); + fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.disps[0], 1, NO_RELOC); } } else if (t->opcode_modifier & JumpInterSegment) { p = frag_more (1 + 2 + 4); /* 1 opcode; 2 segment; 4 offset */ p[0] = t->base_opcode; - if (i.imms[1]->X_seg == absolute_section) + if (i.imms[1]->X_op == O_constant) md_number_to_chars (p + 1, i.imms[1]->X_add_number, 4); else - fix_new (frag_now, p + 1 - frag_now->fr_literal, 4, - i.imms[1]->X_add_symbol, - i.imms[1]->X_subtract_symbol, - i.imms[1]->X_add_number, 0, NO_RELOC); - if (i.imms[0]->X_seg != absolute_section) + fix_new_exp (frag_now, p + 1 - frag_now->fr_literal, 4, + i.imms[1], 0, NO_RELOC); + if (i.imms[0]->X_op != O_constant) as_bad ("can't handle non absolute segment in long call/jmp"); md_number_to_chars (p + 5, i.imms[0]->X_add_number, 2); } @@ -1510,7 +1504,7 @@ md_assemble (line) { if (i.disps[n]) { - if (i.disps[n]->X_seg == absolute_section) + if (i.disps[n]->X_op == O_constant) { if (i.types[n] & (Disp8 | Abs8)) { @@ -1532,9 +1526,8 @@ md_assemble (line) { /* not absolute_section */ /* need a 32-bit fixup (don't support 8bit non-absolute disps) */ p = frag_more (4); - fix_new (frag_now, p - frag_now->fr_literal, 4, - i.disps[n]->X_add_symbol, i.disps[n]->X_subtract_symbol, - i.disps[n]->X_add_number, 0, NO_RELOC); + fix_new_exp (frag_now, p - frag_now->fr_literal, 4, + i.disps[n], 0, NO_RELOC); } } } @@ -1549,7 +1542,7 @@ md_assemble (line) { if (i.imms[n]) { - if (i.imms[n]->X_seg == absolute_section) + if (i.imms[n]->X_op == O_constant) { if (i.types[n] & (Imm8 | Imm8S)) { @@ -1579,9 +1572,8 @@ md_assemble (line) else size = 4; p = frag_more (size); - fix_new (frag_now, p - frag_now->fr_literal, size, - i.imms[n]->X_add_symbol, i.imms[n]->X_subtract_symbol, - i.imms[n]->X_add_number, 0, NO_RELOC); + fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.imms[n], 0, NO_RELOC); } } } @@ -1696,18 +1688,18 @@ i386_operand (operand_string) exp_seg = expression (exp); input_line_pointer = save_input_line_pointer; - if (exp_seg == absent_section) + if (exp.X_op == O_absent) { /* missing or bad expr becomes absolute 0 */ as_bad ("missing or invalid immediate expression '%s' taken as 0", operand_string); - exp->X_seg = absolute_section; + exp->X_op = O_constant; exp->X_add_number = 0; exp->X_add_symbol = (symbolS *) 0; - exp->X_subtract_symbol = (symbolS *) 0; + exp->X_op_symbol = (symbolS *) 0; i.types[this_operand] |= Imm; } - else if (exp_seg == absolute_section) + else if (exp.X_op == O_constant) { i.types[this_operand] |= smallest_imm_type (exp->X_add_number); } @@ -1937,18 +1929,18 @@ i386_operand (operand_string) as_bad ("Ignoring junk '%s' after expression", input_line_pointer); RESTORE_END_STRING (displacement_string_end); input_line_pointer = save_input_line_pointer; - if (exp_seg == absent_section) + if (exp.X_op == O_absent) { /* missing expr becomes absolute 0 */ as_bad ("missing or invalid displacement '%s' taken as 0", operand_string); i.types[this_operand] |= (Disp | Abs); - exp->X_seg = absolute_section; + exp->X_op = O_constant; exp->X_add_number = 0; exp->X_add_symbol = (symbolS *) 0; - exp->X_subtract_symbol = (symbolS *) 0; + exp->X_op_symbol = (symbolS *) 0; } - else if (exp_seg == absolute_section) + else if (exp.X_op == O_constant) { i.types[this_operand] |= SMALLEST_DISP_TYPE (exp->X_add_number); } @@ -2042,7 +2034,6 @@ md_estimate_size_before_relax (fragP, segment) fragP->fr_fix += 4; fix_new (fragP, old_fr_fix, 4, fragP->fr_symbol, - (symbolS *) 0, fragP->fr_offset, 1, NO_RELOC); break; @@ -2054,7 +2045,6 @@ md_estimate_size_before_relax (fragP, segment) fragP->fr_fix += 1 + 4; /* we've added an opcode byte */ fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, - (symbolS *) 0, fragP->fr_offset, 1, NO_RELOC); break; } @@ -2187,7 +2177,7 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) md_number_to_chars (ptr, 0xe9, 1); /* opcode for long jmp */ md_number_to_chars (ptr + 1, offset, 4); fix_new (frag, (ptr + 1) - frag->fr_literal, 4, - to_symbol, (symbolS *) 0, (long) 0, 0, NO_RELOC); + to_symbol, (offsetT) 0, 0, NO_RELOC); } else { diff --git a/gas/config/tc-i960.c b/gas/config/tc-i960.c index 773efc0..e2ed93d 100644 --- a/gas/config/tc-i960.c +++ b/gas/config/tc-i960.c @@ -1,5 +1,5 @@ /* tc-i960.c - All the i80960-specific stuff - Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This file is part of GAS. @@ -113,7 +113,7 @@ static int get_regnum (); /* Translate text to register number */ static int i_scan (); /* Lexical scan of instruction source */ static void mem_fmt (); /* Generate MEMA or MEMB instruction */ static void mema_to_memb (); /* Convert MEMA instruction to MEMB format */ -static segT parse_expr (); /* Parse an expression */ +static void parse_expr (); /* Parse an expression */ static int parse_ldconst (); /* Parse and replace a 'ldconst' pseudo-op */ static void parse_memop (); /* Parse a memory operand */ static void parse_po (); /* Parse machine-dependent pseudo-op */ @@ -208,9 +208,7 @@ const pseudo_typeS md_pseudo_table[] = /* Macros to extract info from an 'expressionS' structure 'e' */ #define adds(e) e.X_add_symbol -#define subs(e) e.X_subtract_symbol #define offs(e) e.X_add_number -#define segs(e) e.X_seg /* Branch-prediction bits for CTRL/COBR format opcodes */ @@ -1050,7 +1048,6 @@ md_convert_frag (headers, fragP) fragP->fr_opcode - fragP->fr_literal, 4, fragP->fr_symbol, - 0, fragP->fr_offset, 1, NO_RELOC); @@ -1239,7 +1236,6 @@ brtab_emit () symbol_find (buf), 0, 0, - 0, NO_RELOC); fixP->fx_im_disp = 2; /* 32-bit displacement fix */ } @@ -1502,51 +1498,49 @@ get_cdisp (dispP, ifmtP, instr, numbits, var_frag, callj) fixP = NULL; - switch (parse_expr (dispP, &e)) + parse_expr (dispP, &e); + switch (e.X_op) { - - case SEG_GOOF: + case O_illegal: as_bad ("expression syntax error"); - break; - case SEG_TEXT: - case SEG_UNKNOWN: - if (var_frag) - { - outP = frag_more (8); /* Allocate worst-case storage */ - md_number_to_chars (outP, instr, 4); - frag_variant (rs_machine_dependent, 4, 4, 1, - adds (e), offs (e), outP, 0, 0); + case O_symbol: + if (S_GET_SEGMENT (e.X_add_symbol) == text_section + || S_GET_SEGMENT (e.X_add_symbol) == undefined_section) + { + if (var_frag) + { + outP = frag_more (8); /* Allocate worst-case storage */ + md_number_to_chars (outP, instr, 4); + frag_variant (rs_machine_dependent, 4, 4, 1, + adds (e), offs (e), outP, 0, 0); + } + else + { + /* Set up a new fix structure, so address can be updated + * when all symbol values are known. + */ + outP = emit (instr); + fixP = fix_new (frag_now, + outP - frag_now->fr_literal, + 4, + adds (e), + offs (e), + 1, + NO_RELOC); + + fixP->fx_callj = callj; + + /* We want to modify a bit field when the address is + * known. But we don't need all the garbage in the + * bit_fix structure. So we're going to lie and store + * the number of bits affected instead of a pointer. + */ + fixP->fx_bit_fixP = (bit_fixS *) numbits; + } } else - { - /* Set up a new fix structure, so address can be updated - * when all symbol values are known. - */ - outP = emit (instr); - fixP = fix_new (frag_now, - outP - frag_now->fr_literal, - 4, - adds (e), - 0, - offs (e), - 1, - NO_RELOC); - - fixP->fx_callj = callj; - - /* We want to modify a bit field when the address is - * known. But we don't need all the garbage in the - * bit_fix structure. So we're going to lie and store - * the number of bits affected instead of a pointer. - */ - fixP->fx_bit_fixP = (bit_fixS *) numbits; - } - break; - - case SEG_DATA: - case SEG_BSS: - as_bad ("attempt to branch into different segment"); + as_bad ("attempt to branch into different segment"); break; default: @@ -1722,14 +1716,14 @@ mem_fmt (args, oP, callx) } /* Parse and process the displacement */ - switch (parse_expr (instr.e, &expr)) + parse_expr (instr.e, &expr); + switch (expr.X_op) { - - case SEG_GOOF: + case O_illegal: as_bad ("expression syntax error"); break; - case SEG_ABSOLUTE: + case O_constant: if (instr.disp == 32) { (void) emit (offs (expr)); /* Output displacement */ @@ -1740,28 +1734,24 @@ mem_fmt (args, oP, callx) if (offs (expr) & ~0xfff) { /* Won't fit in 12 bits: convert already-output - * instruction to MEMB format, output - * displacement. - */ + * instruction to MEMB format, output + * displacement. + */ mema_to_memb (outP); (void) emit (offs (expr)); } else { /* WILL fit in 12 bits: OR into opcode and - * overwrite the binary we already put out - */ + * overwrite the binary we already put out + */ instr.opcode |= offs (expr); md_number_to_chars (outP, instr.opcode, 4); } } break; - case SEG_DIFFERENCE: - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: + default: if (instr.disp == 12) { /* Displacement is dependent on a symbol, whose value @@ -1775,21 +1765,15 @@ mem_fmt (args, oP, callx) * this symbol's value becomes known. */ outP = emit ((long) 0); - fixP = fix_new (frag_now, - outP - frag_now->fr_literal, - 4, - adds (expr), - subs (expr), - offs (expr), - 0, - NO_RELOC); + fixP = fix_new_exp (frag_now, + outP - frag_now->fr_literal, + 4, + &expr, + 0, + NO_RELOC); fixP->fx_im_disp = 2; /* 32-bit displacement fix */ fixP->fx_bsr = callx; /*SAC LD RELAX HACK *//* Mark reloc as being in i stream */ break; - - default: - BAD_CASE (segs (expr)); - break; } } /* memfmt() */ @@ -1836,19 +1820,16 @@ mema_to_memb (opcodeP) * * An empty expression string is treated as an absolute 0. * - * Return "segment" to which the expression evaluates. - * Return SEG_GOOF regardless of expression evaluation if entire input + * Sets O_illegal regardless of expression evaluation if entire input * string is not consumed in the evaluation -- tolerate no dangling junk! * **************************************************************************** */ -static - segT +static void parse_expr (textP, expP) char *textP; /* Text of expression to be parsed */ expressionS *expP; /* Where to put the results of parsing */ { char *save_in; /* Save global here */ - segT seg; /* Segment to which expression evaluates */ symbolS *symP; know (textP); @@ -1856,10 +1837,9 @@ parse_expr (textP, expP) if (*textP == '\0') { /* Treat empty string as absolute 0 */ - expP->X_add_symbol = expP->X_subtract_symbol = NULL; + expP->X_add_symbol = expP->X_op_symbol = NULL; expP->X_add_number = 0; - seg = expP->X_seg = SEG_ABSOLUTE; - + exp->X_op = O_constant; } else { @@ -1870,13 +1850,14 @@ parse_expr (textP, expP) if (input_line_pointer - textP != strlen (textP)) { /* Did not consume all of the input */ - seg = SEG_GOOF; + expP->X_op = O_illegal; } symP = expP->X_add_symbol; if (symP && (hash_find (reg_hash, S_GET_NAME (symP)))) { /* Register name in an expression */ - seg = SEG_GOOF; + /* FIXME: this isn't much of a check any more. */ + expP->X_op = O_illegal; } input_line_pointer = save_in; /* Restore global */ @@ -1914,31 +1895,27 @@ parse_ldconst (arg) arg[3] = NULL; /* So we can tell at the end if it got used or not */ - switch (parse_expr (arg[1], &e)) + parse_expr (arg[1], &e); + switch (e.X_op) { - - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: - case SEG_DIFFERENCE: + default: /* We're dependent on one or more symbols -- use "lda" */ arg[0] = "lda"; break; - case SEG_ABSOLUTE: + case O_constant: /* Try the following mappings: - * ldconst 0,<reg> ->mov 0,<reg> - * ldconst 31,<reg> ->mov 31,<reg> - * ldconst 32,<reg> ->addo 1,31,<reg> - * ldconst 62,<reg> ->addo 31,31,<reg> - * ldconst 64,<reg> ->shlo 8,3,<reg> - * ldconst -1,<reg> ->subo 1,0,<reg> - * ldconst -31,<reg>->subo 31,0,<reg> - * - * anthing else becomes: - * lda xxx,<reg> - */ + * ldconst 0,<reg> ->mov 0,<reg> + * ldconst 31,<reg> ->mov 31,<reg> + * ldconst 32,<reg> ->addo 1,31,<reg> + * ldconst 62,<reg> ->addo 31,31,<reg> + * ldconst 64,<reg> ->shlo 8,3,<reg> + * ldconst -1,<reg> ->subo 1,0,<reg> + * ldconst -31,<reg>->subo 31,0,<reg> + * + * anthing else becomes: + * lda xxx,<reg> + */ n = offs (e); if ((0 <= n) && (n <= 31)) { @@ -1979,7 +1956,7 @@ parse_ldconst (arg) } break; - default: + case O_illegal: as_bad ("invalid constant"); return -1; break; @@ -2362,7 +2339,8 @@ parse_regop (regopP, optext, opdesc) } else { /* fixed point literal acceptable */ - if ((parse_expr (optext, &e) != SEG_ABSOLUTE) + parse_expr (optext, &e); + if (e.X_op != O_constant || (offs (e) < 0) || (offs (e) > 31)) { as_bad ("illegal literal"); @@ -2537,7 +2515,6 @@ relax_cobr (fragP) iP + 4 - fragP->fr_literal, 4, fragP->fr_symbol, - 0, fragP->fr_offset, 1, NO_RELOC); @@ -2711,7 +2688,8 @@ s_sysproc (n_ops, args) } /* bad arg count */ /* Parse "entry_num" argument and check it for validity. */ - if ((parse_expr (args[2], &exp) != SEG_ABSOLUTE) + parse_expr (args[2], &exp); + if (exp.X_op != O_constant || (offs (exp) < 0) || (offs (exp) > 31)) { @@ -3214,7 +3192,7 @@ i960_handle_align (fragp) } /* alignment directive */ - fixp = fix_new (fragp, fragp->fr_fix, fragp->fr_offset, 0, 0, 0, 0, + fixp = fix_new (fragp, fragp->fr_fix, fragp->fr_offset, 0, 0, 0, (int) fragp->fr_type); } diff --git a/gas/config/tc-m88k.c b/gas/config/tc-m88k.c index 1092250..801748f 100644 --- a/gas/config/tc-m88k.c +++ b/gas/config/tc-m88k.c @@ -1,7 +1,7 @@ /* m88k.c -- Assembler for the Motorola 88000 Contributed by Devon Bowen of Buffalo University and Torbjorn Granlund of the Swedish Institute of Computer Science. - Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc. + Copyright (C) 1989, 1990, 1991, 1993 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -274,9 +274,9 @@ md_assemble (op) /* try parsing this instruction into insn */ insn.exp.X_add_symbol = 0; - insn.exp.X_subtract_symbol = 0; + insn.exp.X_op_symbol = 0; insn.exp.X_add_number = 0; - insn.exp.X_seg = 0; + insn.exp.X_op = O_illegal; insn.reloc = NO_RELOC; while (!calcop (format, param, &insn)) @@ -306,47 +306,39 @@ md_assemble (op) case RELOC_LO16: case RELOC_HI16: - fix_new (frag_now, - thisfrag - frag_now->fr_literal + 2, - 2, - insn.exp.X_add_symbol, - insn.exp.X_subtract_symbol, - insn.exp.X_add_number, - 0, - insn.reloc); + fix_new_exp (frag_now, + thisfrag - frag_now->fr_literal + 2, + 2, + &insn.exp, + 0, + insn.reloc); break; case RELOC_IW16: - fix_new (frag_now, - thisfrag - frag_now->fr_literal, - 4, - insn.exp.X_add_symbol, - insn.exp.X_subtract_symbol, - insn.exp.X_add_number, - 0, - insn.reloc); + fix_new_exp (frag_now, + thisfrag - frag_now->fr_literal, + 4, + &insn.exp, + 0, + insn.reloc); break; case RELOC_PC16: - fix_new (frag_now, - thisfrag - frag_now->fr_literal + 2, - 2, - insn.exp.X_add_symbol, - insn.exp.X_subtract_symbol, - insn.exp.X_add_number, - 1, - insn.reloc); + fix_new_exp (frag_now, + thisfrag - frag_now->fr_literal + 2, + 2, + &insn.exp, + 1, + insn.reloc); break; case RELOC_PC26: - fix_new (frag_now, - thisfrag - frag_now->fr_literal, - 4, - insn.exp.X_add_symbol, - insn.exp.X_subtract_symbol, - insn.exp.X_add_number, - 1, - insn.reloc); + fix_new_exp (frag_now, + thisfrag - frag_now->fr_literal, + 4, + &insn.exp, + 1, + insn.reloc); break; default: @@ -542,7 +534,6 @@ get_imm16 (param, insn) { enum reloc_type reloc = NO_RELOC; unsigned int val; - segT seg; char *save_ptr; if (!strncmp (param, "hi16", 4) && !isalnum (param[4])) @@ -563,13 +554,13 @@ get_imm16 (param, insn) save_ptr = input_line_pointer; input_line_pointer = param; - seg = expression (&insn->exp); + expression (&insn->exp); param = input_line_pointer; input_line_pointer = save_ptr; val = insn->exp.X_add_number; - if (seg == SEG_ABSOLUTE) + if (insn->exp.X_op == O_constant) { /* Insert the value now, and reset reloc to NO_RELOC. */ if (reloc == NO_RELOC) @@ -602,17 +593,16 @@ get_pcr (param, insn, reloc) enum reloc_type reloc; { char *saveptr, *saveparam; - segT seg; saveptr = input_line_pointer; input_line_pointer = param; - seg = expression (&insn->exp); + expression (&insn->exp); saveparam = input_line_pointer; input_line_pointer = saveptr; - /* Botch: We should relocate now if SEG_ABSOLUTE. */ + /* Botch: We should relocate now if O_constant. */ insn->reloc = reloc; return saveparam; @@ -1148,8 +1138,7 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) ptr - frag->fr_literal, 4, to_symbol, - (symbolS *) 0, - (long int) 0, + (offsetT) 0, 0, RELOC_PC26); /* Botch: Shouldn't this be RELOC_PC16? */ } @@ -1171,8 +1160,7 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) ptr - frag->fr_literal, 4, to_symbol, - (symbolS *) 0, - (long int) 0, + (offsetT) 0, 0, RELOC_PC26); } diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 9075b26..db0671e 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -161,7 +161,6 @@ static void mips_ip PARAMS ((char *str, struct mips_cl_insn * ip)); static int my_getSmallExpression PARAMS ((expressionS * ep, char *str)); static void my_getExpression PARAMS ((expressionS * ep, char *str)); static symbolS *get_symbol PARAMS ((void)); -static long get_optional_absolute_expression PARAMS ((void)); static void mips_align PARAMS ((int to, int fill)); static void s_align PARAMS ((int)); static void s_stringer PARAMS ((int)); @@ -336,8 +335,8 @@ md_assemble (str) init = 1; } - imm_expr.X_seg = absent_section; - offset_expr.X_seg = absent_section; + imm_expr.X_op = O_absent; + offset_expr.X_op = O_absent; mips_ip (str, &insn); if (insn_error) @@ -351,9 +350,9 @@ md_assemble (str) } else { - if (imm_expr.X_seg != absent_section) + if (imm_expr.X_op != O_absent) append_insn (&insn, &imm_expr, imm_reloc); - else if (offset_expr.X_seg != absent_section) + else if (offset_expr.X_op != O_absent) append_insn (&insn, &offset_expr, offset_reloc); else append_insn (&insn, NULL, BFD_RELOC_UNUSED); @@ -571,7 +570,7 @@ append_insn (ip, address_expr, reloc_type) fixp = NULL; if (address_expr != NULL) { - if (address_expr->X_seg == &bfd_abs_section) + if (address_expr->X_op == O_constant) { switch (reloc_type) { @@ -595,12 +594,10 @@ append_insn (ip, address_expr, reloc_type) { assert (reloc_type != BFD_RELOC_UNUSED); need_reloc: - fixp = fix_new (frag_now, f - frag_now->fr_literal, 4, - address_expr->X_add_symbol, - address_expr->X_subtract_symbol, - address_expr->X_add_number, - reloc_type == BFD_RELOC_16_PCREL_S2, - reloc_type); + fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 4, + address_expr, + reloc_type == BFD_RELOC_16_PCREL_S2, + reloc_type); } } @@ -816,7 +813,7 @@ gp_reference (ep) sym = ep->X_add_symbol; if (sym == (symbolS *) NULL - || ep->X_subtract_symbol != (symbolS *) NULL) + || ep->X_op_symbol != (symbolS *) NULL) return 0; /* Certain symbols can not be referenced off the GP, although it @@ -968,7 +965,7 @@ macro_build (counter, ep, name, fmt, va_alist) * input, in which case the value is not checked for range nor * is a relocation entry generated (yuck). */ - if (ep->X_add_symbol == NULL && ep->X_seg == &bfd_abs_section) + if (ep->X_op == O_constant) { insn.insn_opcode |= (ep->X_add_number >> 2) & 0xffff; ep = NULL; @@ -1010,7 +1007,7 @@ macro_build_lui (counter, ep, regnum) high_expr = *ep; - if (high_expr.X_seg == &bfd_abs_section) + if (high_expr.X_op == O_constant) { /* we can compute the instruction now without a relocation entry */ if (high_expr.X_add_number & 0x8000) @@ -1112,7 +1109,7 @@ check_absolute_expr (ip, expr) expressionS *expr; { - if (expr->X_seg != &bfd_abs_section) + if (expr->X_op != O_constant) as_warn ("Instruction %s requires absolute expression", ip->insn_mo->name); } @@ -1182,8 +1179,8 @@ macro (ip) sreg = breg = (ip->insn_opcode >> 21) & 0x1f; mask = ip->insn_mo->mask; - expr1.X_seg = &bfd_abs_section; - expr1.X_subtract_symbol = NULL; + expr1.X_op = O_constant; + expr1.X_op_symbol = NULL; expr1.X_add_symbol = NULL; expr1.X_add_number = 1; @@ -1582,7 +1579,7 @@ macro (ip) return; case M_LA: - if (offset_expr.X_seg == &bfd_abs_section) + if (offset_expr.X_op == O_constant) { load_register (&icnt, ip, treg, &offset_expr); return; @@ -1598,7 +1595,7 @@ macro (ip) case M_LA_AB: tempreg = (breg == treg) ? AT : treg; - if (offset_expr.X_seg == &bfd_abs_section) + if (offset_expr.X_op == O_constant) load_register (&icnt, ip, tempreg, &offset_expr); else if (gp_reference (&offset_expr)) macro_build (&icnt, &offset_expr, "addiu", "t,r,j", tempreg, GP); @@ -2221,7 +2218,7 @@ macro (ip) case M_ULH_A: case M_ULHU_A: case M_ULW_A: - if (offset_expr.X_seg == &bfd_abs_section) + if (offset_expr.X_op == O_constant) load_register (&icnt, ip, AT, &offset_expr); else if (gp_reference (&offset_expr)) macro_build (&icnt, &offset_expr, "addiu", "t,r,j", AT, GP); @@ -2264,7 +2261,7 @@ macro (ip) case M_USH_A: case M_USW_A: - if (offset_expr.X_seg == &bfd_abs_section) + if (offset_expr.X_op == O_constant) load_register (&icnt, ip, AT, &offset_expr); else if (gp_reference (&offset_expr)) macro_build (&icnt, &offset_expr, "addiu", "t,r,j", AT, GP); @@ -2414,7 +2411,7 @@ mips_ip (str, ip) imm_expr.X_add_number = imm_expr.X_add_number % 32; } ip->insn_opcode |= imm_expr.X_add_number << 6; - imm_expr.X_seg = absent_section; + imm_expr.X_op = O_absent; s = expr_end; continue; @@ -2424,7 +2421,7 @@ mips_ip (str, ip) if ((unsigned) imm_expr.X_add_number > 1023) as_warn ("Illegal break code (%d)", imm_expr.X_add_number); ip->insn_opcode |= imm_expr.X_add_number << 16; - imm_expr.X_seg = absent_section; + imm_expr.X_op = O_absent; s = expr_end; continue; @@ -2434,7 +2431,7 @@ mips_ip (str, ip) if ((unsigned) imm_expr.X_add_number > 0xfffff) as_warn ("Illegal syscall code (%d)", imm_expr.X_add_number); ip->insn_opcode |= imm_expr.X_add_number << 6; - imm_expr.X_seg = absent_section; + imm_expr.X_op = O_absent; s = expr_end; continue; @@ -2625,7 +2622,7 @@ mips_ip (str, ip) { if (c != 'l') { - if (imm_expr.X_seg == &bfd_abs_section) + if (imm_expr.X_op == O_constant) imm_expr.X_add_number = (imm_expr.X_add_number >> 16) & 0xffff; else if (c == 'h') @@ -2668,8 +2665,8 @@ mips_ip (str, ip) * code pattern. */ if ((offset_expr.X_add_symbol - && offset_expr.X_seg != &bfd_abs_section) - || offset_expr.X_subtract_symbol + && offset_expr.X_op != O_constant) + || offset_expr.X_op_symbol || offset_expr.X_add_number > 32767 || offset_expr.X_add_number < -32768) break; @@ -2696,7 +2693,7 @@ mips_ip (str, ip) { if (c != 'l') { - if (imm_expr.X_seg == &bfd_abs_section) + if (imm_expr.X_op == O_constant) imm_expr.X_add_number = (imm_expr.X_add_number >> 16) & 0xffff; else if (c == 'h') @@ -2797,16 +2794,16 @@ my_getSmallExpression (ep, str) if (c) { /* %xx(reg) is an error */ - ep->X_seg = absent_section; + ep->X_op = O_absent; expr_end = str - 3; } else { - ep->X_seg = &bfd_abs_section; + ep->X_op = O_absent; expr_end = sp; } ep->X_add_symbol = NULL; - ep->X_subtract_symbol = NULL; + ep->X_op_symbol = NULL; ep->X_add_number = 0; } else @@ -2829,11 +2826,10 @@ my_getExpression (ep, str) char *str; { char *save_in; - asection *seg; save_in = input_line_pointer; input_line_pointer = str; - seg = expression (ep); + expression (ep); expr_end = input_line_pointer; input_line_pointer = save_in; } @@ -3157,20 +3153,6 @@ get_symbol () return p; } -static long -get_optional_absolute_expression () -{ - expressionS exp; - asection *s; - - s = expression (&exp); - if (!(s == &bfd_abs_section || s == big_section || s == absent_section)) - { - as_bad ("Bad Absolute Expression."); - } - return exp.X_add_number; -} - /* Align the current frag to a given power of two. The MIPS assembler also automatically adjusts any preceding label. */ @@ -3325,7 +3307,7 @@ s_extern (x) symbolP = get_symbol (); if (*input_line_pointer == ',') input_line_pointer++; - size = get_optional_absolute_expression (); + size = get_absolute_expression (); S_SET_VALUE (symbolP, size); S_SET_EXTERNAL (symbolP); @@ -3765,7 +3747,7 @@ s_frame (x) frame_reg = tc_get_register (); if (*input_line_pointer == ',') input_line_pointer++; - frame_off = get_optional_absolute_expression (); + frame_off = get_absolute_expression (); if (*input_line_pointer == ',') input_line_pointer++; pcreg = tc_get_register (); diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index 62df7b4..075308f 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -689,7 +689,7 @@ md_assemble (str) /* See if "set" operand is absolute and small; skip sethi if so. */ if (special_case == SPECIAL_CASE_SET - && the_insn.exp.X_seg == absolute_section) + && the_insn.exp.X_op == O_constant) { if (the_insn.exp.X_add_number >= -(1 << 12) && the_insn.exp.X_add_number < (1 << 12)) @@ -709,14 +709,12 @@ md_assemble (str) /* put out the symbol-dependent stuff */ if (the_insn.reloc != BFD_RELOC_NONE) { - fix_new (frag_now, /* which frag */ - (toP - frag_now->fr_literal), /* where */ - 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, - the_insn.pcrel, - the_insn.reloc); + fix_new_exp (frag_now, /* which frag */ + (toP - frag_now->fr_literal), /* where */ + 4, /* size */ + &the_insn.exp, + the_insn.pcrel, + the_insn.reloc); } switch (special_case) @@ -725,22 +723,19 @@ md_assemble (str) special_case = 0; assert (the_insn.reloc == BFD_RELOC_HI22); /* See if "set" operand has no low-order bits; skip OR if so. */ - if (the_insn.exp.X_seg == absolute_section + if (the_insn.exp.X_op == O_constant && ((the_insn.exp.X_add_number & 0x3FF) == 0)) return; toP = frag_more (4); rsd = (the_insn.opcode >> 25) & 0x1f; the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14); md_number_to_chars (toP, (valueT) the_insn.opcode, 4); - fix_new (frag_now, /* which frag */ - (toP - frag_now->fr_literal), /* where */ - 4, /* size */ - the_insn.exp.X_add_symbol, - the_insn.exp.X_subtract_symbol, - the_insn.exp.X_add_number, - the_insn.pcrel, - BFD_RELOC_LO10 - ); + fix_new_exp (frag_now, /* which frag */ + (toP - frag_now->fr_literal), /* where */ + 4, /* size */ + &the_insn.exp, + the_insn.pcrel, + BFD_RELOC_LO10); return; case SPECIAL_CASE_FDIV: @@ -1545,8 +1540,8 @@ sparc_ip (str) #endif /* end-sanitize-v9 */ && the_insn.exp.X_add_symbol == 0 - && the_insn.exp.X_subtract_symbol == 0 - && the_insn.exp.X_seg == absolute_section + && the_insn.exp.X_op_symbol == 0 + && the_insn.exp.X_op == O_constant && (the_insn.exp.X_add_number > immediate_max || the_insn.exp.X_add_number < ~immediate_max)) as_bad ("constant value must be between %ld and %ld", @@ -1574,7 +1569,8 @@ sparc_ip (str) input_line_pointer = s; - if (expression (&e) == absolute_section) + expression (&e); + if (e.X_op == O_constant) { opcode |= e.X_add_number << 5; s = input_line_pointer; @@ -1793,10 +1789,7 @@ getExpression (str) || seg == text_section || seg == data_section || seg == bss_section - || seg == undefined_section - || seg == diff_section - || seg == big_section - || seg == absent_section) + || seg == undefined_section) /* ok */; else { @@ -2322,9 +2315,9 @@ print_insn (insn) : "???") : "0")); fprintf (stderr, "\t\tX_sub_symbol = %s\n", - ((insn->exp.X_subtract_symbol != NULL) - ? (S_GET_NAME (insn->exp.X_subtract_symbol) - ? S_GET_NAME (insn->exp.X_subtract_symbol) + ((insn->exp.X_op_symbol != NULL) + ? (S_GET_NAME (insn->exp.X_op_symbol) + ? S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0")); fprintf (stderr, "\t\tX_add_number = %d\n", diff --git a/gas/config/tc-tahoe.c b/gas/config/tc-tahoe.c index 7bd97b5..5fc47d3 100644 --- a/gas/config/tc-tahoe.c +++ b/gas/config/tc-tahoe.c @@ -30,6 +30,8 @@ struct top /* tahoe instruction operand */ char *top_error; /* Say if operand is inappropriate */ + segT seg_of_operand; /* segment as returned by expression()*/ + expressionS exp_of_operand; /* The expression as parsed by expression()*/ byte top_dispsize; /* Number of bytes in the displacement if we @@ -665,7 +667,7 @@ md_estimate_size_before_relax (fragP, segment_type) *p |= TAHOE_PC_OR_LONG; /* We now know how big it will be, one long word. */ fragP->fr_fix += 1 + 4; - fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol, 0, + fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol, fragP->fr_offset, FX_PCREL32, NULL); frag_wane (fragP); } @@ -684,7 +686,7 @@ md_estimate_size_before_relax (fragP, segment_type) *p++ = TAHOE_JMP; *p++ = TAHOE_PC_REL_LONG; fragP->fr_fix += 1 + 1 + 1 + 4; - fix_new (fragP, old_fr_fix + 3, fragP->fr_symbol, 0, + fix_new (fragP, old_fr_fix + 3, fragP->fr_symbol, fragP->fr_offset, FX_PCREL32, NULL); frag_wane (fragP); } @@ -705,7 +707,7 @@ md_estimate_size_before_relax (fragP, segment_type) *p++ = TAHOE_JMP; *p++ = TAHOE_PC_REL_LONG; fragP->fr_fix += 2 + 2 + 4; - fix_new (fragP, old_fr_fix + 4, fragP->fr_symbol, 0, + fix_new (fragP, old_fr_fix + 4, fragP->fr_symbol, fragP->fr_offset, FX_PCREL32, NULL); frag_wane (fragP); } @@ -726,7 +728,7 @@ md_estimate_size_before_relax (fragP, segment_type) *p++ = TAHOE_JMP; *p++ = TAHOE_PC_REL_LONG; fragP->fr_fix += 2 + 2 + 2 + 4; - fix_new (fragP, old_fr_fix + 6, fragP->fr_symbol, 0, + fix_new (fragP, old_fr_fix + 6, fragP->fr_symbol, fragP->fr_offset, FX_PCREL32, NULL); frag_wane (fragP); } @@ -743,7 +745,7 @@ md_estimate_size_before_relax (fragP, segment_type) *fragP->fr_opcode = TAHOE_JMP; *p++ = TAHOE_PC_REL_LONG; fragP->fr_fix += 1 + 4; - fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol, 0, + fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol, fragP->fr_offset, FX_PCREL32, NULL); frag_wane (fragP); } @@ -1261,64 +1263,52 @@ tip_op (optex, topP) /* statement has no syntax goofs yet: lets sniff the expression */ input_line_pointer = point; expP = &(topP->exp_of_operand); - switch (expression (expP)) + topP->seg_of_operand = expression (expP); + switch (expP->X_op) { - /* If expression == SEG_PASS1, expression() will have set - need_pass_2 = 1. */ - case SEG_ABSENT: + case O_absent: /* No expression. For BSD4.2 compatibility, missing expression is - absolute 0 */ - expP->X_seg = SEG_ABSOLUTE; + absolute 0 */ + expP->X_op = O_constant; expP->X_add_number = 0; really_none = 1; - case SEG_ABSOLUTE: - /* for SEG_ABSOLUTE, we shouldnt need to set X_subtract_symbol, - X_add_symbol to any particular value. */ + case O_constant: + /* for SEG_ABSOLUTE, we shouldnt need to set X_op_symbol, + X_add_symbol to any particular value. */ /* But, we will program defensively. Since this situation occurs - rarely so it costs us little to do so. */ + rarely so it costs us little to do so. */ expP->X_add_symbol = NULL; - expP->X_subtract_symbol = NULL; + expP->X_op_symbol = NULL; /* How many bytes are needed to express this abs value? */ abs_width = ((((expP->X_add_number & 0xFFFFFF80) == 0) || ((expP->X_add_number & 0xFFFFFF80) == 0xFFFFFF80)) ? 1 : (((expP->X_add_number & 0xFFFF8000) == 0) || ((expP->X_add_number & 0xFFFF8000) == 0xFFFF8000)) ? 2 : 4); - case SEG_TEXT: - case SEG_DATA: - case SEG_BSS: - case SEG_UNKNOWN: + + case O_symbol: break; - case SEG_DIFFERENCE: + default: /* - * Major bug. We can't handle the case of a - * SEG_DIFFERENCE expression in a synthetic opcode - * variable-length instruction. - * We don't have a frag type that is smart enough to - * relax a SEG_DIFFERENCE, and so we just force all - * SEG_DIFFERENCEs to behave like SEG_PASS1s. - * Clearly, if there is a demand we can invent a new or - * modified frag type and then coding up a frag for this - * case will be easy. SEG_DIFFERENCE was invented for the - * .words after a CASE opcode, and was never intended for - * instruction operands. - */ + * Major bug. We can't handle the case of a operator + * expression in a synthetic opcode variable-length + * instruction. We don't have a frag type that is smart + * enough to relax a operator, and so we just force all + * operators to behave like SEG_PASS1s. Clearly, if there is + * a demand we can invent a new or modified frag type and + * then coding up a frag for this case will be easy. + */ need_pass_2 = 1; - case SEG_PASS1: op_bad = "Can't relocate expression error."; break; - case SEG_BIG: + case O_big: /* This is an error. Tahoe doesn't allow any expressions - bigger that a 32 bit long word. Any bigger has to be referenced - by address. */ + bigger that a 32 bit long word. Any bigger has to be referenced + by address. */ op_bad = "Expression is too large for a 32 bits."; break; - - default: - as_fatal ("Complier Bug: I got segment %d in tip_op.", expP->X_seg); - break; } if (*input_line_pointer != '\0') { @@ -1706,7 +1696,7 @@ md_assemble (instruction_string) /* Here to make main operand frag(s). */ this_add_number = expP->X_add_number; this_add_symbol = expP->X_add_symbol; - to_seg = expP->X_seg; + to_seg = operandP->seg_of_operand; know (to_seg == SEG_UNKNOWN || \ to_seg == SEG_ABSOLUTE || \ to_seg == SEG_DATA || \ @@ -1731,7 +1721,7 @@ md_assemble (instruction_string) branch), so I set up the frag, and let GAS do the rest. */ p = frag_more (dispsize); fix_new (frag_now, p - frag_now->fr_literal, - this_add_symbol, 0, this_add_number, + this_add_symbol, this_add_number, size_to_fx (dispsize, 1), NULL); } @@ -1810,7 +1800,7 @@ md_assemble (instruction_string) TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR : TAHOE_PC_REL_LONG); fix_new (frag_now, p - frag_now->fr_literal, - this_add_symbol, 0, this_add_number, + this_add_symbol, this_add_number, (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL); /* * Now (eg) BLEQ 1f @@ -1826,7 +1816,7 @@ md_assemble (instruction_string) TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR : TAHOE_PC_REL_LONG); fix_new (frag_now, p - frag_now->fr_literal, - this_add_symbol, 0, this_add_number, + this_add_symbol, this_add_number, (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL); /* Now (eg) JMP foo */ break; @@ -1840,7 +1830,7 @@ md_assemble (instruction_string) TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR : TAHOE_PC_REL_LONG); fix_new (frag_now, p - frag_now->fr_literal, - this_add_symbol, 0, this_add_number, + this_add_symbol, this_add_number, (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL); /* * Now (eg) ACBx 1f @@ -1859,7 +1849,7 @@ md_assemble (instruction_string) TAHOE_ABSOLUTE_ADDR ? TAHOE_ABSOLUTE_ADDR : TAHOE_PC_REL_LONG); fix_new (frag_now, p - frag_now->fr_literal, - this_add_symbol, 0, this_add_number, + this_add_symbol, this_add_number, (to_seg != SEG_ABSOLUTE) ? FX_PCREL32 : FX_32, NULL); /* * Now (eg) xOBxxx 1f @@ -1916,7 +1906,7 @@ md_assemble (instruction_string) p = frag_more (5); *p++ = TAHOE_IMMEDIATE_LONGWORD; fix_new (frag_now, p - frag_now->fr_literal, - this_add_symbol, 0, this_add_number, + this_add_symbol, this_add_number, FX_32, NULL); } else @@ -2009,7 +1999,7 @@ md_assemble (instruction_string) break; }; fix_new (frag_now, p + 1 - frag_now->fr_literal, - this_add_symbol, 0, this_add_number, + this_add_symbol, this_add_number, size_to_fx (dispsize, pc_rel), NULL); } break; |