OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-dev/] [fsf-gcc-snapshot-1-mar-12/] [or1k-gcc/] [gcc/] [config/] [h8300/] [h8300.md] - Blame information for rev 783

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
;; GCC machine description for Renesas H8/300
2
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
4
;; Free Software Foundation, Inc.
5
 
6
;;   Contributed by Steve Chamberlain (sac@cygnus.com),
7
;;   Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
8
 
9
;; This file is part of GCC.
10
 
11
;; GCC is free software; you can redistribute it and/or modify
12
;; it under the terms of the GNU General Public License as published by
13
;; the Free Software Foundation; either version 3, or (at your option)
14
;; any later version.
15
 
16
;; GCC is distributed in the hope that it will be useful,
17
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
;; GNU General Public License for more details.
20
 
21
;; You should have received a copy of the GNU General Public License
22
;; along with GCC; see the file COPYING3.  If not see
23
;; .
24
 
25
;; We compute exact length on each instruction for most of the time.
26
;; In some case, most notably bit operations that may involve memory
27
;; operands, the lengths in this file are "worst case".
28
 
29
;; On the H8/300H and H8S, adds/subs operate on the 32bit "er"
30
;; registers.  Right now GCC doesn't expose the "e" half to the
31
;; compiler, so using add/subs for addhi and subhi is safe.  Long
32
;; term, we want to expose the "e" half to the compiler (gives us 8
33
;; more 16bit registers).  At that point addhi and subhi can't use
34
;; adds/subs.
35
 
36
;; There's currently no way to have an insv/extzv expander for the H8/300H
37
;; because word_mode is different for the H8/300 and H8/300H.
38
 
39
;; Shifts/rotates by small constants should be handled by special
40
;; patterns so we get the length and cc status correct.
41
 
42
;; Bitfield operations no longer accept memory operands.  We need
43
;; to add variants which operate on memory back to the MD.
44
 
45
;; ??? Implement remaining bit ops available on the h8300
46
 
47
;; ----------------------------------------------------------------------
48
;; CONSTANTS
49
;; ----------------------------------------------------------------------
50
 
51
(define_constants
52
  [(UNSPEC_INCDEC       0)
53
   (UNSPEC_MONITOR      1)])
54
 
55
(define_constants
56
  [(UNSPEC_MOVMD        100)
57
   (UNSPEC_STPCPY       101)])
58
 
59
(define_constants
60
  [(R0_REG       0)
61
   (SC_REG       3)
62
   (COUNTER_REG  4)
63
   (SOURCE_REG   5)
64
   (DESTINATION_REG 6)
65
   (HFP_REG      6)
66
   (SP_REG       7)
67
   (MAC_REG      8)
68
   (AP_REG       9)
69
   (RAP_REG     10)
70
   (FP_REG      11)])
71
 
72
;; ----------------------------------------------------------------------
73
;; ATTRIBUTES
74
;; ----------------------------------------------------------------------
75
 
76
(define_attr "cpu" "h8300,h8300h"
77
  (const (symbol_ref "cpu_type")))
78
 
79
(define_attr "type" "branch,arith,bitbranch,call"
80
  (const_string "arith"))
81
 
82
(define_attr "length_table" "none,addb,addw,addl,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch"
83
  (const_string "none"))
84
 
85
;; The size of instructions in bytes.
86
 
87
(define_attr "length" ""
88
  (cond [(eq_attr "type" "branch")
89
         ;; In a forward delayed branch, (pc) represents the end of the
90
         ;; delay sequence, not the end of the branch itself.
91
         (if_then_else (and (ge (minus (match_dup 0) (pc))
92
                                (const_int -126))
93
                            (le (plus (minus (match_dup 0) (pc))
94
                                      (symbol_ref "DELAY_SLOT_LENGTH (insn)"))
95
                                (const_int 125)))
96
                       (const_int 2)
97
                       (if_then_else (and (eq_attr "cpu" "h8300h")
98
                                          (and (ge (minus (pc) (match_dup 0))
99
                                                   (const_int -32000))
100
                                               (le (minus (pc) (match_dup 0))
101
                                                   (const_int 32000))))
102
                                     (const_int 4)
103
                                     (const_int 6)))
104
         (eq_attr "type" "bitbranch")
105
         (if_then_else
106
          (and (ge (minus (match_dup 0) (pc))
107
                   (const_int -126))
108
               (le (minus (match_dup 0) (pc))
109
                   (const_int 126)))
110
          (plus
111
           (symbol_ref "h8300_insn_length_from_table (insn, operands)")
112
           (const_int 2))
113
          (if_then_else
114
           (and (eq_attr "cpu" "h8300h")
115
                (and (ge (minus (pc) (match_dup 0))
116
                         (const_int -32000))
117
                     (le (minus (pc) (match_dup 0))
118
                         (const_int 32000))))
119
           (plus
120
            (symbol_ref "h8300_insn_length_from_table (insn, operands)")
121
            (const_int 4))
122
           (plus
123
            (symbol_ref "h8300_insn_length_from_table (insn, operands)")
124
            (const_int 6))))
125
         (eq_attr "length_table" "!none")
126
         (symbol_ref "h8300_insn_length_from_table (insn, operands)")]
127
        (const_int 200)))
128
 
129
;; Condition code settings.
130
;;
131
;; none - insn does not affect cc
132
;; none_0hit - insn does not affect cc but it does modify operand 0
133
;;      This attribute is used to keep track of when operand 0 changes.
134
;;      See the description of NOTICE_UPDATE_CC for more info.
135
;; set_znv - insn sets z,n,v to usable values (like a tst insn); c is unknown.
136
;; set_zn  - insn sets z,n to usable values; v,c are unknown.
137
;; compare - compare instruction
138
;; clobber - value of cc is unknown
139
 
140
(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
141
  (const_string "clobber"))
142
 
143
;; Type of delay slot.  NONE means the instruction has no delay slot.
144
;; JUMP means it is an unconditional jump that (if short enough)
145
;; could be implemented using bra/s.
146
(define_attr "delay_slot" "none,jump"
147
  (const_string "none"))
148
 
149
;; "yes" if the instruction can be put into a delay slot.  It's not
150
;; entirely clear that jsr is not valid in delay slots, but it
151
;; definitely doesn't have the effect of causing the called function
152
;; to return to the target of the delayed branch.
153
(define_attr "can_delay" "no,yes"
154
  (cond [(eq_attr "type" "branch,bitbranch,call")
155
           (const_string "no")
156
         (geu (symbol_ref "get_attr_length (insn)") (const_int 2))
157
           (const_string "no")]
158
        (const_string "yes")))
159
 
160
;; Only allow jumps to have a delay slot if we think they might
161
;; be short enough.  This is just an optimization: we don't know
162
;; for certain whether they will be or not.
163
(define_delay (and (eq_attr "delay_slot" "jump")
164
                   (eq (symbol_ref "get_attr_length (insn)") (const_int 2)))
165
  [(eq_attr "can_delay" "yes")
166
   (nil)
167
   (nil)])
168
 
169
;; Provide the maximum length of an assembly instruction in an asm
170
;; statement.  The maximum length of 14 bytes is achieved on H8SX.
171
 
172
(define_asm_attributes
173
  [(set (attr "length")
174
        (cond [(match_test "TARGET_H8300") (const_int 4)
175
               (match_test "TARGET_H8300H") (const_int 10)
176
               (match_test "TARGET_H8300S") (const_int 10)]
177
              (const_int 14)))])
178
 
179
(include "predicates.md")
180
(include "constraints.md")
181
 
182
;; ----------------------------------------------------------------------
183
;; MACRO DEFINITIONS
184
;; ----------------------------------------------------------------------
185
 
186
;; This mode iterator allows :P to be used for patterns that operate on
187
;; pointer-sized quantities.  Exactly one of the two alternatives will match.
188
(define_mode_iterator P [(HI "Pmode == HImode") (SI "Pmode == SImode")])
189
 
190
 
191
;; ----------------------------------------------------------------------
192
;; MOVE INSTRUCTIONS
193
;; ----------------------------------------------------------------------
194
 
195
;; movqi
196
 
197
(define_insn "*movqi_h8300"
198
  [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
199
        (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
200
  "TARGET_H8300
201
   && h8300_move_ok (operands[0], operands[1])"
202
  "@
203
   sub.b        %X0,%X0
204
   mov.b        %R1,%X0
205
   mov.b        %X1,%R0
206
   mov.b        %R1,%X0
207
   mov.b        %R1,%X0
208
   mov.b        %X1,%R0"
209
  [(set_attr "length" "2,2,2,2,4,4")
210
   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
211
 
212
(define_insn "*movqi_h8300hs"
213
  [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
214
        (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
215
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
216
   && h8300_move_ok (operands[0], operands[1])"
217
  "@
218
   sub.b        %X0,%X0
219
   mov.b        %R1,%X0
220
   mov.b        %X1,%R0
221
   mov.b        %R1,%X0
222
   mov.b        %R1,%X0
223
   mov.b        %X1,%R0"
224
  [(set (attr "length")
225
        (symbol_ref "compute_mov_length (operands)"))
226
   (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv")])
227
 
228
(define_insn "*movqi_h8sx"
229
  [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
230
        (match_operand:QI 1 "general_operand_src" "P4>X,rQi"))]
231
  "TARGET_H8300SX"
232
  "@
233
    mov.b       %X1:4,%X0
234
    mov.b       %X1,%X0"
235
  [(set_attr "length_table" "mov_imm4,movb")
236
   (set_attr "cc" "set_znv")])
237
 
238
(define_expand "movqi"
239
  [(set (match_operand:QI 0 "general_operand_dst" "")
240
        (match_operand:QI 1 "general_operand_src" ""))]
241
  ""
242
{
243
  /* One of the ops has to be in a register.  */
244
  if (!TARGET_H8300SX && !h8300_move_ok (operands[0], operands[1]))
245
    operands[1] = copy_to_mode_reg (QImode, operands[1]);
246
})
247
 
248
(define_insn "movstrictqi"
249
  [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
250
                         (match_operand:QI 1 "general_operand_src" "I,rmi>"))]
251
  ""
252
  "@
253
   sub.b        %X0,%X0
254
   mov.b        %X1,%X0"
255
  [(set_attr "length" "2,*")
256
   (set_attr "length_table" "*,movb")
257
   (set_attr "cc" "set_zn,set_znv")])
258
 
259
;; movhi
260
 
261
(define_insn "*movhi_h8300"
262
  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
263
        (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
264
  "TARGET_H8300
265
   && h8300_move_ok (operands[0], operands[1])"
266
  "@
267
   sub.w        %T0,%T0
268
   mov.w        %T1,%T0
269
   mov.w        %T1,%T0
270
   mov.w        %T1,%T0
271
   mov.w        %T1,%T0
272
   mov.w        %T1,%T0"
273
  [(set (attr "length")
274
        (symbol_ref "compute_mov_length (operands)"))
275
   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
276
 
277
(define_insn "*movhi_h8300hs"
278
  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
279
        (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
280
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
281
   && h8300_move_ok (operands[0], operands[1])"
282
  "@
283
   sub.w        %T0,%T0
284
   mov.w        %T1,%T0
285
   mov.w        %T1,%T0
286
   mov.w        %T1,%T0
287
   mov.w        %T1,%T0
288
   mov.w        %T1,%T0"
289
  [(set (attr "length")
290
        (symbol_ref "compute_mov_length (operands)"))
291
   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
292
 
293
(define_insn "*movhi_h8sx"
294
  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
295
        (match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))]
296
  "TARGET_H8300SX"
297
  "@
298
   sub.w        %T0,%T0
299
   mov.w        %T1:3,%T0
300
   mov.w        %T1:4,%T0
301
   mov.w        %T1,%T0
302
   mov.w        %T1,%T0"
303
  [(set_attr "length_table" "*,*,mov_imm4,short_immediate,movw")
304
   (set_attr "length" "2,2,*,*,*")
305
   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
306
 
307
(define_expand "movhi"
308
  [(set (match_operand:HI 0 "general_operand_dst" "")
309
        (match_operand:HI 1 "general_operand_src" ""))]
310
  ""
311
{
312
  /* One of the ops has to be in a register.  */
313
  if (!h8300_move_ok (operands[0], operands[1]))
314
    operands[1] = copy_to_mode_reg (HImode, operand1);
315
})
316
 
317
(define_insn "movstricthi"
318
  [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
319
                         (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]
320
  ""
321
  "@
322
   sub.w        %T0,%T0
323
   mov.w        %T1,%T0
324
   mov.w        %T1,%T0"
325
  [(set_attr "length" "2,2,*")
326
   (set_attr "length_table" "*,*,movw")
327
   (set_attr "cc" "set_zn,set_znv,set_znv")])
328
 
329
;; movsi
330
 
331
(define_expand "movsi"
332
  [(set (match_operand:SI 0 "general_operand_dst" "")
333
        (match_operand:SI 1 "general_operand_src" ""))]
334
  ""
335
{
336
  if (TARGET_H8300)
337
    {
338
      if (h8300_expand_movsi (operands))
339
        DONE;
340
    }
341
  else if (!TARGET_H8300SX)
342
    {
343
      /* One of the ops has to be in a register.  */
344
      if (!h8300_move_ok (operands[0], operands[1]))
345
        operands[1] = copy_to_mode_reg (SImode, operand1);
346
    }
347
})
348
 
349
(define_insn "*movsi_h8300"
350
  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
351
        (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]
352
  "TARGET_H8300
353
   && h8300_move_ok (operands[0], operands[1])"
354
  "*
355
{
356
  unsigned int rn = -1;
357
  switch (which_alternative)
358
    {
359
    case 0:
360
      return \"sub.w    %e0,%e0\;sub.w  %f0,%f0\";
361
    case 1:
362
      if (REGNO (operands[0]) < REGNO (operands[1]))
363
        return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
364
      else
365
        return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
366
    case 2:
367
      /* Make sure we don't trample the register we index with.  */
368
      if (GET_CODE (operands[1]) == MEM)
369
        {
370
          rtx inside = XEXP (operands[1], 0);
371
          if (REG_P (inside))
372
            {
373
              rn = REGNO (inside);
374
            }
375
          else if (GET_CODE (inside) == PLUS)
376
            {
377
              rtx lhs = XEXP (inside, 0);
378
              rtx rhs = XEXP (inside, 1);
379
              if (REG_P (lhs)) rn = REGNO (lhs);
380
              if (REG_P (rhs)) rn = REGNO (rhs);
381
            }
382
        }
383
      if (rn == REGNO (operands[0]))
384
        {
385
          /* Move the second word first.  */
386
          return \"mov.w        %f1,%f0\;mov.w  %e1,%e0\";
387
        }
388
      else
389
        {
390
          if (GET_CODE (operands[1]) == CONST_INT)
391
            {
392
              /* If either half is zero, use sub.w to clear that
393
                 half.  */
394
              if ((INTVAL (operands[1]) & 0xffff) == 0)
395
                return \"mov.w  %e1,%e0\;sub.w  %f0,%f0\";
396
              if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0)
397
                return \"sub.w  %e0,%e0\;mov.w  %f1,%f0\";
398
              /* If the upper half and the lower half are the same,
399
                 copy one half to the other.  */
400
              if ((INTVAL (operands[1]) & 0xffff)
401
                  == ((INTVAL (operands[1]) >> 16) & 0xffff))
402
                return \"mov.w\\t%e1,%e0\;mov.w\\t%e0,%f0\";
403
            }
404
          return \"mov.w        %e1,%e0\;mov.w  %f1,%f0\";
405
        }
406
    case 3:
407
      return \"mov.w    %e1,%e0\;mov.w  %f1,%f0\";
408
    case 4:
409
      return \"mov.w    %f1,%T0\;mov.w  %e1,%T0\";
410
    case 5:
411
      return \"mov.w    %T1,%e0\;mov.w  %T1,%f0\";
412
    default:
413
      gcc_unreachable ();
414
    }
415
}"
416
  [(set (attr "length")
417
        (symbol_ref "compute_mov_length (operands)"))])
418
 
419
(define_insn "*movsi_h8300hs"
420
  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
421
        (match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
422
  "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
423
   && h8300_move_ok (operands[0], operands[1])"
424
  "*
425
{
426
  switch (which_alternative)
427
    {
428
    case 0:
429
      return \"sub.l    %S0,%S0\";
430
    case 7:
431
      return \"clrmac\";
432
    case 8:
433
      return \"clrmac\;ldmac %1,macl\";
434
    case 9:
435
      return \"stmac    macl,%0\";
436
    default:
437
      if (GET_CODE (operands[1]) == CONST_INT)
438
        {
439
          int val = INTVAL (operands[1]);
440
 
441
          /* Look for constants which can be made by adding an 8-bit
442
             number to zero in one of the two low bytes.  */
443
          if (val == (val & 0xff))
444
            {
445
              operands[1] = GEN_INT ((char) val & 0xff);
446
              return \"sub.l\\t%S0,%S0\;add.b\\t%1,%w0\";
447
            }
448
 
449
          if (val == (val & 0xff00))
450
            {
451
              operands[1] = GEN_INT ((char) (val >> 8) & 0xff);
452
              return \"sub.l\\t%S0,%S0\;add.b\\t%1,%x0\";
453
            }
454
 
455
          /* Look for constants that can be obtained by subs, inc, and
456
             dec to 0.  */
457
          switch (val & 0xffffffff)
458
            {
459
            case 0xffffffff:
460
              return \"sub.l\\t%S0,%S0\;subs\\t#1,%S0\";
461
            case 0xfffffffe:
462
              return \"sub.l\\t%S0,%S0\;subs\\t#2,%S0\";
463
            case 0xfffffffc:
464
              return \"sub.l\\t%S0,%S0\;subs\\t#4,%S0\";
465
 
466
            case 0x0000ffff:
467
              return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%f0\";
468
            case 0x0000fffe:
469
              return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%f0\";
470
 
471
            case 0xffff0000:
472
              return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%e0\";
473
            case 0xfffe0000:
474
              return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%e0\";
475
 
476
            case 0x00010000:
477
              return \"sub.l\\t%S0,%S0\;inc.w\\t#1,%e0\";
478
            case 0x00020000:
479
              return \"sub.l\\t%S0,%S0\;inc.w\\t#2,%e0\";
480
            }
481
        }
482
    }
483
   return \"mov.l       %S1,%S0\";
484
}"
485
  [(set (attr "length")
486
        (symbol_ref "compute_mov_length (operands)"))
487
   (set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
488
 
489
(define_insn "*movsi_h8sx"
490
  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
491
        (match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))]
492
  "TARGET_H8300SX"
493
  "@
494
   sub.l        %S0,%S0
495
   mov.l        %S1:3,%S0
496
   mov.l        %S1,%S0
497
   mov.l        %S1,%S0
498
   clrmac
499
   clrmac\;ldmac        %1,macl
500
   stmac        macl,%0"
501
  [(set_attr "length_table" "*,*,short_immediate,movl,*,*,*")
502
   (set_attr "length" "2,2,*,*,2,6,4")
503
   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
504
 
505
(define_insn "*movsf_h8sx"
506
  [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
507
        (match_operand:SF 1 "general_operand_src" "G,rQi"))]
508
  "TARGET_H8300SX"
509
  "@
510
    sub.l       %S0,%S0
511
    mov.l       %S1,%S0"
512
  [(set_attr "length" "2,*")
513
   (set_attr "length_table" "*,movl")
514
   (set_attr "cc" "set_zn,set_znv")])
515
 
516
;; Implement block moves using movmd.  Defining movmemsi allows the full
517
;; range of constant lengths (up to 0x40000 bytes when using movmd.l).
518
;; See h8sx_emit_movmd for details.
519
(define_expand "movmemsi"
520
  [(use (match_operand:BLK 0 "memory_operand" ""))
521
   (use (match_operand:BLK 1 "memory_operand" ""))
522
   (use (match_operand:SI 2 "" ""))
523
   (use (match_operand:SI 3 "const_int_operand" ""))]
524
  "TARGET_H8300SX"
525
  {
526
    if (h8sx_emit_movmd (operands[0], operands[1], operands[2],
527
                         INTVAL (operands[3])))
528
      DONE;
529
    else
530
      FAIL;
531
  })
532
 
533
;; Expander for generating movmd insns.  Operand 0 is the destination
534
;; memory region, operand 1 is the source, operand 2 is the counter
535
;; register and operand 3 is the chunk size (1, 2 or 4).
536
(define_expand "movmd"
537
  [(parallel
538
       [(set (match_operand:BLK 0 "memory_operand" "")
539
             (match_operand:BLK 1 "memory_operand" ""))
540
        (unspec [(match_operand:HI 2 "register_operand" "")
541
                 (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
542
        (clobber (match_dup 4))
543
        (clobber (match_dup 5))
544
        (set (match_dup 2)
545
             (const_int 0))])]
546
  "TARGET_H8300SX"
547
  {
548
    operands[4] = copy_rtx (XEXP (operands[0], 0));
549
    operands[5] = copy_rtx (XEXP (operands[1], 0));
550
  })
551
 
552
 
553
;; This is a difficult instruction to reload since operand 0 must be the
554
;; frame pointer.  See h8300_reg_class_from_letter for an explanation.
555
(define_insn "movmd_internal_normal"
556
  [(set (mem:BLK (match_operand:HI 3 "register_operand" "0,r"))
557
        (mem:BLK (match_operand:HI 4 "register_operand" "1,1")))
558
   (unspec [(match_operand:HI 5 "register_operand" "2,2")
559
            (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD)
560
   (clobber (match_operand:HI 0 "register_operand" "=d,??D"))
561
   (clobber (match_operand:HI 1 "register_operand" "=f,f"))
562
   (set (match_operand:HI 2 "register_operand" "=c,c")
563
        (const_int 0))]
564
  "TARGET_H8300SX && TARGET_NORMAL_MODE"
565
  "@
566
    movmd%m6
567
    #"
568
  [(set_attr "length" "2,14")
569
   (set_attr "can_delay" "no")
570
   (set_attr "cc" "none,clobber")])
571
 
572
(define_insn "movmd_internal"
573
  [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r"))
574
        (mem:BLK (match_operand:SI 4 "register_operand" "1,1")))
575
   (unspec [(match_operand:HI 5 "register_operand" "2,2")
576
            (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD)
577
   (clobber (match_operand:SI 0 "register_operand" "=d,??D"))
578
   (clobber (match_operand:SI 1 "register_operand" "=f,f"))
579
   (set (match_operand:HI 2 "register_operand" "=c,c")
580
        (const_int 0))]
581
  "TARGET_H8300SX && !TARGET_NORMAL_MODE"
582
  "@
583
    movmd%m6
584
    #"
585
  [(set_attr "length" "2,14")
586
   (set_attr "can_delay" "no")
587
   (set_attr "cc" "none,clobber")])
588
 
589
;; Split the above instruction if the destination register isn't er6.
590
;; We need a sequence like:
591
;;
592
;;      mov.l   er6,@-er7
593
;;      mov.l   ,er6
594
;;      movmd.sz
595
;;      mov.l   er6,
596
;;      mov.l   @er7+,er6
597
;;
598
;; where  is the current destination register (operand 4).
599
;; The fourth instruction will be deleted if  dies here.
600
(define_split
601
  [(set (match_operand:BLK 0 "memory_operand" "")
602
        (match_operand:BLK 1 "memory_operand" ""))
603
   (unspec [(match_operand:HI 2 "register_operand" "")
604
            (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
605
   (clobber (match_operand:HI 4 "register_operand" ""))
606
   (clobber (match_operand:HI 5 "register_operand" ""))
607
   (set (match_dup 2)
608
        (const_int 0))]
609
  "TARGET_H8300SX && TARGET_NORMAL_MODE
610
   && reload_completed
611
   && REGNO (operands[4]) != DESTINATION_REG"
612
  [(const_int 0)]
613
  {
614
    rtx dest;
615
 
616
    h8300_swap_into_er6 (XEXP (operands[0], 0));
617
    dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
618
    emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3]));
619
    h8300_swap_out_of_er6 (operands[4]);
620
    DONE;
621
  })
622
 
623
(define_split
624
  [(set (match_operand:BLK 0 "memory_operand" "")
625
        (match_operand:BLK 1 "memory_operand" ""))
626
   (unspec [(match_operand:HI 2 "register_operand" "")
627
            (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
628
   (clobber (match_operand:SI 4 "register_operand" ""))
629
   (clobber (match_operand:SI 5 "register_operand" ""))
630
   (set (match_dup 2)
631
        (const_int 0))]
632
  "TARGET_H8300SX && !TARGET_NORMAL_MODE
633
   && reload_completed
634
   && REGNO (operands[4]) != DESTINATION_REG"
635
  [(const_int 0)]
636
  {
637
    rtx dest;
638
 
639
    h8300_swap_into_er6 (XEXP (operands[0], 0));
640
    dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
641
    emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3]));
642
    h8300_swap_out_of_er6 (operands[4]);
643
    DONE;
644
  })
645
 
646
;; Expand a call to stpcpy() using movsd.  Operand 0 should point to
647
;; the final character, but movsd leaves it pointing to the character
648
;; after that.
649
(define_expand "movstr"
650
  [(use (match_operand 0 "register_operand" ""))
651
   (use (match_operand:BLK 1 "memory_operand" ""))
652
   (use (match_operand:BLK 2 "memory_operand" ""))]
653
  "TARGET_H8300SX"
654
  {
655
    operands[1] = replace_equiv_address
656
      (operands[1], copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
657
    operands[2] = replace_equiv_address
658
      (operands[2], copy_to_mode_reg (Pmode, XEXP (operands[2], 0)));
659
    emit_insn (gen_movsd (operands[1], operands[2], gen_reg_rtx (Pmode)));
660
    emit_insn (gen_add3_insn (operands[0],
661
                              XEXP (operands[1], 0),
662
                              constm1_rtx));
663
    DONE;
664
  })
665
 
666
;; Expander for generating a movsd instruction.  Operand 0 is the
667
;; destination string, operand 1 is the source string and operand 2
668
;; is a scratch register.
669
(define_expand "movsd"
670
  [(parallel
671
     [(set (match_operand:BLK 0 "memory_operand" "")
672
           (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")]
673
                       UNSPEC_STPCPY))
674
      (clobber (match_dup 3))
675
      (clobber (match_dup 4))
676
      (clobber (match_operand 2 "register_operand" ""))])]
677
  "TARGET_H8300SX"
678
  {
679
    operands[3] = copy_rtx (XEXP (operands[0], 0));
680
    operands[4] = copy_rtx (XEXP (operands[1], 0));
681
  })
682
 
683
;; See comments above memcpy_internal().
684
(define_insn "stpcpy_internal_normal"
685
  [(set (mem:BLK (match_operand:HI 3 "register_operand" "0,r"))
686
        (unspec:BLK [(mem:BLK (match_operand:HI 4 "register_operand" "1,1"))]
687
                UNSPEC_STPCPY))
688
   (clobber (match_operand:HI 0 "register_operand" "=d,??D"))
689
   (clobber (match_operand:HI 1 "register_operand" "=f,f"))
690
   (clobber (match_operand:HI 2 "register_operand" "=c,c"))]
691
  "TARGET_H8300SX && TARGET_NORMAL_MODE"
692
  "@
693
    \n1:\tmovsd\t2f\;bra\t1b\n2:
694
    #"
695
  [(set_attr "length" "6,18")
696
   (set_attr "cc" "none,clobber")])
697
 
698
(define_insn "stpcpy_internal"
699
  [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r"))
700
        (unspec:BLK [(mem:BLK (match_operand:SI 4 "register_operand" "1,1"))]
701
                UNSPEC_STPCPY))
702
   (clobber (match_operand:SI 0 "register_operand" "=d,??D"))
703
   (clobber (match_operand:SI 1 "register_operand" "=f,f"))
704
   (clobber (match_operand:SI 2 "register_operand" "=c,c"))]
705
  "TARGET_H8300SX && !TARGET_NORMAL_MODE"
706
  "@
707
    \n1:\tmovsd\t2f\;bra\t1b\n2:
708
    #"
709
  [(set_attr "length" "6,18")
710
   (set_attr "cc" "none,clobber")])
711
 
712
;; Split the above instruction if the destination isn't er6.  This works
713
;; in the same way as the movmd splitter.
714
(define_split
715
  [(set (match_operand:BLK 0 "memory_operand" "")
716
        (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY))
717
   (clobber (match_operand:HI 2 "register_operand" ""))
718
   (clobber (match_operand:HI 3 "register_operand" ""))
719
   (clobber (match_operand:HI 4 "register_operand" ""))]
720
  "TARGET_H8300SX && TARGET_NORMAL_MODE
721
   && reload_completed
722
   && REGNO (operands[2]) != DESTINATION_REG"
723
  [(const_int 0)]
724
  {
725
    rtx dest;
726
 
727
    h8300_swap_into_er6 (XEXP (operands[0], 0));
728
    dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
729
    emit_insn (gen_movsd (dest, operands[1], operands[4]));
730
    h8300_swap_out_of_er6 (operands[2]);
731
    DONE;
732
  })
733
 
734
(define_split
735
  [(set (match_operand:BLK 0 "memory_operand" "")
736
        (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY))
737
   (clobber (match_operand:SI 2 "register_operand" ""))
738
   (clobber (match_operand:SI 3 "register_operand" ""))
739
   (clobber (match_operand:SI 4 "register_operand" ""))]
740
  "TARGET_H8300SX && !TARGET_NORMAL_MODE
741
   && reload_completed
742
   && REGNO (operands[2]) != DESTINATION_REG"
743
  [(const_int 0)]
744
  {
745
    rtx dest;
746
 
747
    h8300_swap_into_er6 (XEXP (operands[0], 0));
748
    dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
749
    emit_insn (gen_movsd (dest, operands[1], operands[4]));
750
    h8300_swap_out_of_er6 (operands[2]);
751
    DONE;
752
  })
753
 
754
(include "mova.md")
755
 
756
(define_expand "movsf"
757
  [(set (match_operand:SF 0 "general_operand_dst" "")
758
        (match_operand:SF 1 "general_operand_src" ""))]
759
  ""
760
  "
761
{
762
  if (TARGET_H8300)
763
    {
764
      if (h8300_expand_movsi (operands))
765
        DONE;
766
    }
767
  else if (!TARGET_H8300SX)
768
    {
769
      /* One of the ops has to be in a register.  */
770
      if (!register_operand (operand1, SFmode)
771
          && !register_operand (operand0, SFmode))
772
        {
773
          operands[1] = copy_to_mode_reg (SFmode, operand1);
774
        }
775
    }
776
}")
777
 
778
(define_insn "*movsf_h8300"
779
  [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
780
        (match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))]
781
  "TARGET_H8300
782
   && (register_operand (operands[0], SFmode)
783
       || register_operand (operands[1], SFmode))"
784
  "*
785
{
786
  /* Copy of the movsi stuff.  */
787
  unsigned int rn = -1;
788
  switch (which_alternative)
789
    {
790
    case 0:
791
      return \"sub.w    %e0,%e0\;sub.w  %f0,%f0\";
792
    case 1:
793
      if (REGNO (operands[0]) < REGNO (operands[1]))
794
        return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
795
      else
796
        return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
797
    case 2:
798
      /* Make sure we don't trample the register we index with.  */
799
      if (GET_CODE (operands[1]) == MEM)
800
        {
801
          rtx inside = XEXP (operands[1], 0);
802
          if (REG_P (inside))
803
            {
804
              rn = REGNO (inside);
805
            }
806
          else if (GET_CODE (inside) == PLUS)
807
            {
808
              rtx lhs = XEXP (inside, 0);
809
              rtx rhs = XEXP (inside, 1);
810
              if (REG_P (lhs)) rn = REGNO (lhs);
811
              if (REG_P (rhs)) rn = REGNO (rhs);
812
            }
813
        }
814
      if (rn == REGNO (operands[0]))
815
        /* Move the second word first.  */
816
        return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
817
      else
818
        /* Move the first word first.  */
819
        return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
820
 
821
    case 3:
822
      return \"mov.w    %e1,%e0\;mov.w  %f1,%f0\";
823
    case 4:
824
      return \"mov.w    %f1,%T0\;mov.w  %e1,%T0\";
825
    case 5:
826
      return \"mov.w    %T1,%e0\;mov.w  %T1,%f0\";
827
    default:
828
      gcc_unreachable ();
829
    }
830
}"
831
  [(set (attr "length")
832
        (symbol_ref "compute_mov_length (operands)"))])
833
 
834
(define_insn "*movsf_h8300hs"
835
  [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
836
        (match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))]
837
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
838
   && (register_operand (operands[0], SFmode)
839
       || register_operand (operands[1], SFmode))"
840
  "@
841
   sub.l        %S0,%S0
842
   mov.l        %S1,%S0
843
   mov.l        %S1,%S0
844
   mov.l        %S1,%S0
845
   mov.l        %S1,%S0
846
   mov.l        %S1,%S0"
847
  [(set (attr "length")
848
        (symbol_ref "compute_mov_length (operands)"))
849
   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
850
 
851
;; ----------------------------------------------------------------------
852
;; PUSH INSTRUCTIONS
853
;; ----------------------------------------------------------------------
854
 
855
(define_insn "*pushqi1_h8300"
856
  [(set (mem:QI
857
          (pre_modify:HI
858
            (reg:HI SP_REG)
859
            (plus:HI (reg:HI SP_REG) (const_int -2))))
860
        (match_operand:QI 0 "register_no_sp_elim_operand" "r"))]
861
  "TARGET_H8300"
862
  "mov.w\\t%T0,@-r7"
863
  [(set_attr "length" "2")])
864
 
865
(define_insn "*pushqi1_h8300hs_"
866
  [(set (mem:QI
867
          (pre_modify:P
868
            (reg:P SP_REG)
869
            (plus:P (reg:P SP_REG) (const_int -4))))
870
        (match_operand:QI 0 "register_no_sp_elim_operand" "r"))]
871
  "TARGET_H8300H || TARGET_H8300S"
872
  "mov.l\\t%S0,@-er7"
873
  [(set_attr "length" "4")])
874
 
875
(define_insn "*pushhi1_h8300hs_"
876
  [(set (mem:HI
877
          (pre_modify:P
878
            (reg:P SP_REG)
879
            (plus:P (reg:P SP_REG) (const_int -4))))
880
        (match_operand:HI 0 "register_no_sp_elim_operand" "r"))]
881
  "TARGET_H8300H || TARGET_H8300S"
882
  "mov.l\\t%S0,@-er7"
883
  [(set_attr "length" "4")])
884
 
885
;; ----------------------------------------------------------------------
886
;; TEST INSTRUCTIONS
887
;; ----------------------------------------------------------------------
888
 
889
(define_insn ""
890
  [(set (cc0) (compare
891
               (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "r,U")
892
                                (const_int 1)
893
                                (match_operand 1 "const_int_operand" "n,n"))
894
               (const_int 0)))]
895
  "TARGET_H8300"
896
  "btst %Z1,%Y0"
897
  [(set_attr "length" "2,4")
898
   (set_attr "cc" "set_zn,set_zn")])
899
 
900
(define_insn ""
901
  [(set (cc0) (compare
902
               (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
903
                                (const_int 1)
904
                                (match_operand 1 "const_int_operand" "n"))
905
               (const_int 0)))]
906
  "TARGET_H8300"
907
  "btst %Z1,%Y0"
908
  [(set_attr "length" "2")
909
   (set_attr "cc" "set_zn")])
910
 
911
(define_insn_and_split "*tst_extzv_1_n"
912
  [(set (cc0) (compare
913
               (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
914
                                (const_int 1)
915
                                (match_operand 1 "const_int_operand" "n,n,n"))
916
               (const_int 0)))
917
   (clobber (match_scratch:QI 2 "=X,X,&r"))]
918
  "(TARGET_H8300H || TARGET_H8300S)"
919
  "@
920
   btst\\t%Z1,%Y0
921
   btst\\t%Z1,%Y0
922
   #"
923
  "&& reload_completed
924
   && !satisfies_constraint_U (operands[0])"
925
  [(set (match_dup 2)
926
        (match_dup 0))
927
   (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
928
                                                   (const_int 1)
929
                                                   (match_dup 1))
930
                                  (const_int 0)))
931
              (clobber (scratch:QI))])]
932
  ""
933
  [(set_attr "length" "2,8,10")
934
   (set_attr "cc" "set_zn,set_zn,set_zn")])
935
 
936
(define_insn ""
937
  [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
938
                                        (const_int 1)
939
                                        (match_operand 1 "const_int_operand" "n"))
940
                       (const_int 0)))]
941
  "(TARGET_H8300H || TARGET_H8300S)
942
   && INTVAL (operands[1]) <= 15"
943
  "btst %Z1,%Y0"
944
  [(set_attr "length" "2")
945
   (set_attr "cc" "set_zn")])
946
 
947
(define_insn_and_split "*tstsi_upper_bit"
948
  [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
949
                                        (const_int 1)
950
                                        (match_operand 1 "const_int_operand" "n"))
951
                       (const_int 0)))
952
   (clobber (match_scratch:SI 2 "=&r"))]
953
  "(TARGET_H8300H || TARGET_H8300S)
954
   && INTVAL (operands[1]) >= 16"
955
  "#"
956
  "&& reload_completed"
957
  [(set (match_dup 2)
958
        (ior:SI (and:SI (match_dup 2)
959
                        (const_int -65536))
960
                (lshiftrt:SI (match_dup 0)
961
                             (const_int 16))))
962
   (set (cc0) (compare (zero_extract:SI (match_dup 2)
963
                                        (const_int 1)
964
                                        (match_dup 3))
965
                       (const_int 0)))]
966
  "operands[3] = GEN_INT (INTVAL (operands[1]) - 16);")
967
 
968
(define_insn "*tstsi_variable_bit"
969
  [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
970
                                        (const_int 1)
971
                                        (and:SI (match_operand:SI 1 "register_operand" "r")
972
                                                (const_int 7)))
973
                       (const_int 0)))]
974
  "TARGET_H8300H || TARGET_H8300S"
975
  "btst %w1,%w0"
976
  [(set_attr "length" "2")
977
   (set_attr "cc" "set_zn")])
978
 
979
(define_insn_and_split "*tstsi_variable_bit_qi"
980
  [(set (cc0)
981
        (compare
982
         (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
983
                          (const_int 1)
984
                          (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
985
                                  (const_int 7)))
986
         (const_int 0)))
987
   (clobber (match_scratch:QI 2 "=X,X,&r"))]
988
  "(TARGET_H8300H || TARGET_H8300S)"
989
  "@
990
   btst\\t%w1,%X0
991
   btst\\t%w1,%X0
992
   #"
993
  "&& reload_completed
994
   && !satisfies_constraint_U (operands[0])"
995
  [(set (match_dup 2)
996
        (match_dup 0))
997
   (parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
998
                                                   (const_int 1)
999
                                                   (and:SI (match_dup 1)
1000
                                                           (const_int 7)))
1001
                                  (const_int 0)))
1002
              (clobber (scratch:QI))])]
1003
  ""
1004
  [(set_attr "length" "2,8,10")
1005
   (set_attr "cc" "set_zn,set_zn,set_zn")])
1006
 
1007
(define_insn "*tstqi"
1008
  [(set (cc0) (compare (match_operand:QI 0 "register_operand" "r")
1009
                       (const_int 0)))]
1010
  ""
1011
  "mov.b        %X0,%X0"
1012
  [(set_attr "length" "2")
1013
   (set_attr "cc" "set_znv")])
1014
 
1015
(define_insn "*tsthi"
1016
  [(set (cc0) (compare (match_operand:HI 0 "register_operand" "r")
1017
                       (const_int 0)))]
1018
  ""
1019
  "mov.w        %T0,%T0"
1020
  [(set_attr "length" "2")
1021
   (set_attr "cc" "set_znv")])
1022
 
1023
(define_insn "*tsthi_upper"
1024
  [(set (cc0) (compare (and:HI (match_operand:HI 0 "register_operand" "r")
1025
                               (const_int -256))
1026
                       (const_int 0)))]
1027
  ""
1028
  "mov.b        %t0,%t0"
1029
  [(set_attr "length" "2")
1030
   (set_attr "cc" "set_znv")])
1031
 
1032
(define_insn "*tstsi"
1033
  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "r")
1034
                       (const_int 0)))]
1035
  "TARGET_H8300H || TARGET_H8300S"
1036
  "mov.l        %S0,%S0"
1037
  [(set_attr "length" "2")
1038
   (set_attr "cc" "set_znv")])
1039
 
1040
(define_insn "*tstsi_upper"
1041
  [(set (cc0) (compare (and:SI (match_operand:SI 0 "register_operand" "r")
1042
                               (const_int -65536))
1043
                       (const_int 0)))]
1044
  ""
1045
  "mov.w        %e0,%e0"
1046
  [(set_attr "length" "2")
1047
   (set_attr "cc" "set_znv")])
1048
 
1049
(define_insn "*cmpqi"
1050
  [(set (cc0)
1051
        (compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
1052
                 (match_operand:QI 1 "h8300_src_operand" "rQi")))]
1053
  ""
1054
  "cmp.b        %X1,%X0"
1055
  [(set_attr "length_table" "addb")
1056
   (set_attr "cc" "compare")])
1057
 
1058
(define_insn "*cmphi_h8300_znvc"
1059
  [(set (cc0)
1060
        (compare (match_operand:HI 0 "register_operand" "r")
1061
                 (match_operand:HI 1 "register_operand" "r")))]
1062
  "TARGET_H8300"
1063
  "cmp.w        %T1,%T0"
1064
  [(set_attr "length" "2")
1065
   (set_attr "cc" "compare")])
1066
 
1067
(define_insn "*cmphi_h8300hs_znvc"
1068
  [(set (cc0)
1069
        (compare (match_operand:HI 0 "h8300_dst_operand" "rU,rQ")
1070
                 (match_operand:HI 1 "h8300_src_operand" "P3>X,rQi")))]
1071
  "TARGET_H8300H || TARGET_H8300S"
1072
  "*
1073
{
1074
  switch (which_alternative)
1075
    {
1076
    case 0:
1077
      if (!TARGET_H8300SX)
1078
        return \"cmp.w  %T1,%T0\";
1079
      else
1080
        return \"cmp.w  %T1:3,%T0\";
1081
    case 1:
1082
      return \"cmp.w    %T1,%T0\";
1083
    default:
1084
      gcc_unreachable ();
1085
      }
1086
}"
1087
  [(set_attr "length_table" "short_immediate,addw")
1088
   (set_attr "cc" "compare,compare")])
1089
 
1090
(define_insn "cmpsi"
1091
  [(set (cc0)
1092
        (compare (match_operand:SI 0 "h8300_dst_operand" "r,rQ")
1093
                 (match_operand:SI 1 "h8300_src_operand" "P3>X,rQi")))]
1094
  "TARGET_H8300H || TARGET_H8300S"
1095
  "*
1096
{
1097
  switch (which_alternative)
1098
    {
1099
    case 0:
1100
      if (!TARGET_H8300SX)
1101
        return \"cmp.l  %S1,%S0\";
1102
      else
1103
        return \"cmp.l  %S1:3,%S0\";
1104
    case 1:
1105
      return \"cmp.l    %S1,%S0\";
1106
    default:
1107
      gcc_unreachable ();
1108
    }
1109
}"
1110
  [(set_attr "length" "2,*")
1111
   (set_attr "length_table" "*,addl")
1112
   (set_attr "cc" "compare,compare")])
1113
 
1114
;; ----------------------------------------------------------------------
1115
;; ADD INSTRUCTIONS
1116
;; ----------------------------------------------------------------------
1117
 
1118
(define_expand "addqi3"
1119
  [(set (match_operand:QI 0 "register_operand" "")
1120
        (plus:QI (match_operand:QI 1 "register_operand" "")
1121
                 (match_operand:QI 2 "h8300_src_operand" "")))]
1122
  ""
1123
  "")
1124
 
1125
(define_insn "*addqi3"
1126
  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
1127
        (plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
1128
                 (match_operand:QI 2 "h8300_src_operand" "rQi")))]
