163d1a8abSmrg;; GCC machine description for Matsushita MN10300 2*ec02198aSmrg;; Copyright (C) 1996-2020 Free Software Foundation, Inc. 363d1a8abSmrg;; Contributed by Jeff Law (law@cygnus.com). 463d1a8abSmrg 563d1a8abSmrg;; This file is part of GCC. 663d1a8abSmrg 763d1a8abSmrg;; GCC is free software; you can redistribute it and/or modify 863d1a8abSmrg;; it under the terms of the GNU General Public License as published by 963d1a8abSmrg;; the Free Software Foundation; either version 3, or (at your option) 1063d1a8abSmrg;; any later version. 1163d1a8abSmrg 1263d1a8abSmrg;; GCC is distributed in the hope that it will be useful, 1363d1a8abSmrg;; but WITHOUT ANY WARRANTY; without even the implied warranty of 1463d1a8abSmrg;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1563d1a8abSmrg;; GNU General Public License for more details. 1663d1a8abSmrg 1763d1a8abSmrg;; You should have received a copy of the GNU General Public License 1863d1a8abSmrg;; along with GCC; see the file COPYING3. If not see 1963d1a8abSmrg;; <http://www.gnu.org/licenses/>. 2063d1a8abSmrg 2163d1a8abSmrg;; The original PO technology requires these to be ordered by speed, 2263d1a8abSmrg;; so that assigner will pick the fastest. 2363d1a8abSmrg 2463d1a8abSmrg;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 2563d1a8abSmrg 2663d1a8abSmrg(define_constants [ 2763d1a8abSmrg (PIC_REG 6) 2863d1a8abSmrg (SP_REG 9) 2963d1a8abSmrg (MDR_REG 50) 3063d1a8abSmrg (CC_REG 51) 3163d1a8abSmrg 3263d1a8abSmrg (UNSPEC_PIC 1) 3363d1a8abSmrg (UNSPEC_GOT 2) 3463d1a8abSmrg (UNSPEC_GOTOFF 3) 3563d1a8abSmrg (UNSPEC_PLT 4) 3663d1a8abSmrg (UNSPEC_GOTSYM_OFF 5) 3763d1a8abSmrg 3863d1a8abSmrg (UNSPEC_EXT 6) 3963d1a8abSmrg (UNSPEC_BSCH 7) 4063d1a8abSmrg 4163d1a8abSmrg ;; This is used to encode LIW patterns. 4263d1a8abSmrg (UNSPEC_LIW 8) 4363d1a8abSmrg ;; This is for the low overhead loop instructions. 4463d1a8abSmrg (UNSPEC_SETLB 9) 4563d1a8abSmrg]) 4663d1a8abSmrg 4763d1a8abSmrg(include "predicates.md") 4863d1a8abSmrg(include "constraints.md") 4963d1a8abSmrg 5063d1a8abSmrg;; Processor type. This attribute must exactly match the processor_type 5163d1a8abSmrg;; enumeration in mn10300.h. 5263d1a8abSmrg(define_attr "cpu" "mn10300,am33,am33_2,am34" 5363d1a8abSmrg (const (symbol_ref "(enum attr_cpu) mn10300_tune_cpu"))) 5463d1a8abSmrg 5563d1a8abSmrg;; Used to control the "enabled" attribute on a per-instruction basis. 5663d1a8abSmrg(define_attr "isa" "base,am33,am33_2,am34" 5763d1a8abSmrg (const_string "base")) 5863d1a8abSmrg 5963d1a8abSmrg(define_attr "enabled" "" 6063d1a8abSmrg (cond [(eq_attr "isa" "base") 6163d1a8abSmrg (const_int 1) 6263d1a8abSmrg 6363d1a8abSmrg (and (eq_attr "isa" "am33") 6463d1a8abSmrg (match_test "TARGET_AM33")) 6563d1a8abSmrg (const_int 1) 6663d1a8abSmrg 6763d1a8abSmrg (and (eq_attr "isa" "am33_2") 6863d1a8abSmrg (match_test "TARGET_AM33_2")) 6963d1a8abSmrg (const_int 1) 7063d1a8abSmrg 7163d1a8abSmrg (and (eq_attr "isa" "am34") 7263d1a8abSmrg (match_test "TARGET_AM34")) 7363d1a8abSmrg (const_int 1) 7463d1a8abSmrg ] 7563d1a8abSmrg (const_int 0)) 7663d1a8abSmrg) 7763d1a8abSmrg 7863d1a8abSmrg(define_mode_iterator INT [QI HI SI]) 7963d1a8abSmrg 8063d1a8abSmrg 8163d1a8abSmrg;; Bundling of smaller insns into a long instruction word (LIW) 8263d1a8abSmrg(define_automaton "liw_bundling") 8363d1a8abSmrg(automata_option "ndfa") 8463d1a8abSmrg 8563d1a8abSmrg(define_cpu_unit "liw_op1_u,liw_op2_u" "liw_bundling") 8663d1a8abSmrg 8763d1a8abSmrg(define_attr "liw" "op1,op2,both,either" 8863d1a8abSmrg (const_string "both")) 8963d1a8abSmrg;; Note: this list must match the one defined for liw_op_names[]. 9063d1a8abSmrg(define_attr "liw_op" "add,cmp,sub,mov,and,or,xor,asr,lsr,asl,none,max" 9163d1a8abSmrg (const_string "none")) 9263d1a8abSmrg 9363d1a8abSmrg(define_insn_reservation "liw_op1" 1 9463d1a8abSmrg (and (ior (eq_attr "cpu" "am33") 9563d1a8abSmrg (eq_attr "cpu" "am33_2") 9663d1a8abSmrg (eq_attr "cpu" "am34")) 9763d1a8abSmrg (eq_attr "liw" "op1")) 9863d1a8abSmrg "liw_op1_u"); 9963d1a8abSmrg(define_insn_reservation "liw_op2" 1 10063d1a8abSmrg (and (ior (eq_attr "cpu" "am33") 10163d1a8abSmrg (eq_attr "cpu" "am33_2") 10263d1a8abSmrg (eq_attr "cpu" "am34")) 10363d1a8abSmrg (eq_attr "liw" "op2")) 10463d1a8abSmrg "liw_op2_u"); 10563d1a8abSmrg(define_insn_reservation "liw_both" 1 10663d1a8abSmrg (and (ior (eq_attr "cpu" "am33") 10763d1a8abSmrg (eq_attr "cpu" "am33_2") 10863d1a8abSmrg (eq_attr "cpu" "am34")) 10963d1a8abSmrg (eq_attr "liw" "both")) 11063d1a8abSmrg "liw_op1_u + liw_op2_u"); 11163d1a8abSmrg(define_insn_reservation "liw_either" 1 11263d1a8abSmrg (and (ior (eq_attr "cpu" "am33") 11363d1a8abSmrg (eq_attr "cpu" "am33_2") 11463d1a8abSmrg (eq_attr "cpu" "am34")) 11563d1a8abSmrg (eq_attr "liw" "either")) 11663d1a8abSmrg "liw_op1_u | liw_op2_u"); 11763d1a8abSmrg 11863d1a8abSmrg;; ---------------------------------------------------------------------- 11963d1a8abSmrg;; Pipeline description. 12063d1a8abSmrg;; ---------------------------------------------------------------------- 12163d1a8abSmrg 12263d1a8abSmrg;; The AM33 only has a single pipeline. It has five stages (fetch, 12363d1a8abSmrg;; decode, execute, memory access, writeback) each of which normally 12463d1a8abSmrg;; takes a single CPU clock cycle. 12563d1a8abSmrg 12663d1a8abSmrg;; The timings attribute consists of two numbers, the first is the 12763d1a8abSmrg;; throughput, which is the number of cycles the instruction takes 12863d1a8abSmrg;; to execute and generate a result. The second is the latency 12963d1a8abSmrg;; which is the effective number of cycles the instruction takes to 13063d1a8abSmrg;; execute if its result is used by the following instruction. The 13163d1a8abSmrg;; latency is always greater than or equal to the throughput. 13263d1a8abSmrg;; These values were taken from the Appendix of the "MN103E Series 13363d1a8abSmrg;; Instruction Manual" and the timings for the AM34. 13463d1a8abSmrg 13563d1a8abSmrg;; Note - it would be nice to use strings rather than integers for 13663d1a8abSmrg;; the possible values of this attribute, so that we can have the 13763d1a8abSmrg;; gcc build mechanism check for values that are not supported by 13863d1a8abSmrg;; the reservations below. But this will not work because the code 13963d1a8abSmrg;; in mn10300_adjust_sched_cost() needs integers not strings. 14063d1a8abSmrg 14163d1a8abSmrg(define_attr "timings" "" (const_int 11)) 14263d1a8abSmrg 14363d1a8abSmrg(define_automaton "pipelining") 14463d1a8abSmrg(define_cpu_unit "throughput" "pipelining") 14563d1a8abSmrg 14663d1a8abSmrg(define_insn_reservation "throughput__1_latency__1" 1 14763d1a8abSmrg (eq_attr "timings" "11") "throughput") 14863d1a8abSmrg(define_insn_reservation "throughput__1_latency__2" 2 14963d1a8abSmrg (eq_attr "timings" "12") "throughput,nothing") 15063d1a8abSmrg(define_insn_reservation "throughput__1_latency__3" 3 15163d1a8abSmrg (eq_attr "timings" "13") "throughput,nothing*2") 15263d1a8abSmrg(define_insn_reservation "throughput__1_latency__4" 4 15363d1a8abSmrg (eq_attr "timings" "14") "throughput,nothing*3") 15463d1a8abSmrg(define_insn_reservation "throughput__2_latency__2" 2 15563d1a8abSmrg (eq_attr "timings" "22") "throughput*2") 15663d1a8abSmrg(define_insn_reservation "throughput__2_latency__3" 3 15763d1a8abSmrg (eq_attr "timings" "23") "throughput*2,nothing") 15863d1a8abSmrg(define_insn_reservation "throughput__2_latency__4" 4 15963d1a8abSmrg (eq_attr "timings" "24") "throughput*2,nothing*2") 16063d1a8abSmrg(define_insn_reservation "throughput__2_latency__5" 5 16163d1a8abSmrg (eq_attr "timings" "25") "throughput*2,nothing*3") 16263d1a8abSmrg(define_insn_reservation "throughput__3_latency__3" 3 16363d1a8abSmrg (eq_attr "timings" "33") "throughput*3") 16463d1a8abSmrg(define_insn_reservation "throughput__3_latency__7" 7 16563d1a8abSmrg (eq_attr "timings" "37") "throughput*3,nothing*4") 16663d1a8abSmrg(define_insn_reservation "throughput__4_latency__4" 4 16763d1a8abSmrg (eq_attr "timings" "44") "throughput*4") 16863d1a8abSmrg(define_insn_reservation "throughput__4_latency__7" 7 16963d1a8abSmrg (eq_attr "timings" "47") "throughput*4,nothing*3") 17063d1a8abSmrg(define_insn_reservation "throughput__4_latency__8" 8 17163d1a8abSmrg (eq_attr "timings" "48") "throughput*4,nothing*4") 17263d1a8abSmrg(define_insn_reservation "throughput__5_latency__5" 5 17363d1a8abSmrg (eq_attr "timings" "55") "throughput*5") 17463d1a8abSmrg(define_insn_reservation "throughput__6_latency__6" 6 17563d1a8abSmrg (eq_attr "timings" "66") "throughput*6") 17663d1a8abSmrg(define_insn_reservation "throughput__7_latency__7" 7 17763d1a8abSmrg (eq_attr "timings" "77") "throughput*7") 17863d1a8abSmrg(define_insn_reservation "throughput__7_latency__8" 8 17963d1a8abSmrg (eq_attr "timings" "78") "throughput*7,nothing") 18063d1a8abSmrg(define_insn_reservation "throughput__8_latency__8" 8 18163d1a8abSmrg (eq_attr "timings" "88") "throughput*8") 18263d1a8abSmrg(define_insn_reservation "throughput__9_latency__9" 9 18363d1a8abSmrg (eq_attr "timings" "99") "throughput*9") 18463d1a8abSmrg(define_insn_reservation "throughput__8_latency_14" 14 18563d1a8abSmrg (eq_attr "timings" "814") "throughput*8,nothing*6") 18663d1a8abSmrg(define_insn_reservation "throughput__9_latency_10" 10 18763d1a8abSmrg (eq_attr "timings" "910") "throughput*9,nothing") 18863d1a8abSmrg(define_insn_reservation "throughput_10_latency_10" 10 18963d1a8abSmrg (eq_attr "timings" "1010") "throughput*10") 19063d1a8abSmrg(define_insn_reservation "throughput_12_latency_16" 16 19163d1a8abSmrg (eq_attr "timings" "1216") "throughput*12,nothing*4") 19263d1a8abSmrg(define_insn_reservation "throughput_13_latency_13" 13 19363d1a8abSmrg (eq_attr "timings" "1313") "throughput*13") 19463d1a8abSmrg(define_insn_reservation "throughput_14_latency_14" 14 19563d1a8abSmrg (eq_attr "timings" "1414") "throughput*14") 19663d1a8abSmrg(define_insn_reservation "throughput_13_latency_17" 17 19763d1a8abSmrg (eq_attr "timings" "1317") "throughput*13,nothing*4") 19863d1a8abSmrg(define_insn_reservation "throughput_23_latency_27" 27 19963d1a8abSmrg (eq_attr "timings" "2327") "throughput*23,nothing*4") 20063d1a8abSmrg(define_insn_reservation "throughput_25_latency_31" 31 20163d1a8abSmrg (eq_attr "timings" "2531") "throughput*25,nothing*6") 20263d1a8abSmrg(define_insn_reservation "throughput_38_latency_39" 39 20363d1a8abSmrg (eq_attr "timings" "3839") "throughput*38,nothing") 20463d1a8abSmrg(define_insn_reservation "throughput_39_latency_40" 40 20563d1a8abSmrg (eq_attr "timings" "3940") "throughput*39,nothing") 20663d1a8abSmrg(define_insn_reservation "throughput_40_latency_40" 40 20763d1a8abSmrg (eq_attr "timings" "4040") "throughput*40") 20863d1a8abSmrg(define_insn_reservation "throughput_41_latency_42" 42 20963d1a8abSmrg (eq_attr "timings" "4142") "throughput*41,nothing") 21063d1a8abSmrg(define_insn_reservation "throughput_42_latency_43" 44 21163d1a8abSmrg (eq_attr "timings" "4243") "throughput*42,nothing") 21263d1a8abSmrg(define_insn_reservation "throughput_43_latency_44" 44 21363d1a8abSmrg (eq_attr "timings" "4344") "throughput*43,nothing") 21463d1a8abSmrg(define_insn_reservation "throughput_45_latency_46" 46 21563d1a8abSmrg (eq_attr "timings" "4546") "throughput*45,nothing") 21663d1a8abSmrg(define_insn_reservation "throughput_47_latency_53" 53 21763d1a8abSmrg (eq_attr "timings" "4753") "throughput*47,nothing*6") 21863d1a8abSmrg 21963d1a8abSmrg;; Note - the conflict between memory load/store instructions 22063d1a8abSmrg;; and floating point instructions described in section 1-7-4 22163d1a8abSmrg;; of Chapter 3 of the MN103E Series Instruction Manual is 22263d1a8abSmrg;; handled by the mn10300_adjust_sched_cost function. 22363d1a8abSmrg 22463d1a8abSmrg;; ---------------------------------------------------------------------- 22563d1a8abSmrg;; MOVE INSTRUCTIONS 22663d1a8abSmrg;; ---------------------------------------------------------------------- 22763d1a8abSmrg 22863d1a8abSmrg;; movqi 22963d1a8abSmrg 23063d1a8abSmrg(define_expand "movqi" 23163d1a8abSmrg [(set (match_operand:QI 0 "nonimmediate_operand") 23263d1a8abSmrg (match_operand:QI 1 "general_operand"))] 23363d1a8abSmrg "" 23463d1a8abSmrg{ 23563d1a8abSmrg /* One of the ops has to be in a register. */ 23663d1a8abSmrg if (!register_operand (operand0, QImode) 23763d1a8abSmrg && !register_operand (operand1, QImode)) 23863d1a8abSmrg operands[1] = force_reg (QImode, operand1); 23963d1a8abSmrg}) 24063d1a8abSmrg 24163d1a8abSmrg(define_insn "*movqi_internal" 24263d1a8abSmrg [(set (match_operand:QI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d") 24363d1a8abSmrg (match_operand:QI 1 "general_operand" " 0,D*r, i,m,D,d,*z"))] 24463d1a8abSmrg "(register_operand (operands[0], QImode) 24563d1a8abSmrg || register_operand (operands[1], QImode))" 24663d1a8abSmrg{ 24763d1a8abSmrg switch (which_alternative) 24863d1a8abSmrg { 24963d1a8abSmrg case 0: 25063d1a8abSmrg return ""; 25163d1a8abSmrg case 1: 25263d1a8abSmrg case 2: 25363d1a8abSmrg case 5: 25463d1a8abSmrg case 6: 25563d1a8abSmrg return "mov %1,%0"; 25663d1a8abSmrg case 3: 25763d1a8abSmrg case 4: 25863d1a8abSmrg return "movbu %1,%0"; 25963d1a8abSmrg default: 26063d1a8abSmrg gcc_unreachable (); 26163d1a8abSmrg } 26263d1a8abSmrg} 26363d1a8abSmrg [(set_attr_alternative "timings" 26463d1a8abSmrg [(const_int 11) 26563d1a8abSmrg (const_int 11) 26663d1a8abSmrg (const_int 11) 26763d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 26863d1a8abSmrg (const_int 13) (const_int 24)) 26963d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 27063d1a8abSmrg (const_int 11) (const_int 22)) 27163d1a8abSmrg (const_int 11) 27263d1a8abSmrg (const_int 11) 27363d1a8abSmrg ])] 27463d1a8abSmrg) 27563d1a8abSmrg 27663d1a8abSmrg;; movhi 27763d1a8abSmrg 27863d1a8abSmrg(define_expand "movhi" 27963d1a8abSmrg [(set (match_operand:HI 0 "nonimmediate_operand") 28063d1a8abSmrg (match_operand:HI 1 "general_operand"))] 28163d1a8abSmrg "" 28263d1a8abSmrg{ 28363d1a8abSmrg /* One of the ops has to be in a register. */ 28463d1a8abSmrg if (!register_operand (operand1, HImode) 28563d1a8abSmrg && !register_operand (operand0, HImode)) 28663d1a8abSmrg operands[1] = force_reg (HImode, operand1); 28763d1a8abSmrg}) 28863d1a8abSmrg 28963d1a8abSmrg(define_insn "*movhi_internal" 29063d1a8abSmrg [(set (match_operand:HI 0 "nonimmediate_operand" "=*r,D*r,D*r,D,m,*z,d") 29163d1a8abSmrg (match_operand:HI 1 "general_operand" " 0, i,D*r,m,D,d,*z"))] 29263d1a8abSmrg "(register_operand (operands[0], HImode) 29363d1a8abSmrg || register_operand (operands[1], HImode))" 29463d1a8abSmrg{ 29563d1a8abSmrg switch (which_alternative) 29663d1a8abSmrg { 29763d1a8abSmrg case 0: 29863d1a8abSmrg return ""; 29963d1a8abSmrg case 1: 30063d1a8abSmrg /* Note that "MOV imm8,An" is already zero-extending, and is 2 bytes. 30163d1a8abSmrg We have "MOV imm16,Dn" at 3 bytes. The only win for the 4 byte 30263d1a8abSmrg movu is for an 8-bit unsigned move into Rn. */ 30363d1a8abSmrg if (TARGET_AM33 30463d1a8abSmrg && CONST_INT_P (operands[1]) 30563d1a8abSmrg && IN_RANGE (INTVAL (operands[1]), 0x80, 0xff) 30663d1a8abSmrg && REGNO_EXTENDED_P (REGNO (operands[0]), 1)) 30763d1a8abSmrg return "movu %1,%0"; 30863d1a8abSmrg /* FALLTHRU */ 30963d1a8abSmrg case 5: 31063d1a8abSmrg case 6: 31163d1a8abSmrg case 2: 31263d1a8abSmrg return "mov %1,%0"; 31363d1a8abSmrg case 3: 31463d1a8abSmrg case 4: 31563d1a8abSmrg return "movhu %1,%0"; 31663d1a8abSmrg default: 31763d1a8abSmrg gcc_unreachable (); 31863d1a8abSmrg } 31963d1a8abSmrg} 32063d1a8abSmrg [(set_attr_alternative "timings" 32163d1a8abSmrg [(const_int 11) 32263d1a8abSmrg (const_int 11) 32363d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 32463d1a8abSmrg (const_int 11) (const_int 22)) 32563d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 32663d1a8abSmrg (const_int 13) (const_int 24)) 32763d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 32863d1a8abSmrg (const_int 11) (const_int 22)) 32963d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 33063d1a8abSmrg (const_int 11) (const_int 22)) 33163d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 33263d1a8abSmrg (const_int 11) (const_int 22)) 33363d1a8abSmrg ])] 33463d1a8abSmrg) 33563d1a8abSmrg 33663d1a8abSmrg;; movsi and helpers 33763d1a8abSmrg 33863d1a8abSmrg;; We use this to handle addition of two values when one operand is the 33963d1a8abSmrg;; stack pointer and the other is a memory reference of some kind. Reload 34063d1a8abSmrg;; does not handle them correctly without this expander. 34163d1a8abSmrg(define_expand "reload_plus_sp_const" 34263d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 34363d1a8abSmrg (match_operand:SI 1 "impossible_plus_operand" "")) 34463d1a8abSmrg (clobber (match_operand:SI 2 "register_operand" "=&A"))] 34563d1a8abSmrg "" 34663d1a8abSmrg{ 34763d1a8abSmrg rtx dest, scratch, other; 34863d1a8abSmrg 34963d1a8abSmrg dest = operands[0]; 35063d1a8abSmrg scratch = operands[2]; 35163d1a8abSmrg 35263d1a8abSmrg other = XEXP (operands[1], 1); 35363d1a8abSmrg if (other == stack_pointer_rtx) 35463d1a8abSmrg other = XEXP (operands[1], 0); 35563d1a8abSmrg 35663d1a8abSmrg if (true_regnum (other) == true_regnum (dest)) 35763d1a8abSmrg { 35863d1a8abSmrg gcc_assert (true_regnum (scratch) != true_regnum (dest)); 35963d1a8abSmrg emit_move_insn (scratch, stack_pointer_rtx); 36063d1a8abSmrg emit_insn (gen_addsi3 (dest, dest, scratch)); 36163d1a8abSmrg } 36263d1a8abSmrg else if (TARGET_AM33 || REGNO_REG_CLASS (true_regnum (dest)) == ADDRESS_REGS) 36363d1a8abSmrg { 36463d1a8abSmrg emit_move_insn (dest, stack_pointer_rtx); 36563d1a8abSmrg if (other == stack_pointer_rtx) 36663d1a8abSmrg emit_insn (gen_addsi3 (dest, dest, dest)); 36763d1a8abSmrg else if (other != const0_rtx) 36863d1a8abSmrg emit_insn (gen_addsi3 (dest, dest, other)); 36963d1a8abSmrg } 37063d1a8abSmrg else 37163d1a8abSmrg { 37263d1a8abSmrg emit_move_insn (scratch, stack_pointer_rtx); 37363d1a8abSmrg if (other == stack_pointer_rtx) 37463d1a8abSmrg { 37563d1a8abSmrg emit_move_insn (dest, scratch); 37663d1a8abSmrg emit_insn (gen_addsi3 (dest, dest, dest)); 37763d1a8abSmrg } 37863d1a8abSmrg else if (other != const0_rtx) 37963d1a8abSmrg { 38063d1a8abSmrg emit_move_insn (dest, other); 38163d1a8abSmrg emit_insn (gen_addsi3 (dest, dest, scratch)); 38263d1a8abSmrg } 38363d1a8abSmrg else 38463d1a8abSmrg emit_move_insn (dest, scratch); 38563d1a8abSmrg } 38663d1a8abSmrg DONE; 38763d1a8abSmrg}) 38863d1a8abSmrg 38963d1a8abSmrg(define_expand "movsi" 39063d1a8abSmrg [(set (match_operand:SI 0 "nonimmediate_operand") 39163d1a8abSmrg (match_operand:SI 1 "general_operand"))] 39263d1a8abSmrg "" 39363d1a8abSmrg{ 39463d1a8abSmrg /* One of the ops has to be in a register. */ 39563d1a8abSmrg if (!register_operand (operand1, SImode) 39663d1a8abSmrg && !register_operand (operand0, SImode)) 39763d1a8abSmrg operands[1] = force_reg (SImode, operand1); 39863d1a8abSmrg if (flag_pic) 39963d1a8abSmrg { 40063d1a8abSmrg rtx temp; 40163d1a8abSmrg if (SYMBOLIC_CONST_P (operands[1])) 40263d1a8abSmrg { 40363d1a8abSmrg if (MEM_P (operands[0])) 40463d1a8abSmrg operands[1] = force_reg (Pmode, operands[1]); 40563d1a8abSmrg else 40663d1a8abSmrg { 40763d1a8abSmrg temp = (!can_create_pseudo_p () 40863d1a8abSmrg ? operands[0] 40963d1a8abSmrg : gen_reg_rtx (Pmode)); 41063d1a8abSmrg operands[1] = mn10300_legitimize_pic_address (operands[1], temp); 41163d1a8abSmrg } 41263d1a8abSmrg } 41363d1a8abSmrg else if (GET_CODE (operands[1]) == CONST 41463d1a8abSmrg && GET_CODE (XEXP (operands[1], 0)) == PLUS 41563d1a8abSmrg && SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0))) 41663d1a8abSmrg { 41763d1a8abSmrg temp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode); 41863d1a8abSmrg temp = mn10300_legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0), 41963d1a8abSmrg temp); 42063d1a8abSmrg operands[1] = expand_binop (SImode, add_optab, temp, 42163d1a8abSmrg XEXP (XEXP (operands[1], 0), 1), 42263d1a8abSmrg (!can_create_pseudo_p () 42363d1a8abSmrg ? temp 42463d1a8abSmrg : gen_reg_rtx (Pmode)), 42563d1a8abSmrg 0, OPTAB_LIB_WIDEN); 42663d1a8abSmrg } 42763d1a8abSmrg } 42863d1a8abSmrg}) 42963d1a8abSmrg 43063d1a8abSmrg(define_insn "*movsi_internal" 43163d1a8abSmrg [(set (match_operand:SI 0 "nonimmediate_operand" 43263d1a8abSmrg "=r,r,r,r,m,r, A,*y,*y,*z,*d") 43363d1a8abSmrg (match_operand:SI 1 "general_operand" 43463d1a8abSmrg " 0,O,i,r,r,m,*y, A, i,*d,*z"))] 43563d1a8abSmrg "register_operand (operands[0], SImode) 43663d1a8abSmrg || register_operand (operands[1], SImode)" 43763d1a8abSmrg{ 43863d1a8abSmrg switch (which_alternative) 43963d1a8abSmrg { 44063d1a8abSmrg case 0: 44163d1a8abSmrg return ""; 44263d1a8abSmrg case 1: /* imm-reg. */ 44363d1a8abSmrg case 2: 44463d1a8abSmrg /* See movhi for a discussion of sizes for 8-bit movu. Note that the 44563d1a8abSmrg 24-bit movu is 6 bytes, which is the same size as the full 32-bit 44663d1a8abSmrg mov form for An and Dn. So again movu is only a win for Rn. */ 44763d1a8abSmrg if (TARGET_AM33 44863d1a8abSmrg && CONST_INT_P (operands[1]) 44963d1a8abSmrg && REGNO_EXTENDED_P (REGNO (operands[0]), 1)) 45063d1a8abSmrg { 45163d1a8abSmrg HOST_WIDE_INT val = INTVAL (operands[1]); 45263d1a8abSmrg if (IN_RANGE (val, 0x80, 0xff) 45363d1a8abSmrg || IN_RANGE (val, 0x800000, 0xffffff)) 45463d1a8abSmrg return "movu %1,%0"; 45563d1a8abSmrg } 45663d1a8abSmrg /* FALLTHRU */ 45763d1a8abSmrg case 3: /* reg-reg */ 45863d1a8abSmrg case 4: /* reg-mem */ 45963d1a8abSmrg case 5: /* mem-reg */ 46063d1a8abSmrg case 6: /* sp-reg */ 46163d1a8abSmrg case 7: /* reg-sp */ 46263d1a8abSmrg case 8: /* imm-sp */ 46363d1a8abSmrg case 9: /* reg-mdr */ 46463d1a8abSmrg case 10: /* mdr-reg */ 46563d1a8abSmrg return "mov %1,%0"; 46663d1a8abSmrg default: 46763d1a8abSmrg gcc_unreachable (); 46863d1a8abSmrg } 46963d1a8abSmrg} 47063d1a8abSmrg [(set_attr "isa" "*,*,*,*,*,*,*,*,am33,*,*") 47163d1a8abSmrg (set_attr "liw" "*,either,*,either,*,*,*,*,*,*,*") 47263d1a8abSmrg (set_attr "liw_op" "mov") 47363d1a8abSmrg (set_attr_alternative "timings" 47463d1a8abSmrg [(const_int 11) 47563d1a8abSmrg (const_int 22) 47663d1a8abSmrg (const_int 22) 47763d1a8abSmrg (const_int 11) 47863d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 47963d1a8abSmrg (const_int 11) (const_int 22)) 48063d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 48163d1a8abSmrg (const_int 13) (const_int 24)) 48263d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 48363d1a8abSmrg (const_int 11) (const_int 22)) 48463d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 48563d1a8abSmrg (const_int 13) (const_int 24)) 48663d1a8abSmrg (const_int 11) 48763d1a8abSmrg (const_int 11) 48863d1a8abSmrg (const_int 11) 48963d1a8abSmrg ])] 49063d1a8abSmrg) 49163d1a8abSmrg 49263d1a8abSmrg(define_expand "movsf" 49363d1a8abSmrg [(set (match_operand:SF 0 "nonimmediate_operand") 49463d1a8abSmrg (match_operand:SF 1 "general_operand"))] 49563d1a8abSmrg "TARGET_AM33_2" 49663d1a8abSmrg{ 49763d1a8abSmrg /* One of the ops has to be in a register. */ 49863d1a8abSmrg if (!register_operand (operand1, SFmode) 49963d1a8abSmrg && !register_operand (operand0, SFmode)) 50063d1a8abSmrg operands[1] = force_reg (SFmode, operand1); 50163d1a8abSmrg}) 50263d1a8abSmrg 50363d1a8abSmrg(define_insn "*movsf_internal" 50463d1a8abSmrg [(set (match_operand:SF 0 "nonimmediate_operand" "=rf,r,f,r,f,r,f,r,m,f,Q,z,d") 50563d1a8abSmrg (match_operand:SF 1 "general_operand" " 0,F,F,r,f,f,r,m,r,Q,f,d,z"))] 50663d1a8abSmrg "TARGET_AM33_2 50763d1a8abSmrg && (register_operand (operands[0], SFmode) 50863d1a8abSmrg || register_operand (operands[1], SFmode))" 50963d1a8abSmrg{ 51063d1a8abSmrg switch (which_alternative) 51163d1a8abSmrg { 51263d1a8abSmrg case 0: 51363d1a8abSmrg return ""; 51463d1a8abSmrg case 1: 51563d1a8abSmrg case 3: 51663d1a8abSmrg case 7: 51763d1a8abSmrg case 8: 51863d1a8abSmrg case 11: 51963d1a8abSmrg case 12: 52063d1a8abSmrg return "mov %1,%0"; 52163d1a8abSmrg case 2: 52263d1a8abSmrg case 4: 52363d1a8abSmrg case 5: 52463d1a8abSmrg case 6: 52563d1a8abSmrg case 9: 52663d1a8abSmrg case 10: 52763d1a8abSmrg return "fmov %1,%0"; 52863d1a8abSmrg default: 52963d1a8abSmrg gcc_unreachable (); 53063d1a8abSmrg } 53163d1a8abSmrg} 53263d1a8abSmrg [(set_attr_alternative "timings" 53363d1a8abSmrg [(const_int 11) 53463d1a8abSmrg (const_int 22) 53563d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 53663d1a8abSmrg (const_int 47) (const_int 25)) 53763d1a8abSmrg (const_int 11) 53863d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 53963d1a8abSmrg (const_int 13) (const_int 14)) 54063d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 54163d1a8abSmrg (const_int 13) (const_int 12)) 54263d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 54363d1a8abSmrg (const_int 13) (const_int 14)) 54463d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 54563d1a8abSmrg (const_int 13) (const_int 24)) 54663d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 54763d1a8abSmrg (const_int 13) (const_int 24)) 54863d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 54963d1a8abSmrg (const_int 13) (const_int 24)) 55063d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 55163d1a8abSmrg (const_int 13) (const_int 24)) 55263d1a8abSmrg (const_int 22) 55363d1a8abSmrg (const_int 22) 55463d1a8abSmrg ])] 55563d1a8abSmrg) 55663d1a8abSmrg 55763d1a8abSmrg;; If the flags register is not live, generate CLR instead of MOV 0. 55863d1a8abSmrg;; For MN103, this is only legal for DATA_REGS; for AM33 this is legal 55963d1a8abSmrg;; but not a win for ADDRESS_REGS. 56063d1a8abSmrg(define_peephole2 56163d1a8abSmrg [(set (match_operand:INT 0 "register_operand" "") (const_int 0))] 56263d1a8abSmrg "peep2_regno_dead_p (0, CC_REG) 56363d1a8abSmrg && (REGNO_DATA_P (REGNO (operands[0]), 1) 56463d1a8abSmrg || REGNO_EXTENDED_P (REGNO (operands[0]), 1))" 56563d1a8abSmrg [(parallel [(set (match_dup 0) (const_int 0)) 56663d1a8abSmrg (clobber (reg:CC CC_REG))])] 56763d1a8abSmrg) 56863d1a8abSmrg 56963d1a8abSmrg(define_insn "*mov<mode>_clr" 57063d1a8abSmrg [(set (match_operand:INT 0 "register_operand" "=D") 57163d1a8abSmrg (const_int 0)) 57263d1a8abSmrg (clobber (reg:CC CC_REG))] 57363d1a8abSmrg "" 57463d1a8abSmrg "clr %0" 57563d1a8abSmrg) 57663d1a8abSmrg 57763d1a8abSmrg;; ---------------------------------------------------------------------- 57863d1a8abSmrg;; ADD INSTRUCTIONS 57963d1a8abSmrg;; ---------------------------------------------------------------------- 58063d1a8abSmrg 58163d1a8abSmrg(define_insn "addsi3" 58263d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r,r,r,!*y,!r") 58363d1a8abSmrg (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0, r") 58463d1a8abSmrg (match_operand:SI 2 "nonmemory_operand" "r,O,i, i, r"))) 58563d1a8abSmrg (clobber (reg:CC CC_REG))] 58663d1a8abSmrg "" 58763d1a8abSmrg { return mn10300_output_add (operands, false); } 58863d1a8abSmrg [(set_attr "timings" "11,11,11,11,22") 58963d1a8abSmrg (set_attr "liw" "either,either,*,*,*") 59063d1a8abSmrg (set_attr "liw_op" "add")] 59163d1a8abSmrg) 59263d1a8abSmrg 59363d1a8abSmrg;; Note that ADD IMM,SP does not set the flags, so omit that here. 59463d1a8abSmrg(define_insn "*addsi3_flags" 595c7a68eb7Smrg [(set (reg CC_REG) 596c7a68eb7Smrg (compare (plus:SI (match_operand:SI 1 "register_operand" "%0, r") 597c7a68eb7Smrg (match_operand:SI 2 "nonmemory_operand" "ri, r")) 598c7a68eb7Smrg (const_int 0))) 599c7a68eb7Smrg (set (match_operand:SI 0 "register_operand" "=r,!r") 600c7a68eb7Smrg (plus:SI (match_dup 1) (match_dup 2)))] 60163d1a8abSmrg "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)" 60263d1a8abSmrg { return mn10300_output_add (operands, true); } 60363d1a8abSmrg [(set_attr "timings" "11,22")] 60463d1a8abSmrg) 60563d1a8abSmrg 60663d1a8abSmrg;; A helper to expand the above, with the CC_MODE filled in. 60763d1a8abSmrg(define_expand "addsi3_flags" 608c7a68eb7Smrg [(parallel [(set (reg:CCZNC CC_REG) 60963d1a8abSmrg (compare:CCZNC (plus:SI (match_dup 1) (match_dup 2)) 610c7a68eb7Smrg (const_int 0))) 611c7a68eb7Smrg (set (match_operand:SI 0 "register_operand") 612c7a68eb7Smrg (plus:SI (match_operand:SI 1 "register_operand") 613c7a68eb7Smrg (match_operand:SI 2 "nonmemory_operand")))])] 61463d1a8abSmrg "" 61563d1a8abSmrg) 61663d1a8abSmrg 61763d1a8abSmrg(define_insn "addc_internal" 61863d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,r,r") 61963d1a8abSmrg (plus:SI 62063d1a8abSmrg (plus:SI 62163d1a8abSmrg (ltu:SI (reg:CC CC_REG) (const_int 0)) 62263d1a8abSmrg (match_operand:SI 1 "register_operand" "%0,0,r")) 62363d1a8abSmrg (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r"))) 62463d1a8abSmrg (clobber (reg:CC CC_REG))] 62563d1a8abSmrg "reload_completed" 62663d1a8abSmrg "@ 62763d1a8abSmrg addc %2,%0 62863d1a8abSmrg addc %2,%0 62963d1a8abSmrg addc %2,%1,%0" 63063d1a8abSmrg [(set_attr "isa" "*,am33,am33")] 63163d1a8abSmrg) 63263d1a8abSmrg 63363d1a8abSmrg(define_expand "adddi3" 63463d1a8abSmrg [(set (match_operand:DI 0 "register_operand" "") 63563d1a8abSmrg (plus:DI (match_operand:DI 1 "register_operand" "") 63663d1a8abSmrg (match_operand:DI 2 "nonmemory_operand" "")))] 63763d1a8abSmrg "" 63863d1a8abSmrg{ 63963d1a8abSmrg rtx op0l, op0h, op1l, op1h, op2l, op2h; 64063d1a8abSmrg 64163d1a8abSmrg op0l = gen_lowpart (SImode, operands[0]); 64263d1a8abSmrg op1l = gen_lowpart (SImode, operands[1]); 64363d1a8abSmrg op2l = gen_lowpart (SImode, operands[2]); 64463d1a8abSmrg op0h = gen_highpart (SImode, operands[0]); 64563d1a8abSmrg op1h = gen_highpart (SImode, operands[1]); 64663d1a8abSmrg op2h = gen_highpart_mode (SImode, DImode, operands[2]); 64763d1a8abSmrg 64863d1a8abSmrg if (!reg_or_am33_const_operand (op2h, SImode)) 64963d1a8abSmrg op2h = force_reg (SImode, op2h); 65063d1a8abSmrg 65163d1a8abSmrg emit_insn (gen_adddi3_internal (op0l, op0h, op1l, op2l, op1h, op2h)); 65263d1a8abSmrg DONE; 65363d1a8abSmrg}) 65463d1a8abSmrg 65563d1a8abSmrg;; Note that reload only supports one commutative operand. Thus we cannot 65663d1a8abSmrg;; auto-swap both the high and low outputs with their matching constraints. 65763d1a8abSmrg;; For MN103, we're strapped for registers but thankfully the alternatives 65863d1a8abSmrg;; are few. For AM33, it becomes much easier to not represent the early 65963d1a8abSmrg;; clobber and 6 permutations of immediate and three-operand adds, but 66063d1a8abSmrg;; instead allocate a scratch register and do the expansion by hand. 66163d1a8abSmrg 66263d1a8abSmrg(define_insn_and_split "adddi3_internal" 66363d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r, r, r") 66463d1a8abSmrg (plus:SI (match_operand:SI 2 "register_operand" "%0, 0, r") 66563d1a8abSmrg (match_operand:SI 3 "nonmemory_operand" "ri,ri,ri"))) 66663d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=D, D, r") 66763d1a8abSmrg (plus:SI 66863d1a8abSmrg (plus:SI 66963d1a8abSmrg (ltu:SI (plus:SI (match_dup 2) (match_dup 3)) (match_dup 2)) 67063d1a8abSmrg (match_operand:SI 4 "register_operand" " 1, D, r")) 67163d1a8abSmrg (match_operand:SI 5 "reg_or_am33_const_operand" " D, 1,ri"))) 67263d1a8abSmrg (clobber (match_scratch:SI 6 "=X, X,&r")) 67363d1a8abSmrg (clobber (reg:CC CC_REG))] 67463d1a8abSmrg "" 67563d1a8abSmrg "#" 67663d1a8abSmrg "reload_completed" 67763d1a8abSmrg [(const_int 0)] 67863d1a8abSmrg{ 67963d1a8abSmrg rtx op0l = operands[0]; 68063d1a8abSmrg rtx op0h = operands[1]; 68163d1a8abSmrg rtx op1l = operands[2]; 68263d1a8abSmrg rtx op2l = operands[3]; 68363d1a8abSmrg rtx op1h = operands[4]; 68463d1a8abSmrg rtx op2h = operands[5]; 68563d1a8abSmrg rtx scratch = operands[6]; 68663d1a8abSmrg rtx x; 68763d1a8abSmrg 68863d1a8abSmrg if (reg_overlap_mentioned_p (op0l, op1h)) 68963d1a8abSmrg { 69063d1a8abSmrg emit_move_insn (scratch, op0l); 69163d1a8abSmrg op1h = scratch; 69263d1a8abSmrg if (reg_overlap_mentioned_p (op0l, op2h)) 69363d1a8abSmrg op2h = scratch; 69463d1a8abSmrg } 69563d1a8abSmrg else if (reg_overlap_mentioned_p (op0l, op2h)) 69663d1a8abSmrg { 69763d1a8abSmrg emit_move_insn (scratch, op0l); 69863d1a8abSmrg op2h = scratch; 69963d1a8abSmrg } 70063d1a8abSmrg 70163d1a8abSmrg if (rtx_equal_p (op0l, op1l)) 70263d1a8abSmrg ; 70363d1a8abSmrg else if (rtx_equal_p (op0l, op2l)) 70463d1a8abSmrg x = op1l, op1l = op2l, op2l = x; 70563d1a8abSmrg else 70663d1a8abSmrg { 70763d1a8abSmrg gcc_assert (TARGET_AM33); 70863d1a8abSmrg if (!REG_P (op2l)) 70963d1a8abSmrg { 71063d1a8abSmrg emit_move_insn (op0l, op2l); 71163d1a8abSmrg op2l = op1l; 71263d1a8abSmrg op1l = op0l; 71363d1a8abSmrg } 71463d1a8abSmrg } 71563d1a8abSmrg emit_insn (gen_addsi3_flags (op0l, op1l, op2l)); 71663d1a8abSmrg 71763d1a8abSmrg if (rtx_equal_p (op0h, op1h)) 71863d1a8abSmrg ; 71963d1a8abSmrg else if (rtx_equal_p (op0h, op2h)) 72063d1a8abSmrg x = op1h, op1h = op2h, op2h = x; 72163d1a8abSmrg else 72263d1a8abSmrg { 72363d1a8abSmrg gcc_assert (TARGET_AM33); 72463d1a8abSmrg if (!REG_P (op2h)) 72563d1a8abSmrg { 72663d1a8abSmrg emit_move_insn (op0h, op2h); 72763d1a8abSmrg op2h = op1h; 72863d1a8abSmrg op1h = op0h; 72963d1a8abSmrg } 73063d1a8abSmrg } 73163d1a8abSmrg emit_insn (gen_addc_internal (op0h, op1h, op2h)); 73263d1a8abSmrg DONE; 73363d1a8abSmrg} 73463d1a8abSmrg [(set_attr "isa" "*,*,am33")] 73563d1a8abSmrg) 73663d1a8abSmrg 73763d1a8abSmrg;; The following pattern is generated by combine when it proves that one 73863d1a8abSmrg;; of the inputs to the low-part of the double-word add is zero, and thus 73963d1a8abSmrg;; no carry is generated into the high-part. 74063d1a8abSmrg 74163d1a8abSmrg(define_insn_and_split "*adddi3_degenerate" 74263d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=&r,&r") 74363d1a8abSmrg (match_operand:SI 2 "nonmemory_operand" " 0, 0")) 74463d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=r , r") 74563d1a8abSmrg (plus:SI (match_operand:SI 3 "register_operand" "%1 , r") 74663d1a8abSmrg (match_operand:SI 4 "nonmemory_operand" "ri, r"))) 74763d1a8abSmrg (clobber (reg:CC CC_REG))] 74863d1a8abSmrg "" 74963d1a8abSmrg "#" 75063d1a8abSmrg "" 75163d1a8abSmrg [(const_int 0)] 75263d1a8abSmrg{ 75363d1a8abSmrg rtx scratch = NULL_RTX; 75463d1a8abSmrg if (!rtx_equal_p (operands[0], operands[2])) 75563d1a8abSmrg { 75663d1a8abSmrg if (reg_overlap_mentioned_p (operands[0], operands[3]) 75763d1a8abSmrg || reg_overlap_mentioned_p (operands[0], operands[4])) 75863d1a8abSmrg { 75963d1a8abSmrg scratch = gen_reg_rtx (SImode); 76063d1a8abSmrg emit_move_insn (scratch, operands[2]); 76163d1a8abSmrg } 76263d1a8abSmrg else 76363d1a8abSmrg emit_move_insn (operands[0], operands[2]); 76463d1a8abSmrg } 76563d1a8abSmrg emit_insn (gen_addsi3 (operands[1], operands[3], operands[4])); 76663d1a8abSmrg if (scratch) 76763d1a8abSmrg emit_move_insn (operands[0], scratch); 76863d1a8abSmrg DONE; 76963d1a8abSmrg}) 77063d1a8abSmrg 77163d1a8abSmrg;; ---------------------------------------------------------------------- 77263d1a8abSmrg;; SUBTRACT INSTRUCTIONS 77363d1a8abSmrg;; ---------------------------------------------------------------------- 77463d1a8abSmrg 77563d1a8abSmrg(define_insn "subsi3" 77663d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 77763d1a8abSmrg (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r") 77863d1a8abSmrg (match_operand:SI 2 "nonmemory_operand" "r,O,i,r"))) 77963d1a8abSmrg (clobber (reg:CC CC_REG))] 78063d1a8abSmrg "" 78163d1a8abSmrg "@ 78263d1a8abSmrg sub %2,%0 78363d1a8abSmrg sub %2,%0 78463d1a8abSmrg sub %2,%0 78563d1a8abSmrg sub %2,%1,%0" 78663d1a8abSmrg [(set_attr "isa" "*,*,*,am33") 78763d1a8abSmrg (set_attr "liw" "either,either,*,*") 78863d1a8abSmrg (set_attr "liw_op" "sub") 78963d1a8abSmrg (set_attr "timings" "11,11,11,22")] 79063d1a8abSmrg) 79163d1a8abSmrg 79263d1a8abSmrg(define_insn "*subsi3_flags" 793c7a68eb7Smrg [(set (reg CC_REG) 794c7a68eb7Smrg (compare (minus:SI (match_operand:SI 1 "register_operand" "0, r") 795c7a68eb7Smrg (match_operand:SI 2 "nonmemory_operand" "ri,r")) 796c7a68eb7Smrg (const_int 0))) 797c7a68eb7Smrg (set (match_operand:SI 0 "register_operand" "=r, r") 798c7a68eb7Smrg (minus:SI (match_dup 1) (match_dup 2)))] 79963d1a8abSmrg "reload_completed && mn10300_match_ccmode (insn, CCZNCmode)" 80063d1a8abSmrg "@ 80163d1a8abSmrg sub %2,%0 80263d1a8abSmrg sub %2,%1,%0" 80363d1a8abSmrg [(set_attr "isa" "*,am33") 80463d1a8abSmrg (set_attr "timings" "11,22")] 80563d1a8abSmrg) 80663d1a8abSmrg 80763d1a8abSmrg;; A helper to expand the above, with the CC_MODE filled in. 80863d1a8abSmrg(define_expand "subsi3_flags" 809c7a68eb7Smrg [(parallel [(set (reg:CCZNC CC_REG) 81063d1a8abSmrg (compare:CCZNC (minus:SI (match_dup 1) (match_dup 2)) 811c7a68eb7Smrg (const_int 0))) 812c7a68eb7Smrg (set (match_operand:SI 0 "register_operand") 813c7a68eb7Smrg (minus:SI (match_operand:SI 1 "register_operand") 814c7a68eb7Smrg (match_operand:SI 2 "nonmemory_operand")))])] 81563d1a8abSmrg "" 81663d1a8abSmrg) 81763d1a8abSmrg 81863d1a8abSmrg(define_insn "subc_internal" 81963d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,r,r") 82063d1a8abSmrg (minus:SI 82163d1a8abSmrg (minus:SI (match_operand:SI 1 "register_operand" " 0,0,r") 82263d1a8abSmrg (match_operand:SI 2 "reg_or_am33_const_operand" " D,i,r")) 82363d1a8abSmrg (geu:SI (reg:CC CC_REG) (const_int 0)))) 82463d1a8abSmrg (clobber (reg:CC CC_REG))] 82563d1a8abSmrg "reload_completed" 82663d1a8abSmrg "@ 82763d1a8abSmrg subc %2,%0 82863d1a8abSmrg subc %2,%0 82963d1a8abSmrg subc %2,%1,%0" 83063d1a8abSmrg [(set_attr "isa" "*,am33,am33")] 83163d1a8abSmrg) 83263d1a8abSmrg 83363d1a8abSmrg(define_expand "subdi3" 83463d1a8abSmrg [(set (match_operand:DI 0 "register_operand" "") 83563d1a8abSmrg (minus:DI (match_operand:DI 1 "register_operand" "") 83663d1a8abSmrg (match_operand:DI 2 "nonmemory_operand" "")))] 83763d1a8abSmrg "" 83863d1a8abSmrg{ 83963d1a8abSmrg rtx op0l, op0h, op1l, op1h, op2l, op2h; 84063d1a8abSmrg 84163d1a8abSmrg op0l = gen_lowpart (SImode, operands[0]); 84263d1a8abSmrg op1l = gen_lowpart (SImode, operands[1]); 84363d1a8abSmrg op2l = gen_lowpart (SImode, operands[2]); 84463d1a8abSmrg op0h = gen_highpart (SImode, operands[0]); 84563d1a8abSmrg op1h = gen_highpart (SImode, operands[1]); 84663d1a8abSmrg op2h = gen_highpart_mode (SImode, DImode, operands[2]); 84763d1a8abSmrg 84863d1a8abSmrg if (!reg_or_am33_const_operand (op2h, SImode)) 84963d1a8abSmrg op2h = force_reg (SImode, op2h); 85063d1a8abSmrg 85163d1a8abSmrg emit_insn (gen_subdi3_internal (op0l, op0h, op1l, op1h, op2l, op2h)); 85263d1a8abSmrg DONE; 85363d1a8abSmrg}) 85463d1a8abSmrg 85563d1a8abSmrg;; As with adddi3, the use of the scratch register helps reduce the 85663d1a8abSmrg;; number of permutations for AM33. 85763d1a8abSmrg;; ??? The early clobber on op0 avoids a reload bug wherein both output 85863d1a8abSmrg;; registers are set the same. Consider negate, where both op2 and op3 85963d1a8abSmrg;; are 0, are csed to the same input register, and reload fails to undo 86063d1a8abSmrg;; the cse when satisfying the matching constraints. 86163d1a8abSmrg 86263d1a8abSmrg(define_insn_and_split "subdi3_internal" 86363d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=&r, r") 86463d1a8abSmrg (minus:SI 86563d1a8abSmrg (match_operand:SI 2 "register_operand" " 0, r") 86663d1a8abSmrg (match_operand:SI 4 "nonmemory_operand" " ri,ri"))) 86763d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=D , r") 86863d1a8abSmrg (minus:SI 86963d1a8abSmrg (minus:SI 87063d1a8abSmrg (match_operand:SI 3 "register_operand" " 1, r") 87163d1a8abSmrg (match_operand:SI 5 "reg_or_am33_const_operand" " D,ri")) 87263d1a8abSmrg (ltu:SI (match_dup 2) (match_dup 4)))) 87363d1a8abSmrg (clobber (match_scratch:SI 6 "=X ,&r")) 87463d1a8abSmrg (clobber (reg:CC CC_REG))] 87563d1a8abSmrg "" 87663d1a8abSmrg "#" 87763d1a8abSmrg "reload_completed" 87863d1a8abSmrg [(const_int 0)] 87963d1a8abSmrg{ 88063d1a8abSmrg rtx op0l = operands[0]; 88163d1a8abSmrg rtx op0h = operands[1]; 88263d1a8abSmrg rtx op1l = operands[2]; 88363d1a8abSmrg rtx op1h = operands[3]; 88463d1a8abSmrg rtx op2l = operands[4]; 88563d1a8abSmrg rtx op2h = operands[5]; 88663d1a8abSmrg rtx scratch = operands[6]; 88763d1a8abSmrg 88863d1a8abSmrg if (reg_overlap_mentioned_p (op0l, op1h)) 88963d1a8abSmrg { 89063d1a8abSmrg emit_move_insn (scratch, op0l); 89163d1a8abSmrg op1h = scratch; 89263d1a8abSmrg if (reg_overlap_mentioned_p (op0l, op2h)) 89363d1a8abSmrg op2h = scratch; 89463d1a8abSmrg } 89563d1a8abSmrg else if (reg_overlap_mentioned_p (op0l, op2h)) 89663d1a8abSmrg { 89763d1a8abSmrg emit_move_insn (scratch, op0l); 89863d1a8abSmrg op2h = scratch; 89963d1a8abSmrg } 90063d1a8abSmrg 90163d1a8abSmrg if (!rtx_equal_p (op0l, op1l)) 90263d1a8abSmrg { 90363d1a8abSmrg gcc_assert (TARGET_AM33); 90463d1a8abSmrg if (!REG_P (op2l)) 90563d1a8abSmrg { 90663d1a8abSmrg emit_move_insn (op0l, op1l); 90763d1a8abSmrg op1l = op0l; 90863d1a8abSmrg } 90963d1a8abSmrg } 91063d1a8abSmrg emit_insn (gen_subsi3_flags (op0l, op1l, op2l)); 91163d1a8abSmrg 91263d1a8abSmrg if (!rtx_equal_p (op0h, op1h)) 91363d1a8abSmrg { 91463d1a8abSmrg gcc_assert (TARGET_AM33); 91563d1a8abSmrg if (!REG_P (op2h)) 91663d1a8abSmrg { 91763d1a8abSmrg emit_move_insn (op0h, op1h); 91863d1a8abSmrg op1h = op0h; 91963d1a8abSmrg } 92063d1a8abSmrg } 92163d1a8abSmrg emit_insn (gen_subc_internal (op0h, op1h, op2h)); 92263d1a8abSmrg DONE; 92363d1a8abSmrg} 92463d1a8abSmrg [(set_attr "isa" "*,am33")] 92563d1a8abSmrg) 92663d1a8abSmrg 92763d1a8abSmrg;; The following pattern is generated by combine when it proves that one 92863d1a8abSmrg;; of the inputs to the low-part of the double-word sub is zero, and thus 92963d1a8abSmrg;; no carry is generated into the high-part. 93063d1a8abSmrg 93163d1a8abSmrg(define_insn_and_split "*subdi3_degenerate" 93263d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=&r,&r") 93363d1a8abSmrg (match_operand:SI 2 "nonmemory_operand" " 0, 0")) 93463d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=r , r") 93563d1a8abSmrg (minus:SI (match_operand:SI 3 "register_operand" " 1, r") 93663d1a8abSmrg (match_operand:SI 4 "nonmemory_operand" " ri, r"))) 93763d1a8abSmrg (clobber (reg:CC CC_REG))] 93863d1a8abSmrg "" 93963d1a8abSmrg "#" 94063d1a8abSmrg "" 94163d1a8abSmrg [(const_int 0)] 94263d1a8abSmrg{ 94363d1a8abSmrg rtx scratch = NULL_RTX; 94463d1a8abSmrg if (!rtx_equal_p (operands[0], operands[2])) 94563d1a8abSmrg { 94663d1a8abSmrg gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1])); 94763d1a8abSmrg if (reg_overlap_mentioned_p (operands[0], operands[3]) 94863d1a8abSmrg || reg_overlap_mentioned_p (operands[0], operands[4])) 94963d1a8abSmrg { 95063d1a8abSmrg scratch = gen_reg_rtx (SImode); 95163d1a8abSmrg emit_move_insn (scratch, operands[2]); 95263d1a8abSmrg } 95363d1a8abSmrg else 95463d1a8abSmrg emit_move_insn (operands[0], operands[2]); 95563d1a8abSmrg } 95663d1a8abSmrg emit_insn (gen_subsi3 (operands[1], operands[3], operands[4])); 95763d1a8abSmrg if (scratch) 95863d1a8abSmrg emit_move_insn (operands[0], scratch); 95963d1a8abSmrg DONE; 96063d1a8abSmrg}) 96163d1a8abSmrg 96263d1a8abSmrg(define_insn_and_split "negsi2" 96363d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,&r") 96463d1a8abSmrg (neg:SI (match_operand:SI 1 "register_operand" " 0, r"))) 96563d1a8abSmrg (clobber (reg:CC CC_REG))] 96663d1a8abSmrg "" 96763d1a8abSmrg "#" 96863d1a8abSmrg "&& reload_completed" 96963d1a8abSmrg [(const_int 0)] 97063d1a8abSmrg{ 97163d1a8abSmrg /* Recall that twos-compliment is ones-compliment plus one. When 97263d1a8abSmrg allocated in DATA_REGS this is 2+1 bytes; otherwise (for am33) 97363d1a8abSmrg this is 3+3 bytes. 97463d1a8abSmrg 97563d1a8abSmrg For AM33, it would have been possible to load zero and use the 97663d1a8abSmrg three-address subtract to have a total size of 3+4*N bytes for 97763d1a8abSmrg multiple negations, plus increased throughput. Not attempted here. */ 97863d1a8abSmrg 97963d1a8abSmrg if (true_regnum (operands[0]) == true_regnum (operands[1])) 98063d1a8abSmrg { 98163d1a8abSmrg emit_insn (gen_one_cmplsi2 (operands[0], operands[0])); 98263d1a8abSmrg emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx)); 98363d1a8abSmrg } 98463d1a8abSmrg else 98563d1a8abSmrg { 98663d1a8abSmrg emit_move_insn (operands[0], const0_rtx); 98763d1a8abSmrg emit_insn (gen_subsi3 (operands[0], operands[0], operands[1])); 98863d1a8abSmrg } 98963d1a8abSmrg DONE; 99063d1a8abSmrg}) 99163d1a8abSmrg 99263d1a8abSmrg;; ---------------------------------------------------------------------- 99363d1a8abSmrg;; MULTIPLY INSTRUCTIONS 99463d1a8abSmrg;; ---------------------------------------------------------------------- 99563d1a8abSmrg 99663d1a8abSmrg;; ??? Note that AM33 has a third multiply variant that puts the high part 99763d1a8abSmrg;; into the MDRQ register, however this variant also constrains the inputs 99863d1a8abSmrg;; to be in DATA_REGS and thus isn't as helpful as it might be considering 99963d1a8abSmrg;; the existence of the 4-operand multiply. Nor is there a set of divide 100063d1a8abSmrg;; insns that use MDRQ. Given that there is an IMM->MDRQ insn, this would 100163d1a8abSmrg;; have been very handy for starting udivmodsi4... 100263d1a8abSmrg 100363d1a8abSmrg(define_expand "mulsidi3" 100463d1a8abSmrg [(set (match_operand:DI 0 "register_operand" "") 100563d1a8abSmrg (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) 100663d1a8abSmrg (sign_extend:DI (match_operand:SI 2 "register_operand" ""))))] 100763d1a8abSmrg "" 100863d1a8abSmrg{ 100963d1a8abSmrg emit_insn (gen_mulsidi3_internal (gen_lowpart (SImode, operands[0]), 101063d1a8abSmrg gen_highpart (SImode, operands[0]), 101163d1a8abSmrg operands[1], operands[2])); 101263d1a8abSmrg DONE; 101363d1a8abSmrg}) 101463d1a8abSmrg 101563d1a8abSmrg(define_insn "mulsidi3_internal" 101663d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,r") 101763d1a8abSmrg (mult:SI (match_operand:SI 2 "register_operand" "%0,r") 101863d1a8abSmrg (match_operand:SI 3 "register_operand" " D,r"))) 101963d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=z,r") 102063d1a8abSmrg (truncate:SI 102163d1a8abSmrg (ashiftrt:DI 102263d1a8abSmrg (mult:DI (sign_extend:DI (match_dup 2)) 102363d1a8abSmrg (sign_extend:DI (match_dup 3))) 102463d1a8abSmrg (const_int 32)))) 102563d1a8abSmrg (clobber (reg:CC CC_REG))] 102663d1a8abSmrg "" 102763d1a8abSmrg{ 102863d1a8abSmrg if (which_alternative == 1) 102963d1a8abSmrg return "mul %2,%3,%1,%0"; 103063d1a8abSmrg else if (TARGET_MULT_BUG) 103163d1a8abSmrg return "nop\;nop\;mul %3,%0"; 103263d1a8abSmrg else 103363d1a8abSmrg return "mul %3,%0"; 103463d1a8abSmrg} 103563d1a8abSmrg [(set_attr "isa" "*,am33") 103663d1a8abSmrg (set (attr "timings") 103763d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))] 103863d1a8abSmrg) 103963d1a8abSmrg 104063d1a8abSmrg(define_expand "umulsidi3" 104163d1a8abSmrg [(set (match_operand:DI 0 "register_operand" "") 104263d1a8abSmrg (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) 104363d1a8abSmrg (zero_extend:DI (match_operand:SI 2 "register_operand" "")))) 104463d1a8abSmrg (clobber (reg:CC CC_REG))] 104563d1a8abSmrg "" 104663d1a8abSmrg{ 104763d1a8abSmrg emit_insn (gen_umulsidi3_internal (gen_lowpart (SImode, operands[0]), 104863d1a8abSmrg gen_highpart (SImode, operands[0]), 104963d1a8abSmrg operands[1], operands[2])); 105063d1a8abSmrg DONE; 105163d1a8abSmrg}) 105263d1a8abSmrg 105363d1a8abSmrg(define_insn "umulsidi3_internal" 105463d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,r") 105563d1a8abSmrg (mult:SI (match_operand:SI 2 "register_operand" "%0,r") 105663d1a8abSmrg (match_operand:SI 3 "register_operand" " D,r"))) 105763d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=z,r") 105863d1a8abSmrg (truncate:SI 105963d1a8abSmrg (lshiftrt:DI 106063d1a8abSmrg (mult:DI (zero_extend:DI (match_dup 2)) 106163d1a8abSmrg (zero_extend:DI (match_dup 3))) 106263d1a8abSmrg (const_int 32)))) 106363d1a8abSmrg (clobber (reg:CC CC_REG))] 106463d1a8abSmrg "" 106563d1a8abSmrg{ 106663d1a8abSmrg if (which_alternative == 1) 106763d1a8abSmrg return "mulu %2,%3,%1,%0"; 106863d1a8abSmrg else if (TARGET_MULT_BUG) 106963d1a8abSmrg return "nop\;nop\;mulu %3,%0"; 107063d1a8abSmrg else 107163d1a8abSmrg return "mulu %3,%0"; 107263d1a8abSmrg} 107363d1a8abSmrg [(set_attr "isa" "*,am33") 107463d1a8abSmrg (set (attr "timings") 107563d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))] 107663d1a8abSmrg) 107763d1a8abSmrg 107863d1a8abSmrg(define_expand "mulsi3" 107963d1a8abSmrg [(parallel [(set (match_operand:SI 0 "register_operand") 108063d1a8abSmrg (mult:SI (match_operand:SI 1 "register_operand") 108163d1a8abSmrg (match_operand:SI 2 "reg_or_am33_const_operand"))) 108263d1a8abSmrg (clobber (match_scratch:SI 3)) 108363d1a8abSmrg (clobber (reg:CC CC_REG))])] 108463d1a8abSmrg "" 108563d1a8abSmrg) 108663d1a8abSmrg 108763d1a8abSmrg(define_insn "*mulsi3" 108863d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D, r,r") 108963d1a8abSmrg (mult:SI (match_operand:SI 2 "register_operand" "%0, 0,r") 109063d1a8abSmrg (match_operand:SI 3 "reg_or_am33_const_operand" " D,ri,r"))) 109163d1a8abSmrg (clobber (match_scratch:SI 1 "=z, z,r")) 109263d1a8abSmrg (clobber (reg:CC CC_REG))] 109363d1a8abSmrg "" 109463d1a8abSmrg{ 109563d1a8abSmrg if (which_alternative == 2) 109663d1a8abSmrg return "mul %2,%3,%1,%0"; 109763d1a8abSmrg else if (TARGET_MULT_BUG) 109863d1a8abSmrg return "nop\;nop\;mul %3,%0"; 109963d1a8abSmrg else 110063d1a8abSmrg return "mul %3,%0"; 110163d1a8abSmrg} 110263d1a8abSmrg [(set_attr "isa" "*,am33,am33") 110363d1a8abSmrg (set (attr "timings") 110463d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") (const_int 24) (const_int 23)))] 110563d1a8abSmrg) 110663d1a8abSmrg 110763d1a8abSmrg(define_expand "udivmodsi4" 110863d1a8abSmrg [(parallel [(set (match_operand:SI 0 "register_operand") 110963d1a8abSmrg (udiv:SI (match_operand:SI 1 "register_operand") 111063d1a8abSmrg (match_operand:SI 2 "register_operand"))) 111163d1a8abSmrg (set (match_operand:SI 3 "register_operand") 111263d1a8abSmrg (umod:SI (match_dup 1) (match_dup 2))) 111363d1a8abSmrg (use (const_int 0)) 111463d1a8abSmrg (clobber (reg:CC CC_REG))])] 111563d1a8abSmrg "" 111663d1a8abSmrg) 111763d1a8abSmrg 111863d1a8abSmrg;; Note the trick to get reload to put the zero into the MDR register, 111963d1a8abSmrg;; rather than exposing the load early and letting CSE or someone try 112063d1a8abSmrg;; to share the zeros between division insns. Which tends to result 112163d1a8abSmrg;; in sequences like 0->r0->d0->mdr. 112263d1a8abSmrg 112363d1a8abSmrg(define_insn "*udivmodsi4" 112463d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D") 112563d1a8abSmrg (udiv:SI (match_operand:SI 2 "register_operand" " 0") 112663d1a8abSmrg (match_operand:SI 3 "register_operand" " D"))) 112763d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=z") 112863d1a8abSmrg (umod:SI (match_dup 2) (match_dup 3))) 112963d1a8abSmrg (use (match_operand:SI 4 "nonmemory_operand" " 1")) 113063d1a8abSmrg (clobber (reg:CC CC_REG))] 113163d1a8abSmrg "" 113263d1a8abSmrg "divu %3,%0" 113363d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 113463d1a8abSmrg (const_int 3839) (const_int 4243)))] 113563d1a8abSmrg) 113663d1a8abSmrg 113763d1a8abSmrg(define_expand "divmodsi4" 113863d1a8abSmrg [(parallel [(set (match_operand:SI 0 "register_operand" "") 113963d1a8abSmrg (div:SI (match_operand:SI 1 "register_operand" "") 114063d1a8abSmrg (match_operand:SI 2 "register_operand" ""))) 114163d1a8abSmrg (set (match_operand:SI 3 "register_operand" "") 114263d1a8abSmrg (mod:SI (match_dup 1) (match_dup 2))) 114363d1a8abSmrg (use (match_dup 4)) 114463d1a8abSmrg (clobber (reg:CC CC_REG))])] 114563d1a8abSmrg "" 114663d1a8abSmrg{ 114763d1a8abSmrg operands[4] = gen_reg_rtx (SImode); 114863d1a8abSmrg emit_insn (gen_ext_internal (operands[4], operands[1])); 114963d1a8abSmrg}) 115063d1a8abSmrg 115163d1a8abSmrg;; ??? Ideally we'd represent this via shift, but it seems like adding a 115263d1a8abSmrg;; special-case pattern for (ashiftrt x 31) is just as likely to result 115363d1a8abSmrg;; in poor register allocation choices. 115463d1a8abSmrg(define_insn "ext_internal" 115563d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=z") 115663d1a8abSmrg (unspec:SI [(match_operand:SI 1 "register_operand" "D")] UNSPEC_EXT))] 115763d1a8abSmrg "" 115863d1a8abSmrg "ext %1" 115963d1a8abSmrg) 116063d1a8abSmrg 116163d1a8abSmrg(define_insn "*divmodsi4" 116263d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D") 116363d1a8abSmrg (div:SI (match_operand:SI 2 "register_operand" " 0") 116463d1a8abSmrg (match_operand:SI 3 "register_operand" " D"))) 116563d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=z") 116663d1a8abSmrg (mod:SI (match_dup 2) (match_dup 3))) 116763d1a8abSmrg (use (match_operand:SI 4 "register_operand" " 1")) 116863d1a8abSmrg (clobber (reg:CC CC_REG))] 116963d1a8abSmrg "" 117063d1a8abSmrg "div %3,%0"; 117163d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 117263d1a8abSmrg (const_int 3839) (const_int 4243)))] 117363d1a8abSmrg) 117463d1a8abSmrg 117563d1a8abSmrg 117663d1a8abSmrg;; ---------------------------------------------------------------------- 117763d1a8abSmrg;; AND INSTRUCTIONS 117863d1a8abSmrg;; ---------------------------------------------------------------------- 117963d1a8abSmrg 118063d1a8abSmrg(define_insn "andsi3" 118163d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,D,r") 118263d1a8abSmrg (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") 118363d1a8abSmrg (match_operand:SI 2 "nonmemory_operand" " i,D,r"))) 118463d1a8abSmrg (clobber (reg:CC CC_REG))] 118563d1a8abSmrg "" 118663d1a8abSmrg "@ 118763d1a8abSmrg and %2,%0 118863d1a8abSmrg and %2,%0 118963d1a8abSmrg and %2,%1,%0" 119063d1a8abSmrg [(set_attr "isa" "*,*,am33") 119163d1a8abSmrg (set_attr "liw" "*,op1,*") 119263d1a8abSmrg (set_attr "liw_op" "and") 119363d1a8abSmrg (set_attr "timings" "22,11,11")] 119463d1a8abSmrg) 119563d1a8abSmrg 119663d1a8abSmrg(define_insn "*andsi3_flags" 1197c7a68eb7Smrg [(set (reg CC_REG) 1198c7a68eb7Smrg (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1199c7a68eb7Smrg (match_operand:SI 2 "nonmemory_operand" " i,D,r")) 1200c7a68eb7Smrg (const_int 0))) 1201c7a68eb7Smrg (set (match_operand:SI 0 "register_operand" "=D,D,r") 1202c7a68eb7Smrg (and:SI (match_dup 1) (match_dup 2)))] 120363d1a8abSmrg "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" 120463d1a8abSmrg "@ 120563d1a8abSmrg and %2,%0 120663d1a8abSmrg and %2,%0 120763d1a8abSmrg and %2,%1,%0" 120863d1a8abSmrg [(set_attr "isa" "*,*,am33") 120963d1a8abSmrg (set_attr "timings" "22,11,11")] 121063d1a8abSmrg) 121163d1a8abSmrg 121263d1a8abSmrg;; Make sure we generate extensions instead of ANDs. 121363d1a8abSmrg 121463d1a8abSmrg(define_split 121563d1a8abSmrg [(parallel [(set (match_operand:SI 0 "register_operand" "") 121663d1a8abSmrg (and:SI (match_operand:SI 1 "register_operand" "") 121763d1a8abSmrg (const_int 255))) 121863d1a8abSmrg (clobber (reg:CC CC_REG))])] 121963d1a8abSmrg "" 122063d1a8abSmrg [(set (match_dup 0) (zero_extend:SI (match_dup 1)))] 122163d1a8abSmrg { operands[1] = gen_lowpart (QImode, operands[1]); } 122263d1a8abSmrg) 122363d1a8abSmrg 122463d1a8abSmrg(define_split 122563d1a8abSmrg [(parallel [(set (match_operand:SI 0 "register_operand" "") 122663d1a8abSmrg (and:SI (match_operand:SI 1 "register_operand" "") 122763d1a8abSmrg (const_int 65535))) 122863d1a8abSmrg (clobber (reg:CC CC_REG))])] 122963d1a8abSmrg "" 123063d1a8abSmrg [(set (match_dup 0) (zero_extend:SI (match_dup 1)))] 123163d1a8abSmrg { operands[1] = gen_lowpart (HImode, operands[1]); } 123263d1a8abSmrg) 123363d1a8abSmrg 123463d1a8abSmrg;; Split AND by an appropriate constant into two shifts. Recall that 123563d1a8abSmrg;; operations with a full 32-bit immediate require an extra cycle, so 123663d1a8abSmrg;; this is a size optimization with no speed penalty. This only applies 123763d1a8abSmrg;; do DATA_REGS; the shift insns that AM33 adds are too large for a win. 123863d1a8abSmrg 123963d1a8abSmrg(define_split 124063d1a8abSmrg [(parallel [(set (match_operand:SI 0 "register_operand" "") 124163d1a8abSmrg (and:SI (match_dup 0) 124263d1a8abSmrg (match_operand:SI 1 "const_int_operand" ""))) 124363d1a8abSmrg (clobber (reg:CC CC_REG))])] 124463d1a8abSmrg "reload_completed 124563d1a8abSmrg && REGNO_DATA_P (true_regnum (operands[0]), 1) 124663d1a8abSmrg && mn10300_split_and_operand_count (operands[1]) != 0" 124763d1a8abSmrg [(const_int 0)] 124863d1a8abSmrg{ 124963d1a8abSmrg int count = mn10300_split_and_operand_count (operands[1]); 125063d1a8abSmrg if (count > 0) 125163d1a8abSmrg { 125263d1a8abSmrg emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (count))); 125363d1a8abSmrg emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (count))); 125463d1a8abSmrg } 125563d1a8abSmrg else 125663d1a8abSmrg { 125763d1a8abSmrg emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (-count))); 125863d1a8abSmrg emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (-count))); 125963d1a8abSmrg } 126063d1a8abSmrg DONE; 126163d1a8abSmrg}) 126263d1a8abSmrg 126363d1a8abSmrg;; ---------------------------------------------------------------------- 126463d1a8abSmrg;; OR INSTRUCTIONS 126563d1a8abSmrg;; ---------------------------------------------------------------------- 126663d1a8abSmrg 126763d1a8abSmrg(define_insn "iorsi3" 126863d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,D,r") 126963d1a8abSmrg (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") 127063d1a8abSmrg (match_operand:SI 2 "nonmemory_operand" " i,D,r"))) 127163d1a8abSmrg (clobber (reg:CC CC_REG))] 127263d1a8abSmrg "" 127363d1a8abSmrg "@ 127463d1a8abSmrg or %2,%0 127563d1a8abSmrg or %2,%0 127663d1a8abSmrg or %2,%1,%0" 127763d1a8abSmrg [(set_attr "isa" "*,*,am33") 127863d1a8abSmrg (set_attr "liw" "*,op1,*") 127963d1a8abSmrg (set_attr "liw_op" "or") 128063d1a8abSmrg (set_attr "timings" "22,11,11")] 128163d1a8abSmrg) 128263d1a8abSmrg 128363d1a8abSmrg(define_insn "*iorsi3_flags" 1284c7a68eb7Smrg [(set (reg CC_REG) 1285c7a68eb7Smrg (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1286c7a68eb7Smrg (match_operand:SI 2 "nonmemory_operand" " i,D,r")) 1287c7a68eb7Smrg (const_int 0))) 1288c7a68eb7Smrg (set (match_operand:SI 0 "register_operand" "=D,D,r") 1289c7a68eb7Smrg (ior:SI (match_dup 1) (match_dup 2)))] 129063d1a8abSmrg "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" 129163d1a8abSmrg "@ 129263d1a8abSmrg or %2,%0 129363d1a8abSmrg or %2,%0 129463d1a8abSmrg or %2,%1,%0" 129563d1a8abSmrg [(set_attr "isa" "*,*,am33") 129663d1a8abSmrg (set_attr "timings" "22,11,11")] 129763d1a8abSmrg) 129863d1a8abSmrg 129963d1a8abSmrg;; ---------------------------------------------------------------------- 130063d1a8abSmrg;; XOR INSTRUCTIONS 130163d1a8abSmrg;; ---------------------------------------------------------------------- 130263d1a8abSmrg 130363d1a8abSmrg(define_insn "xorsi3" 130463d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,D,r") 130563d1a8abSmrg (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") 130663d1a8abSmrg (match_operand:SI 2 "nonmemory_operand" " i,D,r"))) 130763d1a8abSmrg (clobber (reg:CC CC_REG))] 130863d1a8abSmrg "" 130963d1a8abSmrg "@ 131063d1a8abSmrg xor %2,%0 131163d1a8abSmrg xor %2,%0 131263d1a8abSmrg xor %2,%1,%0" 131363d1a8abSmrg [(set_attr "isa" "*,*,am33") 131463d1a8abSmrg (set_attr "liw" "*,op1,*") 131563d1a8abSmrg (set_attr "liw_op" "xor") 131663d1a8abSmrg (set_attr "timings" "22,11,11")] 131763d1a8abSmrg) 131863d1a8abSmrg 131963d1a8abSmrg(define_insn "*xorsi3_flags" 1320c7a68eb7Smrg [(set (reg CC_REG) 1321c7a68eb7Smrg (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0,r") 1322c7a68eb7Smrg (match_operand:SI 2 "nonmemory_operand" " i,D,r")) 1323c7a68eb7Smrg (const_int 0))) 1324c7a68eb7Smrg (set (match_operand:SI 0 "register_operand" "=D,D,r") 1325c7a68eb7Smrg (xor:SI (match_dup 1) (match_dup 2)))] 132663d1a8abSmrg "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" 132763d1a8abSmrg "@ 132863d1a8abSmrg xor %2,%0 132963d1a8abSmrg xor %2,%0 133063d1a8abSmrg xor %2,%1,%0" 133163d1a8abSmrg [(set_attr "isa" "*,*,am33") 133263d1a8abSmrg (set_attr "timings" "22,11,11")] 133363d1a8abSmrg) 133463d1a8abSmrg 133563d1a8abSmrg;; ---------------------------------------------------------------------- 133663d1a8abSmrg;; NOT INSTRUCTIONS 133763d1a8abSmrg;; ---------------------------------------------------------------------- 133863d1a8abSmrg 133963d1a8abSmrg(define_insn "one_cmplsi2" 134063d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D") 134163d1a8abSmrg (not:SI (match_operand:SI 1 "register_operand" " 0"))) 134263d1a8abSmrg (clobber (reg:CC CC_REG))] 134363d1a8abSmrg "" 134463d1a8abSmrg "not %0" 134563d1a8abSmrg) 134663d1a8abSmrg 134763d1a8abSmrg(define_insn "*one_cmplsi2_flags" 1348c7a68eb7Smrg [(set (reg CC_REG) 1349c7a68eb7Smrg (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 1350c7a68eb7Smrg (const_int 0))) 1351c7a68eb7Smrg (set (match_operand:SI 0 "register_operand" "=D") 1352c7a68eb7Smrg (not:SI (match_dup 1)))] 135363d1a8abSmrg "reload_completed && mn10300_match_ccmode (insn, CCZNmode)" 135463d1a8abSmrg "not %0" 135563d1a8abSmrg) 135663d1a8abSmrg 135763d1a8abSmrg;; ---------------------------------------------------------------------- 135863d1a8abSmrg;; COMPARE AND BRANCH INSTRUCTIONS 135963d1a8abSmrg;; ---------------------------------------------------------------------- 136063d1a8abSmrg 136163d1a8abSmrg;; We expand the comparison into a single insn so that it will not be split 136263d1a8abSmrg;; up by reload. 136363d1a8abSmrg(define_expand "cbranchsi4" 136463d1a8abSmrg [(set (pc) 136563d1a8abSmrg (if_then_else 136663d1a8abSmrg (match_operator 0 "ordered_comparison_operator" 136763d1a8abSmrg [(match_operand:SI 1 "register_operand") 136863d1a8abSmrg (match_operand:SI 2 "nonmemory_operand")]) 136963d1a8abSmrg (label_ref (match_operand 3 "")) 137063d1a8abSmrg (pc)))] 137163d1a8abSmrg "" 137263d1a8abSmrg "" 137363d1a8abSmrg) 137463d1a8abSmrg 137563d1a8abSmrg(define_insn_and_split "*cbranchsi4_cmp" 137663d1a8abSmrg [(set (pc) 137763d1a8abSmrg (if_then_else (match_operator 3 "ordered_comparison_operator" 137863d1a8abSmrg [(match_operand:SI 0 "register_operand" "r") 137963d1a8abSmrg (match_operand:SI 1 "nonmemory_operand" "ri")]) 138063d1a8abSmrg (match_operand 2 "label_ref_operand" "") 138163d1a8abSmrg (pc)))] 138263d1a8abSmrg "" 138363d1a8abSmrg "#" 138463d1a8abSmrg "reload_completed" 138563d1a8abSmrg [(const_int 0)] 138663d1a8abSmrg{ 138763d1a8abSmrg mn10300_split_cbranch (CCmode, operands[3], operands[2]); 138863d1a8abSmrg DONE; 138963d1a8abSmrg}) 139063d1a8abSmrg 139163d1a8abSmrg(define_insn "cmpsi" 139263d1a8abSmrg [(set (reg CC_REG) 139363d1a8abSmrg (compare (match_operand:SI 0 "register_operand" "r,r,r") 139463d1a8abSmrg (match_operand:SI 1 "nonmemory_operand" "r,O,i")))] 139563d1a8abSmrg "reload_completed" 139663d1a8abSmrg{ 139763d1a8abSmrg /* The operands of CMP must be distinct registers. In the case where 139863d1a8abSmrg we've failed to optimize the comparison of a register to itself, we 139963d1a8abSmrg must use another method to set the Z flag. We can achieve this 140063d1a8abSmrg effect with a BTST 0,D0. This will not alter the contents of D0; 140163d1a8abSmrg the use of d0 is arbitrary; any data register would work. */ 140263d1a8abSmrg if (rtx_equal_p (operands[0], operands[1])) 140363d1a8abSmrg return "btst 0,d0"; 140463d1a8abSmrg else 140563d1a8abSmrg return "cmp %1,%0"; 140663d1a8abSmrg} 140763d1a8abSmrg [(set_attr_alternative "timings" 140863d1a8abSmrg [(if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22)) 140963d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22)) 141063d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))]) 141163d1a8abSmrg (set_attr "liw" "either,either,*") 141263d1a8abSmrg (set_attr "liw_op" "cmp")] 141363d1a8abSmrg) 141463d1a8abSmrg 141563d1a8abSmrg(define_insn "*integer_conditional_branch" 141663d1a8abSmrg [(set (pc) 141763d1a8abSmrg (if_then_else (match_operator 0 "comparison_operator" 141863d1a8abSmrg [(match_operand 2 "int_mode_flags" "") 141963d1a8abSmrg (const_int 0)]) 142063d1a8abSmrg (label_ref (match_operand 1 "" "")) 142163d1a8abSmrg (pc)))] 142263d1a8abSmrg "reload_completed" 142363d1a8abSmrg "b%b0 %1" 142463d1a8abSmrg) 142563d1a8abSmrg 142663d1a8abSmrg(define_insn_and_split "*cbranchsi4_btst" 142763d1a8abSmrg [(set (pc) 142863d1a8abSmrg (if_then_else 142963d1a8abSmrg (match_operator 3 "CCZN_comparison_operator" 143063d1a8abSmrg [(and:SI (match_operand:SI 0 "register_operand" "D") 143163d1a8abSmrg (match_operand:SI 1 "immediate_operand" "i")) 143263d1a8abSmrg (const_int 0)]) 143363d1a8abSmrg (match_operand 2 "label_ref_operand" "") 143463d1a8abSmrg (pc)))] 143563d1a8abSmrg "" 143663d1a8abSmrg "#" 143763d1a8abSmrg "reload_completed" 143863d1a8abSmrg [(const_int 0)] 143963d1a8abSmrg{ 144063d1a8abSmrg mn10300_split_cbranch (CCZNmode, operands[3], operands[2]); 144163d1a8abSmrg DONE; 144263d1a8abSmrg}) 144363d1a8abSmrg 144463d1a8abSmrg(define_insn "*btstsi" 144563d1a8abSmrg [(set (reg:CCZN CC_REG) 144663d1a8abSmrg (compare:CCZN 144763d1a8abSmrg (and:SI (match_operand:SI 0 "register_operand" "D") 144863d1a8abSmrg (match_operand:SI 1 "immediate_operand" "i")) 144963d1a8abSmrg (const_int 0)))] 145063d1a8abSmrg "reload_completed" 145163d1a8abSmrg "btst %1,%0" 145263d1a8abSmrg) 145363d1a8abSmrg 145463d1a8abSmrg(define_expand "cbranchsf4" 145563d1a8abSmrg [(set (pc) 145663d1a8abSmrg (if_then_else 145763d1a8abSmrg (match_operator 0 "ordered_comparison_operator" 145863d1a8abSmrg [(match_operand:SF 1 "register_operand") 145963d1a8abSmrg (match_operand:SF 2 "nonmemory_operand")]) 146063d1a8abSmrg (label_ref (match_operand 3 "")) 146163d1a8abSmrg (pc)))] 146263d1a8abSmrg "TARGET_AM33_2" 146363d1a8abSmrg "" 146463d1a8abSmrg) 146563d1a8abSmrg 146663d1a8abSmrg(define_insn_and_split "*cbranchsf4_cmp" 146763d1a8abSmrg [(set (pc) 146863d1a8abSmrg (if_then_else (match_operator 3 "ordered_comparison_operator" 146963d1a8abSmrg [(match_operand:SF 0 "register_operand" "f") 147063d1a8abSmrg (match_operand:SF 1 "nonmemory_operand" "fF")]) 147163d1a8abSmrg (match_operand 2 "label_ref_operand" "") 147263d1a8abSmrg (pc))) 147363d1a8abSmrg ] 147463d1a8abSmrg "TARGET_AM33_2" 147563d1a8abSmrg "#" 147663d1a8abSmrg "&& reload_completed" 147763d1a8abSmrg [(const_int 0)] 147863d1a8abSmrg{ 147963d1a8abSmrg mn10300_split_cbranch (CC_FLOATmode, operands[3], operands[2]); 148063d1a8abSmrg DONE; 148163d1a8abSmrg}) 148263d1a8abSmrg 148363d1a8abSmrg(define_insn "*am33_cmpsf" 148463d1a8abSmrg [(set (reg:CC_FLOAT CC_REG) 148563d1a8abSmrg (compare:CC_FLOAT (match_operand:SF 0 "register_operand" "f") 148663d1a8abSmrg (match_operand:SF 1 "nonmemory_operand" "fF")))] 148763d1a8abSmrg "TARGET_AM33_2 && reload_completed" 148863d1a8abSmrg "fcmp %1, %0" 148963d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 149063d1a8abSmrg (const_int 17) (const_int 25)))] 149163d1a8abSmrg) 149263d1a8abSmrg 149363d1a8abSmrg(define_insn "*float_conditional_branch" 149463d1a8abSmrg [(set (pc) 149563d1a8abSmrg (if_then_else (match_operator 0 "comparison_operator" 149663d1a8abSmrg [(reg:CC_FLOAT CC_REG) (const_int 0)]) 149763d1a8abSmrg (label_ref (match_operand 1 "" "")) 149863d1a8abSmrg (pc)))] 149963d1a8abSmrg "TARGET_AM33_2 && reload_completed" 150063d1a8abSmrg "fb%b0 %1" 150163d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 150263d1a8abSmrg (const_int 44) (const_int 33)))] 150363d1a8abSmrg) 150463d1a8abSmrg 150563d1a8abSmrg;; Unconditional and other jump instructions. 150663d1a8abSmrg 150763d1a8abSmrg(define_insn "jump" 150863d1a8abSmrg [(set (pc) 150963d1a8abSmrg (label_ref (match_operand 0 "" "")))] 151063d1a8abSmrg "" 151163d1a8abSmrg "jmp %l0" 151263d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 151363d1a8abSmrg (const_int 11) (const_int 44)))] 151463d1a8abSmrg) 151563d1a8abSmrg 151663d1a8abSmrg(define_insn "indirect_jump" 151763d1a8abSmrg [(set (pc) (match_operand:SI 0 "register_operand" "a"))] 151863d1a8abSmrg "" 151963d1a8abSmrg "jmp (%0)" 152063d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 152163d1a8abSmrg (const_int 11) (const_int 33)))] 152263d1a8abSmrg) 152363d1a8abSmrg 152463d1a8abSmrg(define_expand "builtin_setjmp_receiver" 152563d1a8abSmrg [(match_operand 0 "" "")] 152663d1a8abSmrg "flag_pic" 152763d1a8abSmrg{ 152863d1a8abSmrg emit_insn (gen_load_pic ()); 152963d1a8abSmrg DONE; 153063d1a8abSmrg}) 153163d1a8abSmrg 153263d1a8abSmrg(define_expand "casesi" 153363d1a8abSmrg [(match_operand:SI 0 "register_operand") 153463d1a8abSmrg (match_operand:SI 1 "immediate_operand") 153563d1a8abSmrg (match_operand:SI 2 "immediate_operand") 153663d1a8abSmrg (match_operand 3 "" "") (match_operand 4 "")] 153763d1a8abSmrg "" 153863d1a8abSmrg{ 153963d1a8abSmrg rtx table = gen_reg_rtx (SImode); 154063d1a8abSmrg rtx index = gen_reg_rtx (SImode); 154163d1a8abSmrg rtx addr = gen_reg_rtx (Pmode); 154263d1a8abSmrg rtx test; 154363d1a8abSmrg 154463d1a8abSmrg emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3])); 154563d1a8abSmrg emit_insn (gen_addsi3 (index, operands[0], GEN_INT (- INTVAL (operands[1])))); 154663d1a8abSmrg test = gen_rtx_fmt_ee (GTU, VOIDmode, index, operands[2]); 154763d1a8abSmrg emit_jump_insn (gen_cbranchsi4 (test, index, operands[2], operands[4])); 154863d1a8abSmrg 154963d1a8abSmrg emit_insn (gen_ashlsi3 (index, index, const2_rtx)); 155063d1a8abSmrg emit_move_insn (addr, gen_rtx_MEM (SImode, 155163d1a8abSmrg gen_rtx_PLUS (SImode, table, index))); 155263d1a8abSmrg if (flag_pic) 155363d1a8abSmrg emit_insn (gen_addsi3 (addr, addr, table)); 155463d1a8abSmrg 155563d1a8abSmrg emit_jump_insn (gen_tablejump (addr, operands[3])); 155663d1a8abSmrg DONE; 155763d1a8abSmrg}) 155863d1a8abSmrg 155963d1a8abSmrg(define_insn "tablejump" 156063d1a8abSmrg [(set (pc) (match_operand:SI 0 "register_operand" "a")) 156163d1a8abSmrg (use (label_ref (match_operand 1 "" "")))] 156263d1a8abSmrg "" 156363d1a8abSmrg "jmp (%0)" 156463d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 156563d1a8abSmrg (const_int 11) (const_int 33)))] 156663d1a8abSmrg) 156763d1a8abSmrg 156863d1a8abSmrg;; Call subroutine with no return value. 156963d1a8abSmrg 157063d1a8abSmrg(define_expand "call" 157163d1a8abSmrg [(call (match_operand:QI 0 "general_operand") 157263d1a8abSmrg (match_operand:SI 1 "general_operand"))] 157363d1a8abSmrg "" 157463d1a8abSmrg{ 157563d1a8abSmrg rtx fn = XEXP (operands[0], 0); 157663d1a8abSmrg 157763d1a8abSmrg if (flag_pic && GET_CODE (fn) == SYMBOL_REF) 157863d1a8abSmrg { 157963d1a8abSmrg if (MN10300_GLOBAL_P (fn)) 158063d1a8abSmrg { 158163d1a8abSmrg /* The PLT code won't run on AM30, but then, there's no 158263d1a8abSmrg shared library support for AM30 either, so we just assume 158363d1a8abSmrg the linker is going to adjust all @PLT relocs to the 158463d1a8abSmrg actual symbols. */ 158563d1a8abSmrg emit_use (pic_offset_table_rtx); 158663d1a8abSmrg fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT); 158763d1a8abSmrg } 158863d1a8abSmrg else 158963d1a8abSmrg fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC); 159063d1a8abSmrg } 159163d1a8abSmrg if (! call_address_operand (fn, VOIDmode)) 159263d1a8abSmrg fn = force_reg (SImode, fn); 159363d1a8abSmrg 159463d1a8abSmrg XEXP (operands[0], 0) = fn; 159563d1a8abSmrg}) 159663d1a8abSmrg 159763d1a8abSmrg(define_insn "*call_internal" 159863d1a8abSmrg [(call (mem:QI (match_operand:SI 0 "call_address_operand" "a,S")) 159963d1a8abSmrg (match_operand:SI 1 "" ""))] 160063d1a8abSmrg "" 160163d1a8abSmrg "@ 160263d1a8abSmrg calls %C0 160363d1a8abSmrg call %C0,[],0" 160463d1a8abSmrg [(set_attr_alternative "timings" 160563d1a8abSmrg [(if_then_else (eq_attr "cpu" "am34") 160663d1a8abSmrg (const_int 33) (const_int 44)) 160763d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 160863d1a8abSmrg (const_int 55) (const_int 33)) 160963d1a8abSmrg ]) 161063d1a8abSmrg ] 161163d1a8abSmrg) 161263d1a8abSmrg 161363d1a8abSmrg;; Call subroutine, returning value in operand 0 161463d1a8abSmrg;; (which must be a hard register). 161563d1a8abSmrg 161663d1a8abSmrg(define_expand "call_value" 161763d1a8abSmrg [(set (match_operand 0 "") 161863d1a8abSmrg (call (match_operand:QI 1 "general_operand") 161963d1a8abSmrg (match_operand:SI 2 "general_operand")))] 162063d1a8abSmrg "" 162163d1a8abSmrg{ 162263d1a8abSmrg rtx fn = XEXP (operands[1], 0); 162363d1a8abSmrg 162463d1a8abSmrg if (flag_pic && GET_CODE (fn) == SYMBOL_REF) 162563d1a8abSmrg { 162663d1a8abSmrg if (MN10300_GLOBAL_P (fn)) 162763d1a8abSmrg { 162863d1a8abSmrg /* The PLT code won't run on AM30, but then, there's no 162963d1a8abSmrg shared library support for AM30 either, so we just assume 163063d1a8abSmrg the linker is going to adjust all @PLT relocs to the 163163d1a8abSmrg actual symbols. */ 163263d1a8abSmrg emit_use (pic_offset_table_rtx); 163363d1a8abSmrg fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PLT); 163463d1a8abSmrg } 163563d1a8abSmrg else 163663d1a8abSmrg fn = gen_rtx_UNSPEC (SImode, gen_rtvec (1, fn), UNSPEC_PIC); 163763d1a8abSmrg } 163863d1a8abSmrg if (! call_address_operand (fn, VOIDmode)) 163963d1a8abSmrg fn = force_reg (SImode, fn); 164063d1a8abSmrg 164163d1a8abSmrg XEXP (operands[1], 0) = fn; 164263d1a8abSmrg}) 164363d1a8abSmrg 164463d1a8abSmrg(define_insn "call_value_internal" 164563d1a8abSmrg [(set (match_operand 0 "" "") 164663d1a8abSmrg (call (mem:QI (match_operand:SI 1 "call_address_operand" "a,S")) 164763d1a8abSmrg (match_operand:SI 2 "" "")))] 164863d1a8abSmrg "" 164963d1a8abSmrg "@ 165063d1a8abSmrg calls %C1 165163d1a8abSmrg call %C1,[],0" 165263d1a8abSmrg [(set_attr_alternative "timings" 165363d1a8abSmrg [(if_then_else (eq_attr "cpu" "am34") 165463d1a8abSmrg (const_int 33) (const_int 44)) 165563d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 165663d1a8abSmrg (const_int 55) (const_int 33)) 165763d1a8abSmrg ]) 165863d1a8abSmrg ] 165963d1a8abSmrg) 166063d1a8abSmrg 166163d1a8abSmrg(define_expand "untyped_call" 166263d1a8abSmrg [(parallel [(call (match_operand 0 "") 166363d1a8abSmrg (const_int 0)) 166463d1a8abSmrg (match_operand 1 "") 166563d1a8abSmrg (match_operand 2 "")])] 166663d1a8abSmrg "" 166763d1a8abSmrg{ 166863d1a8abSmrg int i; 166963d1a8abSmrg 167063d1a8abSmrg emit_call_insn (gen_call (operands[0], const0_rtx)); 167163d1a8abSmrg 167263d1a8abSmrg for (i = 0; i < XVECLEN (operands[2], 0); i++) 167363d1a8abSmrg { 167463d1a8abSmrg rtx set = XVECEXP (operands[2], 0, i); 167563d1a8abSmrg emit_move_insn (SET_DEST (set), SET_SRC (set)); 167663d1a8abSmrg } 167763d1a8abSmrg DONE; 167863d1a8abSmrg}) 167963d1a8abSmrg 168063d1a8abSmrg(define_insn "nop" 168163d1a8abSmrg [(const_int 0)] 168263d1a8abSmrg "" 168363d1a8abSmrg "nop" 168463d1a8abSmrg) 168563d1a8abSmrg 168663d1a8abSmrg;; ---------------------------------------------------------------------- 168763d1a8abSmrg;; EXTEND INSTRUCTIONS 168863d1a8abSmrg;; ---------------------------------------------------------------------- 168963d1a8abSmrg 169063d1a8abSmrg(define_insn "zero_extendqisi2" 169163d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,D,r") 169263d1a8abSmrg (zero_extend:SI 169363d1a8abSmrg (match_operand:QI 1 "nonimmediate_operand" " 0,m,r")))] 169463d1a8abSmrg "" 169563d1a8abSmrg "@ 169663d1a8abSmrg extbu %0 169763d1a8abSmrg movbu %1,%0 169863d1a8abSmrg extbu %1,%0" 169963d1a8abSmrg [(set_attr "isa" "*,*,am33") 170063d1a8abSmrg (set_attr_alternative "timings" 170163d1a8abSmrg [(const_int 11) 170263d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 170363d1a8abSmrg (const_int 13) (const_int 24)) 170463d1a8abSmrg (const_int 11) 170563d1a8abSmrg ])] 170663d1a8abSmrg) 170763d1a8abSmrg 170863d1a8abSmrg(define_insn "zero_extendhisi2" 170963d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,D,r") 171063d1a8abSmrg (zero_extend:SI 171163d1a8abSmrg (match_operand:HI 1 "nonimmediate_operand" " 0,m,r")))] 171263d1a8abSmrg "" 171363d1a8abSmrg "@ 171463d1a8abSmrg exthu %0 171563d1a8abSmrg movhu %1,%0 171663d1a8abSmrg exthu %1,%0" 171763d1a8abSmrg [(set_attr "isa" "*,*,am33") 171863d1a8abSmrg (set_attr_alternative "timings" 171963d1a8abSmrg [(const_int 11) 172063d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 172163d1a8abSmrg (const_int 13) (const_int 24)) 172263d1a8abSmrg (const_int 11)])] 172363d1a8abSmrg) 172463d1a8abSmrg 172563d1a8abSmrg(define_insn "extendqisi2" 172663d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,r") 172763d1a8abSmrg (sign_extend:SI 172863d1a8abSmrg (match_operand:QI 1 "register_operand" "0,r")))] 172963d1a8abSmrg "" 173063d1a8abSmrg "@ 173163d1a8abSmrg extb %0 173263d1a8abSmrg extb %1,%0" 173363d1a8abSmrg [(set_attr "isa" "*,am33")] 173463d1a8abSmrg) 173563d1a8abSmrg 173663d1a8abSmrg(define_insn "extendhisi2" 173763d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,r") 173863d1a8abSmrg (sign_extend:SI 173963d1a8abSmrg (match_operand:HI 1 "register_operand" "0,r")))] 174063d1a8abSmrg "" 174163d1a8abSmrg "@ 174263d1a8abSmrg exth %0 174363d1a8abSmrg exth %1,%0" 174463d1a8abSmrg [(set_attr "isa" "*,am33")] 174563d1a8abSmrg) 174663d1a8abSmrg 174763d1a8abSmrg;; ---------------------------------------------------------------------- 174863d1a8abSmrg;; SHIFTS 174963d1a8abSmrg;; ---------------------------------------------------------------------- 175063d1a8abSmrg 175163d1a8abSmrg(define_insn "ashlsi3" 175263d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r,D,d,d,D,D,D,r") 175363d1a8abSmrg (ashift:SI 175463d1a8abSmrg (match_operand:SI 1 "register_operand" " 0,0,0,0,0,0,0,r") 175563d1a8abSmrg (match_operand:QI 2 "nonmemory_operand" " J,K,M,L,D,O,i,r"))) 175663d1a8abSmrg (clobber (reg:CC CC_REG))] 175763d1a8abSmrg "" 175863d1a8abSmrg "@ 175963d1a8abSmrg add %0,%0 176063d1a8abSmrg asl2 %0 176163d1a8abSmrg asl2 %0\;add %0,%0 176263d1a8abSmrg asl2 %0\;asl2 %0 176363d1a8abSmrg asl %S2,%0 176463d1a8abSmrg asl %S2,%0 176563d1a8abSmrg asl %S2,%0 176663d1a8abSmrg asl %2,%1,%0" 176763d1a8abSmrg [(set_attr "isa" "*,*,*,*,*,*,*,am33") 176863d1a8abSmrg (set_attr "liw" "op2,op2,op2,op2,op2,op2,*,*") 176963d1a8abSmrg (set_attr "liw_op" "asl") 177063d1a8abSmrg (set_attr "timings" "11,11,22,22,11,11,11,11")] 177163d1a8abSmrg) 177263d1a8abSmrg 177363d1a8abSmrg(define_insn "lshrsi3" 177463d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,D,D,r") 177563d1a8abSmrg (lshiftrt:SI 177663d1a8abSmrg (match_operand:SI 1 "register_operand" "0,0,0,r") 177763d1a8abSmrg (match_operand:QI 2 "nonmemory_operand" "D,O,i,r"))) 177863d1a8abSmrg (clobber (reg:CC CC_REG))] 177963d1a8abSmrg "" 178063d1a8abSmrg "@ 178163d1a8abSmrg lsr %S2,%0 178263d1a8abSmrg lsr %S2,%0 178363d1a8abSmrg lsr %S2,%0 178463d1a8abSmrg lsr %2,%1,%0" 178563d1a8abSmrg [(set_attr "isa" "*,*,*,am33") 178663d1a8abSmrg (set_attr "liw" "op2,op2,*,*") 178763d1a8abSmrg (set_attr "liw_op" "lsr")] 178863d1a8abSmrg) 178963d1a8abSmrg 179063d1a8abSmrg(define_insn "ashrsi3" 179163d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=D,D,D,r") 179263d1a8abSmrg (ashiftrt:SI 179363d1a8abSmrg (match_operand:SI 1 "register_operand" "0,0,0,r") 179463d1a8abSmrg (match_operand:QI 2 "nonmemory_operand" "D,O,i,r"))) 179563d1a8abSmrg (clobber (reg:CC CC_REG))] 179663d1a8abSmrg "" 179763d1a8abSmrg "@ 179863d1a8abSmrg asr %S2,%0 179963d1a8abSmrg asr %S2,%0 180063d1a8abSmrg asr %S2,%0 180163d1a8abSmrg asr %2,%1,%0" 180263d1a8abSmrg [(set_attr "isa" "*,*,*,am33") 180363d1a8abSmrg (set_attr "liw" "op2,op2,*,*") 180463d1a8abSmrg (set_attr "liw_op" "asr")] 180563d1a8abSmrg) 180663d1a8abSmrg 180763d1a8abSmrg;; ---------------------------------------------------------------------- 180863d1a8abSmrg;; MISCELLANEOUS 180963d1a8abSmrg;; ---------------------------------------------------------------------- 181063d1a8abSmrg 181163d1a8abSmrg;; Note the use of the (const_int 0) when generating the insn that matches 181263d1a8abSmrg;; the bsch pattern. This ensures that the destination register is 181363d1a8abSmrg;; initialised with 0 which will make the BSCH instruction set searching 181463d1a8abSmrg;; at bit 31. 181563d1a8abSmrg;; 181663d1a8abSmrg;; The XOR in the instruction sequence below is there because the BSCH 181763d1a8abSmrg;; instruction returns the bit number of the highest set bit and we want 181863d1a8abSmrg;; the number of zero bits above that bit. The AM33 does not have a 181963d1a8abSmrg;; reverse subtraction instruction, but we can use a simple xor instead 182063d1a8abSmrg;; since we know that the top 27 bits are clear. 182163d1a8abSmrg(define_expand "clzsi2" 182263d1a8abSmrg [(parallel [(set (match_operand:SI 0 "register_operand") 182363d1a8abSmrg (unspec:SI [(match_operand:SI 1 "register_operand") 182463d1a8abSmrg (const_int 0)] UNSPEC_BSCH)) 182563d1a8abSmrg (clobber (reg:CC CC_REG))]) 182663d1a8abSmrg (parallel [(set (match_dup 0) 182763d1a8abSmrg (xor:SI (match_dup 0) 182863d1a8abSmrg (const_int 31))) 182963d1a8abSmrg (clobber (reg:CC CC_REG))])] 183063d1a8abSmrg "TARGET_AM33" 183163d1a8abSmrg) 183263d1a8abSmrg 183363d1a8abSmrg(define_insn "*bsch" 183463d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 183563d1a8abSmrg (unspec:SI [(match_operand:SI 1 "register_operand" "r") 183663d1a8abSmrg (match_operand:SI 2 "nonmemory_operand" "0")] 183763d1a8abSmrg UNSPEC_BSCH)) 183863d1a8abSmrg (clobber (reg:CC CC_REG))] 183963d1a8abSmrg "TARGET_AM33" 184063d1a8abSmrg "bsch %1, %0" 184163d1a8abSmrg) 184263d1a8abSmrg 184363d1a8abSmrg;; ---------------------------------------------------------------------- 184463d1a8abSmrg;; FP INSTRUCTIONS 184563d1a8abSmrg;; ---------------------------------------------------------------------- 184663d1a8abSmrg 184763d1a8abSmrg(define_insn "abssf2" 184863d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=f,f") 184963d1a8abSmrg (abs:SF (match_operand:SF 1 "register_operand" "0,?f")))] 185063d1a8abSmrg "TARGET_AM33_2" 185163d1a8abSmrg "@ 185263d1a8abSmrg fabs %0 185363d1a8abSmrg fabs %1, %0" 185463d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 185563d1a8abSmrg (const_int 17) (const_int 14)))] 185663d1a8abSmrg) 185763d1a8abSmrg 185863d1a8abSmrg(define_insn "negsf2" 185963d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=f,f") 186063d1a8abSmrg (neg:SF (match_operand:SF 1 "register_operand" "0,?f")))] 186163d1a8abSmrg "TARGET_AM33_2" 186263d1a8abSmrg "@ 186363d1a8abSmrg fneg %0 186463d1a8abSmrg fneg %1, %0" 186563d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 186663d1a8abSmrg (const_int 17) (const_int 14)))] 186763d1a8abSmrg) 186863d1a8abSmrg 186963d1a8abSmrg(define_expand "sqrtsf2" 187063d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "") 187163d1a8abSmrg (sqrt:SF (match_operand:SF 1 "register_operand" "")))] 187263d1a8abSmrg "TARGET_AM33_2 && flag_unsafe_math_optimizations" 187363d1a8abSmrg{ 187463d1a8abSmrg rtx scratch = gen_reg_rtx (SFmode); 187563d1a8abSmrg emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode))); 187663d1a8abSmrg emit_insn (gen_divsf3 (operands[0], force_reg (SFmode, CONST1_RTX (SFmode)), 187763d1a8abSmrg scratch)); 187863d1a8abSmrg DONE; 187963d1a8abSmrg}) 188063d1a8abSmrg 188163d1a8abSmrg(define_insn "rsqrtsf2" 188263d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=f,f") 188363d1a8abSmrg (div:SF (match_operand:SF 2 "const_1f_operand" "F,F") 188463d1a8abSmrg (sqrt:SF (match_operand:SF 1 "register_operand" "0,?f")))) 188563d1a8abSmrg (clobber (reg:CC_FLOAT CC_REG))] 188663d1a8abSmrg "TARGET_AM33_2" 188763d1a8abSmrg "@ 188863d1a8abSmrg frsqrt %0 188963d1a8abSmrg frsqrt %1, %0" 189063d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 189163d1a8abSmrg (const_int 4753) (const_int 2327)))] 189263d1a8abSmrg) 189363d1a8abSmrg 189463d1a8abSmrg(define_insn "addsf3" 189563d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=f,f") 189663d1a8abSmrg (plus:SF (match_operand:SF 1 "register_operand" "%0,f") 189763d1a8abSmrg (match_operand:SF 2 "nonmemory_operand" "f,?fF"))) 189863d1a8abSmrg (clobber (reg:CC_FLOAT CC_REG))] 189963d1a8abSmrg "TARGET_AM33_2" 190063d1a8abSmrg "@ 190163d1a8abSmrg fadd %2, %0 190263d1a8abSmrg fadd %2, %1, %0" 190363d1a8abSmrg [(set_attr_alternative "timings" 190463d1a8abSmrg [(if_then_else (eq_attr "cpu" "am34") 190563d1a8abSmrg (const_int 17) (const_int 14)) 190663d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 190763d1a8abSmrg (const_int 17) (const_int 25)) 190863d1a8abSmrg ])] 190963d1a8abSmrg) 191063d1a8abSmrg 191163d1a8abSmrg(define_insn "subsf3" 191263d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=f,f") 191363d1a8abSmrg (minus:SF (match_operand:SF 1 "register_operand" "0,f") 191463d1a8abSmrg (match_operand:SF 2 "nonmemory_operand" "f,?fF"))) 191563d1a8abSmrg (clobber (reg:CC_FLOAT CC_REG))] 191663d1a8abSmrg "TARGET_AM33_2" 191763d1a8abSmrg "@ 191863d1a8abSmrg fsub %2, %0 191963d1a8abSmrg fsub %2, %1, %0" 192063d1a8abSmrg [(set_attr_alternative "timings" 192163d1a8abSmrg [(if_then_else (eq_attr "cpu" "am34") 192263d1a8abSmrg (const_int 17) (const_int 14)) 192363d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 192463d1a8abSmrg (const_int 17) (const_int 25)) 192563d1a8abSmrg ])] 192663d1a8abSmrg) 192763d1a8abSmrg 192863d1a8abSmrg(define_insn "mulsf3" 192963d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=f,f") 193063d1a8abSmrg (mult:SF (match_operand:SF 1 "register_operand" "%0,f") 193163d1a8abSmrg (match_operand:SF 2 "nonmemory_operand" "f,?fF"))) 193263d1a8abSmrg (clobber (reg:CC_FLOAT CC_REG)) 193363d1a8abSmrg ] 193463d1a8abSmrg "TARGET_AM33_2" 193563d1a8abSmrg "@ 193663d1a8abSmrg fmul %2, %0 193763d1a8abSmrg fmul %2, %1, %0" 193863d1a8abSmrg [(set_attr_alternative "timings" 193963d1a8abSmrg [(if_then_else (eq_attr "cpu" "am34") 194063d1a8abSmrg (const_int 17) (const_int 14)) 194163d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 194263d1a8abSmrg (const_int 17) (const_int 25)) 194363d1a8abSmrg ])] 194463d1a8abSmrg) 194563d1a8abSmrg 194663d1a8abSmrg(define_insn "divsf3" 194763d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=f,f") 194863d1a8abSmrg (div:SF (match_operand:SF 1 "register_operand" "0,f") 194963d1a8abSmrg (match_operand:SF 2 "nonmemory_operand" "f,?fF"))) 195063d1a8abSmrg (clobber (reg:CC_FLOAT CC_REG))] 195163d1a8abSmrg "TARGET_AM33_2" 195263d1a8abSmrg "@ 195363d1a8abSmrg fdiv %2, %0 195463d1a8abSmrg fdiv %2, %1, %0" 195563d1a8abSmrg [(set_attr_alternative "timings" 195663d1a8abSmrg [(if_then_else (eq_attr "cpu" "am34") 195763d1a8abSmrg (const_int 2531) (const_int 1216)) 195863d1a8abSmrg (if_then_else (eq_attr "cpu" "am34") 195963d1a8abSmrg (const_int 2531) (const_int 1317)) 196063d1a8abSmrg ])] 196163d1a8abSmrg) 196263d1a8abSmrg 196363d1a8abSmrg(define_insn "fmasf4" 196463d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=c") 196563d1a8abSmrg (fma:SF (match_operand:SF 1 "register_operand" "f") 196663d1a8abSmrg (match_operand:SF 2 "register_operand" "f") 196763d1a8abSmrg (match_operand:SF 3 "register_operand" "f"))) 196863d1a8abSmrg (clobber (reg:CC_FLOAT CC_REG)) 196963d1a8abSmrg ] 197063d1a8abSmrg "TARGET_AM33_2" 197163d1a8abSmrg "fmadd %1, %2, %3, %0" 197263d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 197363d1a8abSmrg (const_int 17) (const_int 24)))] 197463d1a8abSmrg) 197563d1a8abSmrg 197663d1a8abSmrg(define_insn "fmssf4" 197763d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=c") 197863d1a8abSmrg (fma:SF (match_operand:SF 1 "register_operand" "f") 197963d1a8abSmrg (match_operand:SF 2 "register_operand" "f") 198063d1a8abSmrg (neg:SF (match_operand:SF 3 "register_operand" "f")))) 198163d1a8abSmrg (clobber (reg:CC_FLOAT CC_REG)) 198263d1a8abSmrg ] 198363d1a8abSmrg "TARGET_AM33_2" 198463d1a8abSmrg "fmsub %1, %2, %3, %0" 198563d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 198663d1a8abSmrg (const_int 17) (const_int 24)))] 198763d1a8abSmrg) 198863d1a8abSmrg 198963d1a8abSmrg(define_insn "fnmasf4" 199063d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=c") 199163d1a8abSmrg (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) 199263d1a8abSmrg (match_operand:SF 2 "register_operand" "f") 199363d1a8abSmrg (match_operand:SF 3 "register_operand" "f"))) 199463d1a8abSmrg (clobber (reg:CC_FLOAT CC_REG)) 199563d1a8abSmrg ] 199663d1a8abSmrg "TARGET_AM33_2" 199763d1a8abSmrg "fnmadd %1, %2, %3, %0" 199863d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 199963d1a8abSmrg (const_int 17) (const_int 24)))] 200063d1a8abSmrg) 200163d1a8abSmrg 200263d1a8abSmrg(define_insn "fnmssf4" 200363d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=c") 200463d1a8abSmrg (fma:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) 200563d1a8abSmrg (match_operand:SF 2 "register_operand" "f") 200663d1a8abSmrg (neg:SF (match_operand:SF 3 "register_operand" "f")))) 200763d1a8abSmrg (clobber (reg:CC_FLOAT CC_REG)) 200863d1a8abSmrg ] 200963d1a8abSmrg "TARGET_AM33_2" 201063d1a8abSmrg "fnmsub %1, %2, %3, %0" 201163d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 201263d1a8abSmrg (const_int 17) (const_int 24)))] 201363d1a8abSmrg) 201463d1a8abSmrg 201563d1a8abSmrg;; ---------------------------------------------------------------------- 201663d1a8abSmrg;; PROLOGUE/EPILOGUE 201763d1a8abSmrg;; ---------------------------------------------------------------------- 201863d1a8abSmrg(define_expand "prologue" 201963d1a8abSmrg [(const_int 0)] 202063d1a8abSmrg "" 202163d1a8abSmrg { mn10300_expand_prologue (); DONE; } 202263d1a8abSmrg) 202363d1a8abSmrg 202463d1a8abSmrg(define_expand "epilogue" 202563d1a8abSmrg [(return)] 202663d1a8abSmrg "" 202763d1a8abSmrg { mn10300_expand_epilogue (); DONE; } 202863d1a8abSmrg) 202963d1a8abSmrg 203063d1a8abSmrg(define_insn "return" 203163d1a8abSmrg [(return)] 203263d1a8abSmrg "mn10300_can_use_rets_insn ()" 203363d1a8abSmrg{ 203463d1a8abSmrg /* The RETF insn is 4 cycles faster than RETS, though 1 byte larger. */ 203563d1a8abSmrg if (optimize_insn_for_speed_p () && mn10300_can_use_retf_insn ()) 203663d1a8abSmrg return "retf [],0"; 203763d1a8abSmrg else 203863d1a8abSmrg return "rets"; 203963d1a8abSmrg}) 204063d1a8abSmrg 204163d1a8abSmrg(define_insn "return_ret" 204263d1a8abSmrg [(return) 204363d1a8abSmrg (use (match_operand:SI 0 "const_int_operand" ""))] 204463d1a8abSmrg "" 204563d1a8abSmrg{ 204663d1a8abSmrg /* The RETF insn is up to 3 cycles faster than RET. */ 204763d1a8abSmrg fputs ((mn10300_can_use_retf_insn () ? "\tretf " : "\tret "), asm_out_file); 204863d1a8abSmrg mn10300_print_reg_list (asm_out_file, mn10300_get_live_callee_saved_regs (NULL)); 204963d1a8abSmrg fprintf (asm_out_file, ",%d\n", (int) INTVAL (operands[0])); 205063d1a8abSmrg return ""; 205163d1a8abSmrg}) 205263d1a8abSmrg 205363d1a8abSmrg;; This instruction matches one generated by mn10300_gen_multiple_store() 205463d1a8abSmrg(define_insn "store_movm" 205563d1a8abSmrg [(match_parallel 0 "mn10300_store_multiple_operation" 205663d1a8abSmrg [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand 1 "" "")))])] 205763d1a8abSmrg "" 205863d1a8abSmrg{ 205963d1a8abSmrg fputs ("\tmovm ", asm_out_file); 206063d1a8abSmrg mn10300_print_reg_list (asm_out_file, 206163d1a8abSmrg mn10300_store_multiple_regs (operands[0])); 206263d1a8abSmrg fprintf (asm_out_file, ",(sp)\n"); 206363d1a8abSmrg return ""; 206463d1a8abSmrg} 206563d1a8abSmrg ;; Assume that no more than 8 registers will be pushed. 206663d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 206763d1a8abSmrg (const_int 99) (const_int 88)))] 206863d1a8abSmrg) 206963d1a8abSmrg 207063d1a8abSmrg(define_expand "load_pic" 207163d1a8abSmrg [(const_int 0)] 207263d1a8abSmrg "flag_pic" 207363d1a8abSmrg{ 207463d1a8abSmrg if (TARGET_AM33) 207563d1a8abSmrg emit_insn (gen_am33_load_pic (pic_offset_table_rtx)); 207663d1a8abSmrg else if (mn10300_frame_size () == 0) 207763d1a8abSmrg emit_insn (gen_mn10300_load_pic0 (pic_offset_table_rtx)); 207863d1a8abSmrg else 207963d1a8abSmrg emit_insn (gen_mn10300_load_pic1 (pic_offset_table_rtx)); 208063d1a8abSmrg DONE; 208163d1a8abSmrg}) 208263d1a8abSmrg 208363d1a8abSmrg(define_insn "am33_load_pic" 208463d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=a") 208563d1a8abSmrg (unspec:SI [(const_int 0)] UNSPEC_GOT)) 208663d1a8abSmrg (clobber (reg:CC CC_REG))] 208763d1a8abSmrg "TARGET_AM33" 208863d1a8abSmrg{ 208963d1a8abSmrg operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); 209063d1a8abSmrg return ".LPIC%=:\;mov pc,%0\;add %1-(.LPIC%=-.),%0"; 209163d1a8abSmrg} 209263d1a8abSmrg [(set_attr "timings" "33")] 209363d1a8abSmrg) 209463d1a8abSmrg 209563d1a8abSmrg;; Load pic register with push/pop of stack. 209663d1a8abSmrg(define_insn "mn10300_load_pic0" 209763d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=a") 209863d1a8abSmrg (unspec:SI [(const_int 0)] UNSPEC_GOT)) 209963d1a8abSmrg (clobber (reg:SI MDR_REG)) 210063d1a8abSmrg (clobber (reg:CC CC_REG))] 210163d1a8abSmrg "" 210263d1a8abSmrg{ 210363d1a8abSmrg operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); 210463d1a8abSmrg return ("add -4,sp\;" 210563d1a8abSmrg "calls .LPIC%=\n" 210663d1a8abSmrg ".LPIC%=:\;" 210763d1a8abSmrg "movm (sp),[%0]\;" 210863d1a8abSmrg "add %1-(.LPIC%=-.),%0"); 210963d1a8abSmrg} 211063d1a8abSmrg [(set_attr "timings" "88")] 211163d1a8abSmrg) 211263d1a8abSmrg 211363d1a8abSmrg;; Load pic register re-using existing stack space. 211463d1a8abSmrg(define_insn "mn10300_load_pic1" 211563d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=a") 211663d1a8abSmrg (unspec:SI [(const_int 0)] UNSPEC_GOT)) 211763d1a8abSmrg (clobber (mem:SI (reg:SI SP_REG))) 211863d1a8abSmrg (clobber (reg:SI MDR_REG)) 211963d1a8abSmrg (clobber (reg:CC CC_REG))] 212063d1a8abSmrg "" 212163d1a8abSmrg{ 212263d1a8abSmrg operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME); 212363d1a8abSmrg return ("calls .LPIC%=\n" 212463d1a8abSmrg ".LPIC%=:\;" 212563d1a8abSmrg "mov (sp),%0\;" 212663d1a8abSmrg "add %1-(.LPIC%=-.),%0"); 212763d1a8abSmrg} 212863d1a8abSmrg [(set_attr "timings" "66")] 212963d1a8abSmrg) 213063d1a8abSmrg 213163d1a8abSmrg;; The mode on operand 3 has been deliberately omitted because it 213263d1a8abSmrg;; can be either SI (for arithmetic operations) or QI (for shifts). 213363d1a8abSmrg(define_insn "liw" 213463d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 213563d1a8abSmrg (unspec:SI [(match_dup 0) 213663d1a8abSmrg (match_operand 2 "liw_operand" "rO") 213763d1a8abSmrg (match_operand:SI 4 "const_int_operand" "")] 213863d1a8abSmrg UNSPEC_LIW)) 213963d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=r") 214063d1a8abSmrg (unspec:SI [(match_dup 1) 214163d1a8abSmrg (match_operand 3 "liw_operand" "rO") 214263d1a8abSmrg (match_operand:SI 5 "const_int_operand" "")] 214363d1a8abSmrg UNSPEC_LIW))] 214463d1a8abSmrg "TARGET_ALLOW_LIW" 214563d1a8abSmrg "%W4_%W5 %2, %0, %3, %1" 214663d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 214763d1a8abSmrg (const_int 13) (const_int 12)))] 214863d1a8abSmrg) 214963d1a8abSmrg 215063d1a8abSmrg;; The mode on operand 1 has been deliberately omitted because it 215163d1a8abSmrg;; can be either SI (for arithmetic operations) or QI (for shifts). 215263d1a8abSmrg(define_insn "cmp_liw" 215363d1a8abSmrg [(set (reg:CC CC_REG) 215463d1a8abSmrg (compare:CC (match_operand:SI 2 "register_operand" "r") 215563d1a8abSmrg (match_operand 3 "liw_operand" "rO"))) 215663d1a8abSmrg (set (match_operand:SI 0 "register_operand" "=r") 215763d1a8abSmrg (unspec:SI [(match_dup 0) 215863d1a8abSmrg (match_operand 1 "liw_operand" "rO") 215963d1a8abSmrg (match_operand:SI 4 "const_int_operand" "")] 216063d1a8abSmrg UNSPEC_LIW))] 216163d1a8abSmrg "TARGET_ALLOW_LIW" 216263d1a8abSmrg "cmp_%W4 %3, %2, %1, %0" 216363d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 216463d1a8abSmrg (const_int 13) (const_int 12)))] 216563d1a8abSmrg) 216663d1a8abSmrg 216763d1a8abSmrg(define_insn "liw_cmp" 216863d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 216963d1a8abSmrg (unspec:SI [(match_dup 0) 217063d1a8abSmrg (match_operand 1 "liw_operand" "rO") 217163d1a8abSmrg (match_operand:SI 4 "const_int_operand" "")] 217263d1a8abSmrg UNSPEC_LIW)) 217363d1a8abSmrg (set (reg:CC CC_REG) 217463d1a8abSmrg (compare:CC (match_operand:SI 2 "register_operand" "r") 217563d1a8abSmrg (match_operand 3 "liw_operand" "rO")))] 217663d1a8abSmrg "TARGET_ALLOW_LIW" 217763d1a8abSmrg "%W4_cmp %1, %0, %3, %2" 217863d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") 217963d1a8abSmrg (const_int 13) (const_int 12)))] 218063d1a8abSmrg) 218163d1a8abSmrg 218263d1a8abSmrg;; Note - in theory the doloop patterns could be used here to express 218363d1a8abSmrg;; the SETLB and Lcc instructions. In practice this does not work because 218463d1a8abSmrg;; the acceptable forms of the doloop patterns do not include UNSPECs 218563d1a8abSmrg;; and without them gcc's basic block reordering code can duplicate the 218663d1a8abSmrg;; doloop_end pattern, leading to bogus multiple decrements of the loop 218763d1a8abSmrg;; counter. 218863d1a8abSmrg 218963d1a8abSmrg(define_insn "setlb" 219063d1a8abSmrg [(unspec [(const_int 0)] UNSPEC_SETLB)] 219163d1a8abSmrg "TARGET_AM33 && TARGET_ALLOW_SETLB" 219263d1a8abSmrg "setlb" 219363d1a8abSmrg) 219463d1a8abSmrg 219563d1a8abSmrg(define_insn "Lcc" 219663d1a8abSmrg [(set (pc) 219763d1a8abSmrg (if_then_else (match_operator 0 "comparison_operator" 219863d1a8abSmrg [(reg:CC CC_REG) (const_int 0)]) 219963d1a8abSmrg (label_ref (match_operand 1 "" "")) 220063d1a8abSmrg (pc))) 220163d1a8abSmrg (unspec [(const_int 1)] UNSPEC_SETLB)] 220263d1a8abSmrg "TARGET_AM33 && TARGET_ALLOW_SETLB" 220363d1a8abSmrg "L%b0 # loop back to: %1" 220463d1a8abSmrg) 220563d1a8abSmrg 220663d1a8abSmrg(define_insn "FLcc" 220763d1a8abSmrg [(set (pc) 220863d1a8abSmrg (if_then_else (match_operator 0 "comparison_operator" 220963d1a8abSmrg [(reg:CC_FLOAT CC_REG) (const_int 0)]) 221063d1a8abSmrg (label_ref (match_operand 1 "" "")) 221163d1a8abSmrg (pc))) 221263d1a8abSmrg (unspec [(const_int 2)] UNSPEC_SETLB)] 221363d1a8abSmrg "TARGET_AM33_2 && TARGET_ALLOW_SETLB" 221463d1a8abSmrg "FL%b0 # loop back to: %1" 221563d1a8abSmrg [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") (const_int 44) (const_int 11)))] 221663d1a8abSmrg) 2217