/* tc-moxie.c -- Assemble code for moxie
- Copyright 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2009-2016 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
const char FLT_CHARS[] = "rRsSfFdDxXpP";
const char EXP_CHARS[] = "eE";
-static int md_chars_to_number (char *val, int n);
+static valueT md_chars_to_number (char * buf, int n);
+
+/* Byte order. */
+extern int target_big_endian;
void
md_operand (expressionS *op __attribute__((unused)))
for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++)
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ target_big_endian = TARGET_BYTES_BIG_ENDIAN;
+
bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
}
op_end++;
op_end = parse_exp_save_ilp (op_end, &arg);
fix_new_exp (frag_now,
- ((p+1) - frag_now->fr_literal),
+ ((p + (target_big_endian ? 1 : 0)) - frag_now->fr_literal),
1,
&arg,
0,
iword += (a << 4);
}
break;
- case MOXIE_F1_ABi4:
+ case MOXIE_F1_ABi2:
iword = opcode->opcode << 8;
while (ISSPACE (*op_end))
op_end++;
op_end++;
op_end = parse_exp_save_ilp (op_end, &arg);
- offset = frag_more (4);
+ offset = frag_more (2);
fix_new_exp (frag_now,
(offset - frag_now->fr_literal),
- 4,
+ 2,
&arg,
0,
- BFD_RELOC_32);
+ BFD_RELOC_16);
if (*op_end != '(')
{
iword += (a << 4) + b;
}
break;
- case MOXIE_F1_AiB4:
+ case MOXIE_F1_AiB2:
iword = opcode->opcode << 8;
while (ISSPACE (*op_end))
op_end++;
int a, b;
op_end = parse_exp_save_ilp (op_end, &arg);
- offset = frag_more (4);
+ offset = frag_more (2);
fix_new_exp (frag_now,
(offset - frag_now->fr_literal),
- 4,
+ 2,
&arg,
0,
- BFD_RELOC_32);
+ BFD_RELOC_16);
if (*op_end != '(')
{
return NULL;
}
-\f
-const char *md_shortopts = "";
+
+enum options
+{
+ OPTION_EB = OPTION_MD_BASE,
+ OPTION_EL,
+};
struct option md_longopts[] =
{
- {NULL, no_argument, NULL, 0}
+ { "EB", no_argument, NULL, OPTION_EB},
+ { "EL", no_argument, NULL, OPTION_EL},
+ { NULL, no_argument, NULL, 0}
};
+
size_t md_longopts_size = sizeof (md_longopts);
+\f
+const char *md_shortopts = "";
-/* We have no target specific options yet, so these next
- two functions are empty. */
int
md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
{
- return 0;
+ switch (c)
+ {
+ case OPTION_EB:
+ target_big_endian = 1;
+ break;
+ case OPTION_EL:
+ target_big_endian = 0;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
}
void
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
{
+ fprintf (stream, _("\
+ -EB assemble for a big endian system (default)\n\
+ -EL assemble for a little endian system\n"));
}
/* Apply a fixup to the object file. */
void
-md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
+md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
{
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
switch (fixP->fx_r_type)
{
case BFD_RELOC_32:
- *buf++ = val >> 24;
- *buf++ = val >> 16;
- *buf++ = val >> 8;
- *buf++ = val >> 0;
+ if (target_big_endian)
+ {
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val >> 0;
+ }
+ else
+ {
+ buf[3] = val >> 24;
+ buf[2] = val >> 16;
+ buf[1] = val >> 8;
+ buf[0] = val >> 0;
+ }
+ buf += 4;
break;
case BFD_RELOC_16:
- *buf++ = val >> 8;
- *buf++ = val >> 0;
+ if (target_big_endian)
+ {
+ buf[0] = val >> 8;
+ buf[1] = val >> 0;
+ }
+ else
+ {
+ buf[1] = val >> 8;
+ buf[0] = val >> 0;
+ }
+ buf += 2;
break;
case BFD_RELOC_8:
fixP->fx_done = 1;
}
-/* Put number into target byte order (big endian). */
+/* Put number into target byte order. */
void
-md_number_to_chars (char *ptr, valueT use, int nbytes)
+md_number_to_chars (char * ptr, valueT use, int nbytes)
{
- number_to_chars_bigendian (ptr, use, nbytes);
+ if (target_big_endian)
+ number_to_chars_bigendian (ptr, use, nbytes);
+ else
+ number_to_chars_littleendian (ptr, use, nbytes);
}
/* Convert from target byte order to host byte order. */
-static int
-md_chars_to_number (char *val, int n)
+static valueT
+md_chars_to_number (char * buf, int n)
{
- int retval = 0;
+ valueT result = 0;
+ unsigned char * where = (unsigned char *) buf;
- while (n--)
+ if (target_big_endian)
+ {
+ while (n--)
+ {
+ result <<= 8;
+ result |= (*where++ & 255);
+ }
+ }
+ else
{
- retval <<= 8;
- retval |= (*val++ & 255);
+ while (n--)
+ {
+ result <<= 8;
+ result |= (where[n] & 255);
+ }
}
- return retval;
+ return result;
}
/* Generate a machine-dependent relocation. */
case BFD_RELOC_32:
return addr + 4;
case BFD_RELOC_MOXIE_10_PCREL:
- return addr;
+ /* Offset is from the end of the instruction. */
+ return addr + 2;
default:
abort ();
return addr;