aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Macleod <amacleod@cygnus.com>2000-10-03 01:08:36 +0000
committerAndrew Macleod <amacleod@cygnus.com>2000-10-03 01:08:36 +0000
commita77d4ff39d774b173499b723cbdec840ac402a53 (patch)
tree736b2b011e21b034c365a317adea38954b96686e
parent37a5c652a3a5d099a96bf298df3b31e4a3ad034c (diff)
2000-10-01 Andrew MacLeod <amacleod@redhat.com>
* dwarf2out.c (loc_descriptor): use SUBREG_REG to get the register. * emit-rtl.c (gen_lowpart_common, gen_imagpart): Spacing nits. (gen_highpart, constant_subword, operand_subword): Spacing nits. * function.c (purge_single_hard_subreg_set): Correct last change, find correct offsets for subreg. * reload.c (push_reload): Replace missing clause. Index: gcc/dwarf2out.c =================================================================== RCS file: /cvs/gcc/egcs/gcc/dwarf2out.c,v retrieving revision 1.205.2.1 diff -c -p -r1.205.2.1 dwarf2out.c *** dwarf2out.c 2000/09/24 22:21:31 1.205.2.1 --- dwarf2out.c 2000/10/03 00:15:35 *************** loc_descriptor (rtl) *** 7363,7369 **** up an entire register. For now, just assume that it is legitimate to make the Dwarf info refer to the whole register which contains the given subreg. */ ! rtl = XEXP (rtl, 0); /* Fall through. */ --- 7363,7369 ---- up an entire register. For now, just assume that it is legitimate to make the Dwarf info refer to the whole register which contains the given subreg. */ ! rtl = SUBREG_REG (rtl); /* Fall through. */ Index: gcc/emit-rtl.c =================================================================== RCS file: /cvs/gcc/egcs/gcc/emit-rtl.c,v retrieving revision 1.147.2.1 diff -c -p -r1.147.2.1 emit-rtl.c *** emit-rtl.c 2000/09/24 22:21:31 1.147.2.1 --- emit-rtl.c 2000/10/03 00:15:36 *************** gen_lowpart_common (mode, x) *** 830,836 **** if (REGNO (x) < FIRST_PSEUDO_REGISTER) { int final_regno = REGNO (x) + ! SUBREG_REGNO_OFFSET(REGNO (x), GET_MODE (x), offset, mode); /* If the final regno is not valid for MODE, punt. */ /* ??? We do allow it if the current REG is not valid for --- 830,836 ---- if (REGNO (x) < FIRST_PSEUDO_REGISTER) { int final_regno = REGNO (x) + ! SUBREG_REGNO_OFFSET (REGNO (x), GET_MODE (x), offset, mode); /* If the final regno is not valid for MODE, punt. */ /* ??? We do allow it if the current REG is not valid for *************** gen_imagpart (mode, x) *** 1127,1133 **** return XEXP (x, 1); else if (WORDS_BIG_ENDIAN) return gen_lowpart (mode, x); ! else if (!WORDS_BIG_ENDIAN && GET_MODE_BITSIZE (mode) < BITS_PER_WORD && REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER) --- 1127,1133 ---- return XEXP (x, 1); else if (WORDS_BIG_ENDIAN) return gen_lowpart (mode, x); ! else if (! WORDS_BIG_ENDIAN && GET_MODE_BITSIZE (mode) < BITS_PER_WORD && REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER) *************** gen_highpart (mode, x) *** 1266,1272 **** if (REGNO (x) < FIRST_PSEUDO_REGISTER) { int final_regno = REGNO (x) + ! SUBREG_REGNO_OFFSET(REGNO (x), GET_MODE (x), offset, mode); /* integrate.c can't handle parts of a return value register. ??? Then integrate.c should be fixed! --- 1266,1272 ---- if (REGNO (x) < FIRST_PSEUDO_REGISTER) { int final_regno = REGNO (x) + ! SUBREG_REGNO_OFFSET (REGNO (x), GET_MODE (x), offset, mode); /* integrate.c can't handle parts of a return value register. ??? Then integrate.c should be fixed! *************** constant_subword (op, offset, mode) *** 1377,1383 **** else if (BITS_PER_WORD == 16) { val = k[offset >> 1]; ! if ((offset & 1) == !WORDS_BIG_ENDIAN) val >>= 16; val &= 0xffff; return GEN_INT (val); --- 1377,1383 ---- else if (BITS_PER_WORD == 16) { val = k[offset >> 1]; ! if ((offset & 1) == ! WORDS_BIG_ENDIAN) val >>= 16; val &= 0xffff; return GEN_INT (val); *************** constant_subword (op, offset, mode) *** 1405,1413 **** #if HOST_BITS_PER_WIDE_INT >= 64 else if (BITS_PER_WORD >= 64 && offset <= 1) { ! val = k[offset*2 + ! WORDS_BIG_ENDIAN]; val = (((val & 0xffffffff) ^ 0x80000000) - 0x80000000) << 32; ! val |= (HOST_WIDE_INT) k[offset*2 + WORDS_BIG_ENDIAN] & 0xffffffff; return GEN_INT (val); } #endif --- 1405,1413 ---- #if HOST_BITS_PER_WIDE_INT >= 64 else if (BITS_PER_WORD >= 64 && offset <= 1) { ! val = k[offset * 2 + ! WORDS_BIG_ENDIAN]; val = (((val & 0xffffffff) ^ 0x80000000) - 0x80000000) << 32; ! val |= (HOST_WIDE_INT) k[offset * 2 + WORDS_BIG_ENDIAN] & 0xffffffff; return GEN_INT (val); } #endif *************** constant_subword (op, offset, mode) *** 1456,1462 **** if (BITS_PER_WORD == 16) { ! if ((offset & 1) == !WORDS_BIG_ENDIAN) val >>= 16; val &= 0xffff; } --- 1456,1462 ---- if (BITS_PER_WORD == 16) { ! if ((offset & 1) == ! WORDS_BIG_ENDIAN) val >>= 16; val &= 0xffff; } *************** operand_subword (op, offset, validate_ad *** 1602,1608 **** if (REGNO (op) < FIRST_PSEUDO_REGISTER) { int final_regno = REGNO (op) + ! SUBREG_REGNO_OFFSET(REGNO (op), GET_MODE (op), offset * UNITS_PER_WORD, word_mode); --- 1602,1608 ---- if (REGNO (op) < FIRST_PSEUDO_REGISTER) { int final_regno = REGNO (op) + ! SUBREG_REGNO_OFFSET (REGNO (op), GET_MODE (op), offset * UNITS_PER_WORD, word_mode); Index: gcc/function.c =================================================================== RCS file: /cvs/gcc/egcs/gcc/function.c,v retrieving revision 1.220.2.2 diff -c -p -r1.220.2.2 function.c *** function.c 2000/09/30 13:32:25 1.220.2.2 --- function.c 2000/10/03 00:15:39 *************** purge_single_hard_subreg_set (pattern) *** 3409,3418 **** { rtx reg = SET_DEST (pattern); enum machine_mode mode = GET_MODE (SET_DEST (pattern)); ! if (GET_CODE (reg) == SUBREG && REGNO (reg) < FIRST_PSEUDO_REGISTER) { ! reg = gen_rtx_REG (mode, SUBREG_REGNO (reg)); SET_DEST (pattern) = reg; } } --- 3409,3430 ---- { rtx reg = SET_DEST (pattern); enum machine_mode mode = GET_MODE (SET_DEST (pattern)); + int offset = 0; + + if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG + && REGNO (SUBREG_REG (reg)) < FIRST_PSEUDO_REGISTER) + { + offset = SUBREG_REGNO_OFFSET (REGNO (SUBREG_REG (reg)), + GET_MODE (SUBREG_REG (reg)), + SUBREG_BYTE (reg), + GET_MODE (reg)); + reg = SUBREG_REG (reg); + } + ! if (REGNO (reg) < FIRST_PSEUDO_REGISTER) { ! reg = gen_rtx_REG (mode, REGNO (reg) + offset); SET_DEST (pattern) = reg; } } Index: gcc/reload.c =================================================================== RCS file: /cvs/gcc/egcs/gcc/reload.c,v retrieving revision 1.130.2.2 diff -c -p -r1.130.2.2 reload.c *** reload.c 2000/09/30 13:32:26 1.130.2.2 --- reload.c 2000/10/03 00:15:41 *************** push_reload (in, out, inloc, outloc, cla *** 1051,1056 **** --- 1051,1057 ---- (except in the case of STRICT_LOW_PART, and in that case the constraint should label it input-output.) */ if (out != 0 && GET_CODE (out) == SUBREG + && (SUBREG_BYTE (out) == 0 || strict_low) #ifdef CLASS_CANNOT_CHANGE_MODE && (class != CLASS_CANNOT_CHANGE_MODE || ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)), git-svn-id: https://gcc.gnu.org/svn/gcc/branches/subreg-byte-branch@36697 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog326
-rw-r--r--gcc/dwarf2out.c2
-rw-r--r--gcc/emit-rtl.c16
-rw-r--r--gcc/function.c16
-rw-r--r--gcc/reload.c1
5 files changed, 350 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3af3e093d34..ed7b8551fc8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2000-10-01 Andrew MacLeod <amacleod@redhat.com>
+
+ * dwarf2out.c (loc_descriptor): use SUBREG_REG to get the register.
+ * emit-rtl.c (gen_lowpart_common, gen_imagpart): Spacing nits.
+ (gen_highpart, constant_subword, operand_subword): Spacing nits.
+ * function.c (purge_single_hard_subreg_set): Correct last change, find
+ correct offsets for subreg.
+ * reload.c (push_reload): Replace missing clause.
+
2000-09-30 Andrew MacLeod <amacleod@redhat.com>
* function.c (purge_single_hard_subreg_set): Dont use SUBREG_WORD.
@@ -7,6 +16,323 @@
* config/i960/i960.md (zero_extendqihi2): SUBREG's are byte offsets.
* config/m68hc11/m68hc11.c (m68hc11_gen_lowpart): Don't use SUBREG_WORD.
+2000-05-04 Jakub Jelinek <jakub@redhat.com>
+
+ * emit-rtl.c (gen_lowpart_common): Return inner SUBREG
+ if it is lowpart SUBREG, not when SUBREG_BYTE is 0.
+
+ * flow.c (mark_set_1): Remove ALTER_HARD_SUBREG. Use
+ SUBREG_REGNO_OFFSET instead.
+ * config/d30v/d30v.c (d30v_split_double): Use SUBREG_REGNO_OFFSET
+ instead of SUBREG_WORD.
+ (d30v_print_operand_memory_reference): Likewise.
+
+ * ssa.c (coalesce_regs_in_copies): Use ! subreg_lowpart_p instead of
+ checking SUBREG_WORD != 0.
+
+ * cse.c (remove_invalid_subreg_refs): Change offset argument type to
+ unsigned int.
+ * ssa.c (rename_insn_1): Use subreg_lowpart_p instead of checking
+ SUBREG_WORD == 0.
+ (rename_equivalent_regs_in_insn): Likewise.
+ * rtl.h (SUBREG_BYTE): Change to XCUINT from XCINT.
+ * emit-rtl.c (subreg_hard_regno): Make byte_offset, base_regno and
+ final_regno unsigned.
+ (subreg_lowpart_p): Likewise with offset.
+ (operand_subword): Likewise for partwords.
+
+ * config/sparc/sparc.md (cmp_siqi_trunc, cmp_siqi_trunc_set,
+ cmp_diqi_trunc, cmp_diqi_trunc_set, lshrdi3_v8plus+1,
+ lshrdi3_v8plus+2, lshrdi3_v8plus+3, lshrdi3_v8plus+4): Use proper
+ SUBREG_BYTE offset for non-paradoxical subregs in patterns.
+
+ * emit-rtl.c (gen_lowpart_SUBREG): New function.
+ * rtl.h (gen_lowpart_SUBREG): Add prototype.
+ * calls.c (precompute_arguments): Use it.
+ * expr.c (store_expr, expand_expr): Likewise.
+ * regmove.c (optimize_reg_copy_3): Likewise.
+ * reload1.c (emit_reload_insns): Likewise.
+ * stmt.c (expand_anon_union_decl): Likewise.
+
+ * rtl.texi: Remove all traces of SUBREG_WORD.
+ * reload.c (push_reload): Fix test for the new SUBREG_BYTE semantics.
+ * config/sparc/sparc.md (zero_extendhidi2, extendqidi2, extendhidi2):
+ Compute SUBREG_BYTE offset based on DImode, not SImode.
+
+ * function.c (assign_params): Mark arguments SUBREG_PROMOTED_VAR_P
+ if they are actually promoted by the caller and
+ PROMOTE_FOR_CALLS_ONLY is true. Otherwise combiner will not know
+ that their bits are already guaranteed to be zero or sign copies.
+
+ * emit-rtl.c (constant_subword): Don't abort if
+ float bitsize is larger than 64 bits on 64bit host.
+
+ * config/sparc/sparc.h (REG_SIZE): For SUBREG check float mode on
+ SUBREG_REG's mode.
+ * combine.c (simplify_rtx): For two nested SUBREGs if the mode of
+ the inner SUBREG is larger than both other modes we cannot simply
+ add both SUBREG_BYTEs on big endian.
+ (make_extraction): If BYTES_BIG_ENDIAN take the last few bytes
+ of the register, not first.
+ * calls.c (expand_call): For non-paradoxical SUBREG take endianess
+ into account.
+
+ * config/alpha/alpha.c (print_operand_address): Fix typo.
+ * config/mips/mips.c (mips_move_1word, mips_move_2words,
+ mips_secondary_reload_class): SUBREG_REGNO_OFFSET macro
+ requires four arguments.
+ * config/pyr/pyr.c (consecutive_operands): Likewise.
+ * config/sh/sh.c (regs_used, machine_dependent_reorg): Likewise.
+
+ * java/javaop.h: Default int32 to int, not long. Fix comment.
+ * emit-rtl.c (subreg_hard_regno): Till we remove the extensive
+ checks in subreg_hard_regno, propagate info on whether
+ HARD_REGNO_MODE_OK is allowed to fail.
+ * combine.c (simplify_rtx): Don't abort if SUBREG has
+ incompatible modes outside and inside.
+ * caller-save.c (mark_set_regs): Change callers of subreg_hard_regno
+ to pass new argument.
+ * final.c (alter_subreg): Likewise.
+ * local-alloc.c (reg_is_born): Likewise.
+ * rtl.h (subreg_hard_regno): Update prototype.
+
+ * config/alpha/alpha.c (print_operand_address): Use SUBREG_BYTE
+ instead of SUBREG_WORD.
+ * config/ns32k/ns32k.md (udivmoddihi4): Fix explicit subregs in
+ rtl to use byte offsets.
+ * config/sh/sh.h (INDEX_REGISTER_RTX_P): Use SUBREG_BYTE, not
+ SUBREG_WORD.
+ * config/sparc/sparc.h (REG_SIZE): Handle SUBREG arguments.
+ * emit-rtl.c (subreg_realpart_p): Changed to use SUBREG_BYTE.
+ * integrate.c (copy_rtx_and_substitute): Use byte SUBREG offsets
+ in CONCAT handling.
+ * reload.c (find_reloads_subreg_address): Use SUBREG_BYTE. Remove
+ byte endian corrections when fixing up MEM subregs.
+ * resource.c (update_live_status): Use SUBREG_REGNO.
+
+1998-10-03 David S. Miller <davem@pierdol.cobaltmicro.com>
+
+ Use byte offsets in SUBREGs instead of words.
+ * rtl.h (SUBREG_WORD): Rename to SUBREG_BYTE.
+ (SUBREG_REGNO_OFFSET, SUBREG_REGNO): New macros.
+ (subreg_hard_regno, constant_subword, gen_rtx_SUBREG): New
+ functions.
+ * gengenrtl.c (special_rtx): Add SUBREG.
+ * regs.h (REG_SIZE): Allow target to override.
+ (REGMODE_NATURAL_SIZE): New macro which target can override.
+ * tm.texi (ALTER_HARD_SUBREG): Remove, it is now dead.
+ * rtl.texi (subreg): Update to reflect new byte offset
+ representation. Add mentioning of the effect that
+ BYTES_BIG_ENDIAN has on subregs now.
+ * final.c (alter_subreg) [REG]: Remove ALTER_HARD_SUBREG
+ commentary and usage. Use subreg_hard_regno instead.
+ [MEM]: Remove endianness corrections and use SUBREG_BYTE.
+ Check for bogus SUBREG_BYTE values.
+ * emit-rtl.c (gen_rtx_SUBREG): New function, used to verify
+ certain invariants about SUBREGs the compiler creates.
+ (subreg_hard_regno): New function.
+ (gen_lowpart_common): Adjust offset for BYTES_BIG_ENDIAN too.
+ [SUBREG]: When combining two subregs, make sure final offset is a
+ multiple of the SUBREG's mode.
+ [REG]: Remove sparc64 hard regno wordaround. Simplify rest of the
+ code and use SUBREG_REGNO_OFFSET.
+ [CONST_INT, CONST_DOUBLE]: Call constant_subword.
+ (subreg_realpart_p): Use SUBREG_BYTE.
+ (gen_lowpart): Pretty.
+ (gen_highpart) [MEM]: Pretty.
+ [SUBREG]: Use SUBREG_BYTE.
+ [REG]: Remove sparc64 hard regno hacks. Adjust offset for
+ BYTES_BIG_ENDIAN too. Use SUBREG_REGNO_OFFSET for hard regs.
+ (subreg_lowpart_p): Always compute endian corrected goal offset,
+ even at the byte level, then compare against that.
+ (constant_subword): New function, pulled out all constant cases
+ from operand_subword and changed second argument name to offset.
+ (operand_subword): Detect non REG/SUBREG/CONCAT/MEM cases early
+ and call constant_subword to do the work.
+ [REG]: Use SUBREG_REGNO_OFFSET for hard regnos.
+ [SUBREG]: When combining two subregs, make sure final offset is a
+ multiple of the SUBREG's mode.
+ (operand_subword_force): Change second arg name to offset. Abort
+ early if reload is done and this is called.
+ * cse.c (mention_regs): Use SUBREG_BYTE.
+ (remove_invalid_subreg_refs): Second arg now named offset and is a
+ byte offset as per SUBREG_BYTE. Rework to use byte ranges and
+ comparison checks.
+ (canon_hash): Use SUBREG_BYTE.
+ (fold_rtx): Pass SUBREG_BYTE div UNITS_PER_WORD to
+ operand_subword.
+ (gen_lowpart_if_possible): Pretty.
+ (cse_insn): Fix conditional formatting.
+ * dbxout.c (dbxout_symbol_location): Compute SUBREG hard regnos
+ correctly.
+ * expmed.c (store_big_field): Use SUBREG_BYTE.
+ (extract_bit_field): Likewise.
+ (extract_split_bit_field): Likewise.
+ (expand_shift): Likewise.
+ * flow.c (life_analysis_1): Likewise.
+ * global.c (mark_reg_store): Remove word local and commented out
+ code which used it.
+ (mark_reg_clobber): Likewise.
+ (set_preference): Rework to use SUBREG_REGNO_OFFSET,
+ REGMODE_NATURAL_SIZE and SUBREG_BYTE where appropriate.
+ * combine.c (try_combine): Replace explicit XEXP with SUBREG_REG.
+ (simplify_rtx): Do not fixup byte endianness of subregs, the
+ SUBREG_BYTE contains the correct offset. When substituting two
+ subregs into each other still compare against word equality for
+ the fast case, but otherwise make the final offset congruent to
+ the mode of the subreg. Also use subreg_hard_regno to compute the
+ hard regno of a subreg. Rework the rest to use SUBREG_BYTE. This
+ function is too large.
+ (simplify_set): Rework to use SUBREG_BYTE, also fixup another
+ explicit XEXP into a SUBREG_REG.
+ (expand_field_assignment): Use SUBREG_BYTE.
+ (make_extraction): Likewise.
+ (apply_distributive_law): Likewise and fixup subreg comments.
+ (gen_lowpart_for_combine): Compute full byte offset.
+ * dwarf2out.c (is_pseudo_reg): Fixup explicit XEXP into SUBREG_REG
+ (mem_loc_descriptor): Likewise.
+ (loc_descriptor): Likewise.
+ * dwarfout.c (is_pseudo_reg): Fixup explicit XEXP into SUBREG_REG
+ (output_mem_loc_descriptor): Likewise.
+ (output_loc_descriptor): Likewise. This and the previous file
+ have a lot of common duplicated code.
+ * caller-save.c (set_reg_live): Use subreg_hard_regno and tweak.
+ * jump.c (rtx_renumbered_equal_p): Use new subreg byte offsets,
+ and SUBREG_REGNO_OFFSET where appropriate. Also fix bug where
+ reg_y was not subreg correctified for the subreg case.
+ (true_regnum): Use SUBREG_REGNO_OFFSET.
+ * function.c (fixup_var_refs_1): Fixup explicit XEXP into
+ a SUBREG_REG.
+ (fixup_memory_subreg): Use SUBREG_BYTE and remove byte endian
+ correction code.
+ (optimize_bit_field): Use SUBREG_BYTE.
+ * haifa-sched.c (print_value): Likewise.
+ * integrate.c (copy_rtx_and_substitute): Likewise and make sure
+ final byte offset is congruent to subreg's mode size.
+ (subst_constants): Use SUBREG_BYTE.
+ (mark_stores): Use SUBREG_REGNO_OFFSET for hard regs.
+ * local-alloc.c (combine_regs): Rework to use SUBREG_REGNO_OFFSET,
+ SUBREG_BYTE and REGMODE_NATURAL_SIZE.
+ (reg_is_born): Use subreg_hard_regno.
+ * recog.c (valid_replace_rtx_1): Use SUBREG_BYTE and remove byte
+ endian correction code.
+ (indirect_operand): Likewise.
+ (general_operand): Remove dead mode_altering_drug code.
+ (constrain_operands): Use SUBREG_REGNO_OFFSET.
+ * reg-stack.c (mark_regs_pat): Use SUBREG_REGNO. Abort if we see
+ a pseudo reg here.
+ (get_true_reg): Use SUBREG_REGNO_OFFSET.
+ * regmove.c (regmove_optimize): Use SUBREG_BYTE.
+ * reload.c (push_reload): Use SUBREG_BYTE in comments and code.
+ Also use SUBREG_REGNO_OFFSET and SUBREG_REGNO where appropriate.
+ (find_dummy_reload): Use SUBREG_REGNO_OFFSET. Only adjust offsets
+ for hard registers inside subregs.
+ (operands_match_p): Likewise.
+ (find_reloads): Only advance offset for subregs containing hard
+ regs. Remove "can work with subregging" final condition when
+ setting force_reload, it no longer makes sense with byte
+ offsettable subregs. Fix another XEXP into a SUBREG_REG.
+ (find_reload_toplev): Use SUBREG_BYTE. Remove byte endian
+ corrections when fixing up MEM subregs.
+ (find_reloads_addres_1): Use SUBREG_BYTE, SUBREG_REGNO, and
+ SUBREG_REGNO_OFFSET where appropriate.
+ (subst_reloads): When combining two subregs, make sure final
+ offset is congruent to subreg's mode size.
+ (find_replacement): Likewise, also use SUBREG_BYTE and
+ SUBREG_REGNO_OFFSET where appropriate.
+ (refers_to_regno_for_reload_p): Use SUBREG_REGNO.
+ (reg_overlap_mentioned_for_reload_p): Use SUBREG_REGNO_OFFSET.
+ * reload1.c (eliminate_regs) [SUBREG]: Use SUBREG_BYTE, fixup
+ another explicit XEXP into a SUBREG_REG. Remove byte endian
+ correction code for memory subreg fixups.
+ (forget_old_reload_1): Use SUBREG_REGNO_OFFSET.
+ (choose_reload_regs): Use SUBREG_REGNO.
+ (emit_reload_insns): Use SUBREG_BYTE.
+ (reload_combine_note_store): Use SUBREG_REGNO_OFFSET.
+ (move2add_note_store): Use SUBREG_REGNO_OFFSET.
+ * reorg.c (mark_referenced_resources): Use SUBREG_REGNO.
+ * rtlanal.c (refers_to_regno_p): Use SUBREG_REGNO.
+ (reg_overlap_mentioned_p): Likewise.
+ (replace_regs); Make sure final offset of combined subreg is
+ congruent to size of subreg's mode.
+ * sdbout.c (sdbout_symbol): Compute offset using alter_subreg.
+
+ Target changes for new subregging representation.
+ * config/a29k/a29k.c (gpc_reg_operand): Use SUBREG_REGNO.
+ (a29k_get_reloaded_address): Use SUBREG_BYTE.
+ (print_operand): Use SUBREG_BYTE.
+ * config/alpha/alpha.c (get_aligned_mem): Use SUBREG_BYTE and
+ remove byte endianness corrections.
+ (get_unaligned_address): Likewise.
+ * config/dsp16xx/dsp16xx.md (extendqihi2, zero_extendqihi2): Fix
+ SUBREG creation to use byte offset.
+ * config/h8300/h8300.md (Unnamed HImode zero extraction and 16bit
+ inverted load insns): Fix explicit rtl subregs to use byte
+ offsets.
+ * config/i370/i370.md (cmpstrsi, movstrsi, mulsi3, divsi3,
+ udivsi3, umodsi3): Generate SUBREGs with byte offsets.
+ * config/i386/i386.md (HImode zero extend split): Use
+ SUBREG_BYTE.
+ * config/i860/i860.c (single_insn_src_p): Use SUBREG_BYTE.
+ * config/i860/i860.md (mulsi3_big): Fixup explicit SUBREGs in rtl
+ to use byte offsets.
+ (unnamed fmlow.dd insn): Likewise.
+ * config/i960/i960.md (extendhisi2): Generate SUBREGs with byte
+ offsets, also make sure it is congruent to SUBREG's mode size.
+ (extendqisi2, extendqihi2, zero_extendhisi2, zero_extendqisi2,
+ unnamed ldob insn): Likewise.
+ * config/m32r/m32r.md (extendqihi2, extendqisi2, extendhisi2):
+ Likewise.
+ * config/m68k/m68k.md (zero_extendhisi2, zero_extendqihi2,
+ zero-extendqisi2): Likewise.
+ (umulsidi3, mulsidi3, subreghi1ashrdi_const32,
+ subregsi1ashrdi_const32, subreg1lshrdi_const32): Fixup explicit
+ surbegs in rtl to use byte offsets.
+ * config/m88k/m88k.md (extendsidi2): Likewise.
+ * config/mips/mips.c (mips_move_1word): Use SUBREG_REGNO_OFFSET.
+ (mips_move_2words, mips_secondary_reload_class): Likewise.
+ * config/mips/mips.md (DImode plus, minus, move, and logical op
+ splits): Fixup explicit subregs in rtl to use byte offsets.
+ * config/mn10200/mn10200.c (print_operand) [SUBREG]: Use
+ SUBREG_REGNO and fix a reg_names indice bug.
+ * config/mn10300/mn10300.c (print_operand) [SUBREG]: Likewise.
+ * config/ns32k/ns32k.md (udivmoddisi4): Fix explicit subregs in
+ rtl to use byte offsets.
+ * config/pa/pa.md (floatunssisf2, floatunssidf2): Likewise.
+ (mulsi3): Make subregs with byte offsets.
+ * config/pdp11/pdp11.md (zero_extendhisi2, modhi3, modhi3+1):
+ Fixup explicit subregs in rtl to use byte offsets.
+ * config/pyr/pyr.c (subreg_overlap_mentioned_p): Use SUBREG_REGNO.
+ (consecutive_operands): Use SUBREG_REGNO_OFFSET.
+ * config/pyr/pyr.md (extendsidi2): Fixup explicit subregs in rtl
+ to use byte offsets.
+ * config/romp/romp.c (memory_offset_in_range_p): Use SUBREG_BYTE
+ and remove byte endian correction code.
+ * config/rs6000/rs6000.md (DImode const splits): Generate SUBREGs
+ with byte offsets.
+ * config/sh/sh.c (output_movedouble): Use SUBREG_REGNO.
+ (gen_ashift_hi): Use SUBREG_BYTE.
+ (regs_used): Use SUBREG_REGNO_OFFSET.
+ (machine_dependent_reorg): Likewise.
+ * config/sh/sh.md (DImode and DFmode move splits): Use
+ SUBREG_REGNO.
+ * config/sparc/sparc.md (TFmode move splits): Generate SUBREGs
+ with byte offsets.
+ (zero_extendhisi2, zero_extendqidi2_insn, extendhisi2,
+ extendqihi2, sign_extendqihi2_insn, sign_extendqisi2_insn,
+ extendqidi2): Generate SUBREGs with byte offsets, also make sure
+ it is congruent to SUBREG's mode size.
+ (smulsi3_highpart_v8plus): Fix explicit subregs in rtl to use byte
+ offsets.
+ * config/sparc/sparc.c (ultra_find_type): Use SUBREG_BYTE.
+ * config/sparc/sparc.h (ALTER_HARD_SUBREG): Die forever...
+ (REG_SIZE, REGMODE_NATURAL_SIZE): Override.
+ * config/spur/spur.md (movqi, zero_extendhisi2, extendhisi2,
+ extendqihi2, extendqisi2): Generate SUBREGs with byte offsets.
+ * config/v850/v850.c (print_operand): Use SUBREG_REGNO.
+ (v850_reorg): Use SUBREG_REGNO_OFFSET.
+
+
Sun Sep 24 09:15:48 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (store_field): If BITSIZE is negative, use size of type.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index f8ff5c2e099..daecac85716 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -7363,7 +7363,7 @@ loc_descriptor (rtl)
up an entire register. For now, just assume that it is
legitimate to make the Dwarf info refer to the whole register which
contains the given subreg. */
- rtl = XEXP (rtl, 0);
+ rtl = SUBREG_REG (rtl);
/* Fall through. */
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index ff7ca9639f0..8e81f304958 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -830,7 +830,7 @@ gen_lowpart_common (mode, x)
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
{
int final_regno = REGNO (x) +
- SUBREG_REGNO_OFFSET(REGNO (x), GET_MODE (x), offset, mode);
+ SUBREG_REGNO_OFFSET (REGNO (x), GET_MODE (x), offset, mode);
/* If the final regno is not valid for MODE, punt. */
/* ??? We do allow it if the current REG is not valid for
@@ -1127,7 +1127,7 @@ gen_imagpart (mode, x)
return XEXP (x, 1);
else if (WORDS_BIG_ENDIAN)
return gen_lowpart (mode, x);
- else if (!WORDS_BIG_ENDIAN
+ else if (! WORDS_BIG_ENDIAN
&& GET_MODE_BITSIZE (mode) < BITS_PER_WORD
&& REG_P (x)
&& REGNO (x) < FIRST_PSEUDO_REGISTER)
@@ -1266,7 +1266,7 @@ gen_highpart (mode, x)
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
{
int final_regno = REGNO (x) +
- SUBREG_REGNO_OFFSET(REGNO (x), GET_MODE (x), offset, mode);
+ SUBREG_REGNO_OFFSET (REGNO (x), GET_MODE (x), offset, mode);
/* integrate.c can't handle parts of a return value register.
??? Then integrate.c should be fixed!
@@ -1377,7 +1377,7 @@ constant_subword (op, offset, mode)
else if (BITS_PER_WORD == 16)
{
val = k[offset >> 1];
- if ((offset & 1) == !WORDS_BIG_ENDIAN)
+ if ((offset & 1) == ! WORDS_BIG_ENDIAN)
val >>= 16;
val &= 0xffff;
return GEN_INT (val);
@@ -1405,9 +1405,9 @@ constant_subword (op, offset, mode)
#if HOST_BITS_PER_WIDE_INT >= 64
else if (BITS_PER_WORD >= 64 && offset <= 1)
{
- val = k[offset*2 + ! WORDS_BIG_ENDIAN];
+ val = k[offset * 2 + ! WORDS_BIG_ENDIAN];
val = (((val & 0xffffffff) ^ 0x80000000) - 0x80000000) << 32;
- val |= (HOST_WIDE_INT) k[offset*2 + WORDS_BIG_ENDIAN] & 0xffffffff;
+ val |= (HOST_WIDE_INT) k[offset * 2 + WORDS_BIG_ENDIAN] & 0xffffffff;
return GEN_INT (val);
}
#endif
@@ -1456,7 +1456,7 @@ constant_subword (op, offset, mode)
if (BITS_PER_WORD == 16)
{
- if ((offset & 1) == !WORDS_BIG_ENDIAN)
+ if ((offset & 1) == ! WORDS_BIG_ENDIAN)
val >>= 16;
val &= 0xffff;
}
@@ -1602,7 +1602,7 @@ operand_subword (op, offset, validate_address, mode)
if (REGNO (op) < FIRST_PSEUDO_REGISTER)
{
int final_regno = REGNO (op) +
- SUBREG_REGNO_OFFSET(REGNO (op), GET_MODE (op),
+ SUBREG_REGNO_OFFSET (REGNO (op), GET_MODE (op),
offset * UNITS_PER_WORD,
word_mode);
diff --git a/gcc/function.c b/gcc/function.c
index 29bdecb7ebf..41cc3d175a7 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -3409,10 +3409,22 @@ purge_single_hard_subreg_set (pattern)
{
rtx reg = SET_DEST (pattern);
enum machine_mode mode = GET_MODE (SET_DEST (pattern));
+ int offset = 0;
+
+ if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG
+ && REGNO (SUBREG_REG (reg)) < FIRST_PSEUDO_REGISTER)
+ {
+ offset = SUBREG_REGNO_OFFSET (REGNO (SUBREG_REG (reg)),
+ GET_MODE (SUBREG_REG (reg)),
+ SUBREG_BYTE (reg),
+ GET_MODE (reg));
+ reg = SUBREG_REG (reg);
+ }
+
- if (GET_CODE (reg) == SUBREG && REGNO (reg) < FIRST_PSEUDO_REGISTER)
+ if (REGNO (reg) < FIRST_PSEUDO_REGISTER)
{
- reg = gen_rtx_REG (mode, SUBREG_REGNO (reg));
+ reg = gen_rtx_REG (mode, REGNO (reg) + offset);
SET_DEST (pattern) = reg;
}
}
diff --git a/gcc/reload.c b/gcc/reload.c
index e764e624361..185c1c52fe7 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1051,6 +1051,7 @@ push_reload (in, out, inloc, outloc, class,
(except in the case of STRICT_LOW_PART,
and in that case the constraint should label it input-output.) */
if (out != 0 && GET_CODE (out) == SUBREG
+ && (SUBREG_BYTE (out) == 0 || strict_low)
#ifdef CLASS_CANNOT_CHANGE_MODE
&& (class != CLASS_CANNOT_CHANGE_MODE
|| ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),