Commit b8c96320 by Maxim Kuvyrkov Committed by Maxim Kuvyrkov

m68k.c (sched-int.h, [...]): New includes.

	* config/m68k/m68k.c (sched-int.h, insn-codes.h): New includes.
	(TARGET_SCHED_ADJUST_COST, TARGET_SCHED_VARIABLE_ISSUE,
	TARGET_SCHED_INIT_GLOBAL, TARGET_SCHED_FINISH_GLOBAL,
	TARGET_SCHED_INIT, TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE,
	TARGET_SCHED_DFA_POST_ADVANCE_CYCLE): Redefine.
	(m68k_sched_attr_type2): New function.
	(sched_adjust_cost_state): New static variable.
	(m68k_sched_adjust_cost): New static function implementing
	scheduler hook.
	(sched_ib_size, sched_ib_filled, sched_ib_insn, sched_mem_unit_code):
	New static variables.
	(m68k_sched_variable_issue): New static function implementing
	scheduler hook.
	(sched_dump_class_def, sched_dump_class_func_t): New typedefs.
	(sched_dump_split_class): New static function.
	(sched_dump_dfa_guess_unit_code, sched_dump_dfa_state): New static
	variables.
	(sched_dump_dfa_class, m68k_sched_dump): New static function.
	(m68k_sched_md_init_global, m68k_sched_md_finish_global,
	m68k_sched_md_init, m68k_sched_dfa_pre_advance_cycle,
	m68k_sched_dfa_post_advance_cycle): New static functions implementing
	scheduler hooks.

	* config/m68k/m68k.h (m68k_sched_attr_type2): Declare.
	(CPU_UNITS_QUERY): Define.

	* config/m68k/cf.md: New file.
	* config/m68k/m68.md (cf.md): New include.

