OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc2/] [gcc/] [config/] [picochip/] [picochip.md] - Blame information for rev 384

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
;; GCC machine description for picochip
2
;; Copyright (C) 2008, 2009 Free Software Foundation, Inc.
3
;; Contributed by picoChip Designs Ltd (http://www.picochip.com)
4
;; Maintained by Daniel Towner (dant@picochip.com) and Hariharan
5
;; Sandanagobalane (hariharan@picochip.com)
6
;;
7
;; This file is part of GCC.
8
;;
9
;; GCC is free software; you can redistribute it and/or modify
10
;; it under the terms of the GNU General Public License as published by
11
;; the Free Software Foundation; either version 3, or (at your option)
12
;; any later version.
13
;;
14
;; GCC is distributed in the hope that it will be useful,
15
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
;; GNU General Public License for more details.
18
;;
19
;; You should have received a copy of the GNU General Public License
20
;; along with GCC; see the file COPYING3.  If not, see
21
;; .
22
 
23
;; -------------------------------------------------------------------------
24
 
25
;; In addition to the normal output operand formats, the following
26
;; letter formats are also available:
27
;;
28
;;  The following can be used for constants, or the constant part of a
29
;;  memory offset.
30
;;   Q - Output constant unaltered (byte mode).
31
;;   M - Alias for Q, which only works with memory operands.
32
;;   H - Divide constant by 2 (i.e., HImode is 2 bytes)
33
;;   S - Divide constant by 4 (i.e., SImode is 4 bytes)
34
;;
35
;;  The following can be used for two part addresses (i.e., base +
36
;;  offset or base[offset]).
37
;;   o - Output offset only.
38
;;   b - Output base only.
39
;;
40
;;  The following are used on SI registers and constants
41
;;   R - Output register pair (i.e., R[n:m])
42
;;   L - Output lower word/register
43
;;   U - Output upper word/register
44
;;
45
;;  The following are used on DI mode registers.
46
;;   X - Output 3rd register
47
;;   Y - Output 4th register
48
;;
49
;;  Miscellaneous
50
;;   | - Output VLIW separator
51
;;   r - Output register value of memory operand.
52
;;   I - Output an opcode (e.g., ADD for plus, LSL for lshift)
53
;;   i - Output an opcode in symbolic notation (e.g., + for plus)
54
 
55
;; Define the length of an instruction.  Used to allow different types
56
;; of branches to be used for different branch offsets.  Default to 6
57
;; bytes, which is the longest possible single instruction.
58
(define_attr "length" "" (const_int 6))
59
 
60
;; Define some constants which are used in conjuction with branch
61
;; scheduling.  Branches must be 10-bit signed, which equates to
62
;; [-512,511]. However, to compensate for the lack of branch alignment
63
;; these offsets are reduced by a factor of 2.
64
 
65
(define_constants
66
  [
67
   (MIN_BRANCH_OFFSET -256)
68
   (MAX_BRANCH_OFFSET 255)
69
   (SHORT_BRANCH_LENGTH 6)    ; The size of a schedulable short branch.
70
   (LONG_BRANCH_LENGTH 16)    ; The size of an expanded JMP?? macro.
71
   ]
72
)
73
 
74
;; Define identifiers for various special instructions.  These
75
;; instructions may then be used in RTL expansions, or builtins.
76
(define_constants
77
  [
78
   ; Special instruction builtins.
79
   (UNSPEC_SBC             0) ; Sign-bit count
80
   (UNSPEC_ADDS            1) ; Saturating addition
81
   (UNSPEC_SUBS            2) ; Saturating subtraction
82
   (UNSPEC_BREV            3) ; Bit reversal
83
 
84
   ; Special internal instructions (only used by compiler)
85
   (UNSPEC_COPYSW          5) ; Get status word
86
   (UNSPEC_ADDC            6) ; Add with carry.
87
 
88
   ; Scalar port communication builtins
89
   (UNSPEC_PUT             7) ; Communication (put):       port[op0] := op1
90
   (UNSPEC_GET             8) ; Communication (get):       op0 := get_port[op1]
91
   (UNSPEC_TESTPORT        9) ; Communication (test):      op0 := testport[op1]
92
 
93
   ; Array port communication builtins.  These all take extra
94
   ; arguments giving information about the array access being used.
95
   (UNSPEC_PUT_ARRAY      10) ; Array put
96
   (UNSPEC_GET_ARRAY      11) ; Array get
97
   (UNSPEC_TESTPORT_ARRAY 12) ; Array test port
98
 
99
   ;; Array port expansions
100
   (UNSPEC_CALL_GET_ARRAY 13) ;
101
   (UNSPEC_CALL_PUT_ARRAY 14) ;
102
   (UNSPEC_CALL_TESTPORT_ARRAY 15) ;
103
 
104
   ; Array port low-level fn calls
105
   (UNSPEC_CALL_GET_FN  16)
106
   (UNSPEC_CALL_TESTPORT_FN  17)
107
 
108
   ; Halt instruction.
109
   (UNSPEC_HALT 18)
110
 
111
   ; Internal TSTPORT instruction, used to generate a single TSTPORT
112
   ; instruction for use in the testport branch split.
113
   (UNSPEC_INTERNAL_TESTPORT        19)
114
  ]
115
)
116
 
117
;; Register ID's
118
(define_constants
119
  [
120
   (LINK_REGNUM           12) ; Function link register.
121
   (CC_REGNUM             17) ; Condition flags.
122
   (ACC_REGNUM             16) ; Condition flags.
123
   ]
124
)
125
 
126
;;============================================================================
127
;; Predicates and constraints
128
;;============================================================================
129
 
130
(include "predicates.md")
131
(include "constraints.md")
132
 
133
;;============================================================================
134
;; First operand shifting patterns.  These allow certain instructions
135
;; (e.g., add, and, or, xor, sub) to apply a shift-by-constant to
136
;; their first operand.
137
;;
138
;; Note that only the first operand is matched by the shift, to ensure
139
;; that non-commutative instructions (like subtract) work
140
;; properly.  When a commutative instruction, with a shift in the
141
;; second operand is found, the compiler will reorder the operands to
142
;; match.
143
;;============================================================================
144
 
145
(define_insn "*firstOpGenericAshift"
146
  [(set (match_operand:HI 0 "register_operand" "=r")
147
        (match_operator:HI 1 "picochip_first_op_shift_operator"
148
                        [(ashift:HI
149
                          (match_operand:HI 2 "register_operand" "r")
150
                          (match_operand:HI 3 "picochip_J_operand" "J"))
151
                         (match_operand:HI 4 "picochip_register_or_immediate_operand" "ri")]))
152
   (clobber (reg:CC CC_REGNUM))]
153
  ""
154
  "%I1.0 [LSL %2,%3],%4,%0\t// %0 := (%2 << %3) %i1 %4"
155
  [(set_attr "type" "picoAlu")
156
   ;; A long constant must be used if the operator instruction doesn't
157
   ;; accept immediates, or if the constant is too big to fit the
158
   ;; immediate. Note that the following condition is written in the
159
   ;; way which uses the least number of predicates.
160
   (set (attr "longConstant")
161
     (cond [(ior (match_operand 4 "register_operand")
162
                 (and (match_operand 1 "picochip_first_op_shift_operator_imm")
163
                      (match_operand 1 "picochip_J_operand")))
164
              (const_string "false")]
165
              (const_string "true")))])
166
 
167
;; During combine, ashift gets converted into a multiply, necessitating the following pattern.
168
;; Note that we do a log_2(imm) to get the actual LSL operand.
169
 
170
(define_insn "*firstOpGenericAshift"
171
  [(set (match_operand:HI 0 "register_operand" "=r")
172
        (match_operator:HI 1 "picochip_first_op_shift_operator"
173
                        [(mult:HI
174
                          (match_operand:HI 2 "register_operand" "r")
175
                          (match_operand:HI 3 "power_of_2_imm_operand" "n"))
176
                         (match_operand:HI 4 "picochip_register_or_immediate_operand" "ri")]))
177
   (clobber (reg:CC CC_REGNUM))]
178
  ""
179
  "%I1.0 [LSL %2,%P3],%4,%0\t// %0 := (%2 << %3) %i1 %4"
180
  [(set_attr "type" "picoAlu")
181
   ;; A long constant must be used if the operator instruction doesn't
182
   ;; accept immediates, or if the constant is too big to fit the
183
   ;; immediate. Note that the following condition is written in the
184
   ;; way which uses the least number of predicates.
185
   (set (attr "longConstant")
186
     (cond [(ior (match_operand 4 "register_operand")
187
                 (and (match_operand 1 "picochip_first_op_shift_operator_imm")
188
                      (match_operand 1 "picochip_J_operand")))
189
              (const_string "false")]
190
              (const_string "true")))])
191
 
192
(define_insn "*firstOpGenericAshiftrt"
193
  [(set (match_operand:HI 0 "register_operand" "=r")
194
        (match_operator:HI 1 "picochip_first_op_shift_operator"
195
                        [(ashiftrt:HI
196
                          (match_operand:HI 2 "register_operand" "r")
197
                          (match_operand:HI 3 "picochip_J_operand" "J"))
198
                         (match_operand:HI 4 "picochip_register_or_immediate_operand" "ri")]))
199
   (clobber (reg:CC CC_REGNUM))]
200
  ""
201
  "%I1.0 [ASR %2,%3],%4,%0\t// %0 := (%2 >>{arith} %3) %i1 %4"
202
  [(set_attr "type" "picoAlu")
203
   ;; A long constant must be used if the operator instruction doesn't
204
   ;; accept immediates, or if the constant is too big to fit the
205
   ;; immediate. Note that the following condition is written in the
206
   ;; way which uses the least number of predicates.
207
   (set (attr "longConstant")
208
     (cond [(ior (match_operand 4 "register_operand")
209
                 (and (match_operand 1 "picochip_first_op_shift_operator_imm")
210
                      (match_operand 1 "picochip_J_operand")))
211
              (const_string "false")]
212
              (const_string "true")))])
213
 
214
(define_insn "*firstOpGenericLshiftrt"
215
  [(set (match_operand:HI 0 "register_operand" "=r")
216
        (match_operator:HI 1 "picochip_first_op_shift_operator"
217
                        [(lshiftrt:HI
218
                          (match_operand:HI 2 "register_operand" "r")
219
                          (match_operand:HI 3 "picochip_J_operand" "J"))
220
                         (match_operand:HI 4 "picochip_register_or_immediate_operand" "ri")]))
221
   (clobber (reg:CC CC_REGNUM))]
222
  ""
223
  "%I1.0 [LSR %2,%3],%4,%0\t// %0 := (%2 >> %3) %i1 %4"
224
  [(set_attr "type" "picoAlu")
225
   ;; A long constant must be used if the operator instruction doesn't
226
   ;; accept immediates, or if the constant is too big to fit the
227
   ;; immediate. Note that the following condition is written in the
228
   ;; way which uses the least number of predicates.
229
   (set (attr "longConstant")
230
     (cond [(ior (match_operand 4 "register_operand")
231
                 (and (match_operand 1 "picochip_first_op_shift_operator_imm")
232
                      (match_operand 1 "picochip_J_operand")))
233
              (const_string "false")]
234
              (const_string "true")))])
235
 
236
;;===========================================================================
237
;; Jump instructions.
238
;;===========================================================================
239
 
240
(define_insn "indirect_jump"
241
  [(set (pc) (match_operand:HI 0 "register_operand" "r"))]
242
  ""
243
  "JR (%0)\t// Indirect_jump to %0 %>"
244
  [(set_attr "type" "realBranch")
245
   (set_attr "length" "3")])
246
 
247
(define_insn "jump"
248
  [(set (pc)
249
        (label_ref (match_operand 0 "" "")))]
250
  ""
251
  "* return picochip_output_jump(insn);"
252
  [(set (attr "length")
253
        (if_then_else
254
         (and (ge (minus (match_dup 0) (pc)) (const_int MIN_BRANCH_OFFSET))
255
              (le (minus (match_dup 0) (pc)) (const_int MAX_BRANCH_OFFSET)))
256
         (const_int SHORT_BRANCH_LENGTH)
257
         (const_int LONG_BRANCH_LENGTH)))
258
   (set (attr "type")
259
        (if_then_else
260
         (eq_attr "length" "6")
261
         (const_string "realBranch")
262
         (const_string "unknown")))])
263
 
264
(define_insn "*fn_return"
265
  [(return)
266
   (use (reg:HI LINK_REGNUM))]
267
  ""
268
  "JR (R12)\t// Return to caller %>"
269
  [(set_attr "length" "2")
270
   (set_attr "type" "realBranch")
271
   (set_attr "longConstant" "false")])
272
 
273
;; Peephole either 2 LDWs or STWs into LDL/STL.
274
(define_peephole2
275
  [(set (match_operand:HI 0 "register_operand" "")
276
        (match_operand:HI 1 "memory_operand" ""))
277
   (set (match_operand:HI 2 "register_operand" "")
278
        (match_operand:HI 3 "memory_operand" ""))]
279
  "ok_to_peephole_ldw(operands[0],operands[1],operands[2],operands[3])"
280
  [(set (match_dup 4) (match_dup 5))]
281
  "{
282
     operands[4] = gen_min_reg(operands[0],operands[2]);
283
     operands[5] = gen_SImode_mem(operands[1],operands[3]);
284
   }")
285
 
286
(define_peephole2
287
  [(set (match_operand:HI 0 "memory_operand" "")
288
        (match_operand:HI 1 "register_operand" ""))
289
   (set (match_operand:HI 2 "memory_operand" "")
290
        (match_operand:HI 3 "register_operand" ""))]
291
  "ok_to_peephole_stw(operands[0],operands[1],operands[2],operands[3])"
292
  [(set (match_dup 4) (match_dup 5))]
293
  "{
294
     operands[4] = gen_SImode_mem(operands[0],operands[2]);
295
     operands[5] = gen_min_reg(operands[1],operands[3]);
296
   }")
297
 
298
 
299
;; We have instructions like add,subtract,ior,and that set condition
300
;; codes if they are executed on slot 0. If we have
301
;;    add a = b + c
302
;;    if (a!=0)
303
;;    {}
304
;; We would have RTL sequence like
305
;;    add.# rb,rc,ra   # will be replaced by slot no, after scheduling
306
;;    sub.0 ra,0,r15
307
;;    bnz
308
;; Instead, we can just do
309
;;    add.0 rb,rc,ra
310
;;    bnz
311
 
312
(define_peephole2
313
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
314
                   (plus:HI (match_operand:HI 1 "register_operand" "")
315
                            (match_operand:HI 2 "general_operand" "")))
316
              (clobber (reg:CC CC_REGNUM))])
317
   (parallel [(set (pc)
318
                   (if_then_else
319
                    (match_operator:CC 3 "picochip_peephole_comparison_operator"
320
                            [(match_dup 0) (const_int 0)])
321
                   (label_ref       (match_operand    6 "" ""))
322
                   (pc)))
323
              (clobber (reg:CC CC_REGNUM))])]
324
  ""
