diff options
Diffstat (limited to 'gcc/config/ip2k/ip2k.md')
-rw-r--r-- | gcc/config/ip2k/ip2k.md | 6902 |
1 files changed, 0 insertions, 6902 deletions
diff --git a/gcc/config/ip2k/ip2k.md b/gcc/config/ip2k/ip2k.md deleted file mode 100644 index cc64a43f2b9..00000000000 --- a/gcc/config/ip2k/ip2k.md +++ /dev/null @@ -1,6902 +0,0 @@ -;; -*- Mode: Scheme -*- -;; GCC machine description for Ubicom IP2022 Communications Controller. -;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. -;; Contributed by Red Hat, Inc and Ubicom, Inc. -;; -;; This file is part of GNU CC. -;; -;; GNU CC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. -;; -;; GNU CC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. */ - -;; Default all instruction lengths to two bytes (one 16-bit instruction). -;; -(define_attr "length" "" (const_int 2)) - -;; Define if we can "skip" an insn or not -(define_attr "skip" "no,yes" (const_string "no")) - -;; Define an insn clobbers WREG or not -(define_attr "clobberw" "no,yes" (const_string "yes")) - -;; Performance Issues: -;; -;; With the IP2k only having one really useful pointer register we have to -;; make most of our instruction patterns only match one offsettable address -;; before addressing becomes strict whereas afterwards of course we can use -;; any register details that have become fixed. As we've already committed -;; any reloads at this point of course we're a little late so we have to use -;; a number of peephole2 optimizations to remerge viable patterns. We can -;; do a bit more tidying up in the machine-dependent reorg pass to try and -;; make things better still. None of this is ideal, but it's *much* better -;; than nothing. - -;; Constraints: -;; -;; I - -255..-1 - all other literal values have to be loaded -;; J - 0..7 - valid bit number in a register -;; K - 0..127 - valid offset for addressing mode -;; L - 1..127 - positive count suitable for shift. -;; M - -1 as a literal value -;; N - +1 as a literal value -;; O - zero -;; P - 0..255 -;; -;; a - DP or IP registers (general address) -;; f - IP register -;; j - IPL register -;; k - IPH register -;; b - DP register -;; y - DPH register -;; z - DPL register -;; q - SP register -;; c - DP or SP registers (offsettable address) -;; d - non-pointer registers (not SP, DP, IP) -;; u - non-SP registers (everything except SP) -;; -;; R - Indirect thru IP - Avoid this except for QI mode, since we -;; can't access extra bytes. -;; S - Short (stack/dp address). Pointer with 0..127 displacement -;; Note that 0(SP) has undefined contents due to post-decrement push -;; T - data-section immediate value. A CONST_INT or SYMBOL_REF into .data - -;; Special assembly-language format effectors: -;; -;; ABCD - -;; Reference up to 4 big-endian registers - %A0 is Rn+0, while %D0 is Rn+3 -;; STUVWXYZ - -;; Reference up to 8 big-endian registers - %S0 is Rn+0, while %Z0 is Rn+7 -;; -;; H - High part of 16 bit address or literal %hi8data(v) or %hi8insn(v) -;; L - Low part of 16 bit address or literal %lo8data(v) or %lo8insn(v) -;; b - print a literal value with no punctuation (typically bit selector) -;; e - print 1 << v ('exponent') -;; n - print negative number -;; x - print 16 bit hex number -;; < - interior stack push; adjust any stack-relative operands accordingly -;; > - interior stack pop; clear adjustment. - -;; -;; Basic operations to move data in and out of fr's. Also extended to -;; cover the loading of w with immediates -;; - -(define_insn "*movqi_w_gen" - [(set (reg:QI 10) - (match_operand:QI 0 "general_operand" "rSi"))] - "(ip2k_reorg_split_qimode)" - "mov\\tw,%0" - [(set_attr "skip" "yes")]) - -(define_insn "*movqi_fr_w" - [(set (match_operand:QI 0 "nonimmediate_operand" "=rS") - (reg:QI 10))] - "(ip2k_reorg_split_qimode)" - "mov\\t%0,w" - [(set_attr "skip" "yes") - (set_attr "clobberw" "no")]) - - -;; Handle the cases where we get back to back redundant mov patterns issued. -;; This of course sounds somewhat absurd but is actually reasonably common -;; because we aren't able to match certain patterns before registers are -;; chosen. This is particularly true of memory to memory operations where -;; we can't provide patterns that will guarantee to match every time because -;; this would require reloads in the middle of instructions. If we -;; discover a case that doesn't need a reload of course then this combiner -;; operation will tidy up for us. -;; -;; Warning! Whilst it would be nice to match operand 0 as a general operand -;; we mustn't do so because this doesn't work with the REG_DEAD check. -;; -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "ip2k_gen_operand" "")) - (set (match_operand 2 "ip2k_split_dest_operand" "") - (match_dup 0))] - "(peep2_reg_dead_p (2, operands[0]) - && ! (REG_P (operands[2]) && REGNO (operands[2]) == REG_SP) - && (REG_P (operands[2]) - || ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0])))))" - [(set (match_dup 2) - (match_dup 1))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "immediate_operand" "")) - (set (match_operand 2 "ip2k_gen_operand" "") - (match_dup 0))] - "(peep2_reg_dead_p (2, operands[0]) - && ! (REG_P (operands[2]) && REGNO (operands[2]) == REG_SP) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 2) - (match_dup 1))] - "") - -;; -;; Move 8-bit integers. -;; - -(define_expand "movqi" - [(set (match_operand:QI 0 "" "") - (match_operand:QI 1 "" ""))] - "" - "") - -(define_insn "*pushqi" - [(set (match_operand:QI 0 "push_operand" "=<") - (match_operand:QI 1 "general_operand" "g"))] - "" - "push\\t%1" - [(set_attr "skip" "yes") - (set_attr "clobberw" "no")]) - -;; IP isn't offsettable but we can fake this behaviour here and win if we would -;; otherwise use DP and require a reload from IP. This instruction is only -;; matched by peephole2 operations. -;; -(define_insn "*movqi_to_ip_plus_offs" - [(set (mem:QI (plus:HI (reg:HI 4) - (match_operand 0 "const_int_operand" "P,P"))) - (match_operand:QI 1 "general_operand" "O,g"))] - "reload_completed && (INTVAL (operands[0]) < 0x100)" - "*{ - if (INTVAL (operands[0]) == 1) - OUT_AS1 (inc, ipl); - else - { - OUT_AS2 (mov, w, %0); - OUT_AS2 (add, ipl, w); - } - - switch (which_alternative) - { - case 0: - OUT_AS1 (clr, (IP)); - break; - - case 1: - OUT_AS1 (push, %1%<); - OUT_AS1 (pop, (IP)%>); - break; - } - - if (!find_regno_note (insn, REG_DEAD, REG_IP)) - { - if (INTVAL (operands[0]) == 1) - OUT_AS1 (dec, ipl); - else - OUT_AS2 (sub, ipl, w); - } - return \"\"; - }") - -;; IP isn't offsettable but we can fake this behaviour here and win if we would -;; otherwise use DP and require a reload from IP. This instruction is only -;; matched by peephole2 operations. -;; -(define_insn "*movqi_from_ip_plus_offs" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g") - (mem:QI (plus:HI (reg:HI 4) - (match_operand 1 "const_int_operand" "P"))))] - "reload_completed && (INTVAL (operands[1]) < 0x100)" - "*{ - if (INTVAL (operands[1]) == 1) - OUT_AS1 (inc, ipl); - else - { - OUT_AS2 (mov, w, %1); - OUT_AS2 (add, ipl, w); - } - OUT_AS1 (push, (IP)%<); - OUT_AS1 (pop, %0%>); - if (!find_regno_note (insn, REG_DEAD, REG_IP) - && ip2k_xexp_not_uses_reg_p (operands[0], REG_IP, 2)) - { - if (INTVAL (operands[1]) == 1) - OUT_AS1 (dec, ipl); - else - OUT_AS2 (sub, ipl, w); - } - return \"\"; - }") - -(define_insn_and_split "*movqi" - [(set (match_operand:QI 0 "nonimmediate_operand" "=roR,roR,r, rS,roR") - (match_operand:QI 1 "general_operand" " O, ri,o,rioR,rSi"))] - "" - "@ - clr\\t%0 - # - # - # - #" - "(ip2k_reorg_split_qimode - && (GET_CODE (operands[1]) != CONST_INT - || INTVAL (operands[1]) != 0))" - [(set (reg:QI 10) (match_dup 1)) - (set (match_dup 0) (reg:QI 10))] - "" - [(set_attr "skip" "yes,no,no,no,no") - (set_attr "clobberw" "no,yes,yes,yes,yes")]) - -(define_peephole2 - [(set (reg:HI 12) - (reg:HI 4)) - (set (match_operand:QI 0 "nonimmediate_operand" "") - (mem:QI (plus:HI (reg:HI 12) - (match_operand 1 "const_int_operand" ""))))] - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && peep2_regno_dead_p (2, REG_DP) - && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2) - && (INTVAL (operands[1]) < 0x100))" - [(set (match_dup 0) - (mem:QI (plus:HI (reg:HI 4) - (match_dup 1))))] - "") - -(define_peephole2 - [(set (reg:HI 12) - (reg:HI 4)) - (set (mem:QI (plus:HI (reg:HI 12) - (match_operand 0 "const_int_operand" ""))) - (match_operand:QI 1 "general_operand" ""))] - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && peep2_regno_dead_p (2, REG_DP) - && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2) - && (INTVAL (operands[0]) < 0x100))" - [(set (mem:QI (plus:HI (reg:HI 4) - (match_dup 0))) - (match_dup 1))] - "") - -(define_peephole2 - [(set (match_operand:QI 0 "register_operand" "") - (mem:QI (plus:HI (reg:HI 4) - (match_operand 1 "const_int_operand" "")))) - (set (match_operand:QI 2 "nonimmediate_operand" "") - (match_dup 0))] - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && peep2_reg_dead_p (2, operands[0]))" - [(set (match_dup 2) - (mem:QI (plus:HI (reg:HI 4) - (match_dup 1))))] - "") - -;; We sometimes want to copy a value twice, usually when we copy a value into -;; both a structure slot and into a temporary register. We can win here -;; because gcc doesn't know about ways of reusing w while we're copying. -;; -(define_insn_and_split "*movqi_twice" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g") - (match_operand:QI 1 "general_operand" "g")) - (set (match_operand:QI 2 "nonimmediate_operand" "=g") - (match_dup 1))] - "ip2k_reorg_merge_qimode" - "mov\\tw,%1\;mov\\t%0,w\;mov\\t%2,w" - "(ip2k_reorg_split_qimode)" - [(set (reg:QI 10) (match_dup 1)) - (set (match_dup 0) (reg:QI 10)) - (set (match_dup 2) (reg:QI 10))] - "") - -;; Don't try to match until we've removed redundant reloads. Often this -;; simplification will remove the need to do two moves! -;; -(define_peephole2 - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (match_operand:QI 1 "general_operand" "")) - (set (match_operand:QI 2 "nonimmediate_operand" "") - (match_dup 0))] - "(ip2k_reorg_merge_qimode - && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (match_dup 2) - (match_dup 1))])] - "") - -;; Don't try to match until we've removed redundant reloads. Often this -;; simplification will remove the need to do two moves! -;; -(define_peephole2 - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (match_operand:QI 1 "general_operand" "")) - (set (match_operand:QI 2 "nonimmediate_operand" "") - (match_dup 1))] - "(ip2k_reorg_merge_qimode - && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (match_dup 2) - (match_dup 1))])] - "") - -;; -;; Move 16-bit integers. -;; - -(define_expand "movhi" - [(set (match_operand:HI 0 "" "") - (match_operand:HI 1 "" ""))] - "" - "") - -(define_insn "*pushhi_ip" - [(set (match_operand:HI 0 "push_operand" "=<") - (mem:HI (reg:HI 4)))] - "reload_completed" - "inc\\tipl\;push\\t(IP)\;dec\\tipl\;push\\t(IP)" - [(set_attr "clobberw" "no")]) - -(define_insn "*movhi_to_ip" - [(set (mem:HI (reg:HI 4)) - (match_operand:HI 0 "general_operand" "O,roi"))] - "reload_completed" - "*{ - switch (which_alternative) - { - case 0: - OUT_AS1 (clr, (IP)); - OUT_AS1 (inc, ipl); - OUT_AS1 (clr, (IP)); - if (!find_regno_note (insn, REG_DEAD, REG_IP)) - OUT_AS1 (dec, ipl); - return \"\"; - - case 1: - OUT_AS2 (mov, w, %H0); - OUT_AS2 (mov, (IP), w); - OUT_AS2 (mov, w, %L0); - OUT_AS1 (inc, ipl); - OUT_AS2 (mov, (IP), w); - if (!find_regno_note (insn, REG_DEAD, REG_IP)) - OUT_AS1 (dec, ipl); - return \"\"; - default: - abort (); - } - }") - -(define_insn "*movhi_from_ip" - [(set (match_operand:HI 0 "nonimmediate_operand" "=f,bqdo") - (mem:HI (reg:HI 4)))] - "reload_completed" - "*{ - switch (which_alternative) - { - case 0: - OUT_AS1 (push, (IP)); - OUT_AS1 (inc, ipl); - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, ipl, w); - OUT_AS1 (pop, iph); - return \"\"; - - case 1: - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, %H0, w); - OUT_AS1 (inc, ipl); - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, %L0, w); - if (!find_regno_note (insn, REG_DEAD, REG_IP)) - OUT_AS1 (dec, ipl); - return \"\"; - default: - abort (); - } - }") - -(define_insn "*movhi_from_ip_plus_offs" - [(set (match_operand:HI 0 "nonimmediate_operand" "=f,bqdo") - (mem:HI (plus:HI (reg:HI 4) - (match_operand 1 "const_int_operand" "P, P"))))] - "reload_completed && (INTVAL (operands[1]) < 0x100)" - "*{ - switch (which_alternative) - { - case 0: - OUT_AS2 (mov, w, %1); - OUT_AS2 (add, ipl, w); - OUT_AS1 (push, (IP)); - OUT_AS1 (inc, ipl); - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, ipl, w); - OUT_AS1 (pop, iph); - return \"\"; - - case 1: - if (INTVAL (operands[1]) == 1) - OUT_AS1 (inc, ipl); - else - { - OUT_AS2 (mov, w, %1); - OUT_AS2 (add, ipl, w); - } - OUT_AS1 (push, (IP)%<); - OUT_AS1 (pop, %H0%>); - OUT_AS1 (inc, ipl); - OUT_AS1 (push, (IP)%<); - OUT_AS1 (pop, %L0%>); - if (!find_regno_note (insn, REG_DEAD, REG_IP)) - { - OUT_AS1 (dec, ipl); - if (INTVAL (operands[1]) == 1) - OUT_AS1 (dec, ipl); - else - OUT_AS2 (sub, ipl, w); - } - return \"\"; - default: - abort (); - } - }") - -(define_insn_and_split "*movhi" - [(set - (match_operand:HI 0 "ip2k_split_dest_operand" "=<,<,uo,b, uS,uo,uo, q,u") - (match_operand:HI 1 "general_operand" "ron,i, n,T,uoi,uS,ui,ui,q"))] - "" - "@ - push\\t%L1%<\;push\\t%H1%> - push\\t%L1%<\;push\\t%H1%> - mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%L1\;mov\\t%L0,w - loadl\\t%x1\;loadh\\t%x1 - mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w - mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w - mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w - mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%L1\;mov\\t%L0,w - mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%L1\;mov\\t%L0,w" - "(ip2k_reorg_split_himode - && (GET_CODE (operands[1]) == CONST_INT - || (push_operand (operands[0], HImode) - && GET_CODE (operands[1]) == REG) - || (register_operand (operands[0], HImode) - && REGNO (operands[0]) >= 0x80 - && ip2k_gen_operand (operands[1], HImode))))" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] - "{ - ip2k_split_words (QImode, HImode, operands); /* Split into 2=3,4=5 */ - }" - [(set_attr "clobberw" "no,no,yes,no,yes,yes,yes,yes,yes")]) - -;; We don't generally use IP for HImode indirections because it's not -;; offsettable, however if we're accessing something that's already pointed -;; to by IP and would otherwise require a reload of DP then we can win by -;; simulating HImode accesses via IP instead. - -(define_peephole2 - [(set (reg:HI 12) - (reg:HI 4)) - (set (mem:HI (reg:HI 12)) - (match_operand:HI 0 "general_operand" ""))] - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2) - && peep2_regno_dead_p (2, REG_DP))" - [(set (mem:HI (reg:HI 4)) - (match_dup 0))] - "") - -(define_peephole2 - [(set (reg:HI 12) - (reg:HI 4)) - (set (match_operand:HI 0 "nonimmediate_operand" "") - (mem:HI (reg:HI 12)))] - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2) - && peep2_regno_dead_p (2, REG_DP))" - [(set (match_dup 0) - (mem:HI (reg:HI 4)))] - "") - -(define_peephole2 - [(set (reg:HI 12) - (reg:HI 4)) - (set (match_operand:HI 0 "nonimmediate_operand" "") - (mem:HI (plus:HI (reg:HI 12) - (match_operand 1 "const_int_operand" ""))))] - ; - ; We only match here if IP and DP both go dead because emulating - ; offsets in conjunction with IP doesn't win unless IP goes - ; dead too. - ; - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && peep2_regno_dead_p (2, REG_DP) - && peep2_regno_dead_p (2, REG_IP) - && (INTVAL (operands[1]) < 0x100))" - [(set (match_dup 0) - (mem:HI (plus:HI (reg:HI 4) - (match_dup 1))))] - "") - -(define_peephole2 - [(set (reg:HI 12) - (reg:HI 4)) - (set (reg:HI 4) - (mem:HI (plus:HI (reg:HI 12) - (match_operand 0 "const_int_operand" ""))))] - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && peep2_regno_dead_p (2, REG_DP) - && (INTVAL (operands[0]) < 0x100))" - [(set (reg:HI 4) - (mem:HI (plus:HI (reg:HI 4) - (match_dup 0))))] - "") - -(define_peephole2 - [(set (match_operand:HI 0 "register_operand" "") - (mem:HI (reg:HI 4))) - (set (match_operand:HI 2 "nonimmediate_operand" "") - (match_dup 0))] - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && peep2_reg_dead_p (2, operands[0]))" - [(set (match_dup 2) - (mem:HI (reg:HI 4)))] - "") - -(define_peephole2 - [(set (match_operand:HI 0 "register_operand" "") - (mem:HI (plus:HI (reg:HI 4) - (match_operand 1 "const_int_operand" "")))) - (set (match_operand:HI 2 "nonimmediate_operand" "") - (match_dup 0))] - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && peep2_reg_dead_p (2, operands[0]) - && (INTVAL (operands[1]) < 0x100))" - [(set (match_dup 2) - (mem:HI (plus:HI (reg:HI 4) - (match_dup 1))))] - "") - -(define_peephole2 - [(set (match_operand:HI 0 "ip2k_nonsp_reg_operand" "") - (match_operand:HI 1 "ip2k_short_operand" "")) - (set (reg:HI 12) - (reg:HI 4)) - (set (mem:HI (reg:HI 12)) - (match_dup 0))] - "(peep2_reg_dead_p (3, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[0], REG_DP, 2) - && peep2_regno_dead_p (3, REG_DP))" - [(set (mem:HI (reg:HI 4)) - (match_dup 1))] - "") - -;; We sometimes want to copy a value twice, usually when we copy a value into -;; both a structure slot and into a temporary register. We can win here -;; because gcc doesn't know about ways of reusing w while we're copying. -;; -(define_insn "*movhi_twice" - [(set (match_operand:HI 0 "ip2k_gen_operand" "=&uS,uS") - (match_operand:HI 1 "ip2k_gen_operand" "uS,uS")) - (set (match_operand:HI 2 "ip2k_gen_operand" "=&uS,uS") - (match_dup 1))] - "ip2k_reorg_split_simode" - "*{ - switch (which_alternative) - { - case 0: - return AS2 (mov, w, %L1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (mov, %L2, w) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (mov, %H2, w); - - case 1: - return AS2 (mov, w, %L1) CR_TAB - AS1 (push, %H1%<) CR_TAB - AS1 (push, %H1%<) CR_TAB - AS1 (pop, %H0%>) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS1 (pop, %H2%>) CR_TAB - AS2 (mov, %L2, w); - default: - abort (); - } - }") - -;; We have to be *very* careful with this one to use predicates that do not -;; allow this to match if there are any register dependencies between the -;; operands. -;; Don't try to match until we've removed redundant reloads. Often this -;; simplification will remove the need to do two moves! -;; -(define_peephole2 - [(set (match_operand:HI 0 "ip2k_gen_operand" "") - (match_operand:HI 1 "ip2k_gen_operand" "")) - (set (match_operand:HI 2 "ip2k_gen_operand" "") - (match_dup 0))] - "(ip2k_reorg_split_simode)" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (match_dup 2) - (match_dup 1))])] - "") - -;; We have to be *very* careful with this one to use predicates that do not -;; allow this to match if there are any register dependencies between the -;; operands. -;; Don't try to match until we've removed redundant reloads. Often this -;; simplification will remove the need to do two moves! -;; -(define_peephole2 - [(set (match_operand:HI 0 "ip2k_gen_operand" "") - (match_operand:HI 1 "ip2k_gen_operand" "")) - (set (match_operand:HI 2 "ip2k_gen_operand" "") - (match_dup 1))] - "(ip2k_reorg_split_simode - && (!REG_P (operands[0]) - || ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 2)))" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (match_dup 2) - (match_dup 1))])] - "") - -;; -;; Move 32-bit integers. -;; - -(define_expand "movsi" - [(set (match_operand:SI 0 "" "") - (match_operand:SI 1 "" ""))] - "" - "") - -(define_insn_and_split "*movsi" - [(set (match_operand:SI 0 "ip2k_split_dest_operand" "=<, ro, S") - (match_operand:SI 1 "general_operand" "roSi,rSi,roi"))] - "" - "#" - "ip2k_reorg_split_simode" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] - "{ - ip2k_split_words (HImode, SImode, operands); /* Split into 2=3,4=5 */ - }") - -;; We sometimes want to copy a value twice, usually when we copy a value into -;; both a structure slot and into a temporary register. We can win here -;; because gcc doesn't know about ways of reusing w while we're copying. -;; -(define_insn "*movsi_twice" - [(set (match_operand:SI 0 "ip2k_gen_operand" "=&uS,uS") - (match_operand:SI 1 "ip2k_gen_operand" "uS,uS")) - (set (match_operand:SI 2 "ip2k_gen_operand" "=&uS,uS") - (match_dup 1))] - "ip2k_reorg_split_dimode" - "*{ - switch (which_alternative) - { - case 0: - return AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (mov, %A2, w) CR_TAB - AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, %B2, w) CR_TAB - AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, %C2, w) CR_TAB - AS2 (mov, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, %D2, w); - - case 1: - return AS2 (mov, w, %D1) CR_TAB - AS1 (push, %C1%<) CR_TAB - AS1 (push, %B1%<) CR_TAB - AS1 (push, %A1%<) CR_TAB - AS1 (push, %C1%<) CR_TAB - AS1 (push, %B1%<) CR_TAB - AS1 (push, %A1%<) CR_TAB - AS1 (pop, %A0%>) CR_TAB - AS1 (pop, %B0%>) CR_TAB - AS1 (pop, %C0%>) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (pop, %A2%>) CR_TAB - AS1 (pop, %B2%>) CR_TAB - AS1 (pop, %C2%>) CR_TAB - AS2 (mov, %D2, w); - default: - abort (); - } - }") - -;; We have to be *very* careful with this one to use predicates that do not -;; allow this to match if there are any register dependencies between the -;; operands. -;; Don't try to match until we've removed redundant reloads. Often this -;; simplification will remove the need to do two moves! -;; -(define_peephole2 - [(set (match_operand:SI 0 "ip2k_gen_operand" "") - (match_operand:SI 1 "ip2k_gen_operand" "")) - (set (match_operand:SI 2 "ip2k_gen_operand" "") - (match_dup 0))] - "(ip2k_reorg_split_dimode - && (!REG_P (operands[0]) - || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 4) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), 4))) - && (!REG_P (operands[1]) - || (ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[1]), 4) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[1]), 4))) - && (!REG_P (operands[2]) - || (ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 4) - && ip2k_xexp_not_uses_reg_p (operands[1], - REGNO (operands[2]), 4))))" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (match_dup 2) - (match_dup 1))])] - "") - -;; We have to be *very* careful with this one to use predicates that do not -;; allow this to match if there are any register dependencies between the -;; operands. -;; Don't try to match until we've removed redundant reloads. Often this -;; simplification will remove the need to do two moves! -;; -(define_peephole2 - [(set (match_operand:SI 0 "ip2k_gen_operand" "") - (match_operand:SI 1 "ip2k_gen_operand" "")) - (set (match_operand:SI 2 "ip2k_gen_operand" "") - (match_dup 1))] - "(ip2k_reorg_split_dimode - && (!REG_P (operands[0]) - || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 4) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), 4))) - && (!REG_P (operands[1]) - || (ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[1]), 4) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[1]), 4))) - && (!REG_P (operands[2]) - || (ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 4) - && ip2k_xexp_not_uses_reg_p (operands[1], - REGNO (operands[2]), 4))))" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (match_dup 2) - (match_dup 1))])] - "") - -;; -;; Move 64-bit integers. -;; - -(define_expand "movdi" - [(set (match_operand:DI 0 "" "") - (match_operand:DI 1 "" ""))] - "" - "") - -(define_insn_and_split "*movdi" - [(set (match_operand:DI 0 "ip2k_split_dest_operand" "=<, ro, S") - (match_operand:DI 1 "general_operand" "roSi,rSi,roi"))] - "" - "#" - "ip2k_reorg_split_dimode" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] - "{ - ip2k_split_words (SImode, DImode, operands); /* Split into 2=3,4=5 */ - }") - -;; -;; Move 32-bit floating point values. -;; - -(define_expand "movsf" - [(set (match_operand:SF 0 "" "") - (match_operand:SF 1 "" ""))] - "" - "if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) - operands[1] = copy_to_mode_reg (SFmode, operands[1]); - ") - -(define_insn_and_split "*movsf" - [(set (match_operand:SF 0 "ip2k_split_dest_operand" "=r<, o") - (match_operand:SF 1 "general_operand" "roi,ri"))] - "(ip2k_short_operand (operands[0], SFmode) - && ip2k_short_operand (operands[1], SFmode)) - || ! (memory_operand (operands[0], SFmode) - && memory_operand (operands[1], SFmode))" - "#" - "(reload_completed || reload_in_progress)" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5)) - (set (match_dup 6) (match_dup 7)) - (set (match_dup 8) (match_dup 9))] - "{ - /* Split into 2=3,4=5 */ - ip2k_split_words (HImode, SImode, operands); - /* Split 4=5 into 6=7,8=9 */ - ip2k_split_words (QImode, HImode, &operands[4]); - operands[0] = operands[2]; - operands[1] = operands[3]; - ip2k_split_words (QImode, HImode, operands); - }") - -;; -;; Move 64-bit floating point values. -;; - -;; -;; Block move operations. -;; - -;; Copy a block of bytes (memcpy()). We expand the definition to convert -;; our memory operand into a register pointer operand instead. -;; -(define_expand "movstrhi" - [(use (match_operand:BLK 0 "memory_operand" "")) - (use (match_operand:BLK 1 "memory_operand" "")) - (use (match_operand:HI 2 "general_operand" "")) - (use (match_operand 3 "const_int_operand" ""))] - "" - "{ - rtx addr0, addr1, count; - - addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); - addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); - - if (GET_CODE (operands[2]) == CONST_INT) - count = gen_int_mode (INTVAL (operands[2]) & 0xffff, HImode); - else - count = operands[2]; - - emit_insn (gen_movstrhi_expanded (addr0, count, addr1)); - DONE; - }") - -;; Block copy instruction. We handle this by calling one of two functions in -;; libgcc. The first of these is a special case (faster) routine that handles -;; constant block sizes under 256 bytes. This one is particularly common -;; because we use it when copying data structures. The second routine handles -;; the general case where we have either a variable block size or one that is -;; greater than 255 bytes. -;; -(define_insn "movstrhi_expanded" - [(set - (mem:BLK - (match_operand:HI 0 "nonimmediate_operand" "rS,ro,rS, rS, ro, rS")) - (mem:BLK - (match_operand:HI 2 "nonimmediate_operand" "ro,rS,rS, ro, rS, rS"))) - (use - (match_operand:HI 1 "general_operand" "P, P, P,rSi,rSi,roi"))] - "" - "@ - push\\t%L1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>\;page\\t__movstrhi_countqi\;call\\t__movstrhi_countqi - push\\t%L1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>\;page\\t__movstrhi_countqi\;call\\t__movstrhi_countqi - push\\t%L1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>\;page\\t__movstrhi_countqi\;call\\t__movstrhi_countqi - push\\t%L1%<\;push\\t%H1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>%>\;page\\t__movstrhi_counthi\;call\\t__movstrhi_counthi - push\\t%L1%<\;push\\t%H1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>%>\;page\\t__movstrhi_counthi\;call\\t__movstrhi_counthi - push\\t%L1%<\;push\\t%H1%<\;push\\t%L2%<\;push\\t%H2%<\;push\\t%L0%<\;push\\t%H0%>%>%>%>%>\;page\\t__movstrhi_counthi\;call\\t__movstrhi_counthi") - - -;; Bit insert -;; -(define_expand "insv" - [(set (zero_extract:QI (match_operand:QI 0 "nonimmediate_operand" "") - (match_operand 1 "immediate_operand" "") ;size - (match_operand 2 "immediate_operand" "")) ;pos - (match_operand:QI 3 "general_operand" ""))] - "" - "{ - if (! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J') - || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) - FAIL; - }") - -(define_insn "*insv" - [(set (zero_extract:QI - (match_operand:QI - 0 "nonimmediate_operand" "+roR,roR,roR,roR,&roR,&roR,&r") - (match_operand - 1 "immediate_operand" "N, N, J, J, N, J, J") ;sz - (match_operand - 2 "immediate_operand" "J, J, J, J, J, J, J"));pos - (match_operand:QI - 3 "general_operand" "MN, O, M, O, roR, rn,oR"))] - "" - "*{ - unsigned int pos = INTVAL (operands[2]), - siz = INTVAL (operands[1]), - mask = (1 << (pos + siz)) - (1 << pos); - - switch (which_alternative) - { - case 0: - return \"setb\\t%0,%b1\"; - - case 1: - return \"clrb\\t%0,%b1\"; - - case 2: - operands[3] = gen_int_mode (mask & 0xff, QImode); - return AS2 (mov, w, %3) CR_TAB - AS2 (or, %0, w); - - case 3: - operands[3] = gen_int_mode (0xff & ~mask, QImode); - return AS2 (mov, w, %3) CR_TAB - AS2 (and, %0, w); - - case 4: - return AS2 (clrb, %0,%b2) CR_TAB - AS2 (snb, %3, 0) CR_TAB - AS2 (setb, %0, %b2); - - case 5: - case 6: - { - static char buff[256]; - char *p = buff; - - /* Clear the destination field */ - - p += sprintf (buff, \"mov\\tw,#$%2.2x\;and\\t%%0,w\;\", - 0xff & ~mask); - - if (CONSTANT_P (operands[3])) - /* Constant can just be or-ed in. */ - { - p += sprintf (p, \"mov\\tw,#$%2.2x\;or\\t%%0,w\", - (INTVAL (operands[3]) << pos) & mask & 0xff); - return buff; - } - - p += sprintf (p, \"mov\\tw,%%3\;\"); /* Value to deposit */ - - /* Shift and mask the value before OR-ing into the destination. */ - - if (pos != 0) - p += sprintf (p, \"mulu\\tw,#%d\;\", 1<<pos); - - p += sprintf (p, \"\;and\\tw,#$%2.2x\;or\\t%%0,w\", mask); - return buff; - } - default: - abort (); - } - }" - [(set_attr "skip" "yes,yes,no,no,no,no,no") - (set_attr "clobberw" "no,no,yes,yes,no,yes,yes")]) - -;; -;; Add bytes -;; - -(define_expand "addqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (plus:QI (match_operand:QI 1 "general_operand" "") - (match_operand:QI 2 "general_operand" "")))] - "" - "") - -(define_insn "*push_addqi3" - [(set (match_operand:QI 0 "push_operand" "=<,<,<") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%g,g,g") - (match_operand:QI 2 "general_operand" "N,M,g")))] - "" - "@ - push\\t%1\;inc\\t1(SP) - push\\t%1\;dec\\t1(SP) - mov\\tw,%2\;add\\tw,%1\;push\\twreg" - [(set_attr "clobberw" "no,no,yes")]) - -(define_insn "*addqi3_w" - [(set - (reg:QI 10) - (plus:QI - (match_operand:QI 0 "nonimmediate_operand" "%rS, g,rS, g, rS, g,rS") - (match_operand:QI 1 "general_operand" "N, N, M, M,rSi,rSi, g")))] - "(ip2k_reorg_split_qimode)" - "@ - inc\\tw,%0 - inc\\tw,%0 - dec\\tw,%0 - dec\\tw,%0 - mov\\tw,%1\;add\\tw,%0 - mov\\tw,%1\;add\\tw,%0 - mov\\tw,%1\;add\\tw,%0" - [(set_attr "skip" "no,no,no,no,no,no,no")]) - -(define_insn_and_split "*addqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=k,k,z,z,djyoR,djyoR,djyoR,djyS, g,rS, g,rS, g, rS,rS") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0, 0, 0, 0, 0,rS, g,rS, g, rS, g,rS") - (match_operand:QI 2 "general_operand" "N,g,N,g, N, M, rSi, g, N, N, M, M,rSi,rSi, g")))] - "" - "@ - incsnz\\t%0\;dec\\tiph - mov\\tw,%2\;add\\t%0,w - incsnz\\t%0\;dec\\tdph - mov\\tw,%2\;add\\t%0,w - inc\\t%0 - dec\\t%0 - mov\\tw,%2\;add\\t%0,w - mov\\tw,%2\;add\\t%0,w - # - # - # - # - # - # - #" - "(ip2k_reorg_split_qimode - && ! rtx_equal_p (operands[0], operands[1]))" - [(set (reg:QI 10) - (plus:QI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (reg:QI 10))] - "" - [(set_attr "skip" "no,no,no,no,yes,yes,no,no,no,no,no,no,no,no,no") - (set_attr - "clobberw" "no,yes,no,yes,no,no,yes,yes,yes,yes,yes,yes,yes,yes,yes")]) - -;; -;; Add 16-bit integers. -;; - -(define_expand "addhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "") - (plus:HI (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - "if (rtx_equal_p (operands[1], operands[2])) - { - /* It is not impossible to wind up with two constants here. - If we simply emit the ashl, we'll generate unrecognizable - instructions. */ - if (! nonimmediate_operand (operands[1], HImode)) - operands[1] = copy_to_mode_reg (HImode, operands[1]); - emit_insn (gen_ashlhi3 (operands[0], operands[1], GEN_INT (1))); - DONE; - } - ") - -(define_insn "*push_addhi3" ; 0 1 2 3 4 5 6 7 - [(set - (match_operand:HI 0 "push_operand" "=<,<, <, <, <, <,<,<") - (plus:HI - (match_operand:HI 1 "nonimmediate_operand" "%uo,q,uo,bf, uo, uS,q,q") - (match_operand:HI 2 "general_operand" "N,N, M, P,uSi,uoi,u,n")))] - "" - "*{ - switch (which_alternative) { - case 0: - return AS1 (push, %L1%<) CR_TAB - AS1 (push, %H1%>) CR_TAB - AS1 (incsnz, 2(SP)) CR_TAB - AS1 (inc, 1(SP)); - - case 1: - return AS2 (mov, w, %H1) CR_TAB - AS1 (push, %L1) CR_TAB - AS1 (push, wreg) CR_TAB - AS1 (incsnz, 2(SP)) CR_TAB - AS1 (inc, 1(SP)); - - case 2: - return AS1 (push, %L1%<) CR_TAB - AS1 (push, %H1%>) CR_TAB - AS2 (mov, w, #-1) CR_TAB - AS2 (add, 2(SP), w) CR_TAB - AS2 (addc, 1(SP), w); - - case 3: - OUT_AS2 (mov, w, %L2); - OUT_AS2 (add, %L1, w); - OUT_AS1 (push, %L1); - OUT_AS1 (push, %H1); - if (!find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) - OUT_AS2 (sub, %L1, w); - return \"\"; - - case 4: - case 5: - return AS2 (mov, w, %L2) CR_TAB - AS2 (add, w, %L1) CR_TAB - AS1 (push, wreg%<) CR_TAB - AS2 (mov, w, %H2) CR_TAB - AS2 (addc, w, %H1) CR_TAB - AS1 (push, wreg%>); - - case 6: - return AS2 (mov, w, %H1) CR_TAB - AS1 (push, %L1) CR_TAB - AS1 (push, wreg) CR_TAB - AS2 (mov, w, %L2) CR_TAB - AS2 (add, 2(SP), w) CR_TAB - AS2 (mov, w, %H2) CR_TAB - AS2 (addc, 1(SP), w); - - case 7: - { - operands[3] = GEN_INT (INTVAL (operands[2]) + 2); - return AS1 (push, %L3) CR_TAB - AS1 (push, %H3) CR_TAB - AS2 (mov, w, %L1) CR_TAB - AS2 (add, 2(SP), w) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (addc, 1(SP), w); - } - default: - abort (); - } - }" - [(set_attr "clobberw" "no,yes,yes,yes,yes,yes,yes,yes")]) - -(define_insn "*push_addhi3_zero_ext" ; 0 1 2 3 - [(set (match_operand:HI 0 "push_operand" "=<, <, <, <") - (plus:HI - (zero_extend:HI - (match_operand:QI 1 "general_operand" "%roRi,roRi,roRi,rSi")) - (match_operand:HI 2 "general_operand" "N, P, rSi,roi")))] - "" - "@ - inc\\tw,%L2\;push\\twreg\;push\\t#0\;rl\\t1(SP) - mov\\tw,%L2\;add\\tw,%1\;push\\twreg\;push\\t#0\;rl\\t1(SP) - mov\\tw,%L2\;add\\tw,%1\;push\\twreg%<\;mov\\tw,%H2\;addc\\tw,$ff\;push\\twreg%> - mov\\tw,%L2\;add\\tw,%1\;push\\twreg%<\;mov\\tw,%H2\;addc\\tw,$ff\;push\\twreg%>") - -(define_insn "*addhi3_imm_zero_ext_w" - [(set - (match_operand:HI 0 "nonimmediate_operand" "=rS,o,a,b,a,a,rS,o,rS,o") - (plus:HI (zero_extend:HI (reg:QI 10)) - (match_operand 1 "immediate_operand" "O,O,M,i,P,I, P,P, i,i")))] - "" - "@ - mov\\t%L0,w\;clr\\t%H0 - mov\\t%L0,w\;clr\\t%H0 - mov\\t%L0,w\;clr\\t%H0\;dec\\t%L0 - loadh\\t%x1\;loadl\\t%x1\;add\\t%L0,w - mov\\t%L0,w\;clr\\t%H0\;mov\\tw,%1\;add\\t%L0,w - mov\\t%L0,w\;clr\\t%H0\;mov\\tw,#%n1\;sub\\t%L0,w - add\\tw,%L1\;mov\\t%L0,w\;clr\\t%H0\;rl\\t%H0 - add\\tw,%L1\;mov\\t%L0,w\;clr\\t%H0\;rl\\t%H0 - add\\tw,%L1\;mov\\t%L0,w\;clr\\t%H0\;mov\\tw,%H1\;addc\\t%H0,w - add\\tw,%L1\;mov\\t%L0,w\;clr\\t%H0\;mov\\tw,%H1\;addc\\t%H0,w") - -(define_insn_and_split "*addhi3_imm_zero_ext" - [(set - (match_operand:HI - 0 "nonimmediate_operand" "=rS, o, rS, o, a, b, a, a, rS, o, rS, o") - (plus:HI - (zero_extend:HI - (match_operand:QI - 1 "general_operand" "%roR,rS,roR,rS,roR,roR,roR,roR,roR,rS,roR,rS")) - (match_operand - 2 "immediate_operand" " O, O, N, N, M, i, P, I, P, P, i, i")))] - "" - "@ - # - # - clr\\t%H0\;incsnz\\tw,%1\;inc\\t%H0\;mov\\t%L0,w - clr\\t%H0\;incsnz\\tw,%1\;inc\\t%H0\;mov\\t%L0,w - # - # - # - # - # - # - # - #" - "(ip2k_reorg_split_qimode - && (GET_CODE (operands[1]) != CONST_INT - || INTVAL (operands[1]) != 1))" - [(set (reg:QI 10) - (match_dup 1)) - (set (match_dup 0) - (plus:HI (zero_extend:HI (reg:QI 10)) - (match_dup 2)))]) - -(define_insn "*addhi3_immediate" ; 0 1 2 3 4 5 6 7 8 9 a b c d e f - [(set (match_operand:HI 0 "nonimmediate_operand" "=a,do,a,do,a,a,a,do,&uo,&uS,bf,bf,bf,&uS,&uo, u") - (plus:HI (match_operand:HI 1 "general_operand" "%0, 0,0, 0,0,0,0, 0, rS, ro,uo,uo,uo, ro, rS,uo") - (match_operand 2 "immediate_operand" "N, N,M, M,P,I,i, i, N, N, M, P, I, i, i, i")))] - "" - "@ - inc\\t%L0 - incsnz\\t%L0\;inc\\t%H0 - dec\\t%L0 - mov\\tw,#-1\;add\\t%L0,w\;addc\\t%H0,w - mov\\tw,%2\;add\\t%L0,w - mov\\tw,#%n2\;sub\\t%L0,w - mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;add\\t%H0,w - mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;addc\\t%H0,w - mov\\tw,%H1\;mov\\t%H0,w\;incsnz\\tw,%L1\;inc\\t%H0\;mov\\t%L0,w - mov\\tw,%H1\;mov\\t%H0,w\;incsnz\\tw,%L1\;inc\\t%H0\;mov\\t%L0,w - mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w\;dec\\t%L0 - mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w\;mov\\tw,%2\;add\\t%L0,w - mov\\tw,%H1\;push\\t%L1%<\;pop\\t%L0%>\;mov\\t%H0,w\;mov\\tw,#%n2\;sub\\t%L0,w - mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%L2\;add\\tw,%L1\;push\\twreg%<\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w\;pop\\t%L0%>" - [(set_attr "skip" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no,no,no") - (set_attr "clobberw" "no,no,no,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes,yes")]) - -(define_insn "*addhi3_nonimmediate" ; 0 1 2 3 4 5 6 7 - [(set (match_operand:HI 0 "nonimmediate_operand" "=&bf,bf,&dS,&do,d,&rS,&rS, o") - (plus:HI (match_operand:HI 1 "general_operand" "%0, 0, 0, 0,0, ro, rS,rS") - (match_operand:HI 2 "nonimmediate_operand" "ro,uo, ro, rS,r, rS, ro,rS")))] - "" - "@ - mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;add\\t%H0,w - mov\\tw,%L2\;push\\t%H2%<\;add\\t%L0,w\;pop\\twreg%>\;add\\t%H0,w - mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;addc\\t%H0,w - mov\\tw,%L2\;add\\t%L0,w\;mov\\tw,%H2\;addc\\t%H0,w - mov\\tw,%L2\;push\\t%H2%<\;add\\t%L0,w\;pop\\twreg%>\;addc\\t%H0,w - mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w") - -(define_insn "*addhi3_nonimm_zero_extend_w" - [(set (match_operand:HI 0 "nonimmediate_operand" "=a,ro,&ro,&rS,&rS, u") - (plus:HI - (zero_extend:HI (reg:QI 10)) - (match_operand:HI 1 "nonimmediate_operand" "0, 0, rS, rS, ro,uo")))] - "" - "@ - add\\t%L0,w - add\\t%L0,w\;clr\\twreg\;addc\\t%H0,w - add\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;addc\\tw,%H1\;mov\\t%H0,w - add\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;addc\\tw,%H1\;mov\\t%H0,w - add\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;addc\\tw,%H1\;mov\\t%H0,w - add\\tw,%L1\;push\\twreg%<\;clr\\twreg\;addc\\tw,%H1\;mov\\t%H0,w\;pop\\t%L0%>" - [(set_attr "skip" "yes,no,no,no,no,no") - (set_attr "clobberw" "no,yes,yes,yes,yes,yes")]) - -(define_insn_and_split "*addhi3_nonimm_zero_extend" - [(set (match_operand:HI 0 "nonimmediate_operand" "=a, ro,&ro,&rS,&rS, u") - (plus:HI - (zero_extend:HI - (match_operand:QI 1 "general_operand" "roR,roR, rS,roR, rS,rS")) - (match_operand:HI 2 "nonimmediate_operand" "0, 0, rS, rS, ro,uo")))] - "" - "#" - "(ip2k_reorg_split_qimode)" - [(set (reg:QI 10) - (match_dup 1)) - (set (match_dup 0) - (plus:HI (zero_extend:HI (reg:QI 10)) - (match_dup 2)))]) - - -;; -;; Add 32-bit integers. -;; - -(define_expand "addsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "") - (plus:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" "")))] - "" - "") - -(define_insn "*push_addsi3" - [(set (match_operand:SI 0 "push_operand" "=<,<, <") - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%g,g, g") - (match_operand:SI 2 "general_operand" "N,M,rSi")))] - "" - "*{ - switch (which_alternative) { - case 0: - OUT_AS1 (push, %D1%<); - OUT_AS1 (push, %C1%<); - OUT_AS1 (push, %B1%<); - OUT_AS1 (push, %A1%>%>%>); - OUT_AS1 (incsnz, 4(SP)); - OUT_AS1 (incsz, 3(SP)); - OUT_AS1 (page, 1f); - OUT_AS1 (jmp, 1f); - OUT_AS1 (incsnz, 2(SP)); - OUT_AS1 (inc, 1(SP)); - OUT_AS1 (1:,); - return \"\"; - - case 1: - OUT_AS1 (push, %D1%<); - OUT_AS1 (push, %C1%<); - OUT_AS1 (push, %B1%<); - OUT_AS1 (push, %A1%>%>%>); - OUT_AS2 (mov, w, #-1); - OUT_AS2 (add, 4(SP), w); - OUT_AS2 (addc, 3(SP), w); - OUT_AS2 (addc, 2(SP), w); - OUT_AS2 (addc, 1(SP), w); - return \"\"; - - case 2: - OUT_AS2 (mov, w, %D2); - OUT_AS2 (add, w, %D1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %C2); - OUT_AS2 (addc, w, %C1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %B2); - OUT_AS2 (addc, w, %B1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %A2); - OUT_AS2 (addc, w, %A1); - OUT_AS1 (push, wreg%>%>%>); - return \"\"; - - default: - abort(); - } - }" - [(set_attr "clobberw" "no,yes,yes")]) - -(define_insn "*addsi3" ; 0 1 2 3 4 5 6 - [(set - (match_operand:SI 0 "nonimmediate_operand" "=ro,ro, ro, rS,&ro,&rS,&rS") - (plus:SI - (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0, 0, rS, ro, rS") - (match_operand:SI 2 "general_operand" "N, M,rSi,roi,rSi,rSi,roi")))] - "" - "@ - incsnz\\t%D0\;incsz\\t%C0\;page\\t1f\;jmp\\t1f\;incsnz\\t%B0\;inc\\t%A0\;1: - mov\\tw,#-1\;add\\t%D0,w\;addc\\t%C0,w\;addc\\t%B0,w\;addc\\t%A0,w - mov\\tw,%D2\;add\\t%D0,w\;mov\\tw,%C2\;addc\\t%C0,w\;mov\\tw,%B2\;addc\\t%B0,w\;mov\\tw,%A2\;addc\\t%A0,w - mov\\tw,%D2\;add\\t%D0,w\;mov\\tw,%C2\;addc\\t%C0,w\;mov\\tw,%B2\;addc\\t%B0,w\;mov\\tw,%A2\;addc\\t%A0,w - mov\\tw,%D2\;add\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,%A1\;mov\\t%A0,w - mov\\tw,%D2\;add\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,%A1\;mov\\t%A0,w - mov\\tw,%D2\;add\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,%A1\;mov\\t%A0,w" - [(set_attr "clobberw" "no,yes,yes,yes,yes,yes,yes")]) - -(define_insn "*push_addsi3_zero_extendqi" ; 0 1 - [(set (match_operand:SI 0 "push_operand" "=<, <") - (plus:SI (zero_extend:SI - (match_operand:QI 1 "general_operand" "%roRi,rSi")) - (match_operand:SI 2 "general_operand" "rSi,roi")))] - "" - "@ - mov\\tw,%D2\;add\\tw,%1\;push\\twreg%<\;mov\\tw,%C2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%B2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%A2\;addc\\tw,$ff\;push\\twreg%>%>%> - mov\\tw,%D2\;add\\tw,%1\;push\\twreg%<\;mov\\tw,%C2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%B2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%A2\;addc\\tw,$ff\;push\\twreg%>%>%>") - -(define_insn "*addsi3_zero_extendqi" ; - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS,&ro,&rS,&rS") - (plus:SI - (zero_extend:SI - (match_operand:QI 1 "nonimmediate_operand" "rS,roR, rS,roR, rS")) - (match_operand:SI 2 "general_operand" "0, 0,rSi,rSi,roi")))] - "" - "@ - mov\\tw,%1\;add\\t%D0,w\;clr\\twreg\;addc\\t%C0,w\;addc\\t%B0,w\;addc\\t%A0,w - mov\\tw,%1\;add\\t%D0,w\;clr\\twreg\;addc\\t%C0,w\;addc\\t%B0,w\;addc\\t%A0,w - mov\\tw,%1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,$ff\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w - mov\\tw,%1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,$ff\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w - mov\\tw,%1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,$ff\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w") - -(define_insn "*push_addsi3_zero_extendhi" ; 0 1 - [(set (match_operand:SI 0 "push_operand" "=<, <") - (plus:SI (zero_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "%roR,rSR")) - (match_operand:SI 2 "general_operand" "rSi,roi")))] - "" - "@ - mov\\tw,%D2\;add\\tw,%L1\;push\\twreg%<\;mov\\tw,%C2\;addc\\tw,%H1\;push\\twreg%<\;mov\\tw,%B2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%A2\;addc\\tw,$ff\;push\\twreg%>%>%> - mov\\tw,%D2\;add\\tw,%L1\;push\\twreg%<\;mov\\tw,%C2\;addc\\tw,%H1\;push\\twreg%<\;mov\\tw,%B2\;addc\\tw,$ff\;push\\twreg%<\;mov\\tw,%A2\;addc\\tw,$ff\;push\\twreg%>%>%>") - -(define_insn "*addsi3_zero_extendhi" ; - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro,rS,&ro,&rS,&rS") - (plus:SI - (zero_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "rS,ro, rS, ro, rS")) - (match_operand:SI 2 "general_operand" "0, 0,rSi,rSi,roi")))] - "" - "@ - mov\\tw,%L1\;add\\t%D0,w\;mov\\tw,%H1\;addc\\t%C0,w\;clr\\twreg\;addc\\t%B0,w\;addc\\t%A0,w - mov\\tw,%L1\;add\\t%D0,w\;mov\\tw,%H1\;addc\\t%C0,w\;clr\\twreg\;addc\\t%B0,w\;addc\\t%A0,w - mov\\tw,%L1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%H1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w - mov\\tw,%L1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%H1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w - mov\\tw,%L1\;add\\tw,%D2\;mov\\t%D0,w\;mov\\tw,%C2\;addc\\tw,%H1\;mov\\t%C0,w\;mov\\tw,%B2\;addc\\tw,$ff\;mov\\t%B0,w\;mov\\tw,%A2\;addc\\tw,$ff\;mov\\t%A0,w") - -;; -;; Add 64-bit integers. -;; - -(define_expand "adddi3" - [(set (match_operand:DI 0 "nonimmediate_operand" "") - (plus:DI (match_operand:DI 1 "general_operand" "") - (match_operand:DI 2 "general_operand" "")))] - "" - "") - -(define_insn "*push_adddi3" - [(set (match_operand:DI 0 "push_operand" "=<,<, <") - (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%g,g, g") - (match_operand:DI 2 "general_operand" "N,M,rSi")))] - "" - "*{ - switch (which_alternative) - { - case 0: - OUT_AS1 (push, %Z1%<); - OUT_AS1 (push, %Y1%<); - OUT_AS1 (push, %X1%<); - OUT_AS1 (push, %W1%<); - OUT_AS1 (push, %V1%<); - OUT_AS1 (push, %U1%<); - OUT_AS1 (push, %T1%<); - OUT_AS1 (push, %S1%>%>%>%>%>%>%>); - OUT_AS1 (incsnz, 8(SP)); - OUT_AS1 (incsz, 7(SP)); - OUT_AS1 (page, 1f); - OUT_AS1 (jmp, 1f); - OUT_AS1 (incsnz, 6(SP)); - OUT_AS1 (incsz, 5(SP)); - OUT_AS1 (page, 1f); - OUT_AS1 (jmp, 1f); - OUT_AS1 (incsnz, 4(SP)); - OUT_AS1 (incsz, 3(SP)); - OUT_AS1 (page, 1f); - OUT_AS1 (jmp, 1f); - OUT_AS1 (incsnz, 2(SP)); - OUT_AS1 (inc, 1(SP)); - OUT_AS1 (1:,); - return \"\"; - - case 1: - OUT_AS1 (push, %Z1%<); - OUT_AS1 (push, %Y1%<); - OUT_AS1 (push, %X1%<); - OUT_AS1 (push, %W1%<); - OUT_AS1 (push, %V1%<); - OUT_AS1 (push, %U1%<); - OUT_AS1 (push, %T1%<); - OUT_AS1 (push, %S1%>%>%>%>%>%>%>); - OUT_AS2 (mov, w, #-1); - OUT_AS2 (add, 8(SP), w); - OUT_AS2 (addc, 7(SP), w); - OUT_AS2 (addc, 6(SP), w); - OUT_AS2 (addc, 5(SP), w); - OUT_AS2 (addc, 4(SP), w); - OUT_AS2 (addc, 3(SP), w); - OUT_AS2 (addc, 2(SP), w); - OUT_AS2 (addc, 1(SP), w); - return \"\"; - - case 2: - OUT_AS2 (mov, w, %Z2); - OUT_AS2 (add, w, %Z1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %Y2); - OUT_AS2 (addc, w, %Y1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %X2); - OUT_AS2 (addc, w, %X1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %W2); - OUT_AS2 (addc, w, %W1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %V2); - OUT_AS2 (addc, w, %V1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %U2); - OUT_AS2 (addc, w, %U1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %T2); - OUT_AS2 (addc, w, %T1); - OUT_AS1 (push, wreg%<); - OUT_AS2 (mov, w, %S2); - OUT_AS2 (addc, w, %S1); - OUT_AS1 (push, wreg%>%>%>%>%>%>%>); - return \"\"; - - default: - abort(); - } - }" - [(set_attr "clobberw" "no,yes,yes")]) - -(define_insn "*adddi3" ; 0 1 2 3 4 5 6 - [(set - (match_operand:DI 0 "nonimmediate_operand" "=ro,ro, ro, rS,&ro,&rS,&rS") - (plus:DI - (match_operand:DI 1 "nonimmediate_operand" "%0, 0, 0, 0, rS, ro, rS") - (match_operand:DI 2 "general_operand" "N, M,rSi,roi,rSi,rSi,roi")))] - "" - "*{ - switch (which_alternative) - { - case 0: - OUT_AS1 (incsnz, %Z0); - OUT_AS1 (incsz, %Y0); - OUT_AS1 (page, 1f); - OUT_AS1 (jmp, 1f); - OUT_AS1 (incsnz, %X0); - OUT_AS1 (incsz, %W0); - OUT_AS1 (page, 1f); - OUT_AS1 (jmp, 1f); - OUT_AS1 (incsnz, %V0); - OUT_AS1 (incsz, %U0); - OUT_AS1 (page, 1f); - OUT_AS1 (jmp, 1f); - OUT_AS1 (incsnz, %T0); - OUT_AS1 (inc, %S0); - OUT_AS1 (1:, ); - return \"\"; - - case 1: - OUT_AS2 (mov, w, #-1); - OUT_AS2 (add, %Z0, w); - OUT_AS2 (addc, %Y0, w); - OUT_AS2 (addc, %X0, w); - OUT_AS2 (addc, %W0, w); - OUT_AS2 (addc, %V0, w); - OUT_AS2 (addc, %U0, w); - OUT_AS2 (addc, %T0, w); - OUT_AS2 (addc, %S0, w); - return \"\"; - - case 2: - case 3: - OUT_AS2 (mov, w, %Z2); - OUT_AS2 (add, %Z0, w); - OUT_AS2 (mov, w, %Y2); - OUT_AS2 (addc, %Y0, w); - OUT_AS2 (mov, w, %X2); - OUT_AS2 (addc, %X0, w); - OUT_AS2 (mov, w, %W2); - OUT_AS2 (addc, %W0, w); - OUT_AS2 (mov, w, %V2); - OUT_AS2 (addc, %V0, w); - OUT_AS2 (mov, w, %U2); - OUT_AS2 (addc, %U0, w); - OUT_AS2 (mov, w, %T2); - OUT_AS2 (addc, %T0, w); - OUT_AS2 (mov, w, %S2); - OUT_AS2 (addc, %S0, w); - return \"\"; - - case 4: - case 5: - case 6: - OUT_AS2 (mov, w, %Z2); - OUT_AS2 (add, w, %Z1); - OUT_AS2 (mov, %Z0, w); - OUT_AS2 (mov, w, %Y2); - OUT_AS2 (addc, w, %Y1); - OUT_AS2 (mov, %Y0, w); - OUT_AS2 (mov, w, %X2); - OUT_AS2 (addc, w, %X1); - OUT_AS2 (mov, %X0, w); - OUT_AS2 (mov, w, %W2); - OUT_AS2 (addc, w, %W1); - OUT_AS2 (mov, %W0, w); - OUT_AS2 (mov, w, %V2); - OUT_AS2 (addc, w, %V1); - OUT_AS2 (mov, %V0, w); - OUT_AS2 (mov, w, %U2); - OUT_AS2 (addc, w, %U1); - OUT_AS2 (mov, %U0, w); - OUT_AS2 (mov, w, %T2); - OUT_AS2 (addc, w, %T1); - OUT_AS2 (mov, %T0, w); - OUT_AS2 (mov, w, %S2); - OUT_AS2 (addc, w, %S1); - OUT_AS2 (mov, %S0, w); - return \"\"; - - default: - abort(); - } - }" - [(set_attr "clobberw" "no,yes,yes,yes,yes,yes,yes")]) - -(define_insn "*adddi3_zero_extendqi" ; 0 1 2 3 4 - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro, rS,&ro,&rS,&rS") - (plus:DI - (zero_extend:DI - (match_operand:QI 1 "nonimmediate_operand" "rS,roR, rS,roR, rS")) - (match_operand:DI 2 "general_operand" "0, 0,rSi,rSi,roi")))] - "" - "*{ - switch (which_alternative) - { - case 0: - case 1: - OUT_AS2 (mov, w, %1); - OUT_AS2 (add, %Z0, w); - OUT_AS1 (clr, wreg); - OUT_AS2 (addc, %Y0, w); - OUT_AS2 (addc, %X0, w); - OUT_AS2 (addc, %W0, w); - OUT_AS2 (addc, %V0, w); - OUT_AS2 (addc, %U0, w); - OUT_AS2 (addc, %T0, w); - OUT_AS2 (addc, %S0, w); - return \"\"; - - case 2: - case 3: - case 4: - OUT_AS2 (mov, w, %1); - OUT_AS2 (add, w, %Z2); - OUT_AS2 (mov, %Z0, w); - OUT_AS2 (mov, w, %Y2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %Y0, w); - OUT_AS2 (mov, w, %X2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %X0, w); - OUT_AS2 (mov, w, %W2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %W0, w); - OUT_AS2 (mov, w, %V2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %V0, w); - OUT_AS2 (mov, w, %U2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %U0, w); - OUT_AS2 (mov, w, %T2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %T0, w); - OUT_AS2 (mov, w, %S2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %S0, w); - return \"\"; - - default: - abort(); - } - }") - -(define_insn "*adddi3_zero_extendhi" ; 0 1 2 3 4 - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,rS,&ro,&rS,&rS") - (plus:DI - (zero_extend:DI - (match_operand:HI 1 "nonimmediate_operand" "rS,ro, rS, ro, rS")) - (match_operand:DI 2 "general_operand" "0, 0,rSi,rSi,roi")))] - "" - "*{ - switch (which_alternative) - { - case 0: - case 1: - OUT_AS2 (mov, w, %L1); - OUT_AS2 (add, %Z0, w); - OUT_AS2 (mov, w, %H1); - OUT_AS2 (addc, %Y0, w); - OUT_AS1 (clr, wreg); - OUT_AS2 (addc, %X0, w); - OUT_AS2 (addc, %W0, w); - OUT_AS2 (addc, %V0, w); - OUT_AS2 (addc, %U0, w); - OUT_AS2 (addc, %T0, w); - OUT_AS2 (addc, %S0, w); - return \"\"; - - case 2: - case 3: - case 4: - OUT_AS2 (mov, w, %L1); - OUT_AS2 (add, w, %Z2); - OUT_AS2 (mov, %Z0, w); - OUT_AS2 (mov, w, %Y2); - OUT_AS2 (addc, w, %H1); - OUT_AS2 (mov, %Y0, w); - OUT_AS2 (mov, w, %X2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %X0, w); - OUT_AS2 (mov, w, %W2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %W0, w); - OUT_AS2 (mov, w, %V2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %V0, w); - OUT_AS2 (mov, w, %U2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %U0, w); - OUT_AS2 (mov, w, %T2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %T0, w); - OUT_AS2 (mov, w, %S2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %S0, w); - return \"\"; - - default: - abort(); - } - }") - -(define_insn "*adddi3_zero_extendsi" ; 0 1 2 3 4 - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,rS,&ro,&rS,&rS") - (plus:DI - (zero_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "rS,ro, rS, ro, rS")) - (match_operand:DI 2 "general_operand" "0, 0,rSi,rSi,roi")))] - "" - "*{ - switch (which_alternative) - { - case 0: - case 1: - OUT_AS2 (mov, w, %D1); - OUT_AS2 (add, %Z0, w); - OUT_AS2 (mov, w, %C1); - OUT_AS2 (addc, %Y0, w); - OUT_AS2 (mov, w, %B1); - OUT_AS2 (addc, %X0, w); - OUT_AS2 (mov, w, %A1); - OUT_AS2 (addc, %W0, w); - OUT_AS1 (clr, wreg); - OUT_AS2 (addc, %V0, w); - OUT_AS2 (addc, %U0, w); - OUT_AS2 (addc, %T0, w); - OUT_AS2 (addc, %S0, w); - return \"\"; - - case 2: - case 3: - case 4: - OUT_AS2 (mov, w, %D1); - OUT_AS2 (add, w, %Z2); - OUT_AS2 (mov, %Z0, w); - OUT_AS2 (mov, w, %Y2); - OUT_AS2 (addc, w, %C1); - OUT_AS2 (mov, %Y0, w); - OUT_AS2 (mov, w, %X2); - OUT_AS2 (addc, w, %B1); - OUT_AS2 (mov, %X0, w); - OUT_AS2 (mov, w, %W2); - OUT_AS2 (addc, w, %A1); - OUT_AS2 (mov, %W0, w); - OUT_AS2 (mov, w, %V2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %V0, w); - OUT_AS2 (mov, w, %U2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %U0, w); - OUT_AS2 (mov, w, %T2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %T0, w); - OUT_AS2 (mov, w, %S2); - OUT_AS2 (addc, w, $ff); - OUT_AS2 (mov, %S0, w); - return \"\"; - - default: - abort(); - } - }") - -;; -;; Subtract bytes. -;; - -(define_expand "subqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (minus:QI (match_operand:QI 1 "general_operand" "") - (match_operand:QI 2 "general_operand" "")))] - "" - "if (GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_addqi3 (operands[0], operands[1], - gen_int_mode (-INTVAL (operands[2]), QImode))); - DONE; - } - ") - -(define_insn "*push_subqi3" - [(set (match_operand:QI 0 "push_operand" "=<, <") - (minus:QI (match_operand:QI 1 "general_operand" "g,rSn") - (match_operand:QI 2 "general_operand" "rSn, g")))] - "" - "@ - push\\t%1%<\;mov\\tw,%2\;sub\\t1(SP),w%> - push\\t%1%<\;mov\\tw,%2\;sub\\t1(SP),w%>") - -(define_insn "*subqi3_w" - [(set (reg:QI 10) - (minus:QI (match_operand:QI 0 "general_operand" "rS,rSi, g,rSi") - (match_operand:QI 1 "general_operand" "rSi, rS,rSi, g")))] - "(ip2k_reorg_split_qimode)" - "@ - mov\\tw,%1\;sub\\tw,%0 - mov\\tw,%1\;sub\\tw,%0 - mov\\tw,%1\;sub\\tw,%0 - mov\\tw,%1\;sub\\tw,%0") - -(define_insn_and_split "*subqi3" - [(set - (match_operand:QI - 0 "nonimmediate_operand" "=k,k,z,z,djyoR,djyoR,djyS,djyoR, g, g, rS, rS") - (minus:QI - (match_operand:QI - 1 "general_operand" "0,0,0,0, 0, 0, 0, 0, rS,rSi, g,rSi") - (match_operand:QI - 2 "general_operand" "M,g,M,g, M, N, g, rSi,rSi, rS,rSi, g")))] - "" - "@ - incsnz\\t%0\;dec\\tiph - mov\\tw,%2\;sub\\t%0,w - incsnz\\t%0\;dec\\tdph - mov\\tw,%2\;sub\\t%0,w - inc\\t%0 - dec\\t%0 - mov\\tw,%2\;sub\\t%0,w - mov\\tw,%2\;sub\\t%0,w - # - # - # - #" - "(ip2k_reorg_split_qimode - && ! rtx_equal_p (operands[0], operands[1]))" - [(set (reg:QI 10) - (minus:QI (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (reg:QI 10))] - "" - [(set_attr "skip" "no,no,no,no,yes,yes,no,no,no,no,no,no") - (set_attr "clobberw" "no,yes,no,yes,no,no,yes,yes,yes,yes,yes,yes")]) - -;; -;; Subtract 16-bit integers. -;; - -(define_expand "subhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "") - (minus:HI (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - "if (GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_addhi3 (operands[0], operands[1], - gen_int_mode (-INTVAL (operands[2]), HImode))); - DONE; - } - ") - -(define_insn "*push_subhi3" - [(set (match_operand:HI 0 "push_operand" "=<, <") - (minus:HI (match_operand:HI 1 "general_operand" "ron,rSn") - (match_operand:HI 2 "general_operand" "rSn,ron")))] - "" - "@ - push\\t%L1%<\;mov\\tw,%L2\;sub\\t1(SP),w\;push\\t%H1%<\;mov\\tw,%H2\;subc\\t1(SP),w%>%> - push\\t%L1%<\;mov\\tw,%L2\;sub\\t1(SP),w\;push\\t%H1%<\;mov\\tw,%H2\;subc\\t1(SP),w%>%>") - -(define_insn "*subhi3_imm" - [(set - (match_operand:HI 0 "nonimmediate_operand" "=a,a,a,a,do,&r,&ro,&rS") - (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0, 0,ro, rS, ro") - (match_operand 2 "immediate_operand" "N,M,P,i, i, O, i, i")))] - "" - "@ - dec\\t%L0 - inc\\t%L0 - mov\\tw,%2\;sub\\t%L0,w - mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;sub\\t%H0,w - mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;subc\\t%H0,w - mov\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w - mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w" - [(set_attr "skip" "yes,yes,no,no,no,no,no,no") - (set_attr "clobberw" "no,no,yes,yes,yes,yes,yes,yes")]) - -(define_insn "*subhi3_ximm_zero_extend" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro, rS") - (minus:HI (match_operand:HI 1 "immediate_operand" "i, i") - (zero_extend:HI - (match_operand:QI 2 "nonimmediate_operand" "rS,roR"))))] - "" - "@ - mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w\;clr\\twreg\;subc\\t%H0,w - mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w\;clr\\twreg\;subc\\t%H0,w") - -(define_insn "*subhi3_ximm" - [(set (match_operand:HI 0 "nonimmediate_operand" "=&uo,&ro,&rS") - (minus:HI (match_operand:HI 1 "immediate_operand" "i, i, i") - (match_operand:HI 2 "nonimmediate_operand" "0, rS, ro")))] - "" - "@ - mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;push\\t%H2%<\;mov\\tw,%H1\;mov\\t%H0,w\;pop\\twreg%>\;subc\\t%H0,w - mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%H2\;subc\\t%H0,w - mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H1\;mov\\t%H0,w\;mov\\tw,%H2\;subc\\t%H0,w") - -(define_insn "*subhi3_nonimm_zero_extend" - [(set - (match_operand:HI 0 "nonimmediate_operand" "=a,ro, rS,&ro,&rS,&rS") - (minus:HI - (match_operand:HI 1 "nonimmediate_operand" "0, 0, 0, rS, ro, rS") - (zero_extend:HI - (match_operand:QI 2 "general_operand" "roR,rS,roR, rS, rS,roR"))))] - "" - "@ - mov\\tw,%2\;sub\\t%L0,w - mov\\tw,%2\;sub\\t%L0,w\;clr\\twreg\;subc\\t%H0,w - mov\\tw,%2\;sub\\t%L0,w\;clr\\twreg\;subc\\t%H0,w - mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;subc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;subc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%2\;sub\\tw,%L1\;mov\\t%L0,w\;clr\\twreg\;subc\\tw,%H1\;mov\\t%H0,w") - -(define_insn "*subhi3_nonimm" ; 0 1 2 3 4 5 6 - [(set - (match_operand:HI 0 "nonimmediate_operand" "=a,dS, o,&rS,&rS,&rS, o") - (minus:HI - (match_operand:HI 1 "nonimmediate_operand" "0, 0, 0, ro, ro, rS,rS") - (match_operand:HI 2 "nonimmediate_operand" "ro,ro,rS, 0, rS, ro,rS")))] - "" - "@ - mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;sub\\t%H0,w - mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;subc\\t%H0,w - mov\\tw,%L2\;sub\\t%L0,w\;mov\\tw,%H2\;subc\\t%H0,w - mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w - mov\\tw,%L2\;sub\\tw,%L1\;mov\\t%L0,w\;mov\\tw,%H2\;subc\\tw,%H1\;mov\\t%H0,w") - -;; -;; Subtract 32-bit integers. -;; - -(define_insn "subsi3" ; 0 1 2 3 4 5 6 7 8 9 a b - [(set - (match_operand:SI - 0 "nonimmediate_operand" "=ro,ro, ro, rS,&ro,&rS,&ro,&rS,&rS,&ro,&ro,&rS") - (minus:SI - (match_operand:SI - 1 "general_operand" "0, 0, 0, 0, i, ro, rS, rS, ro, rS, i, i") - (match_operand:SI - 2 "general_operand" "M, N,rSi,roi, 0, 0, 0,roi,rSi,rSi, rS, ro")))] - "" - "*{ - switch (which_alternative) { - case 0: - return AS2 (mov, w, #1) CR_TAB - AS2 (add, %D0, w) CR_TAB - AS1 (clr, wreg) CR_TAB - AS2 (addc, %C0, w) CR_TAB - AS2 (addc, %B0, w) CR_TAB - AS2 (addc, %A0, w); - - case 1: - return AS2 (mov, w, #-1) CR_TAB - AS2 (sub, %D0, w) CR_TAB - AS2 (subc, %C0, w) CR_TAB - AS2 (subc, %B0, w) CR_TAB - AS2 (subc, %A0, w); - - case 2: - case 3: - return AS2 (mov, w, %D2) CR_TAB - AS2 (sub, %D0, w) CR_TAB - AS2 (mov, w, %C2) CR_TAB - AS2 (subc, %C0, w) CR_TAB - AS2 (mov, w, %B2) CR_TAB - AS2 (subc, %B0, w) CR_TAB - AS2 (mov, w, %A2) CR_TAB - AS2 (subc, %A0, w); - - case 4: - return AS2 (mov, w, %D2) CR_TAB - AS2 (sub, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (push, %C2%<) CR_TAB - AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %C0, w) CR_TAB - AS1 (push, %B2%<) CR_TAB - AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %B0, w) CR_TAB - AS1 (push, %A2%<) CR_TAB - AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %A0, w); - - case 5: - case 6: - case 7: - case 8: - case 9: - return AS2 (mov, w, %D2) CR_TAB - AS2 (sub, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %C2) CR_TAB - AS2 (subc, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, w, %B2) CR_TAB - AS2 (subc, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, w, %A2) CR_TAB - AS2 (subc, w, %A1) CR_TAB - AS2 (mov, %A0, w); - - case 10: - case 11: - return AS2 (mov, w, %D2) CR_TAB - AS2 (sub, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, w, %C2) CR_TAB - AS2 (subc, %C0, w) CR_TAB - AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, w, %B2) CR_TAB - AS2 (subc, %B0, w) CR_TAB - AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (mov, w, %A2) CR_TAB - AS2 (subc, %A0, w); - default: - abort (); - } - }") - -;; -;; Subtract 64-bit integers. -;; - -(define_insn "subdi3" ; 0 1 2 3 4 5 6 7 8 9 a b - [(set - (match_operand:DI - 0 "nonimmediate_operand" "=ro,ro, ro, rS,ro,&rS,&ro,&rS,&rS,&ro,&ro,&rS") - (minus:DI - (match_operand:DI - 1 "general_operand" "0, 0, 0, 0, i, ro, rS, rS, ro, rS, i, i") - (match_operand:DI - 2 "general_operand" "M, N,rSi,roi, 0, 0, 0,roi,rSi,rSi, rS, ro")))] - "" - "*{ - switch (which_alternative) { - case 0: - return AS2 (mov, w, #1) CR_TAB - AS2 (add, %Z0, w) CR_TAB - AS1 (clr, wreg) CR_TAB - AS2 (addc, %Y0, w) CR_TAB - AS2 (addc, %X0, w) CR_TAB - AS2 (addc, %W0, w) CR_TAB - AS2 (addc, %V0, w) CR_TAB - AS2 (addc, %U0, w) CR_TAB - AS2 (addc, %T0, w) CR_TAB - AS2 (addc, %S0, w); - - case 1: - return AS2 (mov, w, #-1) CR_TAB - AS2 (sub, %Z0, w) CR_TAB - AS2 (subc, %Y0, w) CR_TAB - AS2 (subc, %X0, w) CR_TAB - AS2 (subc, %W0, w) CR_TAB - AS2 (subc, %V0, w) CR_TAB - AS2 (subc, %U0, w) CR_TAB - AS2 (subc, %T0, w) CR_TAB - AS2 (subc, %S0, w); - - case 2: - case 3: - return AS2 (mov, w, %Z2) CR_TAB - AS2 (sub, %Z0, w) CR_TAB - AS2 (mov, w, %Y2) CR_TAB - AS2 (subc, %Y0, w) CR_TAB - AS2 (mov, w, %X2) CR_TAB - AS2 (subc, %X0, w) CR_TAB - AS2 (mov, w, %W2) CR_TAB - AS2 (subc, %W0, w) CR_TAB - AS2 (mov, w, %V2) CR_TAB - AS2 (subc, %V0, w) CR_TAB - AS2 (mov, w, %U2) CR_TAB - AS2 (subc, %U0, w) CR_TAB - AS2 (mov, w, %T2) CR_TAB - AS2 (subc, %T0, w) CR_TAB - AS2 (mov, w, %S2) CR_TAB - AS2 (subc, %S0, w); - - case 4: - return AS2 (mov, w, %Z2) CR_TAB - AS2 (sub, w, %Z1) CR_TAB - AS2 (mov, %Z0, w) CR_TAB - AS1 (push, %Y2%<) CR_TAB - AS2 (mov, w, %Y1) CR_TAB - AS2 (mov, %Y0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %Y0, w) CR_TAB - AS1 (push, %X2%<) CR_TAB - AS2 (mov, w, %X1) CR_TAB - AS2 (mov, %X0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %X0, w) CR_TAB - AS1 (push, %W2%<) CR_TAB - AS2 (mov, w, %W1) CR_TAB - AS2 (mov, %W0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %W0, w) CR_TAB - AS1 (push, %V2%<) CR_TAB - AS2 (mov, w, %V1) CR_TAB - AS2 (mov, %V0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %V0, w) CR_TAB - AS1 (push, %U2%<) CR_TAB - AS2 (mov, w, %U1) CR_TAB - AS2 (mov, %U0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %U0, w) CR_TAB - AS1 (push, %T2%<) CR_TAB - AS2 (mov, w, %T1) CR_TAB - AS2 (mov, %T0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %T0, w) CR_TAB - AS1 (push, %S2%<) CR_TAB - AS2 (mov, w, %S1) CR_TAB - AS2 (mov, %S0, w) CR_TAB - AS1 (pop, wreg%>) CR_TAB - AS2 (subc, %S0, w); - - case 5: - case 6: - case 7: - case 8: - case 9: - return AS2 (mov, w, %Z2) CR_TAB - AS2 (sub, w, %Z1) CR_TAB - AS2 (mov, %Z0, w) CR_TAB - AS2 (mov, w, %Y2) CR_TAB - AS2 (subc, w, %Y1) CR_TAB - AS2 (mov, %Y0, w) CR_TAB - AS2 (mov, w, %X2) CR_TAB - AS2 (subc, w, %X1) CR_TAB - AS2 (mov, %X0, w) CR_TAB - AS2 (mov, w, %W2) CR_TAB - AS2 (subc, w, %W1) CR_TAB - AS2 (mov, %W0, w) CR_TAB - AS2 (mov, w, %V2) CR_TAB - AS2 (subc, w, %V1) CR_TAB - AS2 (mov, %V0, w) CR_TAB - AS2 (mov, w, %U2) CR_TAB - AS2 (subc, w, %U1) CR_TAB - AS2 (mov, %U0, w) CR_TAB - AS2 (mov, w, %T2) CR_TAB - AS2 (subc, w, %T1) CR_TAB - AS2 (mov, %T0, w) CR_TAB - AS2 (mov, w, %S2) CR_TAB - AS2 (subc, w, %S1) CR_TAB - AS2 (mov, %S0, w); - - case 10: - case 11: - return AS2 (mov, w, %Z2) CR_TAB - AS2 (sub, w, %Z1) CR_TAB - AS2 (mov, %Z0, w) CR_TAB - AS2 (mov, w, %Y1) CR_TAB - AS2 (mov, %Y0, w) CR_TAB - AS2 (mov, w, %Y2) CR_TAB - AS2 (subc, %Y0, w) CR_TAB - AS2 (mov, w, %X1) CR_TAB - AS2 (mov, %X0, w) CR_TAB - AS2 (mov, w, %X2) CR_TAB - AS2 (subc, %X0, w) CR_TAB - AS2 (mov, w, %W1) CR_TAB - AS2 (mov, %W0, w) CR_TAB - AS2 (mov, w, %W2) CR_TAB - AS2 (subc, %W0, w) CR_TAB - AS2 (mov, w, %V1) CR_TAB - AS2 (mov, %V0, w) CR_TAB - AS2 (mov, w, %V2) CR_TAB - AS2 (subc, %V0, w) CR_TAB - AS2 (mov, w, %U1) CR_TAB - AS2 (mov, %U0, w) CR_TAB - AS2 (mov, w, %U2) CR_TAB - AS2 (subc, %U0, w) CR_TAB - AS2 (mov, w, %T1) CR_TAB - AS2 (mov, %T0, w) CR_TAB - AS2 (mov, w, %T2) CR_TAB - AS2 (subc, %T0, w) CR_TAB - AS2 (mov, w, %S1) CR_TAB - AS2 (mov, %S0, w) CR_TAB - AS2 (mov, w, %S2) CR_TAB - AS2 (subc, %S0, w); - default: - abort (); - } - }") - -;; -;; Bitwise and instructions. -;; - -(define_expand "andqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (and:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "general_operand" "")))] - "" - "") - -(define_insn "*andqi3_bit" - [(set (match_operand:QI 0 "nonimmediate_operand" "=roR") - (and:QI (match_dup 0) - (match_operand:QI 1 "const_int_operand" "n")))] - "(find_one_clear_bit_p (INTVAL (operands[1]) | 0xffffff00UL) != -1)" - "*{ - operands[2] = GEN_INT (find_one_clear_bit_p (INTVAL (operands[1]) - | 0xffffff00UL)); - return AS2 (clrb, %0, %b2); - }" - [(set_attr "skip" "yes") - (set_attr "clobberw" "no")]) - -(define_insn "*andqi3_w_fr" - [(set (reg:QI 10) - (and:QI (match_operand:QI 0 "general_operand" "roRn") - (reg:QI 10)))] - "(ip2k_reorg_split_qimode)" - "and\\tw,%0" - [(set_attr "skip" "yes")]) - -(define_insn_and_split "*andqi3_fr_w" - [(set (match_operand:QI 0 "nonimmediate_operand" "=roR,rS,roR, rS,rS") - (and:QI - (match_operand:QI 1 "nonimmediate_operand" "%0, 0, rS,roR,rS") - (reg:QI 10)))] - "(ip2k_reorg_split_qimode)" - "@ - and\\t%0,w - and\\t%0,w - # - # - #" - "(ip2k_reorg_split_qimode - && ! rtx_equal_p (operands[0], operands[1]))" - [(set (reg:QI 10) - (and:QI (match_dup 1) - (reg:QI 10))) - (set (match_dup 0) - (reg:QI 10))] - "" - [(set_attr "skip" "yes,yes,no,no,no") - (set_attr "clobberw" "no,no,yes,yes,yes")]) - -(define_insn_and_split "*andqi3" ; 0 1 2 3 4 - [(set (match_operand:QI 0 "nonimmediate_operand" "=roR, rS,roR, rS, rS") - (and:QI - (match_operand:QI 1 "nonimmediate_operand" "%0, 0, rS,roR, rS") - (match_operand:QI 2 "general_operand" "rSn,roRn,rSn,rSn,roRn")))] - "" - "@ - mov\\tw,%2\;and\\t%0,w - # - # - # - #" - "(ip2k_reorg_split_qimode - && (! rtx_equal_p (operands[0], operands[1]) - || GET_CODE (operands[2]) != CONST_INT - || find_one_clear_bit_p (INTVAL (operands[2]) | 0xffffff00UL) == -1))" - [(set (reg:QI 10) - (match_dup 2)) - (set (match_dup 0) - (and:QI (match_dup 1) - (reg:QI 10)))]) - -(define_insn_and_split "andhi3" ; 0 1 2 3 4 - [(set (match_operand:HI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS") - (and:HI - (match_operand:HI 1 "nonimmediate_operand" "%0, 0, ro, rS, rS") - (match_operand:HI 2 "general_operand" "rSn,ron,rSn,rSn,ron")))] - "" - "#" - "(ip2k_reorg_split_himode)" - [(set (match_dup 3) - (and:QI (match_dup 4) - (match_dup 5))) - (set (match_dup 6) - (and:QI (match_dup 7) - (match_dup 8)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], QImode); - operands[4] = ip2k_get_high_half (operands[1], QImode); - operands[5] = ip2k_get_high_half (operands[2], QImode); - operands[6] = ip2k_get_low_half (operands[0], QImode); - operands[7] = ip2k_get_low_half (operands[1], QImode); - operands[8] = ip2k_get_low_half (operands[2], QImode); - }") - -(define_insn_and_split "andsi3" ; 0 1 2 3 4 - [(set (match_operand:SI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS") - (and:SI - (match_operand:SI 1 "nonimmediate_operand" "%0, 0, ro, rS, rS") - (match_operand:SI 2 "general_operand" "rSn,ron,rSn,rSn,ron")))] - "" - "#" - "(ip2k_reorg_split_simode)" - [(set (match_dup 3) - (and:HI (match_dup 4) - (match_dup 5))) - (set (match_dup 6) - (and:HI (match_dup 7) - (match_dup 8)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], HImode); - operands[4] = ip2k_get_high_half (operands[1], HImode); - operands[5] = ip2k_get_high_half (operands[2], HImode); - operands[6] = ip2k_get_low_half (operands[0], HImode); - operands[7] = ip2k_get_low_half (operands[1], HImode); - operands[8] = ip2k_get_low_half (operands[2], HImode); - }") - -(define_insn_and_split "anddi3" ; 0 1 2 3 4 - [(set (match_operand:DI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS") - (and:DI - (match_operand:DI 1 "nonimmediate_operand" "%0, 0, ro, rS, rS") - (match_operand:DI 2 "general_operand" "rSn,ron,rSn,rSn,ron")))] - "" - "#" - "(ip2k_reorg_split_dimode)" - [(set (match_dup 3) - (and:SI (match_dup 4) - (match_dup 5))) - (set (match_dup 6) - (and:SI (match_dup 7) - (match_dup 8)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], SImode); - operands[4] = ip2k_get_high_half (operands[1], SImode); - operands[5] = ip2k_get_high_half (operands[2], SImode); - operands[6] = ip2k_get_low_half (operands[0], SImode); - operands[7] = ip2k_get_low_half (operands[1], SImode); - operands[8] = ip2k_get_low_half (operands[2], SImode); - }") - -;; -;; Bitwise or instructions. -;; - -(define_expand "iorqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "general_operand" "")))] - "" - "") - -(define_insn "*iorqi3_bit" - [(set (match_operand:QI 0 "nonimmediate_operand" "=roR") - (ior:QI (match_dup 0) - (match_operand:QI 1 "const_int_operand" "n")))] - "(find_one_set_bit_p (INTVAL (operands[1]) & 0xff) != -1)" - "*{ - operands[2] = GEN_INT (find_one_set_bit_p (INTVAL (operands[1]) & 0xff)); - return AS2 (setb, %0, %b2); - }" - [(set_attr "skip" "yes") - (set_attr "clobberw" "no")]) - -(define_insn "*iorqi3" ; 0 1 2 3 4 - [(set (match_operand:QI 0 "nonimmediate_operand" "=roR, rS,roR, rS, rS") - (ior:QI - (match_operand:QI 1 "nonimmediate_operand" "%0, 0, rS,roR, rS") - (match_operand:QI 2 "general_operand" "rSi,roRi,rSi,rSi,roRi")))] - "" - "@ - mov\\tw,%2\;or\\t%0,w - mov\\tw,%2\;or\\t%0,w - mov\\tw,%2\;or\\tw,%1\;mov\\t%0,w - mov\\tw,%2\;or\\tw,%1\;mov\\t%0,w - mov\\tw,%2\;or\\tw,%1\;mov\\t%0,w") - -(define_insn_and_split "iorhi3" ; 0 1 2 3 4 - [(set (match_operand:HI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS") - (ior:HI - (match_operand:HI 1 "nonimmediate_operand" "%0, 0, ro, rS, rS") - (match_operand:HI 2 "general_operand" "rSn,ron,rSn,rSn,ron")))] - "" - "#" - "(ip2k_reorg_split_himode)" - [(set (match_dup 3) - (ior:QI (match_dup 4) - (match_dup 5))) - (set (match_dup 6) - (ior:QI (match_dup 7) - (match_dup 8)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], QImode); - operands[4] = ip2k_get_high_half (operands[1], QImode); - operands[5] = ip2k_get_high_half (operands[2], QImode); - operands[6] = ip2k_get_low_half (operands[0], QImode); - operands[7] = ip2k_get_low_half (operands[1], QImode); - operands[8] = ip2k_get_low_half (operands[2], QImode); - }") - -(define_insn_and_split "iorsi3" ; 0 1 2 3 4 - [(set (match_operand:SI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS") - (ior:SI - (match_operand:SI 1 "nonimmediate_operand" "%0, 0, ro, rS, rS") - (match_operand:SI 2 "general_operand" "rSn,ron,rSn,rSn,ron")))] - "" - "#" - "(ip2k_reorg_split_simode)" - [(set (match_dup 3) - (ior:HI (match_dup 4) - (match_dup 5))) - (set (match_dup 6) - (ior:HI (match_dup 7) - (match_dup 8)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], HImode); - operands[4] = ip2k_get_high_half (operands[1], HImode); - operands[5] = ip2k_get_high_half (operands[2], HImode); - operands[6] = ip2k_get_low_half (operands[0], HImode); - operands[7] = ip2k_get_low_half (operands[1], HImode); - operands[8] = ip2k_get_low_half (operands[2], HImode); - }") - -(define_insn_and_split "iordi3" ; 0 1 2 3 4 - [(set (match_operand:DI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS") - (ior:DI - (match_operand:DI 1 "nonimmediate_operand" "%0, 0, ro, rS, rS") - (match_operand:DI 2 "general_operand" "rSn,ron,rSn,rSn,ron")))] - "" - "#" - "(ip2k_reorg_split_dimode)" - [(set (match_dup 3) - (ior:SI (match_dup 4) - (match_dup 5))) - (set (match_dup 6) - (ior:SI (match_dup 7) - (match_dup 8)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], SImode); - operands[4] = ip2k_get_high_half (operands[1], SImode); - operands[5] = ip2k_get_high_half (operands[2], SImode); - operands[6] = ip2k_get_low_half (operands[0], SImode); - operands[7] = ip2k_get_low_half (operands[1], SImode); - operands[8] = ip2k_get_low_half (operands[2], SImode); - }") - -;; -;; Bitwise xor instructions -;; -;; TODO: xor ops can also use "not w, fr"! -;; - -(define_insn "xorqi3" - [(set - (match_operand:QI 0 "nonimmediate_operand" "=roR,roR, rS,roR, rS, rS") - (xor:QI (match_operand:QI 1 "general_operand" "%0, 0, 0, rS,roR, rS") - (match_operand:QI 2 "general_operand" "M,rSi,roRi,rSi,rSi,roRi")))] - "" - "@ - not\\t%0 - mov\\tw,%2\;xor\\t%0,w - mov\\tw,%2\;xor\\t%0,w - mov\\tw,%1\;xor\\tw,%2\;mov\\t%0,w - mov\\tw,%1\;xor\\tw,%2\;mov\\t%0,w - mov\\tw,%1\;xor\\tw,%2\;mov\\t%0,w" - [(set_attr "clobberw" "no,yes,yes,yes,yes,yes")]) - -(define_insn_and_split "xorhi3" ; 0 1 2 3 4 - [(set (match_operand:HI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS") - (xor:HI - (match_operand:HI 1 "nonimmediate_operand" "%0, 0, ro, rS, rS") - (match_operand:HI 2 "general_operand" "rSn,ron,rSn,rSn,ron")))] - "" - "#" - "(ip2k_reorg_split_himode)" - [(set (match_dup 3) - (xor:QI (match_dup 4) - (match_dup 5))) - (set (match_dup 6) - (xor:QI (match_dup 7) - (match_dup 8)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], QImode); - operands[4] = ip2k_get_high_half (operands[1], QImode); - operands[5] = ip2k_get_high_half (operands[2], QImode); - operands[6] = ip2k_get_low_half (operands[0], QImode); - operands[7] = ip2k_get_low_half (operands[1], QImode); - operands[8] = ip2k_get_low_half (operands[2], QImode); - }") - -(define_insn_and_split "xorsi3" ; 0 1 2 3 4 - [(set (match_operand:SI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS") - (xor:SI - (match_operand:SI 1 "nonimmediate_operand" "%0, 0, ro, rS, rS") - (match_operand:SI 2 "general_operand" "rSn,ron,rSn,rSn,ron")))] - "" - "#" - "(ip2k_reorg_split_simode)" - [(set (match_dup 3) - (xor:HI (match_dup 4) - (match_dup 5))) - (set (match_dup 6) - (xor:HI (match_dup 7) - (match_dup 8)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], HImode); - operands[4] = ip2k_get_high_half (operands[1], HImode); - operands[5] = ip2k_get_high_half (operands[2], HImode); - operands[6] = ip2k_get_low_half (operands[0], HImode); - operands[7] = ip2k_get_low_half (operands[1], HImode); - operands[8] = ip2k_get_low_half (operands[2], HImode); - }") - -(define_insn_and_split "xordi3" ; 0 1 2 3 4 - [(set (match_operand:DI 0 "nonimmediate_operand" "=uo, uS,&dS,&do,&dS") - (xor:DI - (match_operand:DI 1 "nonimmediate_operand" "%0, 0, ro, rS, rS") - (match_operand:DI 2 "general_operand" "rSn,ron,rSn,rSn,ron")))] - "" - "#" - "(ip2k_reorg_split_dimode)" - [(set (match_dup 3) - (xor:SI (match_dup 4) - (match_dup 5))) - (set (match_dup 6) - (xor:SI (match_dup 7) - (match_dup 8)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], SImode); - operands[4] = ip2k_get_high_half (operands[1], SImode); - operands[5] = ip2k_get_high_half (operands[2], SImode); - operands[6] = ip2k_get_low_half (operands[0], SImode); - operands[7] = ip2k_get_low_half (operands[1], SImode); - operands[8] = ip2k_get_low_half (operands[2], SImode); - }") - -;; -;; Multiply instructions. -;; - -(define_insn "umulqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=ro, rS, rS") - (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%rS,roR, rS") - (match_operand:QI 2 "general_operand" "rSi,rSi,roRi")))] - "" - "mov\\tw,%1\;mulu\\tw,%2\;mov\\t%0,w") - -(define_insn "mulqihi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro, rS, rS") - (mult:HI - (sign_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "%rS,roR, rS")) - (sign_extend:HI - (match_operand:QI 2 "general_operand" "rSi,rSi,roRi"))))] - "" - "@ - mov\\tw,%1\;muls\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w - mov\\tw,%1\;muls\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w - mov\\tw,%1\;muls\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w") - -(define_insn_and_split "umulqihi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro, rS, rS") - (mult:HI (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "%rS,roR, rS")) - (zero_extend:HI - (match_operand:QI 2 "general_operand" "rSi,rSi,roRi"))))] - "" - "#" - "ip2k_reorg_split_qimode" - [(set (match_dup 3) - (mult:QI (match_dup 1) - (match_dup 2))) - (set (reg:QI 10) - (reg:QI 15)) - (set (match_dup 4) - (reg:QI 10))] - "{ - operands[3] = ip2k_get_low_half (operands[0], QImode); - operands[4] = ip2k_get_high_half (operands[0], QImode); - }") - -(define_insn "*mulhi3_by2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (mult:HI (match_operand:HI 1 "nonimmediate_operand" "0, rS, ro") - (zero_extend:HI (const_int 2))))] - "" - "@ - clrb\\tSTATUS,0\;rl\\t%L0\;rl\\t%H0 - clrb\\tSTATUS,0\;rl\\tw,%L1\;mov\\t%L0,w\;rl\\tw,%H1\;mov\\t%H0,w - clrb\\tSTATUS,0\;rl\\tw,%L1\;mov\\t%L0,w\;rl\\tw,%H1\;mov\\t%H0,w" - [(set_attr "clobberw" "no,yes,yes")]) - -(define_insn "*mulhi3_byqi" - [(set (match_operand:HI - 0 "nonimmediate_operand" "=ro,&ro,&rS, &rS") - (mult:HI (match_operand:HI - 1 "nonimmediate_operand" "0, rS, ro, rS") - (zero_extend:HI (match_operand:QI - 2 "general_operand" "rSi,rSi,rSi,roRi"))))] - "" - "@ - mov\\tw,%L1\;mulu\\tw,%2\;mov\\t%L0,w\;push\\tmulh%<\;mov\\tw,%H1\;mulu\\tw,%2\;pop\\t%H0%>\;add\\t%H0,w - mov\\tw,%L1\;mulu\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w\;mov\\tw,%H1\;mulu\\tw,%2\;add\\t%H0,w - mov\\tw,%L1\;mulu\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w\;mov\\tw,%H1\;mulu\\tw,%2\;add\\t%H0,w - mov\\tw,%L1\;mulu\\tw,%2\;mov\\t%L0,w\;mov\\tw,mulh\;mov\\t%H0,w\;mov\\tw,%H1\;mulu\\tw,%2\;add\\t%H0,w") - -(define_insn "smulqi_highpart" - [(set (match_operand:QI 0 "nonimmediate_operand" "=roR, rS, rS") - (truncate:QI - (lshiftrt:HI - (mult:HI - (sign_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "%rS,roR, rS")) - (sign_extend:HI - (match_operand:QI 2 "general_operand" "rSi,rSi,roRi"))) - (const_int 8))))] - "" - "@ - mov\\tw,%1\;muls\\tw,%2\;mov\\tw,mulh\;mov %0,w - mov\\tw,%1\;muls\\tw,%2\;mov\\tw,mulh\;mov %0,w - mov\\tw,%1\;muls\\tw,%2\;mov\\tw,mulh\;mov %0,w") - -(define_insn "umulqi_highpart" - [(set (match_operand:QI 0 "nonimmediate_operand" "=roR, rS, rS") - (truncate:QI - (lshiftrt:HI - (mult:HI - (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "%rS,roR, rS")) - (zero_extend:HI - (match_operand:QI 2 "general_operand" "rSi,rSi,roRi"))) - (const_int 8))))] - "" - "@ - mov\\tw,%1\;mulu\\tw,%2\;mov\\tw,mulh\;mov %0,w - mov\\tw,%1\;mulu\\tw,%2\;mov\\tw,mulh\;mov %0,w - mov\\tw,%1\;mulu\\tw,%2\;mov\\tw,mulh\;mov %0,w") - -(define_insn "mulhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=uo, uS, uS") - (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rS, ro, rS") - (match_operand:HI 2 "general_operand" "rSi,rSi,roi")))] - "" - "push\\t%L2%<\;push\\t%H2%<\;push\\t%L1%<\;push\\t%H1%>\;page\\t__mulhi3\;call\\t__mulhi3\;pop\\t%H0%>\;pop\\t%L0%>") - -;; If we find that we're multiplying by a constant that's less than 256 we -;; can replace a full "mulhi3" with one of the lighter weight variants -;; that multiplies an HImode value by a QImode one. -;; -(define_split - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,rS") - (mult:HI (match_operand:HI 1 "nonimmediate_operand" "rS,ro") - (match_operand:HI 2 "const_int_operand" "P, P")))] - "(INTVAL (operands[2]) < 0x100)" - [(set (match_dup 0) - (mult:HI (match_dup 1) - (zero_extend:HI (match_dup 3))))] - "operands[3] = gen_int_mode (INTVAL (operands[2]), QImode);") - -;; -;; Divide/Modulus functions. -;; - -(define_expand "udivmodhi4" - [(parallel [(set (reg:HI 128) - (udiv:HI (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" ""))) - (set (reg:HI 130) - (umod:HI (match_dup 1) (match_dup 2))) - (clobber (reg:QI 132)) - (clobber (reg:QI 133))]) - (set (match_operand:HI 0 "general_operand" "") (reg:HI 128)) - (set (match_operand:HI 3 "general_operand" "") (reg:HI 130))] - "" - "") - -(define_insn "*udivmodhi4_call" - [(set (reg:HI 128) - (udiv:HI (match_operand:HI 0 "general_operand" "uSi,uoi") - (match_operand:HI 1 "general_operand" "uoi,uSi"))) - (set (reg:HI 130) - (umod:HI (match_dup 0) (match_dup 1))) - (clobber (reg:QI 132)) - (clobber (reg:QI 133))] - "" - "push\\t%L1%<\;push\\t%H1%<\;push\\t%L0%<\;push\\t%H0%>%>%>\;page\\t__udivmodhi4\;call\\t__udivmodhi4") - -(define_expand "divmodhi4" - [(parallel [(set (reg:HI 128) - (div:HI (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" ""))) - (set (reg:HI 130) - (mod:HI (match_dup 1) - (match_dup 2))) - (clobber (reg:QI 132)) - (clobber (reg:QI 133)) - (clobber (reg:QI 134)) - (clobber (reg:QI 135))]) - (set (match_operand:HI 0 "general_operand" "") (reg:HI 128)) - (set (match_operand:HI 3 "general_operand" "") (reg:HI 130))] - "" - "") - -(define_insn "*divmodhi4_call" - [(set (reg:HI 128) - (div:HI (match_operand:HI 0 "general_operand" "uSi,uoi") - (match_operand:HI 1 "general_operand" "uoi,uSi"))) - (set (reg:HI 130) - (mod:HI (match_dup 0) (match_dup 1))) - (clobber (reg:QI 132)) - (clobber (reg:QI 133)) - (clobber (reg:QI 134)) - (clobber (reg:QI 135))] - "" - "push\\t%L1%<\;push\\t%H1%<\;push\\t%L0%<\;push\\t%H0%>%>%>\;page\\t__divmodhi4\;call\\t__divmodhi4") - -(define_expand "udivmodsi4" - [(parallel [(set (reg:SI 128) - (udiv:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (set (reg:SI 132) - (umod:SI (match_dup 1) - (match_dup 2))) - (clobber (reg:QI 136)) - (clobber (reg:QI 137)) - (clobber (reg:QI 138)) - (clobber (reg:QI 139))]) - (set (match_operand:SI 0 "general_operand" "") (reg:SI 128)) - (set (match_operand:SI 3 "general_operand" "") (reg:SI 132))] - "" - "") - -(define_insn "*udivmodsi4_call" - [(set (reg:SI 128) - (udiv:SI (match_operand:SI 0 "general_operand" "rSi,roi") - (match_operand:SI 1 "general_operand" "roi,rSi"))) - (set (reg:SI 132) - (umod:SI (match_dup 0) - (match_dup 1))) - (clobber (reg:QI 136)) - (clobber (reg:QI 137)) - (clobber (reg:QI 138)) - (clobber (reg:QI 139))] - "" - "push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%<\;push\\t%D0%<\;push\\t%C0%<\;push\\t%B0%<\;push\\t%A0%>%>%>%>%>%>%>\;page\\t__udivmodsi4\;call\\t__udivmodsi4") - -(define_expand "divmodsi4" - [(parallel [(set (reg:SI 128) - (div:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (set (reg:SI 132) - (mod:SI (match_dup 1) - (match_dup 2))) - (clobber (reg:QI 136)) - (clobber (reg:QI 137)) - (clobber (reg:QI 138)) - (clobber (reg:QI 139)) - (clobber (reg:QI 140)) - (clobber (reg:QI 141))]) - (set (match_operand:SI 0 "general_operand" "") (reg:SI 128)) - (set (match_operand:SI 3 "general_operand" "") (reg:SI 132))] - "" - "") - -(define_insn "*divmodsi4_call" - [(set (reg:SI 128) - (div:SI (match_operand:SI 0 "general_operand" "rSn,ron") - (match_operand:SI 1 "general_operand" "ron,rSn"))) - (set (reg:SI 132) - (mod:SI (match_dup 0) - (match_dup 1))) - (clobber (reg:QI 136)) - (clobber (reg:QI 137)) - (clobber (reg:QI 138)) - (clobber (reg:QI 139)) - (clobber (reg:QI 140)) - (clobber (reg:QI 141))] - "" - "push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%<\;push\\t%D0%<\;push\\t%C0%<\;push\\t%B0%<\;push\\t%A0%>%>%>%>%>%>%>\;page\\t__divmodsi4\;call\\t__divmodsi4") - -(define_expand "udivmoddi4" - [(parallel [(set (reg:DI 128) - (udiv:DI (match_operand:DI 1 "general_operand" "") - (match_operand:DI 2 "general_operand" ""))) - (set (reg:DI 136) - (umod:DI (match_dup 1) - (match_dup 2))) - (clobber (reg:QI 144)) - (clobber (reg:QI 145)) - (clobber (reg:QI 146)) - (clobber (reg:QI 147)) - (clobber (reg:QI 148)) - (clobber (reg:QI 149)) - (clobber (reg:QI 150)) - (clobber (reg:QI 151))]) - (set (match_operand:DI 0 "general_operand" "") (reg:DI 128)) - (set (match_operand:DI 3 "general_operand" "") (reg:DI 136))] - "" - "") - -(define_insn "*udivmoddi4_call" - [(set (reg:DI 128) - (udiv:DI (match_operand:DI 0 "general_operand" "rSi,roi") - (match_operand:DI 1 "general_operand" "roi,rSi"))) - (set (reg:DI 136) - (umod:DI (match_dup 0) - (match_dup 1))) - (clobber (reg:QI 144)) - (clobber (reg:QI 145)) - (clobber (reg:QI 146)) - (clobber (reg:QI 147)) - (clobber (reg:QI 148)) - (clobber (reg:QI 149)) - (clobber (reg:QI 150)) - (clobber (reg:QI 151))] - "" - "push\\t%Z1%<\;push\\t%Y1%<\;push\\t%X1%<\;push\\t%W1%<\;push\\t%V1%<\;push\\t%U1%<\;push\\t%T1%<\;push\\t%S1%<\;push\\t%Z0%<\;push\\t%Y0%<\;push\\t%X0%<\;push\\t%W0%<\;push\\t%V0%<\;push\\t%U0%<\;push\\t%T0%<\;push\\t%S00%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>\;page\\t__udivmoddi4\;call\\t__udivmoddi4") - -(define_expand "divmoddi4" - [(parallel [(set (reg:DI 128) - (div:DI (match_operand:DI 1 "general_operand" "") - (match_operand:DI 2 "general_operand" ""))) - (set (reg:DI 136) - (mod:DI (match_dup 1) - (match_dup 2))) - (clobber (reg:QI 144)) - (clobber (reg:QI 145)) - (clobber (reg:QI 146)) - (clobber (reg:QI 147)) - (clobber (reg:QI 148)) - (clobber (reg:QI 149)) - (clobber (reg:QI 150)) - (clobber (reg:QI 151))]) - (set (match_operand:DI 0 "general_operand" "") (reg:DI 128)) - (set (match_operand:DI 3 "general_operand" "") (reg:DI 136))] - "" - "") - -(define_insn "*divmoddi4_call" - [(set (reg:DI 128) - (div:DI (match_operand:DI 0 "general_operand" "rSn,ron") - (match_operand:DI 1 "general_operand" "ron,rSn"))) - (set (reg:DI 136) - (mod:DI (match_dup 0) - (match_dup 1))) - (clobber (reg:QI 144)) - (clobber (reg:QI 145)) - (clobber (reg:QI 146)) - (clobber (reg:QI 147)) - (clobber (reg:QI 148)) - (clobber (reg:QI 149)) - (clobber (reg:QI 150)) - (clobber (reg:QI 151))] - "" - "push\\t%Z1%<\;push\\t%Y1%<\;push\\t%X1%<\;push\\t%W1%<\;push\\t%V1%<\;push\\t%U1%<\;push\\t%T1%<\;push\\t%S1%<\;push\\t%Z0%<\;push\\t%Y0%<\;push\\t%X0%<\;push\\t%W0%<\;push\\t%V0%<\;push\\t%U0%<\;push\\t%T0%<\;push\\t%S00%>%>%>%>%>%>%>%>%>%>%>%>%>%>%>\;page\\t__divmoddi4\;call\\t__divmoddi4") - -;; -;; Arithmetic shift left instructions. -;; - -(define_insn "ashlqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=roR,roR, rS,roR, rS") - (ashift:QI - (match_operand:QI 1 "nonimmediate_operand" "0, rS,roR, 0, 0") - (match_operand:QI 2 "general_operand" "N, L, L, rS,roR")))] - "" - "@ - clrb status,0\;rl\\t%0 - mov\\tw,%e2\;mulu\\tw,%1\;mov\\t%0,w - mov\\tw,%e2\;mulu\\tw,%1\;mov\\t%0,w - mov\\tw,%2\;snz\;page\\t1f\;jmp\\t1f\;2:clrb\\tstatus,0\;rl\\t%0\;decsz\\twreg\;page\\t2b\;jmp\\t2b\;1: - mov\\tw,%2\;snz\;page\\t1f\;jmp\\t1f\;2:clrb\\tstatus,0\;rl\\t%0\;decsz\\twreg\;page\\t2b\;jmp\\t2b\;1:" - [(set_attr "clobberw" "no,yes,yes,yes,yes")]) - -;; Convert simple fixed-size shift of a zero-extended QImode value into a -;; multiply as our multiplier is much faster. We also do this so that the -;; multiply can possibly be merged into a much faster multiply-and-accumulate -;; operation. -;; -(define_split - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro, rS") - (ashift:HI (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "rS,roR")) - (match_operand:QI 2 "const_int_operand" "J, J")))] - "(INTVAL (operands[2]) < 8)" - [(set (match_dup 0) - (mult:HI (zero_extend:HI (match_dup 1)) - (zero_extend:HI (match_dup 3))))] - "operands[3] = gen_int_mode (1 << INTVAL (operands[2]), QImode);") - -(define_insn_and_split "*ashlhi3_by8_zero_extend" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro, rS") - (ashift:HI (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "rS,roR")) - (const_int 8)))] - "" - "#" - "reload_completed" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 3) (const_int 0))] - "{ - operands[2] = ip2k_get_high_half (operands[0], QImode); - operands[3] = ip2k_get_low_half (operands[0], QImode); - }") - -(define_insn "*ashlhi3_zero_extend" ; 0 1 - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro, rS") - (ashift:HI (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "rS,roR")) - (match_operand:QI 2 "const_int_operand" "n, n")))] - "" - "*{ - if (INTVAL (operands[2]) < 8) - return AS2 (mov, w, %1) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (mov, w, MULH) CR_TAB - AS2 (mov, %H0, w); - else - { - operands[3] = GEN_INT (INTVAL (operands[2]) - 8); - return AS2 (mov, w, %1) CR_TAB - AS2 (mulu, w, %e3) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS1 (clr, %L0); - } - }") - -;; Convert simple fixed-size shift of a HImode value into a multiply as -;; our multiplier is much faster. We also do this so that the multiply can -;; possibly be merged into a much faster multiply-and-accumulate operation. -;; -(define_split - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,rS") - (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "rS,ro") - (match_operand:QI 2 "const_int_operand" "J, J")))] - "(INTVAL (operands[2]) < 8)" - [(set (match_dup 0) - (mult:HI (match_dup 1) - (zero_extend:HI (match_dup 3))))] - "operands[3] = gen_int_mode (1 << INTVAL (operands[2]), QImode);") - -(define_insn_and_split "ashlhi3_split" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,rS") - (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "rS,ro") - (match_operand:QI 2 "const_int_operand" "n, n")))] - "(INTVAL (operands[2]) >= 8)" - "#" - "&& ip2k_reorg_split_himode" - [(set (match_dup 4) (const_int 0))] - "{ - operands[3] = ip2k_get_high_half (operands[0], QImode); - operands[4] = ip2k_get_low_half (operands[0], QImode); - operands[5] = ip2k_get_low_half (operands[1], QImode); - - if (INTVAL (operands[2]) == 8) - emit_insn (gen_movqi (operands[3], operands[5])); - else - { - operands[6] = gen_int_mode (INTVAL (operands[2]) - 8, QImode); - emit_insn (gen_ashlqi3 (operands[3], operands[5], operands[6])); - } - }") - -(define_insn "ashlhi3" ; 0 1 2 3 4 - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,&rS,&ro,ro, rS") - (ashift:HI - (match_operand:HI 1 "nonimmediate_operand" "0, ro, rS, 0, 0") - (match_operand:QI 2 "general_operand" "L, L, L,rS,roR")))] - "" - "*{ - switch (which_alternative) - { - case 0: - switch (INTVAL (operands[2])) - { - case 1: - return AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %L0) CR_TAB - AS1 (rl, %H0); - - case 2: - return AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %L0) CR_TAB - AS1 (rl, %H0) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %L0) CR_TAB - AS1 (rl, %H0); - - case 3: - case 4: - case 5: - case 6: - return AS2 (mov, w, %L1) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS1 (push, MULH%<) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (or, 1(SP), w) CR_TAB - AS1 (pop, %H0%>); - - case 7: - return AS1 (rr, %H0) CR_TAB - AS2 (mov, w, %L0) CR_TAB - AS1 (clr, %L0) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0); - - default: - /* Should be caught by a different insn pattern */ - abort (); - } - - case 1: - case 2: - switch (INTVAL (operands[2])) - { - case 1: - return AS2 (clrb, status, 0) CR_TAB - AS2 (rl, w, %L1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (rl, w, %H1) CR_TAB - AS2 (mov, %H0, w); - - case 2: - return AS2 (clrb, status, 0) CR_TAB - AS2 (rl, w, %L1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (rl, w, %H1) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %L0) CR_TAB - AS1 (rl, %H0); - - case 3: - case 4: - case 5: - case 6: - return AS2 (mov, w, %L1) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS1 (push, MULH%<) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (or, 1(SP), w) CR_TAB - AS1 (pop, %H0%>); - - case 7: - return AS2 (rr, w, %H1) CR_TAB - AS2 (mov, w, %L1) CR_TAB - AS1 (clr, %L0) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0); - - default: - /* Should be caught by a different insn pattern */ - abort (); - } - - case 3: - case 4: - return AS2 (mov, w, %2) CR_TAB - AS1 (snz,) CR_TAB - AS1 (page, 2f) CR_TAB - AS1 (jmp, 2f) CR_TAB - AS1 (1:,) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %L0) CR_TAB - AS1 (rl, %H0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b) CR_TAB - AS1 (2:,); - - default: - abort(); - } - }") - -(define_insn_and_split "*ashlsi3_by16_zero_extend" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro,rS") - (ashift:SI (zero_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "rS,ro")) - (const_int 16)))] - "" - "#" - "reload_completed" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 3) (const_int 0))] - "{ - operands[2] = ip2k_get_high_half (operands[0], HImode); - operands[3] = ip2k_get_low_half (operands[0], HImode); - }") - -(define_insn_and_split "ashlsi3_split" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0, rS, ro") - (match_operand:QI 2 "const_int_operand" "n, n, n")))] - "(INTVAL (operands[2]) >= 16)" - "#" - "&& ip2k_reorg_split_simode" - [(const_int 0)] - "{ - operands[3] = ip2k_get_high_half (operands[0], HImode); - operands[4] = ip2k_get_low_half (operands[0], HImode); - operands[5] = ip2k_get_low_half (operands[1], HImode); - - if (INTVAL (operands[2]) == 16) - { - emit_insn (gen_movhi (operands[3], operands[5])); - emit_insn (gen_movhi (operands[4], GEN_INT (0))); - } - else - { - operands[6] = GEN_INT (INTVAL (operands[2]) - 16); - emit_insn (gen_ashlhi3 (operands[3], operands[5], operands[6])); - emit_insn (gen_movhi (operands[4], GEN_INT (0))); - } - }") - -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS,ro,&ro,&rS") - (ashift:SI - (match_operand:SI 1 "nonimmediate_operand" "0, 0, 0, rS, ro") - (match_operand:QI 2 "general_operand" "L,roR,rS, L, L")))] - "" - "*{ - switch (which_alternative) { - case 0: - switch (INTVAL (operands[2])) { - case 1: - return AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0) CR_TAB - AS1 (rl, %B0) CR_TAB - AS1 (rl, %A0); - - case 2: - return AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0) CR_TAB - AS1 (rl, %B0) CR_TAB - AS1 (rl, %A0) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0) CR_TAB - AS1 (rl, %B0) CR_TAB - AS1 (rl, %A0); - - case 8: - return AS2 (mov, w, %B0) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (mov, w, %C0) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, w, %D0) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS1 (clr, %D0); - - case 16: - return AS2 (mov, w, %C0) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (mov, w, %D0) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %D0); - - case 23: - return AS2 (rr, w, %C0) CR_TAB - AS2 (mov, w, %D0) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %D0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0); - - case 24: - return AS2 (mov, w, %D0) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %D0); - - case 31: - return AS2 (rr, w, %D0) CR_TAB - AS1 (clr, %A0) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %D0) CR_TAB - AS1 (rr, %A0); - - default: - return AS2 (mov, w, %2) CR_TAB - AS1 (1:,) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0) CR_TAB - AS1 (rl, %B0) CR_TAB - AS1 (rl, %A0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b); - } - - case 1: - case 2: - return AS2 (mov, w, %2) CR_TAB - AS1 (snz,) CR_TAB - AS1 (page, 2f) CR_TAB - AS1 (jmp, 2f) CR_TAB - AS1 (1:,) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0) CR_TAB - AS1 (rl, %B0) CR_TAB - AS1 (rl, %A0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b) CR_TAB - AS1 (2:,); - - case 3: - case 4: - switch (INTVAL (operands[2])) { - case 1: - return AS2 (clrb, status, 0) CR_TAB - AS2 (rl, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (rl, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (rl, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (rl, w, %A1) CR_TAB - AS2 (mov, %A0, w); - - case 2: - return AS2 (clrb, status, 0) CR_TAB - AS2 (rl, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (rl, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (rl, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (rl, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0) CR_TAB - AS1 (rl, %B0) CR_TAB - AS1 (rl, %A0); - - case 8: - return AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, w, %D1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS1 (clr, %D0); - - case 16: - return AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (mov, w, %D1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %D0); - - case 23: - return AS2 (rr, w, %C1) CR_TAB - AS2 (mov, w, %D1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %D0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0); - - case 24: - return AS2 (mov, w, %D1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %D0); - - case 31: - return AS2 (rr, w, %D1) CR_TAB - AS1 (clr, %A0) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %D0) CR_TAB - AS1 (rr, %A0); - - default: - return AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %2) CR_TAB - AS1 (1:,) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0) CR_TAB - AS1 (rl, %B0) CR_TAB - AS1 (rl, %A0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b); - } - default: - abort (); - } - }") - -(define_insn_and_split "ashldi3_split" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0, rS, ro") - (match_operand:QI 2 "const_int_operand" "n, n, n")))] - "((INTVAL (operands[2]) >= 32) || (INTVAL (operands[2]) == 16))" - "#" - "&& ip2k_reorg_split_dimode" - [(const_int 0)] - "{ - operands[3] = ip2k_get_high_half (operands[0], SImode); - operands[4] = ip2k_get_low_half (operands[0], SImode); - operands[5] = ip2k_get_low_half (operands[1], SImode); - - if (INTVAL (operands[2]) == 16) - { - operands[6] = ip2k_get_high_half (operands[1], SImode); - operands[7] = ip2k_get_high_half (operands[3], HImode); - operands[8] = ip2k_get_low_half (operands[3], HImode); - operands[9] = ip2k_get_high_half (operands[4], HImode); - operands[10] = ip2k_get_low_half (operands[4], HImode); - operands[11] = ip2k_get_low_half (operands[6], HImode); - operands[12] = ip2k_get_high_half (operands[5], HImode); - operands[13] = ip2k_get_low_half (operands[5], HImode); - emit_insn (gen_movhi (operands[7], operands[11])); - emit_insn (gen_movhi (operands[8], operands[12])); - emit_insn (gen_movhi (operands[9], operands[13])); - emit_insn (gen_movhi (operands[10], GEN_INT (0))); - } - else if (INTVAL (operands[2]) == 32) - { - emit_insn (gen_movsi (operands[3], operands[5])); - emit_insn (gen_movsi (operands[4], GEN_INT (0))); - } - else - { - operands[6] = GEN_INT (INTVAL (operands[2]) - 32); - emit_insn (gen_ashlsi3 (operands[3], operands[5], operands[6])); - emit_insn (gen_movsi (operands[4], GEN_INT (0))); - } - }") - -;; -;; Arithmetic shift right instructions. -;; - -(define_expand "ashrqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "general_operand" "")))] - "" - "if (operands[2] == const0_rtx) - { - emit_move_insn (operands[0], operands[1]); - DONE; - } - ") - -(define_insn "*ashrqi3" - [(set - (match_operand:QI 0 "nonimmediate_operand" "=roR,roR, rS,roR, rS,roR, rS") - (ashiftrt:QI - (match_operand:QI 1 "nonimmediate_operand" "0, 0, 0, rS,roR, rS,roR") - (match_operand:QI 2 "general_operand" "N, rS,roR, N, N, L, L")))] - "" - "*{ - switch (which_alternative) - { - case 0: - return AS2 (rl, w, %0) CR_TAB - AS1 (rr, %0); - - case 3: - case 4: - return AS2 (rl, w, %1) CR_TAB /* dup the sign bit */ - AS2 (rr, w, %1) CR_TAB - AS2 (mov, %0, w); - - case 5: - case 6: - /* Do >> by left-shifting partially into MULH. */ - operands[2] = GEN_INT (8 - INTVAL (operands[2])); - return AS2 (mov, w, %1) CR_TAB - AS2 (muls, w, %e2) CR_TAB - AS2 (mov, w, mulh) CR_TAB - AS2 (mov, %0, w); - - case 1: - case 2: - default: - return AS2 (mov, w, %2) CR_TAB - AS1 (snz,) CR_TAB - AS1 (page, 2f) CR_TAB - AS1 (jmp, 2f) CR_TAB - AS1 (1:,) CR_TAB - AS2 (setb, status, 0) CR_TAB - AS2 (sb, %0, 7) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b) CR_TAB - AS1 (2:,); - } - }") - -(define_insn "ashrhi3" ; 0 1 2 3 4 - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,&rS,&ro,ro, rS") - (ashiftrt:HI - (match_operand:HI 1 "nonimmediate_operand" "0, ro, rS, 0, 0") - (match_operand:QI 2 "general_operand" "L, L, L,rS,roR")))] - "" - "*{ - switch (which_alternative) { - case 0: - switch (INTVAL (operands[2])) { - case 1: - return AS2 (rl, w, %H0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0); - - case 2: - return AS2 (rl, w, %H0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0) CR_TAB - AS2 (rl, w, %H0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0); - - case 8: - return AS2 (mov, w, %H0) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS1 (clr, %H0) CR_TAB - AS2 (snb, %L0, 7) CR_TAB - AS1 (not, %H0); - - default: - return AS2 (mov, w, %2) CR_TAB - AS1 (1:,) CR_TAB - AS2 (setb, status, 0) CR_TAB - AS2 (sb, %H0, 7) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b); - } - - case 1: - case 2: - switch (INTVAL (operands[2])) { - case 1: - return AS2 (rl, w, %H1) CR_TAB - AS2 (rr, w, %H1) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (rr, w, %L1) CR_TAB - AS2 (mov, %L0, w); - - case 2: - return AS2 (rl, w, %H1) CR_TAB - AS2 (rr, w, %H1) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (rr, w, %L1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (rl, w, %H0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0); - - case 8: - return AS2 (mov, w, %H1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS1 (clr, %H0) CR_TAB - AS2 (snb, %L0, 7) CR_TAB - AS1 (not, %H0); - - default: - return AS2 (mov, w, %L1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (mov, w, %2) CR_TAB - AS1 (1:,) CR_TAB - AS2 (setb, status, 0) CR_TAB - AS2 (sb, %H0, 7) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b); - } - - case 3: - case 4: - return AS2 (mov, w, %2) CR_TAB - AS1 (snz,) CR_TAB - AS1 (page, 2f) CR_TAB - AS1 (jmp, 2f) CR_TAB - AS1 (1:,) CR_TAB - AS2 (setb, status, 0) CR_TAB - AS2 (sb, %H0, 7) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b) CR_TAB - AS1 (2:,); - - default: - abort(); - } - }") - -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS,ro,&ro,&rS") - (ashiftrt:SI - (match_operand:SI 1 "nonimmediate_operand" "0, 0, 0, rS, ro") - (match_operand:QI 2 "general_operand" "L,roR,rS, L, L")))] - "" - "*{ - switch (which_alternative) { - case 0: - switch (INTVAL (operands[2])) { - case 1: - return AS2 (rl, w, %A0) CR_TAB /* dup the sign bit */ - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0); - - case 2: - return AS2 (rl, w, %A0) CR_TAB /* dup the sign bit */ - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0) CR_TAB - AS2 (rl, w, %A0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0); - - case 8: - return AS2 (mov, w, %C0) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %B0) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, w, %A0) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS1 (clr, %A0) CR_TAB - AS2 (snb, %B0, 7) CR_TAB - AS1 (not, %A0); - - case 16: - return AS2 (mov, w, %B0) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %A0) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS1 (clr, WREG) CR_TAB - AS2 (snb, %C0, 7) CR_TAB - AS1 (not, WREG) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, %A0, w); - - case 23: - return AS2 (rl, w, %B0) CR_TAB - AS2 (mov, w, %A0) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (clr, WREG) CR_TAB - AS2 (snb, %D0, 7) CR_TAB - AS1 (not, WREG) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0); - - case 24: - return AS2 (mov, w, %A0) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (clr, WREG) CR_TAB - AS2 (snb, %D0, 7) CR_TAB - AS1 (not, WREG) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, %A0, w); - - case 31: - return AS2 (rl, w, %A0) CR_TAB - AS1 (clr, WREG) CR_TAB - AS2 (snb, %A0, 7) CR_TAB - AS1 (not, WREG) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS1 (rl, %D0); - - default: - return AS2 (mov, w, %2) CR_TAB - AS1 (1:,) CR_TAB - AS2 (setb, status, 0) CR_TAB - AS2 (sb, %A0, 7) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0) CR_TAB - AS1 (decsz, WREG) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b); - } - - case 1: - case 2: - return AS2 (mov, w, %2) CR_TAB - AS1 (snz,) CR_TAB - AS1 (page, 2f) CR_TAB - AS1 (jmp, 2f) CR_TAB - AS1 (1:,) CR_TAB - AS2 (setb, status, 0) CR_TAB - AS2 (sb, %A0, 7) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0) CR_TAB - AS1 (decsz, WREG) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b) CR_TAB - AS1 (2:,); - - case 3: - case 4: - switch (INTVAL (operands[2])) { - case 1: - return AS2 (rl, w, %A1) CR_TAB /* dup the sign bit */ - AS2 (rr, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (rr, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (rr, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (rr, w, %D1) CR_TAB - AS2 (mov, %D0, w); - - case 2: - return AS2 (rl, w, %A1) CR_TAB /* dup the sign bit */ - AS2 (rr, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (rr, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (rr, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (rr, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (rl, w, %A0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0); - - case 8: - return AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS1 (clr, %A0) CR_TAB - AS2 (snb, %B0, 7) CR_TAB - AS1 (not, %A0); - - case 16: - return AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS1 (clr, WREG) CR_TAB - AS2 (snb, %C0, 7) CR_TAB - AS1 (not, WREG) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, %A0, w); - - case 23: - return AS2 (rl, w, %B1) CR_TAB - AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (clr, WREG) CR_TAB - AS2 (snb, %D0, 7) CR_TAB - AS1 (not, WREG) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0); - - case 24: - return AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (clr, WREG) CR_TAB - AS2 (snb, %D0, 7) CR_TAB - AS1 (not, WREG) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, %A0, w); - - case 31: - return AS2 (rl, w, %A1) CR_TAB - AS1 (clr, WREG) CR_TAB - AS2 (snb, %A1, 7) CR_TAB - AS1 (not, WREG) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS1 (rl, %D0); - - default: - return AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %2) CR_TAB - AS1 (1:,) CR_TAB - AS2 (setb, status, 0) CR_TAB - AS2 (sb, %A0, 7) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b); - } - default: - abort (); - } - }") - -;; -;; Logical shift right instructions. -;; - -(define_insn "lshrqi3" - [(set (match_operand:QI - 0 "nonimmediate_operand" "=roR, rS,roR,roR, rS,&roR,roR, rS") - (lshiftrt:QI - (match_operand:QI - 1 "nonimmediate_operand" "0, 0, 0, rS,roR, rS, rS,roR") - (match_operand:QI - 2 "general_operand" "N,roR, rS, N, N, rS, L, L")))] - "" - "*{ - switch (which_alternative) - { - case 0: - return AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %0); - - case 1: - case 2: - return AS2 (mov, w, %2) CR_TAB - AS1 (snz,) CR_TAB - AS1 (page, 2f) CR_TAB - AS1 (jmp, 2f) CR_TAB - AS1 (1:,) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b) CR_TAB - AS1 (2:,); - - case 3: - case 4: - return AS2 (clrb, status, 0) CR_TAB - AS2 (rr, w, %1) CR_TAB - AS2 (mov, %0, w); - - case 5: - return AS2 (mov, w, %1) CR_TAB - AS2 (mov, %0, w) CR_TAB - AS2 (mov, w, %2) CR_TAB - AS1 (snz,) CR_TAB - AS1 (page, 2f) CR_TAB - AS1 (jmp, 2f) CR_TAB - AS1 (1:,) - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b) CR_TAB - AS1 (2:,); - - case 6: - case 7: - /* Do >> by left-shifting partially into MULH. */ - operands[2] = GEN_INT (8 - INTVAL (operands[2])); - return AS2 (mov, w, %1) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (mov, w, mulh) CR_TAB - AS2 (mov, %0, w); - default: - abort (); - } - }") - -(define_insn_and_split "lshrhi3_split" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,rS") - (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "rS,ro") - (match_operand:QI 2 "const_int_operand" "n, n")))] - "(INTVAL (operands[2]) >= 8)" - "#" - "&& ip2k_reorg_split_himode" - [(const_int 0)] - "{ - operands[3] = ip2k_get_high_half (operands[0], QImode); - operands[4] = ip2k_get_low_half (operands[0], QImode); - operands[5] = ip2k_get_high_half (operands[1], QImode); - - if (INTVAL (operands[2]) == 8) - emit_insn (gen_movqi (operands[4], operands[5])); - else - { - operands[6] = GEN_INT (INTVAL (operands[2]) - 8); - emit_insn (gen_lshrqi3 (operands[4], operands[5], operands[6])); - } - emit_insn (gen_movqi (operands[3], GEN_INT (0))); - }") - -(define_insn "lshrhi3" ; 0 1 2 3 4 - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,&rS,&ro,ro, rS") - (lshiftrt:HI - (match_operand:HI 1 "nonimmediate_operand" " 0, ro, rS, 0, 0") - (match_operand:QI 2 "general_operand" "L, L, L,rS,roR")))] - "" - "*{ - switch (which_alternative) - { - case 0: - switch (INTVAL (operands[2])) - { - case 1: - return AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0); - - case 2: - return AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0); - - case 3: - case 4: - case 5: - case 6: - case 7: - operands[2] = GEN_INT (8 - INTVAL (operands[2])); - return AS2 (mov, w, %L0) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (mov, w, MULH) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (mov, w, %H0) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (or, %L0, w) CR_TAB - AS2 (mov, w, MULH) CR_TAB - AS2 (mov, %H0, w); - - default: - /* Should be caught by a different insn pattern */ - abort (); - } - - case 1: - case 2: - switch (INTVAL (operands[2])) - { - case 1: - return AS2 (clrb, status, 0) CR_TAB - AS2 (rr, w, %H1) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (rr, w, %L1) CR_TAB - AS2 (mov, %L0, w); - - case 2: - return AS2 (clrb, status, 0) CR_TAB - AS2 (rr, w, %H1) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (rr, w, %L1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0); - - case 3: - case 4: - case 5: - case 6: - case 7: - operands[2] = GEN_INT (8 - INTVAL (operands[2])); - return AS2 (mov, w, %L1) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (mov, w, MULH) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mulu, w, %e2) CR_TAB - AS2 (or, %L0, w) CR_TAB - AS2 (mov, w, MULH) CR_TAB - AS2 (mov, %H0, w); - - default: - /* Should be caught by a different insn pattern */ - abort (); - } - - case 3: - case 4: - return AS2 (mov, w, %2) CR_TAB - AS1 (snz,) CR_TAB - AS1 (page, 2f) CR_TAB - AS1 (jmp, 2f) CR_TAB - AS1 (1:,) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %H0) CR_TAB - AS1 (rr, %L0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b) CR_TAB - AS1 (2:,); - - default: - abort(); - } - }") - -(define_insn_and_split "lshrsi3_split" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0, rS, ro") - (match_operand:QI 2 "const_int_operand" "n, n, n")))] - "(INTVAL (operands[2]) >= 16)" - "#" - "&& ip2k_reorg_split_simode" - [(const_int 0)] - "{ - operands[3] = ip2k_get_high_half (operands[0], HImode); - operands[4] = ip2k_get_low_half (operands[0], HImode); - operands[5] = ip2k_get_high_half (operands[1], HImode); - - if (INTVAL (operands[2]) == 16) - emit_insn (gen_movhi (operands[4], operands[5])); - else - { - operands[6] = GEN_INT (INTVAL (operands[2]) - 16); - emit_insn (gen_lshrhi3 (operands[4], operands[5], operands[6])); - } - emit_insn (gen_movhi (operands[3], GEN_INT (0))); - }") - -;; This occurs frequently in supporting FP among other things, -;; and out-of-line is almost as big as inline, so.... -;; -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS,ro,&ro,&rS") - (lshiftrt:SI - (match_operand:SI 1 "nonimmediate_operand" "0, 0, 0, rS, ro") - (match_operand:QI 2 "general_operand" "L,roR,rS, L, L")))] - - "" - "*{ - switch (which_alternative) { - case 0: - switch (INTVAL (operands[2])) { - case 1: - return AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0); - - case 2: - return AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0); - - case 8: - return AS2 (mov, w, %C0) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %B0) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, w, %A0) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS1 (clr, %A0); - - case 16: - return AS2 (mov, w, %B0) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %A0) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %A0); - - case 23: - return AS2 (rl, w, %B0) CR_TAB - AS2 (mov, w, %A0) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %A0) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0); - - case 24: - return AS2 (mov, w, %A0) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %A0); - - case 31: - return AS2 (rl, w, %A0) CR_TAB - AS1 (clr, %D0) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %A0) CR_TAB - AS1 (rl, %D0); - - default: - return AS2 (mov, w, %2) CR_TAB - AS1 (1:,) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b); - } - - case 1: - case 2: - return AS2 (mov, w, %2) CR_TAB - AS1 (snz,) CR_TAB - AS1 (page, 2f) CR_TAB - AS1 (jmp, 2f) CR_TAB - AS1 (1:,) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b) CR_TAB - AS1 (2:,); - - case 3: - case 4: - switch (INTVAL (operands[2])) { - case 1: - return AS2 (clrb, status, 0) CR_TAB - AS2 (rr, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (rr, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (rr, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (rr, w, %D1) CR_TAB - AS2 (mov, %D0, w); - - case 2: - return AS2 (clrb, status, 0) CR_TAB - AS2 (rr, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (rr, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (rr, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (rr, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0); - - case 8: - return AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS1 (clr, %A0); - - case 16: - return AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %A0); - - case 23: - return AS2 (rl, w, %B1) CR_TAB - AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %A0) CR_TAB - AS1 (rl, %D0) CR_TAB - AS1 (rl, %C0); - - case 24: - return AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %A0); - - case 31: - return AS2 (rl, w, %A1) CR_TAB - AS1 (clr, %D0) CR_TAB - AS1 (clr, %C0) CR_TAB - AS1 (clr, %B0) CR_TAB - AS1 (clr, %A0) CR_TAB - AS1 (rl, %D0); - - default: - return AS2 (mov, w, %A1) CR_TAB - AS2 (mov, %A0, w) CR_TAB - AS2 (mov, w, %B1) CR_TAB - AS2 (mov, %B0, w) CR_TAB - AS2 (mov, w, %C1) CR_TAB - AS2 (mov, %C0, w) CR_TAB - AS2 (mov, w, %D1) CR_TAB - AS2 (mov, %D0, w) CR_TAB - AS2 (mov, w, %2) CR_TAB - AS1 (1:,) CR_TAB - AS2 (clrb, status, 0) CR_TAB - AS1 (rr, %A0) CR_TAB - AS1 (rr, %B0) CR_TAB - AS1 (rr, %C0) CR_TAB - AS1 (rr, %D0) CR_TAB - AS1 (decsz, wreg) CR_TAB - AS1 (page, 1b) CR_TAB - AS1 (jmp, 1b); - } - default: - abort (); - } - }") - -(define_insn_and_split "lshrdi3_split" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0, rS, ro") - (match_operand:QI 2 "const_int_operand" "n, n, n")))] - "((INTVAL (operands[2]) >= 32) || (INTVAL (operands[2]) == 16))" - "#" - "&& ip2k_reorg_split_dimode" - [(const_int 0)] - "{ - operands[3] = ip2k_get_high_half (operands[0], SImode); - operands[4] = ip2k_get_low_half (operands[0], SImode); - operands[5] = ip2k_get_high_half (operands[1], SImode); - - if (INTVAL (operands[2]) == 16) - { - operands[6] = ip2k_get_low_half (operands[1], SImode); - operands[7] = ip2k_get_high_half (operands[3], HImode); - operands[8] = ip2k_get_low_half (operands[3], HImode); - operands[9] = ip2k_get_high_half (operands[4], HImode); - operands[10] = ip2k_get_low_half (operands[4], HImode); - operands[11] = ip2k_get_high_half (operands[6], HImode); - operands[12] = ip2k_get_low_half (operands[5], HImode); - operands[13] = ip2k_get_high_half (operands[5], HImode); - emit_insn (gen_movhi (operands[10], operands[11])); - emit_insn (gen_movhi (operands[9], operands[12])); - emit_insn (gen_movhi (operands[8], operands[13])); - emit_insn (gen_movhi (operands[7], GEN_INT(0))); - } - else if (INTVAL (operands[2]) == 32) - { - emit_insn (gen_movsi (operands[4], operands[5])); - emit_insn (gen_movsi (operands[3], GEN_INT (0))); - } - else - { - operands[6] = GEN_INT (INTVAL (operands[2]) - 32); - emit_insn (gen_lshrsi3 (operands[4], operands[5], operands[6])); - emit_insn (gen_movsi (operands[3], GEN_INT (0))); - } - }") - -;; -;; Absolute value conversion instructions. -;; - -(define_insn "absqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g") - (abs:QI (match_operand:QI 1 "nonimmediate_operand" "g")))] - "" - "mov\\tw,%1\;snb\\twreg,7\;sub\\tw,#0\;mov\\t%0,w") - -(define_insn "abssf2" - [(set (match_operand:SF 0 "nonimmediate_operand" "=ro") - (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0")))] - "" - "clrb %A0,7" - [(set_attr "clobberw" "no")]) - -;; -;; Negate (X = 0 - Y) instructions. -;; - -(define_insn_and_split "negqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0, rS, ro")))] - "" - "#" - "" - [(set (match_dup 0) - (not:QI (match_dup 1))) - (set (match_dup 0) - (plus:QI (match_dup 0) - (const_int 1)))] - "") - -(define_insn_and_split "neghi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0, rS, ro")))] - "" - "#" - "" - [(set (match_dup 0) - (not:HI (match_dup 1))) - (set (match_dup 0) - (plus:HI (match_dup 0) - (const_int 1)))] - "") - -(define_insn_and_split "negsi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0, rS, ro")))] - "" - "#" - "" - [(set (match_dup 0) - (not:SI (match_dup 1))) - (set (match_dup 0) - (plus:SI (match_dup 0) - (const_int 1)))] - "") - -(define_insn_and_split "negdi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0, rS, ro")))] - "" - "#" - "" - [(set (match_dup 0) - (not:DI (match_dup 1))) - (set (match_dup 0) - (plus:DI (match_dup 0) - (const_int 1)))] - "") - -;; -;; Bitwise not (one's complement) instructions. -;; - -(define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=g,roR, rS") - (not:QI (match_operand:QI 1 "general_operand" "0, rS,roR")))] - "" - "@ - not\\t%0 - not\\tw,%1\;mov\\t%0,w - not\\tw,%1\;mov\\t%0,w" - [(set_attr "skip" "yes,no,no") - (set_attr "clobberw" "no,yes,yes")]) - -(define_insn_and_split "one_cmplhi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (not:HI (match_operand:HI 1 "general_operand" "0, rS, ro")))] - "" - "#" - "(ip2k_reorg_split_himode)" - [(set (match_dup 3) - (not:QI (match_dup 4))) - (set (match_dup 5) - (not:QI (match_dup 6)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], QImode); - operands[4] = ip2k_get_high_half (operands[1], QImode); - operands[5] = ip2k_get_low_half (operands[0], QImode); - operands[6] = ip2k_get_low_half (operands[1], QImode); - }") - -(define_insn_and_split "one_cmplsi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (not:SI (match_operand:SI 1 "general_operand" "0, rS, ro")))] - "" - "#" - "(ip2k_reorg_split_simode)" - [(set (match_dup 3) - (not:HI (match_dup 4))) - (set (match_dup 5) - (not:HI (match_dup 6)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], HImode); - operands[4] = ip2k_get_high_half (operands[1], HImode); - operands[5] = ip2k_get_low_half (operands[0], HImode); - operands[6] = ip2k_get_low_half (operands[1], HImode); - }") - -(define_insn_and_split "one_cmpldi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,&ro,&rS") - (not:DI (match_operand:DI 1 "general_operand" "0, rS, ro")))] - "" - "#" - "(ip2k_reorg_split_dimode)" - [(set (match_dup 3) - (not:SI (match_dup 4))) - (set (match_dup 5) - (not:SI (match_dup 6)))] - "{ - operands[3] = ip2k_get_high_half (operands[0], SImode); - operands[4] = ip2k_get_high_half (operands[1], SImode); - operands[5] = ip2k_get_low_half (operands[0], SImode); - operands[6] = ip2k_get_low_half (operands[1], SImode); - }") - -;; -;; Sign extension instructions. -;; - -(define_insn "*push_extendqihi2" - [(set (match_operand:HI 0 "push_operand" "=<,<") - (sign_extend:HI (match_operand:QI 1 "general_operand" "roR,n")))] - "" - "@ - push\\t%1%<\;push\\t#0%<\;snb\\t%1,7\;not\\t1(SP)%>%> - push\\t%L1\;push\\t%H1" - [(set_attr "clobberw" "no,no")]) - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rS,ro,ro") - (sign_extend:HI (match_operand:QI 1 "general_operand" "roR,rS, n")))] - "" - "*{ - switch (which_alternative) - { - case 0: - case 1: - if (register_operand (operands[0], HImode) - && register_operand (operands[1], QImode) - && REGNO (operands[0]) == (REGNO (operands[1]) - 1)) - return AS1 (clr, %H0) CR_TAB - AS2 (snb, %1, 7) CR_TAB - AS1 (not, %H0); - else - return AS2 (mov, w, %1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS1 (clr, %H0) CR_TAB - AS2 (snb, wreg, 7) CR_TAB - AS1 (not, %H0); - - case 2: - return AS2 (mov, w, %L1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mov, %H0, w); - default: - abort (); - } - }") - -(define_insn "*push_extendhisi2" - [(set (match_operand:SI 0 "push_operand" "=<,<,<") - (sign_extend:SI (match_operand:HI 1 "general_operand" "roS,n,s")))] - "" - "@ - push\\t%L1%<\;push\\t%H1%<\;clr\\twreg\;snb\\t%H1,7\;not\\twreg\;push\\twreg\;push\\twreg%>%> - push\\t%D1\;push\\t%C1\;push\\t%B1\;push\\t%A1 - push\\t%L1\;push\\t%H1\;push\\t#0\;push\\t#0" - [(set_attr "clobberw" "yes,no,no")]) - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro,rS,ro,ro") - (sign_extend:SI (match_operand:HI 1 "general_operand" "rS,ro, n, s")))] - "" - "@ - mov\\tw,%L1\;push\\t%H1%<\;pop\\t%C0%>\;mov\\t%D0,w\;clr\\twreg\;snb\\t%C0,7\;not\\twreg\;mov\\t%B0,w\;mov\\t%A0,w - mov\\tw,%L1\;push\\t%H1%<\;pop\\t%C0%>\;mov\\t%D0,w\;clr\\twreg\;snb\\t%C0,7\;not\\twreg\;mov\\t%B0,w\;mov\\t%A0,w - mov\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A1\;mov\\t%A0,w - mov\\tw,%L1\;push\\t%H1%<\;pop\\t%C0%>\;mov\\t%D0,w\;clr\\t%B0\;clr\\t%A0") - -(define_insn "*push_extendqisi2" - [(set (match_operand:SI 0 "push_operand" "=<,<") - (sign_extend:SI (match_operand:QI 1 "general_operand" "roR,n")))] - "" - "@ - push\\t%1%<\;clr\\twreg\;snb\\t%1,7\;not\\twreg\;push\\twreg\;push\\twreg\;push\\twreg%> - push\\t%D1\;push\\t%C1\;push\\t%B1\;push\\t%A1" - [(set_attr "clobberw" "yes,no")]) - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS,ro") - (sign_extend:SI (match_operand:QI 1 "general_operand" "rS,roR, n")))] - "" - "@ - mov\\tw,%1\;mov\\t%D0,w\;clr\\twreg\;snb\\t%1,7\;not\\twreg\;mov\\t%C0,w\;mov\\t%B0,w\;mov\\t%A0,w - mov\\tw,%1\;mov\\t%D0,w\;clr\\twreg\;snb\\t%1,7\;not\\twreg\;mov\\t%C0,w\;mov\\t%B0,w\;mov\\t%A0,w - mov\\tw,%D1\;mov\\t%D0,w\;mov\\tw,%C1\;mov\\t%C0,w\;mov\\tw,%B1\;mov\\t%B0,w\;mov\\tw,%A1\;mov\\t%A0,w") - -;; -;; Zero extension instructions. -;; - -(define_insn "*push_zero_extendqihi2" - [(set (match_operand:HI 0 "push_operand" "=<") - (zero_extend:HI (match_operand:QI 1 "general_operand" "roRi")))] - "" - "push\\t%1\;push\\t#0" - [(set_attr "clobberw" "no")]) - -(define_insn_and_split "zero_extendqihi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=ro, rS") - (zero_extend:HI (match_operand:QI 1 "general_operand" "rSi,roRi")))] - "" - "#" - "ip2k_reorg_completed" - [(set (match_dup 3) (match_dup 1)) - (set (match_dup 2) (const_int 0))] - "{ - operands[2] = ip2k_get_high_half (operands[0], QImode); - operands[3] = ip2k_get_low_half (operands[0], QImode); - }") - -(define_insn "*push_zero_extendhisi2" - [(set (match_operand:SI 0 "push_operand" "=<") - (zero_extend:SI (match_operand:HI 1 "general_operand" "roSi")))] - "" - "push\\t%L1%<\;push\\t%H1%>\;push\\t#0\;push\\t#0") - -(define_insn_and_split "zero_extendhisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS") - (zero_extend:SI (match_operand:HI 1 "general_operand" "rSi,roi")))] - "" - "#" - "ip2k_reorg_completed" - [(set (match_dup 3) (match_dup 1)) - (set (match_dup 2) (const_int 0))] - "{ - operands[2] = ip2k_get_high_half (operands[0], HImode); - operands[3] = ip2k_get_low_half (operands[0], HImode); - }") - -(define_insn "*push_zero_extendqisi2" - [(set (match_operand:SI 0 "push_operand" "=<") - (zero_extend:SI (match_operand:QI 1 "general_operand" "roRi")))] - "" - "push\\t%1\;push\\t#0\;push\\t#0\;push\\t#0" - [(set_attr "clobberw" "no")]) - -(define_insn_and_split "zero_extendqisi2" - [(set (match_operand:SI 0 "nonimmediate_operand" "=ro, rS") - (zero_extend:SI (match_operand:QI 1 "general_operand" "rSi,roRi")))] - "" - "#" - "ip2k_reorg_completed" - [(set (match_dup 3) (zero_extend:HI (match_dup 1))) - (set (match_dup 2) (const_int 0))] - "{ - operands[2] = ip2k_get_high_half (operands[0], HImode); - operands[3] = ip2k_get_low_half (operands[0], HImode); - }") - -(define_insn "*push_zero_extendsidi2" - [(set (match_operand:DI 0 "push_operand" "=<") - (zero_extend:DI (match_operand:SI 1 "general_operand" "roSi")))] - "" - "push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%>%>%>\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0") - -(define_insn_and_split "zero_extendsidi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro, rS") - (zero_extend:DI (match_operand:SI 1 "general_operand" "rSi,roi")))] - "" - "#" - "ip2k_reorg_completed" - [(set (match_dup 3) (match_dup 1)) - (set (match_dup 2) (const_int 0))] - "{ - operands[2] = ip2k_get_high_half (operands[0], SImode); - operands[3] = ip2k_get_low_half (operands[0], SImode); - }") - -(define_insn "*push_zero_extendhidi2" - [(set (match_operand:DI 0 "push_operand" "=<") - (zero_extend:DI (match_operand:HI 1 "general_operand" "roSi")))] - "" - "push\\t%L1%<\;push\\t%H1%>\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0" - [(set_attr "clobberw" "no")]) - -(define_insn_and_split "zero_extendhidi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro, rS") - (zero_extend:DI (match_operand:HI 1 "general_operand" "rSi,roi")))] - "" - "#" - "ip2k_reorg_completed" - [(set (match_dup 3) (zero_extend:SI (match_dup 1))) - (set (match_dup 2) (const_int 0))] - "{ - operands[2] = ip2k_get_high_half (operands[0], SImode); - operands[3] = ip2k_get_low_half (operands[0], SImode); - }") - -(define_insn "*push_zero_extendqidi2" - [(set (match_operand:DI 0 "push_operand" "=<") - (zero_extend:DI (match_operand:QI 1 "general_operand" "roRi")))] - "" - "push\\t%1\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0\;push\\t#0" - [(set_attr "clobberw" "no")]) - -(define_insn_and_split "zero_extendqidi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=ro, rS") - (zero_extend:DI (match_operand:QI 1 "general_operand" "rSi,roRi")))] - "" - "#" - "ip2k_reorg_completed" - [(set (match_dup 3) (zero_extend:SI (match_dup 1))) - (set (match_dup 2) (const_int 0))] - "{ - operands[2] = ip2k_get_high_half (operands[0], SImode); - operands[3] = ip2k_get_low_half (operands[0], SImode); - }") - -;; -;; Truncation instructions. -;; - -(define_insn "truncsihi2" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rS, ro") - (truncate:HI (match_operand:SI 1 "general_operand" "roi,rSi")))] - "" - "@ - mov\\tw,%D1\;push\\t%C1%<\;pop\\t%H0%>\;mov\\t%L0,w - mov\\tw,%D1\;push\\t%C1%<\;pop\\t%H0%>\;mov\\t%L0,w") - -(define_insn "truncsiqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=rS, ro") - (truncate:QI (match_operand:SI 1 "general_operand" "roi,rSi")))] - "" - "@ - mov\\tw,%D1\;mov\\t%0,w - mov\\tw,%D1\;mov\\t%0,w") - -(define_insn "trunchiqi2" - [(set (match_operand:QI 0 "nonimmediate_operand" "=rS, ro") - (truncate:QI (match_operand:HI 1 "general_operand" "roi,rSi")))] - "" - "@ - mov\\tw,%L1\;mov\\t%0,w - mov\\tw,%L1\;mov\\t%0,w") - -;; -;; Compare with zero (test) instructions. -;; -;; As we don't have a particularly good set of condition codes we simply -;; tagging our comparison operands for use later within our "compare -;; and branch" instructions. -;; - -(define_insn "tstqi" - [(set (cc0) - (match_operand:QI 0 "nonimmediate_operand" "roR"))] - "" - "* return ip2k_set_compare (operands[0], const0_rtx);") - -(define_insn "tsthi" - [(set (cc0) - (match_operand:HI 0 "nonimmediate_operand" "roS"))] - "" - "* return ip2k_set_compare (operands[0], const0_rtx);") - -(define_insn "tstsi" - [(set (cc0) - (match_operand:SI 0 "nonimmediate_operand" "roS"))] - "" - "* return ip2k_set_compare (operands[0], const0_rtx);") - -(define_insn "tstdi" - [(set (cc0) - (match_operand:DI 0 "nonimmediate_operand" "roS"))] - "" - "* return ip2k_set_compare (operands[0], const0_rtx);") - -;; -;; General value comparison instructions. -;; -;; As we don't have a particularly good set of condition codes we simply -;; tagging our comparison operands for use later within our "compare -;; and branch" instructions. -;; - -(define_insn "cmpqi" - [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "roR, rS") - (match_operand:QI 1 "general_operand" "rSn,roRn")))] - "" - "* return ip2k_set_compare (operands[0], operands[1]);") - -(define_insn "cmphi" - [(set (cc0) - (compare (match_operand:HI 0 "nonimmediate_operand" "ro, rS") - (match_operand:HI 1 "general_operand" "rSn,ron")))] - "" - "* return ip2k_set_compare (operands[0], operands[1]);") - -(define_insn "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "nonimmediate_operand" "ro, rS") - (match_operand:SI 1 "general_operand" "rSn,ron")))] - "" - "* return ip2k_set_compare (operands[0], operands[1]);") - -(define_insn "cmpdi" - [(set (cc0) - (compare (match_operand:DI 0 "nonimmediate_operand" "ro, rS") - (match_operand:DI 1 "general_operand" "rSn,ron")))] - "" - "* return ip2k_set_compare (operands[0], operands[1]);") - -;; -;; Conditional jump instructions. -;; - -(define_expand "beq" - [(set (pc) - (if_then_else (eq (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bne" - [(set (pc) - (if_then_else (ne (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bge" - [(set (pc) - (if_then_else (ge (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (geu (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "blt" - [(set (pc) - (if_then_else (lt (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bltu" - [(set (pc) - (if_then_else (ltu (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - - -(define_expand "ble" - [(set (pc) - (if_then_else (le (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bleu" - [(set (pc) - (if_then_else (leu (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgt" - [(set (pc) - (if_then_else (gt (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - - -;; Implementation of conditional jumps. -;; -;; The assumption is that a previous test or compare instruction will have -;; provided the arguments to be compared to form cc0 and then we perform -;; a compare and branch operation here. -;; -(define_insn "*unsigned_cmp_branch" - [(set (pc) - (if_then_else (match_operator 1 "ip2k_unsigned_comparison_operator" - [(cc0) - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* return ip2k_gen_unsigned_comp_branch (insn, GET_CODE (operands[1]), - operands[0]);") - -;; Signed branches use Z, N or synthesized V. -;; result is generated as 0 (LT), 1 (EQ), 2 (GT) -;; -(define_insn "*signed_cmp_branch" - [(set (pc) - (if_then_else (match_operator 1 "ip2k_signed_comparison_operator" - [(cc0) - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* return ip2k_gen_signed_comp_branch (insn, GET_CODE (operands[1]), - operands[0]);") - -;; Reverse branch - reverse our comparison condition so that we can -;; branch in the opposite sense. -;; -(define_insn_and_split "*rvbranch" - [(set (pc) - (if_then_else (match_operator 1 "comparison_operator" [(cc0) - (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "#" - "reload_completed" - [(set (pc) - (if_then_else (match_dup 2) - (label_ref (match_operand 0 "" "")) - (pc)))] - "{ - operands[2] = gen_rtx (reverse_condition (GET_CODE (operands[1])), - GET_MODE (operands[1]), - cc0_rtx, const0_rtx); - }") - -;; This is a bit test and jump sequence. -;; -(define_insn "*bit_cmpqi_branch" - [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(zero_extract - (match_operand:QI 1 "nonimmediate_operand" "roR") - (const_int 1) - (match_operand 2 "immediate_operand" "i")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)" - "*{ - if (GET_CODE (operands[0]) == EQ) - OUT_AS2 (sb, %1, %b2); - else - OUT_AS2 (snb, %1, %b2); - return AS1 (page, %3) CR_TAB - AS1 (jmp, %3); - }" - [(set_attr "clobberw" "no")]) - -;; This is a bit test and jump sequence but for 16-bit operands. It's pretty -;; certain that there must be a way to do this using a zero_extract operation, -;; but this didn't seem to want to work so we use a bitwise and instead. This -;; is exactly as efficient but the combiner handles this OK - the implementation -;; here isn't quite as nice though. -;; -(define_insn "*bit_cmphi_branch" - [(set - (pc) - (if_then_else - (match_operator 0 "comparison_operator" - [(and:HI (match_operand:HI 1 "nonimmediate_operand" "roS") - (match_operand 2 "const_int_operand" "n")) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "((GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE) - && find_one_set_bit_p (INTVAL (operands[2])) != -1)" - "*{ - int bp = find_one_set_bit_p (INTVAL (operands[2])); - if (INTVAL (operands[2]) >= 8) - operands[4] = GEN_INT (bp - 8); - else - operands[4] = GEN_INT (bp); - - if (GET_CODE (operands[0]) == EQ) - { - if (INTVAL (operands[2]) >= 8) - OUT_AS2 (sb, %H1, %b4); - else - OUT_AS2 (sb, %L1, %b4); - } - else - { - if (INTVAL (operands[2]) >= 8) - OUT_AS2 (snb, %H1, %b4); - else - OUT_AS2 (snb, %L1, %b4); - } - return AS1 (page, %3) CR_TAB - AS1 (jmp, %3); - }" - [(set_attr "clobberw" "no")]) - -;; Add two operands, compare with a third and branch if equal or not-equal. -;; -(define_insn "*add_and_comp_branch" - [(set - (pc) - (if_then_else - (match_operator 0 "comparison_operator" - [(plus:HI - (match_operand:HI 1 "nonimmediate_operand" "ro, rS, rS") - (match_operand:HI 2 "general_operand" "rSn,ron,rSn")) - (match_operand:HI 3 "general_operand" "rSn,rSn,ron")]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)" - "*{ - OUT_AS2 (mov, w, %L2); - OUT_AS2 (add, w, %L1); - OUT_AS2 (cse, w, %L3); - if (GET_CODE (operands[0]) == EQ) - { - OUT_AS1 (page, 1f); - OUT_AS1 (jmp, 1f); - } - else - { - OUT_AS1 (page, %4); - OUT_AS1 (jmp, %4); - } - OUT_AS2 (mov, w, %H2); - OUT_AS2 (addc, w, %H1); - if (GET_CODE (operands[0]) == EQ) - OUT_AS2 (csne, w, %H3); - else - OUT_AS2 (cse, w, %H3); - OUT_AS1 (page, %4); - OUT_AS1 (jmp, %4); - return AS1 (1:, ); - }") - -;; Unconditional jump -;; -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "page\\t%0\;jmp\\t%0" - [(set_attr "clobberw" "no")]) - -;; Indirect jump -;; -(define_insn "indirect_jump" - [(set (pc) (match_operand:HI 0 "nonimmediate_operand" "ro"))] - "" - "page\\t1f\;call\\t1f\;1:mov\\tw,%H0\;mov\\tcallh,w\;mov\\tw,%L0\;mov\\tcalll,w\;ret") - -;; -;; Function call instructions. -;; - -(define_expand "call" - [(call (match_operand 0 "" "") - (match_operand:HI 1 "" ""))] - "" - "") - -(define_insn "*call" - [(call (mem:HI (match_operand:HI 0 "general_operand" "i,roS")) - (match_operand:HI 1 "" ""))] - "" - "@ - page\\t%b0\;call\\t%b0 - push\\t%L0%<\;push\\t%H0%>\;page\\t__indcall\;call\\t__indcall") - -(define_expand "call_pop" - [(parallel [(call (match_operand 0 "" "") - (match_operand:HI 1 "" "")) - (set (reg:HI 6) - (plus:HI (reg:HI 6) - (match_operand:HI 3 "immediate_operand" "")))])] - "" - "") - -(define_insn "*call_pop" - [(call (mem:HI (match_operand:HI 0 "general_operand" "i,roS")) - (match_operand:HI 1 "" "")) - (set (reg:HI 6) - (plus:HI (reg:HI 6) - (match_operand:HI 2 "immediate_operand" "")))] - "" - "@ - page\\t%b0\;call\\t%b0 - push\\t%L0%<\;push\\t%H0%>\;page\\t__indcall\;call\\t__indcall") - -;; Undo any splitting of operands that lead to redundant movhi3 instructions. -;; -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (parallel [(call (mem:HI (match_dup 0)) - (match_operand:HI 2 "" "")) - (set (reg:HI 6) - (plus:HI (reg:HI 6) - (match_operand:HI 3 "immediate_operand" "")))])] - "" - [(parallel [(call (mem:HI (match_dup 1)) - (match_dup 2)) - (set (reg:HI 6) - (plus:HI (reg:HI 6) - (match_dup 3)))])] - "") - -(define_expand "call_value" - [(set (match_operand 0 "" "") - (call (match_operand 1 "" "") - (match_operand:HI 2 "" "")))] - "" - "") - -(define_insn "*call_value" - [(set (match_operand 0 "" "") - (call (mem:HI (match_operand:HI 1 "general_operand" "i,roS")) - (match_operand:HI 2 "" "")))] - "" - "@ - page\\t%b1\;call\\t%b1 - push\\t%L1%<\;push\\t%H1%>\;page\\t__indcall\;call\\t__indcall") - -(define_expand "call_value_pop" - [(parallel [(set (match_operand 0 "" "") - (call (match_operand 1 "" "") - (match_operand:HI 2 "" ""))) - (set (reg:HI 6) - (plus:HI (reg:HI 6) - (match_operand:HI 4 "immediate_operand" "")))])] - "" - "") - -(define_insn "*call_value_pop" - [(set (match_operand 0 "" "") - (call (mem:HI (match_operand:HI 1 "general_operand" "i,roS")) - (match_operand:HI 2 "" ""))) - (set (reg:HI 6) - (plus:HI (reg:HI 6) - (match_operand:HI 3 "immediate_operand" "")))] - "" - "@ - page\\t%b1\;call\\t%b1 - push\\t%L1%<\;push\\t%H1%>\;page\\t__indcall\;call\\t__indcall") - -;; Undo any splitting of operands that lead to redundant movhi3 instructions. -;; -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (parallel [(set (match_operand 2 "" "") - (call (mem:HI (match_dup 0)) - (match_operand:HI 3 "" ""))) - (set (reg:HI 6) - (plus:HI (reg:HI 6) - (match_operand:HI 4 "immediate_operand" "")))])] - "" - [(parallel [(set (match_dup 2) - (call (mem:HI (match_dup 1)) - (match_dup 3))) - (set (reg:HI 6) - (plus:HI (reg:HI 6) - (match_dup 4)))])] - "") - -;; Nop instruction. -;; -;; We don't really want nops to appear in our code so just insert an comment. -;; -(define_insn "nop" - [(const_int 0)] - "" - "; nop") - - -;; SEQ instruction -;; -(define_insn "seq" - [(set (match_operand:QI 0 "register_operand" "=r") - (eq:QI (cc0) (const_int 0)))] - "" - "* return ip2k_gen_sCOND (insn, EQ, operands[0]);") - -;; Tweak SEQ if we can adjust the output operand. Note that we have to do -;; this via a peephole because we need to ensure that any reloads have taken -;; place before we try to do this. If there's a reload in order to get our -;; actual result operand then this peephole won't match. -;; -(define_peephole - [(set (match_operand:QI 0 "register_operand" "") - (eq:QI (cc0) (const_int 0))) - (set (reg:QI 10) - (match_dup 0)) - (set (match_operand:QI 1 "nonimmediate_operand" "") - (reg:QI 10))] - "find_regno_note (insn, REG_DEAD, REGNO (operands[0]))" - "* return ip2k_gen_sCOND (insn, EQ, operands[1]);") - -;; Another peephole match handles the same merge as above but for cases where -;; we're emulating memory accesses via IP and an offset. -;; -(define_peephole - [(set (match_operand:QI 0 "register_operand" "") - (eq:QI (cc0) (const_int 0))) - (set (reg:QI 10) - (match_dup 0)) - (set (mem:QI (plus:HI (reg:HI 4) - (match_operand:QI 1 "const_int_operand" ""))) - (reg:QI 10))] - "(find_regno_note (insn, REG_DEAD, REGNO (operands[0])) - && (INTVAL (operands[1]) < 0x100))" - "*{ - if (INTVAL (operands[1]) == 1) - OUT_AS1 (inc, ipl); - else - { - OUT_AS2 (mov, w, %1); - OUT_AS2 (add, ipl, w); - } - ip2k_gen_sCOND (insn, EQ, - gen_rtx_MEM (QImode, gen_rtx_REG (HImode, REG_IP))); - if (find_regno_note (insn, REG_DEAD, REG_IP)) - { - if (INTVAL (operands[1]) == 1) - OUT_AS1 (dec, ipl); - else - { - OUT_AS2 (mov, w, %1); - OUT_AS2 (sub, ipl, w); - } - } - return \"\"; - }") - -;; SNE instruction -;; -(define_insn "sne" - [(set (match_operand:QI 0 "register_operand" "=r") - (ne:QI (cc0) (const_int 0)))] - "" - "* return ip2k_gen_sCOND (insn, NE, operands[0]);") - -;; Tweak SNE if we can adjust the output operand. Note that we have to do -;; this via a peephole because we need to ensure that any reloads have taken -;; place before we try to do this. If there's a reload in order to get our -;; actual result operand then this peephole won't match. -;; -(define_peephole - [(set (match_operand:QI 0 "register_operand" "") - (ne:QI (cc0) (const_int 0))) - (set (reg:QI 10) - (match_dup 0)) - (set (match_operand:QI 1 "nonimmediate_operand" "") - (reg:QI 10))] - "find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0]))" - "* return ip2k_gen_sCOND (insn, NE, operands[1]);") - -;; Another peephole match handles the same merge as above but for cases where -;; we're emulating memory accesses via IP and an offset. -;; -(define_peephole - [(set (match_operand:QI 0 "register_operand" "") - (ne:QI (cc0) (const_int 0))) - (set (reg:QI 10) - (match_dup 0)) - (set (mem:QI (plus:HI (reg:HI 4) - (match_operand:QI 1 "const_int_operand" ""))) - (reg:QI 10))] - "(find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0])) - && (INTVAL (operands[1]) < 0x100))" - "*{ - if (INTVAL (operands[1]) == 1) - OUT_AS1 (inc, ipl); - else - { - OUT_AS2 (mov, w, %1); - OUT_AS2 (add, ipl, w); - } - ip2k_gen_sCOND (insn, NE, - gen_rtx_MEM (QImode, gen_rtx_REG (HImode, REG_IP))); - if (find_regno_note (insn, REG_DEAD, REG_IP)) - { - if (INTVAL (operands[1]) == 1) - OUT_AS1 (dec, ipl); - else - { - OUT_AS2 (mov, w, %1); - OUT_AS2 (sub, ipl, w); - } - } - return \"\"; - }") - - - -;; Case Dispatch Table Support. -;; -;; Called with 5 arguments: -;; -;; 0. case index -;; 1. lower bound (const_int) -;; 2. range (const_int) -;; 3. label before dispatch table -;; 4. out-of-bounds label -;; -;; With the IP2k we actually really want to do a caseqi but that -;; doesn't exist so we cheat and make it look (to the core of gcc) -;; like we're going to do the SImode stuff but then truncate it -;; away when it's no longer looking :-) -;; -(define_expand "casesi" - [(set (match_dup 5) - (truncate:QI (match_operand:SI 0 "general_operand" "g"))) - (set (match_dup 5) - (minus:QI (match_dup 5) - (match_operand 1 "const_int_operand" "n"))) - (set (cc0) - (compare (match_dup 5) - (match_operand 2 "const_int_operand" "n"))) - (set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 4 "" "")) - (pc))) - (parallel [(set (pc) - (plus:HI (pc) - (zero_extend:HI (match_dup 5)))) - (use (label_ref (match_operand 3 "" ""))) - (use (match_dup 2))])] - "" - "{ - operands[5] = gen_reg_rtx (QImode); - }") - -;; There are TWO instructions per dispatch entry (page & jump), so we -;; multiply by two even though our RTL only indicates a simple addition. -;; Subsequent linker relaxation may well restore this back to what the -;; RTL says though! -;; -;; Note that we handle tables with 128 or more entries differently! -;; -(define_insn "*casedispatch" - [(set (pc) - (plus:HI (pc) (zero_extend:HI - (match_operand:QI 2 "nonimmediate_operand" "roR,roR")))) - (use (label_ref (match_operand 0 "" ""))) - (use (match_operand 1 "const_int_operand" "K, n"))] - "" - "@ - mov\\tw,%2\;add\\tw,wreg\;add\\tpcl,w - mov\\tw,%2\;push\\t%0%<\;push\\t#0%<\;add\\tw,wreg\;snc\;inc\\t1(SP)\;add\\t2(SP),w\;snc\;inc\\t1(SP)\;page\\t__indcall\;jmp\\t__indcall%>%>") - -;; Handle cleaning up the switch statement stuff. We can eliminate some -;; register moves in some cases. Note that our pattern is slightly different -;; to the casesi pattern because our minus has become a plus! -;; -;; Note that as of 07-FEB-2002 we must have this pattern as it is because -;; linker relaxation will not work any other way. -;; -(define_peephole - [(set (reg:QI 10) - (plus:QI (match_operand 5 "nonimmediate_operand" "rS,rS,rS,rS") - (match_operand 1 "const_int_operand" "M, n, M, n"))) - (set (match_operand:QI 0 "register_operand" "+r, r, r, r") - (reg:QI 10)) - (set (cc0) - (compare (match_dup 0) - (match_operand 2 "const_int_operand" "K, K, n, n"))) - (set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 4 "" "")) - (pc))) - (parallel [(set (pc) - (plus:HI (pc) - (zero_extend:HI (match_dup 0)))) - (use (label_ref (match_operand 3 "" ""))) - (use (match_dup 2))])] - "(INTVAL (operands[1]) != 0 - && find_regno_note (insn, REG_DEAD, REGNO (operands[0])))" - "*{ - switch (which_alternative) - { - case 0: - case 2: - OUT_AS2 (dec, w, %5); - break; - - case 1: - case 3: - OUT_AS2 (mov, w, %1); - OUT_AS2 (add, w, %5); - break; - default: - abort (); - } - - OUT_AS2 (cmp, w, %2); - OUT_AS1 (sc, ); - OUT_AS1 (page, %4); - OUT_AS1 (jmp, %4); - - switch (which_alternative) - { - case 0: - case 1: - OUT_AS2 (add, w, WREG); - OUT_AS2 (add, pcl, w); - return \"\"; - - case 2: - case 3: - OUT_AS1 (push, %0%<); - OUT_AS1 (push, #0%<); - OUT_AS2 (add, w, WREG); - OUT_AS1 (snc, ); - OUT_AS1 (inc, 1(SP)); - OUT_AS2 (add, 2(SP), w); - OUT_AS1 (snc, ); - OUT_AS1 (inc, 1(SP)); - OUT_AS1 (page, __indcall); - OUT_AS1 (jmp, __indcall%>%>); - return \"\"; - default: - abort (); - } - }") - -(define_peephole - [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "rS,rS") - (match_operand 1 "const_int_operand" "K, n"))) - (set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (parallel [(set (pc) - (plus:HI (pc) - (zero_extend:HI (match_dup 0)))) - (use (label_ref (match_operand 3 "" ""))) - (use (match_dup 1))])] - "" - "@ - mov\\tw,%0\;cmp\\tw,%1\;sc\;page\\t%2\;jmp\\t%2\;add\\tw,wreg\;add\\tpcl,w - mov\\tw,%0\;cmp\\tw,%1\;sc\;page\\t%2\;jmp\\t%2\;push\\t%0%<\;push\\t#0%<\;add\\tw,wreg\;snc\;inc\\t1(SP)\;add\\t2(SP),w\;snc\;inc\\t1(SP)\;page\\t__indcall\;jmp\\t__indcall%>%>") - -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "+roR") - (plus:HI (match_dup 0) - (const_int -1))) - (set (cc0) - (compare (match_dup 0) - (match_operand 3 "const_int_operand" "n"))) - (set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 1 "" "")) - (pc)))] - "((GET_CODE (operands[2]) == EQ || GET_CODE (operands[2]) == NE) - && ((INTVAL (operands[3]) == -1) || (INTVAL (operands[3]) == 65535)))" - "*{ - OUT_AS2 (mov, w, #255); - OUT_AS2 (add, %L0, w); - if ((GET_CODE (operands[0]) == REG) - && ((REGNO (operands[0]) == REG_DP) - || (REGNO (operands[0]) == REG_IP) - || (REGNO (operands[0]) == REG_SP))) - { - OUT_AS2 (add, %H0, w); - } - else - { - OUT_AS2 (addc, %H0, w); - } - if (GET_CODE (operands[2]) == EQ) - OUT_AS1 (sc, ); - else - OUT_AS1 (snc, ); - return AS1 (page, %1) CR_TAB - AS1 (jmp, %1); - }") - -(define_peephole - [(set (match_operand:QI 0 "nonimmediate_operand" "+rS") - (plus:QI (match_dup 0) - (const_int -1))) - (set (cc0) - (match_dup 0)) - (set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 1 "" "")) - (pc)))] - "(GET_CODE (operands[2]) == EQ || GET_CODE (operands[2]) == NE)" - "*{ - if (GET_CODE (operands[2]) == EQ) - OUT_AS1 (decsnz, %0); - else - OUT_AS1 (decsz, %0); - return AS1 (page, %1) CR_TAB - AS1 (jmp, %1); - }") - -;; Handle move and compare-with-zero operations - we can reuse w across -;; the two operations. -;; -(define_peephole - [(set (reg:QI 10) - (match_operand:QI 1 "nonimmediate_operand" "rS")) - (set (match_operand:QI 0 "nonimmediate_operand" "=rS") - (reg:QI 10)) - (set (cc0) - (match_operand:QI 2 "nonimmediate_operand" "rS")) - (set (pc) - (if_then_else (match_operator 3 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "((GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE) - && (rtx_equal_p (operands[0], operands[2]) - || rtx_equal_p (operands[1], operands[2])))" - "*{ - OUT_AS2 (mov, w, %1); - OUT_AS2 (mov, %0, w); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - }") - -;; Handle move and compare-with-zero operations - we can reuse w across -;; the two operations. -;; -(define_peephole - [(set (reg:QI 10) - (match_operand:QI 1 "nonimmediate_operand" "uS")) - (set (match_operand:QI 0 "nonimmediate_operand" "+uS") - (reg:QI 10)) - (set (cc0) - (match_operand:SI 2 "nonimmediate_operand" "uS")) - (set (pc) - (if_then_else (match_operator 3 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "((GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE) - && (rtx_equal_p (operands[0], - ip2k_get_high_half (ip2k_get_high_half (operands[2], - HImode), QImode)) - || rtx_equal_p (operands[1], - ip2k_get_high_half (ip2k_get_high_half (operands[2], - HImode), - QImode))))" - "*{ - OUT_AS2 (mov, w, %1); - OUT_AS2 (mov, %0, w); - OUT_AS2 (or, w, %B2); - OUT_AS2 (or, w, %C2); - OUT_AS2 (or, w, %D2); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - }") - -;; Handle move and compare-with-zero operations - we can reuse w across -;; the two operations. -;; -(define_peephole - [(set (reg:QI 10) - (match_operand:QI 1 "nonimmediate_operand" "uS")) - (set (match_operand:QI 0 "nonimmediate_operand" "+uS") - (reg:QI 10)) - (set (cc0) - (match_operand:HI 2 "nonimmediate_operand" "uS")) - (set (pc) - (if_then_else (match_operator 3 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "((GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE) - && (rtx_equal_p (operands[0], ip2k_get_high_half (operands[2], QImode)) - || rtx_equal_p (operands[1], ip2k_get_high_half (operands[2], QImode)) - || rtx_equal_p (operands[0], ip2k_get_low_half (operands[2], QImode)) - || rtx_equal_p (operands[1], ip2k_get_low_half (operands[2],QImode))))" - "*{ - OUT_AS2 (mov, w, %1); - OUT_AS2 (mov, %0, w); - if (rtx_equal_p (operands[0], ip2k_get_high_half (operands[2], QImode)) - || rtx_equal_p (operands[1], ip2k_get_high_half (operands[2], QImode))) - OUT_AS2 (or, w, %L2); - else - OUT_AS2 (or, w, %H2); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - }") - -;; Handle move and compare-with-zero operations - we can reuse w across -;; the two operations. -;; -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "+uo") - (match_operand:HI 1 "nonimmediate_operand" "uo")) - (set (cc0) - (match_dup 0)) - (set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "(GET_CODE (operands[2]) == EQ || GET_CODE (operands[2]) == NE)" - "*{ - OUT_AS2 (mov, w, %H1); - OUT_AS1 (push, %L1%<); - OUT_AS1 (pop, %L0%>); - OUT_AS2 (mov, %H0, w); - OUT_AS2 (or, w, %L0); - if (GET_CODE (operands[2]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %3) CR_TAB - AS1 (jmp, %3); - }") - -;; Handle move and compare-with-zero operations - we can reuse w across -;; the two operations. -;; -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "+uo") - (match_operand:HI 1 "nonimmediate_operand" "uo")) - (set (cc0) - (match_dup 1)) - (set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "(GET_CODE (operands[2]) == EQ || GET_CODE (operands[2]) == NE)" - "*{ - OUT_AS2 (mov, w, %H1); - OUT_AS1 (push, %L1%<); - OUT_AS1 (pop, %L0%>); - OUT_AS2 (mov, %H0, w); - OUT_AS2 (or, w, %L0); - if (GET_CODE (operands[2]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %3) CR_TAB - AS1 (jmp, %3); - }") - -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "+f,bqdo") - (mem:HI (reg:HI 4))) - (set (cc0) - (match_dup 0)) - (set (pc) - (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 2 "" "")) - (pc)))] - "(GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)" - "*{ - switch (which_alternative) - { - case 0: - OUT_AS1 (push, (IP)); - OUT_AS1 (inc, ipl); - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, ipl, w); - OUT_AS1 (pop, iph); - OUT_AS2 (or, w, iph); - if (GET_CODE (operands[1]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %2) CR_TAB - AS1 (jmp, %2); - - case 1: - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, %H0, w); - OUT_AS1 (inc, ipl); - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, %L0, w); - if (!find_regno_note (insn, REG_DEAD, REG_IP)) - OUT_AS1 (dec, ipl); - OUT_AS2 (or, w, %H0); - if (GET_CODE (operands[1]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %2) CR_TAB - AS1 (jmp, %2); - default: - abort (); - } - }") - -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "+f,bqdo") - (mem:HI (reg:HI 4))) - (set (cc0) - (mem:HI (reg:HI 4))) - (set (pc) - (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 2 "" "")) - (pc)))] - "(GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)" - "*{ - switch (which_alternative) - { - case 0: - OUT_AS1 (push, (IP)); - OUT_AS1 (inc, ipl); - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, ipl, w); - OUT_AS1 (pop, iph); - OUT_AS2 (or, w, iph); - if (GET_CODE (operands[1]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %2) CR_TAB - AS1 (jmp, %2); - - case 1: - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, %H0, w); - OUT_AS1 (inc, ipl); - OUT_AS2 (mov, w, (IP)); - OUT_AS2 (mov, %L0, w); - if (!find_regno_note (insn, REG_DEAD, REG_IP)) - OUT_AS1 (dec, ipl); - OUT_AS2 (or, w, %H0); - if (GET_CODE (operands[1]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %2) CR_TAB - AS1 (jmp, %2); - default: - abort (); - } - }") - -;; Handle move-twice and compare-with-zero operations - we can reuse w across -;; the two operations. -;; -(define_peephole - [(parallel [(set (match_operand:HI 0 "ip2k_gen_operand" "=uS") - (match_operand:HI 1 "ip2k_gen_operand" "uS")) - (set (match_operand:HI 2 "ip2k_gen_operand" "=uS") - (match_dup 1))]) - (set (cc0) - (match_dup 0)) - (set (pc) - (if_then_else (match_operator 3 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "(GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)" - "*{ - if ((REG_P (operands[0]) - && !(ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 2) - && ip2k_xexp_not_uses_reg_p (operands[2], - REGNO (operands[0]), 2))) - || (REG_P (operands[2]) - && !(ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 2) - && ip2k_xexp_not_uses_reg_p (operands[1], - REGNO (operands[2]), 2)))) - { - OUT_AS2 (mov, w, %L1); - OUT_AS1 (push, %H1%<); - OUT_AS1 (push, %H1%<); - OUT_AS1 (pop, %H0%>); - OUT_AS2 (mov, %L0, w); - OUT_AS1 (pop, %H2%>); - OUT_AS2 (mov, %L2, w); - OUT_AS2 (or, w, %H2); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - } - else - { - OUT_AS2 (mov, w, %L1); - OUT_AS2 (mov, %L0, w); - OUT_AS2 (mov, %L2, w); - OUT_AS2 (mov, w, %H1); - OUT_AS2 (mov, %H0, w); - OUT_AS2 (mov, %H2, w); - OUT_AS2 (or, w, %L2); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - } - }") - -(define_peephole - [(parallel [(set (match_operand:HI 0 "ip2k_gen_operand" "=uS") - (match_operand:HI 1 "ip2k_gen_operand" "uS")) - (set (match_operand:HI 2 "ip2k_gen_operand" "=uS") - (match_dup 1))]) - (set (cc0) - (match_dup 2)) - (set (pc) - (if_then_else (match_operator 3 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "(GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE)" - "*{ - if ((REG_P (operands[0]) - && !(ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 2) - && ip2k_xexp_not_uses_reg_p (operands[2], - REGNO (operands[0]), 2))) - || (REG_P (operands[2]) - && !(ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 2) - && ip2k_xexp_not_uses_reg_p (operands[1], - REGNO (operands[2]), 2)))) - { - OUT_AS2 (mov, w, %L1); - OUT_AS1 (push, %H1%<); - OUT_AS1 (push, %H1%<); - OUT_AS1 (pop, %H0%>); - OUT_AS2 (mov, %L0, w); - OUT_AS1 (pop, %H2%>); - OUT_AS2 (mov, %L2, w); - OUT_AS2 (or, w, %H2); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - } - else - { - OUT_AS2 (mov, w, %L1); - OUT_AS2 (mov, %L0, w); - OUT_AS2 (mov, %L2, w); - OUT_AS2 (mov, w, %H1); - OUT_AS2 (mov, %H0, w); - OUT_AS2 (mov, %H2, w); - OUT_AS2 (or, w, %L2); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - } - }") - -;; Handle move and compare-with-zero operations - we can reuse w across -;; the two operations. -;; -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "+uo") - (match_operand:HI 1 "nonimmediate_operand" "uo")) - (set (cc0) - (match_operand:SI 2 "nonimmediate_operand" "uo")) - (set (pc) - (if_then_else (match_operator 3 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "((GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE) - && (rtx_equal_p (operands[0], ip2k_get_high_half (operands[2], HImode)) - || rtx_equal_p (operands[1], - ip2k_get_high_half (operands[2], HImode))))" - "*{ - OUT_AS2 (mov, w, %H1); - OUT_AS1 (push, %L1%<); - OUT_AS1 (pop, %L0%>); - OUT_AS2 (mov, %H0, w); - OUT_AS2 (or, w, %B0); - OUT_AS2 (or, w, %C0); - OUT_AS2 (or, w, %D0); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - }") - -;; Handle bitwise-and and compare-with-zero operations on bytes. -;; -(define_peephole - [(set (reg:QI 10) - (match_operand:QI 2 "general_operand" " g")) - (set (reg:QI 10) - (and:QI (match_operand:QI 1 "general_operand" "g") - (reg:QI 10))) - (set (match_operand:QI 0 "register_operand" "+r") - (reg:QI 10)) - (set (cc0) - (match_dup 0)) - (set (pc) - (if_then_else (match_operator 3 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "(find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0])) - && (GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE))" - "*{ - OUT_AS2 (mov, w, %1); - OUT_AS2 (and, w, %2); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - }") - -;; Handle bitwise-xor and compare-with-zero operations on bytes. -;; -(define_peephole - [(set (match_operand:QI 0 "register_operand" "+r") - (xor:QI (match_operand:QI 1 "general_operand" "g") - (match_operand:QI 2 "general_operand" "g"))) - (set (cc0) - (match_dup 0)) - (set (pc) - (if_then_else (match_operator 3 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "(find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0])) - && (GET_CODE (operands[3]) == EQ || GET_CODE (operands[3]) == NE))" - "*{ - OUT_AS2 (mov, w, %1); - OUT_AS2 (xor, w, %2); - if (GET_CODE (operands[3]) == EQ) - OUT_AS1 (snz, ); - else - OUT_AS1 (sz, ); - return AS1 (page, %4) CR_TAB - AS1 (jmp, %4); - }") - -;; Cope with reload's vagaries. -;; - -(define_insn "*pushqi_reload_popqi" - [(set (match_operand:QI 0 "ip2k_nonsp_reg_operand" "=u, u") - (match_operand:QI 1 "ip2k_short_operand" "S, S")) - (set (reg:HI 12) - (match_operand:HI 2 "general_operand" "i,ro")) - (set (match_operand:QI 3 "ip2k_short_operand" "=S, S") - (match_dup 0))] - "" - "@ - push\\t%1%<\;loadh\\t%x2\;loadl\\t%x2\;pop\\t%3%> - push\\t%1%<\;mov\\tw,%L2\;push\\t%H2\;pop\\tdph\;mov\\tdpl,w\;pop\\t%3%>" -) - -(define_peephole2 - [(set (match_operand:QI 0 "ip2k_nonsp_reg_operand" "") - (match_operand:QI 1 "ip2k_short_operand" "")) - (set (reg:HI 12) - (match_operand:HI 2 "general_operand" "")) - (set (match_operand:QI 3 "ip2k_short_operand" "") - (match_dup 0))] - "(ip2k_reorg_split_himode - && peep2_reg_dead_p (3, operands[0]) - && ip2k_address_uses_reg_p (operands[1], REG_DP) - && ip2k_address_uses_reg_p (operands[3], REG_DP) - && !(ip2k_address_uses_reg_p (operands[2], REG_SP) - && (GET_CODE (XEXP (operands[2], 0)) == PLUS) - && (INTVAL (XEXP (XEXP (operands[2], 0), 1)) >= 126)) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (reg:HI 12) - (match_dup 2)) - (set (match_dup 3) - (match_dup 0))])] - "") - -(define_insn "*pushhi_reload_pophi" - [(set (match_operand:HI 0 "ip2k_nonsp_reg_operand" "=u, u") - (match_operand:HI 1 "ip2k_short_operand" "S, S")) - (set (reg:HI 12) - (match_operand:HI 2 "general_operand" "i,ro")) - (set (match_operand:HI 3 "ip2k_short_operand" "=S, S") - (match_dup 0))] - "" - "@ - push\\t%L1%<\;push\\t%H1%<\;loadh\\t%x2\;loadl\\t%x2\;pop\\t%H3%>\;pop\\t%L3%> - push\\t%L1%<\;push\\t%H1%<\;mov\\tw,%L2\;push\\t%H2\;pop\\tdph\;mov\\tdpl,w\;pop\\t%H3%>\;pop\\t%L3%>" -) - -(define_peephole2 - [(set (match_operand:HI 0 "ip2k_nonsp_reg_operand" "") - (match_operand:HI 1 "ip2k_short_operand" "")) - (set (reg:HI 12) - (match_operand:HI 2 "general_operand" "")) - (set (match_operand:HI 3 "ip2k_short_operand" "") - (match_dup 0))] - "(ip2k_reorg_split_simode - && peep2_reg_dead_p (3, operands[0]) - && ip2k_address_uses_reg_p (operands[1], REG_DP) - && ip2k_address_uses_reg_p (operands[3], REG_DP) - && !(ip2k_address_uses_reg_p (operands[2], REG_SP) - && (GET_CODE (XEXP (operands[2], 0)) == PLUS) - && (INTVAL (XEXP (XEXP (operands[2], 0), 1)) >= 125)) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (reg:HI 12) - (match_dup 2)) - (set (match_dup 3) - (match_dup 0))])] - "") - -(define_insn "*pushsi_reload_popsi" - [(set (match_operand:SI 0 "ip2k_nonsp_reg_operand" "=u, u") - (match_operand:SI 1 "ip2k_short_operand" "S, S")) - (set (reg:HI 12) - (match_operand:HI 2 "general_operand" "i,ro")) - (set (match_operand:SI 3 "ip2k_short_operand" "=S, S") - (match_dup 0))] - "" - "@ - push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%<\;loadh\\t%x2\;loadl\\t%x2\;pop\\t%A3%>\;pop\\t%B3%>\;pop\\t%C3%>\;pop\\t%D3%> - push\\t%D1%<\;push\\t%C1%<\;push\\t%B1%<\;push\\t%A1%<\;mov\\tw,%L2\;push\\t%H2\;pop\\tdph\;mov\\tdpl,w\;pop\\t%A3%>\;pop\\t%B3%>\;pop\\t%C3%>\;pop\\t%D3%>" -) - -(define_peephole2 - [(set (match_operand:SI 0 "ip2k_nonsp_reg_operand" "") - (match_operand:SI 1 "ip2k_short_operand" "")) - (set (reg:HI 12) - (match_operand:HI 2 "general_operand" "")) - (set (match_operand:SI 3 "ip2k_short_operand" "") - (match_dup 0))] - "(ip2k_reorg_split_dimode - && peep2_reg_dead_p (3, operands[0]) - && ip2k_address_uses_reg_p (operands[1], REG_DP) - && ip2k_address_uses_reg_p (operands[3], REG_DP) - && ! (ip2k_address_uses_reg_p (operands[2], REG_SP) - && (GET_CODE (XEXP (operands[2], 0)) == PLUS) - && (INTVAL (XEXP (XEXP (operands[2], 0), 1)) >= 123)))" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (reg:HI 12) - (match_dup 2)) - (set (match_dup 3) - (match_dup 0))])] - "") - -(define_insn "*pushdi_reload_popdi" - [(set (match_operand:DI 0 "ip2k_nonsp_reg_operand" "=u, u") - (match_operand:DI 1 "ip2k_short_operand" "S, S")) - (set (reg:HI 12) - (match_operand:HI 2 "general_operand" "i,ro")) - (set (match_operand:DI 3 "ip2k_short_operand" "=S, S") - (match_dup 0))] - "" - "@ - push\\t%S1%<\;push\\t%T1%<\;push\\t%U1%<\;push\\t%V1%<\;push\\t%W1%<\;push\\t%X1%<\;push\\t%Y1%<\;push\\t%Z1%<\;loadh\\t%x2\;loadl\\t%x2\;pop\\t%Z3%>\;pop\\t%Y3%>\;pop\\t%X3%>\;pop\\t%W3%>\;pop\\t%V3%>\;pop\\t%U3%>\;pop\\t%T3%>\;pop\\t%S3%> - push\\t%S1%<\;push\\t%T1%<\;push\\t%U1%<\;push\\t%V1%<\;push\\t%W1%<\;push\\t%X1%<\;push\\t%Y1%<\;push\\t%Z1%<\;mov\\tw,%L2\;push\\t%H2\;pop\\tdph\;mov\\tdpl,w\;pop\\t%Z3%>\;pop\\t%Y3%>\;pop\\t%X3%>\;pop\\t%W3%>\;pop\\t%V3%>\;pop\\t%U3%>\;pop\\t%T3%>\;pop\\t%S3%>" -) - -(define_peephole2 - [(set (match_operand:DI 0 "ip2k_nonsp_reg_operand" "") - (match_operand:DI 1 "ip2k_short_operand" "")) - (set (reg:HI 12) - (match_operand:HI 2 "general_operand" "")) - (set (match_operand:DI 3 "ip2k_short_operand" "") - (match_dup 0))] - "((ip2k_reorg_in_progress || ip2k_reorg_completed) - && peep2_reg_dead_p (3, operands[0]) - && ip2k_address_uses_reg_p (operands[1], REG_DP) - && ip2k_address_uses_reg_p (operands[3], REG_DP) - && ! (ip2k_address_uses_reg_p (operands[2], REG_SP) - && (GET_CODE (XEXP (operands[2], 0)) == PLUS) - && (INTVAL (XEXP (XEXP (operands[2], 0), 1)) >= 119)))" - [(parallel [(set (match_dup 0) - (match_dup 1)) - (set (reg:HI 12) - (match_dup 2)) - (set (match_dup 3) - (match_dup 0))])] - "") - -;; FIXME: Disabled because in lshiftrt:SI op1 must match op0 -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(match_operand 1 "general_operand" "") - (match_operand 2 "general_operand" "")])) - (set (match_operand 4 "nonimmediate_operand" "") - (match_dup 0))] - "0 && (peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 4) - (match_op_dup 3 [(match_dup 1) - (match_dup 2)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(zero_extend:HI - (match_operand 1 "general_operand" "")) - (match_operand 2 "general_operand" "")])) - (set (match_operand 4 "nonimmediate_operand" "") - (match_dup 0))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 4) - (match_op_dup 3 [(zero_extend:HI (match_dup 1)) - (match_dup 2)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(match_operand 1 "general_operand" "") - (zero_extend:HI - (match_operand 2 "general_operand" ""))])) - (set (match_operand 4 "nonimmediate_operand" "") - (match_dup 0))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 4) - (match_op_dup 3 [(match_dup 1) - (zero_extend:HI (match_dup 2))]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(zero_extend:SI - (match_operand 1 "general_operand" "")) - (match_operand 2 "general_operand" "")])) - (set (match_operand 4 "nonimmediate_operand" "") - (match_dup 0))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 4) - (match_op_dup 3 [(zero_extend:SI (match_dup 1)) - (match_dup 2)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(match_operand 1 "general_operand" "") - (zero_extend:SI - (match_operand 2 "general_operand" ""))])) - (set (match_operand 4 "nonimmediate_operand" "") - (match_dup 0))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 4) - (match_op_dup 3 [(match_dup 1) - (zero_extend:SI (match_dup 2))]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (match_operand 2 "nonimmediate_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(match_operand 4 "general_operand" "") - (match_dup 0)]))] - "0 && ((peep2_reg_dead_p (2, operands[0]) - || rtx_equal_p (operands[0], operands[2])) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 2) - (match_op_dup 3 [(match_dup 4) - (match_dup 1)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (match_operand 2 "nonimmediate_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(zero_extend:HI - (match_operand 4 "general_operand" "")) - (match_dup 0)]))] - "((peep2_reg_dead_p (2, operands[0]) - || rtx_equal_p (operands[0], operands[2])) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 2) - (match_op_dup 3 [(zero_extend:HI (match_dup 4)) - (match_dup 1)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (match_operand 2 "nonimmediate_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(zero_extend:SI - (match_operand 4 "general_operand" "")) - (match_dup 0)]))] - "((peep2_reg_dead_p (2, operands[0]) - || rtx_equal_p (operands[0], operands[2])) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 2) - (match_op_dup 3 [(zero_extend:SI (match_dup 4)) - (match_dup 1)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (match_operand 2 "nonimmediate_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(match_dup 0) - (match_operand 4 "general_operand" "")]))] - "0 && ((peep2_reg_dead_p (2, operands[0]) - || rtx_equal_p (operands[0], operands[2])) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 2) - (match_op_dup 3 [(match_dup 1) - (match_dup 4)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (match_operand 2 "nonimmediate_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(match_dup 0) - (zero_extend:HI - (match_operand 4 "general_operand" ""))]))] - "((peep2_reg_dead_p (2, operands[0]) - || rtx_equal_p (operands[0], operands[2])) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 2) - (match_op_dup 3 [(match_dup 1) - (zero_extend:HI (match_dup 4))]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (match_operand 2 "nonimmediate_operand" "") - (match_operator 3 "ip2k_binary_operator" - [(match_dup 0) - (zero_extend:SI - (match_operand 4 "general_operand" ""))]))] - "((peep2_reg_dead_p (2, operands[0]) - || rtx_equal_p (operands[0], operands[2])) - && ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 2) - (match_op_dup 3 [(match_dup 1) - (zero_extend:SI (match_dup 4))]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (cc0) - (match_operator 2 "ip2k_binary_operator" - [(match_operand 3 "general_operand" "") - (match_dup 0)]))] - "0 && (peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (cc0) - (match_op_dup 2 [(match_dup 3) - (match_dup 1)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (cc0) - (match_operator 2 "ip2k_binary_operator" - [(zero_extend:HI - (match_operand 3 "general_operand" "")) - (match_dup 0)]))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (cc0) - (match_op_dup 2 [(zero_extend:HI (match_dup 3)) - (match_dup 1)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (cc0) - (match_operator 2 "ip2k_binary_operator" - [(zero_extend:SI - (match_operand 3 "general_operand" "")) - (match_dup 0)]))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (cc0) - (match_op_dup 2 [(zero_extend:SI (match_dup 3)) - (match_dup 1)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (cc0) - (match_operator 2 "ip2k_binary_operator" - [(match_dup 0) - (match_operand 3 "general_operand" "")]))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (cc0) - (match_op_dup 2 [(match_dup 1) - (match_dup 3)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (cc0) - (match_operator 2 "ip2k_binary_operator" - [(match_dup 0) - (zero_extend:HI - (match_operand 3 "general_operand" ""))]))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (cc0) - (match_op_dup 2 [(match_dup 1) - (zero_extend:HI (match_dup 3))]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (cc0) - (match_operator 2 "ip2k_binary_operator" - [(match_dup 0) - (zero_extend:SI - (match_operand 3 "general_operand" ""))]))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (cc0) - (match_op_dup 2 [(match_dup 1) - (zero_extend:SI (match_dup 3))]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operator 3 "ip2k_unary_operator" - [(match_operand 1 "general_operand" "")])) - (set (match_operand 2 "nonimmediate_operand" "") - (match_dup 0))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 2) - (match_op_dup 3 [(match_dup 1)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (match_operand 2 "nonimmediate_operand" "") - (match_operator 3 "ip2k_unary_operator" [(match_dup 0)]))] - "(peep2_reg_dead_p (2, operands[0]) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))))" - [(set (match_dup 2) - (match_op_dup 3 [(match_dup 1)]))] - "") - -(define_peephole2 - [(set (match_operand 0 "ip2k_nonsp_reg_operand" "") - (match_operand 1 "nonimmediate_operand" "")) - (set (cc0) - (match_dup 0))] - "peep2_reg_dead_p (2, operands[0])" - [(set (cc0) - (match_dup 1))] - "") - -;; Look for places where we can shorten a compare operation. -;; -(define_peephole2 - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (const_int 0)) - (set (cc0) - (match_operand:HI 1 "nonimmediate_operand" "")) - (set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "(rtx_equal_p (ip2k_get_high_half (operands[1], QImode), operands[0]))" - [(set (match_dup 0) - (const_int 0)) - (set (cc0) - (match_dup 4)) - (set (pc) - (if_then_else (match_op_dup 2 - [(cc0) (const_int 0)]) - (label_ref (match_dup 3)) - (pc)))] - "{ - operands[4] = ip2k_get_low_half (operands[1], QImode); - }") - -;; Look for places where we can shorten a compare operation. -;; -(define_peephole2 - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (const_int 0)) - (set (cc0) - (compare (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand 2 "const_int_operand" ""))) - (set (pc) - (if_then_else (match_operator 3 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 4 "" "")) - (pc)))] - "(rtx_equal_p (ip2k_get_high_half (operands[1], QImode), operands[0]) - && (abs (INTVAL (operands[2]) <= 127)))" - [(set (match_dup 0) - (const_int 0)) - (set (cc0) - (compare (match_dup 5) - (match_dup 6))) - (set (pc) - (if_then_else (match_op_dup 3 - [(cc0) (const_int 0)]) - (label_ref (match_dup 4)) - (pc)))] - "{ - operands[5] = ip2k_get_low_half (operands[1], QImode); - operands[6] = gen_int_mode (INTVAL (operands[2]) & 0xff, QImode); - }") - -;; This is one of those cases where gcc just can't untangle our wishes. We -;; want to add some values but get two copies of the result. In this instance -;; however, the seconds copy can be made more cheaply by combining things. -;; -(define_peephole - [(set (match_operand:HI 0 "ip2k_nonsp_reg_operand" "+&u") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "rS") - (match_operand:HI 2 "general_operand" "rSi"))) - (set (match_operand:HI 3 "ip2k_gen_operand" "=&uS") - (match_dup 0))] - "(ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))) - && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))) - && (!REG_P (operands[3]) - || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))))))" - "mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\t%L3,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w\;mov\\t%H3,w") - -(define_peephole - [(set (match_operand:HI 0 "ip2k_short_operand" "+&S") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "rS") - (match_operand:HI 2 "general_operand" "rSi"))) - (set (match_operand:HI 3 "ip2k_nonsp_reg_operand" "=&u") - (match_dup 0))] - "(ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ! rtx_equal_p (operands[0], operands[1]) - && ! rtx_equal_p (operands[0], operands[2]))" - "mov\\tw,%L2\;add\\tw,%L1\;mov\\t%L0,w\;mov\\t%L3,w\;mov\\tw,%H2\;addc\\tw,%H1\;mov\\t%H0,w\;mov\\t%H3,w") - -;; Some splits zero the MSByte of a word that we then use for shifting. We -;; can therefore replace full shifts with zero-extended ones. These are -;; cheaper for us. -;; -(define_peephole2 - [(set (match_operand:QI 0 "register_operand" "") - (const_int 0)) - (set (match_operand:HI 1 "nonimmediate_operand" "") - (ashift:HI (match_operand:HI 2 "register_operand" "") - (match_operand 3 "const_int_operand" "")))] - "(rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0]) - && peep2_reg_dead_p (2, operands[0]))" - [(set (match_dup 1) - (ashift:HI (zero_extend:HI (match_dup 4)) - (match_dup 3)))] - "{ - operands[4] = ip2k_get_low_half (operands[2], QImode); - }") - -(define_peephole2 - [(set (match_operand:QI 0 "register_operand" "") - (const_int 0)) - (set (match_operand:HI 1 "nonimmediate_operand" "") - (ashift:HI (match_operand:HI 2 "register_operand" "") - (match_operand 3 "const_int_operand" "")))] - "(rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0]))" - [(set (match_dup 0) - (const_int 0)) - (set (match_dup 1) - (ashift:HI (zero_extend:HI (match_dup 4)) - (match_dup 3)))] - "{ - operands[4] = ip2k_get_low_half (operands[2], QImode); - }") - -;; Some splits zero the MSByte of a word that we then use for multiplying. We -;; can therefore replace the full multiplies with zero-extended ones. -;; These are cheaper for us. -;; -(define_peephole2 - [(set (match_operand:QI 0 "register_operand" "") - (const_int 0)) - (set (match_operand:HI 1 "nonimmediate_operand" "") - (mult:HI (match_operand:HI 2 "register_operand" "") - (zero_extend:HI - (match_operand:QI 3 "const_int_operand" ""))))] - "(rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0]) - && (peep2_reg_dead_p (2, operands[0]) - || rtx_equal_p (operands[1], operands[2])))" - [(set (match_dup 1) - (mult:HI (zero_extend:HI (match_dup 4)) - (zero_extend:HI (match_dup 3))))] - "{ - operands[4] = ip2k_get_low_half (operands[2], QImode); - }") - -(define_peephole2 - [(set (match_operand:QI 0 "register_operand" "") - (const_int 0)) - (set (match_operand:HI 1 "nonimmediate_operand" "") - (mult:HI (match_operand:HI 2 "register_operand" "") - (zero_extend:HI - (match_operand:QI 3 "const_int_operand" ""))))] - "(rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0]))" - [(set (match_dup 0) - (const_int 0)) - (set (match_dup 1) - (mult:HI (zero_extend:HI (match_dup 4)) - (zero_extend:HI (match_dup 3))))] - "{ - operands[4] = ip2k_get_low_half (operands[2], QImode); - }") - -;; Merge in a redundant move before a zero-extended multiply. -;; -(define_peephole2 - [(set (match_operand:QI 0 "register_operand" "") - (match_operand:QI 1 "general_operand" "")) - (set (match_operand:HI 2 "nonimmediate_operand" "") - (mult:HI (zero_extend:HI (match_dup 0)) - (zero_extend:HI - (match_operand:QI 3 "const_int_operand" ""))))] - "(peep2_reg_dead_p (2, operands[0]) - || rtx_equal_p (ip2k_get_high_half (operands[2], QImode), operands[0]) - || rtx_equal_p (ip2k_get_low_half (operands[2], QImode), operands[0]))" - [(set (match_dup 2) - (mult:HI (zero_extend:HI (match_dup 1)) - (zero_extend:HI (match_dup 3))))] - "") - -;; Pick up redundant clears followed by adds - these can just become moves. -;; -(define_peephole2 - [(set (match_operand 0 "register_operand" "") - (const_int 0)) - (set (match_operand 2 "nonimmediate_operand" "") - (plus (match_dup 0) - (match_operand 1 "general_operand" "")))] - "peep2_reg_dead_p (2, operands[0])" - [(set (match_dup 2) - (match_dup 1))] - "") - -(define_peephole2 - [(set (match_operand 0 "register_operand" "") - (const_int 0)) - (set (match_dup 0) - (plus (match_dup 0) - (match_operand 1 "general_operand" "")))] - "" - [(set (match_dup 0) - (match_dup 1))] - "") - -;; Clear up an add followed by a push of the result. The fact that this -;; isn't picked up consistently within the combiner suggests a bug somewhere. -;; -(define_peephole2 - [(set (match_operand:HI 0 "register_operand" "") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:HI 2 "general_operand" ""))) - (set (mem:HI (post_dec:HI (reg:HI 6))) - (match_dup 0))] - "peep2_reg_dead_p (2, operands[0])" - [(set (mem:HI (post_dec:HI (reg:HI 6))) - (plus:HI (match_dup 1) - (match_dup 2)))] - "") - -;; Tidy up stack slot addressing where we've eliminated some registers. -;; This looks like something strange going on though as gcc-2.97 didn't -;; exhibit this behaviour, whereas gcc-3.0.4 does. -;; -(define_peephole2 - [(set (match_operand:HI 0 "register_operand" "") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand 2 "const_int_operand" ""))) - (set (mem:HI (post_dec:HI (reg:HI 6))) - (plus:HI (match_dup 0) - (match_operand 3 "const_int_operand" "")))] - "peep2_reg_dead_p (2, operands[0])" - [(set (mem:HI (post_dec:HI (reg:HI 6))) - (plus:HI (match_dup 1) - (match_dup 4)))] - "{ - operands[4] = gen_int_mode (INTVAL (operands[2]) + INTVAL (operands[3]), - HImode); - }") - -;; Match duplicate loads of a symbol ref. This isn't something that we want to -;; do at the peephole2 stage because more often than not we'll make one of the -;; two loads redundant after we run peephole2. We catch the remaining cases -;; here though -;; -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "+uS") - (match_operand 1 "ip2k_symbol_ref_operand" "i")) - (set (match_operand:HI 2 "nonimmediate_operand" "=uS") - (match_dup 1))] - "((!REG_P (operands[0]) || (REGNO (operands[0]) != REG_DP)) - && (!REG_P (operands[2]) || (REGNO (operands[2]) != REG_DP)))" - "mov\\tw,%L1\;mov\\t%L0,w\;mov\\t%L2,w\;mov\\tw,%H1\;mov\\t%H0,w\;mov\\t%H2,w") - -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "+&uS") - (match_operand 1 "ip2k_symbol_ref_operand" "i")) - (set (match_operand:HI 2 "nonimmediate_operand" "=&uS") - (match_dup 0))] - "" - "*{ - if ((REG_P (operands[0]) - && !(ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), 2) - && ip2k_xexp_not_uses_reg_p (operands[2], - REGNO (operands[0]), 2))) - || (REG_P (operands[2]) - && !(ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[2]), 2) - && ip2k_xexp_not_uses_reg_p (operands[1], - REGNO (operands[2]), 2)))) - { - return AS2 (mov, w, %L1) CR_TAB - AS1 (push, %H1%<) CR_TAB - AS1 (push, %H1%<) CR_TAB - AS1 (pop, %H0%>) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS1 (pop, %H2%>) CR_TAB - AS2 (mov, %L2, w); - } - else - { - return AS2 (mov, w, %L1) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (mov, %L2, w) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (mov, %H2, w); - } - }") - -;; Handle the common array indexing pattern. -;; This is of the form A = X + (Y * C). -;; We use splits earlier in this file to get our interesting cases into the -;; same form (i.e. zero-extended multiply and add). -;; -(define_insn "*mulacchi" - [(set (match_operand:HI 3 "nonimmediate_operand" "=rS") - (plus:HI (mult:HI (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "rS")) - (zero_extend:HI - (match_operand:QI 2 "const_int_operand" "n"))) - (match_operand:HI 0 "general_operand" "rSi")))] - "" - "*{ - if (immediate_operand (operands[0], HImode) - && REG_P (operands[3]) - && (REGNO (operands[3]) == REG_DP) - && (INTVAL (operands[2]) == 2)) - return AS2 (mov, w, %1) CR_TAB - AS1 (loadl, %x0) CR_TAB - AS1 (loadh, %x0) CR_TAB - AS2 (add, dpl, w) CR_TAB - AS2 (add, dpl, w); - else - return AS2 (mov, w, %1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS2 (add, w, %L0) CR_TAB - AS2 (mov, %L3, w) CR_TAB - AS2 (mov, w, %H0) CR_TAB - AS2 (addc, w, MULH) CR_TAB - AS2 (mov, %H3, w); - }") - -(define_peephole2 - [(set (match_operand:HI 0 "register_operand" "") - (mult:HI (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "")) - (zero_extend:HI - (match_operand 2 "const_int_operand" "")))) - (set (match_operand:HI 3 "nonimmediate_operand" "") - (plus:HI (match_dup 0) - (match_operand:HI 4 "general_operand" "")))] - "(((! REG_P (operands[3])) - || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))))) - && peep2_reg_dead_p (2, operands[0]))" - [(set (match_dup 3) - (plus:HI (mult:HI (zero_extend:HI - (match_dup 1)) - (zero_extend:HI - (match_dup 2))) - (match_dup 4)))] - "") - -(define_insn "*mulhi_and_accumulate" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rS") - (mult:HI (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "rS")) - (zero_extend:HI - (match_operand:QI 2 "const_int_operand" "n")))) - (set (match_operand:HI 3 "nonimmediate_operand" "=rS") - (plus:HI (match_dup 0) - (match_operand:HI 4 "general_operand" "%rSi")))] - "((! REG_P (operands[3])) - || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3])))))" - "*{ - return AS2 (mov, w, %1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (add, w, %L4) CR_TAB - AS2 (mov, %L3, w) CR_TAB - AS2 (mov, w, %H4) CR_TAB - AS2 (addc, w, MULH) CR_TAB - AS2 (mov, %H3, w) CR_TAB - AS2 (mov, w, MULH) CR_TAB - AS2 (mov, %H0, w); - }") - -(define_peephole2 - [(set (match_operand:HI 0 "nonimmediate_operand" "") - (mult:HI (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "")) - (zero_extend:HI - (match_operand 2 "const_int_operand" "")))) - (set (match_operand:HI 3 "nonimmediate_operand" "") - (plus:HI (match_dup 0) - (match_operand:HI 4 "general_operand" "")))] - "((! REG_P (operands[3])) - || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3])))))" - [(parallel [(set (match_dup 0) - (mult:HI (zero_extend:HI - (match_dup 1)) - (zero_extend:HI - (match_dup 2)))) - (set (match_dup 3) - (plus:HI (match_dup 0) - (match_dup 4)))])] - "") - -;; Handle the common array indexing pattern. -;; This is of the form A = X + (Y * C). -;; We use splits earlier in this file to get our interesting cases into the -;; same form (i.e. multiply and add). -;; -(define_peephole - [(set (match_operand:HI 0 "register_operand" "=r") - (mult:HI (match_operand:HI 1 "nonimmediate_operand" "rS") - (zero_extend:HI - (match_operand:QI 2 "const_int_operand" "n")))) - (set (match_operand:HI 3 "nonimmediate_operand" "=rS") - (plus:HI (match_dup 0) - (match_operand:HI 4 "general_operand" "%rSi")))] - "((!REG_P (operands[3]) - || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))))) - && find_regno_note (insn, REG_DEAD, REGNO (operands[0])))" - "*{ - if (immediate_operand (operands[4], HImode) - && REG_P (operands[3]) - && (REGNO (operands[3]) == REG_DP) - && (INTVAL (operands[2]) == 2) - && ip2k_xexp_not_uses_reg_p (operands[1], REG_DP, - GET_MODE_SIZE (HImode))) - return AS2 (clrb, STATUS, 0) CR_TAB - AS1 (loadl, %x4) CR_TAB - AS1 (loadh, %x4) CR_TAB - AS2 (rl, w, %L1) CR_TAB - AS2 (add, dpl, w) CR_TAB - AS2 (rl, w, %H1) CR_TAB - AS2 (add, dph, w); - else if (!REG_P (operands[3]) - || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))))) - return AS2 (mov, w, %L1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS2 (add, w, %L4) CR_TAB - AS2 (mov, %L3, w) CR_TAB - AS2 (mov, w, %H4) CR_TAB - AS2 (addc, w, MULH) CR_TAB - AS2 (mov, %H3, w) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS2 (add, %H3, w); - else - return AS2 (mov, w, %L1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS2 (add, w, %L4) CR_TAB - AS1 (push, wreg%<) CR_TAB - AS2 (mov, w, %H4) CR_TAB - AS2 (addc, w, MULH) CR_TAB - AS1 (push, wreg%<) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS1 (pop, %H3%>) CR_TAB - AS1 (pop, %L3%>) CR_TAB - AS2 (add, %H3, w); - }") - -;; Handle the more complex variant of the preceding multiply and accumulate -;; variant of the preceding multiply-and-add operation. This one would -;; otherwise fail to match because the result never goes dead. -;; -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "=rS") - (mult:HI (match_operand:HI 1 "nonimmediate_operand" "rS") - (zero_extend:HI - (match_operand:QI 2 "const_int_operand" "n")))) - (set (match_dup 0) - (plus:HI (match_dup 0) - (match_operand:HI 3 "general_operand" "%rSi")))] - "(!REG_P (operands[0]) - || (ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0]))) - && ip2k_xexp_not_uses_reg_p (operands[3], REGNO (operands[0]), - GET_MODE_SIZE (GET_MODE (operands[0])))))" - "*{ - if (immediate_operand (operands[3], HImode) - && REG_P (operands[0]) - && (REGNO (operands[0]) == REG_DP) - && (INTVAL (operands[2]) == 2)) - return AS2 (clrb, STATUS, 0) CR_TAB - AS1 (loadl, %x3) CR_TAB - AS1 (loadh, %x3) CR_TAB - AS2 (rl, w, %L1) CR_TAB - AS2 (add, dpl, w) CR_TAB - AS2 (rl, w, %H1) CR_TAB - AS2 (add, dph, w); - else - return AS2 (mov, w, %L1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS2 (add, w, %L3) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (mov, w, %H3) CR_TAB - AS2 (addc, w, MULH) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS2 (add, %H0, w); - }") - -;; Handle the a complex variant of the preceding multiply and add -;; operations where the intermediate result is also required. -;; -(define_peephole - [(set (match_operand:HI 0 "nonimmediate_operand" "=rS") - (mult:HI (match_operand:HI 1 "nonimmediate_operand" "rS") - (zero_extend:HI - (match_operand:QI 2 "const_int_operand" "n")))) - (set (match_operand:HI 3 "nonimmediate_operand" "=rS") - (plus:HI (match_dup 0) - (match_operand:HI 4 "general_operand" "%rSi")))] - "((!REG_P (operands[3]) - || (ip2k_xexp_not_uses_reg_p (operands[4], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[0], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[1], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))) - && ip2k_xexp_not_uses_reg_p (operands[2], REGNO (operands[3]), - GET_MODE_SIZE (GET_MODE (operands[3]))))) - && (INTVAL (operands[2]) != 2))" - "* return AS2 (mov, w, %H4) CR_TAB - AS2 (mov, %H3, w) CR_TAB - AS2 (mov, w, %L1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS2 (mov, %L0, w) CR_TAB - AS2 (add, w, %L4) CR_TAB - AS2 (mov, %L3, w) CR_TAB - AS2 (mov, w, MULH) CR_TAB - AS2 (mov, %H0, w) CR_TAB - AS2 (addc, %H3, w) CR_TAB - AS2 (mov, w, %H1) CR_TAB - AS2 (mulu, w, %2) CR_TAB - AS2 (add, %H3, w) CR_TAB - AS2 (add, %H0, w);") - -;; Byte swapping! -;; -(define_peephole - [(set (reg:QI 10) - (match_operand:QI 1 "nonimmediate_operand" "rS")) - (set (match_operand:QI 0 "register_operand" "=r") - (reg:QI 10)) - (set (reg:QI 10) - (match_operand:QI 2 "nonimmediate_operand" "rS")) - (set (match_dup 1) - (reg:QI 10)) - (set (reg:QI 10) - (match_dup 0)) - (set (match_dup 2) - (reg:QI 10))] - "find_regno_note (PREV_INSN (insn), REG_DEAD, REGNO (operands[0]))" - "push\\t%1%<\;push\\t%2%<\;pop\\t%1%>\;pop\\t%2%>") - - |