+2009-02-06 Nick Clifton <nickc@redhat.com>
+
+ PR 9814
+ * config/tc-arm.c (MODE_RECORDED): New define.
+ (output_inst): Record the thumb_mode in the current frag.
+ (arm_handle_align): Ignore the MODE_RECORDED bit in tc_frag_data.
+ (arm_init_frag): Only set the tc_frag_data field if it has not
+ already been set.
+
2009-02-04 H.J. Lu <hongjiu.lu@intel.com>
AVX Programming Reference (January, 2009)
2: assemble for Thumb even though target CPU does not support thumb
instructions. */
static int thumb_mode = 0;
+/* A value distinct from the possible values for thumb_mode that we
+ can use to record whether thumb_mode has been copied into the
+ tc_frag_data field of a frag. */
+#define MODE_RECORDED (1 << 4)
/* If unified_syntax is true, we are processing the new unified
ARM/Thumb syntax. Important differences from the old ARM mode:
return;
to = frag_more (inst.size);
+ /* PR 9814: Record the thumb mode into the current frag so that we know
+ what type of NOP padding to use, if necessary. We override any previous
+ setting so that if the mode has changed then the NOPS that we use will
+ match the encoding of the last instruction in the frag. */
+ frag_now->tc_frag_data = thumb_mode | MODE_RECORDED;
if (thumb_mode && (inst.size > THUMB_SIZE))
{
if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
- if (fragP->tc_frag_data)
+ assert ((fragP->tc_frag_data & MODE_RECORDED) != 0);
+
+ if (fragP->tc_frag_data & (~ MODE_RECORDED))
{
if (target_big_endian)
noop = thumb_bigend_noop;
*p = 0;
}
-/* Perform target specific initialisation of a frag. */
+/* Perform target specific initialisation of a frag.
+ Note - despite the name this initialisation is not done when the frag
+ is created, but only when its type is assigned. A frag can be created
+ and used a long time before its type is set, so beware of assuming that
+ this initialisationis performed first. */
void
arm_init_frag (fragS * fragP)
{
- /* Record whether this frag is in an ARM or a THUMB area. */
- fragP->tc_frag_data = thumb_mode;
+ /* If the current ARM vs THUMB mode has not already
+ been recorded into this frag then do so now. */
+ if ((fragP->tc_frag_data & MODE_RECORDED) == 0)
+ fragP->tc_frag_data = thumb_mode | MODE_RECORDED;
}
#ifdef OBJ_ELF