return ((GET_MODE (op) == mode || mode == VOIDmode)
&& (code == EQ || code == NE));
}
-
+\f
/* Return 1 if the operands of a move are ok. */
int
else
return GET_CODE (src) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (src);
}
+
+/* Expand a symbolic constant load. */
+/* ??? Should generalize this, so that we can also support 32 bit pointers. */
+
+void
+ia64_expand_load_address (dest, src)
+ rtx dest, src;
+{
+ rtx temp;
+
+ /* The destination could be a MEM during initial rtl generation,
+ which isn't a valid destination for the PIC load address patterns. */
+ if (! register_operand (dest, DImode))
+ temp = gen_reg_rtx (DImode);
+ else
+ temp = dest;
+
+ if (TARGET_AUTO_PIC)
+ emit_insn (gen_load_gprel64 (temp, src));
+ else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FLAG (src))
+ emit_insn (gen_load_fptr (temp, src));
+ else if (sdata_symbolic_operand (src, DImode))
+ emit_insn (gen_load_gprel (temp, src));
+ else if (GET_CODE (src) == CONST
+ && GET_CODE (XEXP (src, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (src, 0), 1)) == CONST_INT
+ && (INTVAL (XEXP (XEXP (src, 0), 1)) & 0x1fff) != 0)
+ {
+ rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode);
+ rtx sym = XEXP (XEXP (src, 0), 0);
+ HOST_WIDE_INT ofs, hi, lo;
+
+ /* Split the offset into a sign extended 14-bit low part
+ and a complementary high part. */
+ ofs = INTVAL (XEXP (XEXP (src, 0), 1));
+ lo = ((ofs & 0x3fff) ^ 0x2000) - 0x2000;
+ hi = ofs - lo;
+
+ emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi)));
+ emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
+ }
+ else
+ emit_insn (gen_load_symptr (temp, src));
+
+ if (temp != dest)
+ emit_move_insn (dest, temp);
+}
\f
/* Begin the assembly file. */
ia64_reorg (insns)
rtx insns;
{
+ /* If optimizing, we'll have split before scheduling. */
+ if (optimize == 0)
+ split_all_insns (0);
+
emit_predicate_relation_info (insns);
emit_insn_group_barriers (insns);
}
""
"
{
- /* ??? Should generalize this, so that we can also support 32 bit
- pointers. */
if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
{
- rtx temp;
-
- /* Operand[0] could be a MEM, which isn't a valid destination for the
- PIC load address patterns. */
- if (! register_operand (operands[0], DImode))
- temp = gen_reg_rtx (DImode);
- else
- temp = operands[0];
-
- if (TARGET_AUTO_PIC)
- emit_insn (gen_load_gprel64 (temp, operands[1]));
- else if (GET_CODE (operands[1]) == SYMBOL_REF
- && SYMBOL_REF_FLAG (operands[1]))
- emit_insn (gen_load_fptr (temp, operands[1]));
- else if (sdata_symbolic_operand (operands[1], DImode))
- emit_insn (gen_load_gprel (temp, operands[1]));
- else if (GET_CODE (operands[1]) == CONST
- && GET_CODE (XEXP (operands[1], 0)) == PLUS
- && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT
- && (INTVAL (XEXP (XEXP (operands[1], 0), 1)) & 0x1fff) != 0)
- {
- rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode);
- rtx sym = XEXP (XEXP (operands[1], 0), 0);
- HOST_WIDE_INT ofs, hi, lo;
-
- /* Split the offset into a sign extended 14-bit low part
- and a complementary high part. */
- ofs = INTVAL (XEXP (XEXP (operands[1], 0), 1));
- lo = ((ofs & 0x3fff) ^ 0x2000) - 0x2000;
- hi = ofs - lo;
-
- emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi)));
- emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
- }
- else
- emit_insn (gen_load_symptr (temp, operands[1]));
-
- if (temp == operands[0])
- DONE;
-
- operands[1] = temp;
+ ia64_expand_load_address (operands[0], operands[1]);
+ DONE;
}
-
if (! reload_in_progress && ! reload_completed
&& ! ia64_move_ok (operands[0], operands[1]))
operands[1] = force_reg (DImode, operands[1]);
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r, m,r,*f,*f,*f,Q, r,*b")
(match_operand:DI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,Q,*f,*b,rO"))]
"ia64_move_ok (operands[0], operands[1])"
- "@
- mov %0 = %r1
- addl %0 = %1, r0
- movl %0 = %1
- ld8%O1 %0 = %1%P1
- st8%Q0 %0 = %r1%P0
- getf.sig %0 = %1
- setf.sig %0 = %r1
- mov %0 = %1
- ldf8 %0 = %1%P1
- stf8 %0 = %1%P0
- mov %0 = %1
- mov %0 = %r1"
+ "*
+{
+ static const char * const alt[] = {
+ \"mov %0 = %r1\",
+ \"addl %0 = %1, r0\",
+ \"movl %0 = %1\",
+ \"ld8%O1 %0 = %1%P1\",
+ \"st8%Q0 %0 = %r1%P0\",
+ \"getf.sig %0 = %1\",
+ \"setf.sig %0 = %r1\",
+ \"mov %0 = %1\",
+ \"ldf8 %0 = %1%P1\",
+ \"stf8 %0 = %1%P0\",
+ \"mov %0 = %1\",
+ \"mov %0 = %r1\"
+ };
+
+ /* We use 'i' for alternative 2 despite possible PIC problems.
+
+ If we define LEGITIMATE_CONSTANT_P such that symbols are not
+ allowed, then the compiler dumps the data into constant memory
+ instead of letting us read the values from the GOT. Similarly
+ if we use 'n' instead of 'i'.
+
+ Instead, we allow such insns through reload and then split them
+ afterward (even without optimization). Therefore, we should
+ never get so far with a symbolic operand. */
+
+ if (which_alternative == 2 && ! TARGET_NO_PIC
+ && symbolic_operand (operands[1], VOIDmode))
+ abort ();
+
+ return alt[which_alternative];
+}"
[(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I")])
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "symbolic_operand" ""))]
+ "reload_completed && ! TARGET_NO_PIC"
+ [(const_int 0)]
+ "
+{
+ ia64_expand_load_address (operands[0], operands[1]);
+ DONE;
+}")
+
(define_expand "load_fptr"
[(set (match_dup 2)
(plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))