Introduce H8SX support.

* expr.c (expand_strcpy): Renamed and moved to...
* builtins.c (expand_movstr): ... here.  Tweak.
(expand_builtin_strcpy): Adjust.  Use movstr if len can't be
computed or has side effects.
(expand_builtin_stpcpy): Likewise.  Use strcpy if return value is
unused, or if mempcpy fails.  Adjust the return value in the
latter case.  Use movstr if everything else fails.
* doc/md.texi (movstr): Document.
(movmemM, clrmemM): Fix explanation of memory block operands.
* config/h8300/h8300.md (stpcpy): Renamed to...
(movstr): ... this.  Adjust.
2004-07-07  Alexandre Oliva  <aoliva@redhat.com>
* config/h8300/h8300.md: Rename movstr*, except for movstrict*, to
movmem* and clrstr* to clrmem*.
2004-06-27  Alexandre Oliva  <aoliva@redhat.com>
* config/h8300/h8300.c (h8300_reg_class_from_letter): Map 'D' to
GENERAL_REGS, always.
(h8300_swap_into_er6, h8300_swap_into_er6): Handle the case of
getting the stack pointer as addr.
* config/h8300/h8300.h (PREDICATE_CODES): Remove constant rtxes
from general_operand_dst.
* config/h8300/h8300.md (movmd_internal_normal): New, normal-mode
variant of...
(movmd_internal): ... this.  Add modes to operands.  Disparage `D'
instead of requiring it to match only before reload.
(stpcpy_internal_normal): New, normal-mode variant of...
(stpcpy_internal): ... this.  Add modes to operands.  Disparage
`D' instead of requiring it to match only before reload.
* config/h8300/h8300-protos.h (h8300_legitimate_address_p): Add
mode argument.
* config/h8300/h8300.h (GO_IF_LEGITIMATE_ADDRESS): Pass it to...
* config/h8300/h8300.c (h8300_legitimate_address_p): Pass it to
h8300_get_index.
* config/h8300/h8300.md (attr type): Add call.
(attr can_delay): If type is call, set it no.
(call, call_value): Set type to call.
2004-06-21  Alexandre Oliva  <aoliva@redhat.com>
* config/h8300/h8300.md (logicalhi3_sn, logicalsi3_sn): New.
2004-06-16  Alexandre Oliva  <aoliva@redhat.com>
* tree.c (get_narrower): Don't narrow integral types into
non-integral types.
* config/h8300/h8300.c (h8300_expand_epilogue): Initialize
frame_size *before* the first use.
* config/h8300/h8300.md (movstrictqi): Reintroduce post-increment
on input.
(peephole2): Don't widen instructions that push SP.  Move
decrement of SP to the end of all stm-generating peepholes.
2003-07-24  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.md (insv): Prefer to use AND to clear a bitfield
and OR to set it to all ones.
2003-07-24  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.md (can_delay): Default to "no" for bit branches.
(call, call_value): Set can_delay to "no".
2003-07-22  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.md (extzv): Make subreg check more robust.
2003-07-21  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.md (*brabit): Remove.
* config/h8300/h8300.md (*brabc, *brabs): Remove mode from
zero_extract.  Use bit_memory_operand as the predicate for
operand 1 and 'WU' as the constraint.  Check the difference
between the base length and the final one when deciding which
type of branch to use.
2003-07-21  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.md (extzv): Remove mode from operands 0 and 1.
Use convert_move to extend the result for TARGET_H8300SX.  Check
for QImode memory references.  Optimize the case where the
destination is a paradoxical subreg.
2003-07-21  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.md (*movsf_h8sx): Add an r <- G alternative.
* config/h8300/h8300.md (andqi): Remove bclr from h8sx version.
2003-07-21  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.md: Include mova.md
(length_table): Add mova and mova_zero.
* config/h8300/h8300.c (print_operand): Handle '%o'.  Print a length
after all constant addresses for '%R', '%X', '%T' and '%S'.
(h8300_mova_length): New function.
(h8300_insn_length_from_table): Use it to handle mova and mova_zero.
* config/h8300/t-h8300 (mova.md): Generate from genmova.sh.  Add to
dependencies for s-config, etc.
* config/h8300/gemova.sh: New file.
* config/h8300/mova.md: Generated.
2003-07-20  Alexandre Oliva  <aoliva@redhat.com>
* config/h8300/h8300.c (h8300_bitfield_length): New.
(nibble_operand): Adjust.
(h8300_binary_length): Handle conditional binary op.
(h8300_insn_length_from_table): Handle bitfield and bitbranch.
* config/h8300/h8300.h: Change constraints W# and Y# to P#>X and
P#<X, respectively.  The original P is now IP4>X.  Introduced P#>0
and P#<0, unused so far.  W and Y are now prefixes to multi-letter
constraints.  WU is introduced as a variant of U that requires a
mem, and is therefore considered an EXTRA_MEMORY_CONSTRAINT.
* config/h8300/h8300.md (attr type): Added bitbranch.
(attr length_table): Added bitfield and bitbranch.
(attr length): Compute bitbranch length.
(andqi): Separate pattern for H8300SX.  Use bfld for loading the
least-significant bit of a byte.
(brabit, brabc, brabs): New.
(insv, extzv): Emit bfst and bfld on H8300SX.
(bfld, bfst, seq, sne): New.
(bstzhireg, cmpstz, bstz, bistz): New.
(cmpcondbset, condbset, cmpcondbclr, condbclr): New.
(cmpcondbsetreg, condbsetreg, cmpcondbclrreg, condbclrreg): New.
2003-07-11  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.c (h8sx_binary_memory_operator): New function.
(h8sx_unary_memory_operator): New function.
* config/h8300/h8300.h (EXTRA_MEMORY_CONSTRAINT): Disable.
(PREDICATE_CODES): Add h8sx_{unary,binary}_memory_operator.
* config/h8300/h8300.md: Add peepholes to combine reloads and
arithmetic insns.
2003-07-10  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h830.md (cmpqi): Use 'i' rather than 'n' in constraints.
(*cmphi_h8300hs, *addqi3, *addhi3_h8sx, subhi3): Likewise.
(and?i, ior?i, xor?i): Likewise.
2003-07-10  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.c: Move enums and prototypes to head of file.
Various whitespace fixes.
(h8300_constant_length): New function, split out from...
(h8300_displacement_size): ...here.  Rename h8300_displacement_length.
(h8300_classify_operand): Use IN_RANGE.
(h8300_classify_operand): Use h8300_constant_length.
(h8300_short_move_mem_p): Tighten size check.
(h8sx_mergeable_memrefs_p): Tighten equality check.
2003-06-30  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.h (TARGET_CPU_CPP_BUILTINS): Define __H8300SX__
for -msx.
* config/h8300/crti.asm: Use .h8300sx or .h8300sxn for -msx code.
* config/h8300/crtn.asm: Likewise.
* config/h8300/lib1funcs.asm: Likewise.  Use 32-bit pointers
if __H8300SX__ is defined.
2003-06-27  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300-protos.h (h8300_get_index): Add mode parameter.
* config/h8300/h8300.h (GO_IF_LEGITIMATE_ADDRESS): Update accordingly.
(GO_IF_MODE_DEPENDENT_ADDRESS): Treat POST_DEC, PRE_INC and indexed
addresses as mode-dependent.
* config/h8300/h8300.c (print_operand_address): Update call to
h8300_get_index.
(h8300_get_index): Take a mode argument.  Rework to fix an
earlier misunderstanding.
2003-06-26  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.c (zero_extendqisi2): Force the source operand
into a register if TARGET_H8300SX.
(*zero_extendqisi2_h8300hs, *extendqisi2_h8300): Disable for
TARGET_H8300SX.  Also disable related define_splits.
(*zero_extendqisi2_h8sx, *extendqisi2_h8sx): New patterns.
2003-06-23  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.c (h8300_rtx_costs): Add h8sx handling.
2003-06-20  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.h (OK_FOR_Z): New macro.
(EXTRA_CONSTRAINT_STR): Check it.
* config/h8300/h8300.c (h8300_classify_operand): Accept null
class arguments.
(h8300_insn_length_from_table): Handle LENGTH_TABLE_MOV_IMM4.
* config/h8300/h8300.md (length_table): Add mov_imm4.
(movqi, movhi): Add Z <- W4 alternatives to h8sx patterns.
2003-06-20  Richard Sandiford  <rsandifo@redhat.com>
* genattrtab.c (write_eligible_delay): Allow candidate_insn to
be a label.
* config/h8300/h8300.h (DELAY_SLOT_LENGTH): New macro.
* config/h8300/h8300.c (h8300_reorg): New function.
(TARGET_MACHINE_DEPENDENT_REORG): Define.
* config/h8300/h8300.md (length): Subtract the length of the
delay slot from (pc) when checking the range of forward branches.
(delay_slot, can_delay): New attributes.
(define_delay): Add bra/s handling.
(movmd_internal, return_h8sx, *return_1): Set can_delay to no.
(jump): Add delayed-branch handling.
2003-06-17  Richard Sandiford  <rsandifo@redhat.com>
* expr.c (expand_strcpy): New function.
* builtins.c (expand_builtin_strcpy): Fall back on expand_strcpy.
(expand_builtin_stpcpy): Likewise.
* config/h8300/h8300-protos.h (h8sx_split_movmd): Remove.
(h8300_swap_into_er6, h8300_swap_out_of_er6): Declare.
* config/h8300/h8300.c (h8300_reg_class_from_letter): Tweak 'd'
handling to improve register allocation for -fno-omit-frame-pointer.
(h8sx_split_movmd): Delete, moving er6 handling into...
(h8300_swap_into_er6, h8300_swap_out_of_er6): ...these new functions.
* config/h8300/h8300.md (UNSPEC_STPCPY): New unspec constant.
(movmd): Add calls to copy_rtx.
(movmd_internal): In the second alternative, allow the initial and
final destination registers to be different .  Update the splitter
accordingly.  Call h8300_swap_into_er6 and h8300_swap_out_of_er6
instead of h8sx_split_movmd.
(stpcpy, movsd): New expanders.
(movsd_internal): New define_insn.
2003-06-13  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300-protos.h (h8300_reg_class_from_letter): Declare.
(h8sx_emit_movmd, h8sx_split_movmd): Declare.
* config/h8300/h8300.h (reg_class): Add COUNTER_REGS, SOURCE_REGS
and DESTINATION_REGS.
(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
(REGNO_REG_CLASS): Map er4, er5 and er6 to the new classes.
(REG_CLASS_FROM_LETTER): Use h8300_reg_class_from_letter.
(h8300_move_ratio): Declare.
(MOVE_RATIO): Use it.
* config/h8300/h8300.c (h8300_move_ratio): New variable.
(h8300_init_once): Initialize it.
(h8300_reg_class_from_letter): New function.
(print_operand): Add an 'm' prefix for printing ".b", ".w" or ".l".
(h8sx_emit_movmd, h8sx_split_movmd): New functions.
* config/h8300/h8300.md (UNSPEC_MOVMD): New unspec constant.
(COUNTER_REG, SOURCE_REG, DESTINATION_REG): New register constants.
(movstrsi, movmd): New expanders.
(movmd_internal): New insn.
2003-06-06  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.h (EXTRA_MEMORY_CONSTRAINT): Define.
2003-06-04  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/elf.h (LINK_SPEC): Use -m h8300sxnelf for -msx -mn.
* config/h8300/h8300.c (asm_file_start): Use .h8300sxn likewise.
2003-06-03  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.c (nibble_operand): Fix warning.
* config/h8300/h8300.md (movstricthi): Set adjust_length to no.
(movsi_h8sx): Likewise here and the normal h8sx movhi pattern.
(movsf_h8300h): Disable for TARGET_H8300SX.
2003-06-03  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.h (PREDICATE_CODES): Add h8300_ldm_parallel,
h8300_stm_parallel and h8300_return_parallel.
* config/h8300/h8300.c (h8300_push_pop, h8300_stack_offset_p,
h8300_ldm_stm_regno, h8300_ldm_stm_parallel, h8300_ldm_parallel,
h8300_stm_parallel, h8300_return_parallel): New functions.
(h8300_expand_prologue): Don't enforce ldm/stm register alignment
if TARGET_H8300SX.  Use h8300_push_pop.
(h8300_expand_epilogue): Likewise.  Try to merge the return insn
and final pop when generating h8sx code.  Always emit some form
of return insn.
* config/h8300/h8300.md: Don't enforce register alignment in
stm peepholes if TARGET_H8300SX.
(ldm_h8300s, stm_h8300s, return_h8sx): New patterns.
(ldm_h8300s_[234], stm_h8300_[234]): Disable.
(epilogue): Expect h8300_expand_epilogue to emit a return insn.
2003-06-03  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/t-h8300 (MULTILIB_OPTIONS): Add a -msx multilib.
(MULTILIB_DIRNAMES): Add a directory for it.
(MULTILIB_MATCHES): Delete.
2003-05-28  Richard Sandiford  <rsandifo@redhat.com>
* final.c (walk_alter_subreg): Handle addresses with subregs
inside a ZERO_EXTEND or AND.
* config/h8300/h8300-protos.h (h8300_get_index): Declare.
* config/h8300/h8300.h (INDEX_REG_CLASS): Set to GENERAL_REGS
if TARGET_H8300SX.
(GO_IF_LEGITIMATE_ADDRESS): Use h8300_get_index.
* config/h8300/h8300.c (print_operand_address): Handle @(dd,RnL.b),
@(dd,Rn.w) and @(dd,ERn.L).
(h8300_displacement_size): Take the whole address as argument.
(h8300_classify_operand, h8300_short_move_mem_p): Adjust accordingly.
2003-05-28  Richard Sandiford  <rsandifo@redhat.com>
* config/mips/mips-protos.h (h8300_operands_match_p): Declare.
(h8sx_mergeable_memrefs_p): Declare.
* config/h8300/h8300.h (HAVE_POST_DECREMENT): Define to TARGET_H8300SX.
(HAVE_PRE_INCREMENT): Likewise.
(GO_IF_LEGITIMATE_ADDRESS): Accept pre/post increment/decrement
addresses for TARGET_H8300SX,
* config/h8300/h8300.c (print_operand_address): Deal with PRE_INC
and POST_DEC.
(movb_length_table, movl_length_table): New tables.
(movw_length_table): Define to movb_length_table.
(h8300_displacement_size): New, split out from...
(h8300_classify_address): ...here.  Handle pre/post inc/dec.
(h8300_short_immediate_length): Allow H8OP_MEM_COMPLEX operands.
(h8300_insn_length_from_table): Add cases for movb, movw and movl.
(h8sx_mergeable_memrefs_p, h8300_operands_match_p): New functions.
(output_plussi): Use add.l #xx:3,Rn and sub.l #xx:3,Rn for h8sx.
(compute_plussi_length, compute_plussi_cc): Update accordingly.
(h8sx_unary_shift_operator): Get the mode from the operator.
(binary_shift_operator): Likewise.
* config/h8300/h8300.md: If a peephole2 applies gen_lowpart to
a memory reference, check whether the reference is offsettable.
(length_table): Add movb, movw and movl.
(movqi): Add new h8sx pattern.  Don't force one operand to be a
register when generating h8sx code.
(movhi, movsi, movsf): Likewise.
(movstrictqi): Use the length_table attribute.
(movstricthi): Likewise.  Add h8sx alternative for mov.w #xx:3,Rn.
(addqi3): Split into a define_expand and define_insn.  Don't accept
memory operands in the expander.  Use h8300_operands_match_p to
check for matching operands in the define_insn.
(subqi3, negqi2, one_cmplqi2): Likewise.
(add[hs]i3): Don't accept memory operands in the expander.  Likewise
in any patterns that are unused in h8sx code.  In the h8sx patterns,
use h8300_operands_match_p to check whether operands match.
(sub[hs]i3, and[hi]3, ior[hs]i3, xor[hs]i3, neg[hsi]3,
one_cmpl[hs]i3): Likewise.
(andqi3, iorqi3, xorqi3): Likewise.  Don't call fix_bit_operand
in the expander.
2003-05-23  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300-protos.h (expand_a_shift): Return a bool.
(h8300_insn_length_from_table): Add a second parameter.
(output_h8sx_shift): Declare.
* config/h8300/h8300.h (OK_FOR_W, OK_FOR_Y): New macros.
(EXTRA_CONSTRAINT): Replace with...
(EXTRA_CONSTRAINT_STR): ...this.  Use OK_FOR_W and OK_FOR_Y.
(CONSTRAINT_LEN): Define, returning 2 for 'W' and 'Y'.
(PREDICATE_CODES): Add entries for h8sx_unary_shift_operator
and h8sx_binary_shift_operator.
* config/h8300/h8300.c (two_insn_adds_subs_operand): Return false
for TARGET_H8300SX.
(bit_operand): Replace use of EXTRA_CONSTRAINT with OK_FOR_U.
(bit_memory_operand, fix_bit_operand): Likewise.
(h8300_length_table_for_insn): Remove.
(h8300_classify_operand): Fix check for 16-bit operands in 32-bit
instructions.
(h8300_short_immediate_length, h8300_binary_length): New functions.
(h8300_insn_length_from_table): Add an opcodes parameter.  Rework.
(output_plussi): Use sub to add negative constants.
(compute_plussi_length): Adjust accordingly.
(h8sx_single_shift_type): New enum.
(h8sx_single_shift, h8sx_unary_shift_operator,
h8sx_binary_shift_operator, output_h8sx_shift): New functions.
(expand_a_shift, expand_a_rotate): Emit nothing if the shift is a
single h8sx instruction.  Return false in this case.
* config/h8300/h8300.md (length_table): Add short_immediate.
(length): Pass the operand array to h8300_insn_length_from_table.
(adjust_length): Assume "no" for insns with a length_table attribute.
(*cmphi_h8300hs, cmpsi): Add alternatives for #xx:3.
(*addhi3_h8300hs): Don't use for h8sx.
(*addhi3_h8sx): New pattern, with alternatives for add.w #xx:3
and sub.w #xx:3.
(ashl[qhs]i3, lshr[qhs]i3, ashr[qhs]i3, rotl[qhs]i3): Change operand
1's predicate to nonimmediate_operand.  Only skip default expansion
if expand_a_shift or expand_a_rotate returns true.  Add new patterns
for single h8sx shift instructions.
2003-05-22  Alexandre Oliva  <aoliva@redhat.com>
* config/h8300/h8300.c (nibble_operand): Split out of...
(reg_or_nibble_operand): ... this.
* config/h8300/h8300.h (PREDICATE_CODES): Added nibble_operand.
* config/h8300/h8300.md: (mulqihi3, mulhisi3, umulqihi3,
umulhisi3): Introduce expand, and introduce separate insns for
sign- or zero-extended REG and already-extended CONST_INT.
2003-05-20  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.c (h8300_unary_length): Fix miscounting.
* config/h8300/h8300.md (subqi3): Generalize for h8sx.
(subhi3): Likewise.  Don't accept immediates for operand 1.
Remove the early clobber from second alternative of the h8300s pattern.
(subsi3): Generalize for h8sx.  Force operand 2 into a register
on plain h8300 targets.
(subsi3_h8300): Use h8300_dst_operand for consistency with expander.
(subsi3_h8300h): Generalize for h8sx.
(one_cmplqi2, one_cmplhi2, one_cmplsi2): Likewise.
2003-05-19  Alexandre Oliva  <aoliva@redhat.com>
* config/h8300/h8300.c (reg_or_nibble_operand): New.
* config/h8300/h8300.h (PREDICATE_CODES): Adjust.
(TARGET_H8300SXMUL): New.
(CONST_OK_FOR_P): New.
(CONST_OK_FOR_LETTER_P): Adjust.
* config/h8300/h8300.md (mulqihi3, mulhisi3, umulqihi3,
umulhisi3): Accept 4-bit immediate on H8SX.
(mulhi3, mulsi3, smulsi3_highpart, umulsi3_highpart): New.
(udivsi3, divhi3, udivsi3, divsi3): New.
2003-05-19  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300-protos.h (h8300_insn_length_from_table): Declare.
* config/h8300/h8300.h (OK_FOR_Q): New macro.
(EXTRA_CONSTRAINT): Use it to check the 'Q' constraint.
(PREDICATE_CODES): Add h8300_src_operand and h8300_dst_operand.
Add ADDRESSOF to the bit_operand entry.
* config/h8300/h8300.c (h8300_dst_operand): New predicate.
(h8300_src_operand): Likewise.
(bit_operand): Check nonimmediate_operand rather than general_operand.
Accept any nonimmediate_operand in h8sx code.
(h8300_and_costs): Initialize operands[1].
(h8300_rtx_costs) <AND>: Return false if the operands aren't valid.
(h8300_operand_class): New enum.
(h8300_length_table): New typedef.
(addb_length_table, addw_length_table, addl_length_table,
logicl_length_table): New tables.
(logicb_length_table, logicw_length_table): New macros.
(h8300_classify_operand, h8300_length_from_table,
h8300_length_table_for_insn, h8300_unary_length,
h8300_insn_length_from_table): New functions.
(output_plussi): Only use adds and subs for register destinations.
Disable redundant clause.
(compute_plussi_cc): Likewise.
(compute_plussi_length): Likewise.  Use h8300_length_from_table
to work out the length of an insn.
(output_logical_op): Only use narrower immediate instructions
if the destination is a register.
(compute_logical_op_cc): Likewise.
(compute_logical_op_length): Likewise.  Use h8300_length_from_table.
(h8300_adjust_insn_length): Tighten check for reg<->mem moves.
* config/h8300/h8300.md (length_table): New attribute.
(length): When an instruction has a length_table attribute, use
h8300_insn_length_from_table to calculate its default length.
(cmpqi): Use h8300_dst_operand for the first operand and
h8300_src_operand for the second.
(cmphi, *cmphi_h8300hs, cmpsi, negqi2, neghi2, neghi2_h8300h, negsi2,
negsi2_h8300h, addqi3, addhi3, *addhi3_h8300, *addhi3_h8300hs, addsi3,
addsi_h8300, addsi_h8300h, andhi3, andsi3, iorhi3,
iorsi3, xorhi3, xorsi3): Likewise.
(andqi3): Use h8300_src_operand for operand 2.  Adjust the condition
so that it allows any combination of operands for TARGET_H8300SX.
(iorqi3, xorqi3): Likewise.
(cmpqi): Use the length_table attribute.
(*cmphi_h8300hs, cmpsi, addqi, *addhi3_h8300hs, andqi3, iorqi3,
xorqi3, negqi2, neghi2_h8300h, negsi2_h8300h): Likewise.
(cmpqi): Add 'Q' constraint.
(*cmphi_h8300hs, cmpsi, addqi, *addhi3_h8300hs, addsi_h8300h, andqi3,
iorqi3, xorqi3, negqi2, neghi2_h8300h, negsi2_h8300h): Likewise.
2003-05-14  Richard Sandiford  <rsandifo@redhat.com>
* config/h8300/h8300.h (MASK_H8300SX): New macro.
(TARGET_H8300S): True for both -ms and -msx.
(TARGET_H8300SX): New macro.
(TARGET_SWITCHES): Add entries for -msx and -mno-sx.
* config/h8300/h8300.c (asm_file_start): Write .h8300sx for -msx.
* config/h8300/elf.h (LINK_SPEC): Use -m h8300sxelf for -msx.
* config/h8300/t-h8300 (MULTILIB_MATCHES): Use -ms multilibs for -msx.
[Temporary change.]
2003-02-28  Alexandre Oliva  <aoliva@redhat.com>
* config/h8300/h8300.h (SIZE_TYPE, PTRDIFF_TYPE): Use short with
16-bit pointers and 32-bit ints.
* config/h8300/h8300.h (LEGITIMATE_CONSTANT_P): Accept
CONST_DOUBLE with mode no wider than SImode.
* config/h8300/h8300.md (extendqisi2_h8300): Add constraints for
output operand.
2003-02-27  Alexandre Oliva  <aoliva@redhat.com>
* config/h8300/h8300.c (general_operand_src): Match CONSTANT_P_RTX
or SUBREG thereof.
* config/h8300/h8300.h (PREDICATE_CODES): Adjust.
2003-02-22  Alexandre Oliva  <aoliva@redhat.com>
* config/h8300/h8300.c (dosize): Truncate sign * size to Pmode.

From-SVN: r84257
This commit is contained in:
Alexandre Oliva 2004-07-08 03:40:34 +00:00 committed by Alexandre Oliva
parent 5c121a1b68
commit beed8fc0bb
17 changed files with 4844 additions and 666 deletions

View File

@ -1,3 +1,424 @@
2004-07-08 Alexandre Oliva <aoliva@redhat.com>
Introduce H8SX support.
* expr.c (expand_strcpy): Renamed and moved to...
* builtins.c (expand_movstr): ... here. Tweak.
(expand_builtin_strcpy): Adjust. Use movstr if len can't be
computed or has side effects.
(expand_builtin_stpcpy): Likewise. Use strcpy if return value is
unused, or if mempcpy fails. Adjust the return value in the
latter case. Use movstr if everything else fails.
* doc/md.texi (movstr): Document.
(movmemM, clrmemM): Fix explanation of memory block operands.
* config/h8300/h8300.md (stpcpy): Renamed to...
(movstr): ... this. Adjust.
2004-07-07 Alexandre Oliva <aoliva@redhat.com>
* config/h8300/h8300.md: Rename movstr*, except for movstrict*, to
movmem* and clrstr* to clrmem*.
2004-06-27 Alexandre Oliva <aoliva@redhat.com>
* config/h8300/h8300.c (h8300_reg_class_from_letter): Map 'D' to
GENERAL_REGS, always.
(h8300_swap_into_er6, h8300_swap_into_er6): Handle the case of
getting the stack pointer as addr.
* config/h8300/h8300.h (PREDICATE_CODES): Remove constant rtxes
from general_operand_dst.
* config/h8300/h8300.md (movmd_internal_normal): New, normal-mode
variant of...
(movmd_internal): ... this. Add modes to operands. Disparage `D'
instead of requiring it to match only before reload.
(stpcpy_internal_normal): New, normal-mode variant of...
(stpcpy_internal): ... this. Add modes to operands. Disparage
`D' instead of requiring it to match only before reload.
* config/h8300/h8300-protos.h (h8300_legitimate_address_p): Add
mode argument.
* config/h8300/h8300.h (GO_IF_LEGITIMATE_ADDRESS): Pass it to...
* config/h8300/h8300.c (h8300_legitimate_address_p): Pass it to
h8300_get_index.
* config/h8300/h8300.md (attr type): Add call.
(attr can_delay): If type is call, set it no.
(call, call_value): Set type to call.
2004-06-21 Alexandre Oliva <aoliva@redhat.com>
* config/h8300/h8300.md (logicalhi3_sn, logicalsi3_sn): New.
2004-06-16 Alexandre Oliva <aoliva@redhat.com>
* tree.c (get_narrower): Don't narrow integral types into
non-integral types.
* config/h8300/h8300.c (h8300_expand_epilogue): Initialize
frame_size *before* the first use.
* config/h8300/h8300.md (movstrictqi): Reintroduce post-increment
on input.
(peephole2): Don't widen instructions that push SP. Move
decrement of SP to the end of all stm-generating peepholes.
2003-07-24 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.md (insv): Prefer to use AND to clear a bitfield
and OR to set it to all ones.
2003-07-24 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.md (can_delay): Default to "no" for bit branches.
(call, call_value): Set can_delay to "no".
2003-07-22 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.md (extzv): Make subreg check more robust.
2003-07-21 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.md (*brabit): Remove.
* config/h8300/h8300.md (*brabc, *brabs): Remove mode from
zero_extract. Use bit_memory_operand as the predicate for
operand 1 and 'WU' as the constraint. Check the difference
between the base length and the final one when deciding which
type of branch to use.
2003-07-21 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.md (extzv): Remove mode from operands 0 and 1.
Use convert_move to extend the result for TARGET_H8300SX. Check
for QImode memory references. Optimize the case where the
destination is a paradoxical subreg.
2003-07-21 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.md (*movsf_h8sx): Add an r <- G alternative.
* config/h8300/h8300.md (andqi): Remove bclr from h8sx version.
2003-07-21 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.md: Include mova.md
(length_table): Add mova and mova_zero.
* config/h8300/h8300.c (print_operand): Handle '%o'. Print a length
after all constant addresses for '%R', '%X', '%T' and '%S'.
(h8300_mova_length): New function.
(h8300_insn_length_from_table): Use it to handle mova and mova_zero.
* config/h8300/t-h8300 (mova.md): Generate from genmova.sh. Add to
dependencies for s-config, etc.
* config/h8300/gemova.sh: New file.
* config/h8300/mova.md: Generated.
2003-07-20 Alexandre Oliva <aoliva@redhat.com>
* config/h8300/h8300.c (h8300_bitfield_length): New.
(nibble_operand): Adjust.
(h8300_binary_length): Handle conditional binary op.
(h8300_insn_length_from_table): Handle bitfield and bitbranch.
* config/h8300/h8300.h: Change constraints W# and Y# to P#>X and
P#<X, respectively. The original P is now IP4>X. Introduced P#>0
and P#<0, unused so far. W and Y are now prefixes to multi-letter
constraints. WU is introduced as a variant of U that requires a
mem, and is therefore considered an EXTRA_MEMORY_CONSTRAINT.
* config/h8300/h8300.md (attr type): Added bitbranch.
(attr length_table): Added bitfield and bitbranch.
(attr length): Compute bitbranch length.
(andqi): Separate pattern for H8300SX. Use bfld for loading the
least-significant bit of a byte.
(brabit, brabc, brabs): New.
(insv, extzv): Emit bfst and bfld on H8300SX.
(bfld, bfst, seq, sne): New.
(bstzhireg, cmpstz, bstz, bistz): New.
(cmpcondbset, condbset, cmpcondbclr, condbclr): New.
(cmpcondbsetreg, condbsetreg, cmpcondbclrreg, condbclrreg): New.
2003-07-11 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.c (h8sx_binary_memory_operator): New function.
(h8sx_unary_memory_operator): New function.
* config/h8300/h8300.h (EXTRA_MEMORY_CONSTRAINT): Disable.
(PREDICATE_CODES): Add h8sx_{unary,binary}_memory_operator.
* config/h8300/h8300.md: Add peepholes to combine reloads and
arithmetic insns.
2003-07-10 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h830.md (cmpqi): Use 'i' rather than 'n' in constraints.
(*cmphi_h8300hs, *addqi3, *addhi3_h8sx, subhi3): Likewise.
(and?i, ior?i, xor?i): Likewise.
2003-07-10 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.c: Move enums and prototypes to head of file.
Various whitespace fixes.
(h8300_constant_length): New function, split out from...
(h8300_displacement_size): ...here. Rename h8300_displacement_length.
(h8300_classify_operand): Use IN_RANGE.
(h8300_classify_operand): Use h8300_constant_length.
(h8300_short_move_mem_p): Tighten size check.
(h8sx_mergeable_memrefs_p): Tighten equality check.
2003-06-30 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.h (TARGET_CPU_CPP_BUILTINS): Define __H8300SX__
for -msx.
* config/h8300/crti.asm: Use .h8300sx or .h8300sxn for -msx code.
* config/h8300/crtn.asm: Likewise.
* config/h8300/lib1funcs.asm: Likewise. Use 32-bit pointers
if __H8300SX__ is defined.
2003-06-27 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300-protos.h (h8300_get_index): Add mode parameter.
* config/h8300/h8300.h (GO_IF_LEGITIMATE_ADDRESS): Update accordingly.
(GO_IF_MODE_DEPENDENT_ADDRESS): Treat POST_DEC, PRE_INC and indexed
addresses as mode-dependent.
* config/h8300/h8300.c (print_operand_address): Update call to
h8300_get_index.
(h8300_get_index): Take a mode argument. Rework to fix an
earlier misunderstanding.
2003-06-26 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.c (zero_extendqisi2): Force the source operand
into a register if TARGET_H8300SX.
(*zero_extendqisi2_h8300hs, *extendqisi2_h8300): Disable for
TARGET_H8300SX. Also disable related define_splits.
(*zero_extendqisi2_h8sx, *extendqisi2_h8sx): New patterns.
2003-06-23 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.c (h8300_rtx_costs): Add h8sx handling.
2003-06-20 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.h (OK_FOR_Z): New macro.
(EXTRA_CONSTRAINT_STR): Check it.
* config/h8300/h8300.c (h8300_classify_operand): Accept null
class arguments.
(h8300_insn_length_from_table): Handle LENGTH_TABLE_MOV_IMM4.
* config/h8300/h8300.md (length_table): Add mov_imm4.
(movqi, movhi): Add Z <- W4 alternatives to h8sx patterns.
2003-06-20 Richard Sandiford <rsandifo@redhat.com>
* genattrtab.c (write_eligible_delay): Allow candidate_insn to
be a label.
* config/h8300/h8300.h (DELAY_SLOT_LENGTH): New macro.
* config/h8300/h8300.c (h8300_reorg): New function.
(TARGET_MACHINE_DEPENDENT_REORG): Define.
* config/h8300/h8300.md (length): Subtract the length of the
delay slot from (pc) when checking the range of forward branches.
(delay_slot, can_delay): New attributes.
(define_delay): Add bra/s handling.
(movmd_internal, return_h8sx, *return_1): Set can_delay to no.
(jump): Add delayed-branch handling.
2003-06-17 Richard Sandiford <rsandifo@redhat.com>
* expr.c (expand_strcpy): New function.
* builtins.c (expand_builtin_strcpy): Fall back on expand_strcpy.
(expand_builtin_stpcpy): Likewise.
* config/h8300/h8300-protos.h (h8sx_split_movmd): Remove.
(h8300_swap_into_er6, h8300_swap_out_of_er6): Declare.
* config/h8300/h8300.c (h8300_reg_class_from_letter): Tweak 'd'
handling to improve register allocation for -fno-omit-frame-pointer.
(h8sx_split_movmd): Delete, moving er6 handling into...
(h8300_swap_into_er6, h8300_swap_out_of_er6): ...these new functions.
* config/h8300/h8300.md (UNSPEC_STPCPY): New unspec constant.
(movmd): Add calls to copy_rtx.
(movmd_internal): In the second alternative, allow the initial and
final destination registers to be different . Update the splitter
accordingly. Call h8300_swap_into_er6 and h8300_swap_out_of_er6
instead of h8sx_split_movmd.
(stpcpy, movsd): New expanders.
(movsd_internal): New define_insn.
2003-06-13 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300-protos.h (h8300_reg_class_from_letter): Declare.
(h8sx_emit_movmd, h8sx_split_movmd): Declare.
* config/h8300/h8300.h (reg_class): Add COUNTER_REGS, SOURCE_REGS
and DESTINATION_REGS.
(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
(REGNO_REG_CLASS): Map er4, er5 and er6 to the new classes.
(REG_CLASS_FROM_LETTER): Use h8300_reg_class_from_letter.
(h8300_move_ratio): Declare.
(MOVE_RATIO): Use it.
* config/h8300/h8300.c (h8300_move_ratio): New variable.
(h8300_init_once): Initialize it.
(h8300_reg_class_from_letter): New function.
(print_operand): Add an 'm' prefix for printing ".b", ".w" or ".l".
(h8sx_emit_movmd, h8sx_split_movmd): New functions.
* config/h8300/h8300.md (UNSPEC_MOVMD): New unspec constant.
(COUNTER_REG, SOURCE_REG, DESTINATION_REG): New register constants.
(movstrsi, movmd): New expanders.
(movmd_internal): New insn.
2003-06-06 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.h (EXTRA_MEMORY_CONSTRAINT): Define.
2003-06-04 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/elf.h (LINK_SPEC): Use -m h8300sxnelf for -msx -mn.
* config/h8300/h8300.c (asm_file_start): Use .h8300sxn likewise.
2003-06-03 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.c (nibble_operand): Fix warning.
* config/h8300/h8300.md (movstricthi): Set adjust_length to no.
(movsi_h8sx): Likewise here and the normal h8sx movhi pattern.
(movsf_h8300h): Disable for TARGET_H8300SX.
2003-06-03 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.h (PREDICATE_CODES): Add h8300_ldm_parallel,
h8300_stm_parallel and h8300_return_parallel.
* config/h8300/h8300.c (h8300_push_pop, h8300_stack_offset_p,
h8300_ldm_stm_regno, h8300_ldm_stm_parallel, h8300_ldm_parallel,
h8300_stm_parallel, h8300_return_parallel): New functions.
(h8300_expand_prologue): Don't enforce ldm/stm register alignment
if TARGET_H8300SX. Use h8300_push_pop.
(h8300_expand_epilogue): Likewise. Try to merge the return insn
and final pop when generating h8sx code. Always emit some form
of return insn.
* config/h8300/h8300.md: Don't enforce register alignment in
stm peepholes if TARGET_H8300SX.
(ldm_h8300s, stm_h8300s, return_h8sx): New patterns.
(ldm_h8300s_[234], stm_h8300_[234]): Disable.
(epilogue): Expect h8300_expand_epilogue to emit a return insn.
2003-06-03 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/t-h8300 (MULTILIB_OPTIONS): Add a -msx multilib.
(MULTILIB_DIRNAMES): Add a directory for it.
(MULTILIB_MATCHES): Delete.
2003-05-28 Richard Sandiford <rsandifo@redhat.com>
* final.c (walk_alter_subreg): Handle addresses with subregs
inside a ZERO_EXTEND or AND.
* config/h8300/h8300-protos.h (h8300_get_index): Declare.
* config/h8300/h8300.h (INDEX_REG_CLASS): Set to GENERAL_REGS
if TARGET_H8300SX.
(GO_IF_LEGITIMATE_ADDRESS): Use h8300_get_index.
* config/h8300/h8300.c (print_operand_address): Handle @(dd,RnL.b),
@(dd,Rn.w) and @(dd,ERn.L).
(h8300_displacement_size): Take the whole address as argument.
(h8300_classify_operand, h8300_short_move_mem_p): Adjust accordingly.
2003-05-28 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips-protos.h (h8300_operands_match_p): Declare.
(h8sx_mergeable_memrefs_p): Declare.
* config/h8300/h8300.h (HAVE_POST_DECREMENT): Define to TARGET_H8300SX.
(HAVE_PRE_INCREMENT): Likewise.
(GO_IF_LEGITIMATE_ADDRESS): Accept pre/post increment/decrement
addresses for TARGET_H8300SX,
* config/h8300/h8300.c (print_operand_address): Deal with PRE_INC
and POST_DEC.
(movb_length_table, movl_length_table): New tables.
(movw_length_table): Define to movb_length_table.
(h8300_displacement_size): New, split out from...
(h8300_classify_address): ...here. Handle pre/post inc/dec.
(h8300_short_immediate_length): Allow H8OP_MEM_COMPLEX operands.
(h8300_insn_length_from_table): Add cases for movb, movw and movl.
(h8sx_mergeable_memrefs_p, h8300_operands_match_p): New functions.
(output_plussi): Use add.l #xx:3,Rn and sub.l #xx:3,Rn for h8sx.
(compute_plussi_length, compute_plussi_cc): Update accordingly.
(h8sx_unary_shift_operator): Get the mode from the operator.
(binary_shift_operator): Likewise.
* config/h8300/h8300.md: If a peephole2 applies gen_lowpart to
a memory reference, check whether the reference is offsettable.
(length_table): Add movb, movw and movl.
(movqi): Add new h8sx pattern. Don't force one operand to be a
register when generating h8sx code.
(movhi, movsi, movsf): Likewise.
(movstrictqi): Use the length_table attribute.
(movstricthi): Likewise. Add h8sx alternative for mov.w #xx:3,Rn.
(addqi3): Split into a define_expand and define_insn. Don't accept
memory operands in the expander. Use h8300_operands_match_p to
check for matching operands in the define_insn.
(subqi3, negqi2, one_cmplqi2): Likewise.
(add[hs]i3): Don't accept memory operands in the expander. Likewise
in any patterns that are unused in h8sx code. In the h8sx patterns,
use h8300_operands_match_p to check whether operands match.
(sub[hs]i3, and[hi]3, ior[hs]i3, xor[hs]i3, neg[hsi]3,
one_cmpl[hs]i3): Likewise.
(andqi3, iorqi3, xorqi3): Likewise. Don't call fix_bit_operand
in the expander.
2003-05-23 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300-protos.h (expand_a_shift): Return a bool.
(h8300_insn_length_from_table): Add a second parameter.
(output_h8sx_shift): Declare.
* config/h8300/h8300.h (OK_FOR_W, OK_FOR_Y): New macros.
(EXTRA_CONSTRAINT): Replace with...
(EXTRA_CONSTRAINT_STR): ...this. Use OK_FOR_W and OK_FOR_Y.
(CONSTRAINT_LEN): Define, returning 2 for 'W' and 'Y'.
(PREDICATE_CODES): Add entries for h8sx_unary_shift_operator
and h8sx_binary_shift_operator.
* config/h8300/h8300.c (two_insn_adds_subs_operand): Return false
for TARGET_H8300SX.
(bit_operand): Replace use of EXTRA_CONSTRAINT with OK_FOR_U.
(bit_memory_operand, fix_bit_operand): Likewise.
(h8300_length_table_for_insn): Remove.
(h8300_classify_operand): Fix check for 16-bit operands in 32-bit
instructions.
(h8300_short_immediate_length, h8300_binary_length): New functions.
(h8300_insn_length_from_table): Add an opcodes parameter. Rework.
(output_plussi): Use sub to add negative constants.
(compute_plussi_length): Adjust accordingly.
(h8sx_single_shift_type): New enum.
(h8sx_single_shift, h8sx_unary_shift_operator,
h8sx_binary_shift_operator, output_h8sx_shift): New functions.
(expand_a_shift, expand_a_rotate): Emit nothing if the shift is a
single h8sx instruction. Return false in this case.
* config/h8300/h8300.md (length_table): Add short_immediate.
(length): Pass the operand array to h8300_insn_length_from_table.
(adjust_length): Assume "no" for insns with a length_table attribute.
(*cmphi_h8300hs, cmpsi): Add alternatives for #xx:3.
(*addhi3_h8300hs): Don't use for h8sx.
(*addhi3_h8sx): New pattern, with alternatives for add.w #xx:3
and sub.w #xx:3.
(ashl[qhs]i3, lshr[qhs]i3, ashr[qhs]i3, rotl[qhs]i3): Change operand
1's predicate to nonimmediate_operand. Only skip default expansion
if expand_a_shift or expand_a_rotate returns true. Add new patterns
for single h8sx shift instructions.
2003-05-22 Alexandre Oliva <aoliva@redhat.com>
* config/h8300/h8300.c (nibble_operand): Split out of...
(reg_or_nibble_operand): ... this.
* config/h8300/h8300.h (PREDICATE_CODES): Added nibble_operand.
* config/h8300/h8300.md: (mulqihi3, mulhisi3, umulqihi3,
umulhisi3): Introduce expand, and introduce separate insns for
sign- or zero-extended REG and already-extended CONST_INT.
2003-05-20 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.c (h8300_unary_length): Fix miscounting.
* config/h8300/h8300.md (subqi3): Generalize for h8sx.
(subhi3): Likewise. Don't accept immediates for operand 1.
Remove the early clobber from second alternative of the h8300s pattern.
(subsi3): Generalize for h8sx. Force operand 2 into a register
on plain h8300 targets.
(subsi3_h8300): Use h8300_dst_operand for consistency with expander.
(subsi3_h8300h): Generalize for h8sx.
(one_cmplqi2, one_cmplhi2, one_cmplsi2): Likewise.
2003-05-19 Alexandre Oliva <aoliva@redhat.com>
* config/h8300/h8300.c (reg_or_nibble_operand): New.
* config/h8300/h8300.h (PREDICATE_CODES): Adjust.
(TARGET_H8300SXMUL): New.
(CONST_OK_FOR_P): New.
(CONST_OK_FOR_LETTER_P): Adjust.
* config/h8300/h8300.md (mulqihi3, mulhisi3, umulqihi3,
umulhisi3): Accept 4-bit immediate on H8SX.
(mulhi3, mulsi3, smulsi3_highpart, umulsi3_highpart): New.
(udivsi3, divhi3, udivsi3, divsi3): New.
2003-05-19 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300-protos.h (h8300_insn_length_from_table): Declare.
* config/h8300/h8300.h (OK_FOR_Q): New macro.
(EXTRA_CONSTRAINT): Use it to check the 'Q' constraint.
(PREDICATE_CODES): Add h8300_src_operand and h8300_dst_operand.
Add ADDRESSOF to the bit_operand entry.
* config/h8300/h8300.c (h8300_dst_operand): New predicate.
(h8300_src_operand): Likewise.
(bit_operand): Check nonimmediate_operand rather than general_operand.
Accept any nonimmediate_operand in h8sx code.
(h8300_and_costs): Initialize operands[1].
(h8300_rtx_costs) <AND>: Return false if the operands aren't valid.
(h8300_operand_class): New enum.
(h8300_length_table): New typedef.
(addb_length_table, addw_length_table, addl_length_table,
logicl_length_table): New tables.
(logicb_length_table, logicw_length_table): New macros.
(h8300_classify_operand, h8300_length_from_table,
h8300_length_table_for_insn, h8300_unary_length,
h8300_insn_length_from_table): New functions.
(output_plussi): Only use adds and subs for register destinations.
Disable redundant clause.
(compute_plussi_cc): Likewise.
(compute_plussi_length): Likewise. Use h8300_length_from_table
to work out the length of an insn.
(output_logical_op): Only use narrower immediate instructions
if the destination is a register.
(compute_logical_op_cc): Likewise.
(compute_logical_op_length): Likewise. Use h8300_length_from_table.
(h8300_adjust_insn_length): Tighten check for reg<->mem moves.
* config/h8300/h8300.md (length_table): New attribute.
(length): When an instruction has a length_table attribute, use
h8300_insn_length_from_table to calculate its default length.
(cmpqi): Use h8300_dst_operand for the first operand and
h8300_src_operand for the second.
(cmphi, *cmphi_h8300hs, cmpsi, negqi2, neghi2, neghi2_h8300h, negsi2,
negsi2_h8300h, addqi3, addhi3, *addhi3_h8300, *addhi3_h8300hs, addsi3,
addsi_h8300, addsi_h8300h, andhi3, andsi3, iorhi3,
iorsi3, xorhi3, xorsi3): Likewise.
(andqi3): Use h8300_src_operand for operand 2. Adjust the condition
so that it allows any combination of operands for TARGET_H8300SX.
(iorqi3, xorqi3): Likewise.
(cmpqi): Use the length_table attribute.
(*cmphi_h8300hs, cmpsi, addqi, *addhi3_h8300hs, andqi3, iorqi3,
xorqi3, negqi2, neghi2_h8300h, negsi2_h8300h): Likewise.
(cmpqi): Add 'Q' constraint.
(*cmphi_h8300hs, cmpsi, addqi, *addhi3_h8300hs, addsi_h8300h, andqi3,
iorqi3, xorqi3, negqi2, neghi2_h8300h, negsi2_h8300h): Likewise.
2003-05-14 Richard Sandiford <rsandifo@redhat.com>
* config/h8300/h8300.h (MASK_H8300SX): New macro.
(TARGET_H8300S): True for both -ms and -msx.
(TARGET_H8300SX): New macro.
(TARGET_SWITCHES): Add entries for -msx and -mno-sx.
* config/h8300/h8300.c (asm_file_start): Write .h8300sx for -msx.
* config/h8300/elf.h (LINK_SPEC): Use -m h8300sxelf for -msx.
* config/h8300/t-h8300 (MULTILIB_MATCHES): Use -ms multilibs for -msx.
[Temporary change.]
2003-02-28 Alexandre Oliva <aoliva@redhat.com>
* config/h8300/h8300.h (SIZE_TYPE, PTRDIFF_TYPE): Use short with
16-bit pointers and 32-bit ints.
* config/h8300/h8300.h (LEGITIMATE_CONSTANT_P): Accept
CONST_DOUBLE with mode no wider than SImode.
* config/h8300/h8300.md (extendqisi2_h8300): Add constraints for
output operand.
2003-02-27 Alexandre Oliva <aoliva@redhat.com>
* config/h8300/h8300.c (general_operand_src): Match CONSTANT_P_RTX
or SUBREG thereof.
* config/h8300/h8300.h (PREDICATE_CODES): Adjust.
2003-02-22 Alexandre Oliva <aoliva@redhat.com>
* config/h8300/h8300.c (dosize): Truncate sign * size to Pmode.
2004-05-28 Aaron W. LaFramboise <aaronraolete36@aaronwl.com>
* config.gcc (i[34567]86-*-mingw32*): Enable threads by default.

View File

@ -2976,6 +2976,72 @@ expand_builtin_bcopy (tree arglist)
return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
}
#ifndef HAVE_movstr
# define HAVE_movstr 0
# define CODE_FOR_movstr CODE_FOR_nothing
#endif
/* Expand into a movstr instruction, if one is available. Return 0 if
we failed, the caller should emit a normal call, otherwise try to
get the result in TARGET, if convenient. If ENDP is 0 return the
destination pointer, if ENDP is 1 return the end pointer ala
mempcpy, and if ENDP is 2 return the end pointer minus one ala
stpcpy. */
static rtx
expand_movstr (tree dest, tree src, rtx target, int endp)
{
rtx end;
rtx dest_mem;
rtx src_mem;
rtx insn;
const struct insn_data * data;
if (!HAVE_movstr)
return 0;
dest_mem = get_memory_rtx (dest);
src_mem = get_memory_rtx (src);
if (!endp)
{
target = force_reg (Pmode, XEXP (dest_mem, 0));
dest_mem = replace_equiv_address (dest_mem, target);
end = gen_reg_rtx (Pmode);
}
else
{
if (target == 0 || target == const0_rtx)
{
end = gen_reg_rtx (Pmode);
if (target == 0)
target = end;
}
else
end = target;
}
data = insn_data + CODE_FOR_movstr;
if (data->operand[0].mode != VOIDmode)
end = gen_lowpart (data->operand[0].mode, end);
insn = data->genfun (end, dest_mem, src_mem);
if (insn == 0)
abort ();
emit_insn (insn);
/* movstr is supposed to set end to the address of the NUL
terminator. If the caller requested a mempcpy-like return value,
adjust it. */
if (endp == 1 && target != const0_rtx)
emit_move_insn (target, plus_constant (gen_lowpart (GET_MODE (target),
end), 1));
return target;
}
/* Expand expression EXP, which is a call to the strcpy builtin. Return 0
if we failed the caller should emit a normal call, otherwise try to get
the result in TARGET, if convenient (and in mode MODE if that's
@ -2996,12 +3062,14 @@ expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
if (operand_equal_p (src, dst, 0))
return expand_expr (dst, target, mode, EXPAND_NORMAL);
fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
len = c_strlen (src, 1);
if (len == 0 || TREE_SIDE_EFFECTS (len))
return expand_movstr (TREE_VALUE (arglist),
TREE_VALUE (TREE_CHAIN (arglist)),
target, /*endp=*/0);
fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
len = size_binop (PLUS_EXPR, len, ssize_int (1));
@ -3020,22 +3088,17 @@ expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
static rtx
expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
{
/* If return value is ignored, transform stpcpy into strcpy. */
if (target == const0_rtx)
return expand_builtin_strcpy (arglist, target, mode);
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
else
{
tree dst, src, len;
/* If return value is ignored, transform stpcpy into strcpy. */
if (target == const0_rtx)
{
tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
if (!fn)
return 0;
return expand_expr (build_function_call_expr (fn, arglist),
target, mode, EXPAND_NORMAL);
}
tree narglist;
rtx ret;
/* Ensure we get an actual string whose length can be evaluated at
compile-time, not an expression containing a string. This is
@ -3043,14 +3106,49 @@ expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
when used to produce the return value. */
src = TREE_VALUE (TREE_CHAIN (arglist));
if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
return 0;
return expand_movstr (TREE_VALUE (arglist),
TREE_VALUE (TREE_CHAIN (arglist)),
target, /*endp=*/2);
dst = TREE_VALUE (arglist);
len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
arglist = build_tree_list (NULL_TREE, len);
arglist = tree_cons (NULL_TREE, src, arglist);
arglist = tree_cons (NULL_TREE, dst, arglist);
return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
narglist = build_tree_list (NULL_TREE, len);
narglist = tree_cons (NULL_TREE, src, narglist);
narglist = tree_cons (NULL_TREE, dst, narglist);
ret = expand_builtin_mempcpy (narglist, target, mode, /*endp=*/2);
if (ret)
return ret;
if (TREE_CODE (len) == INTEGER_CST)
{
rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
if (GET_CODE (len_rtx) == CONST_INT)
{
ret = expand_builtin_strcpy (arglist, target, mode);
if (ret)
{
if (! target)
target = gen_reg_rtx (mode);
if (GET_MODE (target) != GET_MODE (ret))
ret = gen_lowpart (GET_MODE (target), ret);
ret = emit_move_insn (target,
plus_constant (ret,
INTVAL (len_rtx)));
if (! ret)
abort ();
return target;
}
}
}
return expand_movstr (TREE_VALUE (arglist),
TREE_VALUE (TREE_CHAIN (arglist)),
target, /*endp=*/2);
}
}