325
  [(parallel [(set (match_dup 0)
326
                   (plus:HI (match_dup 1) (match_dup 2)))
327
              (set (reg:CC CC_REGNUM)
328
                   (match_op_dup 3 [(const_int 0) (const_int 0)]))])
329
   (parallel [(set (pc)
330
                   (if_then_else
331
                    (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
332
                   (label_ref (match_dup 6))
333
                   (pc)))
334
              (use (match_dup 7))])]
335
  "{
336
     operands[7] = GEN_INT(0);
337
   }")
338
 
339
(define_peephole2
340
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
341
                   (plus:HI (match_operand:HI 1 "register_operand" "")
342
                     (match_operand:HI 2 "general_operand" "")))
343
              (clobber (reg:CC CC_REGNUM))])
344
   (set (reg:CC CC_REGNUM)
345
         (match_operator:CC 3 "picochip_peephole_comparison_operator"
346
                   [(match_dup 0) (const_int 0)]))
347
   (parallel [(set (pc)
348
                    (if_then_else
349
                          (match_operator 4 "comparison_operator"
350
                              [(reg:CC CC_REGNUM) (const_int 0)])
351
                     (label_ref (match_operand 5 "" ""))
352
                     (pc)))
353
               (use (match_operand:HI 6 "const_int_operand" ""))])]
354
  ""
355
  [(parallel [(set (match_dup 0)
356
                   (plus:HI (match_dup 1) (match_dup 2)))
357
              (set (reg:CC CC_REGNUM)
358
                   (match_op_dup 3 [(const_int 0) (const_int 0)]))])
359
   (parallel [(set (pc)
360
                   (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
361
                    (label_ref (match_dup 5))
362
                    (pc)))
363
              (use (match_dup 6))])]
364
  "{
365
     operands[7] = GEN_INT(0);
366
   }")
367
 
368
 
369
;; If peephole happens before the cbranch split
370
 
371
(define_peephole2
372
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
373
                    (minus:HI (match_operand:HI 1 "general_operand" "")
374
                              (match_operand:HI 2 "register_operand" "")))
375
              (clobber (reg:CC CC_REGNUM))])
376
   (parallel [(set (pc)
377
                   (if_then_else
378
                    (match_operator:CC 3 "picochip_peephole_comparison_operator"
379
                            [(match_dup 0) (const_int 0)])
380
                     (label_ref       (match_operand    6 "" ""))
381
                     (pc)))
382
              (clobber (reg:CC CC_REGNUM))])]
383
  ""
384
  [(parallel [(set (match_dup 0)
385
                   (minus:HI (match_dup 1) (match_dup 2)))
386
              (set (reg:CC CC_REGNUM)
387
                   (match_op_dup 3 [(const_int 0) (const_int 0)]))])
388
   (parallel [(set (pc)
389
                   (if_then_else
390
                       (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
391
                        (label_ref (match_dup 6))
392
                        (pc)))
393
              (use (match_dup 7))])]
394
  "{
395
     operands[7] = GEN_INT(0);
396
   }")
397
 
398
 
399
;; If peephole happens after the cbranch split
400
 
401
(define_peephole2
402
  [(parallel [(set (match_operand:HI 0 "register_operand" "")
403
                   (minus:HI (match_operand:HI 1 "general_operand" "")
404
                             (match_operand:HI 2 "register_operand" "")))
405
              (clobber (reg:CC CC_REGNUM))])
406
   (set (reg:CC CC_REGNUM)
407
         (match_operator:CC 3 "picochip_peephole_comparison_operator"
408
                 [(match_dup 0) (const_int 0)]))
409
    (parallel [(set (pc)
410
                     (if_then_else
411
                         (match_operator 4 "comparison_operator"
412
                             [(reg:CC CC_REGNUM) (const_int 0)])
413
                      (label_ref (match_operand 5 "" ""))
414
                      (pc)))
415
                (use (match_operand:HI 6 "const_int_operand" ""))])]
416
  ""
417
  [(parallel [(set (match_dup 0)
418
                   (minus:HI (match_dup 1) (match_dup 2)))
419
              (set (reg:CC CC_REGNUM)
420
                   (match_op_dup 3 [(const_int 0) (const_int 0)]))])
421
   (parallel [(set (pc)
422
                   (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
423
                                 (label_ref (match_dup 5))
424
                                 (pc)))
425
              (use (match_dup 6))])]
426
  "{
427
      operands[7] = GEN_INT(0);
428
   }")
429
 
430
;; If peephole happens before the cbranch split
431
 
432
(define_peephole2
433
   [(parallel[(set (match_operand:HI 0 "register_operand" "")
434
                   (and:HI (match_operand:HI 1 "register_operand" "")
435
                           (match_operand:HI 2 "general_operand" "")))
436
              (clobber (reg:CC CC_REGNUM))])
437
   (parallel [(set (pc)
438
                   (if_then_else
439
                    (match_operator:CC 3 "picochip_peephole_comparison_operator"
440
                            [(match_dup 0) (const_int 0)])
441
                   (label_ref       (match_operand    6 "" ""))
442
                   (pc)))
443
              (clobber (reg:CC CC_REGNUM))])]
444
  ""
445
  [(parallel [(set (match_dup 0)
446
                   (and:HI (match_dup 1) (match_dup 2)))
447
              (set (reg:CC CC_REGNUM)
448
                   (match_op_dup 3 [(const_int 0) (const_int 0)]))])
449
   (parallel [(set (pc)
450
                   (if_then_else
451
                       (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
452
                                 (label_ref (match_dup 6))
453
                                 (pc)))
454
              (use (match_dup 7))])]
455
  "{
456
     operands[7] = GEN_INT(0);
457
   }")
458
 
459
(define_peephole2
460
   [(parallel[(set (match_operand:HI 0 "register_operand" "")
461
                   (and:HI (match_operand:HI 1 "register_operand" "")
462
                           (match_operand:HI 2 "general_operand" "")))
463
              (clobber (reg:CC CC_REGNUM))])
464
   (set (reg:CC CC_REGNUM)
465
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
466
                    [(match_dup 0) (const_int 0)]))
467
  (parallel [(set (pc)
468
                  (if_then_else
469
                      (match_operator 4 "comparison_operator"
470
                         [(reg:CC CC_REGNUM) (const_int 0)])
471
                   (label_ref (match_operand 5 "" ""))
472
                   (pc)))
473
              (use (match_operand:HI 6 "const_int_operand" ""))])]
474
  ""
475
  [(parallel [(set (match_dup 0)
476
                   (and:HI (match_dup 1) (match_dup 2)))
477
              (set (reg:CC CC_REGNUM)
478
                   (match_op_dup 3 [(const_int 0) (const_int 0)]))])
479
   (parallel [(set (pc)
480
                   (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
481
                                 (label_ref (match_dup 5))
482
                                 (pc)))
483
              (use (match_dup 6))])]
484
  "{
485
      operands[7] = GEN_INT(0);
486
   }")
487
 
488
;; If peephole happens before the cbranch split
489
 
490
(define_peephole2
491
   [(parallel[(set (match_operand:HI 0 "register_operand" "")
492
                   (ior:HI (match_operand:HI 1 "register_operand" "")
493
                           (match_operand:HI 2 "general_operand" "")))
494
              (clobber (reg:CC CC_REGNUM))])
495
   (parallel [(set (pc)
496
                   (if_then_else
497
                    (match_operator:CC 3 "picochip_peephole_comparison_operator"
498
                          [(match_dup 0) (const_int 0)])
499
                   (label_ref       (match_operand    6 "" ""))
500
                   (pc)))
501
              (clobber (reg:CC CC_REGNUM))])]
502
  ""
503
  [(parallel [(set (match_dup 0)
504
                   (ior:HI (match_dup 1) (match_dup 2)))
505
              (set (reg:CC CC_REGNUM)
506
                   (match_op_dup 3 [(const_int 0) (const_int 0)]))])
507
   (parallel [(set (pc)
508
                   (if_then_else
509
                       (match_op_dup:HI 3 [(reg:CC CC_REGNUM) (const_int 0)])
510
                                 (label_ref (match_dup 6))
511
                                 (pc)))
512
              (use (match_dup 7))])]
513
  "{
514
     operands[7] = GEN_INT(0);
515
   }")
516
 
517
(define_peephole2
518
   [(parallel[(set (match_operand:HI 0 "register_operand" "")
519
                   (ior:HI (match_operand:HI 1 "register_operand" "")
520
                           (match_operand:HI 2 "general_operand" "")))
521
              (clobber (reg:CC CC_REGNUM))])
522
   (set (reg:CC CC_REGNUM)
523
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
524
              [(match_dup 0) (const_int 0)]))
525
  (parallel [(set (pc)
526
                  (if_then_else
527
                     (match_operator 4 "comparison_operator"
528
                        [(reg:CC CC_REGNUM) (const_int 0)])
529
                   (label_ref (match_operand 5 "" ""))
530
                   (pc)))
531
             (use (match_operand:HI 6 "const_int_operand" ""))])]
532
  ""
533
  [(parallel [(set (match_dup 0)
534
                   (ior:HI (match_dup 1) (match_dup 2)))
535
              (set (reg:CC CC_REGNUM)
536
                   (match_op_dup 3 [(const_int 0) (const_int 0)]))])
537
   (parallel [(set (pc)
538
                   (if_then_else (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
539
                                 (label_ref (match_dup 5))
540
                                 (pc)))
541
              (use (match_dup 6))])]
542
  "{
543
      operands[7] = GEN_INT(0);
544
   }")
545
 
546
;; Conditional branch (HI). This is split into separate compare and
547
;; branch instructions if scheduling is enabled.  The branch
548
;; instruction is supplied with the type of comparison on which the
549
;; branch should occur.
550
 
551
(define_insn_and_split "cbranchhi4"
552
  [(set (pc)
553
        (if_then_else
554
            (match_operator:CC 0 "ordered_comparison_operator"
555
                            [(match_operand:HI 1 "register_operand" "r")
556
                             (match_operand:HI 2 "picochip_comparison_operand" "ri")])
557
            (label_ref       (match_operand    3 "" ""))
558
            (pc)))
559
   (clobber (reg:CC CC_REGNUM))]
560
  ""
561
  "* return picochip_output_cbranch(operands);"
562
  "reload_completed
563
   && (picochip_schedule_type != DFA_TYPE_NONE || flag_delayed_branch)"
564
  [(set (reg:CC CC_REGNUM) (match_dup 0))
565
   (parallel [(set (pc)
566
                   (if_then_else (match_op_dup:HI 0 [(reg:CC CC_REGNUM) (const_int 0)])
567
                                 (label_ref (match_dup 3))
568
                                 (pc)))
569
              (use (match_dup 4))])]
570
  "{
571
     operands[4] = GEN_INT(GET_CODE(operands[0]));
572
   }")
573
 
574
;; The only difference between this and the next pattern is that the next pattern
575
;; might introduce subtracts whose first operand is a constant. This would have to
576
;; be a longConstant. But, we know that such a situation wouldnt arise for supported
577
;; comparison operator and hence this pattern assumes that the second constraint combo
578
;; would still generate a normal instruction.
579
 
580
(define_insn "*supported_compare"
581
  [(set (reg:CC CC_REGNUM)
582
        (match_operator:CC 0 "picochip_supported_comparison_operator"
583
                        [(match_operand:HI 1 "register_operand" "r,r,r")
584
                         (match_operand:HI 2 "picochip_comparison_operand" "r,J,i")]))]
585
  ""
586
  "* return picochip_output_compare(operands);"
587
  [; Must be picoAlu because it sets the condition flags.
588
   (set_attr "type" "picoAlu,picoAlu,picoAlu")
589
   (set_attr "longConstant" "false,false,true")
590
   (set_attr "length" "2,2,4")
591
   ])
592
 
593
(define_insn "*compare"
594
  [(set (reg:CC CC_REGNUM)
595
        (match_operator:CC 0 "comparison_operator"
596
                        [(match_operand:HI 1 "register_operand" "r,r,r")
597
                         (match_operand:HI 2 "picochip_comparison_operand" "r,M,i")]))]
598
  ""
599
  "* return picochip_output_compare(operands);"
600
  [; Must be picoAlu because it sets the condition flags.
601
   (set_attr "type" "picoAlu,picoAlu,picoAlu")
602
   (set_attr "longConstant" "false,true,true")
603
   (set_attr "length" "2,4,4")
604
   ])
605
 
606
; Match a branch instruction, created from a tstport/cbranch split.
607
; We use a "use" clause so GCC doesnt try to use this pattern generally.
608
(define_insn "*branch"
609
  [(set (pc)
610
        (if_then_else
611
            (match_operator 2 "comparison_operator"
612
                 [(reg:CC CC_REGNUM) (const_int 0)])
613
                      (label_ref (match_operand 0 "" ""))
614
                      (pc)))
615
   (use (match_operand:HI 1 "const_int_operand" ""))]
616
  ""
617
  "* return picochip_output_branch(operands, insn);"
618
  [(set (attr "length")
619
        (if_then_else
620
         (and (ge (minus (match_dup 0) (pc)) (const_int MIN_BRANCH_OFFSET))
621
              (le (minus (match_dup 0) (pc)) (const_int MAX_BRANCH_OFFSET)))
622
         (const_int SHORT_BRANCH_LENGTH)
623
         (const_int LONG_BRANCH_LENGTH)))
624
    (set (attr "type")
625
        (if_then_else
626
         (eq_attr "length" "6")
627
         (const_string "realBranch")
628
         (const_string "unknown")))])
629
 
630
;; If a movqi is used which accesses memory on a machine which doesn't
631
;; have byte addressing, synthesise the instruction using word load/store
632
;; operations. The movqi's that are required during reload phase are
633
;; handled using reload_inqi/reload_outqi.
634
 
635
(define_expand "movqi"
636
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
637
        (match_operand:QI 1 "general_operand" ""))]
638
  ""
639
{
640
 
641
     if (!reload_completed &&
642
         !TARGET_HAS_BYTE_ACCESS &&
643
         (MEM == GET_CODE(operands[0]) || MEM == GET_CODE(operands[1])))
644
     {
645
       rtx address;
646
       rtx wordAddress;
647
       rtx const1;
648
       rtx shiftVal;
649
       rtx loadedValue;
650
       rtx addressMask;
651
 
652
       warn_of_byte_access();
653
 
654
       /* Load the constant 1 into a register. */
655
       const1 = gen_reg_rtx(HImode);
656
       emit_insn(gen_rtx_SET(HImode, const1, GEN_INT(1)));
657
 
658
       /* Load the address mask with the bitwise complement of 1. */
659
       addressMask = gen_reg_rtx(HImode);
660
       emit_insn(gen_rtx_SET(HImode, addressMask, GEN_INT(-2)));
661
 
662
       /* Handle loads first, in case we are dealing with a mem := mem
663
        * instruction. */
664
       if (MEM == GET_CODE(operands[1]))
665
       {
666
         /* Loads work as follows. The entire word containing the desired byte
667
          * is loaded. The bottom bit of the address indicates which
668
          * byte is required. The desired byte is moved into the most
669
          * significant byte, and then an arithmetic shift right
670
          * invoked to achieve sign extension. The desired byte is
671
          * moved to the MSB by XOR'ing the bottom address bit by 1,
672
          * multiplying the result by 8, and then shifting left by
673
          * that amount. Note that shifts only operate on the bottom
674
          * 4-bits of the source offset, so although the XOR may
675
          * produce a value which has its upper bits set, only bit 4
676
          * (i.e., the inverted, shifted bottom address bit) actually
677
          * gets used.
678
          */
679
 
680
         /* Ensure the address is in a register. */
681
         address = gen_reg_rtx(HImode);
682
         emit_insn(gen_rtx_SET(HImode, address, XEXP(operands[1], 0)));
683
 
684
         /* Compute the word address by masking out the bottom bit. */
685
         wordAddress = gen_reg_rtx(HImode);
686
         emit_insn(gen_andhi3(wordAddress, address, addressMask));
687
 
688
         /* Compute the shift value. This is the bottom address bit,
689
          * inverted, and multiplied by 8. */
690
         shiftVal = gen_reg_rtx(HImode);
691
         emit_insn(gen_xorhi3(shiftVal, address, const1));
692
         emit_insn(gen_ashlhi3(shiftVal, shiftVal, GEN_INT(3)));
693
 
694
         /* Emit the memory load. */
695
         loadedValue = gen_reg_rtx(HImode);
696
         emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress)));
