[PATCH]: Fix gas 68HC12 indexed addressing code generation
Stephane Carrez
Stephane.Carrez@worldnet.fr
Thu Jan 11 12:19:00 GMT 2001
Hi!
For 68HC12 gas, the insns generated for
leax colSelect,x
was wrong when 'colSelect' is an external symbol.
I was trying to relax this symbol to 5-bit, 9-bit and
then to a 16-bit contant but what was generated is wrong.
I've integrated this patch to fix the relaxation for
this operand. I also added some test case.
Stephane
2001-01-11 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* config/tc-m68hc11.c (md_estimate_size_before_relax): Fix
STATE_INDEXED_OFFSET when the symbol is undefined (16-bit offset).
(build_indexed_byte): Don't relax indexed byte, use 16-bit offset
and fix_new_exp() instead.
(md_convert_frag): For indexed post byte use the symbol value
rather than the displacement.
(md_relax_table): Fix indexed offset relax.
2001-01-11 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* gas/m68hc11/opers12.s: Add more tests for index post byte.
* gas/m68hc11/opers12.d: Likewise.
Index: config/tc-m68hc11.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-m68hc11.c,v
retrieving revision 1.10
diff -p -r1.10 tc-m68hc11.c
*** tc-m68hc11.c 2001/01/11 19:42:47 1.10
--- tc-m68hc11.c 2001/01/11 20:14:11
*************** relax_typeS md_relax_table[] =
*** 85,91 ****
/* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
{(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
{(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
! {0, 0, 1, 0},
{1, 1, 0, 0},
/* Relax for dbeq/ibeq/tbeq r,<L>:
--- 85,91 ----
/* Relax for indexed offset: 5-bits, 9-bits, 16-bits. */
{(15), (-16), 0, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9)},
{(255), (-256), 1, ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16)},
! {0, 0, 2, 0},
{1, 1, 0, 0},
/* Relax for dbeq/ibeq/tbeq r,<L>:
*************** build_indexed_byte (op, format, move_ins
*** 1754,1768 ****
return 3;
}
}
! f = frag_more (1);
! number_to_chars_bigendian (f, byte, 1);
! #if 0
! fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
! &op->exp, false, BFD_RELOC_16);
! #endif
! frag_var (rs_machine_dependent, 2, 2,
! ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
! op->exp.X_add_symbol, val, f);
return 3;
}
--- 1754,1779 ----
return 3;
}
}
! if (op->reg1 != REG_PC)
! {
! byte = (byte << 3) | 0xe2;
! f = frag_more (1);
! number_to_chars_bigendian (f, byte, 1);
!
! f = frag_more (2);
! fix_new_exp (frag_now, f - frag_now->fr_literal, 2,
! &op->exp, false, BFD_RELOC_16);
! number_to_chars_bigendian (f, 0, 2);
! }
! else
! {
! f = frag_more (1);
! number_to_chars_bigendian (f, byte, 1);
! frag_var (rs_machine_dependent, 2, 2,
! ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
! op->exp.X_add_symbol,
! op->exp.X_add_number, f);
! }
return 3;
}
*************** md_convert_frag (abfd, sec, fragP)
*** 2425,2430 ****
--- 2436,2442 ----
fragS *fragP;
{
fixS *fixp;
+ long value;
long disp;
char *buffer_address = fragP->fr_literal;
*************** md_convert_frag (abfd, sec, fragP)
*** 2434,2441 ****
buffer_address += fragP->fr_fix;
/* The displacement of the address, from current location. */
! disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
! disp = (disp + fragP->fr_offset) - object_address;
disp += symbol_get_frag (fragP->fr_symbol)->fr_address;
switch (fragP->fr_subtype)
--- 2446,2453 ----
buffer_address += fragP->fr_fix;
/* The displacement of the address, from current location. */
! value = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
! disp = (value + fragP->fr_offset) - object_address;
disp += symbol_get_frag (fragP->fr_symbol)->fr_address;
switch (fragP->fr_subtype)
*************** md_convert_frag (abfd, sec, fragP)
*** 2485,2508 ****
break;
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
! fragP->fr_opcode[0] = fragP->fr_opcode[0] << 5;
! fragP->fr_opcode[0] |= disp & 0x1f;
break;
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
fragP->fr_opcode[0] |= 0xE0;
! fix_new (fragP, fragP->fr_fix + 1, 1,
fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
fragP->fr_fix += 1;
break;
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
! fragP->fr_opcode[0] |= 0xE2;
! fix_new (fragP, fragP->fr_fix, 2,
! fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
! fragP->fr_fix += 1;
break;
case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
--- 2497,2533 ----
break;
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS5):
! fragP->fr_opcode[0] = fragP->fr_opcode[0] << 6;
! if ((fragP->fr_opcode[0] & 0x0ff) == 0x0c0)
! fragP->fr_opcode[0] |= disp & 0x1f;
! else
! fragP->fr_opcode[0] |= value & 0x1f;
break;
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS9):
fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
fragP->fr_opcode[0] |= 0xE0;
! fix_new (fragP, fragP->fr_fix, 1,
fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_8);
fragP->fr_fix += 1;
break;
case ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_BITS16):
fragP->fr_opcode[0] = (fragP->fr_opcode[0] << 3);
! fragP->fr_opcode[0] |= 0xe2;
! if ((fragP->fr_opcode[0] & 0x0ff) == 0x0fa)
! {
! fixp = fix_new (fragP, fragP->fr_fix, 2,
! fragP->fr_symbol, fragP->fr_offset,
! 1, BFD_RELOC_16_PCREL);
! fixp->fx_pcrel_adjust = 2;
! }
! else
! {
! fix_new (fragP, fragP->fr_fix, 2,
! fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_16);
! }
! fragP->fr_fix += 2;
break;
case ENCODE_RELAX (STATE_XBCC_BRANCH, STATE_BYTE):
*************** md_estimate_size_before_relax (fragP, se
*** 2621,2633 ****
else
{
/* Switch the indexed operation to 16-bit mode. */
! if ((fragP->fr_opcode[1] & 0x21) == 0x20)
! fragP->fr_opcode[1] = (fragP->fr_opcode[1] >> 3) | 0xc0 | 0x02;
!
fragP->fr_fix++;
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
fragP->fr_offset, 0, BFD_RELOC_16);
! fragP->fr_fix += 2;
frag_wane (fragP);
}
break;
--- 2646,2657 ----
else
{
/* Switch the indexed operation to 16-bit mode. */
! fragP->fr_opcode[0] = fragP->fr_opcode[0] << 3;
! fragP->fr_opcode[0] |= 0xe2;
fragP->fr_fix++;
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
fragP->fr_offset, 0, BFD_RELOC_16);
! fragP->fr_fix++;
frag_wane (fragP);
}
break;
More information about the Binutils
mailing list