1129
  "h8300_operands_match_p (operands)"
1130
  "add.b        %X2,%X0"
1131
  [(set_attr "length_table" "addb")
1132
   (set_attr "cc" "set_zn")])
1133
 
1134
(define_expand "addhi3"
1135
  [(set (match_operand:HI 0 "register_operand" "")
1136
        (plus:HI (match_operand:HI 1 "register_operand" "")
1137
                 (match_operand:HI 2 "h8300_src_operand" "")))]
1138
  ""
1139
  "")
1140
 
1141
(define_insn "*addhi3_h8300"
1142
  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1143
        (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
1144
                 (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
1145
  "TARGET_H8300"
1146
  "@
1147
   adds %2,%T0
1148
   subs %G2,%T0
1149
   add.b        %t2,%t0
1150
   add.b        %s2,%s0\;addx   %t2,%t0
1151
   add.w        %T2,%T0"
1152
  [(set_attr "length" "2,2,2,4,2")
1153
   (set_attr "cc" "none_0hit,none_0hit,clobber,clobber,set_zn")])
1154
 
1155
;; This splitter is very important to make the stack adjustment
1156
;; interrupt-safe.  The combination of add.b and addx is unsafe!
1157
;;
1158
;; We apply this split after the peephole2 pass so that we won't end
1159
;; up creating too many adds/subs when a scratch register is
1160
;; available, which is actually a common case because stack unrolling
1161
;; tends to happen immediately after a function call.
1162
 
1163
(define_split
1164
  [(set (match_operand:HI 0 "stack_pointer_operand" "")
1165
        (plus:HI (match_dup 0)
1166
                 (match_operand 1 "const_int_gt_2_operand" "")))]
1167
  "TARGET_H8300 && epilogue_completed"
1168
  [(const_int 0)]
1169
  "split_adds_subs (HImode, operands); DONE;")
1170
 
1171
(define_peephole2
1172
  [(match_scratch:HI 2 "r")
1173
   (set (match_operand:HI 0 "stack_pointer_operand" "")
1174
        (plus:HI (match_dup 0)
1175
                 (match_operand:HI 1 "const_int_ge_8_operand" "")))]
1176
  "TARGET_H8300"
1177
  [(set (match_dup 2)
1178
        (match_dup 1))
1179
   (set (match_dup 0)
1180
        (plus:HI (match_dup 0)
1181
                 (match_dup 2)))]
1182
  "")
1183
 
1184
(define_insn "*addhi3_h8300hs"
1185
  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
1186
        (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
1187
                 (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
1188
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
1189
  "@
1190
   adds %2,%S0
1191
   subs %G2,%S0
1192
   add.b        %t2,%t0
1193
   add.w        %T2,%T0
1194
   add.w        %T2,%T0"
1195
  [(set_attr "length" "2,2,2,4,2")
1196
   (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
1197
 
1198
(define_insn "*addhi3_incdec"
1199
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1200
        (unspec:HI [(match_operand:HI 1 "register_operand" "0,0")
1201
                    (match_operand:HI 2 "incdec_operand" "M,O")]
1202
                   UNSPEC_INCDEC))]
1203
  "TARGET_H8300H || TARGET_H8300S"
1204
  "@
1205
   inc.w        %2,%T0
1206
   dec.w        %G2,%T0"
1207
  [(set_attr "length" "2,2")
1208
   (set_attr "cc" "set_zn,set_zn")])
1209
 
1210
(define_insn "*addhi3_h8sx"
1211
  [(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
1212
        (plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
1213
                 (match_operand:HI 2 "h8300_src_operand" "P3>X,P3
1214
  "TARGET_H8300SX && h8300_operands_match_p (operands)"
1215
  "@
1216
   add.w        %T2:3,%T0
1217
   sub.w        %G2:3,%T0
1218
   add.b        %t2,%t0
1219
   add.w        %T2,%T0"
1220
  [(set_attr "length_table" "short_immediate,short_immediate,*,addw")
1221
   (set_attr "length" "*,*,2,*")
1222
   (set_attr "cc" "set_zn")])
1223
 
1224
(define_split
1225
  [(set (match_operand:HI 0 "register_operand" "")
1226
        (plus:HI (match_dup 0)
1227
                 (match_operand:HI 1 "two_insn_adds_subs_operand" "")))]
1228
  ""
1229
  [(const_int 0)]
1230
  "split_adds_subs (HImode, operands); DONE;")
1231
 
1232
(define_expand "addsi3"
1233
  [(set (match_operand:SI 0 "register_operand" "")
1234
        (plus:SI (match_operand:SI 1 "register_operand" "")
1235
                 (match_operand:SI 2 "h8300_src_operand" "")))]
1236
  ""
1237
  "")
1238
 
1239
(define_insn "*addsi_h8300"
1240
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1241
        (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
1242
                 (match_operand:SI 2 "h8300_src_operand" "n,r")))]
1243
  "TARGET_H8300"
1244
  "* return output_plussi (operands);"
1245
  [(set (attr "length")
1246
        (symbol_ref "compute_plussi_length (operands)"))
1247
   (set (attr "cc")
1248
        (symbol_ref "compute_plussi_cc (operands)"))])
1249
 
1250
(define_insn "*addsi_h8300hs"
1251
  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
1252
        (plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
1253
                 (match_operand:SI 2 "h8300_src_operand" "i,rQ")))]
1254
  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1255
  "* return output_plussi (operands);"
1256
  [(set (attr "length")
1257
        (symbol_ref "compute_plussi_length (operands)"))
1258
   (set (attr "cc")
1259
        (symbol_ref "compute_plussi_cc (operands)"))])
1260
 
1261
(define_insn "*addsi3_incdec"
1262
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1263
        (unspec:SI [(match_operand:SI 1 "register_operand" "0,0")
1264
                    (match_operand:SI 2 "incdec_operand" "M,O")]
1265
                   UNSPEC_INCDEC))]
1266
  "TARGET_H8300H || TARGET_H8300S"
1267
  "@
1268
   inc.l        %2,%S0
1269
   dec.l        %G2,%S0"
1270
  [(set_attr "length" "2,2")
1271
   (set_attr "cc" "set_zn,set_zn")])
1272
 
1273
(define_split
1274
  [(set (match_operand:SI 0 "register_operand" "")
1275
        (plus:SI (match_dup 0)
1276
                 (match_operand:SI 1 "two_insn_adds_subs_operand" "")))]
1277
  "TARGET_H8300H || TARGET_H8300S"
1278
  [(const_int 0)]
1279
  "split_adds_subs (SImode, operands); DONE;")
1280
 
1281
;; ----------------------------------------------------------------------
1282
;; SUBTRACT INSTRUCTIONS
1283
;; ----------------------------------------------------------------------
1284
 
1285
(define_expand "subqi3"
1286
  [(set (match_operand:QI 0 "register_operand" "")
1287
        (minus:QI (match_operand:QI 1 "register_operand" "")
1288
                  (match_operand:QI 2 "h8300_src_operand" "")))]
1289
  ""
1290
  "")
1291
 
1292
(define_insn "*subqi3"
1293
  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
1294
        (minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
1295
                  (match_operand:QI 2 "h8300_dst_operand" "rQ")))]
1296
  "h8300_operands_match_p (operands)"
1297
  "sub.b        %X2,%X0"
1298
  [(set_attr "length_table" "addb")
1299
   (set_attr "cc" "set_zn")])
1300
 
1301
(define_expand "subhi3"
1302
  [(set (match_operand:HI 0 "register_operand" "")
1303
        (minus:HI (match_operand:HI 1 "register_operand" "")
1304
                  (match_operand:HI 2 "h8300_src_operand" "")))]
1305
  ""
1306
  "")
1307
 
1308
(define_insn "*subhi3_h8300"
1309
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1310
        (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1311
                  (match_operand:HI 2 "h8300_src_operand" "r,n")))]
1312
  "TARGET_H8300"
1313
  "@
1314
   sub.w        %T2,%T0
1315
   add.b        %E2,%s0\;addx   %F2,%t0"
1316
  [(set_attr "length" "2,4")
1317
   (set_attr "cc" "set_zn,clobber")])
1318
 
1319
(define_insn "*subhi3_h8300hs"
1320
  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ,rQ")
1321
        (minus:HI (match_operand:HI 1 "h8300_dst_operand" "0,0")
1322
                  (match_operand:HI 2 "h8300_src_operand" "rQ,i")))]
1323
  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1324
  "@
1325
   sub.w        %T2,%T0
1326
   sub.w        %T2,%T0"
1327
  [(set_attr "length_table" "addw")
1328
   (set_attr "cc" "set_zn")])
1329
 
1330
(define_expand "subsi3"
1331
  [(set (match_operand:SI 0 "register_operand" "")
1332
        (minus:SI (match_operand:SI 1 "register_operand" "")
1333
                  (match_operand:SI 2 "h8300_src_operand" "")))]
1334
  ""
1335
{
1336
  if (TARGET_H8300)
1337
    operands[2] = force_reg (SImode, operands[2]);
1338
})
1339
 
1340
(define_insn "*subsi3_h8300"
1341
  [(set (match_operand:SI 0 "register_operand" "=r")
1342
        (minus:SI (match_operand:SI 1 "register_operand" "0")
1343
                  (match_operand:SI 2 "register_operand" "r")))]
1344
  "TARGET_H8300"
1345
  "sub.w        %f2,%f0\;subx   %y2,%y0\;subx   %z2,%z0"
1346
  [(set_attr "length" "6")])
1347
 
1348
(define_insn "*subsi3_h8300hs"
1349
  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
1350
        (minus:SI (match_operand:SI 1 "h8300_dst_operand" "0,0")
1351
                  (match_operand:SI 2 "h8300_src_operand" "rQ,i")))]
1352
  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
1353
  "@
1354
   sub.l        %S2,%S0
1355
   sub.l        %S2,%S0"
1356
  [(set_attr "length_table" "addl")
1357
   (set_attr "cc" "set_zn")])
1358
 
1359
;; ----------------------------------------------------------------------
1360
;; MULTIPLY INSTRUCTIONS
1361
;; ----------------------------------------------------------------------
1362
 
1363
;; Note that the H8/300 can only handle umulqihi3.
1364
 
1365
(define_expand "mulqihi3"
1366
  [(set (match_operand:HI 0 "register_operand" "")
1367
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" ""))
1368
                 ;; intentionally-mismatched modes
1369
                 (match_operand:QI 2 "reg_or_nibble_operand" "")))]
1370
  "TARGET_H8300H || TARGET_H8300S"
1371
  "
1372
{
1373
  if (GET_MODE (operands[2]) != VOIDmode)
1374
    operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]);
1375
}")
1376
 
1377
(define_insn "*mulqihi3_const"
1378
  [(set (match_operand:HI 0 "register_operand" "=r")
1379
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1380
                 (match_operand:QI 2 "nibble_operand" "IP4>X")))]
1381
  "TARGET_H8300SX"
1382
  "mulxs.b      %X2,%T0"
1383
  [(set_attr "length" "4")
1384
   (set_attr "cc" "set_zn")])
1385
 
1386
(define_insn "*mulqihi3"
1387
  [(set (match_operand:HI 0 "register_operand" "=r")
1388
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1389
                 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1390
  "TARGET_H8300H || TARGET_H8300S"
1391
  "mulxs.b      %X2,%T0"
1392
  [(set_attr "length" "4")
1393
   (set_attr "cc" "set_zn")])
1394
 
1395
(define_expand "mulhisi3"
1396
  [(set (match_operand:SI 0 "register_operand" "")
1397
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1398
                 ;; intentionally-mismatched modes
1399
                 (match_operand:HI 2 "reg_or_nibble_operand" "")))]
1400
  "TARGET_H8300H || TARGET_H8300S"
1401
  "
1402
{
1403
  if (GET_MODE (operands[2]) != VOIDmode)
1404
    operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]);
1405
}")
1406
 
1407
(define_insn "*mulhisi3_const"
1408
  [(set (match_operand:SI 0 "register_operand" "=r")
1409
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1410
                 (match_operand:SI 2 "nibble_operand" "IP4>X")))]
1411
  "TARGET_H8300SX"
1412
  "mulxs.w      %T2,%S0"
1413
  [(set_attr "length" "4")
1414
   (set_attr "cc" "set_zn")])
1415
 
