aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/ip2k/ip2k.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/ip2k/ip2k.md')
-rw-r--r--gcc/config/ip2k/ip2k.md6902
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%>")
-
-