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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [h8300/] [h8300.md] - Blame information for rev 832

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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