1416
(define_insn "*mulhisi3"
1417
  [(set (match_operand:SI 0 "register_operand" "=r")
1418
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1419
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1420
  "TARGET_H8300H || TARGET_H8300S"
1421
  "mulxs.w      %T2,%S0"
1422
  [(set_attr "length" "4")
1423
   (set_attr "cc" "set_zn")])
1424
 
1425
(define_expand "umulqihi3"
1426
  [(set (match_operand:HI 0 "register_operand" "")
1427
        (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" ""))
1428
                 ;; intentionally-mismatched modes
1429
                 (match_operand:QI 2 "reg_or_nibble_operand" "")))]
1430
  "TARGET_H8300H || TARGET_H8300S"
1431
  "
1432
{
1433
  if (GET_MODE (operands[2]) != VOIDmode)
1434
    operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]);
1435
}")
1436
 
1437
(define_insn "*umulqihi3_const"
1438
  [(set (match_operand:HI 0 "register_operand" "=r")
1439
        (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1440
                 (match_operand:QI 2 "nibble_operand" "IP4>X")))]
1441
  "TARGET_H8300SX"
1442
  "mulxu.b      %X2,%T0"
1443
  [(set_attr "length" "4")
1444
   (set_attr "cc" "set_zn")])
1445
 
1446
(define_insn "*umulqihi3"
1447
  [(set (match_operand:HI 0 "register_operand" "=r")
1448
        (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
1449
                 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1450
  ""
1451
  "mulxu.b      %X2,%T0"
1452
  [(set_attr "length" "2")
1453
   (set_attr "cc" "none_0hit")])
1454
 
1455
(define_expand "umulhisi3"
1456
  [(set (match_operand:SI 0 "register_operand" "")
1457
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1458
                 ;; intentionally-mismatched modes
1459
                 (match_operand:HI 2 "reg_or_nibble_operand" "")))]
1460
  "TARGET_H8300H || TARGET_H8300S"
1461
  "
1462
{
1463
  if (GET_MODE (operands[2]) != VOIDmode)
1464
    operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]);
1465
}")
1466
 
1467
(define_insn "*umulhisi3_const"
1468
  [(set (match_operand:SI 0 "register_operand" "=r")
1469
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1470
                 (match_operand:SI 2 "nibble_operand" "IP4>X")))]
1471
  "TARGET_H8300SX"
1472
  "mulxu.w      %T2,%S0"
1473
  [(set_attr "length" "4")
1474
   (set_attr "cc" "set_zn")])
1475
 
1476
(define_insn "*umulhisi3"
1477
  [(set (match_operand:SI 0 "register_operand" "=r")
1478
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
1479
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1480
  "TARGET_H8300H || TARGET_H8300S"
1481
  "mulxu.w      %T2,%S0"
1482
  [(set_attr "length" "2")
1483
   (set_attr "cc" "none_0hit")])
1484
 
1485
;; We could have used mulu.[wl] here, but mulu.[lw] is only available
1486
;; on a H8SX with a multiplier, whereas muls.w seems to be available
1487
;; on all H8SX variants.
1488
(define_insn "mulhi3"
1489
  [(set (match_operand:HI 0 "register_operand" "=r")
1490
        (mult:HI (match_operand:HI 1 "register_operand" "%0")
1491
                 (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
1492
  "TARGET_H8300SX"
1493
  "muls.w\\t%T2,%T0"
1494
  [(set_attr "length" "2")
1495
   (set_attr "cc" "set_zn")])
1496
 
1497
(define_insn "mulsi3"
1498
  [(set (match_operand:SI 0 "register_operand" "=r")
1499
        (mult:SI (match_operand:SI 1 "register_operand" "%0")
1500
                 (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
1501
  "TARGET_H8300SX"
1502
  "muls.l\\t%S2,%S0"
1503
  [(set_attr "length" "2")
1504
   (set_attr "cc" "set_zn")])
1505
 
1506
(define_insn "smulsi3_highpart"
1507
  [(set (match_operand:SI 0 "register_operand" "=r")
1508
        (truncate:SI
1509
         (lshiftrt:DI
1510
          (mult:DI
1511
           (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1512
           (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
1513
          (const_int 32))))]
1514
  "TARGET_H8300SXMUL"
1515
  "muls/u.l\\t%S2,%S0"
1516
  [(set_attr "length" "2")
1517
   (set_attr "cc" "set_zn")])
1518
 
1519
(define_insn "umulsi3_highpart"
1520
  [(set (match_operand:SI 0 "register_operand" "=r")
1521
        (truncate:SI
1522
         (ashiftrt:DI
1523
          (mult:DI
1524
           (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
1525
           (zero_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
1526
          (const_int 32))))]
1527
  "TARGET_H8300SX"
1528
  "mulu/u.l\\t%S2,%S0"
1529
  [(set_attr "length" "2")
1530
   (set_attr "cc" "none_0hit")])
1531
 
1532
;; This is a "bridge" instruction.  Combine can't cram enough insns
1533
;; together to crate a MAC instruction directly, but it can create
1534
;; this instruction, which then allows combine to create the real
1535
;; MAC insn.
1536
;;
1537
;; Unfortunately, if combine doesn't create a MAC instruction, this
1538
;; insn must generate reasonably correct code.  Egad.
1539
(define_insn ""
1540
  [(set (match_operand:SI 0 "register_operand" "=a")
1541
        (mult:SI
1542
          (sign_extend:SI
1543
            (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1544
          (sign_extend:SI
1545
            (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))]
1546
  "TARGET_MAC"
1547
  "clrmac\;mac  @%2+,@%1+"
1548
  [(set_attr "length" "6")
1549
   (set_attr "cc" "none_0hit")])
1550
 
1551
(define_insn ""
1552
  [(set (match_operand:SI 0 "register_operand" "=a")
1553
        (plus:SI (mult:SI
1554
          (sign_extend:SI (mem:HI
1555
            (post_inc:SI (match_operand:SI 1 "register_operand" "r"))))
1556
          (sign_extend:SI (mem:HI
1557
            (post_inc:SI (match_operand:SI 2 "register_operand" "r")))))
1558
              (match_operand:SI 3 "register_operand" "0")))]
1559
  "TARGET_MAC"
1560
  "mac  @%2+,@%1+"
1561
  [(set_attr "length" "4")
1562
   (set_attr "cc" "none_0hit")])
1563
 
1564
;; ----------------------------------------------------------------------
1565
;; DIVIDE/MOD INSTRUCTIONS
1566
;; ----------------------------------------------------------------------
1567
 
1568
(define_insn "udivhi3"
1569
  [(set (match_operand:HI 0 "register_operand" "=r")
1570
        (udiv:HI
1571
         (match_operand:HI 1 "register_operand" "0")
1572
         (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
1573
  "TARGET_H8300SX"
1574
  "divu.w\\t%T2,%T0"
1575
  [(set_attr "length" "2")])
1576
 
1577
(define_insn "divhi3"
1578
  [(set (match_operand:HI 0 "register_operand" "=r")
1579
        (div:HI
1580
         (match_operand:HI 1 "register_operand" "0")
1581
         (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
1582
  "TARGET_H8300SX"
1583
  "divs.w\\t%T2,%T0"
1584
  [(set_attr "length" "2")])
1585
 
1586
(define_insn "udivsi3"
1587
  [(set (match_operand:SI 0 "register_operand" "=r")
1588
        (udiv:SI
1589
         (match_operand:SI 1 "register_operand" "0")
1590
         (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
1591
  "TARGET_H8300SX"
1592
  "divu.l\\t%S2,%S0"
1593
  [(set_attr "length" "2")])
1594
 
1595
(define_insn "divsi3"
1596
  [(set (match_operand:SI 0 "register_operand" "=r")
1597
        (div:SI
1598
         (match_operand:SI 1 "register_operand" "0")
1599
         (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
1600
  "TARGET_H8300SX"
1601
  "divs.l\\t%S2,%S0"
1602
  [(set_attr "length" "2")])
1603
 
1604
(define_insn "udivmodqi4"
1605
  [(set (match_operand:QI 0 "register_operand" "=r")
1606
        (truncate:QI
1607
          (udiv:HI
1608
            (match_operand:HI 1 "register_operand" "0")
1609
            (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1610
   (set (match_operand:QI 3 "register_operand" "=r")
1611
        (truncate:QI
1612
          (umod:HI
1613
            (match_dup 1)
1614
            (zero_extend:HI (match_dup 2)))))]
1615
  ""
1616
  "*
1617
{
1618
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
1619
    return \"divxu.b\\t%X2,%T0\";
1620
  else
1621
    return \"divxu.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
1622
}"
1623
  [(set_attr "length" "4")])
1624
 
1625
(define_insn "divmodqi4"
1626
  [(set (match_operand:QI 0 "register_operand" "=r")
1627
        (truncate:QI
1628
          (div:HI
1629
            (match_operand:HI 1 "register_operand" "0")
1630
            (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))
1631
   (set (match_operand:QI 3 "register_operand" "=r")
1632
        (truncate:QI
1633
          (mod:HI
1634
            (match_dup 1)
1635
            (sign_extend:HI (match_dup 2)))))]
1636
  "TARGET_H8300H || TARGET_H8300S"
1637
  "*
1638
{
1639
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
1640
    return \"divxs.b\\t%X2,%T0\";
1641
  else
1642
    return \"divxs.b\\t%X2,%T0\;mov.b\\t%t0,%s3\";
1643
}"
1644
  [(set_attr "length" "6")])
1645
 
1646
(define_insn "udivmodhi4"
1647
  [(set (match_operand:HI 0 "register_operand" "=r")
1648
        (truncate:HI
1649
          (udiv:SI
1650
            (match_operand:SI 1 "register_operand" "0")
1651
            (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1652
   (set (match_operand:HI 3 "register_operand" "=r")
1653
        (truncate:HI
1654
          (umod:SI
1655
            (match_dup 1)
1656
            (zero_extend:SI (match_dup 2)))))]
1657
  "TARGET_H8300H || TARGET_H8300S"
1658
  "*
1659
{
1660
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
1661
    return \"divxu.w\\t%T2,%S0\";
1662
  else
1663
    return \"divxu.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
1664
}"
1665
  [(set_attr "length" "4")])
1666
 
1667
(define_insn "divmodhi4"
1668
  [(set (match_operand:HI 0 "register_operand" "=r")
1669
        (truncate:HI
1670
          (div:SI
1671
            (match_operand:SI 1 "register_operand" "0")
1672
            (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))
1673
   (set (match_operand:HI 3 "register_operand" "=r")
1674
        (truncate:HI
1675
          (mod:SI
1676
            (match_dup 1)
1677
            (sign_extend:SI (match_dup 2)))))]
1678
  "TARGET_H8300H || TARGET_H8300S"
1679
  "*
1680
{
1681
  if (find_reg_note (insn, REG_UNUSED, operands[3]))
1682
    return \"divxs.w\\t%T2,%S0\";
1683
  else
1684
    return \"divxs.w\\t%T2,%S0\;mov.w\\t%e0,%f3\";
1685
}"
1686
  [(set_attr "length" "6")])
1687
 
1688
;; ----------------------------------------------------------------------
1689
;; AND INSTRUCTIONS
1690
;; ----------------------------------------------------------------------
1691
(define_insn "bclrqi_msx"
1692
  [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1693
        (and:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1694
                (match_operand:QI 2 "single_zero_operand" "Y0")))]
1695
  "TARGET_H8300SX
1696
   && rtx_equal_p(operands[0], operands[1])"
1697
  "bclr\\t%W2,%0"
1698
  [(set_attr "length" "8")])
1699
 
1700
(define_split
1701
  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=U")
1702
        (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1703
                (match_operand:HI 2 "single_zero_operand" "Y0")))]
1704
  "TARGET_H8300SX"
1705
  [(set (match_dup 0)
1706
        (and:QI (match_dup 1)
1707
                (match_dup 2)))]
1708
{
1709
  if (abs (INTVAL (operands[2])) > 0xFF)
1710
    {
1711
      operands[0] = adjust_address (operands[0], QImode, 0);
1712
      operands[1] = adjust_address (operands[1], QImode, 0);
1713
      operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
1714
    }
1715
  else
1716
    {
1717
      operands[0] = adjust_address (operands[0], QImode, 1);
1718
      operands[1] = adjust_address (operands[1], QImode, 1);
1719
    }
1720
})
1721
 
1722
(define_insn "bclrhi_msx"
1723
  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1724
        (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1725
                (match_operand:HI 2 "single_zero_operand" "Y0")))]
1726
  "TARGET_H8300SX"
1727
  "bclr\\t%W2,%0"
1728
  [(set_attr "length" "8")])
1729
 
1730
(define_insn "*andqi3_2"
1731
  [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
1732
        (and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
1733
                (match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
1734
  "TARGET_H8300SX"
1735
  "@
1736
   bclr\\t %W2,%R0
1737
   and  %X2,%X0
1738
   bfld %2,%1,%R0"
1739
  [(set_attr "length" "8,*,8")
1740
   (set_attr "length_table" "*,logicb,*")
1741
   (set_attr "cc" "none_0hit,set_znv,none_0hit")])
1742
 
1743
(define_insn "andqi3_1"
1744
  [(set (match_operand:QI 0 "bit_operand" "=U,r")
1745
        (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
1746
                (match_operand:QI 2 "h8300_src_operand" "Y0,rn")))]
1747
  "register_operand (operands[0], QImode)
1748
   || single_zero_operand (operands[2], QImode)"
1749
  "@
1750
   bclr %W2,%R0
1751
   and  %X2,%X0"
1752
  [(set_attr "length" "2,8")
1753
   (set_attr "cc" "none_0hit,set_znv")])
1754
 
1755
(define_expand "andqi3"
1756
  [(set (match_operand:QI 0 "register_operand" "")
1757
        (and:QI (match_operand:QI 1 "register_operand" "")
1758
                (match_operand:QI 2 "h8300_src_operand" "")))]
1759
  ""
1760
  "")
1761
 
1762
(define_expand "andhi3"
1763
  [(set (match_operand:HI 0 "register_operand" "")
1764
        (and:HI (match_operand:HI 1 "register_operand" "")
1765
                (match_operand:HI 2 "h8300_src_operand" "")))]
1766
  ""
1767
  "")
1768
 
1769
(define_insn "*andorqi3"
1770
  [(set (match_operand:QI 0 "register_operand" "=r")
1771
        (ior:QI (and:QI (match_operand:QI 2 "register_operand" "r")
1772
                        (match_operand:QI 3 "single_one_operand" "n"))
1773
                (match_operand:QI 1 "register_operand" "0")))]
1774
  ""
1775
  "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"
1776
  [(set_attr "length" "6")])
1777
 
1778
(define_insn "*andorhi3"
1779
  [(set (match_operand:HI 0 "register_operand" "=r")
1780
        (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r")
1781
                        (match_operand:HI 3 "single_one_operand" "n"))
1782
                (match_operand:HI 1 "register_operand" "0")))]
1783
  ""
1784
  "*
1785
{
1786
  operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1787
  if (INTVAL (operands[3]) > 128)
1788
    {
1789
      operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1790
      return \"bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0\";
1791
    }
1792
  return \"bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0\";
1793
}"
1794
  [(set_attr "length" "6")])
1795
 
1796
(define_insn "*andorsi3"
1797
  [(set (match_operand:SI 0 "register_operand" "=r")
1798
        (ior:SI (and:SI (match_operand:SI 2 "register_operand" "r")
1799
                        (match_operand:SI 3 "single_one_operand" "n"))
1800
                (match_operand:SI 1 "register_operand" "0")))]
1801
  "(INTVAL (operands[3]) & 0xffff) != 0"
1802
  "*
1803
{
1804
  operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
1805
  if (INTVAL (operands[3]) > 128)
1806
    {
1807
      operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
1808
      return \"bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0\";
1809
    }
1810
  return \"bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0\";
1811
}"
1812
  [(set_attr "length" "6")])
1813
 
1814
(define_insn "*andorsi3_shift_8"
1815
  [(set (match_operand:SI 0 "register_operand" "=r")
1816
        (ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
1817
                                   (const_int 8))
1818
                        (const_int 65280))
1819
                (match_operand:SI 1 "register_operand" "0")))]
1820
  ""
1821
  "or.b\\t%w2,%x0"
1822
  [(set_attr "length" "2")])
1823
 
1824
(define_expand "andsi3"
1825
  [(set (match_operand:SI 0 "register_operand" "")
1826
        (and:SI (match_operand:SI 1 "register_operand" "")
1827
                (match_operand:SI 2 "h8300_src_operand" "")))]
1828
  ""
1829
  "")
1830
 
1831
;; ----------------------------------------------------------------------
1832
;; OR INSTRUCTIONS
1833
;; ----------------------------------------------------------------------
1834
 
1835
(define_insn "bsetqi_msx"
1836
  [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1837
        (ior:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1838
                (match_operand:QI 2 "single_one_operand" "Y2")))]
1839
  "TARGET_H8300SX
1840
   && rtx_equal_p(operands[0], operands[1])"
1841
  "bset\\t%V2,%0"
1842
  [(set_attr "length" "8")])
1843
 
1844
(define_split
1845
  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=U")
1846
        (ior:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1847
                (match_operand:HI 2 "single_one_operand" "Y2")))]
1848
  "TARGET_H8300SX"
1849
  [(set (match_dup 0)
1850
        (ior:QI (match_dup 1)
1851
                (match_dup 2)))]
1852
{
1853
  if (abs (INTVAL (operands[2])) > 0xFF)
1854
    {
1855
      operands[0] = adjust_address (operands[0], QImode, 0);
1856
      operands[1] = adjust_address (operands[1], QImode, 0);
1857
      operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
1858
    }
1859
  else
1860
    {
1861
      operands[0] = adjust_address (operands[0], QImode, 1);
1862
      operands[1] = adjust_address (operands[1], QImode, 1);
1863
    }
1864
})
1865
 
1866
(define_insn "bsethi_msx"
1867
  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1868
        (ior:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1869
                (match_operand:HI 2 "single_one_operand" "Y2")))]
1870
  "TARGET_H8300SX"
1871
  "bset\\t%V2,%0"
1872
  [(set_attr "length" "8")])
1873
 
1874
(define_insn "iorqi3_1"
1875
  [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
1876
        (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
1877
                (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
1878
  "TARGET_H8300SX || register_operand (operands[0], QImode)
1879
   || single_one_operand (operands[2], QImode)"
1880
  "@
1881
   bset\\t%V2,%R0
1882
   or\\t%X2,%X0"
1883
  [(set_attr "length" "8,*")
1884
   (set_attr "length_table" "*,logicb")
1885
   (set_attr "cc" "none_0hit,set_znv")])
1886
 
1887
 
1888
(define_expand "iorqi3"
1889
  [(set (match_operand:QI 0 "register_operand" "")
1890
        (ior:QI (match_operand:QI 1 "register_operand" "")
1891
                (match_operand:QI 2 "h8300_src_operand" "")))]
1892
  ""
1893
  "")
1894
 
1895
(define_expand "iorhi3"
1896
  [(set (match_operand:HI 0 "register_operand" "")
1897
        (ior:HI (match_operand:HI 1 "register_operand" "")
1898
                (match_operand:HI 2 "h8300_src_operand" "")))]
1899
  ""
1900
  "")
1901
 
1902
(define_expand "iorsi3"
1903
  [(set (match_operand:SI 0 "register_operand" "")
1904
        (ior:SI (match_operand:SI 1 "register_operand" "")
1905
                (match_operand:SI 2 "h8300_src_operand" "")))]
1906
  ""
1907
  "")
1908
 
1909
;; ----------------------------------------------------------------------
1910
;; XOR INSTRUCTIONS
1911
;; ----------------------------------------------------------------------
1912
(define_insn "bnotqi_msx"
1913
  [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
1914
        (xor:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
1915
                (match_operand:QI 2 "single_one_operand" "Y2")))]
1916
  "TARGET_H8300SX
1917
   && rtx_equal_p(operands[0], operands[1])"
1918
  "bnot\\t%V2,%0"
1919
  [(set_attr "length" "8")])
1920
 
1921
(define_split
1922
  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=U")
1923
        (xor:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1924
                (match_operand:HI 2 "single_one_operand" "Y2")))]
1925
  "TARGET_H8300SX"
1926
  [(set (match_dup 0)
1927
        (xor:QI (match_dup 1)
1928
                (match_dup 2)))]
1929
{
1930
  if (abs (INTVAL (operands[2])) > 0xFF)
1931
    {
1932
      operands[0] = adjust_address (operands[0], QImode, 0);
1933
      operands[1] = adjust_address (operands[1], QImode, 0);
1934
      operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
1935
    }
1936
  else
1937
    {
1938
      operands[0] = adjust_address (operands[0], QImode, 1);
1939
      operands[1] = adjust_address (operands[1], QImode, 1);
1940
    }
1941
})
1942
 
1943
(define_insn "bnothi_msx"
1944
  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
1945
        (xor:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
1946
                (match_operand:HI 2 "single_one_operand" "Y2")))]
1947
  "TARGET_H8300SX"
1948
  "bnot\\t%V2,%0"
1949
  [(set_attr "length" "8")])
1950
 
1951
(define_insn "xorqi3_1"
1952
  [(set (match_operand:QI 0 "bit_operand" "=U,r")
1953
        (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
1954
                (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
1955
  "TARGET_H8300SX || register_operand (operands[0], QImode)
1956
   || single_one_operand (operands[2], QImode)"
1957
  "@
1958
   bnot\\t%V2,%R0
1959
   xor\\t%X2,%X0"
1960
  [(set_attr "length" "8,*")
1961
   (set_attr "length_table" "*,logicb")
1962
   (set_attr "cc" "none_0hit,set_znv")])
1963
 
1964
 
1965
(define_expand "xorqi3"
1966
  [(set (match_operand:QI 0 "register_operand" "")
1967
        (xor:QI (match_operand:QI 1 "register_operand" "")
1968
                (match_operand:QI 2 "h8300_src_operand" "")))]
1969
  ""
1970
  "")
1971
 
1972
(define_expand "xorhi3"
1973
  [(set (match_operand:HI 0 "register_operand" "")
1974
        (xor:HI (match_operand:HI 1 "register_operand" "")
1975
                (match_operand:HI 2 "h8300_src_operand" "")))]
1976
  ""
1977
  "")
1978
 
1979
(define_expand "xorsi3"
1980
  [(set (match_operand:SI 0 "register_operand" "")
1981
        (xor:SI (match_operand:SI 1 "register_operand" "")
1982
                (match_operand:SI 2 "h8300_src_operand" "")))]
1983
  ""
1984
  "")
1985
 
1986
;; ----------------------------------------------------------------------
1987
;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
1988
;; ----------------------------------------------------------------------
1989
 
1990
;; We need a separate pattern here because machines other than the
1991
;; original H8300 don't have to split the 16-bit operand into a pair
1992
;; of high/low instructions, so we can accept literal addresses, that
1993
;; have to be loaded into a register on H8300.
1994
(define_insn "*logicalhi3_sn"
1995
  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
1996
        (match_operator:HI 3 "bit_operator"
1997
          [(match_operand:HI 1 "h8300_dst_operand" "%0")
1998
           (match_operand:HI 2 "h8300_src_operand" "rQi")]))]
1999
  "(TARGET_H8300S || TARGET_H8300H) && h8300_operands_match_p (operands)"
2000
  "* return output_logical_op (HImode, operands);"
2001
  [(set (attr "length")
2002
        (symbol_ref "compute_logical_op_length (HImode, operands)"))
2003
   (set (attr "cc")
2004
        (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
2005
 
2006
(define_insn "*logicalsi3_sn"
2007
  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2008
        (match_operator:SI 3 "bit_operator"
2009
          [(match_operand:SI 1 "h8300_dst_operand" "%0")
2010
           (match_operand:SI 2 "h8300_src_operand" "rQi")]))]
2011
  "(TARGET_H8300S || TARGET_H8300H) && h8300_operands_match_p (operands)"
2012
  "* return output_logical_op (SImode, operands);"
2013
  [(set (attr "length")
2014
        (symbol_ref "compute_logical_op_length (SImode, operands)"))
2015
   (set (attr "cc")
2016
        (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
2017
 
2018
(define_insn "*logicalhi3"
2019
  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2020
        (match_operator:HI 3 "bit_operator"
2021
          [(match_operand:HI 1 "h8300_dst_operand" "%0")
2022
           (match_operand:HI 2 "h8300_src_operand" "rQi")]))]
2023
  "h8300_operands_match_p (operands)"
2024
  "* return output_logical_op (HImode, operands);"
2025
  [(set (attr "length")
2026
        (symbol_ref "compute_logical_op_length (HImode, operands)"))
2027
   (set (attr "cc")
2028
        (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
2029
 
2030
(define_insn "*logicalsi3"
2031
  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2032
        (match_operator:SI 3 "bit_operator"
2033
          [(match_operand:SI 1 "h8300_dst_operand" "%0")
2034
           (match_operand:SI 2 "h8300_src_operand" "rQi")]))]
2035
  "h8300_operands_match_p (operands)"
2036
  "* return output_logical_op (SImode, operands);"
2037
  [(set (attr "length")
2038
        (symbol_ref "compute_logical_op_length (SImode, operands)"))
2039
   (set (attr "cc")
2040
        (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
2041
 
2042
;; ----------------------------------------------------------------------
2043
;; NEGATION INSTRUCTIONS
2044
;; ----------------------------------------------------------------------
2045
 
2046
(define_expand "negqi2"
2047
  [(set (match_operand:QI 0 "register_operand" "")
2048
        (neg:QI (match_operand:QI 1 "register_operand" "")))]
2049
  ""
2050
  "")
2051
 
2052
(define_insn "*negqi2"
2053
  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
2054
        (neg:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
2055
  ""
2056
  "neg  %X0"
2057
  [(set_attr "length_table" "unary")
2058
   (set_attr "cc" "set_zn")])
2059
 
2060
(define_expand "neghi2"
2061
  [(set (match_operand:HI 0 "register_operand" "")
2062
        (neg:HI (match_operand:HI 1 "register_operand" "")))]
2063
  ""
2064
  "
2065
{
2066
  if (TARGET_H8300)
2067
    {
2068
      emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
2069
      DONE;
2070
    }
2071
}")
2072
 
2073
(define_expand "neghi2_h8300"
2074
  [(set (match_dup 2)
2075
        (not:HI (match_operand:HI 1 "register_operand" "")))
2076
   (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
2077
   (set (match_operand:HI 0 "register_operand" "")
2078
        (match_dup 2))]
2079
  ""
2080
  "operands[2] = gen_reg_rtx (HImode);")
2081
 
2082
(define_insn "*neghi2_h8300hs"
2083
  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2084
        (neg:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
2085
  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
2086
  "neg.w        %T0"
2087
  [(set_attr "length_table" "unary")
2088
   (set_attr "cc" "set_zn")])
2089
 
2090
(define_expand "negsi2"
2091
  [(set (match_operand:SI 0 "register_operand" "")
2092
        (neg:SI (match_operand:SI 1 "register_operand" "")))]
2093
  ""
2094
  "
2095
{
2096
  if (TARGET_H8300)
2097
    {
2098
      emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
2099
      DONE;
2100
    }
2101
}")
2102
 
2103
(define_expand "negsi2_h8300"
2104
  [(set (match_dup 2)
2105
        (not:SI (match_operand:SI 1 "register_operand" "")))
2106
   (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
2107
   (set (match_operand:SI 0 "register_operand" "")
2108
        (match_dup 2))]
2109
  ""
2110
  "operands[2] = gen_reg_rtx (SImode);")
2111
 
2112
(define_insn "*negsi2_h8300hs"
2113
  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2114
        (neg:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
2115
  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
2116
  "neg.l        %S0"
2117
  [(set_attr "length_table" "unary")
2118
   (set_attr "cc" "set_zn")])
2119
 
2120
(define_expand "negsf2"
2121
  [(set (match_operand:SF 0 "register_operand" "")
2122
        (neg:SF (match_operand:SF 1 "register_operand" "")))]
2123
  ""
2124
  "")
2125
 
2126
(define_insn "*negsf2_h8300"
2127
  [(set (match_operand:SF 0 "register_operand" "=r")
2128
        (neg:SF (match_operand:SF 1 "register_operand" "0")))]
2129
  "TARGET_H8300"
2130
  "xor.b\\t#128,%z0"
2131
  [(set_attr "length" "2")])
2132
 
2133
(define_insn "*negsf2_h8300hs"
2134
  [(set (match_operand:SF 0 "register_operand" "=r")
2135
        (neg:SF (match_operand:SF 1 "register_operand" "0")))]
2136
  "TARGET_H8300H || TARGET_H8300S"
2137
  "xor.w\\t#32768,%e0"
2138
  [(set_attr "length" "4")])
2139
 
2140
;; ----------------------------------------------------------------------
2141
;; ABSOLUTE VALUE INSTRUCTIONS
2142
;; ----------------------------------------------------------------------
2143
 
2144
(define_expand "abssf2"
2145
  [(set (match_operand:SF 0 "register_operand" "")
2146
        (abs:SF (match_operand:SF 1 "register_operand" "")))]
2147
  ""
2148
  "")
2149
 
2150
(define_insn "*abssf2_h8300"
2151
  [(set (match_operand:SF 0 "register_operand" "=r")
2152
        (abs:SF (match_operand:SF 1 "register_operand" "0")))]
2153
  "TARGET_H8300"
2154
  "and.b\\t#127,%z0"
2155
  [(set_attr "length" "2")])
2156
 
2157
(define_insn "*abssf2_h8300hs"
2158
  [(set (match_operand:SF 0 "register_operand" "=r")
2159
        (abs:SF (match_operand:SF 1 "register_operand" "0")))]
2160
  "TARGET_H8300H || TARGET_H8300S"
2161
  "and.w\\t#32767,%e0"
2162
  [(set_attr "length" "4")])
2163
 
2164
;; ----------------------------------------------------------------------
2165
;; NOT INSTRUCTIONS
2166
;; ----------------------------------------------------------------------
2167
 
2168
(define_expand "one_cmplqi2"
2169
  [(set (match_operand:QI 0 "register_operand" "")
2170
        (not:QI (match_operand:QI 1 "register_operand" "")))]
2171
  ""
2172
  "")
2173
 
2174
(define_insn "*one_cmplqi2"
2175
  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
2176
        (not:QI (match_operand:QI 1 "h8300_dst_operand" "0")))]
2177
  ""
2178
  "not  %X0"
2179
  [(set_attr "length_table" "unary")
2180
   (set_attr "cc" "set_znv")])
2181
 
2182
(define_expand "one_cmplhi2"
2183
  [(set (match_operand:HI 0 "register_operand" "")
2184
        (not:HI (match_operand:HI 1 "register_operand" "")))]
2185
  ""
2186
  "")
2187
 
2188
(define_insn "*one_cmplhi2_h8300"
2189
  [(set (match_operand:HI 0 "register_operand" "=r")
2190
        (not:HI (match_operand:HI 1 "register_operand" "0")))]
2191
  "TARGET_H8300"
2192
  "not  %s0\;not        %t0"
2193
  [(set_attr "length" "4")])
2194
 
2195
(define_insn "*one_cmplhi2_h8300hs"
2196
  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2197
        (not:HI (match_operand:HI 1 "h8300_dst_operand" "0")))]
2198
  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
2199
  "not.w        %T0"
2200
  [(set_attr "cc" "set_znv")
2201
   (set_attr "length_table" "unary")])
2202
 
2203
(define_expand "one_cmplsi2"
2204
  [(set (match_operand:SI 0 "register_operand" "")
2205
        (not:SI (match_operand:SI 1 "register_operand" "")))]
2206
  ""
2207
  "")
2208
 
2209
(define_insn "*one_cmplsi2_h8300"
2210
  [(set (match_operand:SI 0 "register_operand" "=r")
2211
        (not:SI (match_operand:SI 1 "register_operand" "0")))]
2212
  "TARGET_H8300"
2213
  "not  %w0\;not        %x0\;not        %y0\;not        %z0"
2214
  [(set_attr "length" "8")])
2215
 
2216
(define_insn "*one_cmplsi2_h8300hs"
2217
  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
2218
        (not:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
2219
  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
2220
  "not.l        %S0"
2221
  [(set_attr "cc" "set_znv")
2222
   (set_attr "length_table" "unary")])
2223
 
2224
;; ----------------------------------------------------------------------
2225
;; JUMP INSTRUCTIONS
2226
;; ----------------------------------------------------------------------
2227
 
2228
;; Conditional jump instructions
2229
 
2230
(define_expand "cbranchqi4"
2231
  [(use (match_operator 0 "ordered_comparison_operator"
2232
         [(match_operand:QI 1 "h8300_dst_operand" "")
2233
          (match_operand:QI 2 "h8300_src_operand" "")]))
2234
   (use (match_operand 3 ""))]
2235
  ""
2236
  "h8300_expand_branch (operands); DONE;")
2237
 
2238
(define_expand "cbranchhi4"
2239
  [(use (match_operator 0 "ordered_comparison_operator"
2240
         [(match_operand:HI 1 "h8300_dst_operand" "")
2241
          (match_operand:HI 2 "h8300_src_operand" "")]))
2242
   (use (match_operand 3 ""))]
2243
  ""
2244
  "
2245
{
2246
  /* Force operand1 into a register if we're compiling
2247
     for the H8/300.  */
2248
  if ((GET_CODE (operands[2]) != REG && operands[2] != const0_rtx)
2249
      && TARGET_H8300)
2250
    operands[2] = force_reg (HImode, operands[2]);
2251
  h8300_expand_branch (operands); DONE;
2252
}")
2253
 
2254
(define_expand "cbranchsi4"
2255
  [(use (match_operator 0 "ordered_comparison_operator"
2256
         [(match_operand:SI 1 "h8300_dst_operand" "")
2257
          (match_operand:SI 2 "h8300_src_operand" "")]))
2258
   (use (match_operand 3 ""))]
2259
  "TARGET_H8300H || TARGET_H8300S"
2260
  "h8300_expand_branch (operands); DONE;")
2261
 
2262
(define_insn "branch_true"
2263
  [(set (pc)
2264
        (if_then_else (match_operator 1 "comparison_operator"
2265
                                      [(cc0) (const_int 0)])
2266
                      (label_ref (match_operand 0 "" ""))
2267
                      (pc)))]
2268
  ""
2269
  "*
2270
{
2271
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
2272
      && (GET_CODE (operands[1]) == GT
2273
          || GET_CODE (operands[1]) == GE
2274
          || GET_CODE (operands[1]) == LE
2275
          || GET_CODE (operands[1]) == LT))
2276
    {
2277
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
2278
      return 0;
2279
    }
2280
 
2281
  if (get_attr_length (insn) == 2)
2282
    return \"b%j1       %l0\";
2283
  else if (get_attr_length (insn) == 4)
2284
    return \"b%j1       %l0:16\";
2285
  else
2286
    return \"b%k1       .Lh8BR%=\;jmp   @%l0\\n.Lh8BR%=:\";
2287
}"
2288
 [(set_attr "type" "branch")
2289
   (set_attr "cc" "none")])
2290
 
2291
(define_insn "branch_false"
2292
  [(set (pc)
2293
        (if_then_else (match_operator 1 "comparison_operator"
2294
                                      [(cc0) (const_int 0)])
2295
                      (pc)
2296
                      (label_ref (match_operand 0 "" ""))))]
2297
  ""
2298
  "*
2299
{
2300
  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
2301
      && (GET_CODE (operands[1]) == GT
2302
          || GET_CODE (operands[1]) == GE
2303
          || GET_CODE (operands[1]) == LE
2304
          || GET_CODE (operands[1]) == LT))
2305
    {
2306
      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
2307
      return 0;
2308
    }
2309
 
2310
  if (get_attr_length (insn) == 2)
2311
    return \"b%k1       %l0\";
2312
  else if (get_attr_length (insn) == 4)
2313
    return \"b%k1       %l0:16\";
2314
  else
2315
    return \"b%j1       .Lh8BR%=\;jmp   @%l0\\n.Lh8BR%=:\";
2316
}"
2317
  [(set_attr "type" "branch")
2318
   (set_attr "cc" "none")])
2319
 
2320
(define_insn "*brabc"
2321
  [(set (pc)
2322
        (if_then_else
2323
         (eq (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
2324
                           (const_int 1)
2325
                           (match_operand:QI 2 "immediate_operand" "n"))
2326
             (const_int 0))
2327
         (label_ref (match_operand 0 "" ""))
2328
         (pc)))]
2329
  "TARGET_H8300SX"
2330
  "*
2331
{
2332
  switch (get_attr_length (insn)
2333
          - h8300_insn_length_from_table (insn, operands))
2334
    {
2335
    case 2:
2336
      return \"bra/bc   %2,%R1,%l0\";
2337
 
2338
    case 4:
2339
      return \"bra/bc   %2,%R1,%l0:16\";
2340
 
2341
    default:
2342
      return \"bra/bs   %2,%R1,.Lh8BR%=\;jmp    @%l0\\n.Lh8BR%=:\";
2343
    }
2344
}"
2345
  [(set_attr "type" "bitbranch")
2346
   (set_attr "length_table" "bitbranch")
2347
   (set_attr "cc" "none")])
2348
 
2349
(define_insn "*brabs"
2350
  [(set (pc)
2351
        (if_then_else
2352
         (ne (zero_extract (match_operand:QI 1 "bit_memory_operand" "WU")
2353
                           (const_int 1)
2354
                           (match_operand:QI 2 "immediate_operand" "n"))
2355
             (const_int 0))
2356
         (label_ref (match_operand 0 "" ""))
2357
         (pc)))]
2358
  "TARGET_H8300SX"
2359
  "*
2360
{
2361
  switch (get_attr_length (insn)
2362
          - h8300_insn_length_from_table (insn, operands))
2363
    {
2364
    case 2:
2365
      return \"bra/bs   %2,%R1,%l0\";
2366
 
2367
    case 4:
2368
      return \"bra/bs   %2,%R1,%l0:16\";
2369
 
2370
    default:
2371
      return \"bra/bc   %2,%R1,.Lh8BR%=\;jmp    @%l0\\n.Lh8BR%=:\";
2372
    }
2373
}"
2374
  [(set_attr "type" "bitbranch")
2375
   (set_attr "length_table" "bitbranch")
2376
   (set_attr "cc" "none")])
2377
 
2378
;; Unconditional and other jump instructions.
2379
 
2380
(define_insn "jump"
2381
  [(set (pc)
2382
        (label_ref (match_operand 0 "" "")))]
2383
  ""
2384
  "*
2385
{
2386
  if (final_sequence != 0)
2387
    {
2388
      if (get_attr_length (insn) == 2)
2389
        return \"bra/s  %l0\";
2390
      else
2391
        {
2392
          /* The branch isn't short enough to use bra/s.  Output the
2393
             branch and delay slot in their normal order.
2394
 
2395
             If this is a backward branch, it will now be branching two
2396
             bytes further than previously thought.  The length-based
2397
             test for bra vs. jump is very conservative though, so the
2398
             branch will still be within range.  */
2399
          rtvec vec;
2400
          int seen;
2401
 
2402
          vec = XVEC (final_sequence, 0);
2403
          final_sequence = 0;
2404
          final_scan_insn (RTVEC_ELT (vec, 1), asm_out_file, optimize, 1, & seen);
2405
          final_scan_insn (RTVEC_ELT (vec, 0), asm_out_file, optimize, 1, & seen);
2406
          INSN_DELETED_P (RTVEC_ELT (vec, 1)) = 1;
2407
          return \"\";
2408
        }
2409
    }
2410
  else if (get_attr_length (insn) == 2)
2411
    return \"bra        %l0\";
2412
  else if (get_attr_length (insn) == 4)
2413
    return \"bra        %l0:16\";
2414
  else
2415
    return \"jmp        @%l0\";
2416
}"
2417
  [(set_attr "type" "branch")
2418
   (set (attr "delay_slot")
2419
        (if_then_else (match_test "TARGET_H8300SX")
2420
                      (const_string "jump")
2421
                      (const_string "none")))
2422
   (set_attr "cc" "none")])
2423
 
2424
;; This is a define expand, because pointers may be either 16 or 32 bits.
2425
 
2426
(define_expand "tablejump"
2427
  [(parallel [(set (pc) (match_operand 0 "register_operand" ""))
2428
              (use (label_ref (match_operand 1 "" "")))])]
2429
  ""
2430
  "")
2431
 
2432
(define_insn "*tablejump_h8300"
2433
  [(set (pc) (match_operand:HI 0 "register_operand" "r"))
2434
   (use (label_ref (match_operand 1 "" "")))]
2435
  "TARGET_H8300"
2436
  "jmp  @%0"
2437
  [(set_attr "cc" "none")
2438
   (set_attr "length" "2")])
2439
 
2440
(define_insn "*tablejump_h8300hs_advanced"
2441
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2442
   (use (label_ref (match_operand 1 "" "")))]
2443
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
2444
  "jmp  @%0"
2445
  [(set_attr "cc" "none")
2446
   (set_attr "length" "2")])
2447
 
2448
(define_insn "*tablejump_h8300hs_normal"
2449
  [(set (pc) (match_operand:HI 0 "register_operand" "r"))
2450
   (use (label_ref (match_operand 1 "" "")))]
2451
  "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
2452
  "jmp @%S0"
2453
  [(set_attr "cc" "none")
2454
   (set_attr "length" "2")])
2455
 
2456
;; This is a define expand, because pointers may be either 16 or 32 bits.
2457
 
2458
(define_expand "indirect_jump"
2459
  [(set (pc) (match_operand 0 "jump_address_operand" ""))]
2460
  ""
2461
  "")
2462
 
2463
(define_insn "*indirect_jump_h8300"
2464
  [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
2465
  "TARGET_H8300"
2466
  "jmp  @%0"
2467
  [(set_attr "cc" "none")
2468
   (set_attr "length" "2")])
2469
 
2470
(define_insn "*indirect_jump_h8300hs_advanced"
2471
  [(set (pc) (match_operand:SI 0 "jump_address_operand" "Vr"))]
2472
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE"
2473
  "jmp @%0"
2474
  [(set_attr "cc" "none")
2475
   (set_attr "length" "2")])
2476
 
2477
(define_insn "*indirect_jump_h8300hs_normal"
2478
  [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))]
2479
  "(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE"
2480
  "jmp @%S0"
2481
  [(set_attr "cc" "none")
2482
   (set_attr "length" "2")])
2483
 
2484
;; Call subroutine with no return value.
2485
 
2486
;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
2487
 
2488
(define_insn "call"
2489
  [(call (match_operand:QI 0 "call_insn_operand" "or")
2490
         (match_operand:HI 1 "general_operand" "g"))]
2491
  ""
2492
  "*
2493
{
2494
  if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
2495
      && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
2496
    return \"jsr\\t@%0:8\";
2497
  else
2498
    return \"jsr\\t%0\";
2499
}"
2500
  [(set_attr "type" "call")
2501
   (set (attr "length")
2502
        (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
2503
                      (const_int 2)
2504
                      (const_int 4)))])
2505
 
2506
;; Call subroutine, returning value in operand 0
2507
;; (which must be a hard register).
2508
 
2509
;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
2510
 
2511
(define_insn "call_value"
2512
  [(set (match_operand 0 "" "=r")
2513
        (call (match_operand:QI 1 "call_insn_operand" "or")
2514
              (match_operand:HI 2 "general_operand" "g")))]
2515
  ""
2516
  "*
2517
{
2518
  if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2519
      && SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
2520
    return \"jsr\\t@%1:8\";
2521
  else
2522
    return \"jsr\\t%1\";
2523
}"
2524
  [(set_attr "type" "call")
2525
   (set (attr "length")
2526
        (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
2527
                      (const_int 2)
2528
                      (const_int 4)))])
2529
 
2530
(define_insn "nop"
2531
  [(const_int 0)]
2532
  ""
2533
  "nop"
2534
  [(set_attr "cc" "none")
2535
   (set_attr "length" "2")])
2536
 
2537
;; ----------------------------------------------------------------------
2538
;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS
2539
;; ----------------------------------------------------------------------
2540
 
2541
(define_expand "push_h8300"
2542
  [(set (mem:HI (pre_dec:HI (reg:HI SP_REG)))
2543
        (match_operand:HI 0 "register_operand" ""))]
2544
  "TARGET_H8300"
2545
  "")
2546
 
2547
(define_expand "push_h8300hs_advanced"
2548
  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2549
        (match_operand:SI 0 "register_operand" ""))]
2550
  "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
2551
  "")
2552
 
2553
(define_expand "push_h8300hs_normal"
2554
  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
2555
        (match_operand:SI 0 "register_operand" ""))]
2556
  "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
2557
  "")
2558
 
2559
(define_expand "pop_h8300"
2560
  [(set (match_operand:HI 0 "register_operand" "")
2561
        (mem:HI (post_inc:HI (reg:HI SP_REG))))]
2562
  "TARGET_H8300"
2563
  "")
2564
 
2565
(define_expand "pop_h8300hs_advanced"
2566
  [(set (match_operand:SI 0 "register_operand" "")
2567
        (mem:SI (post_inc:SI (reg:SI SP_REG))))]
2568
  "TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE"
2569
  "")
2570
 
2571
(define_expand "pop_h8300hs_normal"
2572
  [(set (match_operand:SI 0 "register_operand" "")
2573
        (mem:SI (post_inc:HI (reg:HI SP_REG))))]
2574
  "TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE"
2575
  "")
2576
 
2577
(define_insn "ldm_h8300sx"
2578
  [(match_parallel           0 "h8300_ldm_parallel"
2579
     [(set (match_operand:SI 1 "register_operand" "")
2580
           (match_operand:SI 2 "memory_operand" ""))])]
2581
  "TARGET_H8300S"
2582
  {
2583
    operands[3] = SET_DEST (XVECEXP (operands[0], 0,
2584
                                     XVECLEN (operands[0], 0) - 2));
2585
    return "ldm.l\t@er7+,%S1-%S3";
2586
  }
2587
  [(set_attr "cc" "none")
2588
   (set_attr "length" "4")])
2589
 
2590
(define_insn "stm_h8300sx"
2591
  [(match_parallel           0 "h8300_stm_parallel"
2592
     [(set (match_operand:SI 1 "memory_operand" "")
2593
           (match_operand:SI 2 "register_operand" ""))])]
2594
  "TARGET_H8300S"
2595
  {
2596
    operands[3] = SET_SRC (XVECEXP (operands[0], 0,
2597
                                    XVECLEN (operands[0], 0) - 2));
2598
    return "stm.l\t%S2-%S3,@-er7";
2599
  }
2600
  [(set_attr "cc" "none")
2601
   (set_attr "length" "4")])
2602
 
2603
(define_insn "return_h8sx"
2604
  [(match_parallel           0 "h8300_return_parallel"
2605
     [(return)
2606
      (set (match_operand:SI 1 "register_operand" "")
2607
           (match_operand:SI 2 "memory_operand" ""))])]
2608
  "TARGET_H8300SX"
2609
  {
2610
    operands[3] = SET_DEST (XVECEXP (operands[0], 0,
2611
                                     XVECLEN (operands[0], 0) - 2));
2612
    if (h8300_current_function_interrupt_function_p ())
2613
      return "rte/l\t%S1-%S3";
2614
    else
2615
      return "rts/l\t%S1-%S3";
2616
  }
2617
  [(set_attr "cc" "none")
2618
   (set_attr "can_delay" "no")
2619
   (set_attr "length" "2")])
2620
 
2621
(define_expand "return"
2622
  [(return)]
2623
  "h8300_can_use_return_insn_p ()"
2624
  "")
2625
 
2626
(define_insn "*return_1"
2627
  [(return)]
2628
  "reload_completed"
2629
  "*
2630
{
2631
  if (h8300_current_function_interrupt_function_p ())
2632
    return \"rte\";
2633
  else
2634
    return \"rts\";
2635
}"
2636
  [(set_attr "cc" "none")
2637
   (set_attr "can_delay" "no")
2638
   (set_attr "length" "2")])
2639
 
2640
(define_expand "prologue"
2641
  [(const_int 0)]
2642
  ""
2643
  "h8300_expand_prologue (); DONE;")
2644
 
2645
(define_expand "epilogue"
2646
  [(return)]
2647
  ""
2648
  "h8300_expand_epilogue (); DONE;")
2649
 
2650
(define_insn "monitor_prologue"
2651
  [(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)]
2652
  ""
2653
  "*
2654
{
2655
  if (TARGET_H8300)
2656
    return \"subs\\t#2,r7\;mov.w\\tr0,@-r7\;stc\\tccr,r0l\;mov.b\tr0l,@(2,r7)\;mov.w\\t@r7+,r0\;orc\t#128,ccr\";
2657
  else if (TARGET_H8300H)
2658
    return \"mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr\";
2659
  else if (TARGET_H8300S)
2660
    return \"stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr\";
2661
  gcc_unreachable ();
2662
}"
2663
  [(set_attr "length" "20")])
2664
 
2665
;; ----------------------------------------------------------------------
2666
;; EXTEND INSTRUCTIONS
2667
;; ----------------------------------------------------------------------
2668
 
2669
(define_expand "zero_extendqihi2"
2670
  [(set (match_operand:HI 0 "register_operand" "")
2671
        (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2672
  ""
2673
  "")
2674
 
2675
(define_insn "*zero_extendqihi2_h8300"
2676
  [(set (match_operand:HI 0 "register_operand" "=r,r")
2677
        (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2678
  "TARGET_H8300"
2679
  "@
2680
  mov.b #0,%t0
2681
  #"
2682
  [(set_attr "length" "2,10")])
2683
 
2684
(define_insn "*zero_extendqihi2_h8300hs"
2685
  [(set (match_operand:HI 0 "register_operand" "=r,r")
2686
        (zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2687
  "TARGET_H8300H || TARGET_H8300S"
2688
  "@
2689
  extu.w        %T0
2690
  #"
2691
  [(set_attr "length" "2,10")
2692
   (set_attr "cc" "set_znv,set_znv")])
2693
 
2694
;; Split the zero extension of a general operand (actually a memory
2695
;; operand) into a load of the operand and the actual zero extension
2696
;; so that 1) the length will be accurate, and 2) the zero extensions
2697
;; appearing at the end of basic blocks may be merged.
2698
 
2699
(define_split
2700
  [(set (match_operand:HI 0 "register_operand" "")
2701
        (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
2702
  "reload_completed"
2703
  [(set (match_dup 2)
2704
        (match_dup 1))
2705
   (set (match_dup 0)
2706
        (zero_extend:HI (match_dup 2)))]
2707
  "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2708
 
2709
(define_expand "zero_extendqisi2"
2710
  [(set (match_operand:SI 0 "register_operand" "")
2711
        (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2712
  ""
2713
  {
2714
    if (TARGET_H8300SX)
2715
      operands[1] = force_reg (QImode, operands[1]);
2716
  })
2717
 
2718
(define_insn "*zero_extendqisi2_h8300"
2719
  [(set (match_operand:SI 0 "register_operand" "=r,r")
2720
        (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2721
  "TARGET_H8300"
2722
  "@
2723
  mov.b #0,%x0\;sub.w   %e0,%e0
2724
  mov.b %R1,%w0\;mov.b  #0,%x0\;sub.w   %e0,%e0"
2725
  [(set_attr "length" "4,8")])
2726
 
2727
(define_insn "*zero_extendqisi2_h8300hs"
2728
  [(set (match_operand:SI 0 "register_operand" "=r,r")
2729
        (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2730
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
2731
  "#")
2732
 
2733
(define_split
2734
  [(set (match_operand:SI 0 "register_operand" "")
2735
        (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2736
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
2737
   && reg_overlap_mentioned_p (operands[0], operands[1])
2738
   && reload_completed"
2739
  [(set (match_dup 2)
2740
        (match_dup 1))
2741
   (set (match_dup 3)
2742
        (zero_extend:HI (match_dup 2)))
2743
   (set (match_dup 0)
2744
        (zero_extend:SI (match_dup 3)))]
2745
  "operands[2] = gen_lowpart (QImode, operands[0]);
2746
   operands[3] = gen_lowpart (HImode, operands[0]);")
2747
 
2748
(define_split
2749
  [(set (match_operand:SI 0 "register_operand" "")
2750
        (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
2751
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
2752
   && !reg_overlap_mentioned_p (operands[0], operands[1])
2753
   && reload_completed"
2754
  [(set (match_dup 0)
2755
        (const_int 0))
2756
   (set (strict_low_part (match_dup 2))
2757
        (match_dup 1))]
2758
  "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));")
2759
 
2760
(define_insn "*zero_extendqisi2_h8sx"
2761
  [(set (match_operand:SI 0 "register_operand" "=r")
2762
        (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2763
  "TARGET_H8300SX"
2764
  "extu.l\t#2,%0"
2765
  [(set_attr "length" "2")
2766
   (set_attr "cc" "set_znv")])
2767
 
2768
(define_expand "zero_extendhisi2"
2769
  [(set (match_operand:SI 0 "register_operand" "")
2770
        (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2771
  ""
2772
  "")
2773
 
2774
;; %e prints the high part of a CONST_INT, not the low part.  Arggh.
2775
(define_insn "*zero_extendhisi2_h8300"
2776
  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2777
        (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,i,g>")))]
2778
  "TARGET_H8300"
2779
  "@
2780
  sub.w %e0,%e0
2781
  mov.w %f1,%f0\;sub.w  %e0,%e0
2782
  mov.w %e1,%f0\;sub.w  %e0,%e0"
2783
  [(set_attr "length" "2,4,6")])
2784
 
2785
(define_insn "*zero_extendhisi2_h8300hs"
2786
  [(set (match_operand:SI 0 "register_operand" "=r")
2787
        (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2788
  "TARGET_H8300H || TARGET_H8300S"
2789
  "extu.l       %S0"
2790
  [(set_attr "length" "2")
2791
   (set_attr "cc" "set_znv")])
2792
 
2793
(define_expand "extendqihi2"
2794
  [(set (match_operand:HI 0 "register_operand" "")
2795
        (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2796
  ""
2797
  "")
2798
 
2799
(define_insn "*extendqihi2_h8300"
2800
  [(set (match_operand:HI 0 "register_operand" "=r,r")
2801
        (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2802
  "TARGET_H8300"
2803
  "@
2804
  bld   #7,%s0\;subx    %t0,%t0
2805
  mov.b %R1,%s0\;bld    #7,%s0\;subx    %t0,%t0"
2806
  [(set_attr "length" "4,8")])
2807
 
2808
(define_insn "*extendqihi2_h8300hs"
2809
  [(set (match_operand:HI 0 "register_operand" "=r")
2810
        (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
2811
  "TARGET_H8300H || TARGET_H8300S"
2812
  "exts.w       %T0"
2813
  [(set_attr "length" "2")
2814
   (set_attr "cc" "set_znv")])
2815
 
2816
(define_expand "extendqisi2"
2817
  [(set (match_operand:SI 0 "register_operand" "")
2818
        (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
2819
  ""
2820
  "")
2821
 
2822
(define_insn "*extendqisi2_h8300"
2823
  [(set (match_operand:SI 0 "register_operand" "=r,r")
2824
        (sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
2825
  "TARGET_H8300"
2826
  "@
2827
  bld   #7,%w0\;subx    %x0,%x0\;subx   %y0,%y0\;subx   %z0,%z0
2828
  mov.b %R1,%w0\;bld    #7,%w0\;subx    %x0,%x0\;subx   %y0,%y0\;subx   %z0,%z0"
2829
  [(set_attr "length" "8,12")])
2830
 
2831
;; The following pattern is needed because without the pattern, the
2832
;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
2833
;; shifts, one ashift and one ashiftrt.
2834
 
2835
(define_insn_and_split "*extendqisi2_h8300hs"
2836
  [(set (match_operand:SI 0 "register_operand" "=r")
2837
        (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2838
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX"
2839
  "#"
2840
  "&& reload_completed"
2841
  [(set (match_dup 2)
2842
        (sign_extend:HI (match_dup 1)))
2843
   (set (match_dup 0)
2844
        (sign_extend:SI (match_dup 2)))]
2845
  "operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));")
2846
 
2847
(define_insn "*extendqisi2_h8sx"
2848
  [(set (match_operand:SI 0 "register_operand" "=r")
2849
        (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
2850
  "TARGET_H8300SX"
2851
  "exts.l\t#2,%0"
2852
  [(set_attr "length" "2")
2853
   (set_attr "cc" "set_znv")])
2854
 
2855
(define_expand "extendhisi2"
2856
  [(set (match_operand:SI 0 "register_operand" "")
2857
        (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2858
  ""
2859
  "")
2860
 
2861
(define_insn "*extendhisi2_h8300"
2862
  [(set (match_operand:SI 0 "register_operand" "=r,r")
2863
        (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))]
2864
  "TARGET_H8300"
2865
  "@
2866
  bld   #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0
2867
  mov.w %T1,%f0\;bld    #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0"
2868
  [(set_attr "length" "6,10")])
2869
 
2870
(define_insn "*extendhisi2_h8300hs"
2871
  [(set (match_operand:SI 0 "register_operand" "=r")
2872
        (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
2873
  "TARGET_H8300H || TARGET_H8300S"
2874
  "exts.l       %S0"
2875
  [(set_attr "length" "2")
2876
   (set_attr "cc" "set_znv")])
2877
 
2878
;; ----------------------------------------------------------------------
2879
;; SHIFTS
2880
;; ----------------------------------------------------------------------
2881
;;
2882
;; We make some attempt to provide real efficient shifting.  One example is
2883
;; doing an 8-bit shift of a 16-bit value by moving a byte reg into the other
2884
;; reg and moving 0 into the former reg.
2885
;;
2886
;; We also try to achieve this in a uniform way.  IE: We don't try to achieve
2887
;; this in both rtl and at insn emit time.  Ideally, we'd use rtl as that would
2888
;; give the optimizer more cracks at the code.  However, we wish to do things
2889
;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
2890
;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
2891
;; 16-bit rotates.  Also, if we emit complicated rtl, combine may not be able
2892
;; to detect cases it can optimize.
2893
;;
2894
;; For these and other fuzzy reasons, I've decided to go the less pretty but
2895
;; easier "do it at insn emit time" route.
2896
 
2897
;; QI BIT SHIFTS
2898
 
2899
(define_expand "ashlqi3"
2900
  [(set (match_operand:QI 0 "register_operand" "")
2901
        (ashift:QI (match_operand:QI 1 "register_operand" "")
2902
                   (match_operand:QI 2 "nonmemory_operand" "")))]
2903
  ""
2904
  "if (expand_a_shift (QImode, ASHIFT, operands)) DONE;")
2905
 
2906
(define_expand "ashrqi3"
2907
  [(set (match_operand:QI 0 "register_operand" "")
2908
        (ashiftrt:QI (match_operand:QI 1 "register_operand" "")
2909
                     (match_operand:QI 2 "nonmemory_operand" "")))]
2910
  ""
2911
  "if (expand_a_shift (QImode, ASHIFTRT, operands)) DONE;")
2912
 
2913
(define_expand "lshrqi3"
2914
  [(set (match_operand:QI 0 "register_operand" "")
2915
        (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2916
                     (match_operand:QI 2 "nonmemory_operand" "")))]
2917
  ""
2918
  "if (expand_a_shift (QImode, LSHIFTRT, operands)) DONE;")
2919
 
2920
(define_insn ""
2921
  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
2922
        (match_operator:QI 3 "h8sx_unary_shift_operator"
2923
                        [(match_operand:QI 1 "h8300_dst_operand" "0")
2924
                         (match_operand:QI 2 "const_int_operand" "")]))]
2925
  "h8300_operands_match_p (operands)"
2926
  { return output_h8sx_shift (operands, 'b', 'X'); }
2927
  [(set_attr "length_table" "unary")
2928
   (set_attr "cc" "set_znv")])
2929
 
2930
(define_insn ""
2931
  [(set (match_operand:QI 0 "register_operand" "=r")
2932
        (match_operator:QI 3 "h8sx_binary_shift_operator"
2933
                        [(match_operand:QI 1 "register_operand" "0")
2934
                         (match_operand:QI 2 "nonmemory_operand" "r P3>X")]))]
2935
  ""
2936
  { return output_h8sx_shift (operands, 'b', 'X'); }
2937
  [(set_attr "length" "4")
2938
   (set_attr "cc" "set_znv")])
2939
 
2940
(define_insn "*shiftqi"
2941
  [(set (match_operand:QI 0 "register_operand" "=r,r")
2942
        (match_operator:QI 3 "nshift_operator"
2943
                        [ (match_operand:QI 1 "register_operand" "0,0")
2944
                          (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
2945
   (clobber (match_scratch:QI 4 "=X,&r"))]
2946
  ""
2947
  "* return output_a_shift (operands);"
2948
  [(set (attr "length")
2949
        (symbol_ref "compute_a_shift_length (insn, operands)"))
2950
   (set (attr "cc")
2951
        (symbol_ref "compute_a_shift_cc (insn, operands)"))])
2952
 
2953
;; HI BIT SHIFTS
2954
 
2955
(define_expand "ashlhi3"
2956
  [(set (match_operand:HI 0 "register_operand" "")
2957
        (ashift:HI (match_operand:HI 1 "register_operand" "")
2958
                   (match_operand:QI 2 "nonmemory_operand" "")))]
2959
  ""
2960
  "if (expand_a_shift (HImode, ASHIFT, operands)) DONE;")
2961
 
2962
(define_expand "lshrhi3"
2963
  [(set (match_operand:HI 0 "register_operand" "")
2964
        (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2965
                     (match_operand:QI 2 "nonmemory_operand" "")))]
2966
  ""
2967
  "if (expand_a_shift (HImode, LSHIFTRT, operands)) DONE;")
2968
 
2969
(define_expand "ashrhi3"
2970
  [(set (match_operand:HI 0 "register_operand" "")
2971
        (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2972
                     (match_operand:QI 2 "nonmemory_operand" "")))]
2973
  ""
2974
  "if (expand_a_shift (HImode, ASHIFTRT, operands)) DONE;")
2975
 
2976
(define_insn ""
2977
  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
2978
        (match_operator:HI 3 "h8sx_unary_shift_operator"
2979
                        [(match_operand:HI 1 "h8300_dst_operand" "0")
2980
                         (match_operand:QI 2 "const_int_operand" "")]))]
2981
  "h8300_operands_match_p (operands)"
2982
  { return output_h8sx_shift (operands, 'w', 'T'); }
2983
  [(set_attr "length_table" "unary")
2984
   (set_attr "cc" "set_znv")])
2985
 
2986
(define_insn ""
2987
  [(set (match_operand:HI 0 "register_operand" "=r")
2988
        (match_operator:HI 3 "h8sx_binary_shift_operator"
2989
                        [(match_operand:HI 1 "register_operand" "0")
2990
                         (match_operand:QI 2 "nonmemory_operand" "r P4>X")]))]
2991
  ""
2992
  { return output_h8sx_shift (operands, 'w', 'T'); }
2993
  [(set_attr "length" "4")
2994
   (set_attr "cc" "set_znv")])
2995
 
2996
(define_insn "*shifthi"
2997
  [(set (match_operand:HI 0 "register_operand" "=r,r")
2998
        (match_operator:HI 3 "nshift_operator"
2999
                        [ (match_operand:HI 1 "register_operand" "0,0")
3000
                          (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
3001
   (clobber (match_scratch:QI 4 "=X,&r"))]
3002
  ""
3003
  "* return output_a_shift (operands);"
3004
  [(set (attr "length")
3005
        (symbol_ref "compute_a_shift_length (insn, operands)"))
3006
   (set (attr "cc")
3007
        (symbol_ref "compute_a_shift_cc (insn, operands)"))])
3008
 
3009
;;  SI BIT SHIFTS
3010
 
3011
(define_expand "ashlsi3"
3012
  [(set (match_operand:SI 0 "register_operand" "")
3013
        (ashift:SI (match_operand:SI 1 "register_operand" "")
3014
                   (match_operand:QI 2 "nonmemory_operand" "")))]
3015
  ""
3016
  "if (expand_a_shift (SImode, ASHIFT, operands)) DONE;")
3017
 
3018
(define_expand "lshrsi3"
3019
  [(set (match_operand:SI 0 "register_operand" "")
3020
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3021
                     (match_operand:QI 2 "nonmemory_operand" "")))]
3022
  ""
3023
  "if (expand_a_shift (SImode, LSHIFTRT, operands)) DONE;")
3024
 
3025
(define_expand "ashrsi3"
3026
  [(set (match_operand:SI 0 "register_operand" "")
3027
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3028
                     (match_operand:QI 2 "nonmemory_operand" "")))]
3029
  ""
3030
  "if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE;")
3031
 
3032
(define_insn ""
3033
  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
3034
        (match_operator:SI 3 "h8sx_unary_shift_operator"
3035
                        [(match_operand:SI 1 "h8300_dst_operand" "0")
3036
                         (match_operand:QI 2 "const_int_operand" "")]))]
3037
  "h8300_operands_match_p (operands)"
3038
  { return output_h8sx_shift (operands, 'l', 'S'); }
3039
  [(set_attr "length_table" "unary")
3040
   (set_attr "cc" "set_znv")])
3041
 
3042
(define_insn ""
3043
  [(set (match_operand:SI 0 "register_operand" "=r")
3044
        (match_operator:SI 3 "h8sx_binary_shift_operator"
3045
                        [(match_operand:SI 1 "register_operand" "0")
3046
                         (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
3047
  ""
3048
  { return output_h8sx_shift (operands, 'l', 'S'); }
3049
  [(set_attr "length" "4")
3050
   (set_attr "cc" "set_znv")])
3051
 
3052
(define_insn "*shiftsi"
3053
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3054
        (match_operator:SI 3 "nshift_operator"
3055
                        [ (match_operand:SI 1 "register_operand" "0,0")
3056
                          (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
3057
   (clobber (match_scratch:QI 4 "=X,&r"))]
3058
  ""
3059
  "* return output_a_shift (operands);"
3060
  [(set (attr "length")
3061
        (symbol_ref "compute_a_shift_length (insn, operands)"))
3062
   (set (attr "cc")
3063
        (symbol_ref "compute_a_shift_cc (insn, operands)"))])
3064
 
3065
;; Split a variable shift into a loop.  If the register containing
3066
;; the shift count dies, then we just use that register.
3067
 
3068
(define_split
3069
  [(set (match_operand 0 "register_operand" "")
3070
        (match_operator 2 "nshift_operator"
3071
                        [(match_dup 0)
3072
                         (match_operand:QI 1 "register_operand" "")]))
3073
   (clobber (match_operand:QI 3 "register_operand" ""))]
3074
  "epilogue_completed
3075
   && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
3076
  [(set (cc0) (compare (match_dup 1)
3077
                       (const_int 0)))
3078
   (set (pc)
3079
        (if_then_else (le (cc0) (const_int 0))
3080
                      (label_ref (match_dup 5))
3081
                      (pc)))
3082
   (match_dup 4)
3083
   (parallel
3084
     [(set (match_dup 0)
3085
           (match_op_dup 2 [(match_dup 0) (const_int 1)]))
3086
      (clobber (scratch:QI))])
3087
   (set (match_dup 1)
3088
        (plus:QI (match_dup 1) (const_int -1)))
3089
   (set (cc0) (compare (match_dup 1)
3090
                       (const_int 0)))
3091
   (set (pc)
3092
        (if_then_else (ne (cc0) (const_int 0))
3093
                      (label_ref (match_dup 4))
3094
                      (pc)))
3095
   (match_dup 5)]
3096
  "operands[4] = gen_label_rtx ();
3097
   operands[5] = gen_label_rtx ();")
3098
 
3099
(define_split
3100
  [(set (match_operand 0 "register_operand" "")
3101
        (match_operator 2 "nshift_operator"
3102
                        [(match_dup 0)
3103
                         (match_operand:QI 1 "register_operand" "")]))
3104
   (clobber (match_operand:QI 3 "register_operand" ""))]
3105
  "epilogue_completed
3106
   && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
3107
  [(set (match_dup 3)
3108
        (match_dup 1))
3109
   (set (cc0) (compare (match_dup 3)
3110
                       (const_int 0)))
3111
   (set (pc)
3112
        (if_then_else (le (cc0) (const_int 0))
3113
                      (label_ref (match_dup 5))
3114
                      (pc)))
3115
   (match_dup 4)
3116
   (parallel
3117
     [(set (match_dup 0)
3118
           (match_op_dup 2 [(match_dup 0) (const_int 1)]))
3119
      (clobber (scratch:QI))])
3120
   (set (match_dup 3)
3121
        (plus:QI (match_dup 3) (const_int -1)))
3122
   (set (cc0) (compare (match_dup 3)
3123
                       (const_int 0)))
3124
   (set (pc)
3125
        (if_then_else (ne (cc0) (const_int 0))
3126
                      (label_ref (match_dup 4))
3127
                      (pc)))
3128
   (match_dup 5)]
3129
  "operands[4] = gen_label_rtx ();
3130
   operands[5] = gen_label_rtx ();")
3131
 
3132
;; ----------------------------------------------------------------------
3133
;; ROTATIONS
3134
;; ----------------------------------------------------------------------
3135
 
3136
(define_expand "rotlqi3"
3137
  [(set (match_operand:QI 0 "register_operand" "")
3138
        (rotate:QI (match_operand:QI 1 "register_operand" "")
3139
                   (match_operand:QI 2 "nonmemory_operand" "")))]
3140
  ""
3141
  "if (expand_a_rotate (operands)) DONE;")
3142
 
3143
(define_insn "rotlqi3_1"
3144
  [(set (match_operand:QI 0 "register_operand" "=r")
3145
        (rotate:QI (match_operand:QI 1 "register_operand" "0")
3146
                   (match_operand:QI 2 "immediate_operand" "")))]
3147
  ""
3148
  "* return output_a_rotate (ROTATE, operands);"
3149
  [(set (attr "length")
3150
        (symbol_ref "compute_a_rotate_length (operands)"))])
3151
 
3152
(define_expand "rotlhi3"
3153
  [(set (match_operand:HI 0 "register_operand" "")
3154
        (rotate:HI (match_operand:HI 1 "register_operand" "")
3155
                   (match_operand:QI 2 "nonmemory_operand" "")))]
3156
  ""
3157
  "if (expand_a_rotate (operands)) DONE;")
3158
 
3159
(define_insn "rotlhi3_1"
3160
  [(set (match_operand:HI 0 "register_operand" "=r")
3161
        (rotate:HI (match_operand:HI 1 "register_operand" "0")
3162
                   (match_operand:QI 2 "immediate_operand" "")))]
3163
  ""
3164
  "* return output_a_rotate (ROTATE, operands);"
3165
  [(set (attr "length")
3166
        (symbol_ref "compute_a_rotate_length (operands)"))])
3167
 
3168
(define_expand "rotlsi3"
3169
  [(set (match_operand:SI 0 "register_operand" "")
3170
        (rotate:SI (match_operand:SI 1 "register_operand" "")
3171
                   (match_operand:QI 2 "nonmemory_operand" "")))]
3172
  "TARGET_H8300H || TARGET_H8300S"
3173
  "if (expand_a_rotate (operands)) DONE;")
3174
 
3175
(define_insn "rotlsi3_1"
3176
  [(set (match_operand:SI 0 "register_operand" "=r")
3177
        (rotate:SI (match_operand:SI 1 "register_operand" "0")
3178
                   (match_operand:QI 2 "immediate_operand" "")))]
3179
  "TARGET_H8300H || TARGET_H8300S"
3180
  "* return output_a_rotate (ROTATE, operands);"
3181
  [(set (attr "length")
3182
        (symbol_ref "compute_a_rotate_length (operands)"))])
3183
 
3184
;; -----------------------------------------------------------------
3185
;; BIT FIELDS
3186
;; -----------------------------------------------------------------
3187
;; The H8/300 has given 1/8th of its opcode space to bitfield
3188
;; instructions so let's use them as well as we can.
3189
 
3190
;; You'll never believe all these patterns perform one basic action --
3191
;; load a bit from the source, optionally invert the bit, then store it
3192
;; in the destination (which is known to be zero).
3193
;;
3194
;; Combine obviously need some work to better identify this situation and
3195
;; canonicalize the form better.
3196
 
3197
;;
3198
;; Normal loads with a 16bit destination.
3199
;;
3200
 
3201
(define_insn ""
3202
  [(set (match_operand:HI 0 "register_operand" "=&r")
3203
        (zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3204
                         (const_int 1)
3205
                         (match_operand:HI 2 "immediate_operand" "n")))]
3206
  "TARGET_H8300"
3207
  "sub.w        %0,%0\;bld      %Z2,%Y1\;bst    #0,%X0"
3208
  [(set_attr "length" "6")])
3209
 
3210
;;
3211
;; Inverted loads with a 16bit destination.
3212
;;
3213
 
3214
(define_insn ""
3215
  [(set (match_operand:HI 0 "register_operand" "=&r")
3216
        (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
3217
                                 (match_operand:HI 3 "const_int_operand" "n"))
3218
                         (const_int 1)
3219
                         (match_operand:HI 2 "const_int_operand" "n")))]
3220
  "(TARGET_H8300 || TARGET_H8300SX)
3221
   && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
3222
  "sub.w        %0,%0\;bild     %Z2,%Y1\;bst    #0,%X0"
3223
  [(set_attr "length" "8")])
3224
 
3225
;;
3226
;; Normal loads with a 32bit destination.
3227
;;
3228
 
3229
(define_insn "*extzv_1_r_h8300"
3230
  [(set (match_operand:SI 0 "register_operand" "=&r")
3231
        (zero_extract:SI (match_operand:HI 1 "register_operand" "r")
3232
                         (const_int 1)
3233
                         (match_operand 2 "const_int_operand" "n")))]
3234
  "TARGET_H8300
3235
   && INTVAL (operands[2]) < 16"
3236
  "* return output_simode_bld (0, operands);"
3237
  [(set_attr "length" "8")])
3238
 
3239
(define_insn "*extzv_1_r_h8300hs"
3240
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3241
        (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
3242
                         (const_int 1)
3243
                         (match_operand 2 "const_int_operand" "n,n")))]
3244
  "(TARGET_H8300H || TARGET_H8300S)
3245
   && INTVAL (operands[2]) < 16"
3246
  "* return output_simode_bld (0, operands);"
3247
  [(set_attr "cc" "set_znv,set_znv")
3248
   (set_attr "length" "8,6")])
3249
 
3250
;;
3251
;; Inverted loads with a 32bit destination.
3252
;;
3253
 
3254
(define_insn "*extzv_1_r_inv_h8300"
3255
  [(set (match_operand:SI 0 "register_operand" "=&r")
3256
        (zero_extract:SI (xor:HI (match_operand:HI 1 "register_operand" "r")
3257
                                 (match_operand:HI 3 "const_int_operand" "n"))
3258
                         (const_int 1)
3259
                         (match_operand 2 "const_int_operand" "n")))]
3260
  "TARGET_H8300
3261
   && INTVAL (operands[2]) < 16
3262
   && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
3263
  "* return output_simode_bld (1, operands);"
3264
  [(set_attr "length" "8")])
3265
 
3266
(define_insn "*extzv_1_r_inv_h8300hs"
3267
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3268
        (zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
3269
                                 (match_operand 3 "const_int_operand" "n,n"))
3270
                         (const_int 1)
3271
                         (match_operand 2 "const_int_operand" "n,n")))]
3272
  "(TARGET_H8300H || TARGET_H8300S)
3273
   && INTVAL (operands[2]) < 16
3274
   && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
3275
  "* return output_simode_bld (1, operands);"
3276
  [(set_attr "cc" "set_znv,set_znv")
3277
   (set_attr "length" "8,6")])
3278
 
3279
(define_expand "insv"
3280
  [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "")
3281
                         (match_operand:HI 1 "general_operand" "")
3282
                         (match_operand:HI 2 "general_operand" ""))
3283
        (match_operand:HI 3 "general_operand" ""))]
3284
  "TARGET_H8300 || TARGET_H8300SX"
3285
  "
3286
{
3287
  if (TARGET_H8300SX)
3288
    {
3289
      if (GET_CODE (operands[1]) == CONST_INT
3290
          && GET_CODE (operands[2]) == CONST_INT
3291
          && INTVAL (operands[1]) <= 8
3292
          && INTVAL (operands[2]) >= 0
3293
          && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8
3294
          && memory_operand (operands[0], GET_MODE (operands[0])))
3295
        {
3296
          /* If the source operand is zero, it's better to use AND rather
3297
             than BFST.  Likewise OR if the operand is all ones.  */
3298
          if (GET_CODE (operands[3]) == CONST_INT)
3299
            {
3300
              HOST_WIDE_INT mask = (1 << INTVAL (operands[1])) - 1;
3301
              if ((INTVAL (operands[3]) & mask) == 0)
3302
                FAIL;
3303
              if ((INTVAL (operands[3]) & mask) == mask)
3304
                FAIL;
3305
            }
3306
          if (! bit_memory_operand (operands[0], GET_MODE (operands[0])))
3307
            {
3308
              if (!can_create_pseudo_p ())
3309
                FAIL;
3310
              operands[0] =
3311
                replace_equiv_address (operands[0],
3312
                                       force_reg (Pmode,
3313
                                                  XEXP (operands[0], 0)));
3314
            }
3315
          operands[3] = gen_lowpart (QImode, operands[3]);
3316
          if (! operands[3])
3317
            FAIL;
3318
          if (! register_operand (operands[3], QImode))
3319
            {
3320
              if (!can_create_pseudo_p ())
3321
                FAIL;
3322
              operands[3] = force_reg (QImode, operands[3]);
3323
            }
3324
          emit_insn (gen_bfst (adjust_address (operands[0], QImode, 0),
3325
                               operands[3], operands[1], operands[2]));
3326
          DONE;
3327
        }
3328
 
3329
      FAIL;
3330
    }
3331
 
3332
  /* We only have single bit bit-field instructions.  */
3333
  if (INTVAL (operands[1]) != 1)
3334
    FAIL;
3335
 
3336
  /* For now, we don't allow memory operands.  */
3337
  if (GET_CODE (operands[0]) == MEM
3338
      || GET_CODE (operands[3]) == MEM)
3339
    FAIL;
3340
 
3341
  if (GET_CODE (operands[3]) != REG)
3342
    operands[3] = force_reg (HImode, operands[3]);
3343
}")
3344
 
3345
(define_insn ""
3346
  [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
3347
                         (const_int 1)
3348
                         (match_operand:HI 1 "immediate_operand" "n"))
3349
        (match_operand:HI 2 "register_operand" "r"))]
3350
  ""
3351
  "bld  #0,%R2\;bst     %Z1,%Y0 ; i1"
3352
  [(set_attr "length" "4")])
3353
 
3354
(define_expand "extzv"
3355
  [(set (match_operand:HI 0 "register_operand" "")
3356
        (zero_extract:HI (match_operand:HI 1 "bit_operand" "")
3357
                         (match_operand:HI 2 "general_operand" "")
3358
                         (match_operand:HI 3 "general_operand" "")))]
3359
  "TARGET_H8300 || TARGET_H8300SX"
3360
  "
3361
{
3362
  if (TARGET_H8300SX)
3363
    {
3364
      if (GET_CODE (operands[2]) == CONST_INT
3365
          && GET_CODE (operands[3]) == CONST_INT
3366
          && INTVAL (operands[2]) <= 8
3367
          && INTVAL (operands[3]) >= 0
3368
          && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8
3369
          && memory_operand (operands[1], QImode))
3370
        {
3371
          rtx temp;
3372
 
3373
          /* Optimize the case where we're extracting into a paradoxical
3374
             subreg.  It's only necessary to extend to the inner reg.  */
3375
          if (GET_CODE (operands[0]) == SUBREG
3376
              && subreg_lowpart_p (operands[0])
3377
              && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0])))
3378
                  < GET_MODE_SIZE (GET_MODE (operands[0])))
3379
              && (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0])))
3380
                  == MODE_INT))
3381
            operands[0] = SUBREG_REG (operands[0]);
3382
 
3383
          if (!can_create_pseudo_p ())
3384
            temp = gen_lowpart (QImode, operands[0]);
3385
          else
3386
            temp = gen_reg_rtx (QImode);
3387
          if (! temp)
3388
            FAIL;
3389
          if (! bit_memory_operand (operands[1], QImode))
3390
            {
3391
              if (!can_create_pseudo_p ())
3392
                FAIL;
3393
              operands[1] =
3394
                replace_equiv_address (operands[1],
3395
                                       force_reg (Pmode,
3396
                                                  XEXP (operands[1], 0)));
3397
            }
3398
          emit_insn (gen_bfld (temp, operands[1], operands[2], operands[3]));
3399
          convert_move (operands[0], temp, 1);
3400
          DONE;
3401
        }
3402
      FAIL;
3403
    }
3404
 
3405
  /* We only have single bit bit-field instructions.  */
3406
  if (INTVAL (operands[2]) != 1)
3407
    FAIL;
3408
 
3409
  /* For now, we don't allow memory operands.  */
3410
  if (GET_CODE (operands[1]) == MEM)
3411
    FAIL;
3412
}")
3413
 
3414
;; BAND, BOR, and BXOR patterns
3415
 
3416
(define_insn ""
3417
  [(set (match_operand:HI 0 "bit_operand" "=Ur")
3418
        (match_operator:HI 4 "bit_operator"
3419
           [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3420
                             (const_int 1)
3421
                             (match_operand:HI 2 "immediate_operand" "n"))
3422
            (match_operand:HI 3 "bit_operand" "0")]))]
3423
  ""
3424
  "bld  %Z2,%Y1\;b%c4   #0,%R0\;bst     #0,%R0; bl1"
3425
  [(set_attr "length" "6")])
3426
 
3427
(define_insn ""
3428
  [(set (match_operand:HI 0 "bit_operand" "=Ur")
3429
        (match_operator:HI 5 "bit_operator"
3430
           [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
3431
                             (const_int 1)
3432
                             (match_operand:HI 2 "immediate_operand" "n"))
3433
            (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
3434
                             (const_int 1)
3435
                             (match_operand:HI 4 "immediate_operand" "n"))]))]
3436
  ""
3437
  "bld  %Z2,%Y1\;b%c5   %Z4,%Y3\;bst    #0,%R0; bl3"
3438
  [(set_attr "length" "6")])
3439
 
3440
(define_insn "bfld"
3441
  [(set (match_operand:QI 0 "register_operand" "=r")
3442
        (zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
3443
                         (match_operand:QI 2 "immediate_operand" "n")
3444
                         (match_operand:QI 3 "immediate_operand" "n")))]
3445
  "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
3446
  "*
3447
{
3448
  operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3449
                         - (1 << INTVAL (operands[3])));
3450
  return \"bfld %2,%1,%R0\";
3451
}"
3452
  [(set_attr "cc" "none_0hit")
3453
   (set_attr "length_table" "bitfield")])
3454
 
3455
(define_insn "bfst"
3456
  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3457
                         (match_operand:QI 2 "immediate_operand" "n")
3458
                         (match_operand:QI 3 "immediate_operand" "n"))
3459
        (match_operand:QI 1 "register_operand" "r"))]
3460
  "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
3461
  "*
3462
{
3463
  operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
3464
                         - (1 << INTVAL (operands[3])));
3465
  return \"bfst %R1,%2,%0\";
3466
}"
3467
  [(set_attr "cc" "none_0hit")
3468
   (set_attr "length_table" "bitfield")])
3469
 
3470
(define_expand "cstoreqi4"
3471
  [(use (match_operator 1 "eqne_operator"
3472
         [(match_operand:QI 2 "h8300_dst_operand" "")
3473
          (match_operand:QI 3 "h8300_src_operand" "")]))
3474
   (clobber (match_operand:HI 0 "register_operand"))]
3475
  "TARGET_H8300SX"
3476
  "h8300_expand_store (operands); DONE;")
3477
 
3478
(define_expand "cstorehi4"
3479
  [(use (match_operator 1 "eqne_operator"
3480
         [(match_operand:HI 2 "h8300_dst_operand" "")
3481
          (match_operand:HI 3 "h8300_src_operand" "")]))
3482
   (clobber (match_operand:HI 0 "register_operand"))]
3483
  "TARGET_H8300SX"
3484
  "h8300_expand_store (operands); DONE;")
3485
 
3486
(define_expand "cstoresi4"
3487
  [(use (match_operator 1 "eqne_operator"
3488
         [(match_operand:SI 2 "h8300_dst_operand" "")
3489
          (match_operand:SI 3 "h8300_src_operand" "")]))
3490
   (clobber (match_operand:HI 0 "register_operand"))]
3491
  "TARGET_H8300SX"
3492
  "h8300_expand_store (operands); DONE;")
3493
 
3494
(define_insn "*bstzhireg"
3495
  [(set (match_operand:HI 0 "register_operand" "=r")
3496
        (match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
3497
  "TARGET_H8300SX"
3498
  "mulu.w       #0,%T0\;b%k1    .Lh8BR%=\;inc.w #1,%T0\\n.Lh8BR%=:"
3499
  [(set_attr "cc" "clobber")])
3500
 
3501
(define_insn_and_split "*cmpstz"
3502
  [(set (zero_extract:QI
3503
         (match_operand:QI 0 "bit_memory_operand" "+WU,+WU")
3504
         (const_int 1)
3505
         (match_operand:QI 1 "immediate_operand" "n,n"))
3506
        (match_operator:QI
3507
         2 "eqne_operator"
3508
         [(match_operand 3 "h8300_dst_operand" "r,rQ")
3509
          (match_operand 4 "h8300_src_operand" "I,rQi")]))]
3510
  "TARGET_H8300SX
3511
   && (GET_MODE (operands[3]) == GET_MODE (operands[4])
3512
       || GET_CODE (operands[4]) == CONST_INT)
3513
   && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
3514
   && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
3515
  "#"
3516
  "reload_completed"
3517
  [(set (cc0) (match_dup 5))
3518
   (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
3519
        (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
3520
  "operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);"
3521
  [(set_attr "cc" "set_znv,compare")])
3522
 
3523
(define_insn "*bstz"
3524
  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3525
                         (const_int 1)
3526
                         (match_operand:QI 1 "immediate_operand" "n"))
3527
        (eq:QI (cc0) (const_int 0)))]
3528
  "TARGET_H8300SX && reload_completed"
3529
  "bstz %1,%0"
3530
  [(set_attr "cc" "none_0hit")
3531
   (set_attr "length_table" "unary")])
3532
 
3533
(define_insn "*bistz"
3534
  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
3535
                         (const_int 1)
3536
                         (match_operand:QI 1 "immediate_operand" "n"))
3537
        (ne:QI (cc0) (const_int 0)))]
3538
  "TARGET_H8300SX && reload_completed"
3539
  "bistz        %1,%0"
3540
  [(set_attr "cc" "none_0hit")
3541
   (set_attr "length_table" "unary")])
3542
 
3543
(define_insn_and_split "*cmpcondbset"
3544
  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3545
        (if_then_else:QI
3546
         (match_operator
3547
          1 "eqne_operator"
3548
          [(match_operand 2 "h8300_dst_operand" "r,rQ")
3549
           (match_operand 3 "h8300_src_operand" "I,rQi")])
3550
         (ior:QI
3551
          (match_operand:QI 4 "bit_memory_operand" "0,0")
3552
          (match_operand:QI 5 "single_one_operand" "n,n"))
3553
         (match_dup 4)))]
3554
  "TARGET_H8300SX"
3555
  "#"
3556
  "reload_completed"
3557
  [(set (cc0) (match_dup 6))
3558
   (set (match_dup 0)
3559
        (if_then_else:QI
3560
         (match_op_dup 1 [(cc0) (const_int 0)])
3561
         (ior:QI (match_dup 4) (match_dup 5)) (match_dup 4)))]
3562
  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
3563
  [(set_attr "cc" "set_znv,compare")])
3564
 
3565
(define_insn "*condbset"
3566
  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3567
        (if_then_else:QI
3568
         (match_operator:QI 2 "eqne_operator"
3569
                            [(cc0) (const_int 0)])
3570
         (ior:QI
3571
          (match_operand:QI 3 "bit_memory_operand" "0")
3572
          (match_operand:QI 1 "single_one_operand" "n"))
3573
         (match_dup 3)))]
3574
  "TARGET_H8300SX && reload_completed"
3575
  "bset/%j2\t%V1,%0"
3576
  [(set_attr "cc" "none_0hit")
3577
   (set_attr "length_table" "logicb")])
3578
 
3579
(define_insn_and_split "*cmpcondbclr"
3580
  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3581
        (if_then_else:QI
3582
         (match_operator
3583
          1 "eqne_operator"
3584
          [(match_operand 2 "h8300_dst_operand" "r,rQ")
3585
           (match_operand 3 "h8300_src_operand" "I,rQi")])
3586
         (and:QI
3587
          (match_operand:QI 4 "bit_memory_operand" "0,0")
3588
          (match_operand:QI 5 "single_zero_operand" "n,n"))
3589
         (match_dup 4)))]
3590
  "TARGET_H8300SX"
3591
  "#"
3592
  "reload_completed"
3593
  [(set (cc0) (match_dup 6))
3594
   (set (match_dup 0)
3595
        (if_then_else:QI
3596
         (match_op_dup 1 [(cc0) (const_int 0)])
3597
         (and:QI (match_dup 4) (match_dup 5)) (match_dup 4)))]
3598
  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
3599
  [(set_attr "cc" "set_znv,compare")])
3600
 
3601
(define_insn "*condbclr"
3602
  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3603
        (if_then_else:QI
3604
         (match_operator:QI 2 "eqne_operator"
3605
                            [(cc0) (const_int 0)])
3606
         (and:QI
3607
          (match_operand:QI 3 "bit_memory_operand" "0")
3608
          (match_operand:QI 1 "single_zero_operand" "n"))
3609
         (match_dup 3)))]
3610
  "TARGET_H8300SX && reload_completed"
3611
  "bclr/%j2\t%W1,%0"
3612
  [(set_attr "cc" "none_0hit")
3613
   (set_attr "length_table" "logicb")])
3614
 
3615
(define_insn_and_split "*cmpcondbsetreg"
3616
  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3617
        (if_then_else:QI
3618
         (match_operator
3619
          1 "eqne_operator"
3620
          [(match_operand 2 "h8300_dst_operand" "r,rQ")
3621
           (match_operand 3 "h8300_src_operand" "I,rQi")])
3622
         (ior:QI
3623
          (match_operand:QI 4 "bit_memory_operand" "0,0")
3624
          (ashift:QI (const_int 1)
3625
                     (match_operand:QI 5 "register_operand" "r,r")))
3626
         (match_dup 4)))]
3627
  "TARGET_H8300SX"
3628
  "#"
3629
  "reload_completed"
3630
  [(set (cc0) (match_dup 6))
3631
   (set (match_dup 0)
3632
        (if_then_else:QI
3633
         (match_op_dup 1 [(cc0) (const_int 0)])
3634
         (ior:QI (match_dup 4)
3635
                 (ashift:QI (const_int 1)
3636
                            (match_operand:QI 5 "register_operand" "r,r")))
3637
         (match_dup 4)))]
3638
  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
3639
  [(set_attr "cc" "set_znv,compare")])
3640
 
3641
(define_insn "*condbsetreg"
3642
  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3643
        (if_then_else:QI
3644
         (match_operator:QI 2 "eqne_operator"
3645
                            [(cc0) (const_int 0)])
3646
         (ior:QI
3647
          (match_operand:QI 3 "bit_memory_operand" "0")
3648
          (ashift:QI (const_int 1)
3649
                     (match_operand:QI 1 "register_operand" "r")))
3650
         (match_dup 3)))]
3651
  "TARGET_H8300SX && reload_completed"
3652
  "bset/%j2\t%R1,%0"
3653
  [(set_attr "cc" "none_0hit")
3654
   (set_attr "length_table" "logicb")])
3655
 
3656
(define_insn_and_split "*cmpcondbclrreg"
3657
  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
3658
        (if_then_else:QI
3659
         (match_operator
3660
          1 "eqne_operator"
3661
          [(match_operand 2 "h8300_dst_operand" "r,rQ")
3662
           (match_operand 3 "h8300_src_operand" "I,rQi")])
3663
         (and:QI
3664
          (match_operand:QI 4 "bit_memory_operand" "0,0")
3665
          (ashift:QI (const_int 1)
3666
                     (match_operand:QI 5 "register_operand" "r,r")))
3667
         (match_dup 4)))]
3668
  "TARGET_H8300SX"
3669
  "#"
3670
  "reload_completed"
3671
  [(set (cc0) (match_dup 6))
3672
   (set (match_dup 0)
3673
        (if_then_else:QI
3674
         (match_op_dup 1 [(cc0) (const_int 0)])
3675
         (and:QI (match_dup 4)
3676
                 (ashift:QI (const_int 1)
3677
                            (match_operand:QI 5 "register_operand" "r,r")))
3678
         (match_dup 4)))]
3679
  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
3680
  [(set_attr "cc" "set_znv,compare")])
3681
 
3682
(define_insn "*condbclrreg"
3683
  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
3684
        (if_then_else:QI
3685
         (match_operator:QI 2 "eqne_operator"
3686
                            [(cc0) (const_int 0)])
3687
         (and:QI
3688
          (match_operand:QI 3 "bit_memory_operand" "0")
3689
          (ashift:QI (const_int 1)
3690
                     (match_operand:QI 1 "register_operand" "r")))
3691
         (match_dup 3)))]
3692
  "TARGET_H8300SX && reload_completed"
3693
  "bclr/%j2\t%R1,%0"
3694
  [(set_attr "cc" "none_0hit")
3695
   (set_attr "length_table" "logicb")])
3696
 
3697
 
3698
;; -----------------------------------------------------------------
3699
;; COMBINE PATTERNS
3700
;; -----------------------------------------------------------------
3701
 
3702
;; insv:SI
3703
 
3704
(define_insn "*insv_si_1_n"
3705
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3706
                         (const_int 1)
3707
                         (match_operand:SI 1 "const_int_operand" "n"))
3708
        (match_operand:SI 2 "register_operand" "r"))]
3709
  "(TARGET_H8300H || TARGET_H8300S)
3710
   && INTVAL (operands[1]) < 16"
3711
  "bld\\t#0,%w2\;bst\\t%Z1,%Y0"
3712
  [(set_attr "length" "4")])
3713
 
3714
(define_insn "*insv_si_1_n_lshiftrt"
3715
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3716
                         (const_int 1)
3717
                         (match_operand:SI 1 "const_int_operand" "n"))
3718
        (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3719
                     (match_operand:SI 3 "const_int_operand" "n")))]
3720
  "(TARGET_H8300H || TARGET_H8300S)
3721
   && INTVAL (operands[1]) < 16
3722
   && INTVAL (operands[3]) < 16"
3723
  "bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
3724
  [(set_attr "length" "4")])
3725
 
3726
(define_insn "*insv_si_1_n_lshiftrt_16"
3727
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3728
                         (const_int 1)
3729
                         (match_operand:SI 1 "const_int_operand" "n"))
3730
        (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3731
                     (const_int 16)))]
3732
  "(TARGET_H8300H || TARGET_H8300S)
3733
   && INTVAL (operands[1]) < 16"
3734
  "rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
3735
  [(set_attr "length" "6")])
3736
 
3737
(define_insn "*insv_si_8_8"
3738
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3739
                         (const_int 8)
3740
                         (const_int 8))
3741
        (match_operand:SI 1 "register_operand" "r"))]
3742
  "TARGET_H8300H || TARGET_H8300S"
3743
  "mov.b\\t%w1,%x0"
3744
  [(set_attr "length" "2")])
3745
 
3746
(define_insn "*insv_si_8_8_lshiftrt_8"
3747
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3748
                         (const_int 8)
3749
                         (const_int 8))
3750
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3751
                     (const_int 8)))]
3752
  "TARGET_H8300H || TARGET_H8300S"
3753
  "mov.b\\t%x1,%x0"
3754
  [(set_attr "length" "2")])
3755
 
3756
;; extzv:SI
3757
 
3758
(define_insn "*extzv_8_8"
3759
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3760
        (zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
3761
                         (const_int 8)
3762
                         (const_int 8)))]
3763
  "TARGET_H8300H || TARGET_H8300S"
3764
  "@
3765
   mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0
3766
   sub.l\\t%S0,%S0\;mov.b\\t%x1,%w0"
3767
  [(set_attr "cc" "set_znv,clobber")
3768
   (set_attr "length" "6,4")])
3769
 
3770
(define_insn "*extzv_8_16"
3771
  [(set (match_operand:SI 0 "register_operand" "=r")
3772
        (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3773
                         (const_int 8)
3774
                         (const_int 16)))]
3775
  "TARGET_H8300H || TARGET_H8300S"
3776
  "mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
3777
  [(set_attr "cc" "set_znv")
3778
   (set_attr "length" "6")])
3779
 
3780
(define_insn "*extzv_16_8"
3781
  [(set (match_operand:SI 0 "register_operand" "=r")
3782
        (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3783
                         (const_int 16)
3784
                         (const_int 8)))
3785
   (clobber (match_scratch:SI 2 "=&r"))]
3786
  "TARGET_H8300H"
3787
  "mov.w\\t%e1,%f2\;mov.b\\t%x1,%w0\;mov.b\\t%w2,%x0\;extu.l\\t%S0"
3788
  [(set_attr "length" "8")
3789
   (set_attr "cc" "set_znv")])
3790
 
3791
;; Extract the exponent of a float.
3792
 
3793
(define_insn_and_split "*extzv_8_23"
3794
  [(set (match_operand:SI 0 "register_operand" "=r")
3795
        (zero_extract:SI (match_operand:SI 1 "register_operand" "0")
3796
                         (const_int 8)
3797
                         (const_int 23)))]
3798
  "(TARGET_H8300H || TARGET_H8300S)"
3799
  "#"
3800
  "&& reload_completed"
3801
  [(parallel [(set (match_dup 0)
3802
                   (ashift:SI (match_dup 0)
3803
                              (const_int 1)))
3804
              (clobber (scratch:QI))])
3805
   (parallel [(set (match_dup 0)
3806
                   (lshiftrt:SI (match_dup 0)
3807
                                (const_int 24)))
3808
              (clobber (scratch:QI))])]
3809
  "")
3810
 
3811
;; and:SI
3812
 
3813
;; ((SImode) HImode) << 15
3814
 
3815
(define_insn_and_split "*twoshifts_l16_r1"
3816
  [(set (match_operand:SI 0 "register_operand" "=r")
3817
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3818
                           (const_int 15))
3819
                (const_int 2147450880)))]
3820
  "(TARGET_H8300H || TARGET_H8300S)"
3821
  "#"
3822
  "&& reload_completed"
3823
  [(parallel [(set (match_dup 0)
3824
                   (ashift:SI (match_dup 0)
3825
                              (const_int 16)))
3826
              (clobber (scratch:QI))])
3827
   (parallel [(set (match_dup 0)
3828
                   (lshiftrt:SI (match_dup 0)
3829
                                (const_int 1)))
3830
              (clobber (scratch:QI))])]
3831
  "")
3832
 
3833
;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
3834
 
3835
(define_insn_and_split "*andsi3_ashift_n_lower"
3836
  [(set (match_operand:SI 0 "register_operand" "=r,r")
3837
        (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
3838
                           (match_operand:QI 2 "const_int_operand" "S,n"))
3839
                (match_operand:SI 3 "const_int_operand" "n,n")))
3840
   (clobber (match_scratch:QI 4 "=X,&r"))]
3841
  "(TARGET_H8300H || TARGET_H8300S)
3842
   && INTVAL (operands[2]) <= 15
3843
   && INTVAL (operands[3]) == ((-1 << INTVAL (operands[2])) & 0xffff)"
3844
  "#"
3845
  "&& reload_completed"
3846
  [(parallel [(set (match_dup 5)
3847
                   (ashift:HI (match_dup 5)
3848
                              (match_dup 2)))
3849
              (clobber (match_dup 4))])
3850
   (set (match_dup 0)
3851
        (zero_extend:SI (match_dup 5)))]
3852
  "operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));")
3853
 
3854
;; Accept (A >> 30) & 2 and the like.
3855
 
3856
(define_insn "*andsi3_lshiftrt_n_sb"
3857
  [(set (match_operand:SI 0 "register_operand" "=r")
3858
        (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3859
                             (match_operand:SI 2 "const_int_operand" "n"))
3860
                (match_operand:SI 3 "single_one_operand" "n")))]
3861
  "(TARGET_H8300H || TARGET_H8300S)
3862
   && exact_log2 (INTVAL (operands[3])) < 16
3863
   && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
3864
  "*
3865
{
3866
  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3867
  return \"shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0\";
3868
}"
3869
  [(set_attr "length" "8")])
3870
 
3871
(define_insn_and_split "*andsi3_lshiftrt_9_sb"
3872
  [(set (match_operand:SI 0 "register_operand" "=r")
3873
        (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
3874
                             (const_int 9))
3875
                (const_int 4194304)))]
3876
  "(TARGET_H8300H || TARGET_H8300S)"
3877
  "#"
3878
  "&& reload_completed"
3879
  [(set (match_dup 0)
3880
        (and:SI (lshiftrt:SI (match_dup 0)
3881
                             (const_int 25))
3882
                (const_int 64)))
3883
   (parallel [(set (match_dup 0)
3884
                   (ashift:SI (match_dup 0)
3885
                              (const_int 16)))
3886
              (clobber (scratch:QI))])]
3887
  "")
3888
 
3889
;; plus:SI
3890
 
3891
(define_insn "*addsi3_upper"
3892
  [(set (match_operand:SI 0 "register_operand" "=r")
3893
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3894
                          (const_int 65536))
3895
                 (match_operand:SI 2 "register_operand" "0")))]
3896
  "TARGET_H8300H || TARGET_H8300S"
3897
  "add.w\\t%f1,%e0"
3898
  [(set_attr "length" "2")])
3899
 
3900
(define_insn "*addsi3_lshiftrt_16_zexthi"
3901
  [(set (match_operand:SI 0 "register_operand" "=r")
3902
        (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3903
                              (const_int 16))
3904
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
3905
  "TARGET_H8300H || TARGET_H8300S"
3906
  "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
3907
  [(set_attr "length" "6")])
3908
 
3909
(define_insn_and_split "*addsi3_and_r_1"
3910
  [(set (match_operand:SI 0 "register_operand" "=r")
3911
        (plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
3912
                         (const_int 1))
3913
                 (match_operand:SI 2 "register_operand" "0")))]
3914
  "(TARGET_H8300H || TARGET_H8300S)"
3915
  "#"
3916
  "&& reload_completed"
3917
  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
3918
                                        (const_int 1)
3919
                                        (const_int 0))
3920
                       (const_int 0)))
3921
   (set (pc)
3922
        (if_then_else (eq (cc0)
3923
                          (const_int 0))
3924
                      (label_ref (match_dup 3))
3925
                      (pc)))
3926
   (set (match_dup 2)
3927
        (plus:SI (match_dup 2)
3928
                 (const_int 1)))
3929
   (match_dup 3)]
3930
  "operands[3] = gen_label_rtx ();")
3931
 
3932
(define_insn_and_split "*addsi3_and_not_r_1"
3933
  [(set (match_operand:SI 0 "register_operand" "=r")
3934
        (plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3935
                         (const_int 1))
3936
                 (match_operand:SI 2 "register_operand" "0")))]
3937
  "(TARGET_H8300H || TARGET_H8300S)"
3938
  "#"
3939
  "&& reload_completed"
3940
  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
3941
                                        (const_int 1)
3942
                                        (const_int 0))
3943
                       (const_int 0)))
3944
   (set (pc)
3945
        (if_then_else (ne (cc0)
3946
                          (const_int 0))
3947
                      (label_ref (match_dup 3))
3948
                      (pc)))
3949
   (set (match_dup 2)
3950
        (plus:SI (match_dup 2)
3951
                 (const_int 1)))
3952
   (match_dup 3)]
3953
  "operands[3] = gen_label_rtx ();")
3954
 
3955
;; [ix]or:HI
3956
 
3957
(define_insn "*ixorhi3_zext"
3958
  [(set (match_operand:HI 0 "register_operand" "=r")
3959
        (match_operator:HI 1 "iorxor_operator"
3960
          [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
3961
           (match_operand:HI 3 "register_operand" "0")]))]
3962
  ""
3963
  "%c1.b\\t%X2,%s0"
3964
  [(set_attr "length" "2")])
3965
 
3966
;; [ix]or:SI
3967
 
3968
(define_insn "*ixorsi3_zext_qi"
3969
  [(set (match_operand:SI 0 "register_operand" "=r")
3970
        (match_operator:SI 1 "iorxor_operator"
3971
          [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
3972
           (match_operand:SI 3 "register_operand" "0")]))]
3973
  ""
3974
  "%c1.b\\t%X2,%w0"
3975
  [(set_attr "length" "2")])
3976
 
3977
(define_insn "*ixorsi3_zext_hi"
3978
  [(set (match_operand:SI 0 "register_operand" "=r")
3979
        (match_operator:SI 1 "iorxor_operator"
3980
          [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
3981
           (match_operand:SI 3 "register_operand" "0")]))]
3982
  "TARGET_H8300H || TARGET_H8300S"
3983
  "%c1.w\\t%T2,%f0"
3984
  [(set_attr "length" "2")])
3985
 
3986
(define_insn "*ixorsi3_ashift_16"
3987
  [(set (match_operand:SI 0 "register_operand" "=r")
3988
        (match_operator:SI 1 "iorxor_operator"
3989
          [(ashift:SI (match_operand:SI 2 "register_operand" "r")
3990
                      (const_int 16))
3991
           (match_operand:SI 3 "register_operand" "0")]))]
3992
  "TARGET_H8300H || TARGET_H8300S"
3993
  "%c1.w\\t%f2,%e0"
3994
  [(set_attr "length" "2")])
3995
 
3996
(define_insn "*ixorsi3_lshiftrt_16"
3997
  [(set (match_operand:SI 0 "register_operand" "=r")
3998
        (match_operator:SI 1 "iorxor_operator"
3999
          [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
4000
                        (const_int 16))
4001
           (match_operand:SI 3 "register_operand" "0")]))]
4002
  "TARGET_H8300H || TARGET_H8300S"
4003
  "%c1.w\\t%e2,%f0"
4004
  [(set_attr "length" "2")])
4005
 
4006
;; ior:HI
4007
 
4008
(define_insn "*iorhi3_ashift_8"
4009
  [(set (match_operand:HI 0 "register_operand" "=r")
4010
        (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
4011
                           (const_int 8))
4012
                (match_operand:HI 2 "register_operand" "0")))]
4013
  ""
4014
  "or.b\\t%s1,%t0"
4015
  [(set_attr "length" "2")])
4016
 
4017
(define_insn "*iorhi3_lshiftrt_8"
4018
  [(set (match_operand:HI 0 "register_operand" "=r")
4019
        (ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
4020
                             (const_int 8))
4021
                (match_operand:HI 2 "register_operand" "0")))]
4022
  ""
4023
  "or.b\\t%t1,%s0"
4024
  [(set_attr "length" "2")])
4025
 
4026
(define_insn "*iorhi3_two_qi"
4027
  [(set (match_operand:HI 0 "register_operand" "=r")
4028
        (ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
4029
                (ashift:HI (match_operand:HI 2 "register_operand" "r")
4030
                           (const_int 8))))]
4031
  ""
4032
  "mov.b\\t%s2,%t0"
4033
  [(set_attr "length" "2")])
4034
 
4035
(define_insn "*iorhi3_two_qi_mem"
4036
  [(set (match_operand:HI 0 "register_operand" "=&r")
4037
        (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
4038
                (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
4039
                           (const_int 8))))]
4040
  ""
4041
  "mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
4042
  [(set_attr "length" "16")])
4043
 
4044
(define_split
4045
  [(set (match_operand:HI 0 "register_operand" "")
4046
        (ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" ""))
4047
                (ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "") 0)
4048
                           (const_int 8))))]
4049
  "(TARGET_H8300H || TARGET_H8300S)
4050
   && reload_completed
4051
   && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
4052
  [(set (match_dup 0)
4053
        (match_dup 3))]
4054
  "operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));")
4055
 
4056
;; ior:SI
4057
 
4058
(define_insn "*iorsi3_two_hi"
4059
  [(set (match_operand:SI 0 "register_operand" "=r")
4060
        (ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
4061
                (ashift:SI (match_operand:SI 2 "register_operand" "r")
4062
                           (const_int 16))))]
4063
  "TARGET_H8300H || TARGET_H8300S"
4064
  "mov.w\\t%f2,%e0"
4065
  [(set_attr "length" "2")])
4066
 
4067
(define_insn_and_split "*iorsi3_two_qi_zext"
4068
  [(set (match_operand:SI 0 "register_operand" "=&r")
4069
        (ior:SI (zero_extend:SI (match_operand:QI 1 "memory_operand" "m"))
4070
 
4071
                (and:SI (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
4072
                                   (const_int 8))
4073
                        (const_int 65280))))]
4074
  "(TARGET_H8300H || TARGET_H8300S)"
4075
  "#"
4076
  "&& reload_completed"
4077
  [(set (match_dup 3)
4078
        (ior:HI (zero_extend:HI (match_dup 1))
4079
                (ashift:HI (subreg:HI (match_dup 2) 0)
4080
                           (const_int 8))))
4081
   (set (match_dup 0)
4082
        (zero_extend:SI (match_dup 3)))]
4083
  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
4084
 
4085
(define_insn "*iorsi3_e2f"
4086
  [(set (match_operand:SI 0 "register_operand" "=r")
4087
        (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
4088
                        (const_int -65536))
4089
                (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
4090
                             (const_int 16))))]
4091
  "TARGET_H8300H || TARGET_H8300S"
4092
  "mov.w\\t%e2,%f0"
4093
  [(set_attr "length" "2")])
4094
 
4095
(define_insn_and_split "*iorsi3_two_qi_sext"
4096
  [(set (match_operand:SI 0 "register_operand" "=r")
4097
        (ior:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "0"))
4098
                (ashift:SI (sign_extend:SI (match_operand:QI 2 "register_operand" "r"))
4099
                           (const_int 8))))]
4100
  "(TARGET_H8300H || TARGET_H8300S)"
4101
  "#"
4102
  "&& reload_completed"
4103
  [(set (match_dup 3)
4104
        (ior:HI (zero_extend:HI (match_dup 1))
4105
                (ashift:HI (match_dup 4)
4106
                           (const_int 8))))
4107
   (set (match_dup 0)
4108
        (sign_extend:SI (match_dup 3)))]
4109
  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
4110
   operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));")
4111
 
4112
(define_insn "*iorsi3_w"
4113
  [(set (match_operand:SI 0 "register_operand" "=r,&r")
4114
        (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
4115
                        (const_int -256))
4116
                (zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
4117
  "TARGET_H8300H || TARGET_H8300S"
4118
  "mov.b\\t%X2,%w0"
4119
  [(set_attr "length" "2,8")])
4120
 
4121
(define_insn "*iorsi3_ashift_31"
4122
  [(set (match_operand:SI 0 "register_operand" "=&r")
4123
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
4124
                           (const_int 31))
4125
                (match_operand:SI 2 "register_operand" "0")))]
4126
  "TARGET_H8300H || TARGET_H8300S"
4127
  "rotxl.l\\t%S0\;bor\\t#0,%w1\;rotxr.l\\t%S0"
4128
  [(set_attr "length" "6")
4129
   (set_attr "cc" "set_znv")])
4130
 
4131
(define_insn "*iorsi3_and_ashift"
4132
  [(set (match_operand:SI 0 "register_operand" "=r")
4133
        (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
4134
                                   (match_operand:SI 2 "const_int_operand" "n"))
4135
                        (match_operand:SI 3 "single_one_operand" "n"))
4136
                (match_operand:SI 4 "register_operand" "0")))]
4137
  "(TARGET_H8300H || TARGET_H8300S)
4138
   && (INTVAL (operands[3]) & ~0xffff) == 0"
4139
  "*
4140
{
4141
  rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
4142
                        - INTVAL (operands[2]));
4143
  rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
4144
  operands[2] = srcpos;
4145
  operands[3] = dstpos;
4146
  return \"bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0\";
4147
}"
4148
  [(set_attr "length" "6")])
4149
 
4150
(define_insn "*iorsi3_and_lshiftrt"
4151
  [(set (match_operand:SI 0 "register_operand" "=r")
4152
        (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4153
                                     (match_operand:SI 2 "const_int_operand" "n"))
4154
                        (match_operand:SI 3 "single_one_operand" "n"))
4155
                (match_operand:SI 4 "register_operand" "0")))]
4156
  "(TARGET_H8300H || TARGET_H8300S)
4157
   && ((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
4158
  "*
4159
{
4160
  rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
4161
                        + INTVAL (operands[2]));
4162
  rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3])));
4163
  operands[2] = srcpos;
4164
  operands[3] = dstpos;
4165
  return \"bld\\t%Z2,%Y1\;bor\\t%Z3,%Y0\;bst\\t%Z3,%Y0\";
4166
}"
4167
  [(set_attr "length" "6")])
4168
 
4169
(define_insn "*iorsi3_zero_extract"
4170
  [(set (match_operand:SI 0 "register_operand" "=r")
4171
        (ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
4172
                                 (const_int 1)
4173
                                 (match_operand:SI 2 "const_int_operand" "n"))
4174
                (match_operand:SI 3 "register_operand" "0")))]
4175
  "(TARGET_H8300H || TARGET_H8300S)
4176
   && INTVAL (operands[2]) < 16"
4177
  "bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
4178
  [(set_attr "length" "6")])
4179
 
4180
(define_insn "*iorsi3_and_lshiftrt_n_sb"
4181
  [(set (match_operand:SI 0 "register_operand" "=r")
4182
        (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4183
                                     (const_int 30))
4184
                        (const_int 2))
4185
                (match_operand:SI 2 "register_operand" "0")))]
4186
  "(TARGET_H8300H || TARGET_H8300S)"
4187
  "rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
4188
  [(set_attr "length" "8")])
4189
 
4190
(define_insn "*iorsi3_and_lshiftrt_9_sb"
4191
  [(set (match_operand:SI 0 "register_operand" "=r")
4192
        (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4193
                                     (const_int 9))
4194
                        (const_int 4194304))
4195
                (match_operand:SI 2 "register_operand" "0")))
4196
   (clobber (match_scratch:HI 3 "=&r"))]
4197
  "(TARGET_H8300H || TARGET_H8300S)"
4198
  "*
4199
{
4200
  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4201
    return \"shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0\";
4202
  else
4203
    return \"rotl.l\\t%S1\;rotr.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0\";
4204
}"
4205
  [(set_attr "length" "10")])
4206
 
4207
;; Used to OR the exponent of a float.
4208
 
4209
(define_insn "*iorsi3_shift"
4210
  [(set (match_operand:SI 0 "register_operand" "=r")
4211
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
4212
                           (const_int 23))
4213
                (match_operand:SI 2 "register_operand" "0")))
4214
   (clobber (match_scratch:SI 3 "=&r"))]
4215
  "TARGET_H8300H || TARGET_H8300S"
4216
  "#")
4217
 
4218
(define_split
4219
  [(set (match_operand:SI 0 "register_operand" "")
4220
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4221
                           (const_int 23))
4222
                (match_dup 0)))
4223
   (clobber (match_operand:SI 2 "register_operand" ""))]
4224
  "(TARGET_H8300H || TARGET_H8300S)
4225
   && epilogue_completed
4226
   && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4227
   && REGNO (operands[0]) != REGNO (operands[1])"
4228
  [(parallel [(set (match_dup 3)
4229
                   (ashift:HI (match_dup 3)
4230
                              (const_int 7)))
4231
              (clobber (scratch:QI))])
4232
   (set (match_dup 0)
4233
        (ior:SI (ashift:SI (match_dup 1)
4234
                           (const_int 16))
4235
                (match_dup 0)))]
4236
  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));")
4237
 
4238
(define_split
4239
  [(set (match_operand:SI 0 "register_operand" "")
4240
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4241
                           (const_int 23))
4242
                (match_dup 0)))
4243
   (clobber (match_operand:SI 2 "register_operand" ""))]
4244
  "(TARGET_H8300H || TARGET_H8300S)
4245
   && epilogue_completed
4246
   && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4247
        && REGNO (operands[0]) != REGNO (operands[1]))"
4248
  [(set (match_dup 2)
4249
        (match_dup 1))
4250
   (parallel [(set (match_dup 3)
4251
                   (ashift:HI (match_dup 3)
4252
                              (const_int 7)))
4253
              (clobber (scratch:QI))])
4254
   (set (match_dup 0)
4255
        (ior:SI (ashift:SI (match_dup 2)
4256
                           (const_int 16))
4257
                (match_dup 0)))]
4258
  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));")
4259
 
4260
(define_insn "*iorsi2_and_1_lshiftrt_1"
4261
  [(set (match_operand:SI 0 "register_operand" "=r")
4262
        (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
4263
                        (const_int 1))
4264
                (lshiftrt:SI (match_dup 1)
4265
                             (const_int 1))))]
4266
  "TARGET_H8300H || TARGET_H8300S"
4267
  "shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
4268
  [(set_attr "length" "6")])
4269
 
4270
(define_insn_and_split "*iorsi3_ashift_16_ashift_24"
4271
  [(set (match_operand:SI 0 "register_operand" "=r")
4272
        (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4273
                           (const_int 16))
4274
                (ashift:SI (match_operand:SI 2 "register_operand" "r")
4275
                           (const_int 24))))]
4276
  "(TARGET_H8300H || TARGET_H8300S)"
4277
  "#"
4278
  "&& reload_completed"
4279
  [(set (match_dup 3)
4280
        (ior:HI (ashift:HI (match_dup 4)
4281
                           (const_int 8))
4282
                (match_dup 3)))
4283
   (parallel [(set (match_dup 0)
4284
                   (ashift:SI (match_dup 0)
4285
                              (const_int 16)))
4286
              (clobber (scratch:QI))])]
4287
  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
4288
   operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));")
4289
 
4290
(define_insn_and_split "*iorsi3_ashift_16_ashift_24_mem"
4291
  [(set (match_operand:SI 0 "register_operand" "=&r")
4292
        (ior:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
4293
                                   (const_int 16))
4294
                        (const_int 16711680))
4295
                (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
4296
                           (const_int 24))))]
4297
  "(TARGET_H8300H || TARGET_H8300S)"
4298
  "#"
4299
  "&& reload_completed"
4300
  [(set (match_dup 3)
4301
        (ior:HI (zero_extend:HI (match_dup 1))
4302
                (ashift:HI (subreg:HI (match_dup 2) 0)
4303
                           (const_int 8))))
4304
   (parallel [(set (match_dup 0)
4305
                   (ashift:SI (match_dup 0)
4306
                              (const_int 16)))
4307
              (clobber (scratch:QI))])]
4308
  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));")
4309
 
4310
;; Used to add the exponent of a float.
4311
 
4312
(define_insn "*addsi3_shift"
4313
  [(set (match_operand:SI 0 "register_operand" "=r")
4314
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
4315
                          (const_int 8388608))
4316
                 (match_operand:SI 2 "register_operand" "0")))
4317
   (clobber (match_scratch:SI 3 "=&r"))]
4318
  "TARGET_H8300H || TARGET_H8300S"
4319
  "#")
4320
 
4321
(define_split
4322
  [(set (match_operand:SI 0 "register_operand" "")
4323
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
4324
                          (const_int 8388608))
4325
                 (match_dup 0)))
4326
   (clobber (match_operand:SI 2 "register_operand" ""))]
4327
  "(TARGET_H8300H || TARGET_H8300S)
4328
   && epilogue_completed
4329
   && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4330
   && REGNO (operands[0]) != REGNO (operands[1])"
4331
  [(parallel [(set (match_dup 3)
4332
                   (ashift:HI (match_dup 3)
4333
                              (const_int 7)))
4334
              (clobber (scratch:QI))])
4335
   (set (match_dup 0)
4336
        (plus:SI (mult:SI (match_dup 1)
4337
                          (const_int 65536))
4338
                 (match_dup 0)))]
4339
  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));")
4340
 
4341
(define_split
4342
  [(set (match_operand:SI 0 "register_operand" "")
4343
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
4344
                          (const_int 8388608))
4345
                 (match_dup 0)))
4346
   (clobber (match_operand:SI 2 "register_operand" ""))]
4347
  "(TARGET_H8300H || TARGET_H8300S)
4348
   && epilogue_completed
4349
   && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
4350
        && REGNO (operands[0]) != REGNO (operands[1]))"
4351
  [(set (match_dup 2)
4352
        (match_dup 1))
4353
   (parallel [(set (match_dup 3)
4354
                   (ashift:HI (match_dup 3)
4355
                              (const_int 7)))
4356
              (clobber (scratch:QI))])
4357
   (set (match_dup 0)
4358
        (plus:SI (mult:SI (match_dup 2)
4359
                          (const_int 65536))
4360
                 (match_dup 0)))]
4361
  "operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));")
4362
 
4363
;; ashift:SI
4364
 
4365
(define_insn_and_split "*ashiftsi_sextqi_7"
4366
  [(set (match_operand:SI 0 "register_operand" "=r")
4367
        (ashift:SI (sign_extend:SI (match_operand:QI 1 "register_operand" "0"))
4368
                   (const_int 7)))]
4369
  "(TARGET_H8300H || TARGET_H8300S)"
4370
  "#"
4371
  "&& reload_completed"
4372
  [(parallel [(set (match_dup 2)
4373
                   (ashift:HI (match_dup 2)
4374
                              (const_int 8)))
4375
              (clobber (scratch:QI))])
4376
   (set (match_dup 0)
4377
        (sign_extend:SI (match_dup 2)))
4378
   (parallel [(set (match_dup 0)
4379
                   (ashiftrt:SI (match_dup 0)
4380
                                (const_int 1)))
4381
              (clobber (scratch:QI))])]
4382
  "operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));")
4383
 
4384
;; Storing a part of HImode to QImode.
4385
 
4386
(define_insn ""
4387
  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4388
        (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
4389
                                (const_int 8)) 1))]
4390
  ""
4391
  "mov.b\\t%t1,%R0"
4392
  [(set_attr "cc" "set_znv")
4393
   (set_attr "length" "8")])
4394
 
4395
;; Storing a part of SImode to QImode.
4396
 
4397
(define_insn ""
4398
  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4399
        (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4400
                                (const_int 8)) 3))]
4401
  ""
4402
  "mov.b\\t%x1,%R0"
4403
  [(set_attr "cc" "set_znv")
4404
   (set_attr "length" "8")])
4405
 
4406
(define_insn ""
4407
  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4408
        (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4409
                                (const_int 16)) 3))
4410
   (clobber (match_scratch:SI 2 "=&r"))]
4411
  "TARGET_H8300H || TARGET_H8300S"
4412
  "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
4413
  [(set_attr "cc" "set_znv")
4414
   (set_attr "length" "10")])
4415
 
4416
(define_insn ""
4417
  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
4418
        (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4419
                                (const_int 24)) 3))
4420
   (clobber (match_scratch:SI 2 "=&r"))]
4421
  "TARGET_H8300H || TARGET_H8300S"
4422
  "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
4423
  [(set_attr "cc" "set_znv")
4424
   (set_attr "length" "10")])
4425
 
4426
(define_insn_and_split ""
4427
  [(set (pc)
4428
        (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
4429
                                           (const_int 1)
4430
                                           (const_int 7))
4431
                          (const_int 0))
4432
                      (label_ref (match_operand 1 "" ""))
4433
                      (pc)))]
4434
  ""
4435
  "#"
4436
  ""
4437
  [(set (cc0) (compare (match_dup 0)
4438
                       (const_int 0)))
4439
   (set (pc)
4440
        (if_then_else (ge (cc0)
4441
                          (const_int 0))
4442
                      (label_ref (match_dup 1))
4443
                      (pc)))]
4444
  "")
4445
 
4446
(define_insn_and_split ""
4447
  [(set (pc)
4448
        (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
4449
                                           (const_int 1)
4450
                                           (const_int 7))
4451
                          (const_int 0))
4452
                      (label_ref (match_operand 1 "" ""))
4453
                      (pc)))]
4454
  ""
4455
  "#"
4456
  ""
4457
  [(set (cc0) (compare (match_dup 0)
4458
                       (const_int 0)))
4459
   (set (pc)
4460
        (if_then_else (lt (cc0)
4461
                          (const_int 0))
4462
                      (label_ref (match_dup 1))
4463
                      (pc)))]
4464
  "")
4465
 
4466
;; -----------------------------------------------------------------
4467
;; PEEPHOLE PATTERNS
4468
;; -----------------------------------------------------------------
4469
 
4470
;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
4471
 
4472
(define_peephole2
4473
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
4474
                   (lshiftrt:HI (match_dup 0)
4475
                                (match_operand:HI 1 "const_int_operand" "")))
