aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDon Lindsay <dlindsay@cygnus.com>1999-06-17 15:09:47 +0000
committerDon Lindsay <dlindsay@gcc.gnu.org>1999-06-17 15:09:47 +0000
commit2c8ec431e3d004bab9f620815ffafe7d3be3597e (patch)
tree2dcfc57a63ac1ac16c4f9a4c78bb79ef0a1a5b64
parentfb8684745d6485ed60a4e88d0b2a8fc8b4d4acfa (diff)
downloadgcc-2c8ec431e3d004bab9f620815ffafe7d3be3597e.zip
gcc-2c8ec431e3d004bab9f620815ffafe7d3be3597e.tar.gz
gcc-2c8ec431e3d004bab9f620815ffafe7d3be3597e.tar.bz2
Added -mpcrel flag, and underlying support for PC-relative addressing on m68k.
h Added -mpcrel flag, and underlying support for PC-relative addressing on m68k. Patch is tested, and approved by Jim Wilson. From-SVN: r27576
-rw-r--r--ChangeLog43
-rw-r--r--gcc/config/m68k/hp320.h3
-rw-r--r--gcc/config/m68k/linux.h3
-rw-r--r--gcc/config/m68k/m68k.c163
-rw-r--r--gcc/config/m68k/m68k.h72
-rw-r--r--gcc/config/m68k/m68k.md238
-rw-r--r--gcc/config/m68k/m68kelf.h10
-rw-r--r--gcc/config/m68k/m68kv4.h3
8 files changed, 425 insertions, 110 deletions
diff --git a/ChangeLog b/ChangeLog
index a9fa0f98..b277359 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,46 @@
+Thu Jun 17 15:06:10 PDT 1999 Don Lindsay <dlindsay@cygnus.com>
+
+ * added support for -mpcrel (PC relative addressing for m68k)
+ based on code done by Michael Tiemann <tiemann@axon.cygnus.com>.
+ * invoke.texi (m68000 options): Add documentation for -mpcrel flag.
+ * m68k.c (print_operand_address): Handle 32-bit PIC case.
+ (comments for general_src_operand): Add some explanation
+ about EXTRA_CONSTRAINTS.
+ (OVERRIDE_OPTIONS): Enable -fPIC in combination with -mpcrel.
+ * m68kelf.h (OVERRIDE_OPTIONS): Ditto.
+ (LEGITIMATE_PIC_OPERAND_P): Fix typo.
+ (LEGITIMATE_PIC_OPERAND_P): Re-derive from m68k.h case.
+ * m68k.h (LEGITIMATE_PIC_OPERAND_P): Fix delete-o.
+ (INDIRECTABLE_1_ADDRESS): Delete spurious '/' at end of macro.
+ (OVERRIDE_OPTIONS): Change behavior so that -mpcrel implies -fpic
+ if not already set.
+ (OVERRIDE_OPTIONS): Merge in changes from m68k.h.
+ * m68k.h (TARGET_PCREL): New target flag.
+ (TARGET_SWITCHES): Add "pcrel" as a recognized switch.
+ (OVERRIDE_OPTIONS): Add checks for -mpcrel.
+ (LEGITIMATE_PIC_OPERAND_P): Don't normally accept anything that
+ contains a SYMBOL_REF. Relax this constraint during reload, since
+ we want to use the predicates, not reload's built-in concept of a
+ valid memory address, to control what insns need reloading.
+ (EXTRA_CONSTRAINT): Define constraints to accept pc-relative
+ operands (essentially 'g', 'm', and 's' under normal circumstances).
+ * m68k.c (print_operand): Cause printing of pc-relative addresses
+ to include pc register.
+ (print_operand_address): Ditto.
+ (general_src_operand): Accept operands that are not only
+ general_operands, but are also valid when used as a pc-relative
+ source.
+ (nonimmediate_src_operand): Similar, for nonimmediate_operands.
+ (memory_src_operand): Similar, for memory_operands.
+ (pcrel_address): New predicate to accept the special case of a
+ pc-relative address.
+ * m68k.md (many patterns): Rewrite common SImode, HImode, and
+ QImode insns to accept *_src_operand instead of *_operand where
+ pc-relative operands can fit. For example, a pc-relative operand
+ can be used as a memory source operand for addsi3, but not as a
+ memory destination.
+ * hp320.h linux.h m68kv4.h (LEGITIMATE_PIC_OPERAND_P) as in m68k.h.
+
Sun May 30 16:03:16 1999 Cort Dougan <cort@cs.nmt.edu>
* config.guess (ppc-*-linux-gnu): Also use ld emul elf32ppclinux.
diff --git a/gcc/config/m68k/hp320.h b/gcc/config/m68k/hp320.h
index 9816502..977812e 100644
--- a/gcc/config/m68k/hp320.h
+++ b/gcc/config/m68k/hp320.h
@@ -635,7 +635,8 @@ do { register int i; \
&& ! (GET_CODE (X) == CONST_DOUBLE && CONST_DOUBLE_MEM (X) \
&& GET_CODE (CONST_DOUBLE_MEM (X)) == MEM \
&& symbolic_operand (XEXP (CONST_DOUBLE_MEM (X), 0), VOIDmode))) \
- || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)))
+ || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)) \
+ || PCREL_GENERAL_OPERAND_OK)
/* hpux8 and later have C++ compatible include files, so do not
pretend they are `extern "C"'. */
diff --git a/gcc/config/m68k/linux.h b/gcc/config/m68k/linux.h
index 0df0bd8..a1a4fff 100644
--- a/gcc/config/m68k/linux.h
+++ b/gcc/config/m68k/linux.h
@@ -310,7 +310,8 @@ do { \
&& ! (GET_CODE (X) == CONST_DOUBLE && CONST_DOUBLE_MEM (X) \
&& GET_CODE (CONST_DOUBLE_MEM (X)) == MEM \
&& symbolic_operand (XEXP (CONST_DOUBLE_MEM (X), 0), VOIDmode))) \
- || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)))
+ || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)) \
+ || PCREL_GENERAL_OPERAND_OK)
/* Turn off function cse if we are doing PIC. We always want function
call to be done as `bsr foo@PLTPC', so it will force the assembler
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 98f5197..2d2028b 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -54,6 +54,7 @@ int switch_table_difference_label_flag;
static rtx find_addr_reg ();
rtx legitimize_pic_address ();
+void print_operand_address ();
/* Alignment to use for loops and jumps */
@@ -2717,6 +2718,8 @@ standard_sun_fpa_constant_p (x)
'b' for byte insn (no effect, on the Sun; this is for the ISI).
'd' to force memory addressing to be absolute, not relative.
'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
+ 'o' for operands to go directly to output_operand_address (bypassing
+ print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
than directly). Second part of 'y' below.
'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
@@ -2793,6 +2796,14 @@ print_operand (file, op, letter)
{
asm_fprintf (file, "%R");
}
+ else if (letter == 'o')
+ {
+ /* This is only for direct addresses with TARGET_PCREL */
+ if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
+ || !TARGET_PCREL)
+ abort ();
+ output_addr_const (file, XEXP (op, 0));
+ }
else if (GET_CODE (op) == REG)
{
#ifdef SUPPORT_SUN_FPA
@@ -2858,7 +2869,14 @@ print_operand (file, op, letter)
}
else
{
- asm_fprintf (file, "%0I"); output_addr_const (file, op);
+ /* Use `print_operand_address' instead of `output_addr_const'
+ to ensure that we print relevant PIC stuff. */
+ asm_fprintf (file, "%0I");
+ if (TARGET_PCREL
+ && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
+ print_operand_address (file, op);
+ else
+ output_addr_const (file, op);
}
}
@@ -3159,7 +3177,7 @@ print_operand_address (file, addr)
fprintf (file, "l)");
break;
}
- /* FALL-THROUGH (is this really what we want? */
+ /* FALL-THROUGH (is this really what we want?) */
default:
if (GET_CODE (addr) == CONST_INT
&& INTVAL (addr) < 0x8000
@@ -3176,6 +3194,25 @@ print_operand_address (file, addr)
fprintf (file, "%d:w", INTVAL (addr));
#endif
}
+ else if (GET_CODE (addr) == CONST_INT)
+ {
+ fprintf (file,
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+ "%d",
+#else
+ "%ld",
+#endif
+ INTVAL (addr));
+ }
+ else if (TARGET_PCREL)
+ {
+ fputc ('(', file);
+ output_addr_const (file, addr);
+ if (flag_pic == 1)
+ asm_fprintf (file, ":w,%Rpc)");
+ else
+ asm_fprintf (file, ":l,%Rpc)");
+ }
else
{
/* Special case for SYMBOL_REF if the symbol name ends in
@@ -3288,6 +3325,128 @@ const_sint32_operand (op, mode)
&& (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
}
+/* Operand predicates for implementing asymmetric pc-relative addressing
+ on m68k. The m68k supports pc-relative addressing (mode 7, register 2)
+ when used as a source operand, but not as a destintation operand.
+
+ We model this by restricting the meaning of the basic predicates
+ (general_operand, memory_operand, etc) to forbid the use of this
+ addressing mode, and then define the following predicates that permit
+ this addressing mode. These predicates can then be used for the
+ source operands of the appropriate instructions.
+
+ n.b. While it is theoretically possible to change all machine patterns
+ to use this addressing more where permitted by the architecture,
+ it has only been implemented for "common" cases: SImode, HImode, and
+ QImode operands, and only for the principle operations that would
+ require this addressing mode: data movement and simple integer operations.
+
+ In parallel with these new predicates, two new constraint letters
+ were defined: 'S' and 'T'. 'S' is the -mpcrel analog of 'm'.
+ 'T' replaces 's' in the non-pcrel case. It is a no-op in the pcrel case.
+ In the pcrel case 's' is only valid in combination with 'a' registers.
+ See addsi3, subsi3, cmpsi, and movsi patterns for a better understanding
+ of how these constraints are used.
+
+ The use of these predicates is strictly optional, though patterns that
+ don't will cause an extra reload register to be allocated where one
+ was not necessary:
+
+ lea (abc:w,%pc),%a0 ; need to reload address
+ moveq &1,%d1 ; since write to pc-relative space
+ movel %d1,%a0@ ; is not allowed
+ ...
+ lea (abc:w,%pc),%a1 ; no need to reload address here
+ movel %a1@,%d0 ; since "movel (abc:w,%pc),%d0" is ok
+
+ For more info, consult tiemann@cygnus.com.
+
+
+ All of the ugliness with predicates and constraints is due to the
+ simple fact that the m68k does not allow a pc-relative addressing
+ mode as a destination. gcc does not distinguish between source and
+ destination addresses. Hence, if we claim that pc-relative address
+ modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
+ end up with invalid code. To get around this problem, we left
+ pc-relative modes as invalid addresses, and then added special
+ predicates and constraints to accept them.
+
+ A cleaner way to handle this is to modify gcc to distinguish
+ between source and destination addresses. We can then say that
+ pc-relative is a valid source address but not a valid destination
+ address, and hopefully avoid a lot of the predicate and constraint
+ hackery. Unfortunately, this would be a pretty big change. It would
+ be a useful change for a number of ports, but there aren't any current
+ plans to undertake this.
+
+ ***************************************************************************/
+
+
+/* Special case of a general operand that's used as a source operand.
+ Use this to permit reads from PC-relative memory when -mpcrel
+ is specified. */
+
+int
+general_src_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (TARGET_PCREL
+ && GET_CODE (op) == MEM
+ && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF
+ || GET_CODE (XEXP (op, 0)) == CONST))
+ return 1;
+ return general_operand (op, mode);
+}
+
+/* Special case of a nonimmediate operand that's used as a source.
+ Use this to permit reads from PC-relative memory when -mpcrel
+ is specified. */
+
+int
+nonimmediate_src_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (TARGET_PCREL && GET_CODE (op) == MEM
+ && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF
+ || GET_CODE (XEXP (op, 0)) == CONST))
+ return 1;
+ return nonimmediate_operand (op, mode);
+}
+
+/* Special case of a memory operand that's used as a source.
+ Use this to permit reads from PC-relative memory when -mpcrel
+ is specified. */
+
+int
+memory_src_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (TARGET_PCREL && GET_CODE (op) == MEM
+ && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF
+ || GET_CODE (XEXP (op, 0)) == CONST))
+ return 1;
+ return memory_operand (op, mode);
+}
+
+/* Predicate that accepts only a pc-relative address. This is needed
+ because pc-relative addresses don't satisfy the predicate
+ "general_src_operand". */
+
+int
+pcrel_address (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
+ || GET_CODE (op) == CONST);
+}
+
char *
output_andsi3 (operands)
rtx *operands;
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 268b639..83af590 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -123,6 +123,18 @@ extern int target_flags;
/* A 68020 without bitfields is a good heuristic for a CPU32 */
#define TARGET_CPU32 (TARGET_68020 && !TARGET_BITFIELD)
+/* Use PC-relative addressing modes (without using a global offset table).
+ The m68000 supports 16-bit PC-relative addressing.
+ The m68020 supports 32-bit PC-relative addressing
+ (using outer displacements).
+
+ Under this model, all SYMBOL_REFs (and CONSTs) and LABEL_REFs are
+ treated as all containing an implicit PC-relative component, and hence
+ cannot be used directly as addresses for memory writes. See the comments
+ in m68k.c for more information. */
+#define MASK_PCREL 4096
+#define TARGET_PCREL (target_flags & MASK_PCREL)
+
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
each pair being { "NAME", VALUE }
@@ -181,6 +193,7 @@ extern int target_flags;
{ "cpu32", MASK_68020}, \
{ "align-int", MASK_ALIGN_INT }, \
{ "no-align-int", -MASK_ALIGN_INT }, \
+ { "pcrel", MASK_PCREL}, \
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT}}
/* TARGET_DEFAULT is defined in sun*.h and isi.h, etc. */
@@ -215,6 +228,8 @@ extern int target_flags;
override_options(); \
if (! TARGET_68020 && flag_pic == 2) \
error("-fPIC is not currently supported on the 68000 or 68010\n"); \
+ if (TARGET_PCREL && flag_pic == 0) \
+ flag_pic = 1; \
SUBTARGET_OVERRIDE_OPTIONS; \
}
@@ -760,11 +775,35 @@ extern enum reg_class regno_reg_class[];
C. If C is not defined as an extra constraint, the value returned should
be 0 regardless of VALUE. */
-/* For the m68k, `Q' means address register indirect addressing mode. */
-
-#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG) : \
- 0 )
+/* Letters in the range `Q' through `U' may be defined in a
+ machine-dependent fashion to stand for arbitrary operand types.
+ The machine description macro `EXTRA_CONSTRAINT' is passed the
+ operand as its first argument and the constraint letter as its
+ second operand.
+
+ `Q' means address register indirect addressing mode.
+ `S' is for operands that satisfy 'm' when -mpcrel is in effect.
+ `T' is for operands that satisfy 's' when -mpcrel is not in effect. */
+
+#define EXTRA_CONSTRAINT(OP,CODE) \
+ (((CODE) == 'S') \
+ ? (TARGET_PCREL \
+ && GET_CODE (OP) == MEM \
+ && (GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
+ || GET_CODE (XEXP (OP, 0)) == LABEL_REF \
+ || GET_CODE (XEXP (OP, 0)) == CONST)) \
+ : \
+ (((CODE) == 'T') \
+ ? ( !TARGET_PCREL \
+ && (GET_CODE (OP) == SYMBOL_REF \
+ || GET_CODE (OP) == LABEL_REF \
+ || GET_CODE (OP) == CONST)) \
+ : \
+ (((CODE) == 'Q') \
+ ? (GET_CODE (OP) == MEM \
+ && GET_CODE (XEXP (OP, 0)) == REG) \
+ : \
+ 0)))
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
@@ -789,6 +828,10 @@ extern enum reg_class regno_reg_class[];
? (! CONST_DOUBLE_OK_FOR_LETTER_P (X, 'G') \
&& (CLASS == FP_REGS || CLASS == DATA_OR_FP_REGS) \
? FP_REGS : NO_REGS) \
+ : (TARGET_PCREL \
+ && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \
+ || GET_CODE (X) == LABEL_REF)) \
+ ? ADDR_REGS \
: (CLASS))
/* Force QImode output reloads from subregs to be allocated to data regs,
@@ -1353,7 +1396,17 @@ __transfer_from_trampoline () \
/* Nonzero if the constant value X is a legitimate general operand
when generating PIC code. It is given that flag_pic is on and
- that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
+ that X satisfies CONSTANT_P or is a CONST_DOUBLE.
+
+ PCREL_GENERAL_OPERAND_OK makes reload accept addresses that are
+ accepted by insn predicates, but which would otherwise fail the
+ `general_operand' test. */
+
+#ifndef REG_OK_STRICT
+#define PCREL_GENERAL_OPERAND_OK 0
+#else
+#define PCREL_GENERAL_OPERAND_OK (TARGET_PCREL)
+#endif
#define LEGITIMATE_PIC_OPERAND_P(X) \
((! symbolic_operand (X, VOIDmode) \
@@ -1361,7 +1414,8 @@ __transfer_from_trampoline () \
&& GET_CODE (CONST_DOUBLE_MEM (X)) == MEM \
&& symbolic_operand (XEXP (CONST_DOUBLE_MEM (X), 0), \
VOIDmode))) \
- || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)))
+ || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)) \
+ || PCREL_GENERAL_OPERAND_OK)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
@@ -1431,7 +1485,7 @@ __transfer_from_trampoline () \
|| (GET_CODE (X) == PLUS && XEXP (X, 0) == pic_offset_table_rtx \
&& flag_pic && GET_CODE (XEXP (X, 1)) == SYMBOL_REF) \
|| (GET_CODE (X) == PLUS && XEXP (X, 0) == pic_offset_table_rtx \
- && flag_pic && GET_CODE (XEXP (X, 1)) == LABEL_REF)) \
+ && flag_pic && GET_CODE (XEXP (X, 1)) == LABEL_REF))
#define GO_IF_NONINDEXED_ADDRESS(X, ADDR) \
{ if (INDIRECTABLE_1_ADDRESS_P (X)) goto ADDR; }
@@ -2032,6 +2086,8 @@ do { long l; \
'b' for byte insn (no effect, on the Sun; this is for the ISI).
'd' to force memory addressing to be absolute, not relative.
'f' for float insn (print a CONST_DOUBLE as a float rather than in hex)
+ 'o' for operands to go directly to output_operand_address (bypassing
+ print_operand_address--used only for SYMBOL_REFs under TARGET_PCREL)
'w' for FPA insn (print a CONST_DOUBLE as a SunFPA constant rather
than directly). Second part of 'y' below.
'x' for float insn (print a CONST_DOUBLE as a float rather than in hex),
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index a8dac72..c36e5dd 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -502,7 +502,7 @@
"
{
m68k_last_compare_had_fp_operands = 0;
- if (flag_pic && symbolic_operand (operands[1], SImode))
+ if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
{
/* The source is an address which requires PIC relocation.
Call legitimize_pic_address with the source, mode, and a relocation
@@ -517,8 +517,8 @@
;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes.
(define_insn ""
[(set (cc0)
- (compare (match_operand:SI 0 "nonimmediate_operand" "rKs,mr,>")
- (match_operand:SI 1 "general_operand" "mr,rKs,>")))]
+ (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mSr,mSa,>")
+ (match_operand:SI 1 "general_src_operand" "mSr,mSa,KTr,Ksr,>")))]
"!TARGET_5200"
"*
{
@@ -580,15 +580,15 @@
(define_expand "cmphi"
[(set (cc0)
- (compare (match_operand:HI 0 "nonimmediate_operand" "")
- (match_operand:HI 1 "general_operand" "")))]
+ (compare (match_operand:HI 0 "nonimmediate_src_operand" "")
+ (match_operand:HI 1 "general_src_operand" "")))]
"!TARGET_5200"
"m68k_last_compare_had_fp_operands = 0;")
(define_insn ""
[(set (cc0)
- (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m,>")
- (match_operand:HI 1 "general_operand" "d,rnm,m,n,>")))]
+ (compare (match_operand:HI 0 "nonimmediate_src_operand" "rnmS,d,n,mS,>")
+ (match_operand:HI 1 "general_src_operand" "d,rnmS,mS,n,>")))]
"!TARGET_5200"
"*
{
@@ -616,15 +616,15 @@
(define_expand "cmpqi"
[(set (cc0)
- (compare (match_operand:QI 0 "nonimmediate_operand" "")
- (match_operand:QI 1 "general_operand" "")))]
+ (compare (match_operand:QI 0 "nonimmediate_src_operand" "")
+ (match_operand:QI 1 "general_src_operand" "")))]
"!TARGET_5200"
"m68k_last_compare_had_fp_operands = 0;")
(define_insn ""
[(set (cc0)
- (compare (match_operand:QI 0 "nonimmediate_operand" "dn,md,>")
- (match_operand:QI 1 "general_operand" "dm,nd,>")))]
+ (compare (match_operand:QI 0 "nonimmediate_src_operand" "dn,dmS,>")
+ (match_operand:QI 1 "general_src_operand" "dmS,nd,>")))]
"!TARGET_5200"
"*
{
@@ -765,7 +765,7 @@
;; from a MEM at a constant bit position if we can't use this as a constraint.
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
+ [(set (cc0) (zero_extract (match_operand:QI 0 "memory_src_operand" "oS")
(const_int 1)
(minus:SI (const_int 7)
(match_operand:SI 1 "general_operand" "di"))))]
@@ -948,7 +948,7 @@
""
"
{
- if (flag_pic && symbolic_operand (operands[1], SImode))
+ if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
{
/* The source is an address which requires PIC relocation.
Call legitimize_pic_address with the source, mode, and a relocation
@@ -958,6 +958,17 @@
rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
operands[1] = legitimize_pic_address (operands[1], SImode, temp);
}
+ else if (flag_pic && TARGET_PCREL && ! reload_in_progress)
+ {
+ /* Don't allow writes to memory except via a register;
+ the m68k doesn't consider PC-relative addresses to be writable. */
+ if (symbolic_operand (operands[0], SImode))
+ operands[0] = force_reg (SImode, XEXP (operands[0], 0));
+ else if (GET_CODE (operands[0]) == MEM
+ && symbolic_operand (XEXP (operands[0], 0), SImode))
+ operands[0] = gen_rtx (MEM, SImode,
+ force_reg (SImode, XEXP (operands[0], 0)));
+ }
}")
;; General case of fullword move. The register constraints
@@ -967,12 +978,13 @@
;; Notes: make sure no alternative allows g vs g.
;; We don't allow f-regs since fixed point cannot go in them.
;; We do allow y and x regs since fixed point is allowed in them.
- [(set (match_operand:SI 0 "general_operand" "=g,da,y,!*x*r*m")
- (match_operand:SI 1 "general_operand" "daymKs,i,g,*x*r*m"))]
+ [(set (match_operand:SI 0 "general_operand" "=g,d,a<,y,!*x*r*m")
+ (match_operand:SI 1 "general_src_operand" "daymSKT,n,i,g,*x*r*m"))]
+
"!TARGET_5200"
"*
{
- if (which_alternative == 3)
+ if (which_alternative == 4)
return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\";
if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0]))
return \"fpmove%.l %x1,%x0\";
@@ -985,6 +997,19 @@
"TARGET_5200"
"* return output_move_simode (operands);")
+;; Special case of fullword move, where we need to get a non-GOT PIC
+;; reference into an address register.
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=a<")
+ (match_operand:SI 1 "pcrel_address" ""))]
+ "TARGET_PCREL"
+ "*
+{
+ if (push_operand (operands[0], SImode))
+ return \"pea %a1\";
+ return \"lea %a1,%0\";
+}")
+
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "general_operand" ""))]
@@ -993,7 +1018,7 @@
(define_insn ""
[(set (match_operand:HI 0 "general_operand" "=g")
- (match_operand:HI 1 "general_operand" "g"))]
+ (match_operand:HI 1 "general_src_operand" "gS"))]
"!TARGET_5200"
"* return output_move_himode (operands);")
@@ -1005,55 +1030,55 @@
(define_expand "movstricthi"
[(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
- (match_operand:HI 1 "general_operand" ""))]
+ (match_operand:HI 1 "general_src_operand" ""))]
""
"")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+dm"))
- (match_operand:HI 1 "general_operand" "rmn"))]
+ (match_operand:HI 1 "general_src_operand" "rmSn"))]
"!TARGET_5200"
"* return output_move_stricthi (operands);")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+d,m"))
- (match_operand:HI 1 "general_operand" "rmn,r"))]
+ (match_operand:HI 1 "general_src_operand" "rmn,r"))]
"TARGET_5200"
"* return output_move_stricthi (operands);")
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand" "")
- (match_operand:QI 1 "general_operand" ""))]
+ (match_operand:QI 1 "general_src_operand" ""))]
""
"")
(define_insn ""
[(set (match_operand:QI 0 "general_operand" "=d,*a,m")
- (match_operand:QI 1 "general_operand" "dmi*a,di*a,dmi"))]
+ (match_operand:QI 1 "general_src_operand" "dmSi*a,di*a,dmSi"))]
"!TARGET_5200"
"* return output_move_qimode (operands);")
(define_insn ""
[(set (match_operand:QI 0 "general_operand" "=d<Q>,dm,d*a")
- (match_operand:QI 1 "general_operand" "dmi,d<Q>,di*a"))]
+ (match_operand:QI 1 "general_src_operand" "dmi,d<Q>,di*a"))]
"TARGET_5200"
"* return output_move_qimode (operands);")
(define_expand "movstrictqi"
[(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
- (match_operand:QI 1 "general_operand" ""))]
+ (match_operand:QI 1 "general_src_operand" ""))]
""
"")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+dm"))
- (match_operand:QI 1 "general_operand" "dmn"))]
+ (match_operand:QI 1 "general_src_operand" "dmSn"))]
"!TARGET_5200"
"* return output_move_strictqi (operands);")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+d,m"))
- (match_operand:QI 1 "general_operand" "dmn,d"))]
+ (match_operand:QI 1 "general_src_operand" "dmn,d"))]
"TARGET_5200"
"* return output_move_strictqi (operands);")
@@ -1234,6 +1259,15 @@
operands[1] = change_address (operands[1], XFmode,
XEXP (operands[1], 0));
}
+ if (flag_pic && TARGET_PCREL && ! reload_in_progress)
+ {
+ /* Don't allow writes to memory except via a register;
+ the m68k doesn't consider PC-relative addresses to be writable. */
+ if (GET_CODE (operands[0]) == MEM
+ && symbolic_operand (XEXP (operands[0], 0), SImode))
+ operands[0] = gen_rtx (MEM, XFmode,
+ force_reg (SImode, XEXP (operands[0], 0)));
+ }
}")
(define_insn ""
@@ -1398,7 +1432,7 @@
(define_insn "truncsiqi2"
[(set (match_operand:QI 0 "general_operand" "=dm,d")
(truncate:QI
- (match_operand:SI 1 "general_operand" "doJ,i")))]
+ (match_operand:SI 1 "general_src_operand" "doJS,i")))]
""
"*
{
@@ -1417,7 +1451,7 @@
(define_insn "trunchiqi2"
[(set (match_operand:QI 0 "general_operand" "=dm,d")
(truncate:QI
- (match_operand:HI 1 "general_operand" "doJ,i")))]
+ (match_operand:HI 1 "general_src_operand" "doJS,i")))]
""
"*
{
@@ -1445,7 +1479,7 @@
(define_insn "truncsihi2"
[(set (match_operand:HI 0 "general_operand" "=dm,d")
(truncate:HI
- (match_operand:SI 1 "general_operand" "roJ,i")))]
+ (match_operand:SI 1 "general_src_operand" "roJS,i")))]
""
"*
{
@@ -1565,7 +1599,7 @@
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=do<>,d<")
- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "r,mS")))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"*
{
@@ -1594,7 +1628,7 @@
(define_insn ""
[(set (match_operand:HI 0 "general_operand" "=do<>,d")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"*
{
@@ -1635,7 +1669,7 @@
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=do<>,d")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_src_operand" "d,mS")))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
"*
{
@@ -1688,7 +1722,7 @@
(define_insn "extendqidi2"
[(set (match_operand:DI 0 "general_operand" "=d")
- (sign_extend:DI (match_operand:QI 1 "general_operand" "dm")))]
+ (sign_extend:DI (match_operand:QI 1 "general_src_operand" "rmS")))]
""
"*
{
@@ -1703,7 +1737,7 @@
(define_insn "extendhidi2"
[(set (match_operand:DI 0 "general_operand" "=d")
(sign_extend:DI
- (match_operand:HI 1 "general_operand" "rm")))]
+ (match_operand:HI 1 "general_src_operand" "rmS")))]
""
"*
{
@@ -1765,7 +1799,7 @@
(define_insn "extendhisi2"
[(set (match_operand:SI 0 "general_operand" "=*d,a")
(sign_extend:SI
- (match_operand:HI 1 "nonimmediate_operand" "0,rm")))]
+ (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
""
"*
{
@@ -2278,7 +2312,7 @@
(define_expand "addsi3"
[(set (match_operand:SI 0 "general_operand" "")
(plus:SI (match_operand:SI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
+ (match_operand:SI 2 "general_src_operand" "")))]
""
"")
@@ -2287,16 +2321,18 @@
;; This is needed since they are not themselves reloaded,
;; so commutativity won't apply to them.
(define_insn "*addsi3_internal"
- [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r")
- (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
- (match_operand:SI 2 "general_operand" "dIKLs,rJK,a,mrIKLs")))]
+ [(set (match_operand:SI 0 "general_operand" "=m,?a,?a,d,a")
+ (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0,0")
+ (match_operand:SI 2 "general_src_operand" "dIKLT,rJK,a,mSrIKLT,mSrIKLs")))]
+
+
"! TARGET_5200"
"* return output_addsi3 (operands);")
(define_insn "*addsi3_5200"
[(set (match_operand:SI 0 "general_operand" "=m,?a,?a,r")
(plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0")
- (match_operand:SI 2 "general_operand" "d,rJK,a,mrIKLs")))]
+ (match_operand:SI 2 "general_src_operand" "d,rJK,a,mrIKLs")))]
"TARGET_5200"
"* return output_addsi3 (operands);")
@@ -2304,14 +2340,14 @@
[(set (match_operand:SI 0 "general_operand" "=a")
(plus:SI (match_operand:SI 1 "general_operand" "0")
(sign_extend:SI
- (match_operand:HI 2 "nonimmediate_operand" "rm"))))]
+ (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
"!TARGET_5200"
"add%.w %2,%0")
(define_insn "addhi3"
[(set (match_operand:HI 0 "general_operand" "=m,r")
(plus:HI (match_operand:HI 1 "general_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "dn,rmn")))]
+ (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
"!TARGET_5200"
"*
{
@@ -2373,7 +2409,7 @@
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(plus:HI (match_dup 0)
- (match_operand:HI 1 "general_operand" "dn,rmn")))]
+ (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
"!TARGET_5200"
"*
{
@@ -2428,7 +2464,7 @@
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
- (plus:HI (match_operand:HI 1 "general_operand" "dn,rmn")
+ (plus:HI (match_operand:HI 1 "general_src_operand" "dn,rmSn")
(match_dup 0)))]
"!TARGET_5200"
"*
@@ -2485,7 +2521,7 @@
(define_insn "addqi3"
[(set (match_operand:QI 0 "general_operand" "=m,d")
(plus:QI (match_operand:QI 1 "general_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "dn,dmn")))]
+ (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"*
{
@@ -2511,7 +2547,7 @@
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(plus:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "dn,dmn")))]
+ (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"*
{
@@ -2536,7 +2572,7 @@
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
- (plus:QI (match_operand:QI 1 "general_operand" "dn,dmn")
+ (plus:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
(match_dup 0)))]
"!TARGET_5200"
"*
@@ -2802,9 +2838,9 @@
} ")
(define_insn "subsi3"
- [(set (match_operand:SI 0 "general_operand" "=m,r")
- (minus:SI (match_operand:SI 1 "general_operand" "0,0")
- (match_operand:SI 2 "general_operand" "ds,mrs")))]
+ [(set (match_operand:SI 0 "general_operand" "=m,d,a")
+ (minus:SI (match_operand:SI 1 "general_operand" "0,0,0")
+ (match_operand:SI 2 "general_src_operand" "dT,mSrT,mSrs")))]
""
"sub%.l %2,%0")
@@ -2812,35 +2848,35 @@
[(set (match_operand:SI 0 "general_operand" "=a")
(minus:SI (match_operand:SI 1 "general_operand" "0")
(sign_extend:SI
- (match_operand:HI 2 "nonimmediate_operand" "rm"))))]
+ (match_operand:HI 2 "nonimmediate_src_operand" "rmS"))))]
"!TARGET_5200"
"sub%.w %2,%0")
(define_insn "subhi3"
[(set (match_operand:HI 0 "general_operand" "=m,r")
(minus:HI (match_operand:HI 1 "general_operand" "0,0")
- (match_operand:HI 2 "general_operand" "dn,rmn")))]
+ (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
"!TARGET_5200"
"sub%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(minus:HI (match_dup 0)
- (match_operand:HI 1 "general_operand" "dn,rmn")))]
+ (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
"!TARGET_5200"
"sub%.w %1,%0")
(define_insn "subqi3"
[(set (match_operand:QI 0 "general_operand" "=m,d")
(minus:QI (match_operand:QI 1 "general_operand" "0,0")
- (match_operand:QI 2 "general_operand" "dn,dmn")))]
+ (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"sub%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(minus:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "dn,dmn")))]
+ (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"sub%.b %1,%0")
@@ -2961,7 +2997,7 @@
(define_insn "mulhi3"
[(set (match_operand:HI 0 "general_operand" "=d")
(mult:HI (match_operand:HI 1 "general_operand" "%0")
- (match_operand:HI 2 "general_operand" "dmn")))]
+ (match_operand:HI 2 "general_src_operand" "dmSn")))]
""
"*
{
@@ -2977,7 +3013,7 @@
(mult:SI (sign_extend:SI
(match_operand:HI 1 "nonimmediate_operand" "%0"))
(sign_extend:SI
- (match_operand:HI 2 "nonimmediate_operand" "dm"))))]
+ (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
""
"*
{
@@ -3013,7 +3049,8 @@
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=d")
(mult:SI (match_operand:SI 1 "general_operand" "%0")
- (match_operand:SI 2 "general_operand" "dmsK")))]
+ (match_operand:SI 2 "general_src_operand" "dmSTK")))]
+
"TARGET_68020"
"muls%.l %2,%0")
@@ -3029,7 +3066,7 @@
(mult:SI (zero_extend:SI
(match_operand:HI 1 "nonimmediate_operand" "%0"))
(zero_extend:SI
- (match_operand:HI 2 "nonimmediate_operand" "dm"))))]
+ (match_operand:HI 2 "nonimmediate_src_operand" "dmS"))))]
""
"*
{
@@ -3519,7 +3556,7 @@
(define_insn "divmodsi4"
[(set (match_operand:SI 0 "general_operand" "=d")
(div:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "dmsK")))
+ (match_operand:SI 2 "general_src_operand" "dmSTK")))
(set (match_operand:SI 3 "general_operand" "=d")
(mod:SI (match_dup 1) (match_dup 2)))]
"TARGET_68020 && !TARGET_5200"
@@ -3534,7 +3571,7 @@
(define_insn "udivmodsi4"
[(set (match_operand:SI 0 "general_operand" "=d")
(udiv:SI (match_operand:SI 1 "general_operand" "0")
- (match_operand:SI 2 "general_operand" "dmsK")))
+ (match_operand:SI 2 "general_src_operand" "dmSTK")))
(set (match_operand:SI 3 "general_operand" "=d")
(umod:SI (match_dup 1) (match_dup 2)))]
"TARGET_68020 && !TARGET_5200"
@@ -3549,7 +3586,7 @@
(define_insn "divmodhi4"
[(set (match_operand:HI 0 "general_operand" "=d")
(div:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "dmsK")))
+ (match_operand:HI 2 "general_src_operand" "dmSKT")))
(set (match_operand:HI 3 "general_operand" "=d")
(mod:HI (match_dup 1) (match_dup 2)))]
"!TARGET_5200"
@@ -3572,7 +3609,7 @@
(define_insn "udivmodhi4"
[(set (match_operand:HI 0 "general_operand" "=d")
(udiv:HI (match_operand:HI 1 "general_operand" "0")
- (match_operand:HI 2 "general_operand" "dmsK")))
+ (match_operand:HI 2 "general_src_operand" "dmSKT")))
(set (match_operand:HI 3 "general_operand" "=d")
(umod:HI (match_dup 1) (match_dup 2)))]
"!TARGET_5200"
@@ -3675,16 +3712,16 @@
;; can't allocate pseudos into it.
(define_expand "andsi3"
- [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
- (and:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "dKs,dmMs")))]
+ [(set (match_operand:SI 0 "not_sp_operand" "")
+ (and:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_src_operand" "")))]
""
"")
(define_insn "andsi3_internal"
[(set (match_operand:SI 0 "not_sp_operand" "=m,d")
(and:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "dKs,dmMs")))]
+ (match_operand:SI 2 "general_src_operand" "dKT,dmSM")))]
"!TARGET_5200"
"*
{
@@ -3694,27 +3731,27 @@
(define_insn "andsi3_5200"
[(set (match_operand:SI 0 "not_sp_operand" "=m,d")
(and:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,dmsK")))]
+ (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
"TARGET_5200"
"and%.l %2,%0")
(define_insn "andhi3"
[(set (match_operand:HI 0 "general_operand" "=m,d")
(and:HI (match_operand:HI 1 "general_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "dn,dmn")))]
+ (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"and%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(and:HI (match_dup 0)
- (match_operand:HI 1 "general_operand" "dn,dmn")))]
+ (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"and%.w %1,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
- (and:HI (match_operand:HI 1 "general_operand" "dn,dmn")
+ (and:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
(match_dup 0)))]
"!TARGET_5200"
"and%.w %1,%0")
@@ -3722,20 +3759,20 @@
(define_insn "andqi3"
[(set (match_operand:QI 0 "general_operand" "=m,d")
(and:QI (match_operand:QI 1 "general_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "dn,dmn")))]
+ (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"and%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(and:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "dn,dmn")))]
+ (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"and%.b %1,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
- (and:QI (match_operand:QI 1 "general_operand" "dn,dmn")
+ (and:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
(match_dup 0)))]
"!TARGET_5200"
"and%.b %1,%0")
@@ -3850,14 +3887,14 @@
(define_expand "iorsi3"
[(set (match_operand:SI 0 "general_operand" "")
(ior:SI (match_operand:SI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
+ (match_operand:SI 2 "general_src_operand" "")))]
""
"")
(define_insn "iorsi3_internal"
[(set (match_operand:SI 0 "general_operand" "=m,d")
(ior:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "dKs,dmMs")))]
+ (match_operand:SI 2 "general_src_operand" "dKT,dmSMT")))]
"! TARGET_5200"
"*
{
@@ -3867,27 +3904,27 @@
(define_insn "iorsi3_5200"
[(set (match_operand:SI 0 "general_operand" "=m,d")
(ior:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,dmsK")))]
+ (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
"TARGET_5200"
"or%.l %2,%0")
(define_insn "iorhi3"
[(set (match_operand:HI 0 "general_operand" "=m,d")
(ior:HI (match_operand:HI 1 "general_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "dn,dmn")))]
+ (match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"or%.w %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
(ior:HI (match_dup 0)
- (match_operand:HI 1 "general_operand" "dn,dmn")))]
+ (match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"or%.w %1,%0")
(define_insn ""
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d"))
- (ior:HI (match_operand:HI 1 "general_operand" "dn,dmn")
+ (ior:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
(match_dup 0)))]
"!TARGET_5200"
"or%.w %1,%0")
@@ -3895,20 +3932,20 @@
(define_insn "iorqi3"
[(set (match_operand:QI 0 "general_operand" "=m,d")
(ior:QI (match_operand:QI 1 "general_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "dn,dmn")))]
+ (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"or%.b %2,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
(ior:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "dn,dmn")))]
+ (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
"!TARGET_5200"
"or%.b %1,%0")
(define_insn ""
[(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d"))
- (ior:QI (match_operand:QI 1 "general_operand" "dn,dmn")
+ (ior:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
(match_dup 0)))]
"!TARGET_5200"
"or%.b %1,%0")
@@ -4046,7 +4083,8 @@
(define_insn "xorsi3_internal"
[(set (match_operand:SI 0 "general_operand" "=do,m")
(xor:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "di,dKs")))]
+ (match_operand:SI 2 "general_operand" "di,dKT")))]
+
"!TARGET_5200"
"*
{
@@ -5267,7 +5305,7 @@
[(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
(const_int 32)
(match_operand:SI 2 "const_int_operand" "n"))
- (match_operand:SI 3 "general_operand" "rmi"))]
+ (match_operand:SI 3 "general_src_operand" "rmSi"))]
"TARGET_68020 && TARGET_BITFIELD
&& (INTVAL (operands[2]) % 8) == 0
&& ! mode_dependent_address_p (XEXP (operands[0], 0))"
@@ -5318,7 +5356,7 @@
;
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=rm")
- (zero_extract:SI (match_operand:QI 1 "memory_operand" "o")
+ (zero_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
(const_int 32)
(match_operand:SI 3 "const_int_operand" "n")))]
"TARGET_68020 && TARGET_BITFIELD
@@ -5372,7 +5410,7 @@
;
(define_insn ""
[(set (match_operand:SI 0 "general_operand" "=rm")
- (sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
+ (sign_extract:SI (match_operand:QI 1 "memory_src_operand" "oS")
(const_int 32)
(match_operand:SI 3 "const_int_operand" "n")))]
"TARGET_68020 && TARGET_BITFIELD
@@ -6823,21 +6861,28 @@
"*
if (GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
+ {
+ if (TARGET_PCREL) return \"bsr.l %o0\";
#ifdef MOTOROLA
#ifdef HPUX_ASM
- return \"bsr.l %0\";
+ return \"bsr.l %0\";
#else
#ifdef USE_GAS
- return \"bsr.l %0@PLTPC\";
+ return \"bsr.l %0@PLTPC\";
#else
- return \"bsr %0@PLTPC\";
+ return \"bsr %0@PLTPC\";
#endif
#endif
#else
- /* The ',a1' is a dummy argument telling the Sun assembler we want PIC,
- GAS just plain ignores it. */
- return \"jbsr %0,a1\";
+#ifdef USE_GAS
+ return \"bsr.l %0\";
+#else
+ /* The ',a1' is a dummy argument telling the Sun assembler we want PIC,
+ GAS just plain ignores it. FIXME: not anymore, gas doesnt! */
+ return \"jbsr %0,a1\";
#endif
+#endif
+ }
return \"jsr %0\";
")
@@ -6887,6 +6932,7 @@
if (GET_CODE (operands[1]) == MEM
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
{
+ if (TARGET_PCREL) return \"bsr.l %o1\";
#ifdef MOTOROLA
#ifdef HPUX_ASM
return \"bsr.l %1\";
@@ -6898,10 +6944,14 @@
#endif
#endif
#else
+#ifdef USE_GAS
+ return \"bsr.l %1\";
+#else
/* The ',a1' is a dummy argument telling the Sun assembler we want PIC
- GAS just plain ignores it. */
+ GAS just plain ignores it. FIXME: Not anymore, gas doesnt! */
return \"jbsr %1,a1\";
#endif
+#endif
}
return \"jsr %1\";
")
diff --git a/gcc/config/m68k/m68kelf.h b/gcc/config/m68k/m68kelf.h
index 476692d..88dfc3d 100644
--- a/gcc/config/m68k/m68kelf.h
+++ b/gcc/config/m68k/m68kelf.h
@@ -246,9 +246,11 @@ extern int switch_table_difference_label_flag;
/* In m68k svr4, a symbol_ref rtx can be a valid PIC operand if it is an
operand of a function call. */
#undef LEGITIMATE_PIC_OPERAND_P
-#define LEGITIMATE_PIC_OPERAND_P(X) \
- (! symbolic_operand (X, VOIDmode) \
- || ((GET_CODE(X) == SYMBOL_REF) && SYMBOL_REF_FLAG(X)))
+
+#define LEGITIMATE_PIC_OPERAND_P(X) \
+ (! symbolic_operand (X, VOIDmode) \
+ || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)) \
+ || PCREL_GENERAL_OPERAND_OK)
/* Turn off function cse if we are doing PIC. We always want function call
to be done as `bsr foo@PLTPC', so it will force the assembler to create
@@ -261,6 +263,8 @@ extern int switch_table_difference_label_flag;
if (flag_pic) flag_no_function_cse = 1; \
if (! TARGET_68020 && flag_pic == 2) \
error("-fPIC is not currently supported on the 68000 or 68010\n"); \
+ if (TARGET_PCREL && flag_pic == 0) \
+ flag_pic = 1; \
}
/* end of stuff from m68kv4.h */
diff --git a/gcc/config/m68k/m68kv4.h b/gcc/config/m68k/m68kv4.h
index 16cc1c9..9f2744d 100644
--- a/gcc/config/m68k/m68kv4.h
+++ b/gcc/config/m68k/m68kv4.h
@@ -297,7 +297,8 @@ int switch_table_difference_label_flag;
&& ! (GET_CODE (X) == CONST_DOUBLE && CONST_DOUBLE_MEM (X) \
&& GET_CODE (CONST_DOUBLE_MEM (X)) == MEM \
&& symbolic_operand (XEXP (CONST_DOUBLE_MEM (X), 0), VOIDmode))) \
- || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)))
+ || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X)) \
+ || PCREL_GENERAL_OPERAND_OK)
/* Turn off function cse if we are doing PIC. We always want function call
to be done as `bsr foo@PLTPC', so it will force the assembler to create