697
 
698
         /* Shift the desired byte to the most significant byte. */
699
         rtx topByteValue = gen_reg_rtx (HImode);
700
         emit_insn (gen_ashlhi3 (topByteValue, loadedValue, shiftVal));
701
 
702
         /* Sign extend the top-byte back into the bottom byte. */
703
         rtx signExtendedValue = gen_reg_rtx(HImode);
704
         emit_insn(gen_ashrhi3(signExtendedValue, topByteValue, GEN_INT(8)));
705
 
706
         /* Final extraction of QI mode register. */
707
        operands[1] = gen_rtx_SUBREG(QImode, signExtendedValue, 0);
708
 
709
       }
710
 
711
       if (MEM == GET_CODE(operands[0]) && GET_CODE(operands[1]) != MEM)
712
       {
713
         rtx zeroingByteMask;
714
         rtx temp;
715
         rtx tempQiMode;
716
         rtx tempHiMode;
717
 
718
         /* Get the address. */
719
         address = gen_reg_rtx(HImode);
720
         emit_insn(gen_rtx_SET(HImode, address, XEXP(operands[0], 0)));
721
 
722
         /* Compute the word aligned address. */
723
         wordAddress = gen_reg_rtx(HImode);
724
         emit_insn(gen_andhi3(wordAddress, address, addressMask));
725
 
726
         /* Compute the shift value. */
727
         shiftVal = gen_reg_rtx(HImode);
728
         emit_insn(gen_andhi3(shiftVal, address, const1));
729
         emit_insn(gen_ashlhi3(shiftVal, shiftVal, GEN_INT(3)));
730
 
731
         /* Emit the memory load. */
732
         loadedValue = gen_reg_rtx(HImode);
733
         emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress)));
734
 
735
         /* Zero out the destination bits by AND'ing with 0xFF00
736
          * shifted appropriately. */
737
         zeroingByteMask = gen_reg_rtx(HImode);
738
         emit_insn(gen_rtx_SET(HImode, zeroingByteMask, GEN_INT(-256)));
739
         emit_insn(gen_lshrhi3(zeroingByteMask, zeroingByteMask, shiftVal));
740
         emit_insn(gen_andhi3(loadedValue, loadedValue, zeroingByteMask));
741
 
742
         /* Grab the incoming QI register, and ensure that the top bits
743
          * are zeroed out. This is because the register may be
744
          * storing a signed value, in which case the top-bits will be
745
          * sign bits. These must be removed to ensure that the
746
          * read-modify-write (which uses an OR) doesn't pick up those
747
          * bits, instead of the original memory value which is being
748
          * modified.
749
          */
750
         /*if (register_operand(operands[1],QImode))
751
         {
752
           tempHiMode = XEXP(operands[1], 0);
753
         }
754
         else
755
         {
756
           tempHiMode = operands[1];
757
         }*/
758
         //tempHiMode = force_reg(QImode, operands[1]);
759
         tempHiMode = simplify_gen_subreg(HImode, operands[1], QImode, 0);
760
         temp = gen_reg_rtx(HImode);
761
         emit_insn(gen_rtx_SET(HImode, temp, tempHiMode));
762
         rtx lsbByteMask = gen_reg_rtx (HImode);
763
         emit_insn (gen_rtx_SET (HImode, lsbByteMask, GEN_INT (0xFF)));
764
         emit_insn (gen_andhi3 (temp, temp, lsbByteMask));
765
 
766
         /* Shift the incoming byte value by the appropriate amount,
767
          * and OR into the load value. */
768
         emit_insn(gen_ashlhi3(temp, temp, shiftVal));
769
         emit_insn(gen_iorhi3(loadedValue, loadedValue, temp));
770
 
771
         /* Rewrite the original assignment, to assign the new value
772
          * to the word address. */
773
         operands[0] = gen_rtx_MEM(HImode, wordAddress);
774
         operands[1] = loadedValue;
775
 
776
       }
777
 
778
     }
779
})
780
 
781
(define_insn "*movqi_sign_extend"
782
  [(set (match_operand:HI 0 "register_operand" "=r,r")
783
        (sign_extend:HI (match_operand:QI 1 "memory_operand" "a,m")))]
784
  "TARGET_HAS_BYTE_ACCESS"
785
  "@
786
     LDB (%a1),%0\t\t// %0 = Mem(%a1)
787
     LDB %a1,%0\t\t// %0 = Mem(%M1{byte})"
788
  [(set_attr "type" "mem,mem")
789
   (set_attr "longConstant" "true,false")
790
   (set_attr "length" "4,4")])
791
 
792
;; movqi instructions for machines with and without byte access.
793
(define_insn "*movqi_byte"
794
  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,r,a,m")
795
        (match_operand:QI 1 "general_operand" "r,a,m,I,i,r,r"))]
796
  "TARGET_HAS_BYTE_ACCESS"
797
  "@
798
     COPY.%# %1, %0\t// %0 := %1
799
     LDB (%a1),%0\t\t// %0 = Mem(%a1)
800
     LDB %a1,%0\t\t// %0 = Mem(%M1{byte})
801
     COPY.%# %1,%0\t\t// %0 := #%1 (QI) (short constant)
802
     COPY.%# %1,%0\t\t// %0 := #%1 (QI) (long constant)
803
     STB %1,(%a0)\t\t// Mem(%a0) := %1
804
     STB %1,%a0\t\t// Mem(%M0{byte}) := %1"
805
  [(set_attr "type" "basicAlu,mem,mem,basicAlu,basicAlu,mem,mem")
806
   (set_attr "longConstant" "false,true,false,false,true,true,false")
807
   (set_attr "length" "2,4,4,2,4,4,4")])
808
 
809
;; Machines which don't have byte access can copy registers, and load
810
;; constants, but can't access memory.  The define_expand for movqi
811
;; should already have rewritten memory accesses using word
812
;; operations.  The exception is qi reloads, which are handled using
813
;; the reload_? patterns.
814
(define_insn "*movqi_nobyte"
815
  [(set (match_operand:QI 0 "register_operand" "=r,r")
816
        (match_operand:QI 1 "picochip_register_or_immediate_operand" "r,i"))]
817
  "!TARGET_HAS_BYTE_ACCESS"
818
  "@
819
     COPY.%# %1,%0\t// %0 := %1
820
     COPY.%# %1,%0\t\t// %0 := #%1 (QI)")
821
 
822
(define_insn "movhi"
823
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,a,m,r,r")
824
        (match_operand:HI 1 "general_operand" "r,a,m,r,r,I,i"))]
825
  ""
826
  "@
827
    COPY.%# %1,%0\t\t// %0 := %1
828
    LDW (%a1),%0\t\t// %0 := Mem(%a1)
829
    LDW %a1,%0\t\t// %0 = Mem(%M1{byte})
830
    STW %1,(%a0)\t\t// Mem(%a0) := %1
831
    STW %1,%a0\t\t// Mem(%M0{byte}) := %1
832
    COPY.%# %1,%0\t// %0 := %1 (short constant)
833
    COPY.%# %1,%0\t// %0 := %1 (long constant)"
834
   [(set_attr "type" "basicAlu,mem,mem,mem,mem,basicAlu,basicAlu")
835
    (set_attr "longConstant" "false,true,false,true,false,false,true")
836
    (set_attr "length" "2,4,4,4,4,2,4")])
837
 
838
(define_insn "movsi"
839
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,a,m")
840
        (match_operand:SI 1 "general_operand" "r,a,m,i,r,r"))]
841
  ""
842
  "@
843
    // %R0 := %R1 (SI)\n\tCOPY.%# %L1,%L0 %| COPY.1 %U1,%U0
844
    LDL (%a1),%R0\t\t// %R0 = Mem(%a1)
845
    LDL %a1,%R0\t\t// %R0 = Mem(%M1{byte})
846
    // %R0 := #%1 (SI)\n\tCOPY.%# %L1,%L0 %| COPY.%# %U1,%U0
847
    STL %R1,(%a0)\t\t// Mem(%a0) := %R1
848
    STL %R1,%a0\t\t// Mem(%M0{byte}) := %R1"
849
  [(set_attr "type" "unknown,mem,mem,unknown,mem,mem")
850
   (set_attr "longConstant" "false,true,false,true,false,false")
851
   (set_attr "length" "4,4,4,6,4,4")])
852
 
853
; Split an SI mode register copy into separate HI mode copies, which
854
; can be VLIW'd with other instructions.  Only split the instruction
855
; when VLIW scheduling is enabled.  Splitting the instruction saves
856
; some code space.
857
;
858
; This is predicated in reload_completed.  This ensures that the
859
; instructions aren't broken up too early which can result in the
860
; SImode code being converted into inefficient HI mode code.
861
 
862
(define_split
863
  [(set (match_operand:SI 0 "register_operand" "")
864
        (match_operand:SI 1 "register_operand" ""))]
865
  "reload_completed && picochip_schedule_type == DFA_TYPE_SPEED"
866
  [(set (match_dup 2) (match_dup 3))
867
   (set (match_dup 4) (match_dup 5))]
868
  "{
869
     operands[2] = gen_lowpart (HImode, operands[0]);
870
     operands[3] = gen_lowpart (HImode, operands[1]);
871
     operands[4] = gen_highpart (HImode, operands[0]);
872
     operands[5] = gen_highpart (HImode, operands[1]);
873
 }")
874
 
875
; SI Mode split for load constant.
876
(define_split
877
  [(set (match_operand:SI 0 "register_operand" "")
878
        (match_operand:SI 1 "const_int_operand" ""))]
879
  ""
880
  [(set (match_dup 2) (match_dup 3))
881
   (set (match_dup 4) (match_dup 5))]
882
  "{
883
     operands[2] = gen_lowpart (HImode, operands[0]);
884
     operands[3] = picochip_get_low_const(operands[1]);
885
     operands[4] = gen_highpart (HImode, operands[0]);
886
     operands[5] = picochip_get_high_const(operands[1]);
887
 }")
888
 
889
(define_insn "movsf"
890
  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,m")
891
        (match_operand:SF 1 "general_operand" "r,m,i,r"))]
892
  ""
893
  "@
894
    // %R0 := %R1 (SF)\n\tCOPY.%# %L1,%L0 %| COPY.1 %U1,%U0
895
    LDL %a1,%R0\t\t// %R0 :={SF} Mem(%M1{byte})
896
    // %R0 := #%1 (SF)\n\tCOPY.%# %L1,%L0\n\tCOPY.%# %U1,%U0
897
    STL %R1,%a0\t\t// Mem(%M0{byte}) :={SF} %R1")
898
 
899
;;===========================================================================
900
;; NOP
901
;;===========================================================================
902
 
903
;; No-operation (NOP)
904
(define_insn "nop"
905
  [(const_int 0)]
906
  ""
907
  "NOP\t// nop"
908
  [(set_attr "length" "1")])
909
 
910
;;===========================================================================
911
;; Function Calls.  Define expands are used to ensure that the correct
912
;; type of pattern is emitted, and then the define_insn's match the
913
;; pattern using the correct types.
914
;;
915
;; Note: The comments output as part of these instructions are detected by
916
;; the linker. Don't change the comments!
917
;;===========================================================================
918
 
919
(define_expand "call"
920
  [(parallel [(call (match_operand:QI 0 "memory_operand" "")
921
         (match_operand 1 "const_int_operand" ""))
922
         (clobber (reg:HI LINK_REGNUM))])]
923
  ""
924
  "")
925
 
926
(define_insn "call_for_divmod"
927
  [(call (match_operand:QI 0 "memory_operand" "")
928
         (match_operand 1 "const_int_operand" ""))]
929
  ""
930
  "JL (%M0)\t// fn_call %M0%>"
931
  [(set_attr "length" "4")
932
   (set_attr "type" "realBranch")
933
   (set_attr "longConstant" "true")])
934
 
935
(define_insn "*call_using_symbol"
936
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
937
         (match_operand 1 "const_int_operand" ""))
938
         (clobber (reg:HI LINK_REGNUM))]
939
  ""
940
  "JL (%M0)\t// fn_call %M0%>"
941
  [(set_attr "length" "4")
942
   (set_attr "type" "realBranch")
943
   (set_attr "longConstant" "true")])
944
 
945
(define_insn "*call_using_register"
946
  [(call (mem:QI (match_operand:HI 0 "register_operand" "r"))
947
         (match_operand 1 "const_int_operand" ""))
948
         (clobber (reg:HI LINK_REGNUM))]
949
  ""
950
  "JL (%r0)\t// fn_call_unknown %r0%>"
951
  [(set_attr "length" "2")
952
   (set_attr "type" "realBranch")
953
   (set_attr "longConstant" "false")])
954
 
955
(define_expand "call_value"
956
  [(parallel [(set (match_operand:HI       0 "" "")
957
        (call:HI (match_operand:QI 1 "memory_operand" "g")
958
              (match_operand 2 "const_int_operand" "")))
959
         (clobber (reg:HI LINK_REGNUM))])]
960
  ""
961
  "")
962
 
963
(define_insn "*call_value_using_symbol"
964
  [(set (match_operand:HI 0 "" "")
965
        (call:HI (mem:QI (match_operand:HI 1 "immediate_operand" "i"))
966
              (match_operand 2 "const_int_operand" "")))
967
         (clobber (reg:HI LINK_REGNUM))]
968
  ""
969
  "JL (%M1)\t// fn_call %M1 (value return)%>"
970
  [(set_attr "length" "4")
971
   (set_attr "type" "realBranch")
972
   (set_attr "longConstant" "true")])
973
 
974
(define_insn "*call_value_using_register"
975
  [(set (match_operand:HI 0 "" "")
976
        (call:HI (mem:QI (match_operand:HI 1 "register_operand" "r"))
977
              (match_operand 2 "const_int_operand" "")))
978
         (clobber (reg:HI LINK_REGNUM))]
979
  ""
980
  "JL (%r1)// fn_call_unknown %r1 (value return)%>"
981
  [(set_attr "length" "2")
982
   (set_attr "type" "realBranch")
983
   (set_attr "longConstant" "false")])