From-SVN: r129938
parent 38d34676
2007-11-06 Maxim Kuvyrkov <maxim@codesourcery.com>
* config/m68k/m68k.c (sched-int.h, insn-codes.h): New includes.
(TARGET_SCHED_ADJUST_COST, TARGET_SCHED_VARIABLE_ISSUE,
TARGET_SCHED_INIT_GLOBAL, TARGET_SCHED_FINISH_GLOBAL,
TARGET_SCHED_INIT, TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE,
TARGET_SCHED_DFA_POST_ADVANCE_CYCLE): Redefine.
(m68k_sched_attr_type2): New function.
(sched_adjust_cost_state): New static variable.
(m68k_sched_adjust_cost): New static function implementing
scheduler hook.
(sched_ib_size, sched_ib_filled, sched_ib_insn, sched_mem_unit_code):
New static variables.
(m68k_sched_variable_issue): New static function implementing
scheduler hook.
(sched_dump_class_def, sched_dump_class_func_t): New typedefs.
(sched_dump_split_class): New static function.
(sched_dump_dfa_guess_unit_code, sched_dump_dfa_state): New static
variables.
(sched_dump_dfa_class, m68k_sched_dump): New static function.
(m68k_sched_md_init_global, m68k_sched_md_finish_global,
m68k_sched_md_init, m68k_sched_dfa_pre_advance_cycle,
m68k_sched_dfa_post_advance_cycle): New static functions implementing
scheduler hooks.
* config/m68k/m68k.h (m68k_sched_attr_type2): Declare.
(CPU_UNITS_QUERY): Define.
* config/m68k/cf.md: New file.
* config/m68k/m68.md (cf.md): New include.
2007-11-06 Tom Tromey <tromey@redhat.com>
PR c++/32256, PR c++/32368:
;; ColdFire V2 DFA description.
;; Copyright (C) 2007 Free Software Foundation, Inc.
;; Contributed by CodeSourcery Inc.
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;; ??? To let genattrtab live, implement this attribute in C.
(define_attr "type2"
"alu, alu_l, bcc, bra, call, jmp, lea, move, move_l, mul, pea, rts, unlk,
unknown"
(symbol_ref "m68k_sched_attr_type2 (insn)"))
;; Instruction Buffer
(define_automaton "cf_v2_ib")
;; If one of these cpu units is occupied, that means that corresponding
;; word in the buffer is empty.
(define_cpu_unit "cf_v2_ib_w0, cf_v2_ib_w1, cf_v2_ib_w2, cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib")
(final_presence_set "cf_v2_ib_w1, cf_v2_ib_w2, cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w0")
(final_presence_set "cf_v2_ib_w2, cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w1")
(final_presence_set "cf_v2_ib_w3, cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w2")
(final_presence_set "cf_v2_ib_w4, cf_v2_ib_w5" "cf_v2_ib_w3")
(final_presence_set "cf_v2_ib_w5" "cf_v2_ib_w4")
;; Occupy 1 word.
(define_reservation "cf_v2_ib1" "cf_v2_ib_w0|cf_v2_ib_w1|cf_v2_ib_w2|cf_v2_ib_w3|cf_v2_ib_w4|cf_v2_ib_w5")
;; Occupy 2 words.
(define_reservation "cf_v2_ib2" "(cf_v2_ib_w0+cf_v2_ib_w1)|(cf_v2_ib_w1+cf_v2_ib_w2)|(cf_v2_ib_w2+cf_v2_ib_w3)|(cf_v2_ib_w3+cf_v2_ib_w4)|(cf_v2_ib_w4+cf_v2_ib_w5)")
;; Occupy 3 words.
(define_reservation "cf_v2_ib3" "(cf_v2_ib_w0+cf_v2_ib_w1+cf_v2_ib_w2)|(cf_v2_ib_w1+cf_v2_ib_w2+cf_v2_ib_w3)|(cf_v2_ib_w2+cf_v2_ib_w3+cf_v2_ib_w4)|(cf_v2_ib_w3+cf_v2_ib_w4+cf_v2_ib_w5)")
;; Reservation to subscribe 1 word in the instruction buffer. If a given
;; word in the instruction buffer is subscribed, that means it is empty.
;; This reservation is used at the start of each cycle to setup the number
;; of prefetched instruction words in the instruction buffer.
;; At each cycle, given that memory bus is available (i.e. there is no
;; pending memory operation), IFP prefetches two instruction words into IB.
(define_insn_reservation "cf_v2_ib" 0
(and (eq_attr "cpu" "cf_v2")
(eq_attr "type" "ib"))
"cf_v2_ib1")
;; Operand Execution Pipeline
(define_automaton "cf_v2_oep")
(define_cpu_unit "cf_v2_dsoc, cf_v2_agex" "cf_v2_oep")
;; A memory unit that is reffered to as 'certain hardware resources' in
;; ColdFire reference manuals. This unit remains occupied for two cycles
;; after last dsoc cycle of a store - hence there is a 2 cycle delay between
;; two consecutive stores.
(define_automaton "cf_v2_chr")
(define_cpu_unit "cf_v2_chr" "cf_v2_chr")
;; Memory bus
(define_automaton "cf_v2_mem")
;; When memory bus is subscribed, that implies that instruction buffer won't
;; get its portion this cycle. To model that we query if cf_v2_mem unit is
;; subscribed and adjust number of prefetched instruction words accordingly.
;;
(define_query_cpu_unit "cf_v2_mem" "cf_v2_mem")
;; Register to register move.
;; Takes 1 cycle.
(define_reservation "cf_v2_move_00"
"cf_v2_dsoc+cf_v2_agex")
;; Load from a memory location.
;; Takes 3 cycles.
(define_reservation "cf_v2_move_10"
"cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex")
;; Long load from a memory location.
;; Takes 2 cycles.
(define_reservation "cf_v2_move_l_10"
"cf_v2_dsoc+cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex")
;; Load from an indexed location.
;; Takes 4 cycles.
(define_reservation "cf_v2_move_i0"
"cf_v2_dsoc,cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex")
;; Long load from an indexed location.
;; Takes 3 cycles.
(define_reservation "cf_v2_move_l_i0"
"cf_v2_dsoc+cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex")
;; Store to a memory location.
;; Takes 1 cycle.
(define_reservation "cf_v2_move_01"
"cf_v2_dsoc+cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
;; Store to an indexed location.
;; Takes 2 cycle.
(define_reservation "cf_v2_move_0i"
"cf_v2_dsoc+cf_v2_agex,cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
;; Load from a memory location and store to a memory location.
;; Takes 3 cycles
(define_reservation "cf_v2_move_11"
"cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
;; Long load from a memory location and store to a memory location.
;; Takes 2 cycles.
(define_reservation "cf_v2_move_l_11"
"cf_v2_dsoc+cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
;; Load from an indexed location and store to a memory location.
;; Takes 4 cycles.
(define_reservation "cf_v2_move_i1"
"cf_v2_dsoc,cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
;; Long load from an indexed location and store to a memory location.
;; Takes 3 cycles.
(define_reservation "cf_v2_move_l_i1"
"cf_v2_dsoc+cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
;; Load from a memory location and store to an indexed location.
;; Takes 4 cycles.
(define_reservation "cf_v2_move_1i"
"cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem,cf_v2_agex,cf_v2_mem")
;; Long load from a memory location and store to an indexed location.
;; Takes 3 cycles.
(define_reservation "cf_v2_move_l_1i"
"cf_v2_dsoc+cf_v2_agex,cf_v2_dsoc+cf_v2_agex+cf_v2_mem,cf_v2_agex,cf_v2_mem")
;; Lea operation for a memory location.
;; Takes 1 cycle.
(define_reservation "cf_v2_lea_10"
"cf_v2_dsoc+cf_v2_agex")
;; Lea operation for an indexed location.
;; Takes 2 cycles.
(define_reservation "cf_v2_lea_i0"
"cf_v2_dsoc+cf_v2_agex,cf_v2_agex")
;; Pea operation for a memory location.
;; Takes 2 cycle.
(define_reservation "cf_v2_pea_11"
"cf_v2_dsoc+cf_v2_agex,cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
;; Pea operation for an indexed location.
;; Takes 3 cycles.
(define_reservation "cf_v2_pea_i1"
"cf_v2_dsoc+cf_v2_agex,cf_v2_agex,cf_v2_agex+cf_v2_chr,cf_v2_mem+cf_v2_chr,cf_v2_chr")
(define_automaton "cf_v2_emac")
(define_cpu_unit "cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4"
"cf_v2_emac")
;; Mul operation with register operands.
;; Takes 4 cycles.
(define_reservation "cf_v2_mul_00"
"cf_v2_dsoc,cf_v2_agex+cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4")
;; Mul operation with implicit load from a memory location.
;; Takes 6 cycles.
(define_reservation "cf_v2_mul_10"
"cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex+cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4")
;; Mul operation with implicit load from an indexed location.
;; Takes 7 cycles.
(define_reservation "cf_v2_mul_i0"
"cf_v2_dsoc,cf_v2_agex,cf_v2_agex,cf_v2_dsoc+cf_v2_mem,cf_v2_agex+cf_v2_emac1,cf_v2_emac2,cf_v2_emac3,cf_v2_emac4")
;; Instruction reservations.
;; Below reservations are simple derivation from the above reservations.
;; Each reservation from the above expands into 3 reservations below - one
;; for each instruction size.
;; A number in the end of reservation's name is the size of the instruction.
(define_insn_reservation "cf_v2_move_00_1" 1
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu,alu_l,move,move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "00"))
"cf_v2_ib1+cf_v2_move_00")
(define_insn_reservation "cf_v2_move_00_2" 1
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu,alu_l,move,move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "00"))
"cf_v2_ib2+cf_v2_move_00")
(define_insn_reservation "cf_v2_move_00_3" 1
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu,alu_l,move,move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "00"))
"cf_v2_ib3+cf_v2_move_00")
(define_insn_reservation "cf_v2_move_10_1" 4
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "10"))
"cf_v2_ib1+cf_v2_move_10")
(define_insn_reservation "cf_v2_move_10_2" 4
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "10"))
"cf_v2_ib2+cf_v2_move_10")
(define_insn_reservation "cf_v2_move_10_3" 4
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "10"))
"cf_v2_ib3+cf_v2_move_10")
(define_insn_reservation "cf_v2_move_l_10_1" 3
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "10"))
"cf_v2_ib1+cf_v2_move_l_10")
(define_insn_reservation "cf_v2_move_l_10_2" 3
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "10"))
"cf_v2_ib2+cf_v2_move_l_10")
(define_insn_reservation "cf_v2_move_l_10_3" 3
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "10"))
"cf_v2_ib3+cf_v2_move_l_10")
(define_insn_reservation "cf_v2_move_i0_2" 5
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "i0"))
"cf_v2_ib2+cf_v2_move_i0")
(define_insn_reservation "cf_v2_move_i0_3" 5
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "i0"))
"cf_v2_ib3+cf_v2_move_i0")
(define_insn_reservation "cf_v2_move_l_i0_2" 4
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "i0"))
"cf_v2_ib2+cf_v2_move_l_i0")
(define_insn_reservation "cf_v2_move_l_i0_3" 4
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "i0"))
"cf_v2_ib3+cf_v2_move_l_i0")
(define_insn_reservation "cf_v2_move_01_1" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move,move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "01"))
"cf_v2_ib1+cf_v2_move_01")
(define_insn_reservation "cf_v2_move_01_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move,move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "01"))
"cf_v2_ib2+cf_v2_move_01")
(define_insn_reservation "cf_v2_move_01_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move,move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "01"))
"cf_v2_ib3+cf_v2_move_01")
(define_insn_reservation "cf_v2_move_0i_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move,move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "0i"))
"cf_v2_ib2+cf_v2_move_0i")
(define_insn_reservation "cf_v2_move_0i_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move,move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "0i"))
"cf_v2_ib3+cf_v2_move_0i")
(define_insn_reservation "cf_v2_move_11_1" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "11"))
"cf_v2_ib1+cf_v2_move_11")
(define_insn_reservation "cf_v2_move_11_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "11"))
"cf_v2_ib2+cf_v2_move_11")
(define_insn_reservation "cf_v2_move_11_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "11"))
"cf_v2_ib3+cf_v2_move_11")
(define_insn_reservation "cf_v2_move_l_11_1" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "11"))
"cf_v2_ib1+cf_v2_move_l_11")
(define_insn_reservation "cf_v2_move_l_11_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "11"))
"cf_v2_ib2+cf_v2_move_l_11")
(define_insn_reservation "cf_v2_move_l_11_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "11"))
"cf_v2_ib3+cf_v2_move_l_11")
(define_insn_reservation "cf_v2_move_i1_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "i1"))
"cf_v2_ib2+cf_v2_move_i1")
(define_insn_reservation "cf_v2_move_i1_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "i1"))
"cf_v2_ib3+cf_v2_move_i1")
(define_insn_reservation "cf_v2_move_l_i1_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "i1"))
"cf_v2_ib2+cf_v2_move_l_i1")
(define_insn_reservation "cf_v2_move_l_i1_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "i1"))
"cf_v2_ib3+cf_v2_move_l_i1")
(define_insn_reservation "cf_v2_move_1i_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "1i"))
"cf_v2_ib2+cf_v2_move_1i")
(define_insn_reservation "cf_v2_move_1i_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "alu_l,move"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "1i"))
"cf_v2_ib3+cf_v2_move_1i")
(define_insn_reservation "cf_v2_move_l_1i_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "1i"))
"cf_v2_ib2+cf_v2_move_l_1i")
(define_insn_reservation "cf_v2_move_l_1i_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "move_l"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "1i"))
"cf_v2_ib3+cf_v2_move_l_1i")
(define_insn_reservation "cf_v2_lea_10_1" 1
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "lea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "10"))
"cf_v2_ib1+cf_v2_lea_10")
(define_insn_reservation "cf_v2_lea_10_2" 1
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "lea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "10"))
"cf_v2_ib2+cf_v2_lea_10")
(define_insn_reservation "cf_v2_lea_10_3" 1
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "lea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "10"))
"cf_v2_ib3+cf_v2_lea_10")
(define_insn_reservation "cf_v2_lea_i0_2" 2
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "lea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "i0"))
"cf_v2_ib2+cf_v2_lea_i0")
(define_insn_reservation "cf_v2_lea_i0_3" 2
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "lea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "i0"))
"cf_v2_ib3+cf_v2_lea_i0")
(define_insn_reservation "cf_v2_pea_11_1" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "pea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "11"))
"cf_v2_ib1+cf_v2_pea_11")
(define_insn_reservation "cf_v2_pea_11_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "pea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "11"))
"cf_v2_ib2+cf_v2_pea_11")
(define_insn_reservation "cf_v2_pea_11_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "pea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "11"))
"cf_v2_ib3+cf_v2_pea_11")
(define_insn_reservation "cf_v2_pea_i1_2" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "pea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "i1"))
"cf_v2_ib2+cf_v2_pea_i1")
(define_insn_reservation "cf_v2_pea_i1_3" 0
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "pea"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "i1"))
"cf_v2_ib3+cf_v2_pea_i1")
(define_insn_reservation "cf_v2_mul_00_1" 4
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "mul"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "00"))
"cf_v2_ib1+cf_v2_mul_00")
(define_insn_reservation "cf_v2_mul_00_2" 4
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "mul"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "00"))
"cf_v2_ib2+cf_v2_mul_00")
(define_insn_reservation "cf_v2_mul_00_3" 4
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "mul"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "00"))
"cf_v2_ib3+cf_v2_mul_00")
(define_insn_reservation "cf_v2_mul_10_1" 6
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "mul"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
(eq_attr "op_mem" "10"))
"cf_v2_ib1+cf_v2_mul_10")
(define_insn_reservation "cf_v2_mul_10_2" 6
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "mul"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "10"))
"cf_v2_ib2+cf_v2_mul_10")
(define_insn_reservation "cf_v2_mul_10_3" 6
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "mul"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "10"))
"cf_v2_ib3+cf_v2_mul_10")
(define_insn_reservation "cf_v2_mul_i0_2" 7
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "mul"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
(eq_attr "op_mem" "i0"))
"cf_v2_ib2+cf_v2_mul_i0")
(define_insn_reservation "cf_v2_mul_i0_3" 7
(and (and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "mul"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
(eq_attr "op_mem" "i0"))
"cf_v2_ib3+cf_v2_mul_i0")
;; ??? As return reads target address from stack, use a mem-read reservation
;; for it.
(define_reservation "cf_v2_rts" "cf_v2_move_10")
;; ??? It's not clear what the core does during these 5 cycles.
;; Luckily, we don't care that much about an insn that won't be moved.
(define_insn_reservation "cf_v2_rts_1" 5
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "rts"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
"cf_v2_ib1+cf_v2_rts")
;; Call instructions reservations.
;; ??? It's not clear what reservation is best to use for calls.
;; For now we use mem-write + return reservations to reflect the fact of
;; pushing and poping return address to and from the stack.
(define_insn_reservation "cf_v2_call_1" 3
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "call"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
"cf_v2_ib1+cf_v2_move_10,cf_v2_rts")
(define_insn_reservation "cf_v2_call_2" 3
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "call"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
"cf_v2_ib2+cf_v2_move_10,cf_v2_rts")
(define_insn_reservation "cf_v2_call_3" 3
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "call"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
"cf_v2_ib3+cf_v2_move_10,cf_v2_rts")
;; Branch reservations.
;; ??? Branch reservations are unclear to me so far. Luckily, we don't care
;; ??? that much about branches.
(define_reservation "cf_v2_bcc" "cf_v2_move_00")
(define_insn_reservation "cf_v2_bcc_1" 2
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "bcc"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
"cf_v2_ib1+cf_v2_bcc")
(define_insn_reservation "cf_v2_bcc_2" 2
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "bcc"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
"cf_v2_ib2+cf_v2_bcc")
(define_insn_reservation "cf_v2_bcc_3" 2
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "bcc"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
"cf_v2_ib3+cf_v2_bcc")
(define_reservation "cf_v2_bra" "cf_v2_move_01")
(define_insn_reservation "cf_v2_bra_1" 2
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "bra"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
"cf_v2_ib1+cf_v2_bra")
(define_insn_reservation "cf_v2_bra_2" 2
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "bra"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
"cf_v2_ib2+cf_v2_bra")
(define_insn_reservation "cf_v2_bra_3" 2
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "bra"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
"cf_v2_ib3+cf_v2_bra")
;; Computed jump.
;; Takes 3 cycles.
(define_reservation "cf_v2_jmp"
"cf_v2_dsoc,cf_v2_agex,cf_v2_dsoc,cf_v2_agex")
(define_insn_reservation "cf_v2_jmp_1" 3
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "jmp"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
"cf_v2_ib1+cf_v2_jmp")
(define_insn_reservation "cf_v2_jmp_2" 3
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "jmp"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
"cf_v2_ib2+cf_v2_jmp")
(define_insn_reservation "cf_v2_jmp_3" 3
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "jmp"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
"cf_v2_ib3+cf_v2_jmp")
;; Misc reservations.
(define_insn_reservation "cf_v2_unlk_1" 2
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "type2" "unlk"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
"cf_v2_ib1+cf_v2_move_l_10")
;; This automaton is used to gather statistics on insns that need reservations.
(define_automaton "cf_v2_guess")
(define_query_cpu_unit "cf_v2_guess" "cf_v2_guess")
;; Dummy reservation for instructions that are not handled yet.
(define_insn_reservation "cf_v2_guess_1" 1
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "guess" "yes"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 1)))
"cf_v2_ib1+cf_v2_guess+cf_v2_dsoc+cf_v2_agex")
(define_insn_reservation "cf_v2_guess_2" 1
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "guess" "yes"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 2)))
"cf_v2_ib2+cf_v2_guess+cf_v2_dsoc+cf_v2_agex")
(define_insn_reservation "cf_v2_guess_3" 1
(and (and (eq_attr "cpu" "cf_v2")
(eq_attr "guess" "yes"))
(eq (symbol_ref "get_attr_size (insn)") (const_int 3)))
"cf_v2_ib3+cf_v2_guess+cf_v2_dsoc+cf_v2_agex")
......@@ -73,6 +73,7 @@ extern enum attr_opy_type m68k_sched_attr_opy_type (rtx, int);
extern int m68k_sched_attr_size (rtx);
extern enum attr_op_mem m68k_sched_attr_op_mem (rtx);
extern enum attr_type m68k_sched_branch_type (rtx);
extern enum attr_type2 m68k_sched_attr_type2 (rtx);
#endif /* HAVE_ATTR_cpu */
#endif /* RTX_CODE */
......
......@@ -43,6 +43,9 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h"
#include "flags.h"
#include "df.h"
/* ??? Need to add a dependency between m68k.o and sched-int.h. */
#include "sched-int.h"
#include "insn-codes.h"
enum reg_class regno_reg_class[] =
{
......@@ -118,6 +121,14 @@ struct m68k_address {
int scale;
};
static int m68k_sched_adjust_cost (rtx, rtx, rtx, int);
static int m68k_sched_variable_issue (FILE *, int, rtx, int);
static void m68k_sched_md_init_global (FILE *, int, int);
static void m68k_sched_md_finish_global (FILE *, int);
static void m68k_sched_md_init (FILE *, int, int);
static void m68k_sched_dfa_pre_advance_cycle (void);
static void m68k_sched_dfa_post_advance_cycle (void);
static bool m68k_handle_option (size_t, const char *, int);
static rtx find_addr_reg (rtx);
static const char *singlemove_string (rtx *);
......@@ -185,6 +196,27 @@ int m68k_last_compare_had_fp_operands;
#undef TARGET_ASM_FILE_START_APP_OFF
#define TARGET_ASM_FILE_START_APP_OFF true
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST m68k_sched_adjust_cost
#undef TARGET_SCHED_VARIABLE_ISSUE
#define TARGET_SCHED_VARIABLE_ISSUE m68k_sched_variable_issue
#undef TARGET_SCHED_INIT_GLOBAL
#define TARGET_SCHED_INIT_GLOBAL m68k_sched_md_init_global
#undef TARGET_SCHED_FINISH_GLOBAL
#define TARGET_SCHED_FINISH_GLOBAL m68k_sched_md_finish_global
#undef TARGET_SCHED_INIT
#define TARGET_SCHED_INIT m68k_sched_md_init
#undef TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE
#define TARGET_SCHED_DFA_PRE_ADVANCE_CYCLE m68k_sched_dfa_pre_advance_cycle
#undef TARGET_SCHED_DFA_POST_ADVANCE_CYCLE
#define TARGET_SCHED_DFA_POST_ADVANCE_CYCLE m68k_sched_dfa_post_advance_cycle
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION m68k_handle_option
......@@ -4971,3 +5003,451 @@ m68k_sched_branch_type (rtx insn)
return type;
}
/* Implement type2 attribute. */
enum attr_type2
m68k_sched_attr_type2 (rtx insn)
{
switch (get_attr_type1 (insn))
{
case TYPE1_ALU_REG1:
case TYPE1_ALU_REGX:
return TYPE2_ALU;
case TYPE1_ALU_L:
case TYPE1_ALUQ_L:
case TYPE1_CMP_L:
return TYPE2_ALU_L;
case TYPE1_BCC:
return TYPE2_BCC;
case TYPE1_BRA:
return TYPE2_BRA;
case TYPE1_BSR:
case TYPE1_JSR:
return TYPE2_CALL;
case TYPE1_JMP:
return TYPE2_JMP;
case TYPE1_LEA:
return TYPE2_LEA;
case TYPE1_CLR:
case TYPE1_MOV3Q_L:
case TYPE1_MOVE:
case TYPE1_MOVEQ_L:
case TYPE1_TST:
return TYPE2_MOVE;
case TYPE1_MOVE_L:
case TYPE1_TST_L:
return TYPE2_MOVE_L;
case TYPE1_MUL_W:
case TYPE1_MUL_L:
return TYPE2_MUL;
case TYPE1_PEA:
return TYPE2_PEA;
case TYPE1_RTS:
return TYPE2_RTS;
case TYPE1_UNLK:
return TYPE2_UNLK;
default:
gcc_assert (get_attr_guess (insn) == GUESS_YES);
return TYPE2_UNKNOWN;
}
}
/* An empty state that is used in m68k_sched_adjust_cost. */
static state_t sched_adjust_cost_state;
/* Implement adjust_cost scheduler hook.
Return adjusted COST of dependency LINK between DEF_INSN and INSN. */
static int
m68k_sched_adjust_cost (rtx insn, rtx link ATTRIBUTE_UNUSED, rtx def_insn,
int cost)
{
int delay;
if (recog_memoized (def_insn) < 0
|| recog_memoized (insn) < 0)
return cost;
/* Don't try to issue INSN earlier than DFA permits.
This is especially useful for instructions that write to memory,
as their true dependence (default) latency is better to be set to 0
to workaround alias analysis limitations.
This is, in fact, a machine independent tweak, so, probably,
it should be moved to haifa-sched.c: insn_cost (). */
delay = min_insn_conflict_delay (sched_adjust_cost_state, def_insn, insn);
if (delay > cost)
cost = delay;
return cost;
}
/* Size of the instruction buffer in words. */
static int sched_ib_size;
/* Number of filled words in the instruction buffer. */
static int sched_ib_filled;
/* An insn that reserves (marks empty) one word in the instruction buffer. */
static rtx sched_ib_insn;
/* ID of memory unit. */
static int sched_mem_unit_code;
/* Implementation of the targetm.sched.variable_issue () hook.
It is called after INSN was issued. It returns the number of insns
that can possibly get scheduled on the current cycle.
It is used here to determine the effect of INSN on the instruction
buffer. */
static int
m68k_sched_variable_issue (FILE *sched_dump ATTRIBUTE_UNUSED,
int sched_verbose ATTRIBUTE_UNUSED,
rtx insn, int can_issue_more)
{
int insn_size;
if (recog_memoized (insn) >= 0)
{
insn_size = get_attr_size (insn);
gcc_assert (insn_size <= sched_ib_filled);
--can_issue_more;
}
else if (GET_CODE (PATTERN (insn)) == ASM_INPUT
|| asm_noperands (PATTERN (insn)) >= 0)
insn_size = sched_ib_filled;
else
insn_size = 0;
sched_ib_filled -= insn_size;
return can_issue_more;
}
/* Statistics gatherer. */
typedef enum
{
/* Something needs to be done for this insn. */
SCHED_DUMP_TODO,
/* Support for this insn is complete. */
SCHED_DUMP_DONE,
/* This insn didn't require much effort to support it. */
SCHED_DUMP_NOTHING
} sched_dump_class_def;
/* Pointer to functions that classifies insns into 3 above classes. */
typedef sched_dump_class_def (*sched_dump_class_func_t) (rtx);
/* Return statistical type of INSN regarding splits. */
static sched_dump_class_def
sched_dump_split_class (rtx insn)
{
int i;
i = recog_memoized (insn);
gcc_assert (i >= 0);
switch (get_attr_split (insn))
{
case SPLIT_TODO:
return SCHED_DUMP_TODO;
case SPLIT_DONE:
return SCHED_DUMP_DONE;
case SPLIT_NOTHING:
return SCHED_DUMP_NOTHING;
default:
gcc_unreachable ();
}
}
/* ID of the guess unit. */
static int sched_dump_dfa_guess_unit_code;
/* DFA state for use in sched_dump_dfa_class (). */
static state_t sched_dump_dfa_state;
/* Return statistical type of INSN regarding DFA reservations. */
static sched_dump_class_def
sched_dump_dfa_class (rtx insn)
{
int i;
i = recog_memoized (insn);
gcc_assert (i >= 0 && insn_has_dfa_reservation_p (insn));
if (sched_dump_split_class (insn) == SCHED_DUMP_TODO)
/* Insn is not yet ready for reservations. */
return SCHED_DUMP_NOTHING;
state_reset (sched_dump_dfa_state);
if (state_transition (sched_dump_dfa_state, insn) >= 0)
gcc_unreachable ();
if (cpu_unit_reservation_p (sched_dump_dfa_state,
sched_dump_dfa_guess_unit_code))
return SCHED_DUMP_TODO;
return SCHED_DUMP_DONE;
}
/* Dump statistics on current function into file DUMP_FILENAME and prefix
each entry with PREFIX.
Instructions are classified with DUMP_CLASS. */
static void
m68k_sched_dump (sched_dump_class_func_t dump_class,
const char *prefix, FILE *dump)
{
sbitmap present;
int *todos;
int *dones;
int *nothings;
rtx insn;
gcc_assert (dump != NULL);
present = sbitmap_alloc (CODE_FOR_nothing);
sbitmap_zero (present);
todos = xcalloc (CODE_FOR_nothing, sizeof (*todos));
dones = xcalloc (CODE_FOR_nothing, sizeof (*dones));
nothings = xcalloc (CODE_FOR_nothing, sizeof (*nothings));
/* Gather statistics. */
for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
{
if (INSN_P (insn) && recog_memoized (insn) >= 0)
{
enum insn_code code;
code = INSN_CODE (insn);
gcc_assert (code < CODE_FOR_nothing);
SET_BIT (present, code);
switch (dump_class (insn))
{
case SCHED_DUMP_TODO:
++todos[code];
break;
case SCHED_DUMP_DONE:
++dones[code];
break;
case SCHED_DUMP_NOTHING:
++nothings[code];
break;
}
}
}
/* Print statisctics. */
{
unsigned int i;
sbitmap_iterator si;
int total_todo;
int total_done;
int total_nothing;
total_todo = 0;
total_done = 0;
total_nothing = 0;
EXECUTE_IF_SET_IN_SBITMAP (present, 0, i, si)
{
int todo;
int done;
int nothing;
enum insn_code code;
code = (enum insn_code) i;
todo = todos[code];
done = dones[code];
nothing = nothings[code];
total_todo += todo;
total_done += done;
total_nothing += nothing;
if (todo != 0)
{
fprintf (dump,
"%s: %3d: %d / %d / %d ;",
prefix, code, todo, done, nothing);
{
const char *name;
name = get_insn_name (code);
if (name != NULL)
fprintf (dump, " {%s}\n", name);
else
fprintf (dump, " {unknown}\n");
}
}
}
gcc_assert (CODE_FOR_nothing < 999);
fprintf (dump,
"%s: 999: %d / %d / %d ; {total}\n",
prefix, total_todo, total_done, total_nothing);
}
free (nothings);
nothings = NULL;
free (dones);
dones = NULL;
free (todos);
todos = NULL;
sbitmap_free (present);
present = NULL;
}
/* Implementation of targetm.sched.md_init_global () hook.
It is invoked once per scheduling pass and is used here
to initialize scheduler constants. */
static void
m68k_sched_md_init_global (FILE *sched_dump ATTRIBUTE_UNUSED,
int sched_verbose ATTRIBUTE_UNUSED,
int n_insns ATTRIBUTE_UNUSED)
{
/* Init branch types. */
{
rtx insn;
sched_branch_type = xcalloc (get_max_uid () + 1,
sizeof (*sched_branch_type));
for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
{
if (JUMP_P (insn))
/* !!! FIXME: Implement real scan here. */
sched_branch_type[INSN_UID (insn)] = TYPE_BCC;
}
}
if (reload_completed && sched_verbose >= 8)
/* Dump statistics. */
{
m68k_sched_dump (sched_dump_split_class, "m68k_sched_split",
sched_dump);
sched_dump_dfa_guess_unit_code = get_cpu_unit_code ("cf_v2_guess");
sched_dump_dfa_state = alloca (state_size ());
m68k_sched_dump (sched_dump_dfa_class, "m68k_sched_dfa",
sched_dump);
sched_dump_dfa_state = NULL;
sched_dump_dfa_guess_unit_code = 0;
}
/* Setup target cpu. */
switch (m68k_sched_cpu)
{
case CPU_CF_V2:
sched_ib_size = 6;
sched_mem_unit_code = get_cpu_unit_code ("cf_v2_mem");
break;
default:
gcc_unreachable ();
}
sched_adjust_cost_state = xmalloc (state_size ());
state_reset (sched_adjust_cost_state);
start_sequence ();
emit_insn (gen_ib ());
sched_ib_insn = get_insns ();
end_sequence ();
}
/* Scheduling pass is now finished. Free/reset static variables. */
static void
m68k_sched_md_finish_global (FILE *dump ATTRIBUTE_UNUSED,
int verbose ATTRIBUTE_UNUSED)
{
sched_ib_insn = NULL;
free (sched_adjust_cost_state);
sched_adjust_cost_state = NULL;
sched_mem_unit_code = 0;
sched_ib_size = 0;
free (sched_branch_type);
sched_branch_type = NULL;
}
/* Implementation of targetm.sched.md_init () hook.
It is invoked each time scheduler starts on the new block (basic block or
extended basic block). */
static void
m68k_sched_md_init (FILE *sched_dump ATTRIBUTE_UNUSED,
int sched_verbose ATTRIBUTE_UNUSED,
int n_insns ATTRIBUTE_UNUSED)
{
/* haifa-sched.c: schedule_block () calls advance_cycle () just before
the first cycle. Workaround that. */
sched_ib_filled = -2;
}
/* Implementation of targetm.sched.dfa_pre_advance_cycle () hook.
It is invoked just before current cycle finishes and is used here
to track if instruction buffer got its two words this cycle. */
static void
m68k_sched_dfa_pre_advance_cycle (void)
{
if (!cpu_unit_reservation_p (curr_state, sched_mem_unit_code))
{
sched_ib_filled += 2;
if (sched_ib_filled > sched_ib_size)
sched_ib_filled = sched_ib_size;
}
}
/* Implementation of targetm.sched.dfa_post_advance_cycle () hook.
It is invoked just after new cycle begins and is used here
to setup number of filled words in the instruction buffer so that
instructions which won't have all their words prefetched would be
stalled for a cycle. */
static void
m68k_sched_dfa_post_advance_cycle (void)
{
int i;
int n;
/* Setup number of prefetched instruction words in the instruction
buffer. */
for (i = sched_ib_filled, n = sched_ib_size; i < n; ++i)
{
if (state_transition (curr_state, sched_ib_insn) >= 0)
gcc_unreachable ();
}
}
......@@ -1148,3 +1148,4 @@ extern M68K_CONST_METHOD m68k_const_method (HOST_WIDE_INT);
extern void m68k_emit_move_double (rtx [2]);
#define CPU_UNITS_QUERY 1
......@@ -7729,3 +7729,5 @@
""
"#"
[(set_attr "type" "ib")])
(include "cf.md")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment