/* tc-sh.c -- Assemble code for the Renesas / SuperH SH
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
parse_exp (char *s, sh_operand_info *op)
{
char *save;
- char *new;
+ char *new_pointer;
save = input_line_pointer;
input_line_pointer = s;
|| sh_PIC_related_p (op->immediate.X_op_symbol))
as_bad (_("misplaced PIC operand"));
#endif
- new = input_line_pointer;
+ new_pointer = input_line_pointer;
input_line_pointer = save;
- return new;
+ return new_pointer;
}
/* The many forms of operand:
}
/* Various routines to kill one day. */
-/* Equal to MAX_PRECISION in atof-ieee.c. */
-#define MAX_LITTLENUMS 6
-
-/* Turn a string in input_line_pointer into a floating point constant
- of type TYPE, and store the appropriate bytes in *LITP. The number
- of LITTLENUMS emitted is stored in *SIZEP . An error message is
- returned, or NULL on OK. */
char *
md_atof (int type, char *litP, int *sizeP)
{
- int prec;
- LITTLENUM_TYPE words[4];
- char *t;
- int i;
-
- switch (type)
- {
- case 'f':
- prec = 2;
- break;
-
- case 'd':
- prec = 4;
- break;
-
- default:
- *sizeP = 0;
- return _("bad call to md_atof");
- }
-
- t = atof_ieee (input_line_pointer, type, words);
- if (t)
- input_line_pointer = t;
-
- *sizeP = prec * 2;
-
- if (! target_big_endian)
- {
- for (i = prec - 1; i >= 0; i--)
- {
- md_number_to_chars (litP, (valueT) words[i], 2);
- litP += 2;
- }
- }
- else
- {
- for (i = 0; i < prec; i++)
- {
- md_number_to_chars (litP, (valueT) words[i], 2);
- litP += 2;
- }
- }
-
- return NULL;
+ return ieee_md_atof (type, litP, sizeP, target_big_endian);
}
/* Handle the .uses pseudo-op. This pseudo-op is used just before a
OPTION_NO_EXPAND,
OPTION_PT32,
#endif
+ OPTION_H_TICK_HEX,
OPTION_DUMMY /* Not used. This is just here to make it easy to add and subtract options from this enum. */
};
{"no-expand", no_argument, NULL, OPTION_NO_EXPAND},
{"expand-pt32", no_argument, NULL, OPTION_PT32},
#endif /* HAVE_SH64 */
+ { "h-tick-hex", no_argument, NULL, OPTION_H_TICK_HEX },
{NULL, no_argument, NULL, 0}
};
}
if (!preset_target_arch)
- as_bad ("Invalid argument to --isa option: %s", arg);
+ as_bad (_("Invalid argument to --isa option: %s"), arg);
}
break;
sh64_abi = sh64_abi_64;
}
else
- as_bad ("Invalid argument to --abi option: %s", arg);
+ as_bad (_("Invalid argument to --abi option: %s"), arg);
break;
case OPTION_NO_MIX:
break;
#endif /* HAVE_SH64 */
+ case OPTION_H_TICK_HEX:
+ enable_h_tick_hex = 1;
+ break;
+
default:
return 0;
}
break;
case BFD_RELOC_SH_PCRELIMM8BY4:
+ /* If we are dealing with a known destination ... */
+ if ((fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
+ && (fixP->fx_subsy == NULL || S_IS_DEFINED (fixP->fx_addsy)))
+ {
+ /* Don't silently move the destination due to misalignment.
+ The absolute address is the fragment base plus the offset into
+ the fragment plus the pc relative offset to the label. */
+ if ((fixP->fx_frag->fr_address + fixP->fx_where + val) & 3)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("offset to unaligned destination"));
+
+ /* The displacement cannot be zero or backward even if aligned.
+ Allow -2 because val has already been adjusted somewhere. */
+ if (val < -2)
+ as_bad_where (fixP->fx_file, fixP->fx_line, _("negative offset"));
+ }
+
/* The lower two bits of the PC are cleared before the
displacement is added in. We can assume that the destination
is on a 4 byte boundary. If this instruction is also on a 4
val = ((val >> shift)
| ((long) -1 & ~ ((long) -1 >> shift)));
}
+
+ /* Extend sign for 64-bit host. */
+ val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
if (max != 0 && (val < min || val > max))
as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
else if (max != 0)
bfd_get_reloc_code_name (r_type));
/* Set howto to a garbage value so that we can keep going. */
rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
- assert (rel->howto != NULL);
+ gas_assert (rel->howto != NULL);
}
#ifdef OBJ_ELF
else if (rel->howto->type == R_SH_IND12W)