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:
parent
5c121a1b68
commit
beed8fc0bb
421
gcc/ChangeLog
421
gcc/ChangeLog
@ -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.
|
||||
|
138
gcc/builtins.c
138
gcc/builtins.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
163
gcc/config/h8300/genmova.sh
Normal 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
|
@ -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
@ -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
@ -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
841
gcc/config/h8300/mova.md
Normal 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")])
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user