diff options
author | Andrew Macleod <amacleod@cygnus.com> | 2000-10-03 01:08:36 +0000 |
---|---|---|
committer | Andrew Macleod <amacleod@cygnus.com> | 2000-10-03 01:08:36 +0000 |
commit | a77d4ff39d774b173499b723cbdec840ac402a53 (patch) | |
tree | 736b2b011e21b034c365a317adea38954b96686e | |
parent | 37a5c652a3a5d099a96bf298df3b31e4a3ad034c (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/ChangeLog | 326 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 2 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 16 | ||||
-rw-r--r-- | gcc/function.c | 16 | ||||
-rw-r--r-- | gcc/reload.c | 1 |
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)), |