View File

@ -51,6 +51,13 @@ Boston, MA 02111-1307, USA. */
#else
.h8300s
#endif
#endif
#ifdef __H8300SX__
#ifdef __NORMAL_MODE__
.h8300sxn
#else
.h8300sx
#endif
#endif
.section .init

View File

@ -43,6 +43,13 @@ Boston, MA 02111-1307, USA. */
#else
.h8300s
#endif
#endif
#ifdef __H8300SX__
#ifdef __NORMAL_MODE__
.h8300sxn
#else
.h8300sx
#endif
#endif
.section .init
rts

View File

@ -40,6 +40,6 @@ Boston, MA 02111-1307, USA. */
#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
#undef LINK_SPEC
#define LINK_SPEC "%{mh:%{mn:-m h8300hnelf}} %{mh:%{!mn:-m h8300helf}} %{ms:%{mn:-m h8300snelf}} %{ms:%{!mn:-m h8300self}}"
#define LINK_SPEC "%{mh:%{mn:-m h8300hnelf}} %{mh:%{!mn:-m h8300helf}} %{ms:%{mn:-m h8300snelf}} %{ms:%{!mn:-m h8300self}} %{msx:%{mn:-m h8300sxnelf;:-m h8300sxelf}}"
#endif /* h8300/elf.h */