4476
              (clobber (match_operand:HI 2 "" ""))])
4477
   (set (match_dup 0)
4478
        (and:HI (match_dup 0)
4479
                (match_operand:HI 3 "const_int_operand" "")))]
4480
  "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
4481
  [(set (match_dup 0)
4482
        (and:HI (match_dup 0)
4483
                (const_int 255)))
4484
   (parallel
4485
     [(set (match_dup 0)
4486
           (lshiftrt:HI (match_dup 0)
4487
                        (match_dup 1)))
4488
      (clobber (match_dup 2))])]
4489
  "")
4490
 
4491
;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
4492
 
4493
(define_peephole2
4494
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
4495
                   (ashift:HI (match_dup 0)
4496
                              (match_operand:HI 1 "const_int_operand" "")))
4497
              (clobber (match_operand:HI 2 "" ""))])
4498
   (set (match_dup 0)
4499
        (and:HI (match_dup 0)
4500
                (match_operand:HI 3 "const_int_operand" "")))]
4501
  "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
4502
  [(set (match_dup 0)
4503
        (and:HI (match_dup 0)
4504
                (const_int 255)))
4505
   (parallel
4506
     [(set (match_dup 0)
4507
           (ashift:HI (match_dup 0)
4508
                      (match_dup 1)))
4509
      (clobber (match_dup 2))])]
4510
  "")
4511
 
4512
;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.
4513
 
4514
(define_peephole2
4515
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
4516
                   (lshiftrt:SI (match_dup 0)
4517
                                (match_operand:SI 1 "const_int_operand" "")))
4518
              (clobber (match_operand:SI 2 "" ""))])
4519
   (set (match_dup 0)
4520
        (and:SI (match_dup 0)
4521
                (match_operand:SI 3 "const_int_operand" "")))]
4522
  "INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))"
4523
  [(set (match_dup 0)
4524
        (and:SI (match_dup 0)
4525
                (const_int 255)))
4526
   (parallel
4527
     [(set (match_dup 0)
4528
           (lshiftrt:SI (match_dup 0)
4529
                        (match_dup 1)))
4530
      (clobber (match_dup 2))])]
4531
  "")
4532
 
4533
;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.
4534
 
4535
(define_peephole2
4536
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
4537
                   (ashift:SI (match_dup 0)
4538
                              (match_operand:SI 1 "const_int_operand" "")))
4539
              (clobber (match_operand:SI 2 "" ""))])
4540
   (set (match_dup 0)
4541
        (and:SI (match_dup 0)
4542
                (match_operand:SI 3 "const_int_operand" "")))]
4543
  "INTVAL (operands[3]) == (255 << INTVAL (operands[1]))"
4544
  [(set (match_dup 0)
4545
        (and:SI (match_dup 0)
4546
                (const_int 255)))
4547
   (parallel
4548
     [(set (match_dup 0)
4549
           (ashift:SI (match_dup 0)
4550
                      (match_dup 1)))
4551
      (clobber (match_dup 2))])]
4552
  "")
4553
 
4554
;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.
4555
 
4556
(define_peephole2
4557
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
4558
                   (lshiftrt:SI (match_dup 0)
4559
                                (match_operand:SI 1 "const_int_operand" "")))
4560
              (clobber (match_operand:SI 2 "" ""))])
4561
   (set (match_dup 0)
4562
        (and:SI (match_dup 0)
4563
                (match_operand:SI 3 "const_int_operand" "")))]
4564
  "INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))"
4565
  [(set (match_dup 0)
4566
        (and:SI (match_dup 0)
4567
                (const_int 65535)))
4568
   (parallel
4569
     [(set (match_dup 0)
4570
           (lshiftrt:SI (match_dup 0)
4571
                        (match_dup 1)))
4572
      (clobber (match_dup 2))])]
4573
  "")
4574
 
4575
;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.
4576
 
4577
(define_peephole2
4578
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
4579
                   (ashift:SI (match_dup 0)
4580
                              (match_operand:SI 1 "const_int_operand" "")))
4581
              (clobber (match_operand:SI 2 "" ""))])
4582
   (set (match_dup 0)
4583
        (and:SI (match_dup 0)
4584
                (match_operand:SI 3 "const_int_operand" "")))]
4585
  "INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))"
4586
  [(set (match_dup 0)
4587
        (and:SI (match_dup 0)
4588
                (const_int 65535)))
4589
   (parallel
4590
     [(set (match_dup 0)
4591
           (ashift:SI (match_dup 0)
4592
                      (match_dup 1)))
4593
      (clobber (match_dup 2))])]
4594
  "")
4595
 
4596
;; Convert a QImode push into an SImode push so that the
4597
;; define_peephole2 below can cram multiple pushes into one stm.l.
4598
 
4599
(define_peephole2
4600
  [(parallel [(set (reg:SI SP_REG)
4601
                   (plus:SI (reg:SI SP_REG) (const_int -4)))
4602
              (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3)))
4603
                   (match_operand:QI 0 "register_operand" ""))])]
4604
  "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4605
  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4606
        (match_dup 0))]
4607
  "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
4608
 
4609
(define_peephole2
4610
  [(parallel [(set (reg:HI SP_REG)
4611
                   (plus:HI (reg:HI SP_REG) (const_int -4)))
4612
              (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3)))
4613
                   (match_operand:QI 0 "register_operand" ""))])]
4614
  "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4615
  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4616
        (match_dup 0))]
4617
  "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
4618
 