984
 
985
;;===========================================================================
986
;; Addition
987
;;===========================================================================
988
 
989
;; Note that the addition of a negative value is transformed into the
990
;; subtraction of a positive value, so that the add/sub immediate slot
991
;; can make better use of the 4-bit range.
992
 
993
(define_insn "addhi3"
994
  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
995
        (plus:HI (match_operand:HI 1 "register_operand" "r,r,r,r")
996
                 (match_operand:HI 2 "general_operand" "r,M,n,i")))
997
   (clobber (reg:CC CC_REGNUM))]
998
  ""
999
  {  if (CONST_INT == GET_CODE(operands[2]) &&
1000
         INTVAL(operands[2]) > -16 &&
1001
         INTVAL(operands[2]) < 0)
1002
       return "SUB.%# %1,-(%2),%0\t// %0 := %1 + %2 (HI)";
1003
     else
1004
       return "ADD.%# %1,%2,%0\t// %0 := %1 + %2 (HI)";
1005
  }
1006
  [(set_attr "type" "basicAlu,basicAlu,basicAlu,basicAlu")
1007
   (set_attr "longConstant" "false,false,true,true")
1008
   (set_attr "length" "2,2,4,4")]
1009
  )
1010
 
1011
 
1012
;; If we peepholed the compare instruction out, we need to make sure the add
1013
;; goes in slot 0. This pattern is just to accomplish that.
1014
 
1015
(define_insn "addhi3_with_use_clause"
1016
  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1017
        (plus:HI (match_operand:HI 1 "register_operand" "r,r,r,r")
1018
                 (match_operand:HI 2 "general_operand" "r,M,n,i")))
1019
   (set (reg:CC CC_REGNUM)
1020
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
1021
                        [(const_int 0)
1022
                         (const_int 0)]))]
1023
  ""
1024
  {  if (CONST_INT == GET_CODE(operands[2]) &&
1025
         INTVAL(operands[2]) > -16 &&
1026
         INTVAL(operands[2]) < 0)
1027
       return "SUB.0 %1,-(%2),%0\t// %0 := %1 + %2 (HI)";
1028
     else
1029
       return "ADD.0 %1,%2,%0\t// %0 := %1 + %2 (HI)";
1030
  }
1031
  [(set_attr "type" "picoAlu,picoAlu,picoAlu,picoAlu")
1032
   (set_attr "longConstant" "false,false,true,true")
1033
   (set_attr "length" "2,2,4,4")]
1034
  )
1035
 
1036
;; Match an addition in which the first operand has been shifted
1037
;; (e.g., the comms array functions can emit such instructions).
1038
(define_insn "*addWith1stOpShift"
1039
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1040
        (plus:HI (ashift:HI (match_operand:HI 1 "register_operand" "r,r")
1041
                            (match_operand:HI 2 "const_int_operand" ""))
1042
                 (match_operand:HI 3 "immediate_operand" "I,i")))
1043
   (clobber (reg:CC CC_REGNUM))]
1044
  ""
1045
  "ADD.0 [LSL %1,%2],%3,%0\t// %0 := (%1 << %2) + %3"
1046
  [(set_attr "type" "picoAlu,picoAlu")
1047
   (set_attr "longConstant" "false,true")])
1048
 
1049
(define_insn_and_split "addsi3"
1050
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1051
        (plus:SI (match_operand:SI 1 "register_operand" "r,r")
1052
                 (match_operand:SI 2 "general_operand" "r,i")))
1053
   (clobber (reg:CC CC_REGNUM))]
1054
  ""
1055
  "// %0 := %1 + %2 (SI)\n\tADD.0 %L1,%L2,%L0\n\tADDC.0 %U1,%U2,%U0"
1056
  "reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1057
  [(match_dup 4)
1058
   (match_dup 5)]
1059
  "
1060
{
1061
  rtx op0_high = gen_highpart (HImode, operands[0]);
1062
  rtx op1_high = gen_highpart (HImode, operands[1]);
1063
  rtx op0_low  = gen_lowpart (HImode, operands[0]);
1064
  rtx op1_low  = gen_lowpart (HImode, operands[1]);
1065
  rtx op2_high, op2_low;
1066
 
1067
  if (CONST_INT == GET_CODE(operands[2]))
1068
  {
1069
    op2_high = picochip_get_high_const(operands[2]);
1070
    op2_low = picochip_get_low_const(operands[2]);
1071
  } else {
1072
    op2_high = gen_highpart (HImode, operands[2]);
1073
    op2_low  = gen_lowpart (HImode, operands[2]);
1074
  }
1075
 
1076
  operands[4] = gen_add_multi_lower (op0_low, op1_low, op2_low);
1077
  operands[5] = gen_add_multi_upper (op0_high, op1_high, op2_high);
1078
 
1079
}")
1080
 
1081
;; Perform the lowest part of a multi-part addition (SI/DI). This sets
1082
;; the flags, so is an picoAlu instruction (we could use a
1083
;; conventional addhi, but the addhi is better off being a treated as
1084
;; a basicAlu instruction, rather than a picoAlu instruction).
1085
(define_insn "add_multi_lower"
1086
  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1087
        (plus:HI (match_operand:HI 1 "register_operand" "r,r,r")
1088
                 (match_operand:HI 2 "general_operand" "r,M,i")))
1089
   (set (reg:CC CC_REGNUM)
1090
        (compare:CC (plus:HI (match_dup 1)
1091
                             (match_dup 2))
1092
                    (const_int 0)))]
1093
  ""
1094
  {  if (CONST_INT == GET_CODE(operands[2]) &&
1095
         INTVAL(operands[2]) > -16 &&
1096
         INTVAL(operands[2]) < 0)
1097
       return "SUB.%# %1,-(%2),%0\t// %0+carry := %1 + %2 (low multi-part)";
1098
     else
1099
       return "ADD.%# %1,%2,%0\t// %0+carry := %1 + %2 (low multi-part)";
1100
  }
1101
  [(set_attr "type" "picoAlu,picoAlu,picoAlu")
1102
   (set_attr "longConstant" "false,false,true")
1103
   (set_attr "length" "2,2,4")])
1104
 
1105
;; Perform the central part of a multi-part addition (DI). This uses
1106
;; the CC register, and also sets the CC register, so needs to be
1107
;; placed in the first ALU slot.  Note that the ADDC must
1108
;; use the long constant to represent immediates.
1109
(define_insn "add_multi_mid"
1110
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1111
        (plus:HI (match_operand:HI 1 "register_operand" "r,r")
1112
                 (plus:HI (match_operand:HI 2 "general_operand" "r,i")
1113
                          (reg:CC CC_REGNUM))))
1114
   (set (reg:CC CC_REGNUM)
1115
        (compare:CC (plus:HI (match_dup 1)
1116
                             (match_dup 2))
1117
                    (const_int 0)))]
1118
  ""
1119
  "ADDC.%# %1,%2,%0\t// %0+carry := carry + %1 + %2 (mid multi-part)"
1120
  [(set_attr "type" "picoAlu,picoAlu")
1121
   (set_attr "longConstant" "false,true")
1122
   (set_attr "length" "2,4")])
1123
 
1124
;; Perform the highest part of a multi-part addition (SI/DI). This
1125
;; uses the CC register, but doesn't require any registers to be set,
1126
;; so may be scheduled in either of the ALU's.  Note that the ADDC must
1127
;; use the long constant to represent immediates.
1128
(define_insn "add_multi_upper"
1129
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1130
        (plus:HI (match_operand:HI 1 "register_operand" "r,r")
1131
                 (plus:HI (match_operand:HI 2 "general_operand" "r,i")
1132
                          (reg:CC CC_REGNUM))))
1133
   (clobber (reg:CC CC_REGNUM))]
1134
  ""
1135
  "ADDC.%# %1,%2,%0\t// %0 := carry + %1 + %2 (high multi-part)"
1136
  [(set_attr "type" "basicAlu,basicAlu")
1137
   (set_attr "longConstant" "false,true")
1138
   (set_attr "length" "2,4")])
1139
 
1140
;; The lea instruction is a special type of add operation, which looks
1141
;; like a movhi (reg := address). It expands into reg := fp +
1142
;; offset.  Ideally there should be two variants, which take different
1143
;; sized offsets (i.e., using the long constant, or not, as
1144
;; appropriate).  However, the address operand may have arbitrary
1145
;; values added to it later (i.e., the AP will be eliminated, possibly
1146
;; converting a small offset into a long offset), so a long offset is
1147
;; always assumed.
1148
 
1149
;; Note that the lea can use an addition, and hence may modify the CC
1150
;; register.  This upsets scheduling, so instead the lea is placed in
1151
;; ALU 1 where it cannot modify CC.
1152
 
1153
(define_insn "*lea_add"
1154
 [(set (match_operand:HI 0 "nonimmediate_operand" "=r")
1155
       (plus:HI (match_operand:HI 1 "register_operand" "r")
1156
                (match_operand:HI 2 "immediate_operand" "i")))]
1157
 ""
1158
 "ADD.1 %1,%2,%0\t// lea (add)")
1159
 
1160
;; Note that, though this instruction looks similar to movhi pattern,
1161
;; "p" constraint cannot be specified for operands other than
1162
;; address_operand, hence the extra pattern below.
1163
(define_insn "*lea_move"
1164
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r")
1165
        (match_operand:HI 1 "address_operand" "p"))]
1166
  ""
1167
  {
1168
    if (REG == GET_CODE(operands[1]))
1169
      return "COPY.1 %1,%0\t// %0 := %1 (lea)";
1170
    else
1171
      return "ADD.1 %b1,%o1,%0\t\t// %0 := %b1 + %o1 (lea)";
1172
  }
1173
  [(set_attr "type" "nonCcAlu")
1174
   (set_attr "longConstant" "true")
1175
   (set_attr "length" "4")])
1176
 
1177
 
1178
;;===========================================================================
1179
;; Subtraction.  Note that these patterns never take immediate second
1180
;; operands, since those cases are handled by canonicalising the
1181
;; instruction into the addition of a negative costant.
1182
;; But, if the first operand needs to be a negative constant, it
1183
;; is supported here.
1184
;;===========================================================================
1185
 
1186
(define_insn "subhi3"
1187
  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1188
        (minus:HI (match_operand:HI 1 "general_operand" "r,I,i")
1189
                  (match_operand:HI 2 "register_operand" "r,r,r")))
1190
   (clobber (reg:CC CC_REGNUM))]
1191
  ""
1192
  "SUB.%# %1,%2,%0 // %0 := %1 - %2 (HI)"
1193
  [(set_attr "type" "basicAlu,basicAlu,basicAlu")
1194
   (set_attr "longConstant" "false,true,true")
1195
   (set_attr "length" "2,4,4")])
1196
 
1197
;; If we peepholed the compare instruction out, we need to make sure the
1198
;; sub goes in slot 0. This pattern is just to accomplish that.
1199
 
1200
(define_insn "subhi3_with_use_clause"
1201
  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1202
        (minus:HI (match_operand:HI 1 "general_operand" "r,I,i")
1203
                  (match_operand:HI 2 "register_operand" "r,r,r")))
1204
   (set (reg:CC CC_REGNUM)
1205
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
1206
                        [(const_int 0)
1207
                         (const_int 0)]))]
1208
  ""
1209
  "SUB.0 %1,%2,%0 // %0 := %1 - %2 (HI)"
1210
  [(set_attr "type" "picoAlu,picoAlu,picoAlu")
1211
   (set_attr "longConstant" "false,true,true")
1212
   (set_attr "length" "2,4,4")])
1213
 
1214
(define_insn_and_split "subsi3"
1215
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1216
        (minus:SI (match_operand:SI 1 "general_operand" "r,i")
1217
                  (match_operand:SI 2 "register_operand" "r,r")))
1218
   (clobber (reg:CC CC_REGNUM))]
1219
  ""
1220
  "// %0 := %1 - %2 (SI)\n\tSUB.%# %L1,%L2,%L0\n\tSUBB.%# %U1,%U2,%U0"
1221
  "reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1222
  [(match_dup 4)
1223
   (match_dup 5)]
1224
  "
1225
{
1226
  rtx op0_high = gen_highpart (HImode, operands[0]);
1227
  rtx op0_low  = gen_lowpart (HImode, operands[0]);
1228
  rtx op2_high = gen_highpart (HImode, operands[2]);
1229
  rtx op2_low = gen_lowpart (HImode, operands[2]);
1230
  rtx op1_high,op1_low;
1231
 
1232
  if (CONST_INT == GET_CODE(operands[1]))
1233
  {
1234
    op1_high = picochip_get_high_const(operands[1]);
1235
    op1_low = picochip_get_low_const(operands[1]);
1236
  } else {
1237
    op1_high = gen_highpart (HImode, operands[1]);
1238
    op1_low  = gen_lowpart (HImode, operands[1]);
1239
  }
1240
 
1241
 
1242
  operands[4] = gen_sub_multi_lower (op0_low, op1_low, op2_low);
1243
  operands[5] = gen_sub_multi_upper (op0_high, op1_high, op2_high);
1244
 
1245
}")
1246
 
1247
;; Match the patterns emitted by the multi-part subtraction splitting.
1248
;; This sets the CC register, so it needs to go into slot 0.
1249
(define_insn "sub_multi_lower"
1250
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1251
        (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1252
                  (match_operand:HI 2 "register_operand" "r,r")))
1253
   (set (reg:CC CC_REGNUM)
1254
        (compare:CC (minus:HI (match_dup 1) (match_dup 2))
1255
                    (const_int 0)))]
1256
  ""
1257
  "SUB.%# %1,%2,%0\t// %0+carry := %1 - %2 (lower SI)"
1258
  [(set_attr "type" "picoAlu,picoAlu")
1259
   (set_attr "longConstant" "false,true")
1260
   (set_attr "length" "2,4")])
1261
 
1262
;; Perform the central part of a multi-part addition (DI). This uses
1263
;; the CC register, and also sets the CC register, so needs to be
1264
;; placed in the first ALU.
1265
(define_insn "sub_multi_mid"
1266
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1267
        (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1268
                  (minus:HI (match_operand:HI 2 "register_operand" "r,r")
1269
                            (reg:CC CC_REGNUM))))
1270
   (set (reg:CC CC_REGNUM)
1271
        (compare:CC (minus:HI (match_dup 1)
1272
                              (match_dup 2))
1273
                    (const_int 0)))]
1274
  ""
1275
  "SUBB.%# %1,%2,%0\t// %0+carry := carry - %1 - %2 (mid multi-part)"
1276
  [(set_attr "type" "picoAlu,picoAlu")
1277
   (set_attr "longConstant" "false,true")
1278
   (set_attr "length" "2,4")])
1279
 
1280
(define_insn "sub_multi_upper"
1281
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1282
        (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1283
                  (minus:HI (match_operand:HI 2 "register_operand" "r,r")
1284
                            (reg:CC CC_REGNUM))))
1285
   (clobber (reg:CC CC_REGNUM))]
1286
  ""
1287
  "SUBB.%# %1,%2,%0\t// %0 := carry - %1 - %2 (upper SI)"
1288
  [(set_attr "type" "basicAlu,basicAlu")
1289
   (set_attr "longConstant" "false,true")
1290
   (set_attr "length" "2,4")])
