Home | History | Annotate | Line # | Download | only in arm
arm-fixed.md revision 1.3
      1  1.3  mrg ;; Copyright (C) 2011-2015 Free Software Foundation, Inc.
      2  1.1  mrg ;;
      3  1.1  mrg ;; This file is part of GCC.
      4  1.1  mrg ;;
      5  1.1  mrg ;; GCC is free software; you can redistribute it and/or modify it
      6  1.1  mrg ;; under the terms of the GNU General Public License as published
      7  1.1  mrg ;; by the Free Software Foundation; either version 3, or (at your
      8  1.1  mrg ;; option) any later version.
      9  1.1  mrg ;;
     10  1.1  mrg ;; GCC is distributed in the hope that it will be useful, but WITHOUT
     11  1.1  mrg ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     12  1.1  mrg ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     13  1.1  mrg ;; License for more details.
     14  1.1  mrg ;;
     15  1.1  mrg ;; You should have received a copy of the GNU General Public License
     16  1.1  mrg ;; along with GCC; see the file COPYING3.  If not see
     17  1.1  mrg ;; <http://www.gnu.org/licenses/>.
     18  1.1  mrg ;;
     19  1.1  mrg ;; This file contains ARM instructions that support fixed-point operations.
     20  1.1  mrg 
     21  1.1  mrg (define_insn "add<mode>3"
     22  1.3  mrg   [(set (match_operand:FIXED 0 "s_register_operand" "=l,r")
     23  1.3  mrg 	(plus:FIXED (match_operand:FIXED 1 "s_register_operand" "l,r")
     24  1.3  mrg 		    (match_operand:FIXED 2 "s_register_operand" "l,r")))]
     25  1.1  mrg   "TARGET_32BIT"
     26  1.1  mrg   "add%?\\t%0, %1, %2"
     27  1.3  mrg   [(set_attr "predicable" "yes")
     28  1.3  mrg    (set_attr "predicable_short_it" "yes,no")
     29  1.3  mrg    (set_attr "type" "alu_sreg")])
     30  1.1  mrg 
     31  1.1  mrg (define_insn "add<mode>3"
     32  1.1  mrg   [(set (match_operand:ADDSUB 0 "s_register_operand" "=r")
     33  1.1  mrg 	(plus:ADDSUB (match_operand:ADDSUB 1 "s_register_operand" "r")
     34  1.1  mrg 		     (match_operand:ADDSUB 2 "s_register_operand" "r")))]
     35  1.1  mrg   "TARGET_INT_SIMD"
     36  1.1  mrg   "sadd<qaddsub_suf>%?\\t%0, %1, %2"
     37  1.3  mrg   [(set_attr "predicable" "yes")
     38  1.3  mrg    (set_attr "predicable_short_it" "no")
     39  1.3  mrg    (set_attr "type" "alu_dsp_reg")])
     40  1.1  mrg 
     41  1.1  mrg (define_insn "usadd<mode>3"
     42  1.1  mrg   [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r")
     43  1.1  mrg 	(us_plus:UQADDSUB (match_operand:UQADDSUB 1 "s_register_operand" "r")
     44  1.1  mrg 			  (match_operand:UQADDSUB 2 "s_register_operand" "r")))]
     45  1.1  mrg   "TARGET_INT_SIMD"
     46  1.1  mrg   "uqadd<qaddsub_suf>%?\\t%0, %1, %2"
     47  1.3  mrg   [(set_attr "predicable" "yes")
     48  1.3  mrg    (set_attr "predicable_short_it" "no")
     49  1.3  mrg    (set_attr "type" "alu_dsp_reg")])
     50  1.1  mrg 
     51  1.1  mrg (define_insn "ssadd<mode>3"
     52  1.1  mrg   [(set (match_operand:QADDSUB 0 "s_register_operand" "=r")
     53  1.1  mrg 	(ss_plus:QADDSUB (match_operand:QADDSUB 1 "s_register_operand" "r")
     54  1.1  mrg 			 (match_operand:QADDSUB 2 "s_register_operand" "r")))]
     55  1.1  mrg   "TARGET_INT_SIMD"
     56  1.1  mrg   "qadd<qaddsub_suf>%?\\t%0, %1, %2"
     57  1.3  mrg   [(set_attr "predicable" "yes")
     58  1.3  mrg    (set_attr "predicable_short_it" "no")
     59  1.3  mrg    (set_attr "type" "alu_dsp_reg")])
     60  1.1  mrg 
     61  1.1  mrg (define_insn "sub<mode>3"
     62  1.3  mrg   [(set (match_operand:FIXED 0 "s_register_operand" "=l,r")
     63  1.3  mrg 	(minus:FIXED (match_operand:FIXED 1 "s_register_operand" "l,r")
     64  1.3  mrg 		     (match_operand:FIXED 2 "s_register_operand" "l,r")))]
     65  1.1  mrg   "TARGET_32BIT"
     66  1.1  mrg   "sub%?\\t%0, %1, %2"
     67  1.3  mrg   [(set_attr "predicable" "yes")
     68  1.3  mrg    (set_attr "predicable_short_it" "yes,no")
     69  1.3  mrg    (set_attr "type" "alu_sreg")])
     70  1.1  mrg 
     71  1.1  mrg (define_insn "sub<mode>3"
     72  1.1  mrg   [(set (match_operand:ADDSUB 0 "s_register_operand" "=r")
     73  1.1  mrg 	(minus:ADDSUB (match_operand:ADDSUB 1 "s_register_operand" "r")
     74  1.1  mrg 		      (match_operand:ADDSUB 2 "s_register_operand" "r")))]
     75  1.1  mrg   "TARGET_INT_SIMD"
     76  1.1  mrg   "ssub<qaddsub_suf>%?\\t%0, %1, %2"
     77  1.3  mrg   [(set_attr "predicable" "yes")
     78  1.3  mrg    (set_attr "predicable_short_it" "no")
     79  1.3  mrg    (set_attr "type" "alu_dsp_reg")])
     80  1.1  mrg 
     81  1.1  mrg (define_insn "ussub<mode>3"
     82  1.1  mrg   [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r")
     83  1.1  mrg 	(us_minus:UQADDSUB
     84  1.1  mrg 	  (match_operand:UQADDSUB 1 "s_register_operand" "r")
     85  1.1  mrg 	  (match_operand:UQADDSUB 2 "s_register_operand" "r")))]
     86  1.1  mrg   "TARGET_INT_SIMD"
     87  1.1  mrg   "uqsub<qaddsub_suf>%?\\t%0, %1, %2"
     88  1.3  mrg   [(set_attr "predicable" "yes")
     89  1.3  mrg    (set_attr "predicable_short_it" "no")
     90  1.3  mrg    (set_attr "type" "alu_dsp_reg")])
     91  1.1  mrg 
     92  1.1  mrg (define_insn "sssub<mode>3"
     93  1.1  mrg   [(set (match_operand:QADDSUB 0 "s_register_operand" "=r")
     94  1.1  mrg 	(ss_minus:QADDSUB (match_operand:QADDSUB 1 "s_register_operand" "r")
     95  1.1  mrg 			  (match_operand:QADDSUB 2 "s_register_operand" "r")))]
     96  1.1  mrg   "TARGET_INT_SIMD"
     97  1.1  mrg   "qsub<qaddsub_suf>%?\\t%0, %1, %2"
     98  1.3  mrg   [(set_attr "predicable" "yes")
     99  1.3  mrg    (set_attr "predicable_short_it" "no")
    100  1.3  mrg    (set_attr "type" "alu_dsp_reg")])
    101  1.1  mrg 
    102  1.1  mrg ;; Fractional multiplies.
    103  1.1  mrg 
    104  1.1  mrg ; Note: none of these do any rounding.
    105  1.1  mrg 
    106  1.1  mrg (define_expand "mulqq3"
    107  1.1  mrg   [(set (match_operand:QQ 0 "s_register_operand" "")
    108  1.1  mrg 	(mult:QQ (match_operand:QQ 1 "s_register_operand" "")
    109  1.1  mrg 		 (match_operand:QQ 2 "s_register_operand" "")))]
    110  1.1  mrg   "TARGET_DSP_MULTIPLY && arm_arch_thumb2"
    111  1.1  mrg {
    112  1.1  mrg   rtx tmp1 = gen_reg_rtx (HImode);
    113  1.1  mrg   rtx tmp2 = gen_reg_rtx (HImode);
    114  1.1  mrg   rtx tmp3 = gen_reg_rtx (SImode);
    115  1.3  mrg 
    116  1.1  mrg   emit_insn (gen_extendqihi2 (tmp1, gen_lowpart (QImode, operands[1])));
    117  1.1  mrg   emit_insn (gen_extendqihi2 (tmp2, gen_lowpart (QImode, operands[2])));
    118  1.1  mrg   emit_insn (gen_mulhisi3 (tmp3, tmp1, tmp2));
    119  1.1  mrg   emit_insn (gen_extv (gen_lowpart (SImode, operands[0]), tmp3, GEN_INT (8),
    120  1.1  mrg 		       GEN_INT (7)));
    121  1.1  mrg   DONE;
    122  1.1  mrg })
    123  1.1  mrg 
    124  1.1  mrg (define_expand "mulhq3"
    125  1.1  mrg   [(set (match_operand:HQ 0 "s_register_operand" "")
    126  1.1  mrg 	(mult:HQ (match_operand:HQ 1 "s_register_operand" "")
    127  1.1  mrg 		 (match_operand:HQ 2 "s_register_operand" "")))]
    128  1.1  mrg   "TARGET_DSP_MULTIPLY && arm_arch_thumb2"
    129  1.1  mrg {
    130  1.1  mrg   rtx tmp = gen_reg_rtx (SImode);
    131  1.1  mrg 
    132  1.1  mrg   emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]),
    133  1.1  mrg 			   gen_lowpart (HImode, operands[2])));
    134  1.1  mrg   /* We're doing a s.15 * s.15 multiplication, getting an s.30 result.  Extract
    135  1.1  mrg      an s.15 value from that.  This won't overflow/saturate for _Fract
    136  1.1  mrg      values.  */
    137  1.1  mrg   emit_insn (gen_extv (gen_lowpart (SImode, operands[0]), tmp,
    138  1.1  mrg 		       GEN_INT (16), GEN_INT (15)));
    139  1.1  mrg   DONE;
    140  1.1  mrg })
    141  1.1  mrg 
    142  1.1  mrg (define_expand "mulsq3"
    143  1.1  mrg   [(set (match_operand:SQ 0 "s_register_operand" "")
    144  1.1  mrg 	(mult:SQ (match_operand:SQ 1 "s_register_operand" "")
    145  1.1  mrg 		 (match_operand:SQ 2 "s_register_operand" "")))]
    146  1.1  mrg   "TARGET_32BIT && arm_arch3m"
    147  1.1  mrg {
    148  1.1  mrg   rtx tmp1 = gen_reg_rtx (DImode);
    149  1.1  mrg   rtx tmp2 = gen_reg_rtx (SImode);
    150  1.1  mrg   rtx tmp3 = gen_reg_rtx (SImode);
    151  1.3  mrg 
    152  1.1  mrg   /* s.31 * s.31 -> s.62 multiplication.  */
    153  1.1  mrg   emit_insn (gen_mulsidi3 (tmp1, gen_lowpart (SImode, operands[1]),
    154  1.1  mrg 			   gen_lowpart (SImode, operands[2])));
    155  1.1  mrg   emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (31)));
    156  1.1  mrg   emit_insn (gen_ashlsi3 (tmp3, gen_highpart (SImode, tmp1), GEN_INT (1)));
    157  1.1  mrg   emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), tmp2, tmp3));
    158  1.1  mrg 
    159  1.1  mrg   DONE;
    160  1.1  mrg })
    161  1.1  mrg 
    162  1.1  mrg ;; Accumulator multiplies.
    163  1.1  mrg 
    164  1.1  mrg (define_expand "mulsa3"
    165  1.1  mrg   [(set (match_operand:SA 0 "s_register_operand" "")
    166  1.1  mrg 	(mult:SA (match_operand:SA 1 "s_register_operand" "")
    167  1.1  mrg 		 (match_operand:SA 2 "s_register_operand" "")))]
    168  1.1  mrg   "TARGET_32BIT && arm_arch3m"
    169  1.1  mrg {
    170  1.1  mrg   rtx tmp1 = gen_reg_rtx (DImode);
    171  1.1  mrg   rtx tmp2 = gen_reg_rtx (SImode);
    172  1.1  mrg   rtx tmp3 = gen_reg_rtx (SImode);
    173  1.3  mrg 
    174  1.1  mrg   emit_insn (gen_mulsidi3 (tmp1, gen_lowpart (SImode, operands[1]),
    175  1.1  mrg 			   gen_lowpart (SImode, operands[2])));
    176  1.1  mrg   emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (15)));
    177  1.1  mrg   emit_insn (gen_ashlsi3 (tmp3, gen_highpart (SImode, tmp1), GEN_INT (17)));
    178  1.1  mrg   emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), tmp2, tmp3));
    179  1.1  mrg 
    180  1.1  mrg   DONE;
    181  1.1  mrg })
    182  1.1  mrg 
    183  1.1  mrg (define_expand "mulusa3"
    184  1.1  mrg   [(set (match_operand:USA 0 "s_register_operand" "")
    185  1.1  mrg 	(mult:USA (match_operand:USA 1 "s_register_operand" "")
    186  1.1  mrg 		  (match_operand:USA 2 "s_register_operand" "")))]
    187  1.1  mrg   "TARGET_32BIT && arm_arch3m"
    188  1.1  mrg {
    189  1.1  mrg   rtx tmp1 = gen_reg_rtx (DImode);
    190  1.1  mrg   rtx tmp2 = gen_reg_rtx (SImode);
    191  1.1  mrg   rtx tmp3 = gen_reg_rtx (SImode);
    192  1.3  mrg 
    193  1.1  mrg   emit_insn (gen_umulsidi3 (tmp1, gen_lowpart (SImode, operands[1]),
    194  1.1  mrg 			    gen_lowpart (SImode, operands[2])));
    195  1.1  mrg   emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (16)));
    196  1.1  mrg   emit_insn (gen_ashlsi3 (tmp3, gen_highpart (SImode, tmp1), GEN_INT (16)));
    197  1.1  mrg   emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), tmp2, tmp3));
    198  1.3  mrg 
    199  1.1  mrg   DONE;
    200  1.1  mrg })
    201  1.1  mrg 
    202  1.1  mrg ;; The code sequence emitted by this insn pattern uses the Q flag, which GCC
    203  1.1  mrg ;; doesn't generally know about, so we don't bother expanding to individual
    204  1.1  mrg ;; instructions.  It may be better to just use an out-of-line asm libcall for
    205  1.1  mrg ;; this.
    206  1.1  mrg 
    207  1.1  mrg (define_insn "ssmulsa3"
    208  1.1  mrg   [(set (match_operand:SA 0 "s_register_operand" "=r")
    209  1.1  mrg 	(ss_mult:SA (match_operand:SA 1 "s_register_operand" "r")
    210  1.1  mrg 		    (match_operand:SA 2 "s_register_operand" "r")))
    211  1.1  mrg    (clobber (match_scratch:DI 3 "=r"))
    212  1.1  mrg    (clobber (match_scratch:SI 4 "=r"))
    213  1.1  mrg    (clobber (reg:CC CC_REGNUM))]
    214  1.1  mrg   "TARGET_32BIT && arm_arch6"
    215  1.1  mrg {
    216  1.1  mrg   /* s16.15 * s16.15 -> s32.30.  */
    217  1.1  mrg   output_asm_insn ("smull\\t%Q3, %R3, %1, %2", operands);
    218  1.1  mrg 
    219  1.1  mrg   if (TARGET_ARM)
    220  1.1  mrg     output_asm_insn ("msr\\tAPSR_nzcvq, #0", operands);
    221  1.1  mrg   else
    222  1.1  mrg     {
    223  1.1  mrg       output_asm_insn ("mov\\t%4, #0", operands);
    224  1.1  mrg       output_asm_insn ("msr\\tAPSR_nzcvq, %4", operands);
    225  1.1  mrg     }
    226  1.1  mrg 
    227  1.1  mrg   /* We have:
    228  1.3  mrg       31  high word  0     31  low word  0
    229  1.1  mrg 
    230  1.1  mrg     [ S i i .... i i i ] [ i f f f ... f f ]
    231  1.1  mrg                         |
    232  1.1  mrg 			v
    233  1.1  mrg 	     [ S i ... i f ... f f ]
    234  1.1  mrg 
    235  1.1  mrg     Need 16 integral bits, so saturate at 15th bit of high word.  */
    236  1.1  mrg 
    237  1.1  mrg   output_asm_insn ("ssat\\t%R3, #15, %R3", operands);
    238  1.1  mrg   output_asm_insn ("mrs\\t%4, APSR", operands);
    239  1.1  mrg   output_asm_insn ("tst\\t%4, #1<<27", operands);
    240  1.3  mrg   if (arm_restrict_it)
    241  1.3  mrg     {
    242  1.3  mrg       output_asm_insn ("mvn\\t%4, %R3, asr #32", operands);
    243  1.3  mrg       output_asm_insn ("it\\tne", operands);
    244  1.3  mrg       output_asm_insn ("movne\\t%Q3, %4", operands);
    245  1.3  mrg     }
    246  1.3  mrg   else
    247  1.3  mrg     {
    248  1.3  mrg       if (TARGET_THUMB2)
    249  1.3  mrg         output_asm_insn ("it\\tne", operands);
    250  1.3  mrg       output_asm_insn ("mvnne\\t%Q3, %R3, asr #32", operands);
    251  1.3  mrg     }
    252  1.1  mrg   output_asm_insn ("mov\\t%0, %Q3, lsr #15", operands);
    253  1.1  mrg   output_asm_insn ("orr\\t%0, %0, %R3, asl #17", operands);
    254  1.1  mrg   return "";
    255  1.1  mrg }
    256  1.1  mrg   [(set_attr "conds" "clob")
    257  1.3  mrg    (set_attr "type" "multiple")
    258  1.1  mrg    (set (attr "length")
    259  1.1  mrg 	(if_then_else (eq_attr "is_thumb" "yes")
    260  1.3  mrg 		      (if_then_else (match_test "arm_restrict_it")
    261  1.3  mrg 		                    (const_int 40)
    262  1.3  mrg 		                    (const_int 38))
    263  1.1  mrg 		      (const_int 32)))])
    264  1.1  mrg 
    265  1.1  mrg ;; Same goes for this.
    266  1.1  mrg 
    267  1.1  mrg (define_insn "usmulusa3"
    268  1.1  mrg   [(set (match_operand:USA 0 "s_register_operand" "=r")
    269  1.1  mrg 	(us_mult:USA (match_operand:USA 1 "s_register_operand" "r")
    270  1.1  mrg 		     (match_operand:USA 2 "s_register_operand" "r")))
    271  1.1  mrg    (clobber (match_scratch:DI 3 "=r"))
    272  1.1  mrg    (clobber (match_scratch:SI 4 "=r"))
    273  1.1  mrg    (clobber (reg:CC CC_REGNUM))]
    274  1.1  mrg   "TARGET_32BIT && arm_arch6"
    275  1.1  mrg {
    276  1.1  mrg   /* 16.16 * 16.16 -> 32.32.  */
    277  1.1  mrg   output_asm_insn ("umull\\t%Q3, %R3, %1, %2", operands);
    278  1.1  mrg 
    279  1.1  mrg   if (TARGET_ARM)
    280  1.1  mrg     output_asm_insn ("msr\\tAPSR_nzcvq, #0", operands);
    281  1.1  mrg   else
    282  1.1  mrg     {
    283  1.1  mrg       output_asm_insn ("mov\\t%4, #0", operands);
    284  1.1  mrg       output_asm_insn ("msr\\tAPSR_nzcvq, %4", operands);
    285  1.1  mrg     }
    286  1.1  mrg 
    287  1.1  mrg   /* We have:
    288  1.3  mrg       31  high word  0     31  low word  0
    289  1.1  mrg 
    290  1.1  mrg     [ i i i .... i i i ] [ f f f f ... f f ]
    291  1.1  mrg                         |
    292  1.1  mrg 			v
    293  1.1  mrg 	     [ i i ... i f ... f f ]
    294  1.1  mrg 
    295  1.1  mrg     Need 16 integral bits, so saturate at 16th bit of high word.  */
    296  1.1  mrg 
    297  1.1  mrg   output_asm_insn ("usat\\t%R3, #16, %R3", operands);
    298  1.1  mrg   output_asm_insn ("mrs\\t%4, APSR", operands);
    299  1.1  mrg   output_asm_insn ("tst\\t%4, #1<<27", operands);
    300  1.3  mrg   if (arm_restrict_it)
    301  1.3  mrg     {
    302  1.3  mrg       output_asm_insn ("sbfx\\t%4, %R3, #15, #1", operands);
    303  1.3  mrg       output_asm_insn ("it\\tne", operands);
    304  1.3  mrg       output_asm_insn ("movne\\t%Q3, %4", operands);
    305  1.3  mrg     }
    306  1.3  mrg   else
    307  1.3  mrg     {
    308  1.3  mrg       if (TARGET_THUMB2)
    309  1.3  mrg         output_asm_insn ("it\\tne", operands);
    310  1.3  mrg       output_asm_insn ("sbfxne\\t%Q3, %R3, #15, #1", operands);
    311  1.3  mrg     }
    312  1.1  mrg   output_asm_insn ("lsr\\t%0, %Q3, #16", operands);
    313  1.1  mrg   output_asm_insn ("orr\\t%0, %0, %R3, asl #16", operands);
    314  1.1  mrg   return "";
    315  1.1  mrg }
    316  1.1  mrg   [(set_attr "conds" "clob")
    317  1.3  mrg    (set_attr "type" "multiple")
    318  1.1  mrg    (set (attr "length")
    319  1.1  mrg 	(if_then_else (eq_attr "is_thumb" "yes")
    320  1.3  mrg 		      (if_then_else (match_test "arm_restrict_it")
    321  1.3  mrg 		                    (const_int 40)
    322  1.3  mrg 		                    (const_int 38))
    323  1.1  mrg 		      (const_int 32)))])
    324  1.1  mrg 
    325  1.1  mrg (define_expand "mulha3"
    326  1.1  mrg   [(set (match_operand:HA 0 "s_register_operand" "")
    327  1.1  mrg 	(mult:HA (match_operand:HA 1 "s_register_operand" "")
    328  1.1  mrg 		 (match_operand:HA 2 "s_register_operand" "")))]
    329  1.1  mrg   "TARGET_DSP_MULTIPLY && arm_arch_thumb2"
    330  1.1  mrg {
    331  1.1  mrg   rtx tmp = gen_reg_rtx (SImode);
    332  1.3  mrg 
    333  1.1  mrg   emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]),
    334  1.1  mrg 			   gen_lowpart (HImode, operands[2])));
    335  1.1  mrg   emit_insn (gen_extv (gen_lowpart (SImode, operands[0]), tmp, GEN_INT (16),
    336  1.1  mrg 		       GEN_INT (7)));
    337  1.1  mrg 
    338  1.1  mrg   DONE;
    339  1.1  mrg })
    340  1.1  mrg 
    341  1.1  mrg (define_expand "muluha3"
    342  1.1  mrg   [(set (match_operand:UHA 0 "s_register_operand" "")
    343  1.1  mrg 	(mult:UHA (match_operand:UHA 1 "s_register_operand" "")
    344  1.1  mrg 		  (match_operand:UHA 2 "s_register_operand" "")))]
    345  1.1  mrg   "TARGET_DSP_MULTIPLY"
    346  1.1  mrg {
    347  1.1  mrg   rtx tmp1 = gen_reg_rtx (SImode);
    348  1.1  mrg   rtx tmp2 = gen_reg_rtx (SImode);
    349  1.1  mrg   rtx tmp3 = gen_reg_rtx (SImode);
    350  1.3  mrg 
    351  1.1  mrg   /* 8.8 * 8.8 -> 16.16 multiply.  */
    352  1.1  mrg   emit_insn (gen_zero_extendhisi2 (tmp1, gen_lowpart (HImode, operands[1])));
    353  1.1  mrg   emit_insn (gen_zero_extendhisi2 (tmp2, gen_lowpart (HImode, operands[2])));
    354  1.1  mrg   emit_insn (gen_mulsi3 (tmp3, tmp1, tmp2));
    355  1.1  mrg   emit_insn (gen_extzv (gen_lowpart (SImode, operands[0]), tmp3,
    356  1.1  mrg 			GEN_INT (16), GEN_INT (8)));
    357  1.1  mrg 
    358  1.1  mrg   DONE;
    359  1.1  mrg })
    360  1.1  mrg 
    361  1.1  mrg (define_expand "ssmulha3"
    362  1.1  mrg   [(set (match_operand:HA 0 "s_register_operand" "")
    363  1.1  mrg 	(ss_mult:HA (match_operand:HA 1 "s_register_operand" "")
    364  1.1  mrg 		    (match_operand:HA 2 "s_register_operand" "")))]
    365  1.1  mrg   "TARGET_32BIT && TARGET_DSP_MULTIPLY && arm_arch6"
    366  1.1  mrg {
    367  1.1  mrg   rtx tmp = gen_reg_rtx (SImode);
    368  1.1  mrg   rtx rshift;
    369  1.3  mrg 
    370  1.1  mrg   emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]),
    371  1.1  mrg 			   gen_lowpart (HImode, operands[2])));
    372  1.1  mrg 
    373  1.1  mrg   rshift = gen_rtx_ASHIFTRT (SImode, tmp, GEN_INT (7));
    374  1.1  mrg 
    375  1.1  mrg   emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (HImode, operands[0]),
    376  1.1  mrg 			  gen_rtx_SS_TRUNCATE (HImode, rshift)));
    377  1.1  mrg 
    378  1.1  mrg   DONE;
    379  1.1  mrg })
    380  1.1  mrg 
    381  1.1  mrg (define_expand "usmuluha3"
    382  1.1  mrg   [(set (match_operand:UHA 0 "s_register_operand" "")
    383  1.1  mrg 	(us_mult:UHA (match_operand:UHA 1 "s_register_operand" "")
    384  1.1  mrg 		     (match_operand:UHA 2 "s_register_operand" "")))]
    385  1.1  mrg   "TARGET_INT_SIMD"
    386  1.1  mrg {
    387  1.1  mrg   rtx tmp1 = gen_reg_rtx (SImode);
    388  1.1  mrg   rtx tmp2 = gen_reg_rtx (SImode);
    389  1.1  mrg   rtx tmp3 = gen_reg_rtx (SImode);
    390  1.1  mrg   rtx rshift_tmp = gen_reg_rtx (SImode);
    391  1.3  mrg 
    392  1.1  mrg   /* Note: there's no smul[bt][bt] equivalent for unsigned multiplies.  Use a
    393  1.1  mrg      normal 32x32->32-bit multiply instead.  */
    394  1.1  mrg   emit_insn (gen_zero_extendhisi2 (tmp1, gen_lowpart (HImode, operands[1])));
    395  1.1  mrg   emit_insn (gen_zero_extendhisi2 (tmp2, gen_lowpart (HImode, operands[2])));
    396  1.3  mrg 
    397  1.1  mrg   emit_insn (gen_mulsi3 (tmp3, tmp1, tmp2));
    398  1.1  mrg 
    399  1.1  mrg   /* The operand to "usat" is signed, so we cannot use the "..., asr #8"
    400  1.1  mrg      form of that instruction since the multiplication result TMP3 may have the
    401  1.1  mrg      top bit set, thus be negative and saturate to zero.  Use a separate
    402  1.1  mrg      logical right-shift instead.  */
    403  1.1  mrg   emit_insn (gen_lshrsi3 (rshift_tmp, tmp3, GEN_INT (8)));
    404  1.1  mrg   emit_insn (gen_arm_usatsihi (gen_lowpart (HImode, operands[0]), rshift_tmp));
    405  1.1  mrg 
    406  1.1  mrg   DONE;
    407  1.1  mrg })
    408  1.1  mrg 
    409  1.1  mrg (define_insn "arm_ssatsihi_shift"
    410  1.1  mrg   [(set (match_operand:HI 0 "s_register_operand" "=r")
    411  1.1  mrg 	(ss_truncate:HI (match_operator:SI 1 "sat_shift_operator"
    412  1.1  mrg 			  [(match_operand:SI 2 "s_register_operand" "r")
    413  1.1  mrg 			   (match_operand:SI 3 "immediate_operand" "I")])))]
    414  1.1  mrg   "TARGET_32BIT && arm_arch6"
    415  1.1  mrg   "ssat%?\\t%0, #16, %2%S1"
    416  1.1  mrg   [(set_attr "predicable" "yes")
    417  1.3  mrg    (set_attr "predicable_short_it" "no")
    418  1.1  mrg    (set_attr "shift" "1")
    419  1.3  mrg    (set_attr "type" "alu_shift_imm")])
    420  1.1  mrg 
    421  1.1  mrg (define_insn "arm_usatsihi"
    422  1.1  mrg   [(set (match_operand:HI 0 "s_register_operand" "=r")
    423  1.1  mrg 	(us_truncate:HI (match_operand:SI 1 "s_register_operand")))]
    424  1.1  mrg   "TARGET_INT_SIMD"
    425  1.1  mrg   "usat%?\\t%0, #16, %1"
    426  1.1  mrg   [(set_attr "predicable" "yes")
    427  1.3  mrg    (set_attr "predicable_short_it" "no")
    428  1.3  mrg    (set_attr "type" "alu_imm")]
    429  1.3  mrg )
    430