4619
;; Convert a HImode push into an SImode push so that the
4620
;; define_peephole2 below can cram multiple pushes into one stm.l.
4621
 
4622
(define_peephole2
4623
  [(parallel [(set (reg:SI SP_REG)
4624
                   (plus:SI (reg:SI SP_REG) (const_int -4)))
4625
              (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2)))
4626
                   (match_operand:HI 0 "register_operand" ""))])]
4627
  "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4628
  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4629
        (match_dup 0))]
4630
  "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
4631
 
4632
(define_peephole2
4633
  [(parallel [(set (reg:HI SP_REG)
4634
                   (plus:HI (reg:HI SP_REG) (const_int -4)))
4635
              (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2)))
4636
                   (match_operand:HI 0 "register_operand" ""))])]
4637
  "TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
4638
  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4639
        (match_dup 0))]
4640
  "operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
4641
 
4642
;; Cram four pushes into stm.l.
4643
 
4644
(define_peephole2
4645
  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4646
        (match_operand:SI 0 "register_operand" ""))
4647
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4648
        (match_operand:SI 1 "register_operand" ""))
4649
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4650
        (match_operand:SI 2 "register_operand" ""))
4651
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4652
        (match_operand:SI 3 "register_operand" ""))]
4653
  "TARGET_H8300S && !TARGET_NORMAL_MODE
4654
   && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
4655
       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4656
       && REGNO (operands[2]) == REGNO (operands[0]) + 2
4657
       && REGNO (operands[3]) == REGNO (operands[0]) + 3
4658
       && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
4659
  [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4660
                   (match_dup 0))
4661
              (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4662
                   (match_dup 1))
4663
              (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
4664
                   (match_dup 2))
4665
              (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16)))
4666
                   (match_dup 3))
4667
              (set (reg:SI SP_REG)
4668
                   (plus:SI (reg:SI SP_REG)
4669
                            (const_int -16)))])]
4670
  "")
4671
 
4672
(define_peephole2
4673
  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4674
        (match_operand:SI 0 "register_operand" ""))
4675
   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4676
        (match_operand:SI 1 "register_operand" ""))
4677
   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4678
        (match_operand:SI 2 "register_operand" ""))
4679
   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4680
        (match_operand:SI 3 "register_operand" ""))]
4681
  "TARGET_H8300S && TARGET_NORMAL_MODE
4682
   && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS
4683
       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4684
       && REGNO (operands[2]) == REGNO (operands[0]) + 2
4685
       && REGNO (operands[3]) == REGNO (operands[0]) + 3
4686
       && (TARGET_H8300SX || REGNO (operands[0]) == 0))"
4687
  [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4688
                   (match_dup 0))
4689
              (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4690
                   (match_dup 1))
4691
              (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4692
                   (match_dup 2))
4693
              (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16)))
4694
                   (match_dup 3))
4695
              (set (reg:HI SP_REG)
4696
                   (plus:HI (reg:HI SP_REG)
4697
                            (const_int -16)))])]
4698
  "")
4699
 
4700
;; Cram three pushes into stm.l.
4701
 
4702
(define_peephole2
4703
  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4704
        (match_operand:SI 0 "register_operand" ""))
4705
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4706
        (match_operand:SI 1 "register_operand" ""))
4707
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4708
        (match_operand:SI 2 "register_operand" ""))]
4709
  "TARGET_H8300S && !TARGET_NORMAL_MODE
4710
   && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
4711
       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4712
       && REGNO (operands[2]) == REGNO (operands[0]) + 2
4713
       && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
4714
  [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4715
                   (match_dup 0))
4716
              (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4717
                   (match_dup 1))
4718
              (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12)))
4719
                   (match_dup 2))
4720
              (set (reg:SI SP_REG)
4721
                   (plus:SI (reg:SI SP_REG)
4722
                            (const_int -12)))])]
4723
  "")
4724
 
4725
(define_peephole2
4726
  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4727
        (match_operand:SI 0 "register_operand" ""))
4728
   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4729
        (match_operand:SI 1 "register_operand" ""))
4730
   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4731
        (match_operand:SI 2 "register_operand" ""))]
4732
  "TARGET_H8300S && TARGET_NORMAL_MODE
4733
   && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS
4734
       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4735
       && REGNO (operands[2]) == REGNO (operands[0]) + 2
4736
       && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))"
4737
  [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4738
                   (match_dup 0))
4739
              (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4740
                   (match_dup 1))
4741
              (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12)))
4742
                   (match_dup 2))
4743
              (set (reg:HI SP_REG)
4744
                   (plus:HI (reg:HI SP_REG)
4745
                            (const_int -12)))])]
4746
  "")
4747
 
4748
;; Cram two pushes into stm.l.
4749
 
4750
(define_peephole2
4751
  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4752
        (match_operand:SI 0 "register_operand" ""))
4753
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4754
        (match_operand:SI 1 "register_operand" ""))]
4755
  "TARGET_H8300S && !TARGET_NORMAL_MODE
4756
   && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
4757
       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4758
       && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
4759
  [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4)))
4760
                   (match_dup 0))
4761
              (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8)))
4762
                   (match_dup 1))
4763
              (set (reg:SI SP_REG)
4764
                   (plus:SI (reg:SI SP_REG)
4765
                            (const_int -8)))])]
4766
  "")
4767
 
4768
(define_peephole2
4769
  [(set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4770
        (match_operand:SI 0 "register_operand" ""))
4771
   (set (mem:SI (pre_dec:HI (reg:HI SP_REG)))
4772
        (match_operand:SI 1 "register_operand" ""))]
4773
  "TARGET_H8300S && TARGET_NORMAL_MODE
4774
   && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS
4775
       && REGNO (operands[1]) == REGNO (operands[0]) + 1
4776
       && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))"
4777
  [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4)))
4778
                   (match_dup 0))
4779
              (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8)))
4780
                   (match_dup 1))
4781
              (set (reg:HI SP_REG)
4782
                   (plus:HI (reg:HI SP_REG)
4783
                            (const_int -8)))])]
4784
  "")
4785
 
4786
;; Turn
4787
;;
4788
;;   mov.w #2,r0
4789
;;   add.w r7,r0  (6 bytes)
4790
;;
4791
;; into
4792
;;
4793
;;   mov.w r7,r0
4794
;;   adds  #2,r0  (4 bytes)
4795
 
4796
(define_peephole2
4797
  [(set (match_operand:HI 0 "register_operand" "")
4798
        (match_operand:HI 1 "const_int_operand" ""))
4799
   (set (match_dup 0)
4800
        (plus:HI (match_dup 0)
4801
                 (match_operand:HI 2 "register_operand" "")))]
4802
  "REG_P (operands[0]) && REG_P (operands[2])
4803
   && REGNO (operands[0]) != REGNO (operands[2])
4804
   && (satisfies_constraint_J (operands[1])
4805
       || satisfies_constraint_L (operands[1])
4806
       || satisfies_constraint_N (operands[1]))"
4807
  [(set (match_dup 0)
4808
        (match_dup 2))
4809
   (set (match_dup 0)
4810
        (plus:HI (match_dup 0)
4811
                 (match_dup 1)))]
4812
  "")
4813
 
4814
;; Turn
4815
;;
4816
;;   sub.l  er0,er0
4817
;;   add.b  #4,r0l
4818
;;   add.l  er7,er0  (6 bytes)
4819
;;
4820
;; into
4821
;;
4822
;;   mov.l  er7,er0
4823
;;   adds   #4,er0   (4 bytes)
4824
 
4825
(define_peephole2
4826
  [(set (match_operand:SI 0 "register_operand" "")
4827
        (match_operand:SI 1 "const_int_operand" ""))
4828
   (set (match_dup 0)
4829
        (plus:SI (match_dup 0)
4830
                 (match_operand:SI 2 "register_operand" "")))]
4831
  "(TARGET_H8300H || TARGET_H8300S)
4832
   && REG_P (operands[0]) && REG_P (operands[2])
4833
   && REGNO (operands[0]) != REGNO (operands[2])
4834
   && (satisfies_constraint_L (operands[1])
4835
       || satisfies_constraint_N (operands[1]))"
4836
  [(set (match_dup 0)
4837
        (match_dup 2))
4838
   (set (match_dup 0)
4839
        (plus:SI (match_dup 0)
4840
                 (match_dup 1)))]
4841
  "")
4842
 
4843
;; Turn
4844
;;
4845
;;   mov.l er7,er0
4846
;;   add.l #10,er0  (takes 8 bytes)
4847
;;
4848
;; into
4849
;;
4850
;;   sub.l er0,er0
4851
;;   add.b #10,r0l
4852
;;   add.l er7,er0  (takes 6 bytes)
4853
 
4854
(define_peephole2
4855
  [(set (match_operand:SI 0 "register_operand" "")
4856
        (match_operand:SI 1 "register_operand" ""))
4857
   (set (match_dup 0)
4858
        (plus:SI (match_dup 0)
4859
                 (match_operand:SI 2 "const_int_operand" "")))]
4860
  "(TARGET_H8300H || TARGET_H8300S)
4861
   && REG_P (operands[0]) && REG_P (operands[1])
4862
   && REGNO (operands[0]) != REGNO (operands[1])
4863
   && !satisfies_constraint_L (operands[2])
4864
   && !satisfies_constraint_N (operands[2])
4865
   && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2])
4866
       || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2])
4867
       || INTVAL (operands[2]) == 0xffff
4868
       || INTVAL (operands[2]) == 0xfffe)"
4869
  [(set (match_dup 0)
4870
        (match_dup 2))
4871
   (set (match_dup 0)
4872
        (plus:SI (match_dup 0)
4873
                 (match_dup 1)))]
4874
  "")
4875
 
4876
;; Turn
4877
;;
4878
;;   subs   #1,er4
4879
;;   mov.w  r4,r4
4880
;;   bne    .L2028
4881
;;
4882
;; into
4883
;;
4884
;;   dec.w  #1,r4
4885
;;   bne    .L2028
4886
 
4887
(define_peephole2
4888
  [(set (match_operand:HI 0 "register_operand" "")
4889
        (plus:HI (match_dup 0)
4890
                 (match_operand 1 "incdec_operand" "")))
4891
   (set (cc0) (compare (match_dup 0)
4892
                       (const_int 0)))
4893
   (set (pc)
4894
        (if_then_else (match_operator 3 "eqne_operator"
4895
                        [(cc0) (const_int 0)])
4896
                      (label_ref (match_operand 2 "" ""))
4897
                      (pc)))]
4898
  "TARGET_H8300H || TARGET_H8300S"
4899
  [(set (match_operand:HI 0 "register_operand" "")
4900
        (unspec:HI [(match_dup 0)
4901
                    (match_dup 1)]
4902
                   UNSPEC_INCDEC))
4903
   (set (cc0) (compare (match_dup 0)
4904
                       (const_int 0)))
4905
   (set (pc)
4906
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4907
                      (label_ref (match_dup 2))
4908
                      (pc)))]
4909
  "")
4910
 
4911
;; The SImode version of the previous pattern.
4912
 
4913
(define_peephole2
4914
  [(set (match_operand:SI 0 "register_operand" "")
4915
        (plus:SI (match_dup 0)
4916
                 (match_operand 1 "incdec_operand" "")))
4917
   (set (cc0) (compare (match_dup 0)
4918
                       (const_int 0)))
4919
   (set (pc)
4920
        (if_then_else (match_operator 3 "eqne_operator"
4921
                        [(cc0) (const_int 0)])
4922
                      (label_ref (match_operand 2 "" ""))
4923
                      (pc)))]
4924
  "TARGET_H8300H || TARGET_H8300S"
4925
  [(set (match_operand:SI 0 "register_operand" "")
4926
        (unspec:SI [(match_dup 0)
4927
                    (match_dup 1)]
4928
                   UNSPEC_INCDEC))
4929
   (set (cc0) (compare (match_dup 0)
4930
                       (const_int 0)))
4931
   (set (pc)
4932
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4933
                      (label_ref (match_dup 2))
4934
                      (pc)))]
4935
  "")
4936
 
4937
(define_peephole2
4938
  [(parallel [(set (cc0)
4939
                   (compare (zero_extract:SI (match_operand:QI 0 "register_operand" "")
4940
                                             (const_int 1)
4941
                                             (const_int 7))
4942
                            (const_int 0)))
4943
              (clobber (scratch:QI))])
4944
   (set (pc)
4945
        (if_then_else (match_operator 1 "eqne_operator"
4946
                        [(cc0) (const_int 0)])
4947
                      (label_ref (match_operand 2 "" ""))
4948
                      (pc)))]
4949
  "(TARGET_H8300H || TARGET_H8300S)"
4950
  [(set (cc0) (compare (match_dup 0)
4951
                       (const_int 0)))
4952
   (set (pc)
4953
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
4954
                      (label_ref (match_dup 2))
4955
                      (pc)))]
4956
  "operands[3] = ((GET_CODE (operands[1]) == EQ)
4957
                  ? gen_rtx_GE (VOIDmode, cc0_rtx, const0_rtx)
4958
                  : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));")
4959
 
4960
;; The next three peephole2's will try to transform
4961
;;
4962
;;   mov.b A,r0l    (or mov.l A,er0)
4963
;;   and.l #CST,er0
4964
;;
4965
;; into
4966
;;
4967
;;   sub.l er0
4968
;;   mov.b A,r0l
4969
;;   and.b #CST,r0l (if CST is not 255)
4970
 
4971
(define_peephole2
4972
  [(set (match_operand:QI 0 "register_operand" "")
4973
        (match_operand:QI 1 "general_operand" ""))
4974
   (set (match_operand:SI 2 "register_operand" "")
4975
        (and:SI (match_dup 2)
4976
                (const_int 255)))]
4977
  "(TARGET_H8300H || TARGET_H8300S)
4978
   && !reg_overlap_mentioned_p (operands[2], operands[1])
4979
   && REGNO (operands[0]) == REGNO (operands[2])"
4980
  [(set (match_dup 2)
4981
        (const_int 0))
4982
   (set (strict_low_part (match_dup 0))
4983
        (match_dup 1))]
4984
  "")
4985
 
4986
(define_peephole2
4987
  [(set (match_operand:SI 0 "register_operand" "")
4988
        (match_operand:SI 1 "general_operand" ""))
4989
   (set (match_dup 0)
4990
        (and:SI (match_dup 0)
4991
                (const_int 255)))]
4992
  "(TARGET_H8300H || TARGET_H8300S)
4993
   && !reg_overlap_mentioned_p (operands[0], operands[1])
4994
   && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
4995
   && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
4996
  [(set (match_dup 0)
4997
        (const_int 0))
4998
   (set (strict_low_part (match_dup 2))
4999
        (match_dup 3))]
5000
  "operands[2] = gen_lowpart (QImode, operands[0]);
5001
   operands[3] = gen_lowpart (QImode, operands[1]);")
5002
 
5003
(define_peephole2
5004
  [(set (match_operand 0 "register_operand" "")
5005
        (match_operand 1 "general_operand" ""))
5006
   (set (match_operand:SI 2 "register_operand" "")
5007
        (and:SI (match_dup 2)
5008
                (match_operand:SI 3 "const_int_qi_operand" "")))]
5009
  "(TARGET_H8300H || TARGET_H8300S)
5010
   && (GET_MODE (operands[0]) == QImode
5011
       || GET_MODE (operands[0]) == HImode
5012
       || GET_MODE (operands[0]) == SImode)
5013
   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5014
   && REGNO (operands[0]) == REGNO (operands[2])
5015
   && !reg_overlap_mentioned_p (operands[2], operands[1])
5016
   && !(GET_MODE (operands[1]) != QImode
5017
        && GET_CODE (operands[1]) == MEM
5018
        && !offsettable_memref_p (operands[1]))
5019
   && !(GET_MODE (operands[1]) != QImode
5020
        && GET_CODE (operands[1]) == MEM
5021
        && MEM_VOLATILE_P (operands[1]))"
5022
  [(set (match_dup 2)
5023
        (const_int 0))
5024
   (set (strict_low_part (match_dup 4))
5025
        (match_dup 5))
5026
   (set (match_dup 2)
5027
        (and:SI (match_dup 2)
5028
                (match_dup 6)))]
5029
  "operands[4] = gen_lowpart (QImode, operands[0]);
5030
   operands[5] = gen_lowpart (QImode, operands[1]);
5031
   operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));")
5032
 
5033
(define_peephole2
5034
  [(set (match_operand:SI 0 "register_operand" "")
5035
        (match_operand:SI 1 "register_operand" ""))
5036
   (set (match_dup 0)
5037
        (and:SI (match_dup 0)
5038
                (const_int 65280)))]
5039
  "(TARGET_H8300H || TARGET_H8300S)
5040
   && !reg_overlap_mentioned_p (operands[0], operands[1])"
5041
  [(set (match_dup 0)
5042
        (const_int 0))
5043
   (set (zero_extract:SI (match_dup 0)
5044
                         (const_int 8)
5045
                         (const_int 8))
5046
        (lshiftrt:SI (match_dup 1)
5047
                     (const_int 8)))]
5048
  "")
5049
 
5050
;; If a load of mem:SI is followed by an AND that turns off the upper
5051
;; half, then we can load mem:HI instead.
5052
 
5053
(define_peephole2
5054
  [(set (match_operand:SI 0 "register_operand" "")
5055
        (match_operand:SI 1 "memory_operand" ""))
5056
   (set (match_dup 0)
5057
        (and:SI (match_dup 0)
5058
                (match_operand:SI 2 "const_int_operand" "")))]
5059
  "(TARGET_H8300H || TARGET_H8300S)
5060
   && !MEM_VOLATILE_P (operands[1])
5061
   && offsettable_memref_p (operands[1])
5062
   && (INTVAL (operands[2]) & ~0xffff) == 0
5063
   && INTVAL (operands[2]) != 255"
5064
  [(set (match_dup 3)
5065
        (match_dup 4))
5066
   (set (match_dup 0)
5067
        (and:SI (match_dup 0)
5068
                (match_dup 2)))]
5069
  "operands[3] = gen_lowpart (HImode, operands[0]);
5070
   operands[4] = gen_lowpart (HImode, operands[1]);")
5071
 
5072
;; Convert a memory comparison to a move if there is a scratch register.
5073
 
5074
(define_peephole2
5075
  [(match_scratch:QI 1 "r")
5076
   (set (cc0)
5077
        (compare (match_operand:QI 0 "memory_operand" "")
5078
                 (const_int 0)))]
5079
  ""
5080
  [(set (match_dup 1)
5081
        (match_dup 0))
5082
   (set (cc0) (compare (match_dup 1)
5083
                       (const_int 0)))]
5084
  "")
5085
 
5086
(define_peephole2
5087
  [(match_scratch:HI 1 "r")
5088
   (set (cc0)
5089
        (compare (match_operand:HI 0 "memory_operand" "")
5090
                 (const_int 0)))]
5091
  "(TARGET_H8300H || TARGET_H8300S)"
5092
  [(set (match_dup 1)
5093
        (match_dup 0))
5094
   (set (cc0) (compare (match_dup 1)
5095
                       (const_int 0)))]
5096
  "")
5097
 
5098
(define_peephole2
5099
  [(match_scratch:SI 1 "r")
5100
   (set (cc0)
5101
        (compare (match_operand:SI 0 "memory_operand" "")
5102
                 (const_int 0)))]
5103
  "(TARGET_H8300H || TARGET_H8300S)"
5104
  [(set (match_dup 1)
5105
        (match_dup 0))
5106
   (set (cc0) (compare (match_dup 1)
5107
                       (const_int 0)))]
5108
  "")
5109
 
5110
 
5111
;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
5112
;; the equivalent with shorter sequences.  Here is the summary.  Cases
5113
;; are grouped for each define_peephole2.
5114
;;
5115
;; reg  const_int                   use     insn
5116
;; --------------------------------------------------------
5117
;; dead    -2                       eq/ne   inc.l
5118
;; dead    -1                       eq/ne   inc.l
5119
;; dead     1                       eq/ne   dec.l
5120
;; dead     2                       eq/ne   dec.l
5121
;;
5122
;; dead     1                       ge/lt shar.l
5123
;; dead     3 (H8S)                 ge/lt shar.l
5124
;;
5125
;; dead     1                       geu/ltu shar.l
5126
;; dead     3 (H8S)                 geu/ltu shar.l
5127
;;
5128
;; ----   255                       ge/lt mov.b
5129
;;
5130
;; ----   255                       geu/ltu mov.b
5131
 
5132
;; Transform
5133
;;
5134
;;      cmp.w   #1,r0
5135
;;      bne     .L1
5136
;;
5137
;; into
5138
;;
5139
;;      dec.w   #1,r0
5140
;;      bne     .L1
5141
 
5142
(define_peephole2
5143
  [(set (cc0)
5144
        (compare (match_operand:HI 0 "register_operand" "")
5145
                 (match_operand:HI 1 "incdec_operand" "")))
5146
   (set (pc)
5147
        (if_then_else (match_operator 3 "eqne_operator"
5148
                        [(cc0) (const_int 0)])
5149
                      (label_ref (match_operand 2 "" ""))
5150
                      (pc)))]
5151
  "(TARGET_H8300H || TARGET_H8300S)
5152
   && INTVAL (operands[1]) != 0
5153
   && peep2_reg_dead_p (1, operands[0])"
5154
  [(set (match_dup 0)
5155
        (unspec:HI [(match_dup 0)
5156
                    (match_dup 4)]
5157
                   UNSPEC_INCDEC))
5158
   (set (cc0) (compare (match_dup 0)
5159
                       (const_int 0)))
5160
   (set (pc)
5161
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5162
                      (label_ref (match_dup 2))
5163
                      (pc)))]
5164
  "operands[4] = GEN_INT (- INTVAL (operands[1]));")
5165
 
5166
;; Transform
5167
;;
5168
;;      cmp.w   #1,r0
5169
;;      bgt     .L1
5170
;;
5171
;; into
5172
;;
5173
;;      shar.w  r0
5174
;;      bgt     .L1
5175
 
5176
(define_peephole2
5177
  [(set (cc0)
5178
        (compare (match_operand:HI 0 "register_operand" "")
5179
                 (match_operand:HI 1 "const_int_operand" "")))
5180
   (set (pc)
5181
        (if_then_else (match_operator 2 "gtle_operator"
5182
                        [(cc0) (const_int 0)])
5183
                      (label_ref (match_operand 3 "" ""))
5184
                      (pc)))]
5185
  "(TARGET_H8300H || TARGET_H8300S)
5186
   && peep2_reg_dead_p (1, operands[0])
5187
   && (INTVAL (operands[1]) == 1
5188
        || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5189
  [(parallel [(set (match_dup 0)
5190
                   (ashiftrt:HI (match_dup 0)
5191
                                (match_dup 4)))
5192
              (clobber (scratch:QI))])
5193
   (set (cc0) (compare (match_dup 0)
5194
                       (const_int 0)))
5195
   (set (pc)
5196
        (if_then_else (match_dup 2)
5197
                      (label_ref (match_dup 3))
5198
                      (pc)))]
5199
  "operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
5200
 
5201
;; Transform
5202
;;
5203
;;      cmp.w   #1,r0
5204
;;      bhi     .L1
5205
;;
5206
;; into
5207
;;
5208
;;      shar.w  r0
5209
;;      bne     .L1
5210
 
5211
(define_peephole2
5212
  [(set (cc0)
5213
        (compare (match_operand:HI 0 "register_operand" "")
5214
                 (match_operand:HI 1 "const_int_operand" "")))
5215
   (set (pc)
5216
        (if_then_else (match_operator 2 "gtuleu_operator"
5217
                        [(cc0) (const_int 0)])
5218
                      (label_ref (match_operand 3 "" ""))
5219
                      (pc)))]
5220
  "(TARGET_H8300H || TARGET_H8300S)
5221
   && peep2_reg_dead_p (1, operands[0])
5222
   && (INTVAL (operands[1]) == 1
5223
        || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5224
  [(parallel [(set (match_dup 0)
5225
                   (ashiftrt:HI (match_dup 0)
5226
                                (match_dup 4)))
5227
              (clobber (scratch:QI))])
5228
   (set (cc0) (compare (match_dup 0)
5229
                       (const_int 0)))
5230
   (set (pc)
5231
        (if_then_else (match_dup 5)
5232
                      (label_ref (match_dup 3))
5233
                      (pc)))]
5234
{
5235
  operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5236
  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5237
                                VOIDmode,
5238
                                cc0_rtx,
5239
                                const0_rtx);
5240
})
5241
 
5242
;; Transform
5243
;;
5244
;;      cmp.w   #255,r0
5245
;;      bgt     .L1
5246
;;
5247
;; into
5248
;;
5249
;;      mov.b   r0h,r0h
5250
;;      bgt     .L1
5251
 
5252
(define_peephole2
5253
  [(set (cc0)
5254
        (compare (match_operand:HI 0 "register_operand" "")
5255
                 (const_int 255)))
5256
   (set (pc)
5257
        (if_then_else (match_operator 1 "gtle_operator"
5258
                        [(cc0) (const_int 0)])
5259
                      (label_ref (match_operand 2 "" ""))
5260
                      (pc)))]
5261
  "TARGET_H8300H || TARGET_H8300S"
5262
  [(set (cc0) (compare (and:HI (match_dup 0)
5263
                               (const_int -256))
5264
                       (const_int 0)))
5265
   (set (pc)
5266
        (if_then_else (match_dup 1)
5267
                      (label_ref (match_dup 2))
5268
                      (pc)))]
5269
  "")
5270
 
5271
;; Transform
5272
;;
5273
;;      cmp.w   #255,r0
5274
;;      bhi     .L1
5275
;;
5276
;; into
5277
;;
5278
;;      mov.b   r0h,r0h
5279
;;      bne     .L1
5280
 
5281
(define_peephole2
5282
  [(set (cc0)
5283
        (compare (match_operand:HI 0 "register_operand" "")
5284
                 (const_int 255)))
5285
   (set (pc)
5286
        (if_then_else (match_operator 1 "gtuleu_operator"
5287
                        [(cc0) (const_int 0)])
5288
                      (label_ref (match_operand 2 "" ""))
5289
                      (pc)))]
5290
  "TARGET_H8300H || TARGET_H8300S"
5291
  [(set (cc0) (compare (and:HI (match_dup 0)
5292
                               (const_int -256))
5293
                       (const_int 0)))
5294
   (set (pc)
5295
        (if_then_else (match_dup 3)
5296
                      (label_ref (match_dup 2))
5297
                      (pc)))]
5298
{
5299
  operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
5300
                                VOIDmode,
5301
                                cc0_rtx,
5302
                                const0_rtx);
5303
})
5304
 
5305
;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve
5306
;; the equivalent with shorter sequences.  Here is the summary.  Cases
5307
;; are grouped for each define_peephole2.
5308
;;
5309
;; reg  const_int                   use     insn
5310
;; --------------------------------------------------------
5311
;; live    -2                       eq/ne   copy and inc.l
5312
;; live    -1                       eq/ne   copy and inc.l
5313
;; live     1                       eq/ne   copy and dec.l
5314
;; live     2                       eq/ne   copy and dec.l
5315
;;
5316
;; dead    -2                       eq/ne   inc.l
5317
;; dead    -1                       eq/ne   inc.l
5318
;; dead     1                       eq/ne   dec.l
5319
;; dead     2                       eq/ne   dec.l
5320
;;
5321
;; dead -131072                     eq/ne   inc.w and test
5322
;; dead  -65536                     eq/ne   inc.w and test
5323
;; dead   65536                     eq/ne   dec.w and test
5324
;; dead  131072                     eq/ne   dec.w and test
5325
;;
5326
;; dead 0x000000?? except 1 and 2   eq/ne   xor.b and test
5327
;; dead 0x0000??00                  eq/ne   xor.b and test
5328
;; dead 0x0000ffff                  eq/ne   not.w and test
5329
;;
5330
;; dead 0xffffff?? except -1 and -2 eq/ne   xor.b and not.l
5331
;; dead 0xffff??ff                  eq/ne   xor.b and not.l
5332
;; dead 0x40000000 (H8S)            eq/ne   rotl.l and dec.l
5333
;; dead 0x80000000                  eq/ne   rotl.l and dec.l
5334
;;
5335
;; live     1                       ge/lt copy and shar.l
5336
;; live     3 (H8S)                 ge/lt copy and shar.l
5337
;;
5338
;; live     1                       geu/ltu copy and shar.l
5339
;; live     3 (H8S)                 geu/ltu copy and shar.l
5340
;;
5341
;; dead     1                       ge/lt shar.l
5342
;; dead     3 (H8S)                 ge/lt shar.l
5343
;;
5344
;; dead     1                       geu/ltu shar.l
5345
;; dead     3 (H8S)                 geu/ltu shar.l
5346
;;
5347
;; dead     3 (H8/300H)             ge/lt and.b and test
5348
;; dead     7                       ge/lt and.b and test
5349
;; dead    15                       ge/lt and.b and test
5350
;; dead    31                       ge/lt and.b and test
5351
;; dead    63                       ge/lt and.b and test
5352
;; dead   127                       ge/lt and.b and test
5353
;; dead   255                       ge/lt and.b and test
5354
;;
5355
;; dead     3 (H8/300H)             geu/ltu and.b and test
5356
;; dead     7                       geu/ltu and.b and test
5357
;; dead    15                       geu/ltu and.b and test
5358
;; dead    31                       geu/ltu and.b and test
5359
;; dead    63                       geu/ltu and.b and test
5360
;; dead   127                       geu/ltu and.b and test
5361
;; dead   255                       geu/ltu and.b and test
5362
;;
5363
;; ---- 65535                       ge/lt mov.w
5364
;;
5365
;; ---- 65535                       geu/ltu mov.w
5366
 
5367
;; Transform
5368
;;
5369
;;      cmp.l   #1,er0
5370
;;      beq     .L1
5371
;;
5372
;; into
5373
;;
5374
;;      dec.l   #1,er0
5375
;;      beq     .L1
5376
 
5377
(define_peephole2
5378
  [(set (cc0)
5379
        (compare (match_operand:SI 0 "register_operand" "")
5380
                 (match_operand:SI 1 "incdec_operand" "")))
5381
   (set (pc)
5382
        (if_then_else (match_operator 3 "eqne_operator"
5383
                        [(cc0) (const_int 0)])
5384
                      (label_ref (match_operand 2 "" ""))
5385
                      (pc)))]
5386
  "(TARGET_H8300H || TARGET_H8300S)
5387
   && INTVAL (operands[1]) != 0
5388
   && peep2_reg_dead_p (1, operands[0])"
5389
  [(set (match_dup 0)
5390
        (unspec:SI [(match_dup 0)
5391
                    (match_dup 4)]
5392
                   UNSPEC_INCDEC))
5393
   (set (cc0) (compare (match_dup 0)
5394
                       (const_int 0)))
5395
   (set (pc)
5396
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5397
                      (label_ref (match_dup 2))
5398
                      (pc)))]
5399
  "operands[4] = GEN_INT (- INTVAL (operands[1]));")
5400
 
5401
;; Transform
5402
;;
5403
;;      cmp.l   #65536,er0
5404
;;      beq     .L1
5405
;;
5406
;; into
5407
;;
5408
;;      dec.l   #1,e0
5409
;;      beq     .L1
5410
 