1291
 
1292
;;===========================================================================
1293
;; Multiplication (signed)
1294
;;===========================================================================
1295
 
1296
(define_insn "multiply_machi"
1297
  [(set (reg:HI ACC_REGNUM)
1298
        (mult:HI (match_operand:HI 0 "register_operand" "r,r")
1299
                 (match_operand:HI 1
1300
                        "picochip_register_or_immediate_operand" "r,i")))]
1301
  "TARGET_HAS_MAC_UNIT"
1302
  "MUL %0,%1,acc0\t// acc0 := %0 * %1 (signed)"
1303
  [(set_attr "length" "3,5")
1304
   (set_attr "type" "mac,mac")
1305
   (set_attr "longConstant" "false,true")])
1306
 
1307
(define_expand "mulhi3"
1308
  [(set (match_operand:HI 0 "register_operand" "")
1309
        (mult:HI (match_operand:HI 1 "register_operand" "")
1310
                 (match_operand:HI 2 "picochip_register_or_immediate_operand" "")))]
1311
  "TARGET_HAS_MULTIPLY"
1312
  "")
1313
 
1314
;; Different types of mulhi, depending on the AE type. If the AE has MUL unit,
1315
;; use the following pattern.
1316
(define_insn "*mulhi3_mul"
1317
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1318
        (mult:HI (match_operand:HI 1 "register_operand" "r,r")
1319
                 (match_operand:HI 2
1320
                        "picochip_register_or_immediate_operand" "r,i")))]
1321
  "TARGET_HAS_MUL_UNIT"
1322
  "MULL %1,%2,%0 // %0 := %1 * %2 (HI)"
1323
  [(set_attr "length" "3,5")
1324
   (set_attr "type" "mul,mul")
1325
   (set_attr "longConstant" "false,true")])
1326
 
1327
;; If the AE has MAC unit, instead, use the following pattern.
1328
(define_insn_and_split "*mulhi3_mac"
1329
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1330
        (mult:HI (match_operand:HI 1 "register_operand" "r,r")
1331
                 (match_operand:HI 2
1332
                        "picochip_register_or_immediate_operand" "r,i")))]
1333
  "TARGET_HAS_MAC_UNIT"
1334
  "// %0 := %1 * %2\n\tMUL %1,%2,acc0\n\tREADACC acc0,frac,%0"
1335
  "TARGET_HAS_MAC_UNIT && reload_completed"
1336
  [(match_dup 3)
1337
   (match_dup 4)]
1338
  "
1339
{
1340
    rtx const_rtx = GEN_INT(0);
1341
    operands[3] = (gen_multiply_machi(operands[1], operands[2]));
1342
    operands[4] = (gen_movhi_mac(operands[0],const_rtx));
1343
} "
1344
)
1345
 
1346
(define_insn "umultiply_machisi"
1347
  [(set (reg:SI ACC_REGNUM)
1348
        (mult:SI (zero_extend:SI (match_operand:HI 0 "register_operand" "r"))
1349
                 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))))]
1350
  "TARGET_HAS_MAC_UNIT"
1351
  "MULUU %0,%1,acc0\t// acc0 := %0 * %1 (unsigned)"
1352
  [(set_attr "length" "3")
1353
   (set_attr "type" "mac")
1354
   (set_attr "longConstant" "false")])
1355
 
1356
(define_insn "multiply_machisi"
1357
  [(set (reg:SI ACC_REGNUM)
1358
        (mult:SI (sign_extend:SI (match_operand:HI 0 "register_operand" "r,r"))
1359
                 (sign_extend:SI (match_operand:HI 1
1360
                        "picochip_register_or_immediate_operand" "r,i"))))]
1361
  "TARGET_HAS_MAC_UNIT"
1362
  "MUL %0,%1,acc0\t// acc0 := %0 * %1 (signed)"
1363
  [(set_attr "length" "3,5")
1364
   (set_attr "type" "mac,mac")
1365
   (set_attr "longConstant" "false,true")])
1366
 
1367
;; We want to prevent GCC from thinking ACC is a normal register and using
1368
;; this pattern. We want it to be used only when you use MAC unit
1369
;; multiplication. Added a "use" clause for that sake.
1370
(define_insn "movsi_mac"
1371
   [(set (match_operand:SI 0 "register_operand" "=r")
1372
        (reg:SI ACC_REGNUM))
1373
    (use (match_operand:SI 1 "const_int_operand" ""))]
1374
  "TARGET_HAS_MAC_UNIT"
1375
  "READACC32 acc0,%R0 \t// %0 := acc0 "
1376
  [(set_attr "length" "3")
1377
   (set_attr "type" "mac")
1378
   (set_attr "longConstant" "false")])
1379
 
1380
;; We want to prevent GCC from thinking ACC is a normal register and using
1381
;; this pattern. We want it to be used only when you use MAC unit
1382
;; multiplication. Added a "use" clause for that sake.
1383
(define_insn "movhi_mac"
1384
   [(set (match_operand:HI 0 "register_operand" "=r")
1385
        (reg:HI ACC_REGNUM) )
1386
    (use (match_operand:HI 1 "const_int_operand" ""))]
1387
  "TARGET_HAS_MAC_UNIT"
1388
  "READACC acc0,frac,%0 \t// %0 := acc0 "
1389
  [(set_attr "length" "3")
1390
   (set_attr "type" "mac")
1391
   (set_attr "longConstant" "false")])
1392
 
1393
;; 16-bit to 32-bit widening signed multiplication.
1394
(define_expand "mulhisi3"
1395
  [(set (match_operand:SI 0 "register_operand" "=&r")
1396
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1397
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1398
  "TARGET_HAS_MULTIPLY"
1399
  ""
1400
)
1401
 
1402
(define_insn_and_split "*mulhisi3_mul"
1403
  [(set (match_operand:SI 0 "register_operand" "=&r")
1404
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1405
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1406
  "TARGET_HAS_MUL_UNIT"
1407
  "// %0 := %1 * %2 (HI->SI)\;MULL %1,%2,%L0\;MULH %1,%2,%U0";
1408
  "TARGET_HAS_MUL_UNIT && reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1409
  [(match_dup 3)
1410
   (match_dup 4)]
1411
  "
1412
{
1413
  rtx op0_high = gen_highpart (HImode, operands[0]);
1414
  rtx op0_low  = gen_lowpart (HImode, operands[0]);
1415
  operands[3] = gen_mulhisi3_mul_lower(op0_low,operands[1],operands[2]);
1416
  operands[4] = gen_mulhisi3_mul_higher(op0_high,operands[1],operands[2]);
1417
}
1418
  "
1419
)
1420
 
1421
(define_insn "mulhisi3_mul_lower"
1422
  [(set (match_operand:HI 0 "register_operand" "=&r")
1423
        (subreg:HI
1424
         (mult:SI
1425
          (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1426
          (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) 0))]
1427
  "TARGET_HAS_MUL_UNIT"
1428
  "MULL %1,%2,%0"
1429
  [(set_attr "length" "3")
1430
   (set_attr "type" "mul")
1431
   (set_attr "longConstant" "false")])
1432
 
1433
(define_insn "mulhisi3_mul_higher"
1434
  [(set (match_operand:HI 0 "register_operand" "=&r")
1435
        (subreg:HI
1436
         (mult:SI
1437
          (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1438
          (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) 2))]
1439
  "TARGET_HAS_MUL_UNIT"
1440
  "MULH %1,%2,%0"
1441
  [(set_attr "length" "3")
1442
   (set_attr "type" "mul")
1443
   (set_attr "longConstant" "false")])
1444
 
1445
(define_insn_and_split "*mulhisi3_mac"
1446
  [(set (match_operand:SI 0 "register_operand" "=&r")
1447
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1448
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1449
  "TARGET_HAS_MAC_UNIT"
1450
  "// %0 := %1 * %2 (HI->SI) STAN2\;MUL %1,%2,acc0\;READACC32 acc0,%R0";
1451
  "TARGET_HAS_MAC_UNIT && reload_completed"
1452
  [(match_dup 3)
1453
   (match_dup 4)]
1454
  "
1455
{
1456
    rtx const_rtx = gen_int_mode(0,SImode);
1457
    operands[3] = (gen_multiply_machisi(operands[1], operands[2]));
1458
    operands[4] = (gen_movsi_mac(operands[0],const_rtx));
1459
} "
1460
)
1461
 
1462
;;===========================================================================
1463
;; Widening multiplication (unsigned)
1464
;;===========================================================================
1465
 
1466
(define_expand "umulhisi3"
1467
  [(set (match_operand:SI 0 "register_operand" "=&r")
1468
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1469
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1470
  "TARGET_HAS_MULTIPLY"
1471
  ""
1472
)
1473
 
1474
(define_insn_and_split "*umulhisi3_mul"
1475
  [(set (match_operand:SI 0 "register_operand" "=&r")
1476
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1477
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1478
  "TARGET_HAS_MUL_UNIT"
1479
  "// %0 := %1 * %2 (uHI->uSI Type 1)\;MULUL %1,%2,%L0\n\tMULUH %1,%2,%U0";
1480
  "TARGET_HAS_MUL_UNIT && reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1481
  [(match_dup 3)
1482
   (match_dup 4)]
1483
  "
1484
{
1485
  rtx op0_high = gen_highpart (HImode, operands[0]);
1486
  rtx op0_low  = gen_lowpart (HImode, operands[0]);
1487
  operands[3] = gen_umulhisi3_mul_lower(op0_low,operands[1],operands[2]);
1488
  operands[4] = gen_umulhisi3_mul_higher(op0_high,operands[1],operands[2]);
1489
}
1490
  "
1491
  )
1492
 
1493
(define_insn "umulhisi3_mul_lower"
1494
  [(set (match_operand:HI 0 "register_operand" "=&r")
1495
        (subreg:HI
1496
         (mult:SI
1497
          (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1498
          (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))) 0))]
1499
  "TARGET_HAS_MUL_UNIT"
1500
  "MULUL %1,%2,%0"
1501
  [(set_attr "length" "3")
1502
   (set_attr "type" "mul")
1503
   (set_attr "longConstant" "false")])
1504
 
1505
(define_insn "umulhisi3_mul_higher"
1506
  [(set (match_operand:HI 0 "register_operand" "=&r")
1507
        (subreg:HI
1508
         (mult:SI
1509
          (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1510
          (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))) 2))]
1511
  "TARGET_HAS_MUL_UNIT"
1512
  "MULUH %1,%2,%0"
1513
  [(set_attr "length" "3")
1514
   (set_attr "type" "mul")
1515
   (set_attr "longConstant" "false")])
1516
 
1517
(define_insn_and_split "*umulhisi3_mac"
1518
  [(set (match_operand:SI 0 "register_operand" "=&r")
1519
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1520
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1521
  "TARGET_HAS_MAC_UNIT"
1522
  "// %0 := %1 * %2 (uHI->uSI Type 3)\;MULUU %1,%2,acc0\;READACC32 acc0,%R0";
1523
  "TARGET_HAS_MAC_UNIT && reload_completed"
1524
  [(match_dup 3)
1525
   (match_dup 4)]
1526
  "
1527
{
1528
    rtx const_rtx = gen_int_mode(0,SImode);
1529
    operands[3] = (gen_umultiply_machisi(operands[1], operands[2]));
1530
    operands[4] = (gen_movsi_mac(operands[0],const_rtx));
1531
} "
1532
)
1533
 
1534
;;===========================================================================
1535
;; Division (signed)
1536
;;===========================================================================
1537
 
1538
;; Perform a divmod operation as a function call.  This results in some
1539
;; registers being clobbered (r0-6, r12 - ignore r13,14 as these are
1540
;; known not to be affected).
1541
(define_expand "divmodhi4"
1542
  [
1543
   ; Copy the inputs to r0 and r1.
1544
   (set (reg:HI 0) (match_operand:HI 1 "register_operand" ""))
1545
   (set (reg:HI 1) (match_operand:HI 2 "register_operand" ""))
1546
   ; Make the function call - note that r12 (link) is clobbered. Note also
1547
   ; that an explicit call is generated. This ensures that gcc notices that
1548
   ; any function containing a div/mod is not a leaf function.
1549
   (parallel [(match_dup 4)
1550
              (set (reg:HI 0) (div:HI (reg:HI 0) (reg:HI 1)))
1551
              (set (reg:HI 1) (mod:HI (reg:HI 0) (reg:HI 1)))
1552
              (clobber (reg:HI 2))
1553
              (clobber (reg:HI 3))
1554
              (clobber (reg:HI 4))
1555
              (clobber (reg:HI 5))
1556
              (clobber (reg:HI 12))
1557
              (clobber (reg:CC CC_REGNUM))
1558
              ])
1559
   ; Set the quotient (returned in register 0)
1560
   (set (match_operand:HI 0 "register_operand" "") (reg:HI 0))
1561
   ; Set the remainder (returned in register 1)
1562
   (set (match_operand:HI 3 "register_operand" "") (reg:HI 1))]
1563
  ""
1564
{
1565
  rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_divmodhi4");
1566
  operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1567
})
1568
 
1569
; Match a call to divmodhi4.  As this is a call, the link register
1570
; (r12), and registers r0-5 must be clobbered.  Ignore clobbering of
1571
; r13/4 as these aren't used by the divide function).
1572
(define_insn "*divmodhi4_call"
1573
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1574
         (match_operand 1 "const_int_operand" ""))
1575
   (set (reg:HI 0) (div:HI (reg:HI 0) (reg:HI 1)))
1576
   (set (reg:HI 1) (mod:HI (reg:HI 0) (reg:HI 1)))
1577
   (clobber (reg:HI 2))
1578
   (clobber (reg:HI 3))
1579
   (clobber (reg:HI 4))
1580
   (clobber (reg:HI 5))
1581
   (clobber (reg:HI 12))
1582
   (clobber (reg:CC CC_REGNUM))
1583
]
1584
  ""
1585
  "JL (%0)\t// call %0%>"
1586
  [(set_attr "length" "4")
1587
   (set_attr "longConstant" "true")
1588
   (set_attr "type" "call")])
1589
 
1590
;; Perform a udivmod operation as a function call.  This results in some
1591
;; registers being clobbered (r0-6, r12 - ignore r13,14 as these are
1592
;; known not to be affected).
1593
(define_expand "udivmodhi4"
1594
  [
1595
   ; Copy the inputs to r0 and r1.
1596
   (set (reg:HI 0) (match_operand:HI 1 "register_operand" ""))
1597
   (set (reg:HI 1) (match_operand:HI 2 "register_operand" ""))
1598
   ; Make the function call - note that r12 (link) is clobbered. Note also
1599
   ; that an explicit call is generated. This ensures that gcc notices that
1600
   ; any function containing a div/mod is not a leaf function.
1601
   (parallel [(match_dup 4)
1602
              (set (reg:HI 0) (udiv:HI (reg:HI 0) (reg:HI 1)))
1603
              (set (reg:HI 1) (umod:HI (reg:HI 0) (reg:HI 1)))
1604
              (clobber (reg:HI 2))
1605
              (clobber (reg:HI 3))
1606
              (clobber (reg:HI 4))
1607
              (clobber (reg:HI 5))
1608
              (clobber (reg:HI 12))
1609
              (clobber (reg:CC CC_REGNUM))
1610
              ])
1611
   ; Set the quotient (returned in register 0)
1612
   (set (match_operand:HI 0 "register_operand" "") (reg:HI 0))
1613
   ; Set the remainder (returned in register 1)
1614
   (set (match_operand:HI 3 "register_operand" "") (reg:HI 1))]
1615
  ""
1616
{
1617
  rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_udivmodhi4");
1618
  operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1619
})
1620
 
1621
; Match a call to udivmodhi4.  As this is a call, the link register
1622
; (r12), and registers r0-5 must be clobbered.  Ignore clobbering of
1623
; r13/4 as these aren't used by the divide function).
1624
(define_insn "*udivmodhi4_call"
1625
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1626
         (match_operand 1 "const_int_operand" ""))
1627
   (set (reg:HI 0) (udiv:HI (reg:HI 0) (reg:HI 1)))
1628
   (set (reg:HI 1) (umod:HI (reg:HI 0) (reg:HI 1)))
1629
   (clobber (reg:HI 2))
1630
   (clobber (reg:HI 3))
1631
   (clobber (reg:HI 4))
1632
   (clobber (reg:HI 5))
1633
   (clobber (reg:HI 12))
1634
   (clobber (reg:CC CC_REGNUM))]
1635
  ""
1636
  "JL (%0)\t// call %0%>"
1637
  [(set_attr "length" "4")
1638
   (set_attr "longConstant" "true")
1639
   (set_attr "type" "call")])
1640
 
1641
(define_expand "udivmodsi4"
1642
  [
1643
   ; Make the function call
1644
   (set (reg:SI 0) (match_operand:SI 1 "register_operand" ""))
1645
   (set (reg:SI 2) (match_operand:SI 2 "register_operand" ""))
1646
   (parallel [
1647
     (match_dup 4)
1648
     (set (reg:SI 4) (udiv:SI (reg:SI 0) (reg:SI 2)))
1649
     (set (reg:SI 6) (umod:SI (reg:SI 0) (reg:SI 2)))
1650
     (clobber (reg:SI 0))
1651
     (clobber (reg:SI 2))
1652
     (clobber (reg:HI 12))
1653
   (clobber (reg:CC CC_REGNUM))])
1654
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 4))
1655
   (set (match_operand:SI 3 "register_operand" "") (reg:SI 6))]
1656
  ""
1657
{
1658
  rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_udivmodsi4");
1659
  operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1660
})
1661
 
1662
(define_insn "*udivmodsi4_call"
1663
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1664
         (match_operand 1 "const_int_operand" ""))
1665
   (set (reg:SI 4) (udiv:SI (reg:SI 0) (reg:SI 2)))
1666
   (set (reg:SI 6) (umod:SI (reg:SI 0) (reg:SI 2)))
1667
   (clobber (reg:SI 0))
1668
   (clobber (reg:SI 2))
1669
   (clobber (reg:HI 12))
1670
   (clobber (reg:CC CC_REGNUM))]
1671
  ""
1672
  "JL (%0)\t// call %0%>"
1673
  [(set_attr "length" "4")
1674
   (set_attr "longConstant" "true")
1675
   (set_attr "type" "call")])
1676
 
1677
(define_expand "divmodsi4"
1678
  [
1679
   ; Make the function call
1680
   (set (reg:SI 0) (match_operand:SI 1 "register_operand" ""))
1681
   (set (reg:SI 2) (match_operand:SI 2 "register_operand" ""))
1682
   (parallel [
1683
     (match_dup 4)
1684
     (set (reg:SI 4) (div:SI (reg:SI 0) (reg:SI 2)))
1685
     (set (reg:SI 6) (mod:SI (reg:SI 0) (reg:SI 2)))
1686
     (clobber (reg:SI 0))
1687
     (clobber (reg:SI 2))
1688
     (clobber (reg:HI 12))
1689
     (clobber (reg:CC CC_REGNUM))])
1690
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 4))
1691
   (set (match_operand:SI 3 "register_operand" "") (reg:SI 6))]
1692
  ""
1693
{
1694
  rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_divmodsi4");
1695
  operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1696
})
1697
 
1698
(define_insn "*divmodsi4_call"
1699
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1700
         (match_operand 1 "const_int_operand" ""))
1701
   (set (reg:SI 4) (div:SI (reg:SI 0) (reg:SI 2)))
1702
   (set (reg:SI 6) (mod:SI (reg:SI 0) (reg:SI 2)))
1703
   (clobber (reg:SI 0))
1704
   (clobber (reg:SI 2))
1705
   (clobber (reg:HI 12))
1706
   (clobber (reg:CC CC_REGNUM))]
1707
  ""
1708
  "JL (%0)\t// call %0%>"
1709
  [(set_attr "length" "4")
1710
   (set_attr "longConstant" "true")
1711
   (set_attr "type" "call")])
1712
 
1713
;;===========================================================================
1714
;; Bitwise AND.  The QI/SI mode instructions are automatically
1715
;; synthesised from the HI mode instruction.
1716
;;===========================================================================
1717
 
1718
(define_insn "andhi3"
1719
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1720
        (and:HI (match_operand:HI 1 "register_operand" "r,r")
1721
                (match_operand:HI 2 "general_operand" "r,n")))
1722
   (clobber (reg:CC CC_REGNUM))]
1723
  ""
1724
  "AND.%# %1,%2,%0 // %0 := %1 AND %2 (HI)"
1725
  [(set_attr "type" "basicAlu,basicAlu")
1726
   (set_attr "longConstant" "false,true")
1727
   (set_attr "length" "3,5")])
1728
 
1729
;; If we peepholed the compare instruction out, we need to make sure the
1730
;; "and" goes in slot 0. This pattern is just to accomplish that.
1731
 
1732
(define_insn "andhi3_with_use_clause"
1733
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1734
        (and:HI (match_operand:HI 1 "register_operand" "r,r")
1735
                (match_operand:HI 2 "general_operand" "r,n")))
1736
   (set (reg:CC CC_REGNUM)
1737
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
1738
                        [(const_int 0)
1739
                         (const_int 0)]))]