163
gcc/config/h8300/genmova.sh Normal file
View File

@ -0,0 +1,163 @@
#!/bin/sh
# Generate mova.md, a file containing patterns that can be implemented
# using the h8sx mova instruction.
echo ";; -*- buffer-read-only: t -*-"
echo ";; Generated automatically from genmova.sh"
# Loop over modes for the source operand (the index). Only 8-bit and
# 16-bit indices are allowed.
for s in QI HI; do
# Set $src to the operand syntax for this size of index.
case $s in
QI) src=%X1.b;;
HI) src=%T1.w;;
esac
# A match_operand for the source.
operand="(match_operand:$s 1 \"h8300_dst_operand\" \"0,rQ\")"
# Loop over the destination register's mode. The QI and HI versions use
# the same instructions as the SI ones, they just ignore the upper bits
# of the result.
for d in QI HI SI; do
# If the destination is larger than the source, include a
# zero_extend/plus pattern. We could also match zero extensions
# of memory without the plus, but it's not any smaller or faster
# than separate insns.
case $d:$s in
SI:QI | SI:HI | HI:QI)
cat <<EOF
(define_insn ""
[(set (match_operand:$d 0 "register_operand" "=r,r")
(plus:$d (zero_extend:$d $operand)
(match_operand:$d 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/b.l @(%o2,$src),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
EOF
;;
esac
# Loop over the shift amount.
for shift in 1 2; do
case $shift in
1) opsize=w mult=2;;
2) opsize=l mult=4;;
esac
# Calculate the mask of bits that will be nonzero after the source
# has been extended and shifted.
case $s:$shift in
QI:1) mask=510;;
QI:2) mask=1020;;
HI:1) mask=131070;;
HI:2) mask=262140;;
esac
# There doesn't seem to be a well-established canonical form for
# some of the patterns we need. Emit both shift and multiplication
# patterns.
for form in mult ashift; do
case $form in
mult) amount=$mult;;
ashift) amount=$shift;;
esac
case $d:$s in
# If the source and destination are the same size, we can treat
# mova as a sort of multiply-add instruction.
QI:QI | HI:HI)
cat <<EOF
(define_insn ""
[(set (match_operand:$d 0 "register_operand" "=r,r")
(plus:$d ($form:$d $operand
(const_int $amount))
(match_operand:$d 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/$opsize.l @(%o2,$src),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
EOF
;;
# Handle the cases where the source is smaller than the
# destination. Sometimes combine will keep the extension,
# sometimes it will use an AND.
SI:QI | SI:HI | HI:QI)
# Emit the forms that use zero_extend.
cat <<EOF
(define_insn ""
[(set (match_operand:$d 0 "register_operand" "=r,r")
($form:$d (zero_extend:$d $operand)
(const_int $amount)))]
"TARGET_H8300SX"
"mova/$opsize.l @(0,$src),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:$d 0 "register_operand" "=r,r")
(plus:$d ($form:$d (zero_extend:$d $operand)
(const_int $amount))
(match_operand:$d 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/$opsize.l @(%o2,$src),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
EOF
# Now emit the forms that use AND. When the index is a register,
# these forms are effectively $d-mode operations: the index will
# be a $d-mode REG or SUBREG. When the index is a memory
# location, we will have a paradoxical subreg such as:
#
# (and:SI (mult:SI (subreg:SI (mem:QI ...) 0)
# (const_int 4))
# (const_int 1020))
#
# Match the two case separately: a $d-mode register_operand
# or a $d-mode subreg of an $s-mode memory_operand. Match the
# memory form first since register_operand accepts mem subregs
# before reload.
memory="(match_operand:$s 1 \"memory_operand\" \"m\")"
memory="(subreg:$d $memory 0)"
register="(match_operand:$d 1 \"register_operand\" \"0\")"
for paradoxical in "$memory" "$register"; do
cat <<EOF
(define_insn ""
[(set (match_operand:$d 0 "register_operand" "=r")
(and:$d ($form:$d $paradoxical
(const_int $amount))
(const_int $mask)))]
"TARGET_H8300SX"
"mova/$opsize.l @(0,$src),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:$d 0 "register_operand" "=r")
(plus:$d (and:$d ($form:$d $paradoxical
(const_int $amount))
(const_int $mask))
(match_operand:$d 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/$opsize.l @(%o2,$src),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
EOF
done
;;
esac
done
done
done
done

View File

@ -46,7 +46,7 @@ extern unsigned int compute_logical_op_length (enum machine_mode,
rtx *);
extern int compute_logical_op_cc (enum machine_mode, rtx *);
extern void h8300_expand_branch (enum rtx_code, rtx);
extern void expand_a_shift (enum machine_mode, int, rtx[]);
extern bool expand_a_shift (enum machine_mode, int, rtx[]);
extern int h8300_shift_needs_scratch_p (int, enum machine_mode);
extern int expand_a_rotate (rtx[]);
extern int fix_bit_operand (rtx *, enum rtx_code);
@ -83,7 +83,7 @@ extern int same_cmp_preceding_p (rtx);
extern int same_cmp_following_p (rtx);
extern int h8300_legitimate_constant_p (rtx);
extern int h8300_legitimate_address_p (rtx, int);
extern int h8300_legitimate_address_p (enum machine_mode, rtx, int);
/* Used in builtins.c */
extern rtx h8300_return_addr_rtx (int, rtx);
@ -111,5 +111,14 @@ extern int h8300_hard_regno_mode_ok (int, enum machine_mode);
struct cpp_reader;
extern void h8300_pr_interrupt (struct cpp_reader *);
extern void h8300_pr_saveall (struct cpp_reader *);
extern enum reg_class h8300_reg_class_from_letter (int);
extern rtx h8300_get_index (rtx, enum machine_mode mode, int *);
extern unsigned int h8300_insn_length_from_table (rtx, rtx *);
extern const char * output_h8sx_shift (rtx *, int, int);
extern bool h8300_operands_match_p (rtx *);
extern bool h8sx_mergeable_memrefs_p (rtx, rtx);
extern bool h8sx_emit_movmd (rtx, rtx, rtx, HOST_WIDE_INT);
extern void h8300_swap_into_er6 (rtx);
extern void h8300_swap_out_of_er6 (rtx);
#endif /* ! GCC_H8300_PROTOS_H */

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,14 @@ extern const char * const *h8_reg_names;
builtin_define ("__NORMAL_MODE__"); \
} \
} \
else if (TARGET_H8300SX) \
{ \
builtin_define ("__H8300SX__"); \
if (TARGET_NORMAL_MODE) \
{ \
builtin_define ("__NORMAL_MODE__"); \
} \
} \
else if (TARGET_H8300S) \
{ \
builtin_define ("__H8300S__"); \
@ -103,6 +111,7 @@ extern int target_flags;
#define MASK_RELAX 0x00000400
#define MASK_H8300H 0x00001000
#define MASK_ALIGN_300 0x00002000
#define MASK_H8300SX 0x00004000
/* Macros used in the machine description to test the flags. */
@ -122,7 +131,12 @@ extern int target_flags;
/* Select between the H8/300 and H8/300H CPUs. */
#define TARGET_H8300 (! TARGET_H8300H && ! TARGET_H8300S)
#define TARGET_H8300H (target_flags & MASK_H8300H)
#define TARGET_H8300S (target_flags & MASK_H8300S)
#define TARGET_H8300S (target_flags & (MASK_H8300S | MASK_H8300SX))
#define TARGET_H8300SX (target_flags & MASK_H8300SX)
/* Some multiply instructions are not available in all H8SX variants.
Use this macro instead of TARGET_H8300SX to indicate this, even
though we don't actually generate different code for now. */
#define TARGET_H8300SXMUL TARGET_H8300SX
#define TARGET_NORMAL_MODE (target_flags & MASK_NORMAL_MODE)
/* mac register and relevant instructions are available. */
@ -144,6 +158,8 @@ extern int target_flags;
#define TARGET_SWITCHES \
{ {"s", MASK_H8300S, N_("Generate H8S code")}, \
{"no-s", -MASK_H8300S, N_("Do not generate H8S code")}, \
{"sx", MASK_H8300SX, N_("Generate H8SX code")}, \
{"no-sx", -MASK_H8300SX, N_("Do not generate H8SX code")}, \
{"s2600", MASK_MAC, N_("Generate H8S/2600 code")}, \
{"no-s2600", -MASK_MAC, N_("Do not generate H8S/2600 code")}, \
{"int32", MASK_INT32, N_("Make integers 32 bits wide")}, \
@ -398,7 +414,8 @@ extern int target_flags;
class that represents their union. */
enum reg_class {
NO_REGS, GENERAL_REGS, MAC_REGS, ALL_REGS, LIM_REG_CLASSES
NO_REGS, COUNTER_REGS, SOURCE_REGS, DESTINATION_REGS,
GENERAL_REGS, MAC_REGS, ALL_REGS, LIM_REG_CLASSES
};
#define N_REG_CLASSES ((int) LIM_REG_CLASSES)
@ -406,7 +423,8 @@ enum reg_class {
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
{ "NO_REGS", "GENERAL_REGS", "MAC_REGS", "ALL_REGS", "LIM_REGS" }
{ "NO_REGS", "COUNTER_REGS", "SOURCE_REGS", "DESTINATION_REGS", \
"GENERAL_REGS", "MAC_REGS", "ALL_REGS", "LIM_REGS" }
/* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET
@ -414,8 +432,11 @@ enum reg_class {
#define REG_CLASS_CONTENTS \
{ {0}, /* No regs */ \
{0x010}, /* COUNTER_REGS */ \
{0x020}, /* SOURCE_REGS */ \
{0x040}, /* DESTINATION_REGS */ \
{0xeff}, /* GENERAL_REGS */ \
{0x100}, /* MAC_REGS */ \
{0x100}, /* MAC_REGS */ \
{0xfff}, /* ALL_REGS */ \
}
@ -424,18 +445,23 @@ enum reg_class {
reg number REGNO. This could be a conditional expression
or could index an array. */
#define REGNO_REG_CLASS(REGNO) (REGNO != MAC_REG ? GENERAL_REGS : MAC_REGS)
#define REGNO_REG_CLASS(REGNO) \
((REGNO) == MAC_REG ? MAC_REGS \
: (REGNO) == COUNTER_REG ? COUNTER_REGS \
: (REGNO) == SOURCE_REG ? SOURCE_REGS \
: (REGNO) == DESTINATION_REG ? DESTINATION_REGS \
: GENERAL_REGS)
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS NO_REGS
#define INDEX_REG_CLASS (TARGET_H8300SX ? GENERAL_REGS : NO_REGS)
#define BASE_REG_CLASS GENERAL_REGS
/* Get reg_class from a letter such as appears in the machine description.
'a' is the MAC register. */
#define REG_CLASS_FROM_LETTER(C) ((C) == 'a' ? MAC_REGS : NO_REGS)
#define REG_CLASS_FROM_LETTER(C) (h8300_reg_class_from_letter (C))
/* The letters I, J, K, L, M, N, O, P in a register constraint string
can be used to stand for particular ranges of immediate operands.
@ -458,6 +484,31 @@ enum reg_class {
#define CONST_OK_FOR_O(VALUE) \
((VALUE) == -1 || (VALUE) == -2)
/* Multi-letter constraints for constant are always started with P
(just because it was the only letter in the range left. New
constraints for constants should be added here. */
#define CONST_OK_FOR_Ppositive(VALUE, NBITS) \
((VALUE) > 0 && (VALUE) < (1 << (NBITS)))
#define CONST_OK_FOR_Pnegative(VALUE, NBITS) \
((VALUE) < 0 && (VALUE) > -(1 << (NBITS)))
#define CONST_OK_FOR_P(VALUE, STR) \
((STR)[1] >= '1' && (STR)[1] <= '9' && (STR)[2] == '<' \
? (((STR)[3] == '0' || ((STR)[3] == 'X' && TARGET_H8300SX)) \
&& CONST_OK_FOR_Pnegative ((VALUE), (STR)[1] - '0')) \
: ((STR)[1] >= '1' && (STR)[1] <= '9' && (STR)[2] == '>') \
? (((STR)[3] == '0' || ((STR)[3] == 'X' && TARGET_H8300SX)) \
&& CONST_OK_FOR_Ppositive ((VALUE), (STR)[1] - '0')) \
: 0)
#define CONSTRAINT_LEN_FOR_P(STR) \
((((STR)[1] >= '1' && (STR)[1] <= '9') \
&& ((STR)[2] == '<' || (STR)[2] == '>') \
&& ((STR)[3] == 'X' || (STR)[3] == '0')) ? 4 \
: 0)
#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
((C) == 'P' ? CONST_OK_FOR_P ((VALUE), (STR)) \
: CONST_OK_FOR_LETTER_P ((VALUE), (C)))
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'I' ? CONST_OK_FOR_I (VALUE) : \
(C) == 'J' ? CONST_OK_FOR_J (VALUE) : \
@ -753,6 +804,8 @@ struct cum_arg
#define HAVE_POST_INCREMENT 1
#define HAVE_PRE_DECREMENT 1
#define HAVE_POST_DECREMENT TARGET_H8300SX
#define HAVE_PRE_INCREMENT TARGET_H8300SX
/* Macros to check register numbers against specific register classes. */
@ -824,6 +877,9 @@ struct cum_arg
/* Extra constraints. */
#define OK_FOR_Q(OP) \
(TARGET_H8300SX && memory_operand ((OP), VOIDmode))
#define OK_FOR_R(OP) \
(GET_CODE (OP) == CONST_INT \
? !h8300_shift_needs_scratch_p (INTVAL (OP), QImode) \
@ -861,18 +917,79 @@ struct cum_arg
|| (GET_CODE (OP) == MEM && TARGET_H8300S \
&& GET_CODE (XEXP (OP, 0)) == CONST_INT))
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'R' ? OK_FOR_R (OP) : \
/* Multi-letter constraints starting with W are to be used for
operands that require a memory operand, i.e,. that are never used
along with register constraints (see EXTRA_MEMORY_CONSTRAINTS).
For operands that require a memory operand (or not) but that always
accept a register, a multi-letter constraint starting with Y should
be used instead. */
#define OK_FOR_WU(OP) \
(GET_CODE (OP) == MEM && OK_FOR_U (OP))
#define OK_FOR_W(OP, STR) \
((STR)[1] == 'U' ? OK_FOR_WU (OP) \
: 0)
#define CONSTRAINT_LEN_FOR_W(STR) \
((STR)[1] == 'U' ? 2 \
: 0)
/* We don't have any constraint starting with Y yet, but before
someone uses it for a one-letter constraint and we're left without
any upper-case constraints left, we reserve it for extensions
here. */
#define OK_FOR_Y(OP, STR) \
(0)
#define CONSTRAINT_LEN_FOR_Y(STR) \
(0)
#define OK_FOR_Z(OP) \
(TARGET_H8300SX \
&& GET_CODE (OP) == MEM \
&& CONSTANT_P (XEXP ((OP), 0)))
#define EXTRA_CONSTRAINT_STR(OP, C, STR) \
((C) == 'Q' ? OK_FOR_Q (OP) : \
(C) == 'R' ? OK_FOR_R (OP) : \
(C) == 'S' ? OK_FOR_S (OP) : \
(C) == 'T' ? OK_FOR_T (OP) : \
(C) == 'U' ? OK_FOR_U (OP) : \
(C) == 'W' ? OK_FOR_W ((OP), (STR)) : \
(C) == 'Y' ? OK_FOR_Y ((OP), (STR)) : \
(C) == 'Z' ? OK_FOR_Z (OP) : \
0)
#define CONSTRAINT_LEN(C, STR) \
((C) == 'P' ? CONSTRAINT_LEN_FOR_P (STR) \
: (C) == 'W' ? CONSTRAINT_LEN_FOR_W (STR) \
: (C) == 'Y' ? CONSTRAINT_LEN_FOR_Y (STR) \
: DEFAULT_CONSTRAINT_LEN ((C), (STR)))
/* Experiments suggest that it's better not add 'Q' or 'U' here. No
patterns need it for correctness (no patterns use 'Q' and 'U'
without also providing a register alternative). And defining it
will mean that a spilled pseudo could be replaced by its frame
location in several consecutive insns.
Instead, it seems to be better to force pseudos to be reloaded
into registers and then use peepholes to recombine insns when
beneficial.
Unfortunately, for WU (unlike plain U, that matches regs as well),
we must require a memory address. In fact, all multi-letter
constraints started with W are supposed to have this property, so
we just test for W here. */
#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
((C) == 'W')
#ifndef REG_OK_STRICT
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
do \
{ \
if (h8300_legitimate_address_p ((X), 0)) \
if (h8300_legitimate_address_p ((MODE), (X), 0)) \
goto ADDR; \
} \
while (0)
@ -880,7 +997,7 @@ struct cum_arg
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
do \
{ \
if (h8300_legitimate_address_p ((X), 1)) \
if (h8300_legitimate_address_p ((MODE), (X), 1)) \
goto ADDR; \
} \
while (0)
@ -893,7 +1010,14 @@ struct cum_arg
(the amount of decrement or increment being the length of the operand). */
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
if (GET_CODE (ADDR) == POST_INC || GET_CODE (ADDR) == PRE_DEC) goto LABEL;
if (GET_CODE (ADDR) == POST_INC \
|| GET_CODE (ADDR) == POST_DEC \
|| GET_CODE (ADDR) == PRE_INC \
|| GET_CODE (ADDR) == PRE_DEC) \
goto LABEL; \
if (GET_CODE (ADDR) == PLUS \
&& h8300_get_index (XEXP (ADDR, 0), VOIDmode, 0) != XEXP (ADDR, 0)) \
goto LABEL;
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
@ -936,9 +1060,9 @@ struct cum_arg
We use longs for the H8/300H and the H8S because ints can be 16 or 32.
GCC requires SIZE_TYPE to be the same size as pointers. */
#define SIZE_TYPE \
(TARGET_H8300 || TARGET_NORMAL_MODE ? "unsigned int" : "long unsigned int")
(TARGET_H8300 || TARGET_NORMAL_MODE ? TARGET_INT32 ? "short unsigned int" : "unsigned int" : "long unsigned int")
#define PTRDIFF_TYPE \
(TARGET_H8300 || TARGET_NORMAL_MODE ? "int" : "long int")
(TARGET_H8300 || TARGET_NORMAL_MODE ? TARGET_INT32 ? "short int" : "int" : "long int")
#define POINTER_SIZE \
((TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE ? 32 : 16)
@ -951,6 +1075,12 @@ struct cum_arg
so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
/* Return the length of JUMP's delay slot insn (0 if it has none).
If JUMP is a delayed branch, NEXT_INSN (PREV_INSN (JUMP)) will
be the containing SEQUENCE, not JUMP itself. */
#define DELAY_SLOT_LENGTH(JUMP) \
(NEXT_INSN (PREV_INSN (JUMP)) == JUMP ? 0 : 2)
#define BRANCH_COST 0
/* Tell final.c how to eliminate redundant test instructions. */
@ -1139,14 +1269,29 @@ struct cum_arg
final_prescan_insn (insn, operand, nop)
#define MOVE_RATIO 3
extern int h8300_move_ratio;
#undef MOVE_RATIO
#define MOVE_RATIO h8300_move_ratio
/* Define the codes that are matched by predicates in h8300.c. */
#define PREDICATE_CODES \
{"general_operand_src", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
LABEL_REF, SUBREG, REG, MEM}}, \
{"general_operand_dst", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
LABEL_REF, SUBREG, REG, MEM}}, \
{"general_operand_dst", {SUBREG, REG, MEM}}, \
{"h8300_src_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
LABEL_REF, SUBREG, REG, MEM}}, \
{"h8300_dst_operand", {SUBREG, REG, MEM}}, \
{"nibble_operand", {CONST_INT}}, \
{"reg_or_nibble_operand", {CONST_INT, SUBREG, REG}}, \
{"h8sx_unary_shift_operator", {ASHIFTRT, LSHIFTRT, ASHIFT, ROTATE}}, \
{"h8sx_binary_shift_operator", {ASHIFTRT, LSHIFTRT, ASHIFT}}, \
{"h8sx_binary_memory_operator", {PLUS, MINUS, AND, IOR, XOR, ASHIFT, \
ASHIFTRT, LSHIFTRT, ROTATE}}, \
{"h8sx_unary_memory_operator", {NEG, NOT}}, \
{"h8300_ldm_parallel", {PARALLEL}}, \
{"h8300_stm_parallel", {PARALLEL}}, \
{"h8300_return_parallel", {PARALLEL}}, \
{"single_one_operand", {CONST_INT}}, \
{"single_zero_operand", {CONST_INT}}, \
{"call_insn_operand", {MEM}}, \

File diff suppressed because it is too large Load Diff

View File

@ -72,7 +72,7 @@ Boston, MA 02111-1307, USA. */
#define S2P r6
#endif
#if defined (__H8300H__) || defined (__H8300S__)
#if defined (__H8300H__) || defined (__H8300S__) || defined (__H8300SX__)
#define PUSHP push.l
#define POPP pop.l
@ -105,6 +105,13 @@ Boston, MA 02111-1307, USA. */
.h8300s
#endif
#endif
#ifdef __H8300SX__
#ifdef __NORMAL_MODE__
.h8300sxn
#else
.h8300sx
#endif
#endif
#ifdef L_cmpsi2
#ifdef __H8300__

841
gcc/config/h8300/mova.md Normal file
View File

@ -0,0 +1,841 @@
;; -*- buffer-read-only: t -*-
;; Generated automatically from genmova.sh
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r,r")
(plus:QI (mult:QI (match_operand:QI 1 "h8300_dst_operand" "0,rQ")
(const_int 2))
(match_operand:QI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r,r")
(plus:QI (ashift:QI (match_operand:QI 1 "h8300_dst_operand" "0,rQ")
(const_int 1))
(match_operand:QI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r,r")
(plus:QI (mult:QI (match_operand:QI 1 "h8300_dst_operand" "0,rQ")
(const_int 4))
(match_operand:QI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r,r")
(plus:QI (ashift:QI (match_operand:QI 1 "h8300_dst_operand" "0,rQ")
(const_int 2))
(match_operand:QI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(plus:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/b.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(mult:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2))
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(and:HI (mult:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (and:HI (mult:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 510))
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(and:HI (mult:HI (match_operand:HI 1 "register_operand" "0")
(const_int 2))
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (and:HI (mult:HI (match_operand:HI 1 "register_operand" "0")
(const_int 2))
(const_int 510))
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(ashift:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 1)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 1))
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(and:HI (ashift:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 1))
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (and:HI (ashift:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 1))
(const_int 510))
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(and:HI (ashift:HI (match_operand:HI 1 "register_operand" "0")
(const_int 1))
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (and:HI (ashift:HI (match_operand:HI 1 "register_operand" "0")
(const_int 1))
(const_int 510))
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(mult:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 4)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 4))
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(and:HI (mult:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 4))
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (and:HI (mult:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 4))
(const_int 1020))
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(and:HI (mult:HI (match_operand:HI 1 "register_operand" "0")
(const_int 4))
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (and:HI (mult:HI (match_operand:HI 1 "register_operand" "0")
(const_int 4))
(const_int 1020))
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(ashift:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2))
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(and:HI (ashift:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (and:HI (ashift:HI (subreg:HI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 1020))
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(and:HI (ashift:HI (match_operand:HI 1 "register_operand" "0")
(const_int 2))
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (and:HI (ashift:HI (match_operand:HI 1 "register_operand" "0")
(const_int 2))
(const_int 1020))
(match_operand:HI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/b.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(mult:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (mult:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (mult:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (mult:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 510))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
(const_int 2))
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
(const_int 2))
(const_int 510))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ashift:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 1)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (ashift:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 1))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 1))
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 1))
(const_int 510))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 1))
(const_int 510)))]
"TARGET_H8300SX"
"mova/w.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 1))
(const_int 510))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(mult:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 4)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (mult:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 4))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (mult:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 4))
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (mult:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 4))
(const_int 1020))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4))
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4))
(const_int 1020))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ashift:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (ashift:SI (zero_extend:SI (match_operand:QI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 1020))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 2))
(const_int 1020)))]
"TARGET_H8300SX"
"mova/l.l @(0,%X1.b),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 2))
(const_int 1020))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%X1.b),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(plus:HI (mult:HI (match_operand:HI 1 "h8300_dst_operand" "0,rQ")
(const_int 2))
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(plus:HI (ashift:HI (match_operand:HI 1 "h8300_dst_operand" "0,rQ")
(const_int 1))
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(plus:HI (mult:HI (match_operand:HI 1 "h8300_dst_operand" "0,rQ")
(const_int 4))
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r,r")
(plus:HI (ashift:HI (match_operand:HI 1 "h8300_dst_operand" "0,rQ")
(const_int 2))
(match_operand:HI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/b.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(mult:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (mult:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (mult:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 131070)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (mult:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 131070))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
(const_int 2))
(const_int 131070)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
(const_int 2))
(const_int 131070))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ashift:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
(const_int 1)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (ashift:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
(const_int 1))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ashift:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
(const_int 1))
(const_int 131070)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (ashift:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
(const_int 1))
(const_int 131070))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 1))
(const_int 131070)))]
"TARGET_H8300SX"
"mova/w.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 1))
(const_int 131070))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/w.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(mult:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
(const_int 4)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (mult:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
(const_int 4))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (mult:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
(const_int 4))
(const_int 262140)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (mult:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
(const_int 4))
(const_int 262140))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4))
(const_int 262140)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (mult:SI (match_operand:SI 1 "register_operand" "0")
(const_int 4))
(const_int 262140))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ashift:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (ashift:SI (zero_extend:SI (match_operand:HI 1 "h8300_dst_operand" "0,rQ"))
(const_int 2))
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ashift:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 262140)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (ashift:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)
(const_int 2))
(const_int 262140))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 2))
(const_int 262140)))]
"TARGET_H8300SX"
"mova/l.l @(0,%T1.w),%S0"
[(set_attr "length_table" "mova_zero")
(set_attr "cc" "none")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
(const_int 2))
(const_int 262140))
(match_operand:SI 2 "immediate_operand" "i")))]
"TARGET_H8300SX"
"mova/l.l @(%o2,%T1.w),%S0"
[(set_attr "length_table" "mova")
(set_attr "cc" "none")])

