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
/* This is the table used by gas to figure out relaxing modes. The fields are
forward_branch reach, backward_branch reach, number of bytes it would take,
where the next biggest branch is. */
-const relax_typeS
- md_relax_table[] =
+const relax_typeS md_relax_table[] =
{
{
1, 1, 0, 0
#undef WB
/* End relax stuff */
\f
-static struct hash_control *op_hash = NULL; /* handle of the OPCODE hash table
- NULL means any use before md_begin() will
- crash */
+/* Handle of the OPCODE hash table. NULL means any use before
+ md_begin() will crash. */
+static struct hash_control *op_hash;
/* Init function. Build the hash table. */
void
md_begin ()
{
struct tot *tP;
- char *errorval = "";
+ char *errorval = 0;
int synthetic_too = 1; /* If 0, just use real opcodes. */
- if ((op_hash = hash_new ()))
- {
- for (tP = totstrs; *tP->name && !*errorval; tP++)
- {
- errorval = hash_insert (op_hash, tP->name, &tP->detail);
- }
- if (synthetic_too)
- {
- for (tP = synthetic_totstrs; *tP->name && !*errorval; tP++)
- {
- errorval = hash_insert (op_hash, tP->name, &tP->detail);
- }
- }
- }
- else
- {
- errorval = "Virtual memory exceeded";
- }
- if (*errorval)
- as_fatal (errorval);
-} /* md_begin */
+ op_hash = hash_new ();
-void
-md_end ()
-{
-} /* md_end */
+ for (tP = totstrs; *tP->name && !errorval; tP++)
+ errorval = hash_insert (op_hash, tP->name, &tP->detail);
+
+ if (synthetic_too)
+ for (tP = synthetic_totstrs; *tP->name && !errorval; tP++)
+ errorval = hash_insert (op_hash, tP->name, &tP->detail);
+
+ if (errorval)
+ as_fatal (errorval);
+}
\f
+CONST char *md_shortopts = "ad:STt:V";
+struct option md_longopts[] = {
+ {NULL, no_argument, NULL, 0}
+};
+size_t md_longopts_size = sizeof(md_longopts);
+
int
-md_parse_option (argP, cntP, vecP)
- char **argP;
- int *cntP;
- char ***vecP;
+md_parse_option (c, arg)
+ int c;
+ char *arg;
{
- char *temp_name; /* name for -t or -d options */
- char opt;
-
- switch (**argP)
+ switch (c)
{
case 'a':
- as_warn ("The -a option doesn't exits. (Dispite what the man page says!");
+ as_warn (_("The -a option doesn't exist. (Despite what the man page says!"));
+ break;
- case 'J':
- as_warn ("JUMPIFY (-J) not implemented, use psuedo ops instead.");
+ case 'd':
+ as_warn (_("Displacement length %s ignored!"), arg);
break;
case 'S':
- as_warn ("SYMBOL TABLE not implemented");
- break; /* SYMBOL TABLE not implemented */
+ as_warn (_("SYMBOL TABLE not implemented"));
+ break;
case 'T':
- as_warn ("TOKEN TRACE not implemented");
- break; /* TOKEN TRACE not implemented */
+ as_warn (_("TOKEN TRACE not implemented"));
+ break;
- case 'd':
case 't':
- opt = **argP;
- if (**argP)
- { /* Rest of argument is filename. */
- temp_name = *argP;
- while (**argP)
- (*argP)++;
- }
- else if (*cntP)
- {
- while (**argP)
- (*argP)++;
- --(*cntP);
- temp_name = *++(*vecP);
- **vecP = NULL; /* Remember this is not a file-name. */
- }
- else
- {
- as_warn ("I expected a filename after -%c.", opt);
- temp_name = "{absent}";
- }
-
- if (opt == 'd')
- as_warn ("Displacement length %s ignored!", temp_name);
- else
- as_warn ("I don't need or use temp. file \"%s\".", temp_name);
+ as_warn (_("I don't need or use temp. file \"%s\"."), arg);
break;
case 'V':
- as_warn ("I don't use an interpass file! -V ignored");
+ as_warn (_("I don't use an interpass file! -V ignored"));
break;
default:
return 0;
-
}
+
return 1;
}
+
+void
+md_show_usage (stream)
+ FILE *stream;
+{
+ fprintf(stream, _("\
+Tahoe options:\n\
+-a ignored\n\
+-d LENGTH ignored\n\
+-J ignored\n\
+-S ignored\n\
+-t FILE ignored\n\
+-T ignored\n\
+-V ignored\n"));
+}
\f
/* The functions in this section take numbers in the machine format, and
munges them into Tahoe byte order.
void /* Knows about order of bytes in address. */
md_number_to_chars (con, value, nbytes)
char con[]; /* Return 'nbytes' of chars here. */
- long int value; /* The value of the bits. */
+ valueT value; /* The value of the bits. */
int nbytes; /* Number of bytes in the output. */
{
- int n = nbytes;
- long int v = value;
-
- con += nbytes - 1; /* Tahoes is (Bleah!) big endian */
- while (nbytes--)
- {
- *con-- = value; /* Lint wants & MASK_CHAR. */
- value >>= BITS_PER_CHAR;
- }
- /* XXX line number probably botched for this warning message. */
- if (value != 0 && value != -1)
- as_warn ("Displacement (%ld) long for instruction field length (%d).", v, n);
+ number_to_chars_bigendian (con, value, nbytes);
}
#ifdef comment
fixS *fixP;
long val;
{
- /* char *place = fixP->fx_where + fixP->fx_frag->fr_literal; */
/* should never be called */
know (0);
- return;
-} /* tc_apply_fix() */
+}
void /* Knows about order of bytes in address. */
md_number_to_disp (con, value, nbytes)
? 2
: 42)))) << 5) & 0x60)
| ((!S_IS_DEFINED (fixP->fx_addsy) << 4) & 0x10));
-
- return;
-} /* tc_aout_fix_to_chars() */
+}
/* Relocate byte stuff */
\f
void
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
char *ptr;
- long from_addr, to_addr;
+ addressT from_addr, to_addr;
fragS *frag;
symbolS *to_symbol;
{
- long offset;
+ valueT offset;
offset = to_addr - (from_addr + 1);
*ptr++ = TAHOE_BRW;
void
md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
char *ptr;
- long from_addr, to_addr;
+ addressT from_addr, to_addr;
fragS *frag;
symbolS *to_symbol;
{
- long offset;
+ valueT offset;
offset = to_addr - (from_addr + 4);
*ptr++ = TAHOE_JMP;
*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);
}
*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);
}
*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);
}
*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);
}
*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);
}
* Caller will turn frag into a ".space 0".
*/
void
-md_convert_frag (headers, fragP)
+md_convert_frag (headers, seg, fragP)
object_headers *headers;
+ segT seg;
register fragS *fragP;
{
register char *addressP; /* -> _var to change. */
case 'l':
case 'L':
if (com_width)
- as_warn ("Casting a branch displacement is bad form, and is ignored.");
+ as_warn (_("Casting a branch displacement is bad form, and is ignored."));
else
{
c = (isupper (*point) ? tolower (*point) : *point);
}
if (ndx == -1)
{
- op_bad = "Couldn't parse the [index] in this operand.";
+ op_bad = _("Couldn't parse the [index] in this operand.");
end = point; /* Force all the rest of the tests to fail. */
}
}
else
{
- op_bad = "Couldn't find the opening '[' for the index of this operand.";
+ op_bad = _("Couldn't find the opening '[' for the index of this operand.");
end = point; /* Force all the rest of the tests to fail. */
}
}
}
else
{
- op_bad = "Couldn't find the opening '(' for the deref of this operand.";
+ op_bad = _("Couldn't find the opening '(' for the deref of this operand.");
end = point; /* Force all the rest of the tests to fail. */
}
}
{
if (dec_inc != ' ')
{
- op_bad = "Operand can't be both pre-inc and post-dec.";
+ op_bad = _("Operand can't be both pre-inc and post-dec.");
end = point;
}
else
}
if (imreg != -1 && reg != -1)
- op_bad = "I parsed 2 registers in this operand.";
+ op_bad = _("I parsed 2 registers in this operand.");
/*
* Evaluate whats left of the expression to see if it's valid.
/* 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.";
+ 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. */
- 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);
+ 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;
}
if (*input_line_pointer != '\0')
{
- op_bad = "Junk at end of expression.";
+ op_bad = _("Junk at end of expression.");
}
}
mode = TAHOE_DIRECT_REG;
if (deferred || immediate || (dec_inc != ' ') ||
(reg != -1) || !really_none)
- op_bad = "Syntax error in direct register mode.";
+ op_bad = _("Syntax error in direct register mode.");
else if (ndx != -1)
- op_bad = "You can't index a register in direct register mode.";
+ op_bad = _("You can't index a register in direct register mode.");
else if (imreg == SP_REG && access == 'r')
op_bad =
- "SP can't be the source operand with direct register addressing.";
+ _("SP can't be the source operand with direct register addressing.");
else if (access == 'a')
- op_bad = "Can't take the address of a register.";
+ op_bad = _("Can't take the address of a register.");
else if (access == 'b')
- op_bad = "Direct Register can't be used in a branch.";
+ op_bad = _("Direct Register can't be used in a branch.");
else if (width == 'q' && ((imreg % 2) || (imreg > 13)))
- op_bad = "For quad access, the register must be even and < 14.";
+ op_bad = _("For quad access, the register must be even and < 14.");
else if (call_width)
- op_bad = "You can't cast a direct register.";
+ op_bad = _("You can't cast a direct register.");
if (*op_bad == '\0')
{
/* No errors, check for warnings */
if (width == 'q' && imreg == 12)
- as_warn ("Using reg 14 for quadwords can tromp the FP register.");
+ as_warn (_("Using reg 14 for quadwords can tromp the FP register."));
reg = imreg;
}
/* -(SP) */
mode = TAHOE_AUTO_DEC;
if (deferred || immediate || !really_none)
- op_bad = "Syntax error in auto-dec mode.";
+ op_bad = _("Syntax error in auto-dec mode.");
else if (ndx != -1)
- op_bad = "You can't have an index auto dec mode.";
+ op_bad = _("You can't have an index auto dec mode.");
else if (access == 'r')
- op_bad = "Auto dec mode cant be used for reading.";
+ op_bad = _("Auto dec mode cant be used for reading.");
else if (reg != SP_REG)
- op_bad = "Auto dec only works of the SP register.";
+ op_bad = _("Auto dec only works of the SP register.");
else if (access == 'b')
- op_bad = "Auto dec can't be used in a branch.";
+ op_bad = _("Auto dec can't be used in a branch.");
else if (width == 'q')
- op_bad = "Auto dec won't work with quadwords.";
+ op_bad = _("Auto dec won't work with quadwords.");
/* We know: imm = -1, dec_inc != '-' */
}
else if (dec_inc == '+')
{
if (immediate || !really_none)
- op_bad = "Syntax error in one of the auto-inc modes.";
+ op_bad = _("Syntax error in one of the auto-inc modes.");
else if (deferred)
{
/* *(SP)+ */
mode = TAHOE_AUTO_INC_DEFERRED;
if (reg != SP_REG)
- op_bad = "Auto inc deferred only works of the SP register.";
+ op_bad = _("Auto inc deferred only works of the SP register.");
else if (ndx != -1)
- op_bad = "You can't have an index auto inc deferred mode.";
+ op_bad = _("You can't have an index auto inc deferred mode.");
else if (access == 'b')
- op_bad = "Auto inc can't be used in a branch.";
+ op_bad = _("Auto inc can't be used in a branch.");
}
else
{
/* (SP)+ */
mode = TAHOE_AUTO_INC;
if (access == 'm' || access == 'w')
- op_bad = "You can't write to an auto inc register.";
+ op_bad = _("You can't write to an auto inc register.");
else if (reg != SP_REG)
- op_bad = "Auto inc only works of the SP register.";
+ op_bad = _("Auto inc only works of the SP register.");
else if (access == 'b')
- op_bad = "Auto inc can't be used in a branch.";
+ op_bad = _("Auto inc can't be used in a branch.");
else if (width == 'q')
- op_bad = "Auto inc won't work with quadwords.";
+ op_bad = _("Auto inc won't work with quadwords.");
else if (ndx != -1)
- op_bad = "You can't have an index in auto inc mode.";
+ op_bad = _("You can't have an index in auto inc mode.");
}
/* We know: imm = -1, dec_inc == ' ' */
else if (reg != -1)
{
if ((ndx != -1) && (reg == SP_REG))
- op_bad = "You can't index the sp register.";
+ op_bad = _("You can't index the sp register.");
if (deferred)
{
/* *<disp>(Rn) */
mode = TAHOE_REG_DISP_DEFERRED;
if (immediate)
- op_bad = "Syntax error in register displaced mode.";
+ op_bad = _("Syntax error in register displaced mode.");
}
else if (really_none)
{
else
{
if (really_none)
- op_bad = "An offest is needed for this operand.";
+ op_bad = _("An offest is needed for this operand.");
if (deferred && immediate)
{
/* *$<ADDR> */
/* $<disp> */
mode = TAHOE_IMMEDIATE;
if (ndx != -1)
- op_bad = "You can't index a register in immediate mode.";
+ op_bad = _("You can't index a register in immediate mode.");
if (access == 'a')
- op_bad = "Immediate access can't be used as an address.";
+ op_bad = _("Immediate access can't be used as an address.");
/* ponder the wisdom of a cast because it doesn't do any good. */
}
else if (deferred)
/* Operation-code is ended with whitespace. */
if (p == instring)
{
- titP->tit_error = "No operator";
+ titP->tit_error = _("No operator");
count = 0;
titP->tit_opcode = 0;
}
*p = c; /* Restore char after op-code. */
if (twP == 0)
{
- titP->tit_error = "Unknown operator";
+ titP->tit_error = _("Unknown operator");
count = 0;
titP->tit_opcode = 0;
}
* past any one ',' that marks the end of this operand.
*/
if (!p[1])
- as_fatal ("Compiler bug: ODD number of bytes in arg structure %s.",
+ as_fatal (_("Compiler bug: ODD number of bytes in arg structure %s."),
twP->args);
else if (*instring)
{
count++; /* won another argument, may have an operr */
}
else
- alloperr = "Not enough operands";
+ alloperr = _("Not enough operands");
}
/* Restore the pointer. */
input_line_pointer = save_input_line_pointer;
if (*instring == ' ')
instring++; /* Skip whitespace. */
if (*instring)
- alloperr = "Too many operands";
+ alloperr = _("Too many operands");
}
titP->tit_error = alloperr;
}
*/
if (*t.tit_error)
{
- as_warn ("Ignoring statement due to \"%s\"", t.tit_error);
+ as_warn (_("Ignoring statement due to \"%s\""), t.tit_error);
}
else
{
/* 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 || \
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);
}
opcodeP);
break;
default:
- as_fatal ("Compliler bug: Got a case (%d) I wasn't expecting.",
+ as_fatal (_("Compliler bug: Got a case (%d) I wasn't expecting."),
operandP->top_width);
}
}
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
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;
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
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
break;
case 'b':
case 'w':
- as_warn ("Real branch displacements must be expressions.");
+ as_warn (_("Real branch displacements must be expressions."));
break;
default:
- as_fatal ("Complier error: I got an unknown synthetic branch :%c",
+ as_fatal (_("Complier error: I got an unknown synthetic branch :%c"),
operandP->top_width);
break;
}
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
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;
default:
- as_fatal ("Barf, bad mode %x\n", operandP->top_mode);
+ as_fatal (_("Barf, bad mode %x\n"), operandP->top_mode);
}
}
} /* for(operandP) */
return 0;
} /* md_undefined_symbol() */
-/* Parse an operand that is machine-specific.
- We just return without modifying the expression if we have nothing
- to do. */
-
-/* ARGSUSED */
-void
-md_operand (expressionP)
- expressionS *expressionP;
-{
-} /* md_operand() */
-
/* Round up a section size to the appropriate boundary. */
-long
+valueT
md_section_align (segment, size)
segT segment;
- long size;
+ valueT size;
{
return ((size + 7) & ~7); /* Round all sects to multiple of 8 */
} /* md_section_align() */