/* tc-mcore.c -- Assemble code for M*Core
- Copyright 1999, 2000 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#include "subsegs.h"
#define DEFINE_TABLE
#include "../opcodes/mcore-opc.h"
-#include <ctype.h>
+#include "safe-ctype.h"
#include <string.h>
#ifdef OBJ_ELF
#define UNCD_JUMP 2
#define UNDEF_DISP 0
-#define COND12 1
-#define COND32 2
-#define UNCD12 1
-#define UNCD32 2
-#define UNDEF_WORD_DISP 4
-#define END 5
+#define DISP12 1
+#define DISP32 2
+#define UNDEF_WORD_DISP 3
#define C12_LEN 2
#define C32_LEN 10 /* allow for align */
cpu_type cpu = M340;
/* Initialize the relax table. */
-const relax_typeS md_relax_table[] =
-{
-{ 1, 1, 0, 0 }, /* 0: unused */
-{ 1, 1, 0, 0 }, /* 1: unused */
-{ 1, 1, 0, 0 }, /* 2: unused */
-{ 1, 1, 0, 0 }, /* 3: unused */
-{ 1, 1, 0, 0 }, /* 4: unused */
-{ 2048, -2046, C12_LEN, C(COND_JUMP, COND32) }, /* 5: C(COND_JUMP, COND12) */
-{ 0, 0, C32_LEN, 0 }, /* 6: C(COND_JUMP, COND32) */
-{ 1, 1, 0, 0 }, /* 7: unused */
-{ 1, 1, 0, 0 }, /* 8: unused */
-{ 2048, -2046, U12_LEN, C(UNCD_JUMP, UNCD32) }, /* 9: C(UNCD_JUMP, UNCD12) */
-{ 0, 0, U32_LEN, 0 }, /*10: C(UNCD_JUMP, UNCD32) */
-{ 1, 1, 0, 0 }, /*11: unused */
-{ 0, 0, 0, 0 } /*12: unused */
+const relax_typeS md_relax_table[] = {
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+
+ /* COND_JUMP */
+ { 0, 0, 0, 0 }, /* UNDEF_DISP */
+ { 2048, -2046, C12_LEN, C(COND_JUMP, DISP32) }, /* DISP12 */
+ { 0, 0, C32_LEN, 0 }, /* DISP32 */
+ { 0, 0, C32_LEN, 0 }, /* UNDEF_WORD_DISP */
+
+ /* UNCD_JUMP */
+ { 0, 0, 0, 0 }, /* UNDEF_DISP */
+ { 2048, -2046, U12_LEN, C(UNCD_JUMP, DISP32) }, /* DISP12 */
+ { 0, 0, U32_LEN, 0 }, /* DISP32 */
+ { 0, 0, U32_LEN, 0 } /* UNDEF_WORD_DISP */
+
};
/* Literal pool data structures. */
pool. */
char * ilp = input_line_pointer;
- while (*ilp != 0 && isspace(*ilp))
+ while (*ilp != 0 && ISSPACE (*ilp))
++ ilp;
if (strncmp (ilp, ".line", 5) == 0
- && (isspace (ilp[5]) || *ilp == '\n' || *ilp == '\r'))
+ && (ISSPACE (ilp[5]) || *ilp == '\n' || *ilp == '\r'))
;
else
dump_literals (0);
unsigned * reg;
{
/* Strip leading whitespace. */
- while (isspace (* s))
+ while (ISSPACE (* s))
++ s;
- if (tolower (s[0]) == 'r')
+ if (TOLOWER (s[0]) == 'r')
{
if (s[1] == '1' && s[2] >= '0' && s[2] <= '5')
{
return s + 2;
}
}
- else if ( tolower (s[0]) == 's'
- && tolower (s[1]) == 'p'
- && ! isalnum (s[2]))
+ else if ( TOLOWER (s[0]) == 's'
+ && TOLOWER (s[1]) == 'p'
+ && ! ISALNUM (s[2]))
{
* reg = 0;
return s + 2;
int i;
/* Strip leading whitespace. */
- while (isspace (* s))
+ while (ISSPACE (* s))
++s;
- if ((tolower (s[0]) == 'c' && tolower (s[1]) == 'r'))
+ if ((TOLOWER (s[0]) == 'c' && TOLOWER (s[1]) == 'r'))
{
if (s[2] == '3' && s[3] >= '0' && s[3] <= '1')
{
length = strlen (cregs[i].name);
for (j = 0; j < length; j++)
- buf[j] = tolower (s[j]);
+ buf[j] = TOLOWER (s[j]);
if (strncmp (cregs[i].name, buf, length) == 0)
{
};
for (i = 0; i < 2; i++)
- buf[i] = isascii (s[i]) ? tolower (s[i]) : 0;
+ buf[i] = TOLOWER (s[i]);
for (i = sizeof (psrmods) / sizeof (psrmods[0]); i--;)
{
char * new;
/* Skip whitespace. */
- while (isspace (* s))
+ while (ISSPACE (* s))
++ s;
save = input_line_pointer;
symbol_table_insert (brarsym);
output = frag_var (rs_machine_dependent,
- md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length,
- md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length,
+ md_relax_table[C (UNCD_JUMP, DISP32)].rlx_length,
+ md_relax_table[C (UNCD_JUMP, DISP12)].rlx_length,
C (UNCD_JUMP, 0), brarsym, 0, 0);
output[0] = INST_BYTE0 (MCORE_INST_BR); /* br .+xxx */
output[1] = INST_BYTE1 (MCORE_INST_BR);
* off = 0;
- while (isspace (* s))
+ while (ISSPACE (* s))
++ s;
if (* s == '(')
{
s = parse_reg (s + 1, reg);
- while (isspace (* s))
+ while (ISSPACE (* s))
++ s;
if (* s == ',')
}
}
- while (isspace (* s))
+ while (ISSPACE (* s))
++ s;
if (* s == ')')
char name[20];
/* Drop leading whitespace. */
- while (isspace (* str))
+ while (ISSPACE (* str))
str ++;
/* Find the op code end. */
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (*op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
op_end = parse_reg (op_end + 1, & reg);
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',') /* xtrb- r1,rx */
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg << 8;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= (reg << 8);
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == '-')
as_bad (_("ending register must be r15"));
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
}
op_end ++;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == '(')
as_fatal (_("first register must be r4"));
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == '-')
as_fatal (_("last register must be r7"));
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
op_end ++;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == '(')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ')')
inst |= reg << 4;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
op_end = input_line_pointer;
output = frag_var (rs_machine_dependent,
- md_relax_table[C (COND_JUMP, COND32)].rlx_length,
- md_relax_table[C (COND_JUMP, COND12)].rlx_length,
+ md_relax_table[C (COND_JUMP, DISP32)].rlx_length,
+ md_relax_table[C (COND_JUMP, DISP12)].rlx_length,
C (COND_JUMP, 0), e.X_add_symbol, e.X_add_number, 0);
isize = C32_LEN;
break;
op_end = input_line_pointer;
output = frag_var (rs_machine_dependent,
- md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length,
- md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length,
+ md_relax_table[C (UNCD_JUMP, DISP32)].rlx_length,
+ md_relax_table[C (UNCD_JUMP, DISP12)].rlx_length,
C (UNCD_JUMP, 0), e.X_add_symbol, e.X_add_number, 0);
isize = U32_LEN;
break;
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg << 4;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
inst |= reg;
/* Skip whitespace. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
++ op_end;
if (* op_end == ',')
}
/* Drop whitespace after all the operands have been parsed. */
- while (isspace (* op_end))
+ while (ISSPACE (* op_end))
op_end ++;
/* Give warning message if the insn has more operands than required. */
int targ_addr = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
- targ_addr += symbol_get_frag (fragP->fr_symbol)->fr_address;
switch (fragP->fr_subtype)
{
- case C (COND_JUMP, COND12):
- case C (UNCD_JUMP, UNCD12):
+ case C (COND_JUMP, DISP12):
+ case C (UNCD_JUMP, DISP12):
{
/* Get the address of the end of the instruction. */
int next_inst = fragP->fr_fix + fragP->fr_address + 2;
}
fragP->fr_fix += 2;
- fragP->fr_var = 0;
}
break;
- case C (COND_JUMP, COND32):
+ case C (COND_JUMP, DISP32):
case C (COND_JUMP, UNDEF_WORD_DISP):
{
/* A conditional branch wont fit into 12 bits so:
else
buffer[1] = 4; /* jmpi, ptr, and the 'tail pad' */
}
-
- fragP->fr_var = 0;
}
break;
- case C (UNCD_JUMP, UNCD32):
+ case C (UNCD_JUMP, DISP32):
case C (UNCD_JUMP, UNDEF_WORD_DISP):
{
/* An unconditional branch will not fit in 12 bits, make code which
fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_32);
fragP->fr_fix += U32_LEN;
}
-
- fragP->fr_var = 0;
}
break;
{
switch (fragP->fr_subtype)
{
+ default:
+ abort ();
+
case C (UNCD_JUMP, UNDEF_DISP):
/* Used to be a branch to somewhere which was unknown. */
if (!fragP->fr_symbol)
{
- fragP->fr_subtype = C (UNCD_JUMP, UNCD12);
- fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length;
+ fragP->fr_subtype = C (UNCD_JUMP, DISP12);
}
else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
{
- fragP->fr_subtype = C (UNCD_JUMP, UNCD12);
- fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD12)].rlx_length;
+ fragP->fr_subtype = C (UNCD_JUMP, DISP12);
}
else
{
fragP->fr_subtype = C (UNCD_JUMP, UNDEF_WORD_DISP);
- fragP->fr_var = md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
- return md_relax_table[C (UNCD_JUMP, UNCD32)].rlx_length;
}
break;
- default:
- abort ();
-
case C (COND_JUMP, UNDEF_DISP):
/* Used to be a branch to somewhere which was unknown. */
if (fragP->fr_symbol
{
/* Got a symbol and it's defined in this segment, become byte
sized - maybe it will fix up */
- fragP->fr_subtype = C (COND_JUMP, COND12);
- fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
+ fragP->fr_subtype = C (COND_JUMP, DISP12);
}
else if (fragP->fr_symbol)
{
/* Its got a segment, but its not ours, so it will always be long. */
fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);
- fragP->fr_var = md_relax_table[C (COND_JUMP, COND32)].rlx_length;
- return md_relax_table[C (COND_JUMP, COND32)].rlx_length;
}
else
{
/* We know the abs value. */
- fragP->fr_subtype = C (COND_JUMP, COND12);
- fragP->fr_var = md_relax_table[C (COND_JUMP, COND12)].rlx_length;
+ fragP->fr_subtype = C (COND_JUMP, DISP12);
}
+ break;
+ case C (UNCD_JUMP, DISP12):
+ case C (UNCD_JUMP, DISP32):
+ case C (UNCD_JUMP, UNDEF_WORD_DISP):
+ case C (COND_JUMP, DISP12):
+ case C (COND_JUMP, DISP32):
+ case C (COND_JUMP, UNDEF_WORD_DISP):
+ /* When relaxing a section for the second time, we don't need to
+ do anything besides return the current size. */
break;
}
- return fragP->fr_var;
+ return md_relax_table[fragP->fr_subtype].rlx_length;
}
/* Put number into target byte order. */