aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog3
-rw-r--r--gas/config/tc-sh.c315
2 files changed, 162 insertions, 156 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 48ef58b..0c1b5fc 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,8 @@
Fri Dec 16 14:40:16 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
+ * config/tc-sh.c (md_begin): Don't fill in md_relax_table here.
+ (md_relax_table): Use static initialization.
+
* Makefile.in (CHECKFLAGS): Don't pass AS_FOR_TARGET,
CC_FOR_TARGET, OBJDUMP_FOR_TARGET, NM_FOR_TARGET; they're not
used.
diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c
index 0f5fb0f..d4e8ddf 100644
--- a/gas/config/tc-sh.c
+++ b/gas/config/tc-sh.c
@@ -30,10 +30,9 @@
#define DEFINE_TABLE
#include "../opcodes/sh-opc.h"
#include <ctype.h>
-
const char comment_chars[] = "!";
const char line_separator_chars[] = ";";
-const char line_comment_chars[] = "!";
+const char line_comment_chars[] = "!#";
/* This table describes all the machine specific pseudo-ops the assembler
has to support. The fields are:
@@ -45,11 +44,19 @@ const char line_comment_chars[] = "!";
void cons ();
void s_align_bytes ();
+int shl = 0;
+
+static void little()
+{
+ shl = 1;
+}
+
const pseudo_typeS md_pseudo_table[] =
{
{"int", cons, 4},
{"word", cons, 2},
{"form", listing_psize, 0},
+ {"little", little,0},
{"heading", listing_title, 0},
{"import", s_ignore, 0},
{"page", listing_eject, 0},
@@ -113,7 +120,28 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
#define UNCOND32_LENGTH 14
-const relax_typeS md_relax_table[C (END, 0)];
+const relax_typeS md_relax_table[C (END, 0)] = {
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { 0 },
+ /* C (COND_JUMP, COND8) */
+ { COND8_F, COND8_M, COND8_LENGTH, C (COND_JUMP, COND12) },
+ /* C (COND_JUMP, COND12) */
+ { COND12_F, COND12_M, COND12_LENGTH, C (COND_JUMP, COND32), },
+ /* C (COND_JUMP, COND32) */
+ { COND32_F, COND32_M, COND32_LENGTH, 0, },
+ { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+
+ { 0 },
+ /* C (UNCOND_JUMP, UNCOND12) */
+ { UNCOND12_F, UNCOND12_M, UNCOND12_LENGTH, C (UNCOND_JUMP, UNCOND32), },
+ /* C (UNCOND_JUMP, UNCOND32) */
+ { UNCOND32_F, UNCOND32_M, UNCOND32_LENGTH, 0, },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
+};
static struct hash_control *opcode_hash_control; /* Opcode mnemonics */
@@ -127,6 +155,7 @@ md_begin ()
{
sh_opcode_info *opcode;
char *prev_name = "";
+ register relax_typeS *table;
opcode_hash_control = hash_new ();
@@ -145,35 +174,6 @@ md_begin ()
opcode->name = prev_name;
}
}
-
- /* Initialize the relax table */
- md_relax_table[C (COND_JUMP, COND8)].rlx_forward = COND8_F;
- md_relax_table[C (COND_JUMP, COND8)].rlx_backward = COND8_M;
- md_relax_table[C (COND_JUMP, COND8)].rlx_length = COND8_LENGTH;
- md_relax_table[C (COND_JUMP, COND8)].rlx_more = C (COND_JUMP, COND12);
-
- md_relax_table[C (COND_JUMP, COND12)].rlx_forward = COND12_F;
- md_relax_table[C (COND_JUMP, COND12)].rlx_backward = COND12_M;
- md_relax_table[C (COND_JUMP, COND12)].rlx_length = COND12_LENGTH;
- md_relax_table[C (COND_JUMP, COND12)].rlx_more = C (COND_JUMP, COND32);
-
- md_relax_table[C (COND_JUMP, COND32)].rlx_forward = COND32_F;
- md_relax_table[C (COND_JUMP, COND32)].rlx_backward = COND32_M;
- md_relax_table[C (COND_JUMP, COND32)].rlx_length = COND32_LENGTH;
- md_relax_table[C (COND_JUMP, COND32)].rlx_more = 0;
-
-
- md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_forward = UNCOND12_F;
- md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_backward = UNCOND12_M;
- md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length = UNCOND12_LENGTH;
- md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_more = C (UNCOND_JUMP, UNCOND32);
-
- md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_forward = UNCOND32_F;
- md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_backward = UNCOND32_M;
- md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length = UNCOND32_LENGTH;
- md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_more = 0;
-
-
}
static int reg_m;
@@ -641,7 +641,9 @@ build_relax (opcode)
sh_opcode_info *opcode;
{
int len;
+ int high_byte = shl ? 1 : 0 ;
char *p;
+
if (opcode->arg[0] == A_BDISP8)
{
p = frag_var (rs_machine_dependent,
@@ -651,18 +653,18 @@ build_relax (opcode)
immediate.X_add_symbol,
immediate.X_add_number,
0);
- p[0] = (opcode->nibbles[0] << 4) | (opcode->nibbles[1]);
+ p[high_byte] = (opcode->nibbles[0] << 4) | (opcode->nibbles[1]);
}
else if (opcode->arg[0] == A_BDISP12)
{
p = frag_var (rs_machine_dependent,
md_relax_table[C (UNCOND_JUMP, UNCOND32)].rlx_length,
- len = md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length,
+ len = md_relax_table[C (UNCOND_JUMP, UNCOND12)].rlx_length,
C (UNCOND_JUMP, 0),
immediate.X_add_symbol,
immediate.X_add_number,
0);
- p[0] = (opcode->nibbles[0] << 4);
+ p[high_byte] = (opcode->nibbles[0] << 4);
}
}
@@ -678,7 +680,7 @@ build_Mytes (opcode, operand)
int index;
char nbuf[4];
char *output = frag_more (2);
-
+ int low_byte = shl ? 0 : 1;
nbuf[0] = 0;
nbuf[1] = 0;
nbuf[2] = 0;
@@ -702,39 +704,45 @@ build_Mytes (opcode, operand)
nbuf[index] = reg_m;
break;
case DISP_4:
- insert (output + 1, R_SH_IMM4, 0);
+ insert (output + low_byte, R_SH_IMM4, 0);
break;
case IMM_4BY4:
- insert (output + 1, R_SH_IMM4BY4, 0);
+ insert (output + low_byte, R_SH_IMM4BY4, 0);
break;
case IMM_4BY2:
- insert (output + 1, R_SH_IMM4BY2, 0);
+ insert (output + low_byte, R_SH_IMM4BY2, 0);
break;
case IMM_4:
- insert (output + 1, R_SH_IMM4, 0);
+ insert (output + low_byte, R_SH_IMM4, 0);
break;
case IMM_8BY4:
- insert (output + 1, R_SH_IMM8BY4, 0);
+ insert (output + low_byte, R_SH_IMM8BY4, 0);
break;
case IMM_8BY2:
- insert (output + 1, R_SH_IMM8BY2, 0);
+ insert (output + low_byte, R_SH_IMM8BY2, 0);
break;
case IMM_8:
- insert (output + 1, R_SH_IMM8, 0);
+ insert (output + low_byte, R_SH_IMM8, 0);
break;
case PCRELIMM_8BY4:
- insert (output + 1, R_SH_PCRELIMM8BY4, 1);
+ insert (output, R_SH_PCRELIMM8BY4, 1);
break;
case PCRELIMM_8BY2:
- insert (output + 1, R_SH_PCRELIMM8BY2, 1);
+ insert (output, R_SH_PCRELIMM8BY2, 1);
break;
default:
printf ("failed for %d\n", i);
}
}
}
- output[0] = (nbuf[0] << 4) | (nbuf[1]);
- output[1] = (nbuf[2] << 4) | (nbuf[3]);
+ if (shl) {
+ output[1] = (nbuf[0] << 4) | (nbuf[1]);
+ output[0] = (nbuf[2] << 4) | (nbuf[3]);
+ }
+ else {
+ output[0] = (nbuf[0] << 4) | (nbuf[1]);
+ output[1] = (nbuf[2] << 4) | (nbuf[3]);
+ }
}
/* This is the guts of the machine-dependent assembler. STR points to a
@@ -843,63 +851,66 @@ DEFUN (tc_headers_hook, (headers),
*/
char *
md_atof (type, litP, sizeP)
- char type;
+ int type;
char *litP;
int *sizeP;
{
int prec;
- LITTLENUM_TYPE words[MAX_LITTLENUMS];
- LITTLENUM_TYPE *wordP;
+ LITTLENUM_TYPE words[4];
char *t;
- char *atof_ieee ();
+ int i;
switch (type)
{
case 'f':
- case 'F':
- case 's':
- case 'S':
prec = 2;
break;
case 'd':
- case 'D':
- case 'r':
- case 'R':
prec = 4;
break;
- case 'x':
- case 'X':
- prec = 6;
- break;
-
- case 'p':
- case 'P':
- prec = 6;
- break;
-
default:
*sizeP = 0;
- return "Bad call to MD_NTOF()";
+ return "bad call to md_atof";
}
+
t = atof_ieee (input_line_pointer, type, words);
if (t)
input_line_pointer = t;
- *sizeP = prec * sizeof (LITTLENUM_TYPE);
- for (wordP = words; prec--;)
+ *sizeP = prec * 2;
+
+ if (shl)
{
- md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
- litP += sizeof (LITTLENUM_TYPE);
+ for (i = prec - 1; i >= 0; i--)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
}
- return 0;
+ else
+ {
+ for (i = 0; i < prec; i++)
+ {
+ md_number_to_chars (litP, (valueT) words[i], 2);
+ litP += 2;
+ }
+ }
+
+ return NULL;
}
+
+
CONST char *md_shortopts = "";
struct option md_longopts[] = {
-#define OPTION_RELAX (OPTION_MD_BASE)
+
+#define OPTION_RELAX (OPTION_MD_BASE)
+#define OPTION_LITTLE (OPTION_MD_BASE+1)
+
{"relax", no_argument, NULL, OPTION_RELAX},
+ {"little", no_argument, NULL, OPTION_LITTLE},
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);
@@ -914,6 +925,9 @@ md_parse_option (c, arg)
case OPTION_RELAX:
relax = 1;
break;
+ case OPTION_LITTLE:
+ shl = 1;
+ break;
default:
return 0;
@@ -972,6 +986,8 @@ md_convert_frag (headers, fragP)
{
unsigned char *buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
int donerelax = 0;
+ int highbyte = shl ? 1 : 0;
+ int lowbyte = shl ? 0 : 1;
int targ_addr = ((fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0) + fragP->fr_offset);
switch (fragP->fr_subtype)
{
@@ -983,7 +999,7 @@ md_convert_frag (headers, fragP)
int disp = targ_addr - next_inst - 2;
disp /= 2;
- md_number_to_chars (buffer + 1, disp & 0xff, 1);
+ md_number_to_chars (buffer + lowbyte, disp & 0xff, 1);
fragP->fr_fix += 2;
fragP->fr_var = 0;
}
@@ -998,9 +1014,9 @@ md_convert_frag (headers, fragP)
int disp = targ_addr - next_inst - 2;
disp /= 2;
- t = buffer[0] & 0xf0;
+ t = buffer[highbyte] & 0xf0;
md_number_to_chars (buffer, disp & 0xfff, 2);
- buffer[0] = (buffer[0] & 0xf) | t;
+ buffer[highbyte] = (buffer[highbyte] & 0xf) | t;
fragP->fr_fix += 2;
fragP->fr_var = 0;
}
@@ -1023,22 +1039,22 @@ md_convert_frag (headers, fragP)
int t = buffer[0] & 0x10;
disp /= 2;
+abort();
+ buffer[highbyte] = 0xa0; /* branch over move and disp */
+ buffer[lowbyte] = 3;
+ buffer[highbyte+2] = 0xd0 | JREG; /* Build mov insn */
+ buffer[lowbyte+2] = 0x00;
- buffer[0] = 0xa0; /* branch over move and disp */
- buffer[1] = 3;
- buffer[2] = 0xd0 | JREG; /* Build mov insn */
- buffer[3] = 0x00;
+ buffer[highbyte+4] = 0; /* space for 32 bit jump disp */
+ buffer[lowbyte+4] = 0;
+ buffer[highbyte+6] = 0;
+ buffer[lowbyte+6] = 0;
- buffer[4] = 0; /* space for 32 bit jump disp */
- buffer[5] = 0;
- buffer[6] = 0;
- buffer[7] = 0;
+ buffer[highbyte+8] = 0x40 | JREG; /* Build jmp @JREG */
+ buffer[lowbyte+8] = t ? 0xb : 0x2b;
- buffer[10] = 0x40 | JREG; /* Build jmp @JREG */
- buffer[11] = t ? 0xb : 0x2b;
-
- buffer[12] = 0x20; /* build nop */
- buffer[13] = 0x0b;
+ buffer[highbyte+10] = 0x20; /* build nop */
+ buffer[lowbyte+10] = 0x0b;
/* Make reloc for the long disp */
fix_new (fragP,
@@ -1064,11 +1080,11 @@ md_convert_frag (headers, fragP)
int disp = targ_addr - next_inst;
disp /= 2;
md_number_to_chars (buffer + 2, disp & 0xfff, 2);
- buffer[0] ^= 0x2; /* Toggle T/F bit */
- buffer[1] = 1; /* branch over jump and nop */
- buffer[2] = (buffer[2] & 0xf) | 0xa0; /* Build jump insn */
- buffer[4] = 0x20; /* Build nop */
- buffer[5] = 0x0b;
+ buffer[highbyte] ^= 0x2; /* Toggle T/F bit */
+ buffer[lowbyte] = 1; /* branch over jump and nop */
+ buffer[highbyte+2] = (buffer[highbyte+2] & 0xf) | 0xa0; /* Build jump insn */
+ buffer[lowbyte+5] = 0x20; /* Build nop */
+ buffer[lowbyte+5] = 0x0b;
fragP->fr_fix += 6;
fragP->fr_var = 0;
donerelax = 1;
@@ -1093,7 +1109,7 @@ md_convert_frag (headers, fragP)
int disp = targ_addr - next_inst;
disp /= 2;
-
+abort();
buffer[0] ^= 0x2; /* Toggle T/F bit */
#define JREG 14
buffer[1] = 5; /* branch over mov, jump, nop and ptr */
@@ -1154,6 +1170,7 @@ md_apply_fix (fixP, val)
{
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
int addr = fixP->fx_frag->fr_address + fixP->fx_where;
+ int lowbyte = shl ? 0 : 1;
if (fixP->fx_r_type == 0)
{
if (fixP->fx_size == 2)
@@ -1196,36 +1213,57 @@ md_apply_fix (fixP, val)
as_warn ("non aligned displacement at %x\n", addr);
#endif
/* val -= (addr + 4); */
- val += 3;
+ if (shl||1)
+ val += 1;
+ else
+ val += 3;
val /= 4;
if (val & ~0xff)
as_warn ("pcrel too far at %x\n", addr);
-
- *buf = val;
+ buf[lowbyte] = val;
break;
case R_SH_PCRELIMM8BY2:
addr &= ~1;
- if (val & 0x1)
- as_bad ("odd displacement at %x\n", addr);
+ /* if ((val & 0x1) != shl)
+ as_bad ("odd displacement at %x\n", addr);*/
/* val -= (addr + 4); */
- val++;
+/* if (!shl)
+ val++;*/
val /= 2;
if (val & ~0xff)
as_warn ("pcrel too far at %x\n", addr);
- *buf = val;
+ buf[lowbyte] = val;
break;
case R_SH_IMM32:
- *buf++ = val >> 24;
- *buf++ = val >> 16;
- *buf++ = val >> 8;
- *buf++ = val >> 0;
+ if (shl)
+ {
+ *buf++ = val >> 0;
+ *buf++ = val >> 8;
+ *buf++ = val >> 16;
+ *buf++ = val >> 24;
+ }
+ else
+ {
+ *buf++ = val >> 24;
+ *buf++ = val >> 16;
+ *buf++ = val >> 8;
+ *buf++ = val >> 0;
+ }
break;
case R_SH_IMM16:
- *buf++ = val >> 8;
- *buf++ = val >> 0;
+ if (shl)
+ {
+ *buf++ = val >> 0;
+ *buf++ = val >> 8;
+ }
+ else
+ {
+ *buf++ = val >> 8;
+ *buf++ = val >> 0;
+ }
break;
default:
@@ -1310,7 +1348,10 @@ md_number_to_chars (ptr, use, nbytes)
valueT use;
int nbytes;
{
- number_to_chars_bigendian (ptr, use, nbytes);
+ if (shl)
+ number_to_chars_littleendian (ptr, use, nbytes);
+ else
+ number_to_chars_bigendian (ptr, use, nbytes);
}
long
@@ -1325,22 +1366,6 @@ short
tc_coff_fix2rtype (fix_ptr)
fixS *fix_ptr;
{
- return fix_ptr->fx_r_type;
-}
-
-void
-tc_reloc_mangle (fix_ptr, intr, base)
- fixS *fix_ptr;
- struct internal_reloc *intr;
- bfd_vma base;
-
-{
- symbolS *symbol_ptr;
-
- symbol_ptr = fix_ptr->fx_addsy;
-
- /* If this relocation is attached to a symbol then it's ok
- to output it */
if (fix_ptr->fx_r_type == RELOC_32)
{
/* cons likes to create reloc32's whatever the size of the reloc..
@@ -1348,43 +1373,16 @@ tc_reloc_mangle (fix_ptr, intr, base)
switch (fix_ptr->fx_size)
{
case 2:
- intr->r_type = R_IMM16;
+ return R_SH_IMM16;
break;
case 1:
- intr->r_type = R_IMM8;
+ return R_SH_IMM8;
break;
default:
abort ();
}
}
- else
- {
- intr->r_type = fix_ptr->fx_r_type;
- }
-
- intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
- intr->r_offset = fix_ptr->fx_offset;
-
- /* Turn the segment of the symbol into an offset. */
- if (symbol_ptr)
- {
- symbolS *dot;
-
- dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
- if (dot)
- {
- intr->r_offset += S_GET_VALUE (symbol_ptr);
- intr->r_symndx = dot->sy_number;
- }
- else
- {
- intr->r_symndx = symbol_ptr->sy_number;
- }
- }
- else
- {
- intr->r_symndx = -1;
- }
+ return R_SH_IMM32;
}
int
@@ -1393,3 +1391,8 @@ tc_coff_sizemachdep (frag)
{
return md_relax_table[frag->fr_subtype].rlx_length;
}
+
+int
+sh_init_after_args()
+{
+}