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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [h8300/] [h8300.md] - Blame information for rev 298

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

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

powered by: WebSVN 2.1.0

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