Home | History | Annotate | Line # | Download | only in vax
vax.md revision 1.17
      1 ;; Machine description for GNU compiler, VAX Version
      2 ;; Copyright (C) 1987-2020 Free Software Foundation, Inc.
      3 
      4 ;; This file is part of GCC.
      5 
      6 ;; GCC is free software; you can redistribute it and/or modify
      7 ;; it under the terms of the GNU General Public License as published by
      8 ;; the Free Software Foundation; either version 3, or (at your option)
      9 ;; any later version.
     10 
     11 ;; GCC is distributed in the hope that it will be useful,
     12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 ;; GNU General Public License for more details.
     15 
     16 ;; You should have received a copy of the GNU General Public License
     17 ;; along with GCC; see the file COPYING3.  If not see
     18 ;; <http://www.gnu.org/licenses/>.
     19 
     20 
     21 ;;- Instruction patterns.  When multiple patterns apply,
     22 ;;- the first one in the file is chosen.
     23 ;;-
     24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et al.
     25 ;;-
     26 ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
     27 ;;- updates for most instructions.
     28 
     29 ;; UNSPEC_VOLATILE usage:
     30 
     31 (define_c_enum "unspecv" [
     32   VUNSPEC_BLOCKAGE 	    ; 'blockage' insn to prevent scheduling across an
     33 			    ; insn in the code.
     34   VUNSPEC_SYNC_ISTREAM      ; sequence of insns to sync the I-stream
     35   VUNSPEC_PEM		    ; 'procedure_entry_mask' insn.
     36 
     37   VUNSPEC_EH_RETURN
     38 ])
     39 
     40 (define_constants
     41   [(VAX_AP_REGNUM 12)	    ; Register 12 contains the argument pointer
     42    (VAX_FP_REGNUM 13)	    ; Register 13 contains the frame pointer
     43    (VAX_SP_REGNUM 14)	    ; Register 14 contains the stack pointer
     44    (VAX_PC_REGNUM 15)	    ; Register 15 contains the program counter
     45    (VAX_PSW_REGNUM 16)	    ; Program Status Word
     46   ]
     47 )
     48 
     49 ;; Integer modes supported on VAX, with a mapping from machine mode
     50 ;; to mnemonic suffix.  DImode is always a special case.
     51 (define_mode_iterator VAXint [QI HI SI])
     52 (define_mode_iterator VAXintQH [QI HI])
     53 (define_mode_iterator VAXintQHSD [QI HI SI DI])
     54 (define_mode_attr  isfx [(QI "b") (HI "w") (SI "l") (DI "q")])
     55 
     56 ;; Similar for float modes supported on VAX.
     57 (define_mode_iterator VAXfp [SF DF])
     58 (define_mode_attr  fsfx [(SF "f") (DF "%#")])
     59 
     60 ;; Some output patterns want integer immediates with a prefix...
     61 (define_mode_attr  iprefx [(QI "B") (HI "H") (SI "N")])
     62 
     63 ;;
     64 (include "constraints.md")
     65 (include "predicates.md")
     66 
     67 (define_insn "*cmp<mode>"
     68   [(set (cc0)
     69 	(compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT")
     70 		 (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
     71   ""
     72   "@
     73    tst<VAXint:isfx> %0
     74    cmp<VAXint:isfx> %0,%1")
     75 
     76 (define_insn "*cmp<mode>"
     77   [(set (cc0)
     78 	(compare (match_operand:VAXfp 0 "general_operand" "gF,gF")
     79 		 (match_operand:VAXfp 1 "general_operand" "G,gF")))]
     80   ""
     81   "@
     82    tst<VAXfp:fsfx> %0
     83    cmp<VAXfp:fsfx> %0,%1")
     84 
     85 (define_insn "*bit<mode>"
     86   [(set (cc0)
     87 	(compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
     88 			     (match_operand:VAXint 1 "general_operand" "nrmT"))
     89 		 (const_int 0)))]
     90   ""
     91   "bit<VAXint:isfx> %0,%1")
     92 
     93 ;; The VAX has no sCOND insns.  It does have add/subtract with carry
     94 ;; which could be used to implement the sltu and sgeu patterns.  However,
     95 ;; to do this properly requires a complete rewrite of the compare insns
     96 ;; to keep them together with the sltu/sgeu insns until after the
     97 ;; reload pass is complete.  The previous implementation didn't do this
     98 ;; and has been deleted.
     99 
    100 
    102 (define_insn "mov<mode>"
    103   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
    104 	(match_operand:VAXfp 1 "general_operand" "G,gF"))]
    105   ""
    106   "@
    107    clr<VAXfp:fsfx> %0
    108    mov<VAXfp:fsfx> %1,%0")
    109 
    110 ;; Some VAXen don't support this instruction.
    111 ;;(define_insn "movti"
    112 ;;  [(set (match_operand:TI 0 "general_operand" "=g")
    113 ;;	(match_operand:TI 1 "general_operand" "g"))]
    114 ;;  ""
    115 ;;  "movh %1,%0")
    116 
    117 (define_insn "movdi"
    118   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
    119 	(match_operand:DI 1 "general_operand" "g"))]
    120   ""
    121   "* return vax_output_int_move (insn, operands, DImode);")
    122 
    123 ;; The VAX move instructions have space-time tradeoffs.  On a MicroVAX
    124 ;; register-register mov instructions take 3 bytes and 2 CPU cycles.  clrl
    125 ;; takes 2 bytes and 3 cycles.  mov from constant to register takes 2 cycles
    126 ;; if the constant is smaller than 4 bytes, 3 cycles for a longword
    127 ;; constant.  movz, mneg, and mcom are as fast as mov, so movzwl is faster
    128 ;; than movl for positive constants that fit in 16 bits but not 6 bits.  cvt
    129 ;; instructions take 4 cycles.  inc takes 3 cycles.  The machine description
    130 ;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl
    131 ;; instead of movl).
    132 
    133 ;; Cycle counts for other models may vary (on a VAX 750 they are similar,
    134 ;; but on a VAX 9000 most move and add instructions with one constant
    135 ;; operand take 1 cycle).
    136 
    137 ;;  Loads of constants between 64 and 128 used to be done with
    138 ;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space.
    139 
    140 (define_expand "movsi"
    141   [(set (match_operand:SI 0 "nonimmediate_operand" "")
    142 	(match_operand:SI 1 "general_operand" ""))]
    143   ""
    144   "
    145 {
    146 #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
    147   if (flag_pic
    148       && GET_CODE (operands[1]) == CONST
    149       && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF
    150       && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (operands[1], 0), 0)))
    151     {
    152       rtx symbol_ref = XEXP (XEXP (operands[1], 0), 0);
    153       rtx const_int = XEXP (XEXP (operands[1], 0), 1);
    154       rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
    155       emit_move_insn (temp, symbol_ref);
    156       emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, const_int));
    157       DONE;
    158     }
    159 #endif
    160 }")
    161 
    162 (define_insn "movsi_2"
    163   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    164 	(match_operand:SI 1 "nonsymbolic_operand" "nrmT"))]
    165   ""
    166   "* return vax_output_int_move (insn, operands, SImode);")
    167 
    168 (define_insn "mov<mode>"
    169   [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g")
    170 	(match_operand:VAXintQH 1 "general_operand" "g"))]
    171   ""
    172   "* return vax_output_int_move (insn, operands, <MODE>mode);")
    173 
    174 (define_insn "movstricthi"
    175   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g"))
    176 	(match_operand:HI 1 "general_operand" "g"))]
    177   ""
    178   "*
    179 {
    180   if (CONST_INT_P (operands[1]))
    181     {
    182       int i = INTVAL (operands[1]);
    183       if (i == 0)
    184 	return \"clrw %0\";
    185       else if ((unsigned int)i < 64)
    186 	return \"movw %1,%0\";
    187       else if ((unsigned int)~i < 64)
    188 	return \"mcomw %H1,%0\";
    189       else if ((unsigned int)i < 256)
    190 	return \"movzbw %1,%0\";
    191     }
    192   return \"movw %1,%0\";
    193 }")
    194 
    195 (define_insn "movstrictqi"
    196   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g"))
    197 	(match_operand:QI 1 "general_operand" "g"))]
    198   ""
    199   "*
    200 {
    201   if (CONST_INT_P (operands[1]))
    202     {
    203       int i = INTVAL (operands[1]);
    204       if (i == 0)
    205 	return \"clrb %0\";
    206       else if ((unsigned int)~i < 64)
    207 	return \"mcomb %B1,%0\";
    208     }
    209   return \"movb %1,%0\";
    210 }")
    211 
    212 ;; This is here to accept 4 arguments and pass the first 3 along
    213 ;; to the cpymemhi1 pattern that really does the work.
    214 (define_expand "cpymemhi"
    215   [(set (match_operand:BLK 0 "general_operand" "=g")
    216 	(match_operand:BLK 1 "general_operand" "g"))
    217    (use (match_operand:HI 2 "general_operand" "g"))
    218    (match_operand 3 "" "")]
    219   ""
    220   "
    221 {
    222 #if 0
    223   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) <= 48)
    224     {
    225       emit_insn (gen_cpymemsi1_2 (operands[0], operands[1], operands[2]));
    226       DONE;
    227     }
    228 #endif
    229   emit_insn (gen_cpymemhi1 (operands[0], operands[1], operands[2]));
    230   DONE;
    231 }")
    232 
    233 ;;(define_insn "cpymemsi1_2"
    234 ;;  [(set (match_operand:BLK 0 "memory_operand" "=B")
    235 ;;	(match_operand:BLK 1 "memory_operand" "B"))
    236 ;;   (use (match_operand:SI 2 "const_int_operand" "g"))]
    237 ;;  "INTVAL (operands[2]) <= 48"
    238 ;;  "* return vax_output_cpymemsi (insn, operands);")
    239 
    240 ;; The definition of this insn does not really explain what it does,
    241 ;; but it should suffice
    242 ;; that anything generated as this insn will be recognized as one
    243 ;; and that it won't successfully combine with anything.
    244 
    245 (define_insn "cpymemhi1"
    246   [(set (match_operand:BLK 0 "memory_operand" "=o")
    247 	(match_operand:BLK 1 "memory_operand" "o"))
    248    (use (match_operand:HI 2 "general_operand" "g"))
    249    (clobber (reg:SI 0))
    250    (clobber (reg:SI 1))
    251    (clobber (reg:SI 2))
    252    (clobber (reg:SI 3))
    253    (clobber (reg:SI 4))
    254    (clobber (reg:SI 5))]
    255   ""
    256   "movc3 %2,%1,%0")
    257 
    259 ;; Extension and truncation insns.
    260 
    261 (define_insn "truncsiqi2"
    262   [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
    263 	(truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
    264   ""
    265   "cvtlb %1,%0")
    266 
    267 (define_insn "truncsihi2"
    268   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
    269 	(truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
    270   ""
    271   "cvtlw %1,%0")
    272 
    273 (define_insn "trunchiqi2"
    274   [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
    275 	(truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))]
    276   ""
    277   "cvtwb %1,%0")
    278 
    279 (define_insn "extendhisi2"
    280   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    281 	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
    282   ""
    283   "cvtwl %1,%0")
    284 
    285 (define_insn "extendqihi2"
    286   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
    287 	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
    288   ""
    289   "cvtbw %1,%0")
    290 
    291 (define_insn "extendqisi2"
    292   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    293 	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
    294   ""
    295   "cvtbl %1,%0")
    296 
    297 (define_insn "extendsfdf2"
    298   [(set (match_operand:DF 0 "nonimmediate_operand" "=g")
    299 	(float_extend:DF (match_operand:SF 1 "general_operand" "gF")))]
    300   ""
    301   "cvtf%# %1,%0")
    302 
    303 (define_insn "truncdfsf2"
    304   [(set (match_operand:SF 0 "nonimmediate_operand" "=g")
    305 	(float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))]
    306   ""
    307   "cvt%#f %1,%0")
    308 
    309 (define_insn "zero_extendhisi2"
    310   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    311 	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
    312   ""
    313   "movzwl %1,%0")
    314 
    315 (define_insn "zero_extendqihi2"
    316   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
    317 	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
    318   ""
    319   "movzbw %1,%0")
    320 
    321 (define_insn "zero_extendqisi2"
    322   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    323 	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
    324   ""
    325   "movzbl %1,%0")
    326 
    328 ;; Fix-to-float conversion insns.
    329 
    330 (define_insn "float<VAXint:mode><VAXfp:mode>2"
    331   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
    332 	(float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))]
    333   ""
    334   "cvt<VAXint:isfx><VAXfp:fsfx> %1,%0")
    335 
    336 ;; Float-to-fix conversion insns.
    337 
    338 (define_insn "fix_trunc<VAXfp:mode><VAXint:mode>2"
    339   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
    340 	(fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))]
    341   ""
    342   "cvt<VAXfp:fsfx><VAXint:isfx> %1,%0")
    343 
    344 (define_expand "fixuns_trunc<VAXfp:mode><VAXint:mode>2"
    345   [(set (match_operand:VAXint 0 "nonimmediate_operand" "")
    346 	(fix:VAXint (match_operand:VAXfp 1 "general_operand")))]
    347   "")
    348 
    350 ;;- All kinds of add instructions.
    351 
    352 (define_insn "add<mode>3"
    353   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
    354 	(plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
    355 		    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
    356   ""
    357   "@
    358    add<VAXfp:fsfx>2 %2,%0
    359    add<VAXfp:fsfx>2 %1,%0
    360    add<VAXfp:fsfx>3 %1,%2,%0")
    361 
    362 (define_insn "pushlclsymreg"
    363   [(set (match_operand:SI 0 "push_operand" "=g")
    364 	(plus:SI (match_operand:SI 1 "register_operand" "%r")
    365 		 (match_operand:SI 2 "local_symbolic_operand" "i")))]
    366   "flag_pic"
    367   "pushab %a2[%1]")
    368 
    369 (define_insn "pushextsymreg"
    370   [(set (match_operand:SI 0 "push_operand" "=g")
    371 	(plus:SI (match_operand:SI 1 "register_operand" "%r")
    372 		 (match_operand:SI 2 "external_symbolic_operand" "i")))]
    373   "flag_pic"
    374   "pushab %a2[%1]")
    375 
    376 (define_insn "movlclsymreg"
    377   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    378 	(plus:SI (match_operand:SI 1 "register_operand" "%r")
    379 		 (match_operand:SI 2 "local_symbolic_operand" "i")))]
    380   "flag_pic"
    381   "movab %a2[%1],%0")
    382 
    383 (define_insn "movextsymreg"
    384   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    385 	(plus:SI (match_operand:SI 1 "register_operand" "%r")
    386 		 (match_operand:SI 2 "external_symbolic_operand" "i")))]
    387   "flag_pic"
    388   "movab %a2[%1],%0")
    389 
    390 (define_insn "add<mode>3"
    391   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
    392 	(plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")
    393 		     (match_operand:VAXint 2 "general_operand" "nrmT")))]
    394   ""
    395   "* return vax_output_int_add (insn, operands, <MODE>mode);")
    396 
    397 (define_expand "adddi3"
    398   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
    399 	(plus:DI (match_operand:DI 1 "general_operand" "g")
    400 		 (match_operand:DI 2 "general_operand" "g")))]
    401   "!reload_in_progress"
    402   "vax_expand_addsub_di_operands (operands, PLUS); DONE;")
    403 
    404 (define_insn "adcdi3"
    405   [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr")
    406 	(plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0")
    407 		 (match_operand:DI 2 "general_addsub_di_operand" "nRr")))]
    408   "TARGET_QMATH"
    409   "* return vax_output_int_add (insn, operands, DImode);")
    410 
    411 ;; The add-with-carry (adwc) instruction only accepts two operands.
    412 (define_insn "adddi3_old"
    413   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>")
    414 	(plus:DI (match_operand:DI 1 "general_operand" "%0,ro>")
    415 		 (match_operand:DI 2 "general_operand" "Fsro,Fs")))]
    416   "!TARGET_QMATH"
    417   "* return vax_output_int_add (insn, operands, DImode);")
    418 
    420 ;;- All kinds of subtract instructions.
    421 
    422 (define_insn "sub<mode>3"
    423   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
    424 	(minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
    425 		     (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
    426   ""
    427   "@
    428    sub<VAXfp:fsfx>2 %2,%0
    429    sub<VAXfp:fsfx>3 %2,%1,%0")
    430 
    431 (define_insn "sub<mode>3"
    432   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
    433 	(minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
    434 		      (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
    435   ""
    436   "@
    437    sub<VAXint:isfx>2 %2,%0
    438    sub<VAXint:isfx>3 %2,%1,%0")
    439 
    440 (define_expand "subdi3"
    441   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
    442 	(minus:DI (match_operand:DI 1 "general_operand" "g")
    443 		  (match_operand:DI 2 "general_operand" "g")))]
    444   "!reload_in_progress"
    445   "vax_expand_addsub_di_operands (operands, MINUS); DONE;")
    446 
    447 (define_insn "sbcdi3"
    448   [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=&Rr,&Rr")
    449 	(minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I")
    450 		  (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))]
    451   "TARGET_QMATH"
    452   "* return vax_output_int_subtract (insn, operands, DImode);")
    453 
    454 ;; The subtract-with-carry (sbwc) instruction only takes two operands.
    455 (define_insn "subdi3_old"
    456   [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>")
    457 	(minus:DI (match_operand:DI 1 "general_operand" "0,or>")
    458 		  (match_operand:DI 2 "general_operand" "Fsor,Fs")))]
    459   "!TARGET_QMATH"
    460   "* return vax_output_int_subtract (insn, operands, DImode);")
    461 
    463 ;;- Multiply instructions.
    464 
    465 (define_insn "mul<mode>3"
    466   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
    467 	(mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
    468 		    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
    469   ""
    470   "@
    471    mul<VAXfp:fsfx>2 %2,%0
    472    mul<VAXfp:fsfx>2 %1,%0
    473    mul<VAXfp:fsfx>3 %1,%2,%0")
    474 
    475 (define_insn "mul<mode>3"
    476   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
    477 	(mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
    478 		     (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
    479   ""
    480   "@
    481    mul<VAXint:isfx>2 %2,%0
    482    mul<VAXint:isfx>2 %1,%0
    483    mul<VAXint:isfx>3 %1,%2,%0")
    484 
    485 (define_insn "mulsidi3"
    486   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
    487 	(mult:DI (sign_extend:DI
    488 		  (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
    489 		 (sign_extend:DI
    490 		  (match_operand:SI 2 "nonimmediate_operand" "nrmT"))))]
    491   ""
    492   "emul %1,%2,$0,%0")
    493 
    494 (define_insn ""
    495   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
    496 	(plus:DI
    497 	 (mult:DI (sign_extend:DI
    498 		   (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
    499 		  (sign_extend:DI
    500 		   (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
    501 	 (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))]
    502   ""
    503   "emul %1,%2,%3,%0")
    504 
    505 ;; 'F' constraint means type CONST_DOUBLE
    506 (define_insn ""
    507   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
    508 	(plus:DI
    509 	 (mult:DI (sign_extend:DI
    510 		   (match_operand:SI 1 "nonimmediate_operand" "nrmT"))
    511 		  (sign_extend:DI
    512 		   (match_operand:SI 2 "nonimmediate_operand" "nrmT")))
    513 	 (match_operand:DI 3 "immediate_operand" "F")))]
    514   "GET_CODE (operands[3]) == CONST_DOUBLE
    515     && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)"
    516   "*
    517 {
    518   if (CONST_DOUBLE_HIGH (operands[3]))
    519     operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[3]));
    520   return \"emul %1,%2,%3,%0\";
    521 }")
    522 
    524 ;;- Divide instructions.
    525 
    526 (define_insn "div<mode>3"
    527   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
    528 	(div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
    529 		   (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
    530   ""
    531   "@
    532    div<VAXfp:fsfx>2 %2,%0
    533    div<VAXfp:fsfx>3 %2,%1,%0")
    534 
    535 (define_insn "div<mode>3"
    536   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
    537 	(div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
    538 		    (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
    539   ""
    540   "@
    541    div<VAXint:isfx>2 %2,%0
    542    div<VAXint:isfx>3 %2,%1,%0")
    543 
    544 ;This is left out because it is very slow;
    545 ;we are better off programming around the "lack" of this insn.
    546 ;(define_insn "divmoddisi4"
    547 ;  [(set (match_operand:SI 0 "general_operand" "=g")
    548 ;	(div:SI (match_operand:DI 1 "general_operand" "g")
    549 ;		(match_operand:SI 2 "general_operand" "g")))
    550 ;   (set (match_operand:SI 3 "general_operand" "=g")
    551 ;	(mod:SI (match_operand:DI 1 "general_operand" "g")
    552 ;		(match_operand:SI 2 "general_operand" "g")))]
    553 ;  ""
    554 ;  "ediv %2,%1,%0,%3")
    555 
    557 ;; Bit-and on the VAX is done with a clear-bits insn.
    558 (define_expand "and<mode>3"
    559   [(set (match_operand:VAXint 0 "nonimmediate_operand" "")
    560 	(and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" ""))
    561 		    (match_operand:VAXint 2 "general_operand" "")))]
    562   ""
    563   "
    564 {
    565   rtx op1 = operands[1];
    566 
    567   /* If there is a constant argument, complement that one.  */
    568   if (CONST_INT_P (operands[2]) && ! CONST_INT_P (op1))
    569     {
    570       operands[1] = operands[2];
    571       operands[2] = op1;
    572       op1 = operands[1];
    573     }
    574 
    575   if (CONST_INT_P (op1))
    576     operands[1] = GEN_INT (~INTVAL (op1));
    577   else
    578     operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1);
    579 }")
    580 
    581 (define_insn "*and<mode>"
    582   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
    583 	(and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
    584 		    (match_operand:VAXint 2 "general_operand" "0,nrmT")))]
    585   ""
    586   "@
    587    bic<VAXint:isfx>2 %1,%0
    588    bic<VAXint:isfx>3 %1,%2,%0")
    589 
    590 ;; The following used to be needed because constant propagation can
    591 ;; create them starting from the bic insn patterns above.  This is no
    592 ;; longer a problem.  However, having these patterns allows optimization
    593 ;; opportunities in combine.c.
    594 
    595 (define_insn "*and<mode>_const_int"
    596   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
    597 	(and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
    598 		    (match_operand:VAXint 2 "const_int_operand" "n,n")))]
    599   ""
    600   "@
    601    bic<VAXint:isfx>2 %<VAXint:iprefx>2,%0
    602    bic<VAXint:isfx>3 %<VAXint:iprefx>2,%1,%0")
    603 
    604 
    606 ;;- Bit set instructions.
    607 
    608 (define_insn "ior<mode>3"
    609   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
    610 	(ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
    611 		    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
    612   ""
    613   "@
    614    bis<VAXint:isfx>2 %2,%0
    615    bis<VAXint:isfx>2 %1,%0
    616    bis<VAXint:isfx>3 %2,%1,%0")
    617 
    618 ;;- xor instructions.
    619 
    620 (define_insn "xor<mode>3"
    621   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
    622 	(xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
    623 		    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
    624   ""
    625   "@
    626    xor<VAXint:isfx>2 %2,%0
    627    xor<VAXint:isfx>2 %1,%0
    628    xor<VAXint:isfx>3 %2,%1,%0")
    629 
    630 
    632 (define_insn "neg<mode>2"
    633   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
    634 	(neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))]
    635   ""
    636   "mneg<VAXfp:fsfx> %1,%0")
    637 
    638 (define_insn "neg<mode>2"
    639   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
    640 	(neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
    641   ""
    642   "mneg<VAXint:isfx> %1,%0")
    643 
    644 (define_insn "one_cmpl<mode>2"
    645   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
    646 	(not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
    647   ""
    648   "mcom<VAXint:isfx> %1,%0")
    649 
    650 
    652 ;; Arithmetic right shift on the VAX works by negating the shift count,
    653 ;; then emitting a right shift with the shift count negated.  This means
    654 ;; that all actual shift counts in the RTL will be positive.  This
    655 ;; prevents converting shifts to ZERO_EXTRACTs with negative positions,
    656 ;; which isn't valid.
    657 (define_expand "ashrsi3"
    658   [(set (match_operand:SI 0 "general_operand" "=g")
    659 	(ashiftrt:SI (match_operand:SI 1 "general_operand" "g")
    660 		     (match_operand:QI 2 "general_operand" "g")))]
    661   ""
    662   "
    663 {
    664   if (! CONST_INT_P (operands[2]))
    665     operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
    666 }")
    667 
    668 (define_insn ""
    669   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    670 	(ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
    671 		     (match_operand:QI 2 "const_int_operand" "n")))]
    672   ""
    673   "ashl $%n2,%1,%0")
    674 
    675 (define_insn ""
    676   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    677 	(ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
    678 		     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
    679   ""
    680   "ashl %2,%1,%0")
    681 
    682 (define_insn "ashlsi3"
    683   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    684 	(ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
    685 		   (match_operand:QI 2 "general_operand" "g")))]
    686   ""
    687   "*
    688 {
    689   if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1]))
    690     return \"addl2 %0,%0\";
    691   if (REG_P (operands[1]) && CONST_INT_P (operands[2]))
    692     {
    693       int i = INTVAL (operands[2]);
    694       if (i == 1)
    695 	return \"addl3 %1,%1,%0\";
    696       if (i == 2 && !optimize_size)
    697 	{
    698 	  if (push_operand (operands[0], SImode))
    699 	    return \"pushal 0[%1]\";
    700 	  return \"moval 0[%1],%0\";
    701 	}
    702       if (i == 3 && !optimize_size)
    703 	{
    704 	  if (push_operand (operands[0], SImode))
    705 	    return \"pushaq 0[%1]\";
    706 	  return \"movaq 0[%1],%0\";
    707 	}
    708     }
    709   return \"ashl %2,%1,%0\";
    710 }")
    711 
    712 ;; Arithmetic right shift on the VAX works by negating the shift count.
    713 (define_expand "ashrdi3"
    714   [(set (match_operand:DI 0 "general_operand" "=g")
    715 	(ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
    716 		     (match_operand:QI 2 "general_operand" "g")))]
    717   ""
    718   "
    719 {
    720   operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
    721 }")
    722 
    723 (define_insn "ashldi3"
    724   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
    725 	(ashift:DI (match_operand:DI 1 "general_operand" "g")
    726 		   (match_operand:QI 2 "general_operand" "g")))]
    727   ""
    728   "ashq %2,%D1,%0")
    729 
    730 (define_insn ""
    731   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
    732 	(ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
    733 		     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
    734   ""
    735   "ashq %2,%D1,%0")
    736 
    737 ;; We used to have expand_shift handle logical right shifts by using extzv,
    738 ;; but this make it very difficult to do lshrdi3.  Since the VAX is the
    739 ;; only machine with this kludge, it's better to just do this with a
    740 ;; define_expand and remove that case from expand_shift.
    741 
    742 (define_expand "lshrsi3"
    743   [(set (match_dup 3)
    744 	(minus:QI (const_int 32)
    745 		  (match_dup 4)))
    746    (set (match_operand:SI 0 "nonimmediate_operand" "=g")
    747 	(zero_extract:SI (match_operand:SI 1 "general_operand" "g")
    748 			 (match_dup 3)
    749 			 (match_operand:SI 2 "register_operand" "g")))]
    750   ""
    751   "
    752 {
    753   operands[3] = gen_reg_rtx (QImode);
    754   operands[4] = gen_lowpart (QImode, operands[2]);
    755   operands[4] = gen_rtx_MINUS (QImode, GEN_INT (32), operands[4]);
    756   emit_move_insn (operands[3], operands[4]);
    757   emit_insn (gen_extzv (operands[0], operands[1], operands[3], operands[2]));
    758   DONE;
    759 }")
    760 
    761 ;; Rotate right on the VAX works by negating the shift count.
    762 (define_expand "rotrsi3"
    763   [(set (match_operand:SI 0 "general_operand" "=g")
    764 	(rotatert:SI (match_operand:SI 1 "general_operand" "g")
    765 		     (match_operand:QI 2 "general_operand" "g")))]
    766   ""
    767   "
    768 {
    769   if (! CONST_INT_P (operands[2]))
    770     operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
    771 }")
    772 
    773 (define_insn "rotlsi3"
    774   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    775 	(rotate:SI (match_operand:SI 1 "general_operand" "nrmT")
    776 		   (match_operand:QI 2 "general_operand" "g")))]
    777   ""
    778   "rotl %2,%1,%0")
    779 
    780 (define_insn ""
    781   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    782 	(rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
    783 		     (match_operand:QI 2 "const_int_operand" "n")))]
    784   ""
    785   "rotl %R2,%1,%0")
    786 
    787 (define_insn ""
    788   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    789 	(rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
    790 		     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
    791   ""
    792   "rotl %2,%1,%0")
    793 
    794 ;This insn is probably slower than a multiply and an add.
    795 ;(define_insn ""
    796 ;  [(set (match_operand:SI 0 "general_operand" "=g")
    797 ;	(mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
    798 ;			  (match_operand:SI 2 "general_operand" "g"))
    799 ;		 (match_operand:SI 3 "general_operand" "g")))]
    800 ;  ""
    801 ;  "index %1,$0x80000000,$0x7fffffff,%3,%2,%0")
    802 
    804 ;; Special cases of bit-field insns which we should
    805 ;; recognize in preference to the general case.
    806 ;; These handle aligned 8-bit and 16-bit fields,
    807 ;; which can usually be done with move instructions.
    808 
    809 ;; netbsd changed this to REG_P (operands[0]) || (MEM_P (operands[0]) && ...
    810 ;; but gcc made it just !MEM_P (operands[0]) || ...
    811 
    812 (define_insn ""
    813   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro")
    814 			 (match_operand:QI 1 "const_int_operand" "n")
    815 			 (match_operand:SI 2 "const_int_operand" "n"))
    816 	(match_operand:SI 3 "general_operand" "g"))]
    817    "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
    818    && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
    819    && (REG_P (operands[0])
    820        || (MEM_P (operands[0])
    821           && ! mode_dependent_address_p (XEXP (operands[0], 0),
    822 				       MEM_ADDR_SPACE (operands[0]))))"
    823   "*
    824 {
    825   if (REG_P (operands[0]))
    826     {
    827       if (INTVAL (operands[2]) != 0)
    828 	return \"insv %3,%2,%1,%0\";
    829     }
    830   else
    831     operands[0]
    832       = adjust_address (operands[0],
    833 			INTVAL (operands[1]) == 8 ? QImode : HImode,
    834 			INTVAL (operands[2]) / 8);
    835 
    836   CC_STATUS_INIT;
    837   if (INTVAL (operands[1]) == 8)
    838     return \"movb %3,%0\";
    839   return \"movw %3,%0\";
    840 }")
    841 
    842 (define_insn ""
    843   [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
    844 	(zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
    845 			 (match_operand:QI 2 "const_int_operand" "n")
    846 			 (match_operand:SI 3 "const_int_operand" "n")))]
    847   "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
    848    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
    849    && (REG_P (operands[1])
    850        || (MEM_P (operands[1])
    851           && ! mode_dependent_address_p (XEXP (operands[1], 0),
    852 				      MEM_ADDR_SPACE (operands[1]))))"
    853   "*
    854 {
    855   if (REG_P (operands[1]))
    856     {
    857       if (INTVAL (operands[3]) != 0)
    858 	return \"extzv %3,%2,%1,%0\";
    859     }
    860   else
    861     operands[1]
    862       = adjust_address (operands[1],
    863 			INTVAL (operands[2]) == 8 ? QImode : HImode,
    864 			INTVAL (operands[3]) / 8);
    865 
    866   if (INTVAL (operands[2]) == 8)
    867     return \"movzbl %1,%0\";
    868   return \"movzwl %1,%0\";
    869 }")
    870 
    871 (define_insn ""
    872   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    873 	(sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
    874 			 (match_operand:QI 2 "const_int_operand" "n")
    875 			 (match_operand:SI 3 "const_int_operand" "n")))]
    876   "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
    877    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
    878    && (REG_P (operands[1])
    879        || (MEM_P (operands[1])
    880           && ! mode_dependent_address_p (XEXP (operands[1], 0),
    881 				      MEM_ADDR_SPACE (operands[1]))))"
    882   "*
    883 {
    884   if (REG_P (operands[1]))
    885     {
    886       if (INTVAL (operands[3]) != 0)
    887 	return \"extv %3,%2,%1,%0\";
    888     }
    889   else
    890     operands[1]
    891       = adjust_address (operands[1],
    892 			INTVAL (operands[2]) == 8 ? QImode : HImode,
    893 			INTVAL (operands[3]) / 8);
    894 
    895   if (INTVAL (operands[2]) == 8)
    896     return \"cvtbl %1,%0\";
    897   return \"cvtwl %1,%0\";
    898 }")
    899 
    901 ;; Register-only SImode cases of bit-field insns.
    902 
    903 (define_insn ""
    904   [(set (cc0)
    905 	(compare
    906 	 (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
    907 			  (match_operand:QI 1 "general_operand" "g")
    908 			  (match_operand:SI 2 "general_operand" "nrmT"))
    909 	 (match_operand:SI 3 "general_operand" "nrmT")))]
    910   ""
    911   "cmpv %2,%1,%0,%3")
    912 
    913 (define_insn ""
    914   [(set (cc0)
    915 	(compare
    916 	 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
    917 			  (match_operand:QI 1 "general_operand" "g")
    918 			  (match_operand:SI 2 "general_operand" "nrmT"))
    919 	 (match_operand:SI 3 "general_operand" "nrmT")))]
    920   ""
    921   "cmpzv %2,%1,%0,%3")
    922 
    923 ;; When the field position and size are constant and the destination
    924 ;; is a register, extv and extzv are much slower than a rotate followed
    925 ;; by a bicl or sign extension.  Because we might end up choosing ext[z]v
    926 ;; anyway, we can't allow immediate values for the primary source operand.
    927 
    928 (define_insn ""
    929   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    930 	(sign_extract:SI (match_operand:SI 1 "register_operand" "ro")
    931 			 (match_operand:QI 2 "general_operand" "g")
    932 			 (match_operand:SI 3 "general_operand" "nrmT")))]
    933   ""
    934   "*
    935 {
    936   if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
    937       || ! REG_P (operands[0])
    938       || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16))
    939     return \"extv %3,%2,%1,%0\";
    940   if (INTVAL (operands[2]) == 8)
    941     return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
    942   return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
    943 }")
    944 
    945 (define_insn ""
    946   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
    947 	(zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
    948 			 (match_operand:QI 2 "general_operand" "g")
    949 			 (match_operand:SI 3 "general_operand" "nrmT")))]
    950   ""
    951   "*
    952 {
    953   if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
    954       || ! REG_P (operands[0]))
    955     return \"extzv %3,%2,%1,%0\";
    956   if (INTVAL (operands[2]) == 8)
    957     return \"rotl %R3,%1,%0\;movzbl %0,%0\";
    958   if (INTVAL (operands[2]) == 16)
    959     return \"rotl %R3,%1,%0\;movzwl %0,%0\";
    960   if (INTVAL (operands[3]) & 31)
    961     return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
    962   if (rtx_equal_p (operands[0], operands[1]))
    963     {
    964       if (INTVAL (operands[2]) == 32)
    965 	return \"\";  /* no-op */
    966       else
    967 	return \"bicl2 %M2,%0\";
    968     }
    969   if (INTVAL (operands[2]) == 32)
    970     return \"movl %1,%0\";
    971   return \"bicl3 %M2,%1,%0\";
    972 }")
    973 
    974 ;; Non-register cases.
    975 ;; nonimmediate_operand is used to make sure that mode-ambiguous cases
    976 ;; don't match these (and therefore match the cases above instead).
    977 
    978 (define_insn ""
    979   [(set (cc0)
    980 	(compare
    981 	 (sign_extract:SI (match_operand:QI 0 "memory_operand" "m")
    982 			  (match_operand:QI 1 "general_operand" "g")
    983 			  (match_operand:SI 2 "general_operand" "nrmT"))
    984 	 (match_operand:SI 3 "general_operand" "nrmT")))]
    985   ""
    986   "cmpv %2,%1,%0,%3")
    987 
    988 (define_insn ""
    989   [(set (cc0)
    990 	(compare
    991 	 (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm")
    992 			  (match_operand:QI 1 "general_operand" "g")
    993 			  (match_operand:SI 2 "general_operand" "nrmT"))
    994 	 (match_operand:SI 3 "general_operand" "nrmT")))]
    995   ""
    996   "cmpzv %2,%1,%0,%3")
    997 
    998 (define_expand "extv"
    999   [(set (match_operand:SI 0 "general_operand" "")
   1000 	(sign_extract:SI (match_dup 4)
   1001 			 (match_operand:QI 2 "general_operand" "")
   1002 			 (match_operand:SI 3 "general_operand" ""))
   1003    )]
   1004   ""
   1005   "{
   1006       /*
   1007        * If the source operand is a memory reference, and the address
   1008        * is a symbol, and we're in PIC mode, load the address into a
   1009        * register.  Don't evaluate the field start or width at this time.
   1010        */
   1011       operands[4] = operands[1];
   1012       if (flag_pic
   1013        /* && !reload_completed */
   1014 	  && MEM_P (operands[1])
   1015 	  && !mode_dependent_address_p (XEXP (operands[1], 0),
   1016 					MEM_ADDR_SPACE (operands[1]))
   1017           && SYMBOL_REF_P (XEXP (operands[1], 0))
   1018 	  && !SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0))
   1019 	 )
   1020 	{
   1021 	  rtx address = XEXP (operands[1], 0);
   1022 	  rtx temp = gen_reg_rtx (Pmode);
   1023 	  emit_move_insn (temp, address);
   1024 	  /* copy the original memory reference, replacing the address */
   1025 	  operands[4] = change_address (operands[1], VOIDmode, temp);
   1026 	  set_mem_align (operands[4], MEM_ALIGN (operands[1]));
   1027 	}
   1028   }"
   1029 )
   1030 
   1031 (define_insn ""
   1032   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
   1033 	(sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
   1034 			 (match_operand:QI 2 "general_operand" "g")
   1035 			 (match_operand:SI 3 "general_operand" "nrmT")))]
   1036   ""
   1037   "*
   1038 {
   1039   if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
   1040       || ! CONST_INT_P (operands[3])
   1041       || (INTVAL (operands[2]) != 8 && INTVAL (operands[2]) != 16)
   1042       || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
   1043       || side_effects_p (operands[1])
   1044       || (MEM_P (operands[1])
   1045 	  && mode_dependent_address_p (XEXP (operands[1], 0),
   1046 				       MEM_ADDR_SPACE (operands[1]))))
   1047     return \"extv %3,%2,%1,%0\";
   1048   if (INTVAL (operands[2]) == 8)
   1049     return \"rotl %R3,%1,%0\;cvtbl %0,%0\";
   1050   return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
   1051 }")
   1052 
   1053 (define_expand "extzv"
   1054   [(set (match_operand:SI 0 "general_operand" "")
   1055 	(zero_extract:SI (match_operand:SI 1 "general_operand" "")
   1056 			 (match_operand:QI 2 "general_operand" "")
   1057 			 (match_operand:SI 3 "general_operand" "")))]
   1058   ""
   1059   "")
   1060 
   1061 (define_insn ""
   1062   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
   1063 	(zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
   1064 			 (match_operand:QI 2 "general_operand" "g")
   1065 			 (match_operand:SI 3 "general_operand" "nrmT")))]
   1066   ""
   1067   "*
   1068 {
   1069   if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
   1070       || ! CONST_INT_P (operands[3])
   1071       || INTVAL (operands[2]) + INTVAL (operands[3]) > 32
   1072       || side_effects_p (operands[1])
   1073       || (MEM_P (operands[1])
   1074 	  && mode_dependent_address_p (XEXP (operands[1], 0),
   1075 				       MEM_ADDR_SPACE (operands[1]))))
   1076     return \"extzv %3,%2,%1,%0\";
   1077   if (INTVAL (operands[2]) == 8)
   1078     return \"rotl %R3,%1,%0\;movzbl %0,%0\";
   1079   if (INTVAL (operands[2]) == 16)
   1080     return \"rotl %R3,%1,%0\;movzwl %0,%0\";
   1081   if (MEM_P (operands[1])
   1082       && GET_CODE (XEXP (operands[1], 0)) == PLUS
   1083       && REG_P (XEXP (XEXP (operands[1], 0), 0))
   1084       && CONST_INT_P (XEXP (XEXP (operands[1], 0), 1))
   1085       && CONST_INT_P (operands[2])
   1086       && CONST_INT_P (operands[3]))
   1087     {
   1088       HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[1], 0), 1));
   1089       HOST_WIDE_INT l = INTVAL (operands[2]);
   1090       HOST_WIDE_INT v = INTVAL (operands[3]);
   1091       if ((o & 3) && (o & 3) * 8 + v + l <= 32)
   1092 	{
   1093 	  rtx tmp;
   1094 	  tmp = XEXP (XEXP (operands[1], 0), 0);
   1095 	  if (o & ~3)
   1096 	    tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
   1097 	  operands[1] = gen_rtx_MEM (QImode, tmp);
   1098 	  operands[3] = GEN_INT (v + (o & 3) * 8);
   1099 	}
   1100       if (optimize_size)
   1101 	return \"extzv %3,%2,%1,%0\";
   1102     }
   1103   return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
   1104 }")
   1105 
   1106 (define_expand "insv"
   1107   [(set (zero_extract:SI (match_dup 4)
   1108 			 (match_operand:QI 1 "general_operand" "")
   1109 			 (match_operand:SI 2 "general_operand" ""))
   1110 	(match_operand:SI 3 "general_operand" ""))]
   1111   ""
   1112   "{
   1113     /*
   1114      * If the destination operand is a memory reference, and the address
   1115      * is a symbol, and we're in PIC mode, load the address into a
   1116      * register.  Don't evaluate the field start or width at this time.
   1117      */
   1118     operands[4] = operands[0];
   1119     if (flag_pic
   1120      /*	&& !reload_completed */
   1121 	&& MEM_P (operands[0])
   1122 	&& !mode_dependent_address_p (XEXP (operands[0], 0),
   1123 				       MEM_ADDR_SPACE (operands[0]))
   1124 	&& SYMBOL_REF_P (XEXP (operands[0], 0))
   1125 	&& !SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0))
   1126        )
   1127       {
   1128 	rtx address = XEXP (operands[0], 0);
   1129 	rtx temp = gen_reg_rtx (Pmode);
   1130 	emit_move_insn (temp, address);
   1131 	/* copy the original memory reference, replacing the address */
   1132 	operands[4] = change_address (operands[0], VOIDmode, temp);
   1133 	set_mem_align (operands[4], MEM_ALIGN (operands[0]));
   1134       }
   1135 
   1136   }")
   1137 
   1138 (define_insn ""
   1139   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g")
   1140 			 (match_operand:QI 1 "general_operand" "g")
   1141 			 (match_operand:SI 2 "general_operand" "nrmT"))
   1142 	(match_operand:SI 3 "general_operand" "nrmT"))]
   1143   ""
   1144   "*
   1145 {
   1146   if (MEM_P (operands[0])
   1147       && GET_CODE (XEXP (operands[0], 0)) == PLUS
   1148       && REG_P (XEXP (XEXP (operands[0], 0), 0))
   1149       && CONST_INT_P (XEXP (XEXP (operands[0], 0), 1))
   1150       && CONST_INT_P (operands[1])
   1151       && CONST_INT_P (operands[2]))
   1152     {
   1153       HOST_WIDE_INT o = INTVAL (XEXP (XEXP (operands[0], 0), 1));
   1154       HOST_WIDE_INT v = INTVAL (operands[2]);
   1155       HOST_WIDE_INT l = INTVAL (operands[1]);
   1156       if ((o & 3) && (o & 3) * 8 + v + l <= 32)
   1157 	{
   1158 	  rtx tmp;
   1159 	  tmp = XEXP (XEXP (operands[0], 0), 0);
   1160 	  if (o & ~3)
   1161 	    tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (o & ~3));
   1162 	  operands[0] = gen_rtx_MEM (QImode, tmp);
   1163 	  operands[2] = GEN_INT (v + (o & 3) * 8);
   1164 	}
   1165     }
   1166   return \"insv %3,%2,%1,%0\";
   1167 }")
   1168 
   1169 (define_insn ""
   1170   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
   1171 			 (match_operand:QI 1 "general_operand" "g")
   1172 			 (match_operand:SI 2 "general_operand" "nrmT"))
   1173 	(match_operand:SI 3 "general_operand" "nrmT"))]
   1174   ""
   1175   "insv %3,%2,%1,%0")
   1176 
   1178 ;; Unconditional jump
   1179 (define_insn "jump"
   1180   [(set (pc)
   1181 	(label_ref (match_operand 0 "" "")))]
   1182   ""
   1183   "jbr %l0")
   1184 
   1185 ;; Conditional jumps
   1186 
   1187 (define_expand "cbranch<mode>4"
   1188   [(set (cc0)
   1189         (compare (match_operand:VAXint 1 "nonimmediate_operand" "")
   1190                  (match_operand:VAXint 2 "general_operand" "")))
   1191    (set (pc)
   1192         (if_then_else
   1193               (match_operator 0 "ordered_comparison_operator" [(cc0)
   1194                                                                (const_int 0)])
   1195               (label_ref (match_operand 3 "" ""))
   1196               (pc)))]
   1197  "")
   1198 
   1199 (define_expand "cbranch<mode>4"
   1200   [(set (cc0)
   1201         (compare (match_operand:VAXfp 1 "general_operand" "")
   1202                  (match_operand:VAXfp 2 "general_operand" "")))
   1203    (set (pc)
   1204         (if_then_else
   1205               (match_operator 0 "ordered_comparison_operator" [(cc0)
   1206                                                                (const_int 0)])
   1207               (label_ref (match_operand 3 "" ""))
   1208               (pc)))]
   1209  "")
   1210 
   1211 (define_insn "*branch"
   1212   [(set (pc)
   1213 	(if_then_else (match_operator 0 "ordered_comparison_operator"
   1214 				      [(cc0)
   1215 				       (const_int 0)])
   1216 		      (label_ref (match_operand 1 "" ""))
   1217 		      (pc)))]
   1218   ""
   1219   "j%c0 %l1")
   1220 
   1221 ;; Recognize reversed jumps.
   1222 (define_insn "*branch_reversed"
   1223   [(set (pc)
   1224 	(if_then_else (match_operator 0 "ordered_comparison_operator"
   1225 				      [(cc0)
   1226 				       (const_int 0)])
   1227 		      (pc)
   1228 		      (label_ref (match_operand 1 "" ""))))]
   1229   ""
   1230   "j%C0 %l1") ; %C0 negates condition
   1231 
   1233 ;; Recognize jbs, jlbs, jbc and jlbc instructions.  Note that the operand
   1234 ;; of jlbs and jlbc insns are SImode in the hardware.  However, if it is
   1235 ;; memory, we use QImode in the insn.  So we can't use those instructions
   1236 ;; for mode-dependent addresses.
   1237 
   1238 (define_insn ""
   1239   [(set (pc)
   1240 	(if_then_else
   1241 	 (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
   1242 			      (const_int 1)
   1243 			      (match_operand:SI 1 "general_operand" "I,nrmT"))
   1244 	     (const_int 0))
   1245 	 (label_ref (match_operand 2 "" ""))
   1246 	 (pc)))]
   1247   ""
   1248   "@
   1249    jlbs %0,%l2
   1250    jbs %1,%0,%l2")
   1251 
   1252 (define_insn ""
   1253   [(set (pc)
   1254 	(if_then_else
   1255 	 (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
   1256 			      (const_int 1)
   1257 			      (match_operand:SI 1 "general_operand" "I,nrmT"))
   1258 	     (const_int 0))
   1259 	 (label_ref (match_operand 2 "" ""))
   1260 	 (pc)))]
   1261   ""
   1262   "@
   1263    jlbc %0,%l2
   1264    jbc %1,%0,%l2")
   1265 
   1266 (define_insn ""
   1267   [(set (pc)
   1268 	(if_then_else
   1269 	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
   1270 			      (const_int 1)
   1271 			      (match_operand:SI 1 "general_operand" "I,nrmT"))
   1272 	     (const_int 0))
   1273 	 (label_ref (match_operand 2 "" ""))
   1274 	 (pc)))]
   1275   ""
   1276   "@
   1277    jlbs %0,%l2
   1278    jbs %1,%0,%l2")
   1279 
   1280 (define_insn ""
   1281   [(set (pc)
   1282 	(if_then_else
   1283 	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r")
   1284 			      (const_int 1)
   1285 			      (match_operand:SI 1 "general_operand" "I,nrmT"))
   1286 	     (const_int 0))
   1287 	 (label_ref (match_operand 2 "" ""))
   1288 	 (pc)))]
   1289   ""
   1290   "@
   1291    jlbc %0,%l2
   1292    jbc %1,%0,%l2")
   1293 
   1295 ;; Subtract-and-jump and Add-and-jump insns.
   1296 ;; These are not used when output is for the Unix assembler
   1297 ;; because it does not know how to modify them to reach far.
   1298 
   1299 ;; Normal sob insns.
   1300 
   1301 (define_insn ""
   1302   [(set (pc)
   1303 	(if_then_else
   1304 	 (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
   1305 		      (const_int -1))
   1306 	     (const_int 0))
   1307 	 (label_ref (match_operand 1 "" ""))
   1308 	 (pc)))
   1309    (set (match_dup 0)
   1310 	(plus:SI (match_dup 0)
   1311 		 (const_int -1)))]
   1312   "!TARGET_UNIX_ASM"
   1313   "jsobgtr %0,%l1")
   1314 
   1315 (define_insn ""
   1316   [(set (pc)
   1317 	(if_then_else
   1318 	 (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
   1319 		      (const_int -1))
   1320 	     (const_int 0))
   1321 	 (label_ref (match_operand 1 "" ""))
   1322 	 (pc)))
   1323    (set (match_dup 0)
   1324 	(plus:SI (match_dup 0)
   1325 		 (const_int -1)))]
   1326   "!TARGET_UNIX_ASM"
   1327   "jsobgeq %0,%l1")
   1328 
   1329 ;; Normal aob insns.  Define a version for when operands[1] is a constant.
   1330 (define_insn ""
   1331   [(set (pc)
   1332 	(if_then_else
   1333 	 (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
   1334 		      (const_int 1))
   1335 	     (match_operand:SI 1 "general_operand" "nrmT"))
   1336 	 (label_ref (match_operand 2 "" ""))
   1337 	 (pc)))
   1338    (set (match_dup 0)
   1339 	(plus:SI (match_dup 0)
   1340 		 (const_int 1)))]
   1341   "!TARGET_UNIX_ASM"
   1342   "jaoblss %1,%0,%l2")
   1343 
   1344 (define_insn ""
   1345   [(set (pc)
   1346 	(if_then_else
   1347 	 (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
   1348 	     (match_operand:SI 1 "general_operand" "nrmT"))
   1349 	 (label_ref (match_operand 2 "" ""))
   1350 	 (pc)))
   1351    (set (match_dup 0)
   1352 	(plus:SI (match_dup 0)
   1353 		 (const_int 1)))]
   1354   "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
   1355   "jaoblss %P1,%0,%l2")
   1356 
   1357 (define_insn ""
   1358   [(set (pc)
   1359 	(if_then_else
   1360 	 (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
   1361 		      (const_int 1))
   1362 	     (match_operand:SI 1 "general_operand" "nrmT"))
   1363 	 (label_ref (match_operand 2 "" ""))
   1364 	 (pc)))
   1365    (set (match_dup 0)
   1366 	(plus:SI (match_dup 0)
   1367 		 (const_int 1)))]
   1368   "!TARGET_UNIX_ASM"
   1369   "jaobleq %1,%0,%l2")
   1370 
   1371 (define_insn ""
   1372   [(set (pc)
   1373 	(if_then_else
   1374 	 (le (match_operand:SI 0 "nonimmediate_operand" "+g")
   1375 	     (match_operand:SI 1 "general_operand" "nrmT"))
   1376 	 (label_ref (match_operand 2 "" ""))
   1377 	 (pc)))
   1378    (set (match_dup 0)
   1379 	(plus:SI (match_dup 0)
   1380 		 (const_int 1)))]
   1381   "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
   1382   "jaobleq %P1,%0,%l2")
   1383 
   1384 ;; Something like a sob insn, but compares against -1.
   1385 ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.
   1386 
   1387 (define_insn ""
   1388   [(set (pc)
   1389 	(if_then_else
   1390 	 (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
   1391 	     (const_int 0))
   1392 	 (label_ref (match_operand 1 "" ""))
   1393 	 (pc)))
   1394    (set (match_dup 0)
   1395 	(plus:SI (match_dup 0)
   1396 		 (const_int -1)))]
   1397   ""
   1398   "decl %0\;jgequ %l1")
   1399 
   1401 (define_expand "call_pop"
   1402   [(parallel [(call (match_operand:QI 0 "memory_operand" "")
   1403 		    (match_operand:SI 1 "const_int_operand" ""))
   1404 	      (set (reg:SI VAX_SP_REGNUM)
   1405 		   (plus:SI (reg:SI VAX_SP_REGNUM)
   1406 			    (match_operand:SI 3 "immediate_operand" "")))])]
   1407   ""
   1408 {
   1409   gcc_assert (INTVAL (operands[3]) <= 255 * 4 && INTVAL (operands[3]) % 4 == 0);
   1410 
   1411   /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
   1412      during EH unwinding.  We must include the argument count pushed by
   1413      the calls instruction.  */
   1414   operands[1] = GEN_INT (INTVAL (operands[3]) + 4);
   1415 })
   1416 
   1417 (define_insn "*call_pop"
   1418   [(call (match_operand:QI 0 "memory_operand" "m")
   1419 	 (match_operand:SI 1 "const_int_operand" "n"))
   1420    (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
   1421 					(match_operand:SI 2 "immediate_operand" "i")))]
   1422   ""
   1423 {
   1424   operands[1] = GEN_INT ((INTVAL (operands[1]) - 4) / 4);
   1425   return "calls %1,%0";
   1426 })
   1427 
   1428 (define_expand "call_value_pop"
   1429   [(parallel [(set (match_operand 0 "" "")
   1430 		   (call (match_operand:QI 1 "memory_operand" "")
   1431 			 (match_operand:SI 2 "const_int_operand" "")))
   1432 	      (set (reg:SI VAX_SP_REGNUM)
   1433 		   (plus:SI (reg:SI VAX_SP_REGNUM)
   1434 			    (match_operand:SI 4 "immediate_operand" "")))])]
   1435   ""
   1436 {
   1437   gcc_assert (INTVAL (operands[4]) <= 255 * 4 && INTVAL (operands[4]) % 4 == 0);
   1438 
   1439   /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
   1440      during EH unwinding.  We must include the argument count pushed by
   1441      the calls instruction.  */
   1442   operands[2] = GEN_INT (INTVAL (operands[4]) + 4);
   1443 })
   1444 
   1445 (define_insn "*call_value_pop"
   1446   [(set (match_operand 0 "" "")
   1447 	(call (match_operand:QI 1 "memory_operand" "m")
   1448 	      (match_operand:SI 2 "const_int_operand" "n")))
   1449    (set (reg:SI VAX_SP_REGNUM) (plus:SI (reg:SI VAX_SP_REGNUM)
   1450 					(match_operand:SI 3 "immediate_operand" "i")))]
   1451   ""
   1452   "*
   1453 {
   1454   operands[2] = GEN_INT ((INTVAL (operands[2]) - 4) / 4);
   1455   return \"calls %2,%1\";
   1456 }")
   1457 
   1458 (define_expand "call"
   1459   [(call (match_operand:QI 0 "memory_operand" "")
   1460       (match_operand:SI 1 "const_int_operand" ""))]
   1461   ""
   1462   "
   1463 {
   1464   /* Operand 1 is the number of bytes to be popped by DW_CFA_GNU_args_size
   1465      during EH unwinding.  We must include the argument count pushed by
   1466      the calls instruction.  */
   1467   operands[1] = GEN_INT (INTVAL (operands[1]) + 4);
   1468 }")
   1469 
   1470 (define_insn "*call"
   1471    [(call (match_operand:QI 0 "memory_operand" "m")
   1472 	  (match_operand:SI 1 "const_int_operand" ""))]
   1473   ""
   1474   "calls $0,%0")
   1475 
   1476 (define_expand "call_value"
   1477   [(set (match_operand 0 "" "")
   1478       (call (match_operand:QI 1 "memory_operand" "")
   1479 	    (match_operand:SI 2 "const_int_operand" "")))]
   1480   ""
   1481   "
   1482 {
   1483   /* Operand 2 is the number of bytes to be popped by DW_CFA_GNU_args_size
   1484      during EH unwinding.  We must include the argument count pushed by
   1485      the calls instruction.  */
   1486   operands[2] = GEN_INT (INTVAL (operands[2]) + 4);
   1487 }")
   1488 
   1489 (define_insn "*call_value"
   1490   [(set (match_operand 0 "" "")
   1491 	(call (match_operand:QI 1 "memory_operand" "m")
   1492 	      (match_operand:SI 2 "const_int_operand" "")))]
   1493   ""
   1494   "calls $0,%1")
   1495 
   1496 ;; Call subroutine returning any type.
   1497 
   1498 (define_expand "untyped_call"
   1499   [(parallel [(call (match_operand 0 "" "")
   1500 	      (const_int 0))
   1501 	      (match_operand 1 "" "")
   1502 	      (match_operand 2 "" "")])]
   1503   ""
   1504   "
   1505 {
   1506   int i;
   1507 
   1508   emit_call_insn (gen_call_pop (operands[0], const0_rtx, NULL, const0_rtx));
   1509 
   1510   for (i = 0; i < XVECLEN (operands[2], 0); i++)
   1511     {
   1512       rtx set = XVECEXP (operands[2], 0, i);
   1513       emit_move_insn (SET_DEST (set), SET_SRC (set));
   1514     }
   1515 
   1516   /* The optimizer does not know that the call sets the function value
   1517      registers we stored in the result block.  We avoid problems by
   1518      claiming that all hard registers are used and clobbered at this
   1519      point.  */
   1520   emit_insn (gen_blockage ());
   1521 
   1522   DONE;
   1523 }")
   1524 
   1525 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
   1526 ;; all of memory.  This blocks insns from being moved across this point.
   1527 
   1528 (define_insn "blockage"
   1529   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
   1530   ""
   1531   "")
   1532 
   1533 (define_insn "procedure_entry_mask"
   1534   [(unspec_volatile [(match_operand 0 "const_int_operand")] VUNSPEC_PEM)]
   1535   ""
   1536   ".word %x0")
   1537 
   1538 (define_insn "return"
   1539   [(return)]
   1540   ""
   1541   "ret")
   1542 
   1543 (define_expand "prologue"
   1544   [(const_int 0)]
   1545   ""
   1546 {
   1547   vax_expand_prologue ();
   1548   DONE;
   1549 })
   1550 
   1551 (define_expand "epilogue"
   1552   [(return)]
   1553   ""
   1554   "
   1555 {
   1556   emit_jump_insn (gen_return ());
   1557   DONE;
   1558 }")
   1559 
   1560 ;; Exception handling
   1561 ;; This is used when compiling the stack unwinding routines.
   1562 (define_expand "eh_return"
   1563   [(use (match_operand 0 "general_operand"))]
   1564   ""
   1565 {
   1566   if (GET_MODE (operands[0]) != word_mode)
   1567     operands[0] = convert_to_mode (word_mode, operands[0], 0);
   1568   emit_insn (gen_eh_set_retaddr (operands[0]));
   1569   DONE;
   1570 })
   1571 
   1572 (define_insn_and_split "eh_set_retaddr"
   1573   [(unspec [(match_operand:SI 0 "general_operand")] VUNSPEC_EH_RETURN)
   1574    (clobber (match_scratch:SI 1 "=&r"))
   1575    ]
   1576   ""
   1577   "#"
   1578   "reload_completed"
   1579   [(const_int 0)]
   1580 {
   1581   /* the return address for the current frame is always at 0x10(%fp) */
   1582   rtx tmp = plus_constant(Pmode, frame_pointer_rtx, 4 * UNITS_PER_WORD);
   1583   tmp = gen_rtx_MEM (word_mode, tmp);
   1584   MEM_VOLATILE_P(tmp) = 1;
   1585   tmp = gen_rtx_SET(tmp, operands[0]);
   1586   emit_insn(tmp);
   1587   DONE;
   1588 })
   1589 
   1590 (define_insn "nop"
   1591   [(const_int 0)]
   1592   ""
   1593   "nop")
   1594 
   1595 ;; This had a wider constraint once, and it had trouble.
   1596 ;; If you are tempted to try `g', please don't--it's not worth
   1597 ;; the risk we will reopen the same bug.
   1598 (define_insn "indirect_jump"
   1599   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
   1600   ""
   1601   "jmp (%0)")
   1602 
   1603 ;; This is here to accept 5 arguments (as passed by expand_end_case)
   1604 ;; and pass the first 4 along to the casesi1 pattern that really does
   1605 ;; the actual casesi work.  We emit a jump here to the default label
   1606 ;; _before_ the casesi so that we can be sure that the casesi never
   1607 ;; drops through.
   1608 ;; This is suboptimal perhaps, but so is much of the rest of this
   1609 ;; machine description.  For what it's worth, HPPA uses the same trick.
   1610 ;;
   1611 ;; operand 0 is index
   1612 ;; operand 1 is the minimum bound (a const_int)
   1613 ;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int)
   1614 ;; operand 3 is CODE_LABEL for the table;
   1615 ;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default).
   1616 ;;
   1617 ;; We emit:
   1618 ;;	i = index - minimum_bound
   1619 ;;	if (i > (maximum_bound - minimum_bound + 1) goto default;
   1620 ;;	casesi (i, 0, table);
   1621 ;;
   1622 (define_expand "casesi"
   1623   [(match_operand:SI 0 "general_operand" "")
   1624    (match_operand:SI 1 "general_operand" "")
   1625    (match_operand:SI 2 "general_operand" "")
   1626    (match_operand 3 "" "")
   1627    (match_operand 4 "" "")]
   1628   ""
   1629 {
   1630   rtx test;
   1631 
   1632   /* i = index - minimum_bound;
   1633      But only if the lower bound is not already zero.  */
   1634   if (operands[1] != const0_rtx)
   1635     {
   1636       rtx index = gen_reg_rtx (SImode);
   1637       emit_insn (gen_addsi3 (index,
   1638 			     operands[0],
   1639 			     GEN_INT (-INTVAL (operands[1]))));
   1640       operands[0] = index;
   1641     }
   1642 
   1643   /* if (i > (maximum_bound - minimum_bound + 1)) goto default;  */
   1644   test = gen_rtx_fmt_ee (GTU, VOIDmode, operands[0], operands[2]);
   1645   emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
   1646 
   1647   /* casesi (i, 0, table);  */
   1648   emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3]));
   1649   DONE;
   1650 })
   1651 
   1652 ;; This insn is a bit of a lier.  It actually falls through if no case
   1653 ;; matches.  But, we prevent that from ever happening by emitting a jump
   1654 ;; before this, see the define_expand above.
   1655 (define_insn "casesi1"
   1656   [(match_operand:SI 1 "const_int_operand" "n")
   1657    (set (pc)
   1658 	(plus:SI (sign_extend:SI
   1659 		  (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT")
   1660 					    (const_int 2))
   1661 			  (pc))))
   1662 		 (label_ref:SI (match_operand 2 "" ""))))]
   1663   ""
   1664   "casel %0,$0,%1")
   1665 
   1667 (define_insn "pushextsym"
   1668   [(set (match_operand:SI 0 "push_operand" "=g")
   1669 	(match_operand:SI 1 "external_symbolic_operand" "i"))]
   1670   ""
   1671   "pushab %a1")
   1672 
   1673 (define_insn "movextsym"
   1674   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
   1675 	(match_operand:SI 1 "external_symbolic_operand" "i"))]
   1676   ""
   1677   "movab %a1,%0")
   1678 
   1679 (define_insn "pushlclsym"
   1680   [(set (match_operand:SI 0 "push_operand" "=g")
   1681 	(match_operand:SI 1 "local_symbolic_operand" "i"))]
   1682   ""
   1683   "pushab %a1")
   1684 
   1685 (define_insn "movlclsym"
   1686   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
   1687 	(match_operand:SI 1 "local_symbolic_operand" "i"))]
   1688   ""
   1689   "movab %a1,%0")
   1690 
   1692 ;;- load or push effective address
   1693 ;; These come after the move and add/sub patterns
   1694 ;; because we don't want pushl $1 turned into pushad 1.
   1695 ;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3.
   1696 
   1697 ;; It does not work to use constraints to distinguish pushes from moves,
   1698 ;; because < matches any autodecrement, not just a push.
   1699 
   1700 (define_insn "pushaddr<mode>"
   1701   [(set (match_operand:SI 0 "push_operand" "=g")
   1702 	(match_operand:VAXintQHSD 1 "address_operand" "p"))]
   1703   ""
   1704   "pusha<VAXintQHSD:isfx> %a1")
   1705 
   1706 (define_insn "movaddr<mode>"
   1707   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
   1708 	(match_operand:VAXintQHSD 1 "address_operand" "p"))]
   1709   ""
   1710   "mova<VAXintQHSD:isfx> %a1,%0")
   1711 
   1712 (define_insn "pushaddr<mode>"
   1713   [(set (match_operand:SI 0 "push_operand" "=g")
   1714 	(match_operand:VAXfp 1 "address_operand" "p"))]
   1715   ""
   1716   "pusha<VAXfp:fsfx> %a1")
   1717 
   1718 (define_insn "movaddr<mode>"
   1719   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
   1720 	(match_operand:VAXfp 1 "address_operand" "p"))]
   1721   ""
   1722   "mova<VAXfp:fsfx> %a1,%0")
   1723 
   1725 ;; These used to be peepholes, but it is more straightforward to do them
   1726 ;; as single insns.  However, we must force the output to be a register
   1727 ;; if it is not an offsettable address so that we know that we can assign
   1728 ;; to it twice.
   1729 
   1730 ;; If we had a good way of evaluating the relative costs, these could be
   1731 ;; machine-independent.
   1732 
   1733 ;; Optimize   extzv ...,z;    andl2 ...,z
   1734 ;; or	      ashl ...,z;     andl2 ...,z
   1735 ;; with other operands constant.  This is what the combiner converts the
   1736 ;; above sequences to before attempting to recognize the new insn.
   1737 
   1738 (define_insn ""
   1739   [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
   1740 	(and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
   1741 			     (match_operand:QI 2 "const_int_operand" "n"))
   1742 		(match_operand:SI 3 "const_int_operand" "n")))]
   1743   "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0"
   1744   "*
   1745 {
   1746   unsigned long mask1 = INTVAL (operands[3]);
   1747   unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1;
   1748 
   1749   if ((mask1 & mask2) != mask1)
   1750     operands[3] = GEN_INT (mask1 & mask2);
   1751 
   1752   return \"rotl %R2,%1,%0\;bicl2 %N3,%0\";
   1753 }")
   1754 
   1755 ;; left-shift and mask
   1756 ;; The only case where `ashl' is better is if the mask only turns off
   1757 ;; bits that the ashl would anyways, in which case it should have been
   1758 ;; optimized away.
   1759 
   1760 (define_insn ""
   1761   [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
   1762 	(and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
   1763 			   (match_operand:QI 2 "const_int_operand" "n"))
   1764 		(match_operand:SI 3 "const_int_operand" "n")))]
   1765   ""
   1766   "*
   1767 {
   1768   operands[3]
   1769     = GEN_INT (INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1));
   1770   return \"rotl %2,%1,%0\;bicl2 %N3,%0\";
   1771 }")
   1772 
   1773 ;; Instruction sequence to sync the VAX instruction stream.
   1774 (define_insn "sync_istream"
   1775   [(unspec_volatile [(const_int 0)] VUNSPEC_SYNC_ISTREAM)]
   1776   ""
   1777   "movpsl -(%|sp)\;pushal 1(%|pc)\;rei")
   1778 
   1779 (define_expand "nonlocal_goto"
   1780   [(use (match_operand 0 "general_operand" ""))
   1781    (use (match_operand 1 "general_operand" ""))
   1782    (use (match_operand 2 "general_operand" ""))
   1783    (use (match_operand 3 "general_operand" ""))]
   1784   ""
   1785 {
   1786   rtx lab = operands[1];
   1787   rtx stack = operands[2];
   1788   rtx fp = operands[3];
   1789 
   1790   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
   1791   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
   1792 
   1793   emit_move_insn (hard_frame_pointer_rtx, fp);
   1794   emit_stack_restore (SAVE_NONLOCAL, stack);
   1795 
   1796   emit_use (hard_frame_pointer_rtx);
   1797   emit_use (stack_pointer_rtx);
   1798 
   1799   /* We'll convert this to direct jump via a peephole optimization.  */
   1800   emit_indirect_jump (copy_to_reg (lab));
   1801   emit_barrier ();
   1802   DONE;
   1803 })
   1804 
   1805 (include "builtins.md")
   1806 
   1807 (define_peephole2
   1808   [(set (match_operand:SI 0 "push_operand" "")
   1809         (const_int 0))
   1810    (set (match_dup 0)
   1811         (match_operand:SI 1 "const_int_operand" ""))]
   1812   "INTVAL (operands[1]) >= 0"
   1813   [(set (match_dup 0)
   1814         (match_dup 1))]
   1815   "operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));")
   1816 
   1817 (define_peephole2
   1818   [(set (match_operand:SI 0 "push_operand" "")
   1819         (match_operand:SI 1 "general_operand" ""))
   1820    (set (match_dup 0)
   1821         (match_operand:SI 2 "general_operand" ""))]
   1822   "vax_decomposed_dimode_operand_p (operands[2], operands[1])"
   1823   [(set (match_dup 0)
   1824         (match_dup 2))]
   1825   "{
   1826     operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));
   1827     operands[2] = REG_P (operands[2])
   1828       ? gen_rtx_REG(DImode, REGNO (operands[2]))
   1829       : gen_rtx_MEM(DImode, XEXP (operands[2], 0));
   1830 }")
   1831 
   1832 ; Leave this commented out until we can determine whether the second move
   1833 ; precedes a jump which relies on the CC flags being set correctly.
   1834 (define_peephole2
   1835   [(set (match_operand:SI 0 "nonimmediate_operand" "")
   1836         (match_operand:SI 1 "general_operand" ""))
   1837    (set (match_operand:SI 2 "nonimmediate_operand" "")
   1838         (match_operand:SI 3 "general_operand" ""))]
   1839   "0 && vax_decomposed_dimode_operand_p (operands[1], operands[3])
   1840    && vax_decomposed_dimode_operand_p (operands[0], operands[2])"
   1841   [(set (match_dup 0)
   1842         (match_dup 1))]
   1843   "{
   1844     operands[0] = REG_P (operands[0])
   1845       ? gen_rtx_REG(DImode, REGNO (operands[0]))
   1846       : gen_rtx_MEM(DImode, XEXP (operands[0], 0));
   1847     operands[1] = REG_P (operands[1])
   1848       ? gen_rtx_REG(DImode, REGNO (operands[1]))
   1849       : gen_rtx_MEM(DImode, XEXP (operands[1], 0));
   1850 }")
   1851