summaryrefslogtreecommitdiff
path: root/gcc/config/m68k/m68k.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/m68k/m68k.c')
-rw-r--r--gcc/config/m68k/m68k.c667
1 files changed, 440 insertions, 227 deletions
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 90e2491fb73..57e15c82de4 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -103,6 +103,27 @@ struct m68k_frame
/* Current frame information calculated by m68k_compute_frame_layout(). */
static struct m68k_frame current_frame;
+/* Structure describing an m68k address.
+
+ If CODE is UNKNOWN, the address is BASE + INDEX * SCALE + OFFSET,
+ with null fields evaluating to 0. Here:
+
+ - BASE satisfies m68k_legitimate_base_reg_p
+ - INDEX satisfies m68k_legitimate_index_reg_p
+ - OFFSET satisfies m68k_legitimate_constant_address_p
+
+ INDEX is either HImode or SImode. The other fields are SImode.
+
+ If CODE is PRE_DEC, the address is -(BASE). If CODE is POST_INC,
+ the address is (BASE)+. */
+struct m68k_address {
+ enum rtx_code code;
+ rtx base;
+ rtx index;
+ rtx offset;
+ int scale;
+};
+
static bool m68k_handle_option (size_t, const char *, int);
static rtx find_addr_reg (rtx);
static const char *singlemove_string (rtx *);
@@ -1666,6 +1687,76 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx insn, int signpos)
return "btst %0,%1";
}
+/* Return true if X is a legitimate base register. STRICT_P says
+ whether we need strict checking. */
+
+bool
+m68k_legitimate_base_reg_p (rtx x, bool strict_p)
+{
+ /* Allow SUBREG everywhere we allow REG. This results in better code. */
+ if (!strict_p && GET_CODE (x) == SUBREG)
+ x = SUBREG_REG (x);
+
+ return (REG_P (x)
+ && (strict_p
+ ? REGNO_OK_FOR_BASE_P (REGNO (x))
+ : !DATA_REGNO_P (REGNO (x)) && !FP_REGNO_P (REGNO (x))));
+}
+
+/* Return true if X is a legitimate index register. STRICT_P says
+ whether we need strict checking. */
+
+bool
+m68k_legitimate_index_reg_p (rtx x, bool strict_p)
+{
+ if (!strict_p && GET_CODE (x) == SUBREG)
+ x = SUBREG_REG (x);
+
+ return (REG_P (x)
+ && (strict_p
+ ? REGNO_OK_FOR_INDEX_P (REGNO (x))
+ : !FP_REGNO_P (REGNO (x))));
+}
+
+/* Return true if X is a legitimate index expression for a (d8,An,Xn) or
+ (bd,An,Xn) addressing mode. Fill in the INDEX and SCALE fields of
+ ADDRESS if so. STRICT_P says whether we need strict checking. */
+
+static bool
+m68k_decompose_index (rtx x, bool strict_p, struct m68k_address *address)
+{
+ int scale;
+
+ /* Check for a scale factor. */
+ scale = 1;
+ if ((TARGET_68020 || TARGET_COLDFIRE)
+ && GET_CODE (x) == MULT
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) == 2
+ || INTVAL (XEXP (x, 1)) == 4
+ || (INTVAL (XEXP (x, 1)) == 8
+ && (TARGET_COLDFIRE_FPU || !TARGET_COLDFIRE))))
+ {
+ scale = INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ }
+
+ /* Check for a word extension. */
+ if (!TARGET_COLDFIRE
+ && GET_CODE (x) == SIGN_EXTEND
+ && GET_MODE (XEXP (x, 0)) == HImode)
+ x = XEXP (x, 0);
+
+ if (m68k_legitimate_index_reg_p (x, strict_p))
+ {
+ address->scale = scale;
+ address->index = x;
+ return true;
+ }
+
+ return false;
+}
+
/* Return true if X is an illegitimate symbolic constant. */
bool
@@ -1683,6 +1774,251 @@ m68k_illegitimate_symbolic_constant_p (rtx x)
return false;
}
+/* Return true if X is a legitimate constant address that can reach
+ bytes in the range [X, X + REACH). STRICT_P says whether we need
+ strict checking. */
+
+static bool
+m68k_legitimate_constant_address_p (rtx x, unsigned int reach, bool strict_p)
+{
+ rtx base, offset;
+
+ if (!CONSTANT_ADDRESS_P (x))
+ return false;
+
+ if (flag_pic
+ && !(strict_p && TARGET_PCREL)
+ && symbolic_operand (x, VOIDmode))
+ return false;
+
+ if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P && reach > 1)
+ {
+ split_const (x, &base, &offset);
+ if (GET_CODE (base) == SYMBOL_REF
+ && !offset_within_block_p (base, INTVAL (offset) + reach - 1))
+ return false;
+ }
+
+ return true;
+}
+
+/* Return true if X is a LABEL_REF for a jump table. Assume that unplaced
+ labels will become jump tables. */
+
+static bool
+m68k_jump_table_ref_p (rtx x)
+{
+ if (GET_CODE (x) != LABEL_REF)
+ return false;
+
+ x = XEXP (x, 0);
+ if (!NEXT_INSN (x) && !PREV_INSN (x))
+ return true;
+
+ x = next_nonnote_insn (x);
+ return x && JUMP_TABLE_DATA_P (x);
+}
+
+/* Return true if X is a legitimate address for values of mode MODE.
+ STRICT_P says whether strict checking is needed. If the address
+ is valid, describe its components in *ADDRESS. */
+
+static bool
+m68k_decompose_address (enum machine_mode mode, rtx x,
+ bool strict_p, struct m68k_address *address)
+{
+ unsigned int reach;
+
+ memset (address, 0, sizeof (*address));
+
+ if (mode == BLKmode)
+ reach = 1;
+ else
+ reach = GET_MODE_SIZE (mode);
+
+ /* Check for (An) (mode 2). */
+ if (m68k_legitimate_base_reg_p (x, strict_p))
+ {
+ address->base = x;
+ return true;
+ }
+
+ /* Check for -(An) and (An)+ (modes 3 and 4). */
+ if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
+ && m68k_legitimate_base_reg_p (XEXP (x, 0), strict_p))
+ {
+ address->code = GET_CODE (x);
+ address->base = XEXP (x, 0);
+ return true;
+ }
+
+ /* Check for (d16,An) (mode 5). */
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && IN_RANGE (INTVAL (XEXP (x, 1)), -0x8000, 0x8000 - reach)
+ && m68k_legitimate_base_reg_p (XEXP (x, 0), strict_p))
+ {
+ address->base = XEXP (x, 0);
+ address->offset = XEXP (x, 1);
+ return true;
+ }
+
+ /* Check for GOT loads. These are (bd,An,Xn) addresses if
+ TARGET_68020 && flag_pic == 2, otherwise they are (d16,An)
+ addresses. */
+ if (flag_pic
+ && GET_CODE (x) == PLUS
+ && XEXP (x, 0) == pic_offset_table_rtx
+ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
+ || GET_CODE (XEXP (x, 1)) == LABEL_REF))
+ {
+ address->base = XEXP (x, 0);
+ address->offset = XEXP (x, 1);
+ return true;
+ }
+
+ /* The ColdFire FPU only accepts addressing modes 2-5. */
+ if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ return false;
+
+ /* Check for (xxx).w and (xxx).l. Also, in the TARGET_PCREL case,
+ check for (d16,PC) or (bd,PC,Xn) with a suppressed index register.
+ All these modes are variations of mode 7. */
+ if (m68k_legitimate_constant_address_p (x, reach, strict_p))
+ {
+ address->offset = x;
+ return true;
+ }
+
+ /* Check for (d8,PC,Xn), a mode 7 form. This case is needed for
+ tablejumps.
+
+ ??? do_tablejump creates these addresses before placing the target
+ label, so we have to assume that unplaced labels are jump table
+ references. It seems unlikely that we would ever generate indexed
+ accesses to unplaced labels in other cases. */
+ if (GET_CODE (x) == PLUS
+ && m68k_jump_table_ref_p (XEXP (x, 1))
+ && m68k_decompose_index (XEXP (x, 0), strict_p, address))
+ {
+ address->offset = XEXP (x, 1);
+ return true;
+ }
+
+ /* Everything hereafter deals with (d8,An,Xn.SIZE*SCALE) or
+ (bd,An,Xn.SIZE*SCALE) addresses. */
+
+ if (TARGET_68020)
+ {
+ /* Check for a nonzero base displacement. */
+ if (GET_CODE (x) == PLUS
+ && m68k_legitimate_constant_address_p (XEXP (x, 1), reach, strict_p))
+ {
+ address->offset = XEXP (x, 1);
+ x = XEXP (x, 0);
+ }
+
+ /* Check for a suppressed index register. */
+ if (m68k_legitimate_base_reg_p (x, strict_p))
+ {
+ address->base = x;
+ return true;
+ }
+
+ /* Check for a suppressed base register. Do not allow this case
+ for non-symbolic offsets as it effectively gives gcc freedom
+ to treat data registers as base registers, which can generate
+ worse code. */
+ if (address->offset
+ && symbolic_operand (address->offset, VOIDmode)
+ && m68k_decompose_index (x, strict_p, address))
+ return true;
+ }
+ else
+ {
+ /* Check for a nonzero base displacement. */
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && IN_RANGE (INTVAL (XEXP (x, 1)), -0x80, 0x80 - reach))
+ {
+ address->offset = XEXP (x, 1);
+ x = XEXP (x, 0);
+ }
+ }
+
+ /* We now expect the sum of a base and an index. */
+ if (GET_CODE (x) == PLUS)
+ {
+ if (m68k_legitimate_base_reg_p (XEXP (x, 0), strict_p)
+ && m68k_decompose_index (XEXP (x, 1), strict_p, address))
+ {
+ address->base = XEXP (x, 0);
+ return true;
+ }
+
+ if (m68k_legitimate_base_reg_p (XEXP (x, 1), strict_p)
+ && m68k_decompose_index (XEXP (x, 0), strict_p, address))
+ {
+ address->base = XEXP (x, 1);
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Return true if X is a legitimate address for values of mode MODE.
+ STRICT_P says whether strict checking is needed. */
+
+bool
+m68k_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p)
+{
+ struct m68k_address address;
+
+ return m68k_decompose_address (mode, x, strict_p, &address);
+}
+
+/* Return true if X is a memory, describing its address in ADDRESS if so.
+ Apply strict checking if called during or after reload. */
+
+static bool
+m68k_legitimate_mem_p (rtx x, struct m68k_address *address)
+{
+ return (MEM_P (x)
+ && m68k_decompose_address (GET_MODE (x), XEXP (x, 0),
+ reload_in_progress || reload_completed,
+ address));
+}
+
+/* Return true if X matches the 'Q' constraint. It must be a memory
+ with a base address and no constant offset or index. */
+
+bool
+m68k_matches_q_p (rtx x)
+{
+ struct m68k_address address;
+
+ return (m68k_legitimate_mem_p (x, &address)
+ && address.code == UNKNOWN
+ && address.base
+ && !address.offset
+ && !address.index);
+}
+
+/* Return true if X matches the 'U' constraint. It must be a base address
+ with a constant offset and no index. */
+
+bool
+m68k_matches_u_p (rtx x)
+{
+ struct m68k_address address;
+
+ return (m68k_legitimate_mem_p (x, &address)
+ && address.code == UNKNOWN
+ && address.base
+ && address.offset
+ && !address.index);
+}
+
/* Legitimize PIC addresses. If the address is already
position-independent, we return ORIG. Newly generated
position-independent addresses go to REG. If we need more
@@ -3271,265 +3607,142 @@ print_operand (FILE *file, rtx op, int letter)
offset is output in word mode (e.g. movel a5@(_foo:w), a0). When generating
-fPIC code the offset is output in long mode (e.g. movel a5@(_foo:l), a0) */
-#if MOTOROLA
-# define ASM_OUTPUT_CASE_FETCH(file, labelno, regname) \
- asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,%s.", labelno, labelno, regname)
-#else /* !MOTOROLA */
-# define ASM_OUTPUT_CASE_FETCH(file, labelno, regname) \
- asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b,%s:", labelno, labelno, regname)
-#endif /* !MOTOROLA */
-
void
print_operand_address (FILE *file, rtx addr)
{
- register rtx reg1, reg2, breg, ireg;
- rtx offset;
-
- switch (GET_CODE (addr))
- {
- case REG:
- fprintf (file, MOTOROLA ? "(%s)" : "%s@", M68K_REGNAME (REGNO (addr)));
- break;
- case PRE_DEC:
- fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
- M68K_REGNAME (REGNO (XEXP (addr, 0))));
- break;
- case POST_INC:
- fprintf (file, MOTOROLA ? "(%s)+" : "%s@+",
- M68K_REGNAME (REGNO (XEXP (addr, 0))));
- break;
- case PLUS:
- reg1 = reg2 = ireg = breg = offset = 0;
- if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
- {
- offset = XEXP (addr, 0);
- addr = XEXP (addr, 1);
- }
- else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
- {
- offset = XEXP (addr, 1);
- addr = XEXP (addr, 0);
- }
- if (GET_CODE (addr) != PLUS)
- {
- ;
- }
- else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)
- {
- reg1 = XEXP (addr, 0);
- addr = XEXP (addr, 1);
- }
- else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)
- {
- reg1 = XEXP (addr, 1);
- addr = XEXP (addr, 0);
- }
- else if (GET_CODE (XEXP (addr, 0)) == MULT)
- {
- reg1 = XEXP (addr, 0);
- addr = XEXP (addr, 1);
- }
- else if (GET_CODE (XEXP (addr, 1)) == MULT)
- {
- reg1 = XEXP (addr, 1);
- addr = XEXP (addr, 0);
- }
- else if (GET_CODE (XEXP (addr, 0)) == REG)
- {
- reg1 = XEXP (addr, 0);
- addr = XEXP (addr, 1);
- }
- else if (GET_CODE (XEXP (addr, 1)) == REG)
- {
- reg1 = XEXP (addr, 1);
- addr = XEXP (addr, 0);
- }
- if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT
- || GET_CODE (addr) == SIGN_EXTEND)
+ struct m68k_address address;
+
+ if (!m68k_decompose_address (QImode, addr, true, &address))
+ gcc_unreachable ();
+
+ if (address.code == PRE_DEC)
+ fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
+ M68K_REGNAME (REGNO (address.base)));
+ else if (address.code == POST_INC)
+ fprintf (file, MOTOROLA ? "(%s)+" : "%s@+",
+ M68K_REGNAME (REGNO (address.base)));
+ else if (!address.base && !address.index)
+ {
+ /* A constant address. */
+ gcc_assert (address.offset == addr);
+ if (GET_CODE (addr) == CONST_INT)
{
- if (reg1 == 0)
- reg1 = addr;
+ /* (xxx).w or (xxx).l. */
+ if (IN_RANGE (INTVAL (addr), -0x8000, 0x7fff))
+ fprintf (file, MOTOROLA ? "%d.w" : "%d:w", (int) INTVAL (addr));
else
- reg2 = addr;
- addr = 0;
- }
-#if 0 /* for OLD_INDEXING */
- else if (GET_CODE (addr) == PLUS)
- {
- if (GET_CODE (XEXP (addr, 0)) == REG)
- {
- reg2 = XEXP (addr, 0);
- addr = XEXP (addr, 1);
- }
- else if (GET_CODE (XEXP (addr, 1)) == REG)
- {
- reg2 = XEXP (addr, 1);
- addr = XEXP (addr, 0);
- }
- }
-#endif
- if (offset != 0)
- {
- gcc_assert (!addr);
- addr = offset;
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
}
- if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND
- || GET_CODE (reg1) == MULT))
- || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
- {
- breg = reg2;
- ireg = reg1;
- }
- else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
+ else if (TARGET_PCREL)
{
- breg = reg1;
- ireg = reg2;
+ /* (d16,PC) or (bd,PC,Xn) (with suppressed index register). */
+ fputc ('(', file);
+ output_addr_const (file, addr);
+ asm_fprintf (file, flag_pic == 1 ? ":w,%Rpc)" : ":l,%Rpc)");
}
- if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF
- && ! (flag_pic && ireg == pic_offset_table_rtx))
+ else
{
- int scale = 1;
- if (GET_CODE (ireg) == MULT)
- {
- scale = INTVAL (XEXP (ireg, 1));
- ireg = XEXP (ireg, 0);
- }
- if (GET_CODE (ireg) == SIGN_EXTEND)
+ /* (xxx).l. We need a special case for SYMBOL_REF if the symbol
+ name ends in `.<letter>', as the last 2 characters can be
+ mistaken as a size suffix. Put the name in parentheses. */
+ if (GET_CODE (addr) == SYMBOL_REF
+ && strlen (XSTR (addr, 0)) > 2
+ && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
{
- ASM_OUTPUT_CASE_FETCH (file,
- CODE_LABEL_NUMBER (XEXP (addr, 0)),
- M68K_REGNAME (REGNO (XEXP (ireg, 0))));
- fprintf (file, "w");
+ putc ('(', file);
+ output_addr_const (file, addr);
+ putc (')', file);
}
else
- {
- ASM_OUTPUT_CASE_FETCH (file,
- CODE_LABEL_NUMBER (XEXP (addr, 0)),
- M68K_REGNAME (REGNO (ireg)));
- fprintf (file, "l");
- }
- if (scale != 1)
- fprintf (file, MOTOROLA ? "*%d" : ":%d", scale);
- putc (')', file);
- break;
- }
- if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF
- && ! (flag_pic && breg == pic_offset_table_rtx))
- {
- ASM_OUTPUT_CASE_FETCH (file,
- CODE_LABEL_NUMBER (XEXP (addr, 0)),
- M68K_REGNAME (REGNO (breg)));
- fprintf (file, "l)");
- break;
+ output_addr_const (file, addr);
}
- if (ireg != 0 || breg != 0)
+ }
+ else
+ {
+ int labelno;
+
+ /* If ADDR is a (d8,pc,Xn) address, this is the number of the
+ label being acceesed, otherwise it is -1. */
+ labelno = (address.offset
+ && !address.base
+ && GET_CODE (address.offset) == LABEL_REF
+ ? CODE_LABEL_NUMBER (XEXP (address.offset, 0))
+ : -1);
+ if (MOTOROLA)
{
- int scale = 1;
-
- gcc_assert (breg);
- gcc_assert (flag_pic || !addr || GET_CODE (addr) != LABEL_REF);
-
- if (MOTOROLA)
+ /* Print the "offset(base" component. */
+ if (labelno >= 0)
+ asm_fprintf (file, "%LL%d-%LLI%d.b(%Rpc,", labelno, labelno);
+ else
{
- if (addr != 0)
+ if (address.offset)
{
- output_addr_const (file, addr);
- if (flag_pic && (breg == pic_offset_table_rtx))
+ output_addr_const (file, address.offset);
+ if (flag_pic && address.base == pic_offset_table_rtx)
{
fprintf (file, "@GOT");
- if (flag_pic == 1)
+ if (flag_pic == 1 && TARGET_68020)
fprintf (file, ".w");
}
}
- fprintf (file, "(%s", M68K_REGNAME (REGNO (breg)));
- if (ireg != 0)
- putc (',', file);
+ putc ('(', file);
+ if (address.base)
+ fputs (M68K_REGNAME (REGNO (address.base)), file);
}
- else /* !MOTOROLA */
+ /* Print the ",index" component, if any. */
+ if (address.index)
{
- fprintf (file, "%s@(", M68K_REGNAME (REGNO (breg)));
- if (addr != 0)
- {
- output_addr_const (file, addr);
- if (breg == pic_offset_table_rtx)
- switch (flag_pic)
- {
- case 1:
- fprintf (file, ":w");
- break;
- case 2:
- fprintf (file, ":l");
- break;
- default:
- break;
- }
- if (ireg != 0)
- putc (',', file);
- }
- } /* !MOTOROLA */
- if (ireg != 0 && GET_CODE (ireg) == MULT)
- {
- scale = INTVAL (XEXP (ireg, 1));
- ireg = XEXP (ireg, 0);
+ if (address.base)
+ putc (',', file);
+ fprintf (file, "%s.%c",
+ M68K_REGNAME (REGNO (address.index)),
+ GET_MODE (address.index) == HImode ? 'w' : 'l');
+ if (address.scale != 1)
+ fprintf (file, "*%d", address.scale);
}
- if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)
- fprintf (file, MOTOROLA ? "%s.w" : "%s:w",
- M68K_REGNAME (REGNO (XEXP (ireg, 0))));
- else if (ireg != 0)
- fprintf (file, MOTOROLA ? "%s.l" : "%s:l",
- M68K_REGNAME (REGNO (ireg)));
- if (scale != 1)
- fprintf (file, MOTOROLA ? "*%d" : ":%d", scale);
putc (')', file);
- break;
- }
- else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF
- && ! (flag_pic && reg1 == pic_offset_table_rtx))
- {
- ASM_OUTPUT_CASE_FETCH (file,
- CODE_LABEL_NUMBER (XEXP (addr, 0)),
- M68K_REGNAME (REGNO (reg1)));
- fprintf (file, "l)");
- break;
}
- /* FALL-THROUGH (is this really what we want?) */
- default:
- if (GET_CODE (addr) == CONST_INT
- && INTVAL (addr) < 0x8000
- && INTVAL (addr) >= -0x8000)
- {
- fprintf (file, MOTOROLA ? "%d.w" : "%d:w", (int) INTVAL (addr));
- }
- else if (GET_CODE (addr) == CONST_INT)
+ else /* !MOTOROLA */
{
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
- }
- else if (TARGET_PCREL)
- {
- fputc ('(', file);
- output_addr_const (file, addr);
- if (flag_pic == 1)
- asm_fprintf (file, ":w,%Rpc)");
+ if (!address.offset && !address.index)
+ fprintf (file, "%s@", M68K_REGNAME (REGNO (address.base)));
else
- asm_fprintf (file, ":l,%Rpc)");
- }
- else
- {
- /* Special case for SYMBOL_REF if the symbol name ends in
- `.<letter>', this can be mistaken as a size suffix. Put
- the name in parentheses. */
- if (GET_CODE (addr) == SYMBOL_REF
- && strlen (XSTR (addr, 0)) > 2
- && XSTR (addr, 0)[strlen (XSTR (addr, 0)) - 2] == '.')
{
- putc ('(', file);
- output_addr_const (file, addr);
+ /* Print the "base@(offset" component. */
+ if (labelno >= 0)
+ asm_fprintf (file, "%Rpc@(%LL%d-%LLI%d-2:b", labelno, labelno);
+ else
+ {
+ if (address.base)
+ fputs (M68K_REGNAME (REGNO (address.base)), file);
+ fprintf (file, "@(");
+ if (address.offset)
+ {
+ output_addr_const (file, address.offset);
+ if (address.base == pic_offset_table_rtx && TARGET_68020)
+ switch (flag_pic)
+ {
+ case 1:
+ fprintf (file, ":w"); break;
+ case 2:
+ fprintf (file, ":l"); break;
+ default:
+ break;
+ }
+ }
+ }
+ /* Print the ",index" component, if any. */
+ if (address.index)
+ {
+ fprintf (file, ",%s:%c",
+ M68K_REGNAME (REGNO (address.index)),
+ GET_MODE (address.index) == HImode ? 'w' : 'l');
+ if (address.scale != 1)
+ fprintf (file, ":%d", address.scale);
+ }
putc (')', file);
}
- else
- output_addr_const (file, addr);
}
- break;
}
}