diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9ba27517538..1cca26365fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2000-07-17 Richard Henderson + + * config/ia64/ia64.md (movdi): Split out load address code. + New post-reload splitter for symbolic operands. + (movdi_internal): Abort if we didn't split symbolic operands + when we should have. + * config/ia64/ia64.c (ia64_expand_load_address): New, from movdi bits. + (ia64_reorg): Split insns when not optimizing. + * config/ia64/ia64-protos.h (ia64_expand_load_address): Declare. + Mon Jul 17 23:43:26 MET DST 2000 Jan Hubicka * real.h (REAL_VALUE_TO_TARGET_LONG_DOUBLE): Use LONG_DOUBLE_TYPE_SIZE @@ -39,7 +49,7 @@ Mon Jul 17 08:26:35 2000 Clinton Popetz 2000-07-17 Mark Klein - * pa.c (emit_hpdiv_const): Update to match new pattern for udivsi3. + * pa.c (emit_hpdiv_const): Update to match new pattern for udivsi3. 2000-07-17 J. David Anglin diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index e918420aa3f..8949c1dfac9 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -52,6 +52,7 @@ extern int call_multiple_values_operation PARAMS((rtx, enum machine_mode)); extern int predicate_operator PARAMS((rtx, enum machine_mode)); extern int ia64_move_ok PARAMS((rtx, rtx)); +extern void ia64_expand_load_address PARAMS((rtx, rtx)); extern void ia64_expand_fetch_and_op PARAMS ((enum fetchop_code, enum machine_mode, rtx [])); extern void ia64_expand_op_and_fetch PARAMS ((enum fetchop_code, diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index c88f1a94753..a87d25661c6 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -542,7 +542,7 @@ predicate_operator (op, mode) return ((GET_MODE (op) == mode || mode == VOIDmode) && (code == EQ || code == NE)); } - + /* Return 1 if the operands of a move are ok. */ int @@ -566,6 +566,53 @@ ia64_move_ok (dst, src) 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); +} /* Begin the assembly file. */ @@ -3016,6 +3063,10 @@ void 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); } diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 9c90de16e8b..1e5253b2019 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -247,53 +247,11 @@ "" " { - /* ??? 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]); @@ -303,21 +261,53 @@ [(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" "")))