View File

@ -27,9 +27,17 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
MULTILIB_OPTIONS = mh/ms mn mint32
MULTILIB_DIRNAMES = h8300h h8300s normal int32
MULTILIB_OPTIONS = mh/ms/msx mn mint32
MULTILIB_DIRNAMES = h8300h h8300s h8sx normal int32
MULTILIB_EXCEPTIONS = mint32 mn mn/mint32
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
s-config s-conditions s-flags s-codes s-constants s-emit s-recog \
s-opinit s-extract s-peep s-attr s-attrtab s-output: \
$(srcdir)/config/h8300/mova.md
$(srcdir)/config/h8300/mova.md: $(srcdir)/config/h8300/genmova.sh
$(SHELL) $(srcdir)/config/h8300/genmova.sh \
> $(srcdir)/config/h8300/mova.md

View File

@ -2778,8 +2778,9 @@ The @samp{cmp@var{m}} patterns should be used instead.
@cindex @code{movmem@var{m}} instruction pattern
@item @samp{movmem@var{m}}
Block move instruction. The addresses of the destination and source
strings are the first two operands, and both are in mode @code{Pmode}.
Block move instruction. The destination and source blocks of memory
are the first two operands, and both are @code{mem:BLK}s with an
address in mode @code{Pmode}.
The number of bytes to move is the third operand, in mode @var{m}.
Usually, you specify @code{word_mode} for @var{m}. However, if you can
@ -2803,12 +2804,21 @@ individually moved data units in the block.
These patterns need not give special consideration to the possibility
that the source and destination strings might overlap.
@cindex @code{movstr} instruction pattern
@item @samp{movstr}
String copy instruction, with @code{stpcpy} semantics. Operand 0 is
an output operand in mode @code{Pmode}. The addresses of the
destination and source strings are operands 1 and 2, and both are
@code{mem:BLK}s with addresses in mode @code{Pmode}. The execution of
the expansion of this pattern should store in operand 0 the address in
which the @code{NUL} terminator was stored in the destination string.
@cindex @code{clrmem@var{m}} instruction pattern
@item @samp{clrmem@var{m}}
Block clear instruction. The addresses of the destination string is the
first operand, in mode @code{Pmode}. The number of bytes to clear is
the second operand, in mode @var{m}. See @samp{movmem@var{m}} for
a discussion of the choice of mode.
Block clear instruction. The destination string is the first operand,
given as a @code{mem:BLK} whose address is in mode @code{Pmode}. The
number of bytes to clear is the second operand, in mode @var{m}. See
@samp{movmem@var{m}} for a discussion of the choice of mode.
The third operand is the known alignment of the destination, in the form
of a @code{const_int} rtx. Thus, if the compiler knows that the