1740
  ""
1741
  "AND.0 %1,%2,%0 // %0 := %1 AND %2 (HI)"
1742
  [(set_attr "type" "picoAlu,picoAlu")
1743
   (set_attr "longConstant" "false,true")
1744
   (set_attr "length" "3,5")])
1745
 
1746
;;===========================================================================
1747
;; Bitwise inclusive-OR.  The QI mode instruction is automatically
1748
;; synthesised from the HI mode instruction.
1749
;;===========================================================================
1750
 
1751
(define_insn "iorhi3"
1752
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1753
        (ior:HI (match_operand:HI 1 "register_operand" "r,r")
1754
                (match_operand:HI 2 "register_operand" "r,n")))
1755
   (clobber (reg:CC CC_REGNUM))]
1756
  ""
1757
  "OR.%# %1,%2,%0 // %0 := %1 IOR %2 (HI)"
1758
  [(set_attr "type" "basicAlu,basicAlu")
1759
   (set_attr "longConstant" "false,true")
1760
   (set_attr "length" "3,5")])
1761
 
1762
(define_insn "iorhi3_with_use_clause"
1763
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1764
        (ior:HI (match_operand:HI 1 "register_operand" "r,r")
1765
                (match_operand:HI 2 "general_operand" "r,n")))
1766
   (set (reg:CC CC_REGNUM)
1767
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
1768
                        [(const_int 0)
1769
                         (const_int 0)]))]
1770
  ""
1771
  "OR.0 %1,%2,%0 // %0 := %1 IOR %2 (HI)"
1772
  [(set_attr "type" "picoAlu,picoAlu")
1773
   (set_attr "longConstant" "false,true")
1774
   (set_attr "length" "3,5")])
1775
 
1776
;;===========================================================================
1777
;; Bitwise exclusive-OR.  The QI/SI mode instructions are automatically
1778
;; synthesised from the HI mode instruction.
1779
;;===========================================================================
1780
 
1781
(define_insn "xorhi3"
1782
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1783
        (xor:HI (match_operand:HI 1 "register_operand" "r,r")
1784
                (match_operand:HI 2 "picochip_register_or_immediate_operand" "r,n")))
1785
   (clobber (reg:CC CC_REGNUM))]
1786
  ""
1787
  "XOR.%# %1,%2,%0 // %0 := %1 XOR %2 (HI)"
1788
  [(set_attr "type" "basicAlu,basicAlu")
1789
   (set_attr "longConstant" "false,true")
1790
   (set_attr "length" "3,5")])
1791
 
1792
;;===========================================================================
1793
;; Arithmetic shift left.
1794
;;===========================================================================
1795
 
1796
(define_insn "ashlhi3"
1797
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1798
        (ashift:HI (match_operand:HI 1 "register_operand" "r,r")
1799
                (match_operand:HI 2 "general_operand" "r,J")))]
1800
  ""
1801
  "LSL.%# %1,%2,%0 // %0 := %1 << %2"
1802
  [(set_attr "type" "picoAlu,basicAlu")
1803
   (set_attr "length" "3,3")])
1804
 
1805
;;===========================================================================
1806
;; Arithmetic shift right.
1807
;;===========================================================================
1808
 
1809
(define_insn "builtin_asri"
1810
  [(set (match_operand:HI 0 "register_operand" "=r")
1811
        (ashiftrt:HI (match_operand:HI 1 "register_operand" "r")
1812
                     (match_operand:HI 2 "immediate_operand" "")))
1813
   (clobber (reg:CC CC_REGNUM))]
1814
  ""
1815
  "ASR.%# %1,%2,%0\t// %0 = %1 >>{arith} %2"
1816
  [(set_attr "type" "basicAlu")
1817
   (set_attr "length" "3")])
1818
 
1819
;; The picoChip ISA doesn't have a variable arithmetic shift right, so
1820
;; synthesise it.  Shifts by constants are directly supported.
1821
 
1822
(define_expand "ashrhi3"
1823
  [(match_operand:HI 0 "register_operand" "")
1824
   (match_operand:HI 1 "register_operand" "")
1825
   (match_operand:HI 2 "picochip_register_or_immediate_operand" "")]
1826
  ""
1827
{
1828
  if (GET_CODE(operands[2]) == CONST_INT)
1829
    /* Shift by constant is easy. */
1830
    emit_insn (gen_builtin_asri (operands[0], operands[1], operands[2]));
1831
  else
1832
  {
1833
    /* Synthesise a variable shift. */
1834
 
1835
    /* Fill a temporary with the sign bits. */
1836
    rtx tmp1 = gen_reg_rtx (HImode);
1837
    emit_insn (gen_builtin_asri (tmp1, operands[1], GEN_INT(15)));
1838
 
1839
    /* Shift the unsigned value. */
1840
    rtx tmp2 = gen_reg_rtx (HImode);
1841
    emit_insn (gen_lshrhi3 (tmp2, operands[1], operands[2]));
1842
 
1843
    /* The word of sign bits must be shifted back to the left, to zero
1844
     * out the unwanted lower bits.  The amount to shift left by is (15 -
1845
     * count). Since the shifts are computed modulo 16 (i.e., only the
1846
     * lower 4 bits of the count are used), the shift amount (15 - count)
1847
     * is equivalent to !count. */
1848
    rtx tmp3 = gen_reg_rtx (HImode);
1849
    rtx tmp3_1 = GEN_INT (-1);
1850
    emit_insn (gen_xorhi3 (tmp3, operands[2], tmp3_1));
1851
    rtx tmp4 = gen_reg_rtx (HImode);
1852
    emit_insn (gen_ashlhi3 (tmp4, tmp1, tmp3));
1853
 
1854
    /* Combine the sign bits with the shifted value. */
1855
    emit_insn (gen_iorhi3 (operands[0], tmp2, tmp4));
1856
 
1857
  }
1858
  DONE;
1859
})
1860
 
1861
;;===========================================================================
1862
;; Logical shift right.
1863
;;===========================================================================
1864
 
1865
(define_insn "lshrhi3"
1866
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1867
        (lshiftrt:HI (match_operand:HI 1 "register_operand" "r,r")
1868
                (match_operand:HI 2 "general_operand" "r,J")))]
1869
  ""
1870
  "LSR.%# %1,%2,%0 // %0 := %1 >> %2"
1871
  [(set_attr "type" "picoAlu,basicAlu")
1872
   (set_attr "length" "3,3")])
1873
 
1874
;;===========================================================================
1875
;; Negate.
1876
;;===========================================================================
1877
 
1878
;; Negations are performed by subtracting from the constant 0, which
1879
;; is loaded into a register.  By using a register containing 0, the
1880
;; chances of being able to CSE with another 0 value are increased.
1881
 