5411
(define_peephole2
5412
  [(set (cc0)
5413
        (compare (match_operand:SI 0 "register_operand" "")
5414
                 (match_operand:SI 1 "const_int_operand" "")))
5415
   (set (pc)
5416
        (if_then_else (match_operator 3 "eqne_operator"
5417
                        [(cc0) (const_int 0)])
5418
                      (label_ref (match_operand 2 "" ""))
5419
                      (pc)))]
5420
  "(TARGET_H8300H || TARGET_H8300S)
5421
   && peep2_reg_dead_p (1, operands[0])
5422
   && (INTVAL (operands[1]) == -131072
5423
       || INTVAL (operands[1]) == -65536
5424
       || INTVAL (operands[1]) == 65536
5425
       || INTVAL (operands[1]) == 131072)"
5426
  [(set (match_dup 0)
5427
        (plus:SI (match_dup 0)
5428
                 (match_dup 4)))
5429
   (set (cc0) (compare (match_dup 0)
5430
                       (const_int 0)))
5431
   (set (pc)
5432
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5433
                      (label_ref (match_dup 2))
5434
                      (pc)))]
5435
  "operands[4] = GEN_INT (- INTVAL (operands[1]));")
5436
 
5437
;; Transform
5438
;;
5439
;;      cmp.l   #100,er0
5440
;;      beq     .L1
5441
;;
5442
;; into
5443
;;
5444
;;      xor.b   #100,er0
5445
;;      mov.l   er0,er0
5446
;;      beq     .L1
5447
 
5448
(define_peephole2
5449
  [(set (cc0)
5450
        (compare (match_operand:SI 0 "register_operand" "")
5451
                 (match_operand:SI 1 "const_int_operand" "")))
5452
   (set (pc)
5453
        (if_then_else (match_operator 3 "eqne_operator"
5454
                        [(cc0) (const_int 0)])
5455
                      (label_ref (match_operand 2 "" ""))
5456
                      (pc)))]
5457
  "(TARGET_H8300H || TARGET_H8300S)
5458
   && peep2_reg_dead_p (1, operands[0])
5459
   && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
5460
       || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
5461
       || INTVAL (operands[1]) == 0x0000ffff)
5462
   && INTVAL (operands[1]) != 0
5463
   && INTVAL (operands[1]) != 1
5464
   && INTVAL (operands[1]) != 2"
5465
  [(set (match_dup 0)
5466
        (xor:SI (match_dup 0)
5467
                (match_dup 1)))
5468
   (set (cc0) (compare (match_dup 0)
5469
                       (const_int 0)))
5470
   (set (pc)
5471
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5472
                      (label_ref (match_dup 2))
5473
                      (pc)))]
5474
  "")
5475
 
5476
;; Transform
5477
;;
5478
;;      cmp.l   #-100,er0
5479
;;      beq     .L1
5480
;;
5481
;; into
5482
;;
5483
;;      xor.b   #99,er0
5484
;;      not.l   er0
5485
;;      beq     .L1
5486
 
5487
(define_peephole2
5488
  [(set (cc0)
5489
        (compare (match_operand:SI 0 "register_operand" "")
5490
                 (match_operand:SI 1 "const_int_operand" "")))
5491
   (set (pc)
5492
        (if_then_else (match_operator 3 "eqne_operator"
5493
                        [(cc0) (const_int 0)])
5494
                      (label_ref (match_operand 2 "" ""))
5495
                      (pc)))]
5496
  "(TARGET_H8300H || TARGET_H8300S)
5497
   && peep2_reg_dead_p (1, operands[0])
5498
   && ((INTVAL (operands[1]) | 0x00ff) == -1
5499
        || (INTVAL (operands[1]) | 0xff00) == -1)
5500
   && INTVAL (operands[1]) != -1
5501
   && INTVAL (operands[1]) != -2"
5502
  [(set (match_dup 0)
5503
        (xor:SI (match_dup 0)
5504
                (match_dup 4)))
5505
   (set (match_dup 0)
5506
        (not:SI (match_dup 0)))
5507
   (set (cc0) (compare (match_dup 0)
5508
                       (const_int 0)))
5509
   (set (pc)
5510
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5511
                      (label_ref (match_dup 2))
5512
                      (pc)))]
5513
  "operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);")
5514
 
5515
;; Transform
5516
;;
5517
;;      cmp.l   #-2147483648,er0
5518
;;      beq     .L1
5519
;;
5520
;; into
5521
;;
5522
;;      rotl.l  er0
5523
;;      dec.l   #1,er0
5524
;;      beq     .L1
5525
 
5526
(define_peephole2
5527
  [(set (cc0)
5528
        (compare (match_operand:SI 0 "register_operand" "")
5529
                 (match_operand:SI 1 "const_int_operand" "")))
5530
   (set (pc)
5531
        (if_then_else (match_operator 3 "eqne_operator"
5532
                        [(cc0) (const_int 0)])
5533
                      (label_ref (match_operand 2 "" ""))
5534
                      (pc)))]
5535
  "(TARGET_H8300H || TARGET_H8300S)
5536
   && peep2_reg_dead_p (1, operands[0])
5537
   && (INTVAL (operands[1]) == -2147483647 - 1
5538
       || (TARGET_H8300S && INTVAL (operands[1]) == 1073741824))"
5539
  [(set (match_dup 0)
5540
        (rotate:SI (match_dup 0)
5541
                   (match_dup 4)))
5542
   (set (match_dup 0)
5543
        (unspec:SI [(match_dup 0)
5544
                    (const_int -1)]
5545
                   UNSPEC_INCDEC))
5546
   (set (cc0) (compare (match_dup 0)
5547
                       (const_int 0)))
5548
   (set (pc)
5549
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5550
                      (label_ref (match_dup 2))
5551
                      (pc)))]
5552
  "operands[4] = GEN_INT (INTVAL (operands[1]) == -2147483647 - 1 ? 1 : 2);")
5553
 
5554
;; Transform
5555
;;
5556
;;      cmp.l   #1,er0
5557
;;      bgt     .L1
5558
;;
5559
;; into
5560
;;
5561
;;      mov.l   er0,er1
5562
;;      shar.l  er1
5563
;;      bgt     .L1
5564
 
5565
;; We avoid this transformation if we see more than one copy of the
5566
;; same compare insn immediately before this one.
5567
 
5568
(define_peephole2
5569
  [(match_scratch:SI 4 "r")
5570
   (set (cc0)
5571
        (compare (match_operand:SI 0 "register_operand" "")
5572
                 (match_operand:SI 1 "const_int_operand" "")))
5573
   (set (pc)
5574
        (if_then_else (match_operator 2 "gtle_operator"
5575
                        [(cc0) (const_int 0)])
5576
                      (label_ref (match_operand 3 "" ""))
5577
                      (pc)))]
5578
  "(TARGET_H8300H || TARGET_H8300S)
5579
   && !peep2_reg_dead_p (1, operands[0])
5580
   && (INTVAL (operands[1]) == 1
5581
        || (TARGET_H8300S && INTVAL (operands[1]) == 3))
5582
   && !same_cmp_preceding_p (insn)"
5583
  [(set (match_dup 4)
5584
        (match_dup 0))
5585
   (parallel [(set (match_dup 4)
5586
                   (ashiftrt:SI (match_dup 4)
5587
                                (match_dup 5)))
5588
              (clobber (scratch:QI))])
5589
   (set (cc0) (compare (match_dup 4)
5590
                       (const_int 0)))
5591
   (set (pc)
5592
        (if_then_else (match_dup 2)
5593
                      (label_ref (match_dup 3))
5594
                      (pc)))]
5595
  "operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
5596
 
5597
;; Transform
5598
;;
5599
;;      cmp.l   #1,er0
5600
;;      bhi     .L1
5601
;;
5602
;; into
5603
;;
5604
;;      mov.l   er0,er1
5605
;;      shar.l  er1
5606
;;      bne     .L1
5607
 
5608
;; We avoid this transformation if we see more than one copy of the
5609
;; same compare insn immediately before this one.
5610
 
5611
(define_peephole2
5612
  [(match_scratch:SI 4 "r")
5613
   (set (cc0)
5614
        (compare (match_operand:SI 0 "register_operand" "")
5615
                 (match_operand:SI 1 "const_int_operand" "")))
5616
   (set (pc)
5617
        (if_then_else (match_operator 2 "gtuleu_operator"
5618
                        [(cc0) (const_int 0)])
5619
                      (label_ref (match_operand 3 "" ""))
5620
                      (pc)))]
5621
  "(TARGET_H8300H || TARGET_H8300S)
5622
   && !peep2_reg_dead_p (1, operands[0])
5623
   && (INTVAL (operands[1]) == 1
5624
        || (TARGET_H8300S && INTVAL (operands[1]) == 3))
5625
   && !same_cmp_preceding_p (insn)"
5626
  [(set (match_dup 4)
5627
        (match_dup 0))
5628
   (parallel [(set (match_dup 4)
5629
                   (ashiftrt:SI (match_dup 4)
5630
                                (match_dup 5)))
5631
              (clobber (scratch:QI))])
5632
   (set (cc0) (compare (match_dup 4)
5633
                       (const_int 0)))
5634
   (set (pc)
5635
        (if_then_else (match_dup 6)
5636
                      (label_ref (match_dup 3))
5637
                      (pc)))]
5638
{
5639
  operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5640
  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5641
                                VOIDmode,
5642
                                cc0_rtx,
5643
                                const0_rtx);
5644
})
5645
 
5646
;; Transform
5647
;;
5648
;;      cmp.l   #1,er0
5649
;;      bgt     .L1
5650
;;
5651
;; into
5652
;;
5653
;;      shar.l  er0
5654
;;      bgt     .L1
5655
 
5656
(define_peephole2
5657
  [(set (cc0)
5658
        (compare (match_operand:SI 0 "register_operand" "")
5659
                 (match_operand:SI 1 "const_int_operand" "")))
5660
   (set (pc)
5661
        (if_then_else (match_operator 2 "gtle_operator"
5662
                        [(cc0) (const_int 0)])
5663
                      (label_ref (match_operand 3 "" ""))
5664
                      (pc)))]
5665
  "(TARGET_H8300H || TARGET_H8300S)
5666
   && peep2_reg_dead_p (1, operands[0])
5667
   && (INTVAL (operands[1]) == 1
5668
        || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5669
  [(parallel [(set (match_dup 0)
5670
                   (ashiftrt:SI (match_dup 0)
5671
                                (match_dup 4)))
5672
              (clobber (scratch:QI))])
5673
   (set (cc0) (compare (match_dup 0)
5674
                       (const_int 0)))
5675
   (set (pc)
5676
        (if_then_else (match_dup 2)
5677
                      (label_ref (match_dup 3))
5678
                      (pc)))]
5679
  "operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
5680
 
5681
;; Transform
5682
;;
5683
;;      cmp.l   #1,er0
5684
;;      bhi     .L1
5685
;;
5686
;; into
5687
;;
5688
;;      shar.l  er0
5689
;;      bne     .L1
5690
 
5691
(define_peephole2
5692
  [(set (cc0)
5693
        (compare (match_operand:SI 0 "register_operand" "")
5694
                 (match_operand:SI 1 "const_int_operand" "")))
5695
   (set (pc)
5696
        (if_then_else (match_operator 2 "gtuleu_operator"
5697
                        [(cc0) (const_int 0)])
5698
                      (label_ref (match_operand 3 "" ""))
5699
                      (pc)))]
5700
  "(TARGET_H8300H || TARGET_H8300S)
5701
   && peep2_reg_dead_p (1, operands[0])
5702
   && (INTVAL (operands[1]) == 1
5703
        || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
5704
  [(parallel [(set (match_dup 0)
5705
                   (ashiftrt:SI (match_dup 0)
5706
                                (match_dup 4)))
5707
              (clobber (scratch:QI))])
5708
   (set (cc0) (compare (match_dup 0)
5709
                       (const_int 0)))
5710
   (set (pc)
5711
        (if_then_else (match_dup 5)
5712
                      (label_ref (match_dup 3))
5713
                      (pc)))]
5714
{
5715
  operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
5716
  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5717
                                VOIDmode,
5718
                                cc0_rtx,
5719
                                const0_rtx);
5720
})
5721
 
5722
;; Transform
5723
;;
5724
;;      cmp.l   #15,er0
5725
;;      bgt     .L1
5726
;;
5727
;; into
5728
;;
5729
;;      and     #240,r0l
5730
;;      mov.l   er0,er0
5731
;;      bgt     .L1
5732
 
5733
(define_peephole2
5734
  [(set (cc0)
5735
        (compare (match_operand:SI 0 "register_operand" "")
5736
                 (match_operand:SI 1 "const_int_operand" "")))
5737
   (set (pc)
5738
        (if_then_else (match_operator 2 "gtle_operator"
5739
                        [(cc0) (const_int 0)])
5740
                      (label_ref (match_operand 3 "" ""))
5741
                      (pc)))]
5742
  "(TARGET_H8300H || TARGET_H8300S)
5743
   && peep2_reg_dead_p (1, operands[0])
5744
   && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
5745
       || INTVAL (operands[1]) == 7
5746
       || INTVAL (operands[1]) == 15
5747
       || INTVAL (operands[1]) == 31
5748
       || INTVAL (operands[1]) == 63
5749
       || INTVAL (operands[1]) == 127
5750
       || INTVAL (operands[1]) == 255)"
5751
  [(set (match_dup 0)
5752
        (and:SI (match_dup 0)
5753
                (match_dup 4)))
5754
   (set (cc0) (compare (match_dup 0)
5755
                       (const_int 0)))
5756
   (set (pc)
5757
        (if_then_else (match_dup 2)
5758
                      (label_ref (match_dup 3))
5759
                      (pc)))]
5760
  "operands[4] = GEN_INT (~INTVAL (operands[1]));")
5761
 
5762
;; Transform
5763
;;
5764
;;      cmp.l   #15,er0
5765
;;      bhi     .L1
5766
;;
5767
;; into
5768
;;
5769
;;      and     #240,r0l
5770
;;      mov.l   er0,er0
5771
;;      bne     .L1
5772
 
5773
(define_peephole2
5774
  [(set (cc0)
5775
        (compare (match_operand:SI 0 "register_operand" "")
5776
                 (match_operand:SI 1 "const_int_operand" "")))
5777
   (set (pc)
5778
        (if_then_else (match_operator 2 "gtuleu_operator"
5779
                        [(cc0) (const_int 0)])
5780
                      (label_ref (match_operand 3 "" ""))
5781
                      (pc)))]
5782
  "(TARGET_H8300H || TARGET_H8300S)
5783
   && peep2_reg_dead_p (1, operands[0])
5784
   && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
5785
       || INTVAL (operands[1]) == 7
5786
       || INTVAL (operands[1]) == 15
5787
       || INTVAL (operands[1]) == 31
5788
       || INTVAL (operands[1]) == 63
5789
       || INTVAL (operands[1]) == 127
5790
       || INTVAL (operands[1]) == 255)"
5791
  [(set (match_dup 0)
5792
        (and:SI (match_dup 0)
5793
                (match_dup 4)))
5794
   (set (cc0) (compare (match_dup 0)
5795
                       (const_int 0)))
5796
   (set (pc)
5797
        (if_then_else (match_dup 5)
5798
                      (label_ref (match_dup 3))
5799
                      (pc)))]
5800
{
5801
  operands[4] = GEN_INT (~INTVAL (operands[1]));
5802
  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
5803
                                VOIDmode,
5804
                                cc0_rtx,
5805
                                const0_rtx);
5806
})
5807
 
5808
;; Transform
5809
;;
5810
;;      cmp.l   #65535,er0
5811
;;      bgt     .L1
5812
;;
5813
;; into
5814
;;
5815
;;      mov.l   e0,e0
5816
;;      bgt     .L1
5817
 
5818
(define_peephole2
5819
  [(set (cc0)
5820
        (compare (match_operand:SI 0 "register_operand" "")
5821
                 (const_int 65535)))
5822
   (set (pc)
5823
        (if_then_else (match_operator 1 "gtle_operator"
5824
                        [(cc0) (const_int 0)])
5825
                      (label_ref (match_operand 2 "" ""))
5826
                      (pc)))]
5827
  "TARGET_H8300H || TARGET_H8300S"
5828
  [(set (cc0) (compare (and:SI (match_dup 0)
5829
                               (const_int -65536))
5830
                       (const_int 0)))
5831
   (set (pc)
5832
        (if_then_else (match_dup 1)
5833
                      (label_ref (match_dup 2))
5834
                      (pc)))]
5835
  "")
5836
 
5837
;; Transform
5838
;;
5839
;;      cmp.l   #65535,er0
5840
;;      bhi     .L1
5841
;;
5842
;; into
5843
;;
5844
;;      mov.l   e0,e0
5845
;;      bne     .L1
5846
 
5847
(define_peephole2
5848
  [(set (cc0)
5849
        (compare (match_operand:SI 0 "register_operand" "")
5850
                 (const_int 65535)))
5851
   (set (pc)
5852
        (if_then_else (match_operator 1 "gtuleu_operator"
5853
                        [(cc0) (const_int 0)])
5854
                      (label_ref (match_operand 2 "" ""))
5855
                      (pc)))]
5856
  "TARGET_H8300H || TARGET_H8300S"
5857
  [(set (cc0) (compare (and:SI (match_dup 0)
5858
                               (const_int -65536))
5859
                       (const_int 0)))
5860
   (set (pc)
5861
        (if_then_else (match_dup 3)
5862
                      (label_ref (match_dup 2))
5863
                      (pc)))]
5864
{
5865
  operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
5866
                                VOIDmode,
5867
                                cc0_rtx,
5868
                                const0_rtx);
5869
})
5870
 
5871
;; Transform
5872
;;
5873
;;      cmp.l   #1,er0
5874
;;      beq     .L1
5875
;;
5876
;; into
5877
;;
5878
;;      mov.l   er0,er1
5879
;;      dec.l   #1,er1
5880
;;      beq     .L1
5881
 
5882
;; We avoid this transformation if we see more than one copy of the
5883
;; same compare insn.
5884
 
5885
(define_peephole2
5886
  [(match_scratch:SI 4 "r")
5887
   (set (cc0)
5888
        (compare (match_operand:SI 0 "register_operand" "")
5889
                 (match_operand:SI 1 "incdec_operand" "")))
5890
   (set (pc)
5891
        (if_then_else (match_operator 3 "eqne_operator"
5892
                        [(cc0) (const_int 0)])
5893
                      (label_ref (match_operand 2 "" ""))
5894
                      (pc)))]
5895
  "(TARGET_H8300H || TARGET_H8300S)
5896
   && INTVAL (operands[1]) != 0
5897
   && !peep2_reg_dead_p (1, operands[0])
5898
   && !same_cmp_following_p (insn)"
5899
  [(set (match_dup 4)
5900
        (match_dup 0))
5901
   (set (match_dup 4)
5902
        (unspec:SI [(match_dup 4)
5903
                    (match_dup 5)]
5904
                   UNSPEC_INCDEC))
5905
   (set (cc0) (compare (match_dup 4)
5906
                       (const_int 0)))
5907
   (set (pc)
5908
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5909
                      (label_ref (match_dup 2))
5910
                      (pc)))]
5911
  "operands[5] = GEN_INT (- INTVAL (operands[1]));")
5912
 
5913
;; Narrow the mode of testing if possible.
5914
 
5915
(define_peephole2
5916
  [(set (match_operand:HI 0 "register_operand" "")
5917
        (and:HI (match_dup 0)
5918
                (match_operand:HI 1 "const_int_qi_operand" "")))
5919
   (set (cc0) (compare (match_dup 0)
5920
                       (const_int 0)))
5921
   (set (pc)
5922
        (if_then_else (match_operator 3 "eqne_operator"
5923
                        [(cc0) (const_int 0)])
5924
                      (label_ref (match_operand 2 "" ""))
5925
                      (pc)))]
5926
  "peep2_reg_dead_p (2, operands[0])"
5927
  [(set (match_dup 4)
5928
        (and:QI (match_dup 4)
5929
                (match_dup 5)))
5930
   (set (cc0) (compare (match_dup 4)
5931
                       (const_int 0)))
5932
   (set (pc)
5933
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5934
                      (label_ref (match_dup 2))
5935
                      (pc)))]
5936
  "operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
5937
   operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);")
5938
 
5939
(define_peephole2
5940
  [(set (match_operand:SI 0 "register_operand" "")
5941
        (and:SI (match_dup 0)
5942
                (match_operand:SI 1 "const_int_qi_operand" "")))
5943
   (set (cc0) (compare (match_dup 0)
5944
                       (const_int 0)))
5945
   (set (pc)
5946
        (if_then_else (match_operator 3 "eqne_operator"
5947
                        [(cc0) (const_int 0)])
5948
                      (label_ref (match_operand 2 "" ""))
5949
                      (pc)))]
5950
  "peep2_reg_dead_p (2, operands[0])"
5951
  [(set (match_dup 4)
5952
        (and:QI (match_dup 4)
5953
                (match_dup 5)))
5954
   (set (cc0) (compare (match_dup 4)
5955
                       (const_int 0)))
5956
   (set (pc)
5957
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5958
                      (label_ref (match_dup 2))
5959
                      (pc)))]
5960
  "operands[4] = gen_rtx_REG (QImode, REGNO (operands[0]));
5961
   operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);")
5962
 
5963
(define_peephole2
5964
  [(set (match_operand:SI 0 "register_operand" "")
5965
        (and:SI (match_dup 0)
5966
                (match_operand:SI 1 "const_int_hi_operand" "")))
5967
   (set (cc0) (compare (match_dup 0)
5968
                       (const_int 0)))
5969
   (set (pc)
5970
        (if_then_else (match_operator 3 "eqne_operator"
5971
                        [(cc0) (const_int 0)])
5972
                      (label_ref (match_operand 2 "" ""))
5973
                      (pc)))]
5974
  "peep2_reg_dead_p (2, operands[0])"
5975
  [(set (match_dup 4)
5976
        (and:HI (match_dup 4)
5977
                (match_dup 5)))
5978
   (set (cc0) (compare (match_dup 4)
5979
                       (const_int 0)))
5980
   (set (pc)
5981
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
5982
                      (label_ref (match_dup 2))
5983
                      (pc)))]
5984
  "operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
5985
   operands[5] = gen_int_mode (INTVAL (operands[1]), HImode);")
5986
 
5987
(define_peephole2
5988
  [(set (match_operand:SI 0 "register_operand" "")
5989
        (and:SI (match_dup 0)
5990
                (match_operand:SI 1 "const_int_qi_operand" "")))
5991
   (set (match_dup 0)
5992
        (xor:SI (match_dup 0)
5993
                (match_operand:SI 2 "const_int_qi_operand" "")))
5994
   (set (cc0) (compare (match_dup 0)
5995
                       (const_int 0)))
5996
   (set (pc)
5997
        (if_then_else (match_operator 4 "eqne_operator"
5998
                        [(cc0) (const_int 0)])
5999
                      (label_ref (match_operand 3 "" ""))
6000
                      (pc)))]
6001
  "peep2_reg_dead_p (3, operands[0])
6002
   && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0"
6003
  [(set (match_dup 5)
6004
        (and:QI (match_dup 5)
6005
                (match_dup 6)))
6006
   (set (match_dup 5)
6007
        (xor:QI (match_dup 5)
6008
                (match_dup 7)))
6009
   (set (cc0) (compare (match_dup 5)
6010
                       (const_int 0)))
6011
   (set (pc)
6012
        (if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
6013
                      (label_ref (match_dup 3))
6014
                      (pc)))]
6015
  "operands[5] = gen_rtx_REG (QImode, REGNO (operands[0]));
6016
   operands[6] = gen_int_mode (INTVAL (operands[1]), QImode);
6017
   operands[7] = gen_int_mode (INTVAL (operands[2]), QImode);")
6018
 
6019
;; These triggers right at the end of allocation of locals in the
6020
;; prologue (and possibly at other places).
6021
 
6022
;; stack adjustment of -4, generate one push
6023
;;
6024
;; before : 6 bytes, 10 clocks
6025
;; after  : 4 bytes, 10 clocks
6026
 
6027
(define_peephole2
6028
  [(set (reg:SI SP_REG)
6029
        (plus:SI (reg:SI SP_REG)
6030
                 (const_int -4)))
6031
   (set (mem:SI (reg:SI SP_REG))
6032
        (match_operand:SI 0 "register_operand" ""))]
6033
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
6034
   && REGNO (operands[0]) != SP_REG"
6035
  [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6036
        (match_dup 0))]
6037
  "")
6038
 
6039
;; stack adjustment of -12, generate one push
6040
;;
6041
;; before : 10 bytes, 14 clocks
6042
;; after  :  8 bytes, 14 clocks
6043
 
6044
(define_peephole2
6045
  [(set (reg:SI SP_REG)
6046
        (plus:SI (reg:SI SP_REG)
6047
                 (const_int -12)))
6048
   (set (mem:SI (reg:SI SP_REG))
6049
        (match_operand:SI 0 "register_operand" ""))]
6050
  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE
6051
   && REGNO (operands[0]) != SP_REG"
6052
  [(set (reg:SI SP_REG)
6053
        (plus:SI (reg:SI SP_REG)
6054
                 (const_int -4)))
6055
   (set (reg:SI SP_REG)
6056
        (plus:SI (reg:SI SP_REG)
6057
                 (const_int -4)))
6058
   (set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
6059
        (match_dup 0))]
6060
  "")
6061
 
6062
;; Transform
6063
;;
6064
;;      mov     dst,reg
6065
;;      op      src,reg
6066
;;      mov     reg,dst
6067
;;
6068
;; into
6069
;;
6070
;;      op      src,dst
6071
;;
6072
;; if "reg" dies at the end of the sequence.
6073
(define_peephole2
6074
  [(set (match_operand 0 "register_operand" "")
6075
        (match_operand 1 "memory_operand" ""))
6076
   (set (match_dup 0)
6077
        (match_operator 2 "h8sx_binary_memory_operator"
6078
           [(match_dup 0)
6079
            (match_operand 3 "h8300_src_operand" "")]))
6080
   (set (match_operand 4 "memory_operand" "")
6081
        (match_dup 0))]
6082
  "0 /* Disable because it breaks compiling fp-bit.c.  */
6083
   && TARGET_H8300SX
6084
   && peep2_reg_dead_p (3, operands[0])
6085
   && !reg_overlap_mentioned_p (operands[0], operands[3])
6086
   && !reg_overlap_mentioned_p (operands[0], operands[4])
6087
   && h8sx_mergeable_memrefs_p (operands[4], operands[1])"
6088
  [(set (match_dup 4)
6089
        (match_dup 5))]
6090
  {
6091
    operands[5] = shallow_copy_rtx (operands[2]);
6092
    XEXP (operands[5], 0) = operands[1];
6093
  })
6094
 
6095
;; Transform
6096
;;
6097
;;      mov     src,reg
6098
;;      op      reg,dst
6099
;;
6100
;; into
6101
;;
6102
;;      op      src,dst
6103
;;
6104
;; if "reg" dies in the second insn.
6105
(define_peephole2
6106
  [(set (match_operand 0 "register_operand" "")
6107
        (match_operand 1 "h8300_src_operand" ""))
6108
   (set (match_operand 2 "h8300_dst_operand" "")
6109
        (match_operator 3 "h8sx_binary_memory_operator"
6110
           [(match_operand 4 "h8300_dst_operand" "")
6111
            (match_dup 0)]))]
6112
  "0 /* Disable because it breaks compiling fp-bit.c.  */
6113
   && TARGET_H8300SX
6114
   && peep2_reg_dead_p (2, operands[0])
6115
   && !reg_overlap_mentioned_p (operands[0], operands[4])"
6116
  [(set (match_dup 2)
6117
        (match_dup 5))]
6118
  {
6119
    operands[5] = shallow_copy_rtx (operands[3]);
6120
    XEXP (operands[5], 1) = operands[1];
6121
  })
6122
 
6123
;; Transform
6124
;;
6125
;;      mov     dst,reg
6126
;;      op      reg
6127
;;      mov     reg,dst
6128
;;
6129
;; into
6130
;;
6131
;;      op      dst
6132
;;
6133
;; if "reg" dies at the end of the sequence.
6134
(define_peephole2
6135
  [(set (match_operand 0 "register_operand" "")
6136
        (match_operand 1 "memory_operand" ""))
6137
   (set (match_dup 0)
6138
        (match_operator 2 "h8sx_unary_memory_operator"
6139
           [(match_dup 0)]))
6140
   (set (match_operand 3 "memory_operand" "")
6141
        (match_dup 0))]
6142
  "TARGET_H8300SX
6143
   && peep2_reg_dead_p (3, operands[0])
6144
   && !reg_overlap_mentioned_p (operands[0], operands[3])
6145
   && h8sx_mergeable_memrefs_p (operands[3], operands[1])"
6146
  [(set (match_dup 3)
6147
        (match_dup 4))]
6148
  {
6149
    operands[4] = shallow_copy_rtx (operands[2]);
6150
    XEXP (operands[4], 0) = operands[1];
6151
  })
6152
 
6153
;; Transform
6154
;;
6155
;;      mov     src1,reg
6156
;;      cmp     reg,src2
6157
;;
6158
;; into
6159
;;
6160
;;      cmp     src1,src2
6161
;;
6162
;; if "reg" dies in the comparison.
6163
(define_peephole2
6164
  [(set (match_operand 0 "register_operand" "")
6165
        (match_operand 1 "h8300_dst_operand" ""))
6166
   (set (cc0)
6167
        (compare (match_dup 0)
6168
                 (match_operand 2 "h8300_src_operand" "")))]
6169
  "TARGET_H8300SX
6170
   && peep2_reg_dead_p (2, operands[0])
6171
   && !reg_overlap_mentioned_p (operands[0], operands[2])
6172
   && operands[2] != const0_rtx"
6173
  [(set (cc0)
6174
        (compare (match_dup 1)
6175
                 (match_dup 2)))])
6176
 
6177
;; Likewise for the second operand.
6178
(define_peephole2
6179
  [(set (match_operand 0 "register_operand" "")
6180
        (match_operand 1 "h8300_src_operand" ""))
6181
   (set (cc0)
6182
        (compare (match_operand 2 "h8300_dst_operand" "")
6183
                 (match_dup 0)))]
6184
  "TARGET_H8300SX
6185
   && peep2_reg_dead_p (2, operands[0])
6186
   && !reg_overlap_mentioned_p (operands[0], operands[2])"
6187
  [(set (cc0)
6188
        (compare (match_dup 2)
6189
                 (match_dup 1)))])
6190
 
6191
;; Combine two moves.
6192
(define_peephole2
6193
  [(set (match_operand 0 "register_operand" "")
6194
        (match_operand 1 "h8300_src_operand" ""))
6195
   (set (match_operand 2 "h8300_dst_operand" "")
6196
        (match_dup 0))]
6197
  "TARGET_H8300SX
6198
   && peep2_reg_dead_p (2, operands[0])
6199
   && !reg_overlap_mentioned_p (operands[0], operands[2])"
6200
  [(set (match_dup 2)
6201
        (match_dup 1))])

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.