View File

@ -2660,11 +2660,13 @@ walk_alter_subreg (rtx *xp)
{
case PLUS:
case MULT:
case AND:
XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1));
break;
case MEM:
case ZERO_EXTEND:
XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
break;

View File

@ -5525,6 +5525,11 @@ write_eligible_delay (const char *kind)
printf (" if (slot >= %d)\n", max_slots);
printf (" abort ();\n");
printf ("\n");
/* Allow dbr_schedule to pass labels, etc. This can happen if try_split
converts a compound instruction into a loop. */
printf (" if (!INSN_P (candidate_insn))\n");
printf (" return 0;\n");
printf ("\n");
/* If more than one delay type, find out which type the delay insn is. */

View File

@ -4544,6 +4544,7 @@ get_narrower (tree op, int *unsignedp_ptr)
int uns = 0;
int first = 1;
tree win = op;
bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op));
while (TREE_CODE (op) == NOP_EXPR)
{
@ -4580,6 +4581,10 @@ get_narrower (tree op, int *unsignedp_ptr)
uns = TYPE_UNSIGNED (TREE_TYPE (op));
first = 0;
op = TREE_OPERAND (op, 0);
/* Keep trying to narrow, but don't assign op to win if it
would turn an integral type into something else. */
if (INTEGRAL_TYPE_P (TREE_TYPE (op)) != integral_p)
continue;
}
win = op;