1882
(define_expand "neghi2"
1883
  [(set (match_dup 2) (match_dup 3))
1884
   (parallel [(set (match_operand:HI 0 "register_operand" "=r")
1885
                   (minus:HI (match_dup 2)
1886
                             (match_operand:HI 1 "register_operand" "r")))
1887
              (clobber (reg:CC CC_REGNUM))])]
1888
  ""
1889
  "operands[2] = gen_reg_rtx(HImode);
1890
   operands[3] = GEN_INT(0x00000000);")
1891
 
1892
(define_expand "negsi2"
1893
  [(set (match_dup 2) (match_dup 3))
1894
   (parallel [(set (match_operand:SI 0 "register_operand" "=r")
1895
                   (minus:SI (match_dup 2)
1896
                             (match_operand:SI 1 "register_operand" "r")))
1897
              (clobber (reg:CC CC_REGNUM))])]
1898
  ""
1899
  "operands[2] = gen_reg_rtx(SImode);
1900
   operands[3] = GEN_INT(0x00000000);")
1901
 
1902
;;===========================================================================
1903
;; Absolute value. Taken from the Hacker's Delight, page 17. The second of the
1904
;; four options given there produces the smallest, fastest code.
1905
;;===========================================================================
1906
 
1907
(define_insn_and_split "abshi2"
1908
  [(set (match_operand:HI 0 "register_operand" "")
1909
   (abs:HI (match_operand:HI 1 "register_operand" "")))]
1910
 ""
1911
 "#"
1912
 ""
1913
 [(parallel [(set (match_dup 2)
1914
                  (plus:HI (ashiftrt:HI (match_dup 1) (const_int 15))
1915
                           (match_dup 1)))
1916
             (clobber (reg:CC CC_REGNUM))])
1917
  (parallel [(set (match_dup 0)
1918
                  (xor:HI (ashiftrt:HI (match_dup 1) (const_int 15))
1919
                          (match_dup 2)))
1920
             (clobber (reg:CC CC_REGNUM))])]
1921
{
1922
  operands[2] = gen_reg_rtx (HImode);
1923
})
1924
 
1925
;;===========================================================================
1926
;; Bitwise complement.  Use auto-synthesised variant for SI mode. Though this
1927
;; internally uses xor, the compiler doesnt automatically synthesize it using
1928
;; xor, if this pattern was removed.
1929
;;===========================================================================
1930
 
1931
(define_insn "one_cmplhi2"
1932
  [(set (match_operand:HI 0 "register_operand" "=r")
1933
        (not:HI (match_operand:HI 1 "register_operand" "0")))
1934
   (clobber (reg:CC CC_REGNUM))]
1935
  ""
1936
  "XOR.%# %1,-1,%0 // %0 := ~%1"
1937
  [(set_attr "type" "basicAlu")
1938
   (set_attr "longConstant" "true")
1939
   (set_attr "length" "5")])
1940
 
1941
;;===========================================================================
1942
;; Count leading zeros. The special sign-bit-count instruction can be used
1943
;; to help us here.
1944
;;    op1:=clz(op1)
1945
;; The code works by checking to see if the top bit is set. If it is,
1946
;; then there are no leading zeros. If the top bit is cleared, then
1947
;; the SBC instruction is used to determine how many more leading
1948
;; zeros are present, and adding one more for the initial zero.
1949
;;===========================================================================
1950
 
1951
(define_insn "clzhi2"
1952
  [(set (match_operand:HI 0 "register_operand" "=&r")
1953
        (clz:HI (match_operand:HI 1 "register_operand" "r")))]
1954
  ""
1955
  "// Count leading zeros\;SBC %1,%0\;ASR.0 %1,15,r15 %| ADD.1 %0,1,%0\;COPYNE 0,%0"
1956
  [(set_attr "length" "11")])
1957
 
1958
;;===========================================================================
1959
;; Count trailing zeros. This can be achieved efficiently by reversing
1960
;; using the bitrev instruction, and then counting the leading zeros as
1961
;; described above.
1962
;;===========================================================================
1963
 
1964
(define_insn "ctzhi2"
1965
  [(set (match_operand:HI 0 "register_operand" "=&r")
1966
        (ctz:HI (match_operand:HI 1 "register_operand" "r")))]
1967
  ""
1968
  "// Count trailing zeros\;BREV %1,%0\;SBC %0,%0\;AND.0 %1,0x0001,r15 %| ADD.1 %0,1,%0\;COPYNE 0,%0"
1969
  [(set_attr "length" "15")])
1970
 
1971
;;===========================================================================
1972
;; Find the first set bit, starting from the least significant bit position.
1973
;; This is very similar to the ctz function, except that the bit index is one
1974
;; greater than the number of trailing zeros (i.e., SBC + 2), and the
1975
;; result of ffs on the zero value is defined.
1976
;;===========================================================================
1977
 
1978
(define_insn "ffshi2"
1979
  [(set (match_operand:HI 0 "register_operand" "=&r")
1980
        (ffs:HI (match_operand:HI 1 "register_operand" "r")))]
1981
  ""
1982
  "// First first bit\;BREV %1,%0\;SBC %0,%0\;AND.0 %1,0x0001,r15 %| ADD.1 %0,2,%0\;COPYNE 1,%0\;SUB.0 %1,0x0000,r15\;COPYEQ 0,%0"
1983
  [(set_attr "length" "20")])
1984
 
1985
;;===========================================================================
1986
;; Tablejump Instruction.  Jump to an absolute address.
1987
;;===========================================================================
1988
 
1989
(define_insn "tablejump"
1990
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "r")] 1))
1991
   (use (label_ref (match_operand 1 "" "")))
1992
   (clobber (match_dup 0))]
1993
  ""
1994
  "JR (%0)\t // Table jump to %0 %>"
1995
  [(set_attr "length" "2")
1996
   (set_attr "type" "realBranch")])
1997
 
1998
;; Given the memory address of a QImode value, and a scratch register,
1999
;; store the memory operand into the given output operand.  The scratch
2000
;; operand will not conflict with either of the operands.  The other
2001
;; two operands may conflict with each other.
2002
 
2003
(define_insn "synthesised_loadqi_unaligned"
2004
  [(set (match_operand:QI 0 "register_operand" "=r")
2005
        (match_operand:QI 1 "memory_operand" "m"))
2006
   (clobber (match_operand:HI 2 "register_operand" "=&r"))
2007
   (clobber (reg:CC CC_REGNUM))]
2008
  ""
2009
  "// Synthesised loadqi %0 = Mem(%1) (Scratch %2)\n\tAND.0 %1,-2,%2\n\tLDW (%2)0,%0 %| AND.0 %1,1,%2\n\tLSL.0 %2,3,%2\n\tSUB.0 8,%2,%2\n\tLSL.0 %0,%2,%0\n\tASR.0 %0,8,%0"
2010
  ; Approximate length only.  Probably a little shorter than this.
2011
  [(set_attr "length" "40")])
2012
 
2013
;; Given a memory operand whose alignment is known (the HImode aligned
2014
;; base is operand 0, and the number of bits by which to shift is in
2015
;; operand 5),
2016
(define_expand "synthesised_storeqi_aligned"
2017
  [; s1 = mem_op
2018
   (set (match_operand:HI 2 "register_operand" "")
2019
        (match_operand:HI 0 "memory_operand" ""))
2020
   ; s1 = s1 and mask
2021
   (parallel [(set (match_dup 2) (and:HI (match_dup 2) (match_dup 5)))
2022
   (clobber (reg:CC CC_REGNUM))])
2023
   ; s2 = source << bitShift
2024
   (set (match_dup 3)
2025
        (ashift:HI (subreg:HI (match_operand:QI 1 "register_operand" "") 0)
2026
                   (match_operand:HI 4 "const_int_operand" "")))
2027
   ; s1 = s1 or s2
2028
   (parallel [(set (match_dup 2) (ior:HI (match_dup 2) (match_dup 3)))
2029
   (clobber (reg:CC CC_REGNUM))])
2030
   ; mem_op = s1
2031
   (set (match_dup 0) (match_dup 2))]
2032
  "!TARGET_HAS_BYTE_ACCESS"
2033
{
2034
  /* Create the byte mask 0xFF00. */
2035
  operands[5] = gen_int_mode(((~0xFF) >> INTVAL (operands[4])), HImode);
2036
})
2037
 
2038
;; Reload instructions.  See picochip_secondary_reload for an
2039
;; explanation of why an SI mode register is used as a scratch.  The
2040
;; memory operand must be stored in a register (i.e., it can't be an
2041
;; offset to another register - this would require another scratch
2042
;; register into which the address of the offset could be computed).
2043
 
2044
(define_expand "reload_inqi"
2045
  [(parallel [(match_operand:QI 0 "register_operand" "=&r")
2046
              (match_operand:QI 1 "memory_operand" "m")
2047
              (match_operand:SI 2 "register_operand" "=&r")])]
2048
  "!TARGET_HAS_BYTE_ACCESS"
2049
{
2050
  rtx scratch, seq;
2051
 
2052
  /* Get the scratch register.  Given an SI mode value, we have a
2053
     choice of two HI mode scratch registers, so we can be sure that at
2054
     least one of the scratch registers will be different to the output
2055
     register, operand[0]. */
2056
 
2057
  if (REGNO (operands[0]) == REGNO (operands[2]))
2058
    scratch = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
2059
  else
2060
    scratch = gen_rtx_REG (HImode, REGNO (operands[2]));
2061
 
2062
  /* Ensure that the scratch doesn't overlap either of the other
2063
     two operands - however, the other two may overlap each
2064
     other. */
2065
  gcc_assert (REGNO(scratch) != REGNO(operands[0]));
2066
  gcc_assert (REGNO(scratch) != REGNO(operands[1]));
2067
 
2068
  gcc_assert (GET_CODE (operands[1]) == MEM);
2069
 
2070
  if (picochip_word_aligned_memory_reference(XEXP(operands[1], 0)))
2071
  {
2072
    /* Aligned reloads are easy, since they can use word-loads. */
2073
    seq = gen_synthesised_loadqi_aligned(operands[0], operands[1], scratch);
2074
  }
2075
  else
2076
  {
2077
    /* Emit the instruction using a define_insn. */
2078
    seq = gen_synthesised_loadqi_unaligned(operands[0], operands[1], scratch);
2079
  }
2080
  emit_insn (seq);
2081
 
2082
  DONE;
2083
 
2084
})
2085
 
2086
(define_expand "reload_outqi"
2087
  [(parallel [(match_operand 0 "memory_operand" "=m")
2088
              (match_operand:QI 1 "register_operand" "r")
2089
              (match_operand:SI 2 "register_operand" "=&r")])]
2090
  "!TARGET_HAS_BYTE_ACCESS"
2091
{
2092
  rtx scratch1 = gen_rtx_REG(HImode, REGNO(operands[2]));
2093
  rtx scratch2 = gen_rtx_REG(HImode, REGNO(operands[2]) + 1);
2094
  rtx seq;
2095
 
2096
  gcc_assert (GET_CODE (operands[0]) == MEM);
2097
 
2098
  if (picochip_word_aligned_memory_reference(XEXP(operands[0], 0)))
2099
    {
2100
      rtx alignedAddr, bitShift;
2101
 
2102
      /* Convert the address of the known alignment into two operands
2103
       * representing the aligned base address, and the number of shift bits
2104
       * required to access the required value. */
2105
      picochip_get_hi_aligned_mem(operands[0], &alignedAddr, &bitShift);
2106
 
2107
      /* Emit an aligned store of the source, with the given bit offset. */
2108
      seq = gen_synthesised_storeqi_aligned(alignedAddr, operands[1], scratch1, scratch2, bitShift);
2109
 
2110
    }
2111
  else
2112
    {
2113
      /* This isnt exercised at all. Moreover, with new devices, byte access
2114
         is available in all variants. */
2115
      gcc_unreachable();
2116
    }
2117
 
2118
  emit_insn (seq);
2119
  DONE;
2120
 
2121
})
2122
 
2123
;; Perform a byte load of an alignable memory operand.
2124
; op0 = register to load. op1 = memory operand from which to load
2125
; op2 = op1, aligned to HI, op3 = const bit shift required to extract byte,
2126
; op4 = INTVAL(8 - op3)
2127
(define_expand "synthesised_loadqi_aligned"
2128
  [; Load memory operand into register
2129
   (set (match_operand:HI 2 "register_operand" "=r")
2130
        (match_dup 3))
2131
   ; Shift required byte into top byte of word.
2132
   (set (match_dup 2)
2133
        (ashift:HI (match_dup 2)
2134
                   (match_dup 4)))
2135
   ; Arithmetic shift of byte to sign extend, and move to lowest register.
2136
   (parallel[(set (subreg:HI (match_dup 0) 0)
2137
        (ashiftrt:HI (match_dup 2)
2138
                     (const_int 8)))
2139
   (clobber (reg:CC CC_REGNUM))])
2140
   (use (match_operand:QI 1 "picochip_alignable_memory_operand" "g"))]
2141
  "!TARGET_HAS_BYTE_ACCESS"
2142
{
2143
  rtx alignedAddr, bitShift;
2144
 
2145
  /* Convert the address of the known alignment into two operands
2146
   * representing the aligned base address, and the number of shift bits
2147
   * required to access the required value. */
2148
  picochip_get_hi_aligned_mem(operands[1], &alignedAddr, &bitShift);
2149
 
2150
  operands[3] = alignedAddr;
2151
  operands[4] = GEN_INT(8 - INTVAL(bitShift));
2152
})
2153
 
2154
;;============================================================================
2155
;; Special instructions.
2156
;;============================================================================
2157
 
2158
; Count sign-bits.
2159
(define_insn "sbc"
2160
  [(set (match_operand:HI             0 "register_operand" "=r")
2161
        (unspec:HI [(match_operand:HI 1 "register_operand" "r")]
2162
                   UNSPEC_SBC))]
2163
  ""
2164
  "SBC %1,%0\t\t// %0 := SBC(%1)"
2165
  [(set_attr "type" "picoAlu")
2166
   (set_attr "length" "2")])
2167
 
2168
; Bit reversal.
2169
(define_insn "brev"
2170
  [(set (match_operand:HI             0 "register_operand" "=r")
2171
        (unspec:HI [(match_operand:HI 1 "register_operand" "r")]
2172
                   UNSPEC_BREV))]
2173
  ""
2174
  "BREV %1,%0\t\t// %0 := BREV(%1)"
2175
  [(set_attr "length" "2")
2176
   (set_attr "type" "picoAlu")])
2177
 
2178
; Byte swap.
2179
(define_insn "bswaphi2"
2180
  [(set (match_operand:HI             0 "register_operand" "=r")
2181
        (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
2182
  ""
2183
  "BYTESWAP %1,%0\t\t// %0 := ByteSwap(%1)"
2184
  [(set_attr "length" "2")
2185
   (set_attr "type" "picoAlu")])
2186
 
2187
; Read status word.
2188
(define_insn "copysw"
2189
  [(set (match_operand:HI 0 "register_operand" "=r")
2190
        (unspec_volatile:HI [(reg:CC CC_REGNUM)] UNSPEC_COPYSW))]
2191
  ""
2192
  "COPYSW.%# %0\t// %0 := Flags"
2193
  [(set_attr "type" "basicAlu")
2194
   (set_attr "length" "2")])
2195
 
2196
; Saturating addition.
2197
(define_insn "sataddhi3"
2198
  [(set (match_operand:HI             0 "register_operand" "=r")
2199
        (unspec:HI [(match_operand:HI 1 "register_operand" "r")
2200
                    (match_operand:HI 2 "register_operand" "r")]
2201
                   UNSPEC_ADDS))
2202
   (clobber (reg:CC CC_REGNUM))]
2203
  ""
2204
  "ADDS %1,%2,%0\t// %0 := sat(%1 + %2)"
2205
  [(set_attr "type" "picoAlu")
2206
   (set_attr "length" "3")])
2207
 
2208
; Saturating subtraction.
2209
(define_insn "satsubhi3"
2210
  [(set (match_operand:HI             0 "register_operand" "=r")
2211
        (unspec:HI [(match_operand:HI 1 "register_operand" "r")
2212
                    (match_operand:HI 2 "register_operand" "r")]
2213
                   UNSPEC_SUBS))
2214
   (clobber (reg:CC CC_REGNUM))]
2215
  ""
2216
  "SUBS %1,%2,%0\t// %0 := sat(%1 - %2)"
2217
  [(set_attr "type" "picoAlu")
2218
   (set_attr "length" "3")])
2219
 
2220
(define_insn "halt"
2221
  [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "i")]
2222
        UNSPEC_HALT)]
2223
  ""
2224
  "HALT\t// (id %0)"
2225
  [(set_attr "length" "1")
2226
   (set_attr "type" "unknown")])
2227
 
2228
(define_insn "internal_testport"
2229
  [(set (reg:CC CC_REGNUM)
2230
        (unspec_volatile:CC [(match_operand:HI 0 "const_int_operand" "i")]
2231
           UNSPEC_INTERNAL_TESTPORT))]
2232
  ""
2233
  "TSTPORT %0"
2234
  [(set_attr "length" "2")
2235
   (set_attr "longConstant" "false")
2236
   (set_attr "type" "picoAlu")])
2237
 
