This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Patch to clean up h8300 parsing code
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: 07 Jul 2003 10:39:24 +0100
- Subject: Re: Patch to clean up h8300 parsing code
- References: <wvnd6gqy7ja.fsf@talisman.cambridge.redhat.com>
Richard Sandiford <rsandifo@talisman.cambridge.redhat.com> writes:
> * config/tc-h8300.c (h8300sxnmode): Add prototype.
> (DSYMMODE): Remove.
> (parse_exp): Replace expressionS argument with a h8_op. Parse the
> operand size as well.
> (skip_colonthing): Remove unused expression argument. Tighten
> checks for 2-digit sizes.
> (colonmod24): Remove.
> (get_mova_operands): Combine calls to parse_exp and skip_colonthing.
> (get_operand): Likewise. Use the standard code to read the size of
> pc-relative operands.
> (fix_operand_size): Include the size-guessing logic that used to be
> in colonmod24 and get_operand().
This wasn't right: it made fix_operand_size use 2-bit displacements
for addresses like @(foo+1,ERn). Fixed below.
Nick OKed the original in private, so since the change is obvious,
I checked this version in.
Richard
* config/tc-h8300.c (h8300sxnmode): Add prototype.
(DSYMMODE): Remove.
(parse_exp): Replace expressionS argument with a h8_op. Parse the
operand size as well.
(skip_colonthing): Remove unused expression argument. Tighten checks
for 2-digit sizes.
(colonmod24): Remove.
(get_mova_operands): Combine calls to parse_exp and skip_colonthing.
(get_operand): Likewise. Use the standard code to read the size of
pc-relative operands.
(fix_operand_size): Include the size-guessing logic that used to be
in colonmod24 and get_operand. Don't apply dd:2 optimizations to
offsets with a symbolic component.
testsuite/
* gas/h8300/h8sx_disp2.[sd]: Add tests for symbolic displacements.
Index: gas/config/tc-h8300.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-h8300.c,v
retrieving revision 1.33
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.33 tc-h8300.c
*** gas/config/tc-h8300.c 25 Jun 2003 15:31:58 -0000 1.33
--- gas/config/tc-h8300.c 7 Jul 2003 09:29:44 -0000
*************** const char comment_chars[] = ";";
*** 43,56 ****
const char line_comment_chars[] = "#";
const char line_separator_chars[] = "";
! void cons PARAMS ((int));
! void sbranch PARAMS ((int));
! void h8300hmode PARAMS ((int));
! void h8300smode PARAMS ((int));
! void h8300hnmode PARAMS ((int));
! void h8300snmode PARAMS ((int));
! void h8300sxmode PARAMS ((int));
! static void pint PARAMS ((int));
int Hmode;
int Smode;
--- 43,57 ----
const char line_comment_chars[] = "#";
const char line_separator_chars[] = "";
! void cons PARAMS ((int));
! void sbranch PARAMS ((int));
! void h8300hmode PARAMS ((int));
! void h8300smode PARAMS ((int));
! void h8300hnmode PARAMS ((int));
! void h8300snmode PARAMS ((int));
! void h8300sxmode PARAMS ((int));
! void h8300sxnmode PARAMS ((int));
! static void pint PARAMS ((int));
int Hmode;
int Smode;
*************** int Nmode;
*** 58,64 ****
int SXmode;
#define PSIZE (Hmode ? L_32 : L_16)
- #define DSYMMODE (Hmode ? L_24 : L_16)
int bsize = L_8; /* Default branch displacement. */
--- 59,64 ----
*************** static void build_bytes PARAMS ((cons
*** 339,350 ****
static void do_a_fix_imm PARAMS ((int, int, struct h8_op *, int));
static void check_operand PARAMS ((struct h8_op *, unsigned int, char *));
static const struct h8_instruction * get_specific PARAMS ((const struct h8_instruction *, struct h8_op *, int));
! static char * get_operands PARAMS ((unsigned, char *, struct h8_op *));
! static void get_operand PARAMS ((char **, struct h8_op *, int));
! static char * skip_colonthing PARAMS ((char *, expressionS *, int *));
! static char * parse_exp PARAMS ((char *, expressionS *));
! static int parse_reg PARAMS ((char *, op_type *, unsigned *, int));
! char * colonmod24 PARAMS ((struct h8_op *, char *));
static int constant_fits_width_p PARAMS ((struct h8_op *, unsigned int));
static int constant_fits_size_p PARAMS ((struct h8_op *, int, int));
--- 339,349 ----
static void do_a_fix_imm PARAMS ((int, int, struct h8_op *, int));
static void check_operand PARAMS ((struct h8_op *, unsigned int, char *));
static const struct h8_instruction * get_specific PARAMS ((const struct h8_instruction *, struct h8_op *, int));
! static char *get_operands PARAMS ((unsigned, char *, struct h8_op *));
! static void get_operand PARAMS ((char **, struct h8_op *, int));
! static int parse_reg PARAMS ((char *, op_type *, unsigned *, int));
! static char *skip_colonthing PARAMS ((char *, int *));
! static char *parse_exp PARAMS ((char *, struct h8_op *));
static int constant_fits_width_p PARAMS ((struct h8_op *, unsigned int));
static int constant_fits_size_p PARAMS ((struct h8_op *, int, int));
*************** parse_reg (src, mode, reg, direction)
*** 474,529 ****
return 0;
}
static char *
! parse_exp (s, op)
! char *s;
! expressionS *op;
{
! char *save = input_line_pointer;
! char *new;
! input_line_pointer = s;
! expression (op);
! if (op->X_op == O_absent)
as_bad (_("missing operand"));
! new = input_line_pointer;
input_line_pointer = save;
! return new;
}
static char *
! skip_colonthing (ptr, exp, mode)
! char *ptr;
! expressionS *exp ATTRIBUTE_UNUSED;
int *mode;
{
! if (*ptr == ':')
{
! ptr++;
*mode &= ~SIZE;
! if (ptr[0] == '8' && ! ISDIGIT (ptr[1]))
*mode |= L_8;
! else if (ptr[0] == '2' && ! ISDIGIT (ptr[1]))
*mode |= L_2;
! else if (ptr[0] == '3' && ! ISDIGIT (ptr[1]))
*mode |= L_3;
! else if (ptr[0] == '4' && ! ISDIGIT (ptr[1]))
*mode |= L_4;
! else if (ptr[0] == '5' && ! ISDIGIT (ptr[1]))
*mode |= L_5;
! else if (ptr[0] == '2' && ptr[1] == '4')
*mode |= L_24;
! else if (ptr[0] == '3' && ptr[1] == '2')
*mode |= L_32;
! else if (ptr[0] == '1' && ptr[1] == '6')
*mode |= L_16;
else
as_bad (_("invalid operand size requested"));
! while (ISDIGIT (*ptr))
! ptr++;
}
! return ptr;
}
/* The many forms of operand:
--- 473,537 ----
return 0;
}
+
+ /* Parse an immediate or address-related constant and store it in OP.
+ If the user also specifies the operand's size, store that size
+ in OP->MODE, otherwise leave it for later code to decide. */
+
static char *
! parse_exp (src, op)
! char *src;
! struct h8_op *op;
{
! char *save;
! save = input_line_pointer;
! input_line_pointer = src;
! expression (&op->exp);
! if (op->exp.X_op == O_absent)
as_bad (_("missing operand"));
! src = input_line_pointer;
input_line_pointer = save;
!
! return skip_colonthing (src, &op->mode);
}
+
+ /* If SRC starts with an explicit operand size, skip it and store the size
+ in *MODE. Leave *MODE unchanged otherwise. */
+
static char *
! skip_colonthing (src, mode)
! char *src;
int *mode;
{
! if (*src == ':')
{
! src++;
*mode &= ~SIZE;
! if (src[0] == '8' && !ISDIGIT (src[1]))
*mode |= L_8;
! else if (src[0] == '2' && !ISDIGIT (src[1]))
*mode |= L_2;
! else if (src[0] == '3' && !ISDIGIT (src[1]))
*mode |= L_3;
! else if (src[0] == '4' && !ISDIGIT (src[1]))
*mode |= L_4;
! else if (src[0] == '5' && !ISDIGIT (src[1]))
*mode |= L_5;
! else if (src[0] == '2' && src[1] == '4' && !ISDIGIT (src[2]))
*mode |= L_24;
! else if (src[0] == '3' && src[1] == '2' && !ISDIGIT (src[2]))
*mode |= L_32;
! else if (src[0] == '1' && src[1] == '6' && !ISDIGIT (src[2]))
*mode |= L_16;
else
as_bad (_("invalid operand size requested"));
! while (ISDIGIT (*src))
! src++;
}
! return src;
}
/* The many forms of operand:
*************** skip_colonthing (ptr, exp, mode)
*** 541,575 ****
@(exp:[8], pc) pc rel
@@aa[:8] memory indirect. */
- char *
- colonmod24 (op, src)
- struct h8_op *op;
- char *src;
- {
- int mode = 0;
- src = skip_colonthing (src, &op->exp, &mode);
-
- if (!mode)
- {
- /* If the operand is a 16-bit constant integer, leave fix_operand_size
- to calculate its size. Otherwise choose a default here. */
- if (op->exp.X_add_number < -32768
- || op->exp.X_add_number > 32767)
- {
- if (Hmode)
- mode = L_24;
- else
- mode = L_16;
- }
- else if (op->exp.X_add_symbol
- || op->exp.X_op_symbol)
- mode = DSYMMODE;
- }
-
- op->mode |= mode;
- return src;
- }
-
static int
constant_fits_width_p (operand, width)
struct h8_op *operand;
--- 549,554 ----
*************** get_operand (ptr, op, direction)
*** 707,719 ****
src++;
if (*src == '@')
{
! src++;
! src = parse_exp (src, &op->exp);
!
! src = skip_colonthing (src, &op->exp, &op->mode);
!
! *ptr = src;
!
if (op->exp.X_add_number >= 0x100)
{
int divisor;
--- 686,692 ----
src++;
if (*src == '@')
{
! *ptr = parse_exp (src + 1, op);
if (op->exp.X_add_number >= 0x100)
{
int divisor;
*************** get_operand (ptr, op, direction)
*** 731,762 ****
}
else
op->mode = MEMIND;
-
return;
}
if (*src == '-' || *src == '+')
{
! char c = *src;
! src++;
! len = parse_reg (src, &mode, &num, direction);
if (len == 0)
{
/* Oops, not a reg after all, must be ordinary exp. */
! src--;
! /* Must be a symbol. */
! op->mode = ABS | PSIZE | direction;
! *ptr = skip_colonthing (parse_exp (src, &op->exp),
! &op->exp, &op->mode);
!
return;
}
if ((mode & SIZE) != PSIZE)
as_bad (_("Wrong size pointer register for architecture."));
! op->mode = c == '-' ? RDPREDEC : RDPREINC;
op->reg = num;
! *ptr = src + len;
return;
}
if (*src == '(')
--- 704,729 ----
}
else
op->mode = MEMIND;
return;
}
if (*src == '-' || *src == '+')
{
! len = parse_reg (src + 1, &mode, &num, direction);
if (len == 0)
{
/* Oops, not a reg after all, must be ordinary exp. */
! op->mode = ABS | direction;
! *ptr = parse_exp (src, op);
return;
}
if ((mode & SIZE) != PSIZE)
as_bad (_("Wrong size pointer register for architecture."));
!
! op->mode = src[0] == '-' ? RDPREDEC : RDPREINC;
op->reg = num;
! *ptr = src + 1 + len;
return;
}
if (*src == '(')
*************** get_operand (ptr, op, direction)
*** 801,815 ****
/* Start off assuming a 16 bit offset. */
! src = parse_exp (src, &op->exp);
!
! src = colonmod24 (op, src);
!
if (*src == ')')
{
- src++;
op->mode |= ABS | direction;
! *ptr = src;
return;
}
--- 768,778 ----
/* Start off assuming a 16 bit offset. */
! src = parse_exp (src, op);
if (*src == ')')
{
op->mode |= ABS | direction;
! *ptr = src + 1;
return;
}
*************** get_operand (ptr, op, direction)
*** 817,823 ****
{
as_bad (_("expected @(exp, reg16)"));
return;
-
}
src++;
--- 780,785 ----
*************** get_operand (ptr, op, direction)
*** 849,855 ****
}
else
op->mode |= DISP | direction;
! src = skip_colonthing (src, &op->exp, &op->mode);
if (*src != ')' && '(')
{
--- 811,817 ----
}
else
op->mode |= DISP | direction;
! src = skip_colonthing (src, &op->mode);
if (*src != ')' && '(')
{
*************** get_operand (ptr, op, direction)
*** 857,863 ****
return;
}
*ptr = src + 1;
-
return;
}
len = parse_reg (src, &mode, &num, direction);
--- 819,824 ----
*************** get_operand (ptr, op, direction)
*** 889,909 ****
/* must be a symbol */
op->mode = ABS | direction;
! src = parse_exp (src, &op->exp);
!
! *ptr = colonmod24 (op, src);
!
return;
}
}
if (*src == '#')
{
- src++;
op->mode = IMM;
! src = parse_exp (src, &op->exp);
! *ptr = skip_colonthing (src, &op->exp, &op->mode);
!
return;
}
else if (strncmp (src, "mach", 4) == 0 ||
--- 850,864 ----
/* must be a symbol */
op->mode = ABS | direction;
! *ptr = parse_exp (src, op);
return;
}
}
if (*src == '#')
{
op->mode = IMM;
! *ptr = parse_exp (src + 1, op);
return;
}
else if (strncmp (src, "mach", 4) == 0 ||
*************** get_operand (ptr, op, direction)
*** 918,952 ****
}
else
{
! src = parse_exp (src, &op->exp);
! /* Trailing ':' size ? */
! if (*src == ':')
! {
! if (src[1] == '1' && src[2] == '6')
! {
! op->mode = PCREL | L_16;
! src += 3;
! }
! else if (src[1] == '8')
! {
! op->mode = PCREL | L_8;
! src += 2;
! }
! else
! as_bad (_("expect :8 or :16 here"));
! }
! else
! {
! int val = op->exp.X_add_number;
!
! op->mode = PCREL;
! if (-128 < val && val < 127)
! op->mode |= L_8;
! else
! op->mode |= L_16;
! }
!
! *ptr = src;
}
}
--- 873,880 ----
}
else
{
! op->mode = PCREL;
! *ptr = parse_exp (src, op);
}
}
*************** get_mova_operands (char *op_end, struct
*** 1010,1017 ****
goto error;
ptr += 3;
operand[0].mode = 0;
! ptr = parse_exp (ptr, &operand[0].exp);
! ptr = colonmod24 (operand + 0, ptr);
if (*ptr !=',')
goto error;
--- 938,944 ----
goto error;
ptr += 3;
operand[0].mode = 0;
! ptr = parse_exp (ptr, &operand[0]);
if (*ptr !=',')
goto error;
*************** clever_message (instruction, operand)
*** 1880,1890 ****
}
! /* Adjust OPERAND's value and size given that it is accessing a field
! of SIZE bytes.
! This function handles the choice between @(d:2,ERn) and @(d:16,ERn)
! when no size is explicitly given. It also scales down the assembly-level
displacement in an @(d:2,ERn) operand. */
static void
--- 1807,1817 ----
}
! /* If OPERAND is part of an address, adjust its size and value given
! that it addresses SIZE bytes.
! This function decides how big non-immediate constants are when no
! size was explicitly given. It also scales down the assembly-level
displacement in an @(d:2,ERn) operand. */
static void
*************** fix_operand_size (operand, size)
*** 1892,1903 ****
struct h8_op *operand;
int size;
{
! if ((operand->mode & MODE) == DISP)
{
/* If the user didn't specify an operand width, see if we
can use @(d:2,ERn). */
! if (SXmode
! && (operand->mode & SIZE) == 0
&& (operand->exp.X_add_number == size
|| operand->exp.X_add_number == size * 2
|| operand->exp.X_add_number == size * 3))
--- 1819,1831 ----
struct h8_op *operand;
int size;
{
! if (SXmode && (operand->mode & MODE) == DISP)
{
/* If the user didn't specify an operand width, see if we
can use @(d:2,ERn). */
! if ((operand->mode & SIZE) == 0
! && operand->exp.X_add_symbol == 0
! && operand->exp.X_op_symbol == 0
&& (operand->exp.X_add_number == size
|| operand->exp.X_add_number == size * 2
|| operand->exp.X_add_number == size * 3))
*************** fix_operand_size (operand, size)
*** 1913,1920 ****
}
}
- /* If the operand needs a size but doesn't have one yet, it must be
- a 16-bit integer (see colonmod24). */
if ((operand->mode & SIZE) == 0)
switch (operand->mode & MODE)
{
--- 1841,1846 ----
*************** fix_operand_size (operand, size)
*** 1923,1929 ****
case INDEXW:
case INDEXL:
case ABS:
! operand->mode |= L_16;
break;
}
}
--- 1849,1874 ----
case INDEXW:
case INDEXL:
case ABS:
! /* Pick a 24-bit address unless we know that a 16-bit address
! is safe. get_specific() will relax L_24 into L_32 where
! necessary. */
! if (Hmode
! && (operand->exp.X_add_number < -32768
! || operand->exp.X_add_number > 32767
! || operand->exp.X_add_symbol != 0
! || operand->exp.X_op_symbol != 0))
! operand->mode |= L_24;
! else
! operand->mode |= L_16;
! break;
!
! case PCREL:
! /* This condition is long standing, though somewhat suspect. */
! if (operand->exp.X_add_number > -128
! && operand->exp.X_add_number < 127)
! operand->mode |= L_8;
! else
! operand->mode |= L_16;
break;
}
}
Index: gas/testsuite/gas/h8300/h8sx_disp2.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/h8300/h8sx_disp2.d,v
retrieving revision 1.1
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.1 h8sx_disp2.d
*** gas/testsuite/gas/h8300/h8sx_disp2.d 10 Jun 2003 07:22:22 -0000 1.1
--- gas/testsuite/gas/h8300/h8sx_disp2.d 7 Jul 2003 09:29:44 -0000
***************
*** 5,37 ****
Disassembly of section \.text:
0+00 <\.text>:
! * 0: 01 75 68 08 * 01 75 68 08 80 02 add.b #0x2,@\(0x1:2,r0\)
! * 4: 80 02 *
! * 6: 01 76 68 08 * 01 76 68 08 80 02 add.b #0x2,@\(0x2:2,r0\)
! * a: 80 02 *
! * c: 01 77 68 08 * 01 77 68 08 80 02 add.b #0x2,@\(0x3:2,r0\)
! *10: 80 02 *
! *12: 01 74 6e 08 * 01 74 6e 08 00 04 80 02 add.b #0x2,@\(0x4:16,r0\)
! *16: 00 04 80 02 *
! *1a: 01 5e c0 10 * 01 5e c0 10 00 01 00 02 add.w #0x2,@\(0x1:16,r0\)
! *1e: 00 01 00 02 *
! *22: 01 5e 10 10 * 01 5e 10 10 00 02 add.w #0x2,@\(0x2:2,r0\)
! *26: 00 02 *
! *28: 01 5e 20 10 * 01 5e 20 10 00 02 add.w #0x2,@\(0x4:2,r0\)
! *2c: 00 02 *
! *2e: 01 5e 30 10 * 01 5e 30 10 00 02 add.w #0x2,@\(0x6:2,r0\)
! *32: 00 02 *
! *34: 01 5e c0 10 * 01 5e c0 10 00 08 00 02 add.w #0x2,@\(0x8:16,r0\)
! *38: 00 08 00 02 *
! *3c: 01 0e c0 10 * 01 0e c0 10 00 01 00 02 add.l #0x2,@\(0x1:16,r0\)
! *40: 00 01 00 02 *
! *44: 01 0e c0 10 * 01 0e c0 10 00 02 00 02 add.l #0x2,@\(0x2:16,r0\)
! *48: 00 02 00 02 *
! *4c: 01 0e 10 10 * 01 0e 10 10 00 02 add.l #0x2,@\(0x4:2,r0\)
! *50: 00 02 *
! *52: 01 0e 20 10 * 01 0e 20 10 00 02 add.l #0x2,@\(0x8:2,r0\)
! *56: 00 02 *
! *58: 01 0e 30 10 * 01 0e 30 10 00 02 add.l #0x2,@\(0xc:2,r0\)
! *5c: 00 02 *
! *5e: 01 0e c0 10 * 01 0e c0 10 00 10 00 02 add.l #0x2,@\(0x10:16,r0\)
! *62: 00 10 00 02 *
--- 5,46 ----
Disassembly of section \.text:
0+00 <\.text>:
! .*: 01 75 68 08 * 01 75 68 08 80 02 add.b #0x2,@\(0x1:2,r0\)
! .*: 80 02 *
! .*: 01 76 68 08 * 01 76 68 08 80 02 add.b #0x2,@\(0x2:2,r0\)
! .*: 80 02 *
! .*: 01 77 68 08 * 01 77 68 08 80 02 add.b #0x2,@\(0x3:2,r0\)
! .*: 80 02 *
! .*: 01 74 6e 08 * 01 74 6e 08 00 04 80 02 add.b #0x2,@\(0x4:16,r0\)
! .*: 00 04 80 02 *
! .*: 78 04 6a 28 * 78 04 6a 28 00 00 00 00 80 02 add.b #0x2,@\(0x0:32,r0\)
! .*: 00 00 00 00 *
! .*: 80 02 *
! .*: 01 5e c0 10 * 01 5e c0 10 00 01 00 02 add.w #0x2,@\(0x1:16,r0\)
! .*: 00 01 00 02 *
! .*: 01 5e 10 10 * 01 5e 10 10 00 02 add.w #0x2,@\(0x2:2,r0\)
! .*: 00 02 *
! .*: 01 5e 20 10 * 01 5e 20 10 00 02 add.w #0x2,@\(0x4:2,r0\)
! .*: 00 02 *
! .*: 01 5e 30 10 * 01 5e 30 10 00 02 add.w #0x2,@\(0x6:2,r0\)
! .*: 00 02 *
! .*: 01 5e c0 10 * 01 5e c0 10 00 08 00 02 add.w #0x2,@\(0x8:16,r0\)
! .*: 00 08 00 02 *
! .*: 01 5e c8 10 * 01 5e c8 10 00 00 00 00 00 02 add.w #0x2,@\(0x0:32,r0\)
! .*: 00 00 00 00 *
! .*: 00 02 *
! .*: 01 0e c0 10 * 01 0e c0 10 00 01 00 02 add.l #0x2,@\(0x1:16,r0\)
! .*: 00 01 00 02 *
! .*: 01 0e c0 10 * 01 0e c0 10 00 02 00 02 add.l #0x2,@\(0x2:16,r0\)
! .*: 00 02 00 02 *
! .*: 01 0e 10 10 * 01 0e 10 10 00 02 add.l #0x2,@\(0x4:2,r0\)
! .*: 00 02 *
! .*: 01 0e 20 10 * 01 0e 20 10 00 02 add.l #0x2,@\(0x8:2,r0\)
! .*: 00 02 *
! .*: 01 0e 30 10 * 01 0e 30 10 00 02 add.l #0x2,@\(0xc:2,r0\)
! .*: 00 02 *
! .*: 01 0e c0 10 * 01 0e c0 10 00 10 00 02 add.l #0x2,@\(0x10:16,r0\)
! .*: 00 10 00 02 *
! .*: 01 0e c8 10 * 01 0e c8 10 00 00 00 00 00 02 add.l #0x2,@\(0x0:32,r0\)
! .*: 00 00 00 00 *
! .*: 00 02 *
Index: gas/testsuite/gas/h8300/h8sx_disp2.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/h8300/h8sx_disp2.s,v
retrieving revision 1.1
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.1 h8sx_disp2.s
*** gas/testsuite/gas/h8300/h8sx_disp2.s 10 Jun 2003 07:22:22 -0000 1.1
--- gas/testsuite/gas/h8300/h8sx_disp2.s 7 Jul 2003 09:29:44 -0000
***************
*** 3,14 ****
--- 3,16 ----
add.b #2,@(2,er0) ; L_2
add.b #2,@(3,er0) ; L_2
add.b #2,@(4,er0) ; L_16
+ add.b #2,@(foo+1,er0) ; L_32
add.w #2,@(1,er0) ; L_16
add.w #2,@(2,er0) ; L_2
add.w #2,@(4,er0) ; L_2
add.w #2,@(6,er0) ; L_2
add.w #2,@(8,er0) ; L_16
+ add.w #2,@(foo+2,er0) ; L_32
add.l #2,@(1,er0) ; L_16
add.l #2,@(2,er0) ; L_16
***************
*** 16,18 ****
--- 18,21 ----
add.l #2,@(8,er0) ; L_2
add.l #2,@(12,er0) ; L_2
add.l #2,@(16,er0) ; L_16
+ add.l #2,@(foo+4,er0) ; L_32