X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=gcc%2Fconfig%2Fmn10200%2Fmn10200.md;fp=gcc%2Fconfig%2Fmn10200%2Fmn10200.md;h=0000000000000000000000000000000000000000;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=ea658fdb31c8f1d3c73d5928c3c1a71fbaa5ffd9;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/mn10200/mn10200.md b/gcc/config/mn10200/mn10200.md deleted file mode 100644 index ea658fdb..00000000 --- a/gcc/config/mn10200/mn10200.md +++ /dev/null @@ -1,2050 +0,0 @@ -;; GCC machine description for Matsushita MN10200 -;; Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. -;; Contributed by Jeff Law (law@cygnus.com). - -;; 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. - -;; The original PO technology requires these to be ordered by speed, -;; so that assigner will pick the fastest. - -;; See file "rtl.def" for documentation on define_insn, match_*, et. al. - -;; Condition code settings. -;; none - insn does not affect cc -;; none_0hit - insn does not affect cc but it does modify operand 0 -;; This attribute is used to keep track of when operand 0 changes. -;; See the description of NOTICE_UPDATE_CC for more info. -;; set_znv - sets z,n,v to usable values; c is unknown. -;; set_zn - sets z,n to usable values; v,c is unknown. -;; compare - compare instruction -;; clobber - value of cc is unknown -(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber" - (const_string "clobber")) - -;; ---------------------------------------------------------------------- -;; MOVE INSTRUCTIONS -;; ---------------------------------------------------------------------- -;; -;; Some general notes on move instructions. -;; -;; The hardware can't encode nop moves involving data registers, so -;; we catch them and emit a nop instead. -;; -;; Loads/stores to/from address registers must be 16bit aligned, -;; thus we avoid them for QImode. -;; -;; Stores from address registers always store 24bits, so avoid -;; stores from address registers in HImode, SImode, and SFmode. -;; -;; As a result of the various problems using address registers in -;; QImode, HImode, SImode, and SFmode, we discourage their use via -;; '*' in their constraints. They're still allowed, but they're never -;; the preferred class for insns with those modes. - -;; movqi - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand0, QImode) - && !register_operand (operand1, QImode)) - operands[1] = copy_to_mode_reg (QImode, operand1); -}") - -;; We avoid memory operations involving address registers because we -;; can't be sure they'll be suitably aligned. -;; -;; We also discourage holding QImode values in address registers. -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a") - (match_operand:QI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a"))] - "register_operand (operands[0], QImode) - || register_operand (operands[1], QImode)" - "@ - nop - sub %0,%0 - sub %0,%0 - mov %S1,%0 - movbu %1,%0 - movb %1,%0 - mov %1,%0 - mov %1,%0 - mov %1,%0" - [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - -;; movhi - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand1, HImode) - && !register_operand (operand0, HImode)) - operands[1] = copy_to_mode_reg (HImode, operand1); -}") - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a,*a") - (match_operand:HI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a,m"))] - "register_operand (operands[0], HImode) - || register_operand (operands[1], HImode)" - "@ - nop - sub %0,%0 - sub %0,%0 - mov %s1,%0 - mov %1,%0 - mov %1,%0 - mov %1,%0 - mov %1,%0 - mov %1,%0 - mov %A1,%0" - [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - -;; movpsi and helpers - -(define_expand "movpsi" - [(set (match_operand:PSI 0 "general_operand" "") - (match_operand:PSI 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand1, PSImode) - && !register_operand (operand0, PSImode)) - operands[1] = copy_to_mode_reg (PSImode, operand1); -}") - - -;; Constant and indexed addresses are not valid addresses for PSImode, -;; therefore they won't be matched by the general movpsi pattern below. -;; ??? We had patterns to handle indexed addresses, but they kept making -;; us run out of regs, so they were eliminated. - -(define_insn "" - [(set (match_operand:PSI 0 "register_operand" "=a") - (match_operand:PSI 1 "constant_memory_operand" ""))] - "" - "mov %A1,%0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:PSI 0 "constant_memory_operand" "=X") - (match_operand:PSI 1 "register_operand" "a"))] - "" - "mov %1,%A0" - [(set_attr "cc" "none_0hit")]) - -;; We want to prefer address registers here because 24bit moves to/from -;; memory are shorter and faster when done via address registers. -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,a?d,?da,a,m,?d,m") - (match_operand:PSI 1 "general_operand" "0,I,?dai,m,a,m,?d"))] - "register_operand (operands[0], PSImode) - || register_operand (operands[1], PSImode)" - "@ - nop - sub %0,%0 - mov %1,%0 - mov %A1,%0 - mov %1,%A0 - movx %A1,%0 - movx %1,%A0" - [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand1, SImode) - && !register_operand (operand0, SImode)) - operands[1] = copy_to_mode_reg (SImode, operand1); -}") - -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a") - (match_operand:SI 1 "general_operand" "0,I,I,d,dim,*a,d,*a,i"))] - "register_operand (operands[0], SImode) - || register_operand (operands[1], SImode)" - "* -{ - switch (which_alternative) - { - case 0: - return \"nop\"; - case 1: - case 2: - return \"sub %H0,%H0\;sub %L0,%L0\"; - case 3: - case 5: - case 6: - case 7: - return \"mov %H1,%H0\;mov %L1,%L0\"; - - /* The next two cases try to optimize cases where one half - of the constant is all zeros, or when the two halves are - the same. */ - case 4: - case 8: - if (REG_P (operands[0]) - && GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) & 0xffff0000) == 0) - output_asm_insn (\"sub %H0,%H0\", operands); - else - output_asm_insn (\"mov %h1,%H0\", operands); - - if (GET_CODE (operands[1]) == CONST_INT - && ((INTVAL (operands[1]) & 0xffff) - == ((INTVAL (operands[1]) >> 16) & 0xffff))) - output_asm_insn (\"mov %H0,%L0\", operands); - else if (GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) & 0xffff) == 0) - output_asm_insn (\"sub %L0,%L0\", operands); - else - output_asm_insn (\"mov %o1,%L0\", operands); - return \"\"; - default: - abort(); - } -}" - [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - -(define_expand "movsf" - [(set (match_operand:SF 0 "general_operand" "") - (match_operand:SF 1 "general_operand" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand (operand1, SFmode) - && !register_operand (operand0, SFmode)) - operands[1] = copy_to_mode_reg (SFmode, operand1); -}") - -(define_insn "" - [(set (match_operand:SF 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a") - (match_operand:SF 1 "general_operand" "0,G,G,d,dim,*a,d,*a,i"))] - "register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode)" - "* -{ - switch (which_alternative) - { - case 0: - return \"nop\"; - - case 1: - case 2: - return \"sub %H0,%H0\;sub %L0,%L0\"; - - default: - { - long val = 0; - REAL_VALUE_TYPE rv; - - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_SINGLE (rv, val); - } - - if (GET_CODE (operands[1]) == CONST_INT) - val = INTVAL (operands[1]); - - if ((GET_CODE (operands[1]) == CONST_INT - || GET_CODE (operands[1]) == CONST_DOUBLE) - && (val & 0xffff0000) == 0) - output_asm_insn (\"sub %H0,%H0\", operands); - else - output_asm_insn (\"mov %h1,%H0\", operands); - - if (GET_CODE (operands[1]) == CONST_INT - && ((INTVAL (operands[1]) & 0xffff) - == ((INTVAL (operands[1]) >> 16) & 0xffff))) - output_asm_insn (\"mov %H0,%L0\", operands); - else if ((GET_CODE (operands[1]) == CONST_INT - || GET_CODE (operands[1]) == CONST_DOUBLE) - && (val & 0x0000ffff) == 0) - output_asm_insn (\"sub %L0,%L0\", operands); - else - output_asm_insn (\"mov %o1,%L0\", operands); - return \"\"; - } - } -}" - [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) - - -;; ---------------------------------------------------------------------- -;; TEST INSTRUCTIONS -;; ---------------------------------------------------------------------- - -;; Go ahead and define tsthi and tstpsi so we can eliminate redundant tst insns -;; when we start trying to optimize this port. -(define_insn "tsthi" - [(set (cc0) (match_operand:HI 0 "nonimmediate_operand" "da"))] - "" - "* return output_tst (operands[0], insn);" - [(set_attr "cc" "set_znv")]) - -(define_insn "tstpsi" - [(set (cc0) (match_operand:PSI 0 "nonimmediate_operand" "da"))] - "" - "* return output_tst (operands[0], insn);" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (cc0) (zero_extend:HI (match_operand:QI 0 "memory_operand" "d")))] - "" - "* return output_tst (operands[0], insn);" - [(set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (cc0) (zero_extend:PSI (match_operand:QI 0 "memory_operand" "d")))] - "" - "* return output_tst (operands[0], insn);" - [(set_attr "cc" "set_znv")]) - -(define_insn "cmphi" - [(set (cc0) - (compare:HI (match_operand:HI 0 "nonimmediate_operand" "da") - (match_operand:HI 1 "general_operand" "dai")))] - "" - "cmp %1,%0" - [(set_attr "cc" "compare")]) - -(define_insn "cmppsi" - [(set (cc0) - (compare:PSI (match_operand:PSI 0 "nonimmediate_operand" "da") - (match_operand:PSI 1 "general_operand" "dai")))] - "" - "cmp %1,%0" - [(set_attr "cc" "compare")]) - -;; ---------------------------------------------------------------------- -;; ADD INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "addhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (plus:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "dai")))] - "" - "add %2,%0" - [(set_attr "cc" "set_zn")]) - -(define_insn "addpsi3" - [(set (match_operand:PSI 0 "general_operand" "=da") - (plus:PSI (match_operand:PSI 1 "general_operand" "%0") - (match_operand:PSI 2 "general_operand" "dai")))] - "" - "add %2,%0" - [(set_attr "cc" "set_zn")]) - -;; We want to avoid using explicit registers; reload won't tell us -;; if it has to spill them and may generate incorrect code in such -;; cases. -;; -;; So we call out to a library routine to perform 32bit add or -;; subtract operations. -;; -;; operand2 must be nonmemory_operand so that we will accept CONST_INTs -;; during initial code generation. -(define_expand "addsi3" - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - " -{ - /* If adding a CONST_INT, we are better off generating code ourselves. - - During RTL generation we call out to library routines. - - After RTL generation we can not call the library routines as - they need to push arguments via virtual_outgoing_args_rtx which - has already been instantiated. So, after RTL generation we just - FAIL and open code the operation. */ - if (GET_CODE (operands[2]) == CONST_INT) - { - if (!rtx_equal_p (operands[0], operands[1])) - emit_move_insn (operands[0], operands[1]); - emit_insn (gen_addsi3_const (operands[0], operands[0], operands[2])); - DONE; - } - else if (rtx_equal_function_value_matters) - { - rtx ret, insns; - - start_sequence (); - ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__addsi3\"), - NULL_RTX, 1, SImode, 2, operands[1], - SImode, operands[2], SImode); - insns = get_insns (); - end_sequence (); - emit_libcall_block (insns, operands[0], ret, - gen_rtx_PLUS (SImode, operands[1], operands[2])); - DONE; - } - else - FAIL; -}") - -(define_insn "addsi3_const" - [(set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "const_int_operand" "i"))) - (clobber (match_scratch:SI 3 "=&d"))] - "" - "* -{ - unsigned long value = INTVAL (operands[2]); - - /* If only the high bits are set in the constant, then we only - need a single add operation. It might be better to catch this - at RTL expansion time. */ - if ((value & 0xffff) == 0) - return \"add %h2,%H0\"; - - value >>= 16; - value &= 0xffff; - - if (value == 0) - return \"sub %3,%3\;add %o2,%L0\;addc %3,%H0\"; - else - return \"mov %h2,%3\;add %o2,%L0\;addc %3,%H0\"; -}" - [(set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; SUBTRACT INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "subhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (minus:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "dai")))] - "" - "sub %2,%0" - [(set_attr "cc" "set_zn")]) - -(define_insn "subpsi3" - [(set (match_operand:PSI 0 "general_operand" "=da") - (minus:PSI (match_operand:PSI 1 "general_operand" "0") - (match_operand:PSI 2 "general_operand" "dai")))] - "" - "sub %2,%0" - [(set_attr "cc" "set_zn")]) - -(define_expand "subsi3" - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" "")))] - "" - " -{ - /* During RTL generation we call out to library routines. - - After RTL generation we can not call the library routines as - they need to push arguments via virtual_outgoing_args_rtx which - has already been instantiated. So, after RTL generation we just - FAIL and open code the operation. */ - if (rtx_equal_function_value_matters) - { - rtx ret, insns; - - start_sequence (); - ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__subsi3\"), - NULL_RTX, 1, SImode, 2, operands[1], - SImode, operands[2], SImode); - insns = get_insns (); - end_sequence (); - emit_libcall_block (insns, operands[0], ret, - gen_rtx_MINUS (SImode, operands[1], operands[2])); - DONE; - } - else - FAIL; -}") - -;; There isn't a negate instruction, so we fake it. -;; -;; We used to expand this into patterns, but a single pattern -;; actually generates better overall code. -;; -;; We could do HImode negations with a "not;add" sequence, but -;; generally it's generated slightly worse code. -;; -;; The second alternative is not strictly necesasry, but helps -;; when the register allocators start running short of registers. -(define_insn "neghi2" - [(set (match_operand:HI 0 "general_operand" "=&d,d") - (neg:HI (match_operand:HI 1 "general_operand" "d,0")))] - "" - "@ - sub %0,%0\;sub %1,%0 - not %0\;add 1,%0" - [(set_attr "cc" "set_zn")]) - -;; The not/and sequence won't work here. It's not clear if we'll -;; ever need to provide an alternate sequence since this should -;; be used much less frequently than neghi2. -(define_insn "negpsi2" - [(set (match_operand:PSI 0 "general_operand" "=&d") - (neg:PSI (match_operand:PSI 1 "general_operand" "d")))] - "" - "sub %0,%0\;sub %1,%0" - [(set_attr "cc" "set_zn")]) - -;; Using a magic libcall that accepts its arguments in any -;; data register pair has proven to be the most efficient -;; and most compact way to represent negsi2. -(define_insn "negsi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (neg:SI (match_operand:SI 1 "register_operand" "0")))] - "" - "jsr ___negsi2_%0" - [(set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; MULTIPLY INSTRUCTIONS -;; ---------------------------------------------------------------------- -;; -;; The mn10200 has HIxHI->SI widening multiply, but we get _severe_ -;; code density regressions if we enable such a pattern. - -(define_insn "mulhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (mult:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "d")))] - "" - "mul %2,%0" - [(set_attr "cc" "set_zn")]) - -(define_insn "udivmodhi4" - [(set (match_operand:HI 0 "general_operand" "=d") - (udiv:HI (match_operand:HI 1 "general_operand" "0") - (match_operand:HI 2 "general_operand" "d"))) - (set (match_operand:HI 3 "general_operand" "=&d") - (umod:HI (match_dup 1) (match_dup 2)))] - "" - "* -{ - if (zero_dreg) - output_asm_insn (\"mov %0,mdr\", &zero_dreg); - else - output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands); - - if (find_reg_note (insn, REG_UNUSED, operands[3])) - return \"divu %2,%0\"; - else - return \"divu %2,%0\;mov mdr,%3\"; -}" - [(set_attr "cc" "set_zn")]) - - -;; ---------------------------------------------------------------------- -;; AND INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "andhi3" - [(set (match_operand:HI 0 "general_operand" "=d,d") - (and:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "M,di")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff) - return \"extxbu %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fff) - return \"add %0,%0\;lsr %0\"; - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffe) - return \"lsr %0\;add %0,%0\"; - return \"and %2,%0\"; -}" - [(set_attr "cc" "none_0hit,set_znv")]) - -;; This expander + pattern exist only to allow trampolines to be aligned -;; in the stack. -(define_expand "andpsi3" - [(set (match_operand:PSI 0 "general_operand" "") - (and:PSI (match_operand:PSI 1 "general_operand" "") - (match_operand:PSI 2 "const_int_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT - || (INTVAL (operands[2]) & 0xff0000) != 0xff0000) - FAIL; -}") - -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d") - (and:PSI (match_operand:PSI 1 "general_operand" "%0") - (match_operand:PSI 2 "const_int_operand" "i")))] - "GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) & 0xff0000) == 0xff0000" - "and %2,%0" - [(set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; OR INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "iorhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (ior:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "di")))] - "" - "or %2,%0" - [(set_attr "cc" "set_znv")]) - -;; ---------------------------------------------------------------------- -;; XOR INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "xorhi3" - [(set (match_operand:HI 0 "general_operand" "=d") - (xor:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "di")))] - "" - "xor %2,%0" - [(set_attr "cc" "set_znv")]) - -;; ---------------------------------------------------------------------- -;; NOT INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "general_operand" "=d") - (not:HI (match_operand:HI 1 "general_operand" "0")))] - "" - "not %0" - [(set_attr "cc" "set_znv")]) - - -;; ----------------------------------------------------------------- -;; BIT INSTRUCTIONS -;; ----------------------------------------------------------------- - -;; These clears a constant set of bits in memory or in a register. -;; We must support register destinations to make reload happy. -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "+R,d") - (subreg:QI - (and:HI (subreg:HI (match_dup 0) 0) - (match_operand 1 "const_int_operand" "")) 0)) - (clobber (match_scratch:HI 2 "=&d,X"))] - "" - "@ - mov %N1,%2\;bclr %2,%0 - and %1,%0" - [(set_attr "cc" "clobber")]) - -;; This clears a variable set of bits in memory or in a register. -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "+R,d") - (subreg:QI - (and:HI (subreg:HI (match_dup 0) 0) - (not:HI (match_operand:HI 1 "general_operand" "d,d"))) 0)) - (clobber (match_scratch:HI 2 "=X,&d"))] - "" - "@ - bclr %1,%0 - mov %1,%2\;not %2\;and %2,%0" - [(set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "+R,d") - (subreg:QI - (and:HI (not:HI (match_operand:HI 1 "general_operand" "d,d")) - (subreg:HI (match_dup 0) 0)) 0)) - (clobber (match_scratch:HI 2 "=X,&d"))] - "" - "@ - bclr %1,%0 - mov %1,%2\;not %2\;and %2,%0" - [(set_attr "cc" "clobber")]) - -;; These set bits in memory. -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "+R,d") - (subreg:QI - (ior:HI (subreg:HI (match_dup 0) 0) - (match_operand:HI 1 "general_operand" "d,d")) 0))] - "" - "@ - bset %1,%0 - or %1,%0" - [(set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:QI 0 "general_operand" "+R,d") - (subreg:QI - (ior:HI (match_operand:HI 1 "general_operand" "d,d") - (subreg:HI (match_dup 0) 0)) 0))] - "" - "@ - bset %1,%0 - or %1,%0" - [(set_attr "cc" "clobber")]) - -;; Not any shorter/faster than using cmp, but it might save a -;; register if the result of the AND isn't ever used. - -(define_insn "" - [(set (cc0) - (zero_extract:HI (match_operand:HI 0 "general_operand" "d") - (match_operand 1 "const_int_operand" "") - (match_operand 2 "const_int_operand" "")))] - "" - "* -{ - int len = INTVAL (operands[1]); - int bit = INTVAL (operands[2]); - int mask = 0; - rtx xoperands[2]; - - while (len > 0) - { - mask |= (1 << bit); - bit++; - len--; - } - - xoperands[0] = operands[0]; - xoperands[1] = GEN_INT (mask); - output_asm_insn (\"btst %1,%0\", xoperands); - return \"\"; -}" - [(set_attr "cc" "clobber")]) - -(define_insn "" - [(set (cc0) (and:HI (match_operand:HI 0 "general_operand" "d") - (match_operand:HI 1 "const_int_operand" "i")))] - "" - "btst %1,%0" - [(set_attr "cc" "clobber")]) - - -;; ---------------------------------------------------------------------- -;; JUMP INSTRUCTIONS -;; ---------------------------------------------------------------------- - -;; Conditional jump instructions - -(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 "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 "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)))] - "" - "") - -(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_insn "" - [(set (pc) - (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 - && (GET_CODE (operands[1]) == GT - || GET_CODE (operands[1]) == GE - || GET_CODE (operands[1]) == LE - || GET_CODE (operands[1]) == LT)) - return 0; - - if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode) - return \"b%b1x %0\"; - else - return \"b%b1 %0\"; -}" - [(set_attr "cc" "none")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 - && (GET_CODE (operands[1]) == GT - || GET_CODE (operands[1]) == GE - || GET_CODE (operands[1]) == LE - || GET_CODE (operands[1]) == LT)) - return 0; - - if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode) - return \"b%B1x %0\"; - else - return \"b%B1 %0\"; -}" - [(set_attr "cc" "none")]) - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "jmp %l0" - [(set_attr "cc" "none")]) - -(define_insn "indirect_jump" - [(set (pc) (match_operand:PSI 0 "register_operand" "a"))] - "" - "jmp (%0)" - [(set_attr "cc" "none")]) - -(define_insn "tablejump" - [(set (pc) (match_operand:PSI 0 "register_operand" "a")) - (use (label_ref (match_operand 1 "" "")))] - "" - "jmp (%0)" - [(set_attr "cc" "none")]) - -;; Call subroutine with no return value. - -(define_expand "call" - [(call (match_operand:QI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - if (! call_address_operand (XEXP (operands[0], 0), VOIDmode)) - XEXP (operands[0], 0) = force_reg (PSImode, XEXP (operands[0], 0)); - emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1])); - DONE; -}") - -(define_insn "call_internal" - [(call (mem:QI (match_operand:PSI 0 "call_address_operand" "aS")) - (match_operand:HI 1 "general_operand" "g"))] - "" - "jsr %C0" - [(set_attr "cc" "clobber")]) - -;; Call subroutine, returning value in operand 0 -;; (which must be a hard register). - -(define_expand "call_value" - [(set (match_operand 0 "" "") - (call (match_operand:QI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - if (! call_address_operand (XEXP (operands[1], 0), VOIDmode)) - XEXP (operands[1], 0) = force_reg (PSImode, XEXP (operands[1], 0)); - emit_call_insn (gen_call_value_internal (operands[0], - XEXP (operands[1], 0), - operands[2])); - DONE; -}") - -(define_insn "call_value_internal" - [(set (match_operand 0 "" "=da") - (call (mem:QI (match_operand:PSI 1 "call_address_operand" "aS")) - (match_operand:HI 2 "general_operand" "g")))] - "" - "jsr %C1" - [(set_attr "cc" "clobber")]) - -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - emit_call_insn (gen_call (operands[0], const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - DONE; -}") - -(define_insn "nop" - [(const_int 0)] - "" - "nop" - [(set_attr "cc" "none")]) - -;; ---------------------------------------------------------------------- -;; EXTEND INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=d,d,d") - (zero_extend:HI - (match_operand:QI 1 "general_operand" "0,di,m")))] - "" - "@ - extxbu %0 - mov %1,%0\;extxbu %0 - movbu %1,%0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "zero_extendqipsi2" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (zero_extend:PSI - (match_operand:QI 1 "general_operand" "0,di,m")))] - "" - "@ - extxbu %0 - mov %1,%0\;extxbu %0 - movbu %1,%0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=d,d,d") - (zero_extend:SI - (match_operand:QI 1 "general_operand" "0,di,m")))] - "" - "@ - extxbu %L0\;sub %H0,%H0 - mov %1,%L0\;extxbu %L0\;sub %H0,%H0 - movbu %1,%L0\;sub %H0,%H0" - [(set_attr "cc" "clobber")]) - -(define_insn "zero_extendhipsi2" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (zero_extend:PSI - (match_operand:HI 1 "general_operand" "0,di,m")))] - "" - "@ - extxu %0 - mov %1,%0\;extxu %0 - mov %1,%0\;extxu %0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=d,d") - (zero_extend:SI - (match_operand:HI 1 "general_operand" "0,dim")))] - "" - "@ - sub %H0,%H0 - mov %1,%L0\;sub %H0,%H0" - [(set_attr "cc" "clobber,clobber")]) - -;; The last alternative is necessary because the second operand might -;; have been the frame pointer. The frame pointer would get replaced -;; by (plus (stack_pointer) (const_int)). -;; -;; Reload would think that it only needed a PSImode register in -;; push_reload and at the start of allocate_reload_regs. However, -;; at the end of allocate_reload_reg it would realize that the -;; reload register must also be valid for SImode, and if it was -;; not valid reload would abort. -(define_insn "zero_extendpsisi2" - [(set (match_operand:SI 0 "register_operand" "=d,?d,?*d,?*d") - (zero_extend:SI (match_operand:PSI 1 "extendpsi_operand" - "m,?0,?*dai,Q")))] - "" - "@ - mov %L1,%L0\;movbu %H1,%H0 - jsr ___zero_extendpsisi2_%0 - mov %1,%L0\;jsr ___zero_extendpsisi2_%0 - mov a3,%L0\;add %Z1,%L0\;jsr ___zero_extendpsisi2_%0" - [(set_attr "cc" "clobber")]) - -;;- sign extension instructions - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=d,d,d") - (sign_extend:HI - (match_operand:QI 1 "general_operand" "0,di,m")))] - "" - "* -{ - if (which_alternative == 0) - return \"extxb %0\"; - else if (which_alternative == 1) - return \"mov %1,%0\;extxb %0\"; - else if (GET_CODE (XEXP (operands[1], 0)) == REG) - return \"movbu %1,%0\;extxb %0\"; - else - return \"movb %1,%0\"; -}" - [(set_attr "cc" "none_0hit")]) - -(define_insn "extendqipsi2" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (sign_extend:PSI - (match_operand:QI 1 "general_operand" "0,di,m")))] - "" - "* -{ - if (which_alternative == 0) - return \"extxb %0\"; - else if (which_alternative == 1) - return \"mov %1,%0\;extxb %0\"; - else if (GET_CODE (XEXP (operands[1], 0)) == REG) - return \"movbu %1,%0\;extxb %0\"; - else - return \"movb %1,%0\"; -}" - [(set_attr "cc" "none_0hit")]) - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=d,d,d") - (sign_extend:SI - (match_operand:QI 1 "general_operand" "0,di,m")))] - "" - "* -{ - if (which_alternative == 0) - return \"extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\"; - else if (which_alternative == 1) - return \"mov %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\"; - else if (GET_CODE (XEXP (operands[1], 0)) == REG) - return \"movbu %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\"; - else - return \"movb %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\"; -}" - [(set_attr "cc" "clobber")]) - -(define_insn "extendhipsi2" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (sign_extend:PSI - (match_operand:HI 1 "general_operand" "0,di,m")))] - "" - "@ - extx %0 - mov %1,%0\;extx %0 - mov %1,%0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=d,d,d") - (sign_extend:SI - (match_operand:HI 1 "general_operand" "0,di,m")))] - "" - "@ - mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0 - mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0 - mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0" - [(set_attr "cc" "clobber")]) - -;; The last alternative is necessary because the second operand might -;; have been the frame pointer. The frame pointer would get replaced -;; by (plus (stack_pointer) (const_int)). -;; -;; Reload would think that it only needed a PSImode register in -;; push_reload and at the start of allocate_reload_regs. However, -;; at the end of allocate_reload_reg it would realize that the -;; reload register must also be valid for SImode, and if it was -;; not valid reload would abort. -(define_insn "extendpsisi2" - [(set (match_operand:SI 0 "general_operand" "=d,?d,?*d,?*d") - (sign_extend:SI (match_operand:PSI 1 "extendpsi_operand" - "m,?0,?*dai,Q")))] - "" - "@ - mov %L1,%L0\;movb %H1,%H0 - jsr ___sign_extendpsisi2_%0 - mov %1,%L0\;jsr ___sign_extendpsisi2_%0 - mov a3,%L0\;add %Z1,%L0\;jsr ___sign_extendpsisi2_%0" - [(set_attr "cc" "clobber")]) - -(define_insn "truncsipsi2" - [(set (match_operand:PSI 0 "general_operand" "=a,?d,?*d,da") - (truncate:PSI (match_operand:SI 1 "psimode_truncation_operand" "m,?m,?*d,i")))] - "" - "@ - mov %1,%0 - movx %A1,%0 - jsr ___truncsipsi2_%1_%0 - mov %1,%0" - [(set_attr "cc" "clobber")]) - - -;; Combine should be simplifying this stuff, but isn't. -;; -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d,d,d") - (sign_extend:SI - (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m"))))] - "" - "@ - extxbu %L0\;sub %H0,%H0 - mov %1,%L0\;extxbu %L0\;sub %H0,%H0 - movbu %1,%L0\;sub %H0,%H0" - [(set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (truncate:PSI - (sign_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))] - "" - "* -{ - if (which_alternative == 0) - return \"extxb %0\"; - else if (which_alternative == 1) - return \"mov %1,%0\;extxb %0\"; - else if (GET_CODE (XEXP (operands[1], 0)) == REG) - return \"movbu %1,%0\;extxb %0\"; - else - return \"movb %1,%0\"; -}" - [(set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (truncate:PSI - (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))] - "" - "@ - extx %0 - mov %1,%0\;extx %0 - mov %1,%0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (truncate:PSI - (sign_extend:SI - (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))))] - "" - "@ - extxbu %0 - mov %1,%0\;extxbu %0 - movbu %1,%0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (truncate:PSI - (zero_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))] - "" - "@ - extxu %0 - mov %1,%0\;extxu %0 - mov %1,%0\;extxu %0" - [(set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (truncate:PSI - (zero_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))] - "" - "@ - extxbu %0 - mov %1,%0\;extxbu %0 - movbu %1,%0" - [(set_attr "cc" "none_0hit")]) - -;; ---------------------------------------------------------------------- -;; SHIFTS -;; ---------------------------------------------------------------------- - -;; If the shift count is small, we expand it into several single bit -;; shift insns. Otherwise we expand into a generic shift insn which -;; handles larger shift counts, shift by variable amounts, etc. -(define_expand "ashlhi3" - [(set (match_operand:HI 0 "general_operand" "") - (ashift:HI (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - /* This is an experiment to see if exposing more of the underlying - operations results in better code. */ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) <= 4) - { - int count = INTVAL (operands[2]); - emit_move_insn (operands[0], operands[1]); - while (count > 0) - { - emit_insn (gen_rtx_SET (HImode, operands[0], - gen_rtx_ASHIFT (HImode, - operands[0], GEN_INT (1)))); - count--; - } - DONE; - } - else - { - expand_a_shift (HImode, ASHIFT, operands); - DONE; - } -}") - -;; ASHIFT one bit. -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d") - (ashift:HI (match_operand:HI 1 "general_operand" "0") - (const_int 1)))] - "" - "add %0,%0" - [(set_attr "cc" "set_zn")]) - -(define_expand "lshrhi3" - [(set (match_operand:HI 0 "general_operand" "") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - /* This is an experiment to see if exposing more of the underlying - operations results in better code. */ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) <= 4) - { - int count = INTVAL (operands[2]); - emit_move_insn (operands[0], operands[1]); - while (count > 0) - { - emit_insn (gen_rtx_SET (HImode, operands[0], - gen_rtx_LSHIFTRT (HImode, - operands[0], - GEN_INT (1)))); - count--; - } - DONE; - } - else - { - expand_a_shift (HImode, LSHIFTRT, operands); - DONE; - } -}") - -;; LSHIFTRT one bit. -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") - (const_int 1)))] - "" - "lsr %0" - [(set_attr "cc" "set_znv")]) - -(define_expand "ashrhi3" - [(set (match_operand:HI 0 "general_operand" "") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - /* This is an experiment to see if exposing more of the underlying - operations results in better code. */ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) <= 4) - { - int count = INTVAL (operands[2]); - emit_move_insn (operands[0], operands[1]); - while (count > 0) - { - emit_insn (gen_rtx_SET (HImode, operands[0], - gen_rtx_ASHIFTRT (HImode, operands[0], - GEN_INT (1)))); - count--; - } - DONE; - } - else - { - expand_a_shift (HImode, ASHIFTRT, operands); - DONE; - } -}") - -;; ASHIFTRT one bit. -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") - (const_int 1)))] - "" - "asr %0" - [(set_attr "cc" "set_znv")]) - -;; And the general HImode shift pattern. Handles both shift by constants -;; and shift by variable counts. -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=d,d") - (match_operator:HI 3 "nshift_operator" - [ (match_operand:HI 1 "general_operand" "0,0") - (match_operand:HI 2 "general_operand" "KL,dan")])) - (clobber (match_scratch:HI 4 "=X,&d"))] - "" - "* return emit_a_shift (insn, operands);" - [(set_attr "cc" "clobber")]) - -;; We expect only ASHIFT with constant shift counts to be common for -;; PSImode, so we optimize just that case. For all other cases we -;; extend the value to SImode and perform the shift in SImode. -(define_expand "ashlpsi3" - [(set (match_operand:PSI 0 "general_operand" "") - (ashift:PSI (match_operand:PSI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - /* This is an experiment to see if exposing more of the underlying - operations results in better code. */ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) <= 7) - { - int count = INTVAL (operands[2]); - emit_move_insn (operands[0], operands[1]); - while (count > 0) - { - emit_insn (gen_rtx_SET (PSImode, operands[0], - gen_rtx_ASHIFT (PSImode, - operands[0], GEN_INT (1)))); - count--; - } - DONE; - } - else - { - expand_a_shift (PSImode, ASHIFT, operands); - DONE; - } -}") - -;; ASHIFT one bit. -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d") - (ashift:PSI (match_operand:PSI 1 "general_operand" "0") - (const_int 1)))] - "" - "add %0,%0" - [(set_attr "cc" "set_zn")]) - -(define_expand "lshrpsi3" - [(set (match_operand:PSI 0 "general_operand" "") - (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - rtx reg = gen_reg_rtx (SImode); - - emit_insn (gen_zero_extendpsisi2 (reg, operands[1])); - reg = expand_binop (SImode, lshr_optab, reg, - operands[2], reg, 1, OPTAB_WIDEN); - emit_insn (gen_truncsipsi2 (operands[0], reg)); - DONE; -}") - -(define_expand "ashrpsi3" - [(set (match_operand:PSI 0 "general_operand" "") - (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - rtx reg = gen_reg_rtx (SImode); - - emit_insn (gen_extendpsisi2 (reg, operands[1])); - reg = expand_binop (SImode, ashr_optab, reg, - operands[2], reg, 0, OPTAB_WIDEN); - emit_insn (gen_truncsipsi2 (operands[0], reg)); - DONE; -}") - -(define_expand "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ashift:SI (match_operand:SI 1 "nonmemory_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - /* For small shifts, just emit a series of single bit shifts inline. - - For other constant shift counts smaller than a word or non-constant - shift counts we call out to a library call during RTL generation time; - after RTL generation time we allow optabs.c to open code the operation. - See comments in addsi3/subsi3 expanders. - - Otherwise we allow optabs.c to open code the operation. */ - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) <= 3)) - { - int count = INTVAL (operands[2]); - emit_move_insn (operands[0], operands[1]); - while (count > 0) - { - emit_insn (gen_rtx_SET (SImode, operands[0], - gen_rtx_ASHIFT (SImode, - operands[0], GEN_INT (1)))); - count--; - } - DONE; - } - else if (rtx_equal_function_value_matters - && (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 15)) - { - rtx ret, insns; - - start_sequence (); - ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__ashlsi3\"), - NULL_RTX, 1, SImode, 2, operands[1], - SImode, operands[2], HImode); - insns = get_insns (); - end_sequence (); - emit_libcall_block (insns, operands[0], ret, - gen_rtx_ASHIFT (SImode, operands[1], operands[2])); - DONE; - } - else - FAIL; -}") - -;; ASHIFT one bit. -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (ashift:SI (match_operand:SI 1 "general_operand" "0") - (const_int 1)))] - "" - "add %L0,%L0\;addc %H0,%H0" - [(set_attr "cc" "clobber")]) - -(define_expand "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - /* For small shifts, just emit a series of single bit shifts inline. - - For other constant shift counts smaller than a word or non-constant - shift counts we call out to a library call during RTL generation time; - after RTL generation time we allow optabs.c to open code the operation. - See comments in addsi3/subsi3 expanders. - - Otherwise we allow optabs.c to open code the operation. */ - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) <= 2)) - { - int count = INTVAL (operands[2]); - emit_move_insn (operands[0], operands[1]); - while (count > 0) - { - emit_insn (gen_rtx_SET (SImode, operands[0], - gen_rtx_LSHIFTRT (SImode, operands[0], - GEN_INT (1)))); - count--; - } - DONE; - } - else if (rtx_equal_function_value_matters - && (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 15)) - { - rtx ret, insns; - - start_sequence (); - ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__lshrsi3\"), - NULL_RTX, 1, SImode, 2, operands[1], - SImode, operands[2], HImode); - insns = get_insns (); - end_sequence (); - emit_libcall_block (insns, operands[0], ret, - gen_rtx_LSHIFTRT (SImode, operands[1], operands[2])); - DONE; - } - else - FAIL; -}") - -;; LSHIFTRT one bit. -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") - (const_int 1)))] - "" - "lsr %H0\;ror %L0" - [(set_attr "cc" "clobber")]) - -(define_expand "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "" - " -{ - /* For small shifts, just emit a series of single bit shifts inline. - - For other constant shift counts smaller than a word or non-constant - shift counts we call out to a library call during RTL generation time; - after RTL generation time we allow optabs.c to open code the operation. - See comments in addsi3/subsi3 expanders. - - Otherwise we allow optabs.c to open code the operation. */ - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) <= 2)) - { - int count = INTVAL (operands[2]); - emit_move_insn (operands[0], operands[1]); - while (count > 0) - { - emit_insn (gen_rtx_SET (SImode, operands[0], - gen_rtx_ASHIFTRT (SImode, operands[0], - GEN_INT (1)))); - count--; - } - DONE; - } - else if (rtx_equal_function_value_matters - && (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 15)) - { - rtx ret, insns; - - start_sequence (); - ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__ashrsi3\"), - NULL_RTX, 1, SImode, 2, operands[1], - SImode, operands[2], HImode); - insns = get_insns (); - end_sequence (); - emit_libcall_block (insns, operands[0], ret, - gen_rtx_ASHIFTRT (SImode, operands[1], operands[2])); - DONE; - } - else - FAIL; -}") - -;; ASHIFTRT one bit. -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=d") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") - (const_int 1)))] - "" - "asr %H0\;ror %L0" - [(set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; FP INSTRUCTIONS -;; ---------------------------------------------------------------------- -;; -;; The mn102 series does not have floating point instructions, but since -;; FP values are held in integer regs, we can clear the high bit easily -;; which gives us an efficient inline floating point absolute value. -;; -;; Similarly for negation of a FP value. -;; - -(define_expand "abssf2" - [(set (match_operand:SF 0 "register_operand" "") - (abs:SF (match_operand:SF 1 "register_operand" "")))] - "" - " -{ - rtx target, result, insns; - - start_sequence (); - target = operand_subword (operands[0], 1, 1, SFmode); - result = expand_binop (HImode, and_optab, - operand_subword_force (operands[1], 1, SFmode), - GEN_INT(0x7fff), target, 0, OPTAB_WIDEN); - - if (result == 0) - abort (); - - if (result != target) - emit_move_insn (result, target); - - emit_move_insn (operand_subword (operands[0], 0, 1, SFmode), - operand_subword_force (operands[1], 0, SFmode)); - - insns = get_insns (); - end_sequence (); - - emit_no_conflict_block (insns, operands[0], operands[1], 0, 0); - DONE; -}") - -(define_expand "negsf2" - [(set (match_operand:SF 0 "register_operand" "") - (neg:SF (match_operand:SF 1 "register_operand" "")))] - "" - " -{ - rtx target, result, insns; - - start_sequence (); - target = operand_subword (operands[0], 1, 1, SFmode); - result = expand_binop (HImode, xor_optab, - operand_subword_force (operands[1], 1, SFmode), - GEN_INT(-0x8000), target, 0, OPTAB_WIDEN); - - if (result == 0) - abort (); - - if (result != target) - emit_move_insn (result, target); - - emit_move_insn (operand_subword (operands[0], 0, 1, SFmode), - operand_subword_force (operands[1], 0, SFmode)); - - insns = get_insns (); - end_sequence (); - - emit_no_conflict_block (insns, operands[0], operands[1], 0, 0); - DONE; -}") - -;; ---------------------------------------------------------------------- -;; PROLOGUE/EPILOGUE -;; ---------------------------------------------------------------------- -(define_expand "prologue" - [(const_int 0)] - "" - "expand_prologue (); DONE;") - -(define_insn "outline_prologue_call" - [(const_int 1)] - "" - "jsr ___prologue" - [(set_attr "cc" "clobber")]) - -(define_expand "epilogue" - [(return)] - "" - " -{ - expand_epilogue (); - DONE; -}") - -(define_insn "outline_epilogue_call_a0" - [(const_int 2)] - "" - "jsr ___epilogue_a0" - [(set_attr "cc" "clobber")]) - -(define_insn "outline_epilogue_call_d0" - [(const_int 3)] - "" - "jsr ___epilogue_d0" - [(set_attr "cc" "clobber")]) - -(define_insn "outline_epilogue_jump" - [(const_int 4) - (return)] - "" - "jmp ___epilogue_noreturn" - [(set_attr "cc" "clobber")]) - -(define_insn "return" - [(return)] - "reload_completed && total_frame_size () == 0 - && !current_function_needs_context" - "* -{ - rtx next = next_active_insn (insn); - - if (next - && GET_CODE (next) == JUMP_INSN - && GET_CODE (PATTERN (next)) == RETURN) - return \"\"; - return \"rts\"; -}" - [(set_attr "cc" "clobber")]) - -(define_insn "return_internal" - [(const_int 0) - (return)] - "" - "rts" - [(set_attr "cc" "clobber")]) - -;; These are special combiner patterns to improve array/pointer accesses. -;; -;; A typical sequence involves extending an integer/char, shifting it left -;; a few times, then truncating the value to PSImode. -;; -;; This first pattern combines the shifting & truncation operations, by -;; itself it is a win because the shifts end up occurring in PSImode instead -;; of SImode. However, it has the secondary effect of giving us the -;; opportunity to match patterns which allow us to remove the initial -;; extension completely, which is a big win. -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d,a,da") - (truncate:PSI - (ashift:SI (match_operand:SI 1 "psimode_truncation_operand" "d,m,m,i") - (match_operand:HI 2 "const_int_operand" "i,i,i,i"))))] - "" - "* -{ - int count = INTVAL (operands[2]); - if (which_alternative == 0) - output_asm_insn (\"jsr ___truncsipsi2_%1_%0\", operands); - else if (which_alternative == 1) - output_asm_insn (\"movx %A1,%0\", operands); - else - output_asm_insn (\" mov %1,%0\", operands); - - while (count) - { - output_asm_insn (\"add %0,%0\", operands); - count--; - } - return \"\"; -}" - [(set_attr "cc" "clobber")]) - -;; Similarly, except that we also have zero/sign extension of the -;; original operand. */ -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d") - (truncate:PSI - (ashift:SI - (zero_extend:SI (match_operand:HI 1 "general_operand" "0,dim")) - (match_operand:HI 2 "const_int_operand" "i,i"))))] - "" - "* -{ - int count = INTVAL (operands[2]); - - /* First extend operand 1 to PSImode. */ - if (which_alternative == 0) - output_asm_insn (\"extxu %0\", operands); - else - output_asm_insn (\"mov %1,%0\;extxu %0\", operands); - - /* Now do the shifting. */ - while (count) - { - output_asm_insn (\"add %0,%0\", operands); - count--; - } - return \"\"; -}" - [(set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (truncate:PSI - (ashift:SI - (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m")) - (match_operand:HI 2 "const_int_operand" "i,i,i"))))] - "" - "* -{ - int count = INTVAL (operands[2]); - - /* First extend operand 1 to PSImode. */ - if (which_alternative == 0) - output_asm_insn (\"extx %0\", operands); - else if (which_alternative == 1) - output_asm_insn (\"mov %1,%0\;extx %0\", operands); - else - output_asm_insn (\"mov %1,%0\", operands); - - /* Now do the shifting. */ - while (count) - { - output_asm_insn (\"add %0,%0\", operands); - count--; - } - return \"\"; -}" - [(set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (truncate:PSI - (ashift:SI - (sign_extend:SI - (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m"))) - (match_operand:HI 2 "const_int_operand" "i,i,i"))))] - "" - "* -{ - int count = INTVAL (operands[2]); - - /* First extend operand 1 to PSImode. */ - if (which_alternative == 0) - output_asm_insn (\"extxbu %0\", operands); - else if (which_alternative == 1) - output_asm_insn (\"mov %1,%0\;extxbu %0\", operands); - else - output_asm_insn (\"movbu %1,%0\", operands); - - /* Now do the shifting. */ - while (count) - { - output_asm_insn (\"add %0,%0\", operands); - count--; - } - return \"\"; -}" - [(set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:PSI 0 "general_operand" "=d,d,d") - (truncate:PSI - (ashift:SI - (sign_extend:SI - (match_operand:QI 1 "general_operand" "0,di,m")) - (match_operand:HI 2 "const_int_operand" "i,i,i"))))] - "" - "* -{ - int count = INTVAL (operands[2]); - - /* First extend operand 1 to PSImode. */ - if (which_alternative == 0) - output_asm_insn (\"extxb %0\", operands); - else if (which_alternative == 1) - output_asm_insn (\"mov %1,%0\;extxb %0\", operands); - else if (GET_CODE (XEXP (operands[1], 0)) == REG) - output_asm_insn (\"movbu %1,%0\;extxb %0\", operands); - else - output_asm_insn (\"movb %1,%0\", operands); - - /* Now do the shifting. */ - while (count) - { - output_asm_insn (\"add %0,%0\", operands); - count--; - } - return \"\"; -}" - [(set_attr "cc" "clobber")]) - -;; Try to combine consecutive updates of the stack pointer (or any -;; other register for that matter). -(define_peephole - [(set (match_operand:PSI 0 "register_operand" "=da") - (plus:PSI (match_dup 0) - (match_operand 1 "const_int_operand" ""))) - (set (match_dup 0) - (plus:PSI (match_dup 0) - (match_operand 2 "const_int_operand" "")))] - "" - "* -{ - operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1])); - return \"add %1,%0\"; -}" - [(set_attr "cc" "clobber")]) - -;; -;; We had patterns to check eq/ne, but the they don't work because -;; 0x80000000 + 0x80000000 = 0x0 with a carry out. -;; -;; The Z flag and C flag would be set, and we have no way to -;; check for the Z flag set and C flag clear. -;; -;; This will work on the mn10200 because we can check the ZX flag -;; if the comparison is in HImode. -(define_peephole - [(set (cc0) (match_operand:HI 0 "register_operand" "d")) - (set (pc) (if_then_else (ge (cc0) (const_int 0)) - (match_operand 1 "" "") - (pc)))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcc %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:HI 0 "register_operand" "d")) - (set (pc) (if_then_else (lt (cc0) (const_int 0)) - (match_operand 1 "" "") - (pc)))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcs %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:HI 0 "register_operand" "d")) - (set (pc) (if_then_else (ge (cc0) (const_int 0)) - (pc) - (match_operand 1 "" "")))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcs %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:HI 0 "register_operand" "d")) - (set (pc) (if_then_else (lt (cc0) (const_int 0)) - (pc) - (match_operand 1 "" "")))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcc %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:PSI 0 "register_operand" "d")) - (set (pc) (if_then_else (ge (cc0) (const_int 0)) - (match_operand 1 "" "") - (pc)))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bccx %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:PSI 0 "register_operand" "d")) - (set (pc) (if_then_else (lt (cc0) (const_int 0)) - (match_operand 1 "" "") - (pc)))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcsx %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:PSI 0 "register_operand" "d")) - (set (pc) (if_then_else (ge (cc0) (const_int 0)) - (pc) - (match_operand 1 "" "")))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bcsx %1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (cc0) (match_operand:PSI 0 "register_operand" "d")) - (set (pc) (if_then_else (lt (cc0) (const_int 0)) - (pc) - (match_operand 1 "" "")))] - "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" - "add %0,%0\;bccx %1" - [(set_attr "cc" "clobber")]) - -;; We call out to library routines to perform 32bit addition and subtraction -;; operations (see addsi3/subsi3 expanders for why). These peepholes catch -;; the trivial case where the operation could be done with an add;addc or -;; sub;subc sequence. -(define_peephole - [(set (mem:SI (reg:PSI 7)) (reg:SI 2)) - (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF - && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__addsi3\") == 0" - "add d2,d0\;addc d3,d1" - [(set_attr "cc" "clobber")]) - -(define_peephole - [(set (mem:SI (reg:PSI 7)) (reg:SI 2)) - (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")))] - "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF - && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__subsi3\") == 0" - "sub d2,d0\;subc d3,d1" - [(set_attr "cc" "clobber")])