2238
;;============================================================================
2239
;; Communications builtins.
2240
;;
2241
;; Each builtin comes in two forms: a single port version, which maps
2242
;; to a single instruction, and an array port version.  The array port
2243
;; version is treated as a special type of instruction, which is then
2244
;; split into a number of smaller instructions, if the index of the
2245
;; port can't be converted into a constant.  When the RTL split is
2246
;; performed, a function call is emitted, in which the index of the
2247
;; port to use is used to compute the address of the function to call
2248
;; (i.e., each array port is a function in its own right, and the
2249
;; functions are stored as an array which is then indexed to determine
2250
;; the correct function). The communication function port array is
2251
;; created by the linker if and only if it is required (in a
2252
;; collect2-like manner).
2253
;;============================================================================
2254
 
2255
; Simple scalar get.
2256
(define_insn "commsGet"
2257
  [(set (match_operand:SI             0 "register_operand" "=r")
2258
        (unspec_volatile:SI
2259
         [(match_operand:HI 1 "immediate_operand" "n")]
2260
         UNSPEC_GET))]
2261
  ""
2262
  "GET %1,%R0\t// %R0 := PORT(%1)"
2263
  [(set_attr "type" "comms")
2264
   (set_attr "length" "2")])
2265
 
2266
; Entry point for array get (the actual port index is computed as the
2267
; sum of the index, and the base).
2268
;
2269
; op0 - Destination
2270
; op1 - Requested port index
2271
; op2 - size of port array (constant)
2272
; op3 - base index of port array (constant)
2273
 
2274
(define_expand "commsArrayGet"
2275
  [(parallel
2276
      [(set (reg:SI 0)
2277
            (unspec_volatile:SI [(match_operand:HI 1 "general_operand" "")
2278
                         (match_operand:HI 2 "immediate_operand" "")
2279
                         (match_operand:HI 3 "immediate_operand" "")]
2280
                UNSPEC_CALL_GET_ARRAY))
2281
       (clobber (reg:HI LINK_REGNUM))])
2282
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 0))]
2283
  ""
2284
  "")
2285
 
2286
;; The actual array get instruction. When the array index is a constant,
2287
;; an exact instruction may be generated. When the index is variable,
2288
;; a call to a special function is generated. This code could be
2289
;; split into individual RTL instructions, but it is so rarely
2290
;; used, that we won't bother.
2291
(define_insn "*commsArrayGetInstruction"
2292
  [(set (reg:SI 0)
2293
        (unspec_volatile:SI [(match_operand:HI 0 "general_operand" "r,i")
2294
                     (match_operand:HI 1 "immediate_operand" "")
2295
                     (match_operand:HI 2 "immediate_operand" "")]
2296
                UNSPEC_CALL_GET_ARRAY))
2297
   (clobber (reg:HI LINK_REGNUM))]
2298
  ""
2299
{
2300
  return picochip_output_get_array (which_alternative, operands);
2301
})
2302
 
2303
; Scalar Put instruction.
2304
(define_insn "commsPut"
2305
  [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "")
2306
                     (match_operand:SI 1 "register_operand" "r")]
2307
                    UNSPEC_PUT)]
2308
  ""
2309
  "PUT %R1,%0\t// PORT(%0) := %R1"
2310
  [(set_attr "type" "comms")
2311
   (set_attr "length" "2")])
2312
 
2313
; Entry point for array put. The operands accepted are:
2314
;   op0 - Value to put
2315
;   op1 - Requested port index
2316
;   op2 - size of port array
2317
;   op3 - base index of port array
2318
; The arguments are marshalled into the fixed registers, so that
2319
; the actual put instruction can expand into a call if necessary
2320
; (e.g., if the index is variable at run-time).
2321
 
2322
(define_expand "commsArrayPut"
2323
  [(set (reg:SI 0) (match_operand:SI 0 "general_operand" ""))
2324
   (parallel
2325
      [(unspec_volatile [(match_operand:HI 1 "general_operand" "")
2326
                         (match_operand:HI 2 "immediate_operand" "")
2327
                         (match_operand:HI 3 "immediate_operand" "")]
2328
                UNSPEC_CALL_PUT_ARRAY)
2329
       (use (reg:SI 0))
2330
       (clobber (reg:HI LINK_REGNUM))])]
2331
  ""
2332
  "")
2333
 
2334
;; The actual array put instruction. When the array index is a constant,
2335
;; an exact instruction may be generated. When the index is variable,
2336
;; a call to a special function is generated. This code could be
2337
;; split into individual RTL instructions, but it is so rarely
2338
;; used, that we won't bother.
2339
(define_insn "*commsArrayPutInstruction"
2340
  [(unspec_volatile [(match_operand:HI 0 "general_operand" "r,i")
2341
                     (match_operand:HI 1 "immediate_operand" "")
2342
                     (match_operand:HI 2 "immediate_operand" "")]
2343
                UNSPEC_CALL_PUT_ARRAY)
2344
   (use (reg:SI 0))
2345
   (clobber (reg:HI LINK_REGNUM))]
2346
  ""
2347
{
2348
  return picochip_output_put_array (which_alternative, operands);
2349
})
2350
 
2351
;; Scalar test port instruction.
2352
(define_insn "commsTestPort"
2353
  [(set (match_operand:HI             0 "register_operand" "=r")
2354
        (unspec_volatile:HI [(match_operand:HI 1 "const_int_operand" "")]
2355
                   UNSPEC_TESTPORT))
2356
   (clobber (reg:CC CC_REGNUM))]
2357
  ""
2358
  "// %0 := TestPort(%1)\;TSTPORT %1\;COPYSW.0 %0\;AND.0 %0,8,%0"
2359
  [(set_attr "length" "9")])
2360
 
2361
; Entry point for array tstport (the actual port index is computed as the
2362
; sum of the index, and the base).
2363
;
2364
; op0 - Test value.
2365
; op1 - Requested port index
2366
; op2 - size of port array (constant)
2367
; op3 - base index of port array (constant)
2368
 
2369
(define_expand "commsArrayTestPort"
2370
  [(parallel
2371
      [(set (match_operand:HI 0 "register_operand" "")
2372
            (unspec_volatile:HI [(match_operand:HI 1 "general_operand" "")
2373
                              (match_operand:HI 2 "immediate_operand" "")
2374
                              (match_operand:HI 3 "immediate_operand" "")]
2375
                UNSPEC_CALL_TESTPORT_ARRAY))
2376
       (clobber (reg:HI LINK_REGNUM))])]
2377
  ""
2378
  "")
2379
 
2380
;; The actual array testport instruction. When the array index is a constant,
2381
;; an exact instruction may be generated. When the index is variable,
2382
;; a call to a special function is generated. This code could be
2383
;; split into individual RTL instructions, but it is so rarely
2384
;; used, that we won't bother.
2385
(define_insn "*commsArrayTestportInstruction"
2386
  [(set (match_operand:HI 0 "register_operand" "=r,r")
2387
        (unspec_volatile:HI [(match_operand:HI 1 "general_operand" "r,i")
2388
                          (match_operand:HI 2 "immediate_operand" "")
2389
                          (match_operand:HI 3 "immediate_operand" "")]
2390
                UNSPEC_CALL_TESTPORT_ARRAY))
2391
   (clobber (reg:HI LINK_REGNUM))]
2392
  ""
2393
{
2394
  return picochip_output_testport_array (which_alternative, operands);
2395
})
2396
 
2397
;; Merge a TSTPORT instruction with the branch to which it
2398
;; relates.  Often the TSTPORT function (generated by a built-in), is
2399
;; used to control conditional execution.  The normal sequence of
2400
;; instructions would be:
2401
;;    TSTPORT p
2402
;;    COPYSW temp
2403
;;    AND temp, 0x0008, temp
2404
;;    SUB temp,0,discard
2405
;;    BEQ label
2406
;; This can be made more efficient by detecting the special case where
2407
;; the result of a TSTPORT is used to branch, to allow the following
2408
;; RTL sequence to be generated instead:
2409
;;    TSTPORT p
2410
;;    BEQ label
2411
;; A big saving in cycles and bytes!
2412
 
2413
(define_insn_and_split "tstport_branch"
2414
 [(set (pc)
2415
        (if_then_else
2416
            (match_operator 0 "comparison_operator"
2417
                            [(unspec_volatile:HI
2418
                                [(match_operand:HI 1 "const_int_operand" "")]
2419
                                           UNSPEC_TESTPORT)
2420
                             (const_int 0)])
2421
            (label_ref       (match_operand    2 "" ""))
2422
            (pc)))
2423
   (clobber (reg:CC CC_REGNUM))]
2424
 ""
2425
 "#"
2426
 ""
2427
 [(set (reg:CC CC_REGNUM)
2428
       (unspec_volatile:CC [(match_dup 1)] UNSPEC_INTERNAL_TESTPORT))
2429
  (parallel [(set (pc)
2430
                  (if_then_else
2431
                       (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
2432
                                (label_ref (match_dup 2))
2433
                                (pc)))
2434
             (use (match_dup 3))])]
2435
 "{
2436
    /* Note that the sense of the branch is reversed, since we are
2437
     * comparing flag != 0. */
2438
    gcc_assert (GET_CODE(operands[0]) == NE || GET_CODE(operands[0]) == EQ);
2439
    operands[4] = gen_rtx_fmt_ee(reverse_condition(GET_CODE(operands[0])),
2440
                  GET_MODE(operands[0]), XEXP(operands[0], 0), XEXP(operands[0], 1));
2441
    operands[3] = GEN_INT (0);
2442
  }")
2443
 
2444
;;============================================================================
2445
;; Epilogue/Epilogue expansion.
2446
;;============================================================================
2447
 
2448
(define_expand "prologue"
2449
  [(clobber (const_int 0))]
2450
  ""
2451
{
2452
  picochip_expand_prologue ();
2453
  DONE;
2454
})
2455
 
2456
(define_expand "epilogue"
2457
  [(use (const_int 0))]
2458
  ""
2459
{
2460
  picochip_expand_epilogue (FALSE);
2461
  DONE;
2462
})
2463
 
2464
;;============================================================================
2465
;; Trap instruction. This is used to indicate an error. For the
2466
;; picoChip processors this is handled by calling a HALT instruction,
2467
;; which stops the processor.
2468
;;============================================================================
2469
 
2470
(define_insn "trap"
2471
  [(trap_if (const_int 1) (const_int 6))]
2472
  ""
2473
  "HALT\t// (Trap)"
2474
  [(set_attr "length" "2")])
2475
 
2476
;;============================================================================
2477
;; Conditional copy instructions.  Only equal/not-equal comparisons are
2478
;; supported.  All other types of comparison remain as branch
2479
;; sequences.
2480
;;============================================================================
2481
 
2482
;; Define expand seems to consider the resulting two instructions to be
2483
;; independent. It was moving the actual copy instruction further down
2484
;; with a call instruction in between. The call was clobbering the CC
2485
;; and hence the cond_copy was wrong. With a split, it works correctly.
2486
(define_expand "movhicc"
2487
  [(set (reg:CC CC_REGNUM) (match_operand 1 "comparison_operator" ""))
2488
   (parallel [(set (match_operand:HI 0 "register_operand" "=r,r")
2489
                   (if_then_else:HI (match_op_dup:HI 1 [(reg:CC CC_REGNUM) (const_int 0)])
2490
                                 (match_operand:HI 2 "picochip_register_or_immediate_operand" "0,0")
2491
                                 (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))
2492
              (use (match_dup 4))])]
2493
  ""
2494
  {if (!picochip_check_conditional_copy (operands))
2495
     FAIL;
2496
   operands[4] = GEN_INT(GET_CODE(operands[1]));
2497
  })
2498
 
2499
;; We dont do any checks here. But this pattern is used only when movhicc
2500
;; was checked. Put a "use" clause to make sure.
2501
(define_insn "*conditional_copy"
2502
  [(set (match_operand:HI 0 "register_operand" "=r,r")
2503
        (if_then_else:HI
2504
            (match_operator:HI 4 "picochip_peephole_comparison_operator"
2505
                 [(reg:CC CC_REGNUM) (const_int 0)])
2506
         (match_operand:HI 1 "picochip_register_or_immediate_operand" "0,0")
2507
         (match_operand:HI 2 "picochip_register_or_immediate_operand" "r,i")))
2508
   (use (match_operand:HI 3 "const_int_operand" ""))]
2509
  ""
2510
{
2511
 
2512
  gcc_assert (GET_CODE(operands[4]) == EQ || GET_CODE(operands[4]) == NE);
2513
  /* Note that the comparison is reversed as the pattern matches
2514
     the *else* part of the if_then_else */
2515
  switch (GET_CODE(operands[4]))
2516
    {
2517
    case EQ: return "COPYNE %2,%0\t// if (NE) %0 := %2";
2518
    case NE: return "COPYEQ %2,%0\t// if (EQ) %0 := %2";
2519
    default:
2520
      gcc_unreachable();
2521
    }
2522
}
2523
  [(set_attr "length" "2")
2524
   (set_attr "type" "picoAlu,picoAlu")
2525
   (set_attr "longConstant" "false,true")])
2526
 
2527
;;============================================================================
2528
;; Scheduling, including delay slot scheduling.
2529
;;============================================================================
2530
 
2531
(automata_option "v")
2532
(automata_option "ndfa")
2533
 
2534
;; Define each VLIW slot as a CPU resource.  Note the three flavours of
2535
;; branch.  `realBranch' is an actual branch instruction.  `macroBranch'
2536
;; is a directive to the assembler, which may expand into multiple
2537
;; instructions.  `call' is an actual branch instruction, but one which
2538
;; sets the link register, and hence can't be scheduled alongside
2539
;; other instructions which set the link register.  When the DFA
2540
;; scheduler is fixed to prevent it scheduling a JL with an R12
2541
;; setting register, the call type branches can be replaced by
2542
;; realBranch types instead.
2543
 
2544
(define_attr "type"
2545
  "picoAlu,basicAlu,nonCcAlu,mem,call,realBranch,macroBranch,mul,mac,app,comms,unknown"
2546
  (const_string "unknown"))
2547
 
2548
(define_attr "schedType" "none,space,speed"
2549
  (const (symbol_ref "picochip_schedule_type")))
2550
 
2551
;; Define whether an instruction uses a long constant.
2552
 
2553
(define_attr "longConstant"
2554
  "true,false" (const_string "false"))
2555
 
2556
;; Define three EU slots.
2557
(define_query_cpu_unit "slot0,slot1,slot2")
2558
 
2559
;; Pull in the pipeline descriptions for speed or space scheduling.
2560
(include "dfa_speed.md")
2561
(include "dfa_space.md")
2562
 
2563
; Unknown instructions are assumed to take a single cycle, and use all
2564
; slots.  This enables them to actually output a sequence of
2565
; instructions without any limitation.  For the purposes of
2566
; scheduling, unknown instructions are a pain, and should be removed
2567
; completely.  This means that RTL patterns should always be used to
2568
; reduce complex sequences of instructions to individual instructions.
2569
(define_insn_reservation "unknownInsn" 1
2570
  (eq_attr "type" "unknown")
2571
  "(slot0+slot1+slot2)")
2572
 
2573
; Allow any non-branch instructions to be placed in the branch
2574
; slot. Branch slots are always executed.
2575
(define_delay (eq_attr "type" "realBranch,call")
2576
  [(eq_attr "type" "!realBranch,macroBranch,call,unknown") (nil) (nil)])

powered by: WebSVN 2.1.0

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