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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [picochip/] [picochip.md] - Blame information for rev 713

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

Line No. Rev Author Line
1 709 jeremybenn
;; GCC machine description for picochip
2
;; Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
3
;; Contributed by Picochip 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 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
  [(const_int 0)]
565
  "{
566
     rtx const_int_opnd;
567
     const_int_opnd = GEN_INT(GET_CODE(operands[0]));
568
     if (picochip_supported_comparison_operator (operands[0], HImode))
569
       emit_insn (gen_supported_compare (operands[0], operands[1], operands[2]));
570
     else
571
       emit_insn (gen_compare (operands[0], operands[1], operands[2]));
572
     emit_jump_insn (gen_branch (operands[3], const_int_opnd, operands[0]));
573
   }")
574
 
575
;; The only difference between this and the next pattern is that the next pattern
576
;; might introduce subtracts whose first operand is a constant. This would have to
577
;; be a longConstant. But, we know that such a situation wouldnt arise for supported
578
;; comparison operator and hence this pattern assumes that the second constraint combo
579
;; would still generate a normal instruction.
580
 
581
(define_insn "supported_compare"
582
  [(set (reg:CC CC_REGNUM)
583
        (match_operator:CC 0 "picochip_supported_comparison_operator"
584
                        [(match_operand:HI 1 "register_operand" "r,r,r")
585
                         (match_operand:HI 2 "picochip_comparison_operand" "r,J,i")]))]
586
  ""
587
  "* return picochip_output_compare(operands);"
588
  [; Must be picoAlu because it sets the condition flags.
589
   (set_attr "type" "picoAlu,picoAlu,picoAlu")
590
   (set_attr "longConstant" "false,false,true")
591
   (set_attr "length" "2,2,4")
592
   ])
593
 
594
;; This pattern was added to match the previous pattern. When doing if-convert
595
;; the pattern generated using movhicc does not have a eq:CC but only a eq for
596
;; operator. If this pattern were not to be there, Gcc decides not to use
597
;; movhicc at all. Whereas, in Gcc 4.4, it seems to be cleverer.
598
(define_insn "*supported_compare1"
599
  [(set (reg:CC CC_REGNUM)
600
        (match_operator 0 "picochip_supported_comparison_operator"
601
                        [(match_operand:HI 1 "register_operand" "r,r,r")
602
                         (match_operand:HI 2 "picochip_comparison_operand" "r,J,i")]))]
603
  ""
604
  "* return picochip_output_compare(operands);"
605
  [; Must be picoAlu because it sets the condition flags.
606
   (set_attr "type" "picoAlu,picoAlu,picoAlu")
607
   (set_attr "longConstant" "false,false,true")
608
   (set_attr "length" "2,2,4")
609
   ])
610
 
611
(define_insn "compare"
612
  [(set (reg:CC CC_REGNUM)
613
        (match_operator:CC 0 "comparison_operator"
614
                        [(match_operand:HI 1 "register_operand" "r,r,r")
615
                         (match_operand:HI 2 "picochip_comparison_operand" "r,M,i")]))]
616
  ""
617
  "* return picochip_output_compare(operands);"
618
  [; Must be picoAlu because it sets the condition flags.
619
   (set_attr "type" "picoAlu,picoAlu,picoAlu")
620
   (set_attr "longConstant" "false,true,true")
621
   (set_attr "length" "2,4,4")
622
   ])
623
 
624
; Match a branch instruction, created from a tstport/cbranch split.
625
; We use a "use" clause so GCC doesnt try to use this pattern generally.
626
(define_insn "branch"
627
  [(set (pc)
628
        (if_then_else
629
            (match_operator 2 "comparison_operator"
630
                 [(reg:CC CC_REGNUM) (const_int 0)])
631
                      (label_ref (match_operand 0 "" ""))
632
                      (pc)))
633
   (use (match_operand:HI 1 "const_int_operand" ""))]
634
  ""
635
  "* return picochip_output_branch(operands, insn);"
636
  [(set (attr "length")
637
        (if_then_else
638
         (and (ge (minus (match_dup 0) (pc)) (const_int MIN_BRANCH_OFFSET))
639
              (le (minus (match_dup 0) (pc)) (const_int MAX_BRANCH_OFFSET)))
640
         (const_int SHORT_BRANCH_LENGTH)
641
         (const_int LONG_BRANCH_LENGTH)))
642
    (set (attr "type")
643
        (if_then_else
644
         (eq_attr "length" "6")
645
         (const_string "realBranch")
646
         (const_string "unknown")))])
647
 
648
;; If a movqi is used which accesses memory on a machine which doesn't
649
;; have byte addressing, synthesise the instruction using word load/store
650
;; operations. The movqi's that are required during reload phase are
651
;; handled using reload_inqi/reload_outqi.
652
 
653
(define_expand "movqi"
654
  [(set (match_operand:QI 0 "nonimmediate_operand" "")
655
        (match_operand:QI 1 "general_operand" ""))]
656
  ""
657
{
658
 
659
     if (!reload_completed &&
660
         !TARGET_HAS_BYTE_ACCESS &&
661
         (MEM == GET_CODE(operands[0]) || MEM == GET_CODE(operands[1])))
662
     {
663
       rtx address;
664
       rtx wordAddress;
665
       rtx const1;
666
       rtx shiftVal;
667
       rtx loadedValue;
668
       rtx addressMask;
669
       rtx topByteValue;
670
       rtx signExtendedValue;
671
 
672
 
673
       warn_of_byte_access();
674
 
675
       /* Load the constant 1 into a register. */
676
       const1 = gen_reg_rtx(HImode);
677
       emit_insn(gen_rtx_SET(HImode, const1, GEN_INT(1)));
678
 
679
       /* Load the address mask with the bitwise complement of 1. */
680
       addressMask = gen_reg_rtx(HImode);
681
       emit_insn(gen_rtx_SET(HImode, addressMask, GEN_INT(-2)));
682
 
683
       /* Handle loads first, in case we are dealing with a mem := mem
684
        * instruction. */
685
       if (MEM == GET_CODE(operands[1]))
686
       {
687
         /* Loads work as follows. The entire word containing the desired byte
688
          * is loaded. The bottom bit of the address indicates which
689
          * byte is required. The desired byte is moved into the most
690
          * significant byte, and then an arithmetic shift right
691
          * invoked to achieve sign extension. The desired byte is
692
          * moved to the MSB by XOR'ing the bottom address bit by 1,
693
          * multiplying the result by 8, and then shifting left by
694
          * that amount. Note that shifts only operate on the bottom
695
          * 4-bits of the source offset, so although the XOR may
696
          * produce a value which has its upper bits set, only bit 4
697
          * (i.e., the inverted, shifted bottom address bit) actually
698
          * gets used.
699
          */
700
 
701
         /* Ensure the address is in a register. */
702
         address = gen_reg_rtx(HImode);
703
         emit_insn(gen_rtx_SET(HImode, address, XEXP(operands[1], 0)));
704
 
705
         /* Compute the word address by masking out the bottom bit. */
706
         wordAddress = gen_reg_rtx(HImode);
707
         emit_insn(gen_andhi3(wordAddress, address, addressMask));
708
 
709
         /* Compute the shift value. This is the bottom address bit,
710
          * inverted, and multiplied by 8. */
711
         shiftVal = gen_reg_rtx(HImode);
712
         emit_insn(gen_xorhi3(shiftVal, address, const1));
713
         emit_insn(gen_ashlhi3(shiftVal, shiftVal, GEN_INT(3)));
714
 
715
         /* Emit the memory load. */
716
         loadedValue = gen_reg_rtx(HImode);
717
         emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress)));
718
 
719
         /* Shift the desired byte to the most significant byte. */
720
         topByteValue = gen_reg_rtx (HImode);
721
         emit_insn (gen_ashlhi3 (topByteValue, loadedValue, shiftVal));
722
 
723
         /* Sign extend the top-byte back into the bottom byte. */
724
         signExtendedValue = gen_reg_rtx(HImode);
725
         emit_insn(gen_ashrhi3(signExtendedValue, topByteValue, GEN_INT(8)));
726
 
727
         /* Final extraction of QI mode register. */
728
        operands[1] = gen_rtx_SUBREG(QImode, signExtendedValue, 0);
729
 
730
       }
731
 
732
       if (MEM == GET_CODE(operands[0]) && GET_CODE(operands[1]) != MEM)
733
       {
734
         rtx zeroingByteMask;
735
         rtx temp;
736
         rtx tempHiMode;
737
         rtx lsbByteMask;
738
 
739
         /* Get the address. */
740
         address = gen_reg_rtx(HImode);
741
         emit_insn(gen_rtx_SET(HImode, address, XEXP(operands[0], 0)));
742
 
743
         /* Compute the word aligned address. */
744
         wordAddress = gen_reg_rtx(HImode);
745
         emit_insn(gen_andhi3(wordAddress, address, addressMask));
746
 
747
         /* Compute the shift value. */
748
         shiftVal = gen_reg_rtx(HImode);
749
         emit_insn(gen_andhi3(shiftVal, address, const1));
750
         emit_insn(gen_ashlhi3(shiftVal, shiftVal, GEN_INT(3)));
751
 
752
         /* Emit the memory load. */
753
         loadedValue = gen_reg_rtx(HImode);
754
         emit_insn(gen_rtx_SET(HImode, loadedValue, gen_rtx_MEM(HImode, wordAddress)));
755
 
756
         /* Zero out the destination bits by AND'ing with 0xFF00
757
          * shifted appropriately. */
758
         zeroingByteMask = gen_reg_rtx(HImode);
759
         emit_insn(gen_rtx_SET(HImode, zeroingByteMask, GEN_INT(-256)));
760
         emit_insn(gen_lshrhi3(zeroingByteMask, zeroingByteMask, shiftVal));
761
         emit_insn(gen_andhi3(loadedValue, loadedValue, zeroingByteMask));
762
 
763
         /* Grab the incoming QI register, and ensure that the top bits
764
          * are zeroed out. This is because the register may be
765
          * storing a signed value, in which case the top-bits will be
766
          * sign bits. These must be removed to ensure that the
767
          * read-modify-write (which uses an OR) doesn't pick up those
768
          * bits, instead of the original memory value which is being
769
          * modified.
770
          */
771
         tempHiMode = simplify_gen_subreg(HImode, operands[1], QImode, 0);
772
         temp = gen_reg_rtx(HImode);
773
         emit_insn(gen_rtx_SET(HImode, temp, tempHiMode));
774
         lsbByteMask = gen_reg_rtx (HImode);
775
         emit_insn (gen_rtx_SET (HImode, lsbByteMask, GEN_INT (0xFF)));
776
         emit_insn (gen_andhi3 (temp, temp, lsbByteMask));
777
 
778
         /* Shift the incoming byte value by the appropriate amount,
779
          * and OR into the load value. */
780
         emit_insn(gen_ashlhi3(temp, temp, shiftVal));
781
         emit_insn(gen_iorhi3(loadedValue, loadedValue, temp));
782
 
783
         /* Rewrite the original assignment, to assign the new value
784
          * to the word address. */
785
         operands[0] = gen_rtx_MEM(HImode, wordAddress);
786
         operands[1] = loadedValue;
787
 
788
       }
789
 
790
     }
791
})
792
 
793
(define_insn "*movqi_sign_extend"
794
  [(set (match_operand:HI 0 "register_operand" "=r,r")
795
        (sign_extend:HI (match_operand:QI 1 "memory_operand" "a,m")))]
796
  "TARGET_HAS_BYTE_ACCESS"
797
  "@
798
     LDB (%a1),%0\t\t// %0 = Mem(%a1)
799
     LDB %a1,%0\t\t// %0 = Mem(%M1{byte})"
800
  [(set_attr "type" "mem,mem")
801
   (set_attr "longConstant" "true,false")
802
   (set_attr "length" "4,4")])
803
 
804
;; movqi instructions for machines with and without byte access.
805
(define_insn "*movqi_byte"
806
  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,r,a,m")
807
        (match_operand:QI 1 "general_operand" "r,a,m,I,i,r,r"))]
808
  "TARGET_HAS_BYTE_ACCESS"
809
  "@
810
     COPY.%# %1, %0\t// %0 := %1
811
     LDB (%a1),%0\t\t// %0 = Mem(%a1)
812
     LDB %a1,%0\t\t// %0 = Mem(%M1{byte})
813
     COPY.%# %1,%0\t\t// %0 := #%1 (QI) (short constant)
814
     COPY.%# %1,%0\t\t// %0 := #%1 (QI) (long constant)
815
     STB %1,(%a0)\t\t// Mem(%a0) := %1
816
     STB %1,%a0\t\t// Mem(%M0{byte}) := %1"
817
  [(set_attr "type" "basicAlu,mem,mem,basicAlu,basicAlu,mem,mem")
818
   (set_attr "longConstant" "false,true,false,false,true,true,false")
819
   (set_attr "length" "2,4,4,2,4,4,4")])
820
 
821
;; Machines which don't have byte access can copy registers, and load
822
;; constants, but can't access memory.  The define_expand for movqi
823
;; should already have rewritten memory accesses using word
824
;; operations.  The exception is qi reloads, which are handled using
825
;; the reload_? patterns.
826
(define_insn "*movqi_nobyte"
827
  [(set (match_operand:QI 0 "register_operand" "=r,r")
828
        (match_operand:QI 1 "picochip_register_or_immediate_operand" "r,i"))]
829
  "!TARGET_HAS_BYTE_ACCESS"
830
  "@
831
     COPY.%# %1,%0\t// %0 := %1
832
     COPY.%# %1,%0\t\t// %0 := #%1 (QI)")
833
 
834
(define_insn "movhi"
835
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,a,m,r,r")
836
        (match_operand:HI 1 "general_operand" "r,a,m,r,r,I,i"))]
837
  ""
838
  "@
839
    COPY.%# %1,%0\t\t// %0 := %1
840
    LDW (%a1),%0\t\t// %0 := Mem(%a1)
841
    LDW %a1,%0\t\t// %0 = Mem(%M1{byte})
842
    STW %1,(%a0)\t\t// Mem(%a0) := %1
843
    STW %1,%a0\t\t// Mem(%M0{byte}) := %1
844
    COPY.%# %1,%0\t// %0 := %1 (short constant)
845
    COPY.%# %1,%0\t// %0 := %1 (long constant)"
846
   [(set_attr "type" "basicAlu,mem,mem,mem,mem,basicAlu,basicAlu")
847
    (set_attr "longConstant" "false,true,false,true,false,false,true")
848
    (set_attr "length" "2,4,4,4,4,2,4")])
849
 
850
(define_insn "movsi"
851
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,a,m")
852
        (match_operand:SI 1 "general_operand" "r,a,m,i,r,r"))]
853
  ""
854
  "@
855
    // %R0 := %R1 (SI)\n\tCOPY.%# %L1,%L0 %| COPY.1 %U1,%U0
856
    LDL (%a1),%R0\t\t// %R0 = Mem(%a1)
857
    LDL %a1,%R0\t\t// %R0 = Mem(%M1{byte})
858
    // %R0 := #%1 (SI)\n\tCOPY.%# %L1,%L0 %| COPY.%# %U1,%U0
859
    STL %R1,(%a0)\t\t// Mem(%a0) := %R1
860
    STL %R1,%a0\t\t// Mem(%M0{byte}) := %R1"
861
  [(set_attr "type" "unknown,mem,mem,unknown,mem,mem")
862
   (set_attr "longConstant" "false,true,false,true,false,false")
863
   (set_attr "length" "4,4,4,6,4,4")])
864
 
865
; Split an SI mode register copy into separate HI mode copies, which
866
; can be VLIW'd with other instructions.  Only split the instruction
867
; when VLIW scheduling is enabled.  Splitting the instruction saves
868
; some code space.
869
;
870
; This is predicated in reload_completed.  This ensures that the
871
; instructions aren't broken up too early which can result in the
872
; SImode code being converted into inefficient HI mode code.
873
 
874
(define_split
875
  [(set (match_operand:SI 0 "register_operand" "")
876
        (match_operand:SI 1 "register_operand" ""))]
877
  "reload_completed && picochip_schedule_type == DFA_TYPE_SPEED"
878
  [(set (match_dup 2) (match_dup 3))
879
   (set (match_dup 4) (match_dup 5))]
880
  "{
881
     operands[2] = gen_lowpart (HImode, operands[0]);
882
     operands[3] = gen_lowpart (HImode, operands[1]);
883
     operands[4] = gen_highpart (HImode, operands[0]);
884
     operands[5] = gen_highpart (HImode, operands[1]);
885
 }")
886
 
887
; SI Mode split for load constant.
888
(define_split
889
  [(set (match_operand:SI 0 "register_operand" "")
890
        (match_operand:SI 1 "const_int_operand" ""))]
891
  "reload_completed"
892
  [(set (match_dup 2) (match_dup 3))
893
   (set (match_dup 4) (match_dup 5))]
894
  "{
895
     operands[2] = gen_lowpart (HImode, operands[0]);
896
     operands[3] = picochip_get_low_const(operands[1]);
897
     operands[4] = gen_highpart (HImode, operands[0]);
898
     operands[5] = picochip_get_high_const(operands[1]);
899
 }")
900
 
901
(define_insn "movsf"
902
  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,m")
903
        (match_operand:SF 1 "general_operand" "r,m,i,r"))]
904
  ""
905
  "@
906
    // %R0 := %R1 (SF)\n\tCOPY.%# %L1,%L0 %| COPY.1 %U1,%U0
907
    LDL %a1,%R0\t\t// %R0 :={SF} Mem(%M1{byte})
908
    // %R0 := #%1 (SF)\n\tCOPY.%# %L1,%L0\n\tCOPY.%# %U1,%U0
909
    STL %R1,%a0\t\t// Mem(%M0{byte}) :={SF} %R1")
910
 
911
;; memcpy pattern
912
;; 0 = destination (mem:BLK ...)
913
;; 1 = source (mem:BLK ...)
914
;; 2 = count
915
;; 3 = alignment
916
(define_expand "movmemhi"
917
  [(match_operand 0 "memory_operand" "")
918
  (match_operand 1 "memory_operand" "")
919
  (match_operand:HI 2 "immediate_operand" "")
920
  (match_operand 3 "" "")]
921
  "picochip_schedule_type != DFA_TYPE_NONE"
922
  "if (picochip_expand_movmemhi(operands)) DONE; FAIL;"
923
)
924
 
925
;;===========================================================================
926
;; NOP
927
;;===========================================================================
928
 
929
;; No-operation (NOP)
930
(define_insn "nop"
931
  [(const_int 0)]
932
  ""
933
  "NOP\t// nop"
934
  [(set_attr "length" "1")])
935
 
936
;;===========================================================================
937
;; Function Calls.  Define expands are used to ensure that the correct
938
;; type of pattern is emitted, and then the define_insn's match the
939
;; pattern using the correct types.
940
;;
941
;; Note: The comments output as part of these instructions are detected by
942
;; the linker. Don't change the comments!
943
;;===========================================================================
944
 
945
(define_expand "call"
946
  [(parallel [(call (match_operand:QI 0 "memory_operand" "")
947
         (match_operand 1 "const_int_operand" ""))
948
         (clobber (reg:HI LINK_REGNUM))])]
949
  ""
950
  "")
951
 
952
(define_insn "call_for_divmod"
953
  [(call (match_operand:QI 0 "memory_operand" "")
954
         (match_operand 1 "const_int_operand" ""))]
955
  ""
956
  "JL (%M0)\t// fn_call %M0%>"
957
  [(set_attr "length" "4")
958
   (set_attr "type" "realBranch")
959
   (set_attr "longConstant" "true")])
960
 
961
(define_insn "*call_using_symbol"
962
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
963
         (match_operand 1 "const_int_operand" ""))
964
         (clobber (reg:HI LINK_REGNUM))]
965
  ""
966
  "JL (%M0)\t// fn_call %M0%>"
967
  [(set_attr "length" "4")
968
   (set_attr "type" "realBranch")
969
   (set_attr "longConstant" "true")])
970
 
971
(define_insn "*call_using_register"
972
  [(call (mem:QI (match_operand:HI 0 "register_operand" "r"))
973
         (match_operand 1 "const_int_operand" ""))
974
         (clobber (reg:HI LINK_REGNUM))]
975
  ""
976
  "JL (%r0)\t// fn_call_unknown %r0%>"
977
  [(set_attr "length" "2")
978
   (set_attr "type" "realBranch")
979
   (set_attr "longConstant" "false")])
980
 
981
(define_expand "call_value"
982
  [(parallel [(set (match_operand:HI       0 "" "")
983
        (call:HI (match_operand:QI 1 "memory_operand" "g")
984
              (match_operand 2 "const_int_operand" "")))
985
         (clobber (reg:HI LINK_REGNUM))])]
986
  ""
987
  "")
988
 
989
(define_insn "*call_value_using_symbol"
990
  [(set (match_operand:HI 0 "" "")
991
        (call:HI (mem:QI (match_operand:HI 1 "immediate_operand" "i"))
992
              (match_operand 2 "const_int_operand" "")))
993
         (clobber (reg:HI LINK_REGNUM))]
994
  ""
995
  "JL (%M1)\t// fn_call %M1 (value return)%>"
996
  [(set_attr "length" "4")
997
   (set_attr "type" "realBranch")
998
   (set_attr "longConstant" "true")])
999
 
1000
(define_insn "*call_value_using_register"
1001
  [(set (match_operand:HI 0 "" "")
1002
        (call:HI (mem:QI (match_operand:HI 1 "register_operand" "r"))
1003
              (match_operand 2 "const_int_operand" "")))
1004
         (clobber (reg:HI LINK_REGNUM))]
1005
  ""
1006
  "JL (%r1)// fn_call_unknown %r1 (value return)%>"
1007
  [(set_attr "length" "2")
1008
   (set_attr "type" "realBranch")
1009
   (set_attr "longConstant" "false")])
1010
 
1011
;;===========================================================================
1012
;; Addition
1013
;;===========================================================================
1014
 
1015
;; Note that the addition of a negative value is transformed into the
1016
;; subtraction of a positive value, so that the add/sub immediate slot
1017
;; can make better use of the 4-bit range.
1018
 
1019
(define_insn "addhi3"
1020
  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1021
        (plus:HI (match_operand:HI 1 "register_operand" "r,r,r,r")
1022
                 (match_operand:HI 2 "general_operand" "r,M,n,i")))
1023
   (clobber (reg:CC CC_REGNUM))]
1024
  ""
1025
  {  if (CONST_INT == GET_CODE(operands[2]) &&
1026
         INTVAL(operands[2]) > -16 &&
1027
         INTVAL(operands[2]) < 0)
1028
       return "SUB.%# %1,-(%2),%0\t// %0 := %1 + %2 (HI)";
1029
     else
1030
       return "ADD.%# %1,%2,%0\t// %0 := %1 + %2 (HI)";
1031
  }
1032
  [(set_attr "type" "basicAlu,basicAlu,basicAlu,basicAlu")
1033
   (set_attr "longConstant" "false,false,true,true")
1034
   (set_attr "length" "2,2,4,4")]
1035
  )
1036
 
1037
 
1038
;; If we peepholed the compare instruction out, we need to make sure the add
1039
;; goes in slot 0. This pattern is just to accomplish that.
1040
 
1041
(define_insn "addhi3_with_use_clause"
1042
  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1043
        (plus:HI (match_operand:HI 1 "register_operand" "r,r,r,r")
1044
                 (match_operand:HI 2 "general_operand" "r,M,n,i")))
1045
   (set (reg:CC CC_REGNUM)
1046
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
1047
                        [(const_int 0)
1048
                         (const_int 0)]))]
1049
  ""
1050
  {  if (CONST_INT == GET_CODE(operands[2]) &&
1051
         INTVAL(operands[2]) > -16 &&
1052
         INTVAL(operands[2]) < 0)
1053
       return "SUB.0 %1,-(%2),%0\t// %0 := %1 + %2 (HI)";
1054
     else
1055
       return "ADD.0 %1,%2,%0\t// %0 := %1 + %2 (HI)";
1056
  }
1057
  [(set_attr "type" "picoAlu,picoAlu,picoAlu,picoAlu")
1058
   (set_attr "longConstant" "false,false,true,true")
1059
   (set_attr "length" "2,2,4,4")]
1060
  )
1061
 
1062
;; Match an addition in which the first operand has been shifted
1063
;; (e.g., the comms array functions can emit such instructions).
1064
(define_insn "*addWith1stOpShift"
1065
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1066
        (plus:HI (ashift:HI (match_operand:HI 1 "register_operand" "r,r")
1067
                            (match_operand:HI 2 "const_int_operand" ""))
1068
                 (match_operand:HI 3 "immediate_operand" "I,i")))
1069
   (clobber (reg:CC CC_REGNUM))]
1070
  ""
1071
  "ADD.0 [LSL %1,%2],%3,%0\t// %0 := (%1 << %2) + %3"
1072
  [(set_attr "type" "picoAlu,picoAlu")
1073
   (set_attr "longConstant" "false,true")])
1074
 
1075
(define_insn_and_split "addsi3"
1076
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1077
        (plus:SI (match_operand:SI 1 "register_operand" "r,r")
1078
                 (match_operand:SI 2 "general_operand" "r,i")))
1079
   (clobber (reg:CC CC_REGNUM))]
1080
  ""
1081
  "// %0 := %1 + %2 (SI)\n\tADD.0 %L1,%L2,%L0\n\tADDC.0 %U1,%U2,%U0"
1082
  "reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1083
  [(match_dup 4)
1084
   (match_dup 5)]
1085
  "
1086
{
1087
  rtx op0_high = gen_highpart (HImode, operands[0]);
1088
  rtx op1_high = gen_highpart (HImode, operands[1]);
1089
  rtx op0_low  = gen_lowpart (HImode, operands[0]);
1090
  rtx op1_low  = gen_lowpart (HImode, operands[1]);
1091
  rtx op2_high, op2_low;
1092
 
1093
  if (CONST_INT == GET_CODE(operands[2]))
1094
  {
1095
    op2_high = picochip_get_high_const(operands[2]);
1096
    op2_low = picochip_get_low_const(operands[2]);
1097
  } else {
1098
    op2_high = gen_highpart (HImode, operands[2]);
1099
    op2_low  = gen_lowpart (HImode, operands[2]);
1100
  }
1101
 
1102
  operands[4] = gen_add_multi_lower (op0_low, op1_low, op2_low);
1103
  operands[5] = gen_add_multi_upper (op0_high, op1_high, op2_high);
1104
 
1105
}")
1106
 
1107
;; Perform the lowest part of a multi-part addition (SI/DI). This sets
1108
;; the flags, so is an picoAlu instruction (we could use a
1109
;; conventional addhi, but the addhi is better off being a treated as
1110
;; a basicAlu instruction, rather than a picoAlu instruction).
1111
(define_insn "add_multi_lower"
1112
  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1113
        (plus:HI (match_operand:HI 1 "register_operand" "r,r,r")
1114
                 (match_operand:HI 2 "general_operand" "r,M,i")))
1115
   (set (reg:CC CC_REGNUM)
1116
        (compare:CC (plus:HI (match_dup 1)
1117
                             (match_dup 2))
1118
                    (const_int 0)))]
1119
  ""
1120
  {  if (CONST_INT == GET_CODE(operands[2]) &&
1121
         INTVAL(operands[2]) > -16 &&
1122
         INTVAL(operands[2]) < 0)
1123
       return "SUB.%# %1,-(%2),%0\t// %0+carry := %1 + %2 (low multi-part)";
1124
     else
1125
       return "ADD.%# %1,%2,%0\t// %0+carry := %1 + %2 (low multi-part)";
1126
  }
1127
  [(set_attr "type" "picoAlu,picoAlu,picoAlu")
1128
   (set_attr "longConstant" "false,false,true")
1129
   (set_attr "length" "2,2,4")])
1130
 
1131
;; Perform the central part of a multi-part addition (DI). This uses
1132
;; the CC register, and also sets the CC register, so needs to be
1133
;; placed in the first ALU slot.  Note that the ADDC must
1134
;; use the long constant to represent immediates.
1135
(define_insn "add_multi_mid"
1136
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1137
        (plus:HI (match_operand:HI 1 "register_operand" "r,r")
1138
                 (plus:HI (match_operand:HI 2 "general_operand" "r,i")
1139
                          (reg:CC CC_REGNUM))))
1140
   (set (reg:CC CC_REGNUM)
1141
        (compare:CC (plus:HI (match_dup 1)
1142
                             (match_dup 2))
1143
                    (const_int 0)))]
1144
  ""
1145
  "ADDC.%# %1,%2,%0\t// %0+carry := carry + %1 + %2 (mid multi-part)"
1146
  [(set_attr "type" "picoAlu,picoAlu")
1147
   (set_attr "longConstant" "false,true")
1148
   (set_attr "length" "2,4")])
1149
 
1150
;; Perform the highest part of a multi-part addition (SI/DI). This
1151
;; uses the CC register, but doesn't require any registers to be set,
1152
;; so may be scheduled in either of the ALU's.  Note that the ADDC must
1153
;; use the long constant to represent immediates.
1154
(define_insn "add_multi_upper"
1155
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1156
        (plus:HI (match_operand:HI 1 "register_operand" "r,r")
1157
                 (plus:HI (match_operand:HI 2 "general_operand" "r,i")
1158
                          (reg:CC CC_REGNUM))))
1159
   (clobber (reg:CC CC_REGNUM))]
1160
  ""
1161
  "ADDC.%# %1,%2,%0\t// %0 := carry + %1 + %2 (high multi-part)"
1162
  [(set_attr "type" "basicAlu,basicAlu")
1163
   (set_attr "longConstant" "false,true")
1164
   (set_attr "length" "2,4")])
1165
 
1166
;; The lea instruction is a special type of add operation, which looks
1167
;; like a movhi (reg := address). It expands into reg := fp +
1168
;; offset.  Ideally there should be two variants, which take different
1169
;; sized offsets (i.e., using the long constant, or not, as
1170
;; appropriate).  However, the address operand may have arbitrary
1171
;; values added to it later (i.e., the AP will be eliminated, possibly
1172
;; converting a small offset into a long offset), so a long offset is
1173
;; always assumed.
1174
 
1175
;; Note that the lea can use an addition, and hence may modify the CC
1176
;; register.  This upsets scheduling, so instead the lea is placed in
1177
;; ALU 1 where it cannot modify CC.
1178
 
1179
(define_insn "*lea_add"
1180
 [(set (match_operand:HI 0 "nonimmediate_operand" "=r")
1181
       (plus:HI (match_operand:HI 1 "register_operand" "r")
1182
                (match_operand:HI 2 "immediate_operand" "i")))]
1183
 ""
1184
 "ADD.1 %1,%2,%0\t// lea (add)")
1185
 
1186
;; Note that, though this instruction looks similar to movhi pattern,
1187
;; "p" constraint cannot be specified for operands other than
1188
;; address_operand, hence the extra pattern below.
1189
(define_insn "*lea_move"
1190
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r")
1191
        (match_operand:HI 1 "address_operand" "p"))]
1192
  ""
1193
  {
1194
    if (REG == GET_CODE(operands[1]))
1195
      return "COPY.1 %1,%0\t// %0 := %1 (lea)";
1196
    else
1197
      return "ADD.1 %b1,%o1,%0\t\t// %0 := %b1 + %o1 (lea)";
1198
  }
1199
  [(set_attr "type" "nonCcAlu")
1200
   (set_attr "longConstant" "true")
1201
   (set_attr "length" "4")])
1202
 
1203
 
1204
;;===========================================================================
1205
;; Subtraction.  Note that these patterns never take immediate second
1206
;; operands, since those cases are handled by canonicalising the
1207
;; instruction into the addition of a negative costant.
1208
;; But, if the first operand needs to be a negative constant, it
1209
;; is supported here.
1210
;;===========================================================================
1211
 
1212
(define_insn "subhi3"
1213
  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1214
        (minus:HI (match_operand:HI 1 "general_operand" "r,I,i")
1215
                  (match_operand:HI 2 "register_operand" "r,r,r")))
1216
   (clobber (reg:CC CC_REGNUM))]
1217
  ""
1218
  "SUB.%# %1,%2,%0 // %0 := %1 - %2 (HI)"
1219
  [(set_attr "type" "basicAlu,basicAlu,basicAlu")
1220
   (set_attr "longConstant" "false,true,true")
1221
   (set_attr "length" "2,4,4")])
1222
 
1223
;; If we peepholed the compare instruction out, we need to make sure the
1224
;; sub goes in slot 0. This pattern is just to accomplish that.
1225
 
1226
(define_insn "subhi3_with_use_clause"
1227
  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1228
        (minus:HI (match_operand:HI 1 "general_operand" "r,I,i")
1229
                  (match_operand:HI 2 "register_operand" "r,r,r")))
1230
   (set (reg:CC CC_REGNUM)
1231
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
1232
                        [(const_int 0)
1233
                         (const_int 0)]))]
1234
  ""
1235
  "SUB.0 %1,%2,%0 // %0 := %1 - %2 (HI)"
1236
  [(set_attr "type" "picoAlu,picoAlu,picoAlu")
1237
   (set_attr "longConstant" "false,true,true")
1238
   (set_attr "length" "2,4,4")])
1239
 
1240
(define_insn_and_split "subsi3"
1241
  [(set (match_operand:SI 0 "register_operand" "=r,r")
1242
        (minus:SI (match_operand:SI 1 "general_operand" "r,i")
1243
                  (match_operand:SI 2 "register_operand" "r,r")))
1244
   (clobber (reg:CC CC_REGNUM))]
1245
  ""
1246
  "// %0 := %1 - %2 (SI)\n\tSUB.%# %L1,%L2,%L0\n\tSUBB.%# %U1,%U2,%U0"
1247
  "reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1248
  [(match_dup 4)
1249
   (match_dup 5)]
1250
  "
1251
{
1252
  rtx op0_high = gen_highpart (HImode, operands[0]);
1253
  rtx op0_low  = gen_lowpart (HImode, operands[0]);
1254
  rtx op2_high = gen_highpart (HImode, operands[2]);
1255
  rtx op2_low = gen_lowpart (HImode, operands[2]);
1256
  rtx op1_high,op1_low;
1257
 
1258
  if (CONST_INT == GET_CODE(operands[1]))
1259
  {
1260
    op1_high = picochip_get_high_const(operands[1]);
1261
    op1_low = picochip_get_low_const(operands[1]);
1262
  } else {
1263
    op1_high = gen_highpart (HImode, operands[1]);
1264
    op1_low  = gen_lowpart (HImode, operands[1]);
1265
  }
1266
 
1267
 
1268
  operands[4] = gen_sub_multi_lower (op0_low, op1_low, op2_low);
1269
  operands[5] = gen_sub_multi_upper (op0_high, op1_high, op2_high);
1270
 
1271
}")
1272
 
1273
;; Match the patterns emitted by the multi-part subtraction splitting.
1274
;; This sets the CC register, so it needs to go into slot 0.
1275
(define_insn "sub_multi_lower"
1276
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1277
        (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1278
                  (match_operand:HI 2 "register_operand" "r,r")))
1279
   (set (reg:CC CC_REGNUM)
1280
        (compare:CC (minus:HI (match_dup 1) (match_dup 2))
1281
                    (const_int 0)))]
1282
  ""
1283
  "SUB.%# %1,%2,%0\t// %0+carry := %1 - %2 (lower SI)"
1284
  [(set_attr "type" "picoAlu,picoAlu")
1285
   (set_attr "longConstant" "false,true")
1286
   (set_attr "length" "2,4")])
1287
 
1288
;; Perform the central part of a multi-part addition (DI). This uses
1289
;; the CC register, and also sets the CC register, so needs to be
1290
;; placed in the first ALU.
1291
(define_insn "sub_multi_mid"
1292
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1293
        (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1294
                  (minus:HI (match_operand:HI 2 "register_operand" "r,r")
1295
                            (reg:CC CC_REGNUM))))
1296
   (set (reg:CC CC_REGNUM)
1297
        (compare:CC (minus:HI (match_dup 1)
1298
                              (match_dup 2))
1299
                    (const_int 0)))]
1300
  ""
1301
  "SUBB.%# %1,%2,%0\t// %0+carry := carry - %1 - %2 (mid multi-part)"
1302
  [(set_attr "type" "picoAlu,picoAlu")
1303
   (set_attr "longConstant" "false,true")
1304
   (set_attr "length" "2,4")])
1305
 
1306
(define_insn "sub_multi_upper"
1307
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1308
        (minus:HI (match_operand:HI 1 "general_operand" "r,i")
1309
                  (minus:HI (match_operand:HI 2 "register_operand" "r,r")
1310
                            (reg:CC CC_REGNUM))))
1311
   (clobber (reg:CC CC_REGNUM))]
1312
  ""
1313
  "SUBB.%# %1,%2,%0\t// %0 := carry - %1 - %2 (upper SI)"
1314
  [(set_attr "type" "basicAlu,basicAlu")
1315
   (set_attr "longConstant" "false,true")
1316
   (set_attr "length" "2,4")])
1317
 
1318
;;===========================================================================
1319
;; Multiplication (signed)
1320
;;===========================================================================
1321
 
1322
(define_insn "multiply_machi"
1323
  [(set (reg:HI ACC_REGNUM)
1324
        (mult:HI (match_operand:HI 0 "register_operand" "r,r")
1325
                 (match_operand:HI 1
1326
                        "picochip_register_or_immediate_operand" "r,i")))]
1327
  "TARGET_HAS_MAC_UNIT"
1328
  "MUL %0,%1,acc0\t// acc0 := %0 * %1 (signed)"
1329
  [(set_attr "length" "3,5")
1330
   (set_attr "type" "mac,mac")
1331
   (set_attr "longConstant" "false,true")])
1332
 
1333
(define_expand "mulhi3"
1334
  [(set (match_operand:HI 0 "register_operand" "")
1335
        (mult:HI (match_operand:HI 1 "register_operand" "")
1336
                 (match_operand:HI 2 "picochip_register_or_immediate_operand" "")))]
1337
  "TARGET_HAS_MULTIPLY"
1338
  "")
1339
 
1340
;; Different types of mulhi, depending on the AE type. If the AE has MUL unit,
1341
;; use the following pattern.
1342
(define_insn "*mulhi3_mul"
1343
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1344
        (mult:HI (match_operand:HI 1 "register_operand" "r,r")
1345
                 (match_operand:HI 2
1346
                        "picochip_register_or_immediate_operand" "r,i")))]
1347
  "TARGET_HAS_MUL_UNIT"
1348
  "MULL %1,%2,%0 // %0 := %1 * %2 (HI)"
1349
  [(set_attr "length" "3,5")
1350
   (set_attr "type" "mul,mul")
1351
   (set_attr "longConstant" "false,true")])
1352
 
1353
;; If the AE has MAC unit, instead, use the following pattern.
1354
(define_insn_and_split "*mulhi3_mac"
1355
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1356
        (mult:HI (match_operand:HI 1 "register_operand" "r,r")
1357
                 (match_operand:HI 2
1358
                        "picochip_register_or_immediate_operand" "r,i")))]
1359
  "TARGET_HAS_MAC_UNIT"
1360
  "// %0 := %1 * %2\n\tMUL %1,%2,acc0\n\tREADACC acc0,frac,%0"
1361
  "TARGET_HAS_MAC_UNIT && reload_completed"
1362
  [(match_dup 3)
1363
   (match_dup 4)]
1364
  "
1365
{
1366
    rtx const_rtx = GEN_INT(0);
1367
    operands[3] = (gen_multiply_machi(operands[1], operands[2]));
1368
    operands[4] = (gen_movhi_mac(operands[0],const_rtx));
1369
} "
1370
)
1371
 
1372
(define_insn "umultiply_machisi"
1373
  [(set (reg:SI ACC_REGNUM)
1374
        (mult:SI (zero_extend:SI (match_operand:HI 0 "register_operand" "r"))
1375
                 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))))]
1376
  "TARGET_HAS_MAC_UNIT"
1377
  "MULUU %0,%1,acc0\t// acc0 := %0 * %1 (unsigned)"
1378
  [(set_attr "length" "3")
1379
   (set_attr "type" "mac")
1380
   (set_attr "longConstant" "false")])
1381
 
1382
(define_insn "multiply_machisi"
1383
  [(set (reg:SI ACC_REGNUM)
1384
        (mult:SI (sign_extend:SI (match_operand:HI 0 "register_operand" "r,r"))
1385
                 (sign_extend:SI (match_operand:HI 1
1386
                        "picochip_register_or_immediate_operand" "r,i"))))]
1387
  "TARGET_HAS_MAC_UNIT"
1388
  "MUL %0,%1,acc0\t// acc0 := %0 * %1 (signed)"
1389
  [(set_attr "length" "3,5")
1390
   (set_attr "type" "mac,mac")
1391
   (set_attr "longConstant" "false,true")])
1392
 
1393
;; We want to prevent GCC from thinking ACC is a normal register and using
1394
;; this pattern. We want it to be used only when you use MAC unit
1395
;; multiplication. Added a "use" clause for that sake.
1396
(define_insn "movsi_mac"
1397
   [(set (match_operand:SI 0 "register_operand" "=r")
1398
        (reg:SI ACC_REGNUM))
1399
    (use (match_operand:SI 1 "const_int_operand" ""))]
1400
  "TARGET_HAS_MAC_UNIT"
1401
  "READACC32 acc0,%R0 \t// %0 := acc0 "
1402
  [(set_attr "length" "3")
1403
   (set_attr "type" "mac")
1404
   (set_attr "longConstant" "false")])
1405
 
1406
;; We want to prevent GCC from thinking ACC is a normal register and using
1407
;; this pattern. We want it to be used only when you use MAC unit
1408
;; multiplication. Added a "use" clause for that sake.
1409
(define_insn "movhi_mac"
1410
   [(set (match_operand:HI 0 "register_operand" "=r")
1411
        (reg:HI ACC_REGNUM) )
1412
    (use (match_operand:HI 1 "const_int_operand" ""))]
1413
  "TARGET_HAS_MAC_UNIT"
1414
  "READACC acc0,frac,%0 \t// %0 := acc0 "
1415
  [(set_attr "length" "3")
1416
   (set_attr "type" "mac")
1417
   (set_attr "longConstant" "false")])
1418
 
1419
;; 16-bit to 32-bit widening signed multiplication.
1420
(define_expand "mulhisi3"
1421
  [(set (match_operand:SI 0 "register_operand" "=&r")
1422
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1423
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1424
  "TARGET_HAS_MULTIPLY"
1425
  ""
1426
)
1427
 
1428
(define_insn_and_split "*mulhisi3_mul"
1429
  [(set (match_operand:SI 0 "register_operand" "=&r")
1430
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1431
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1432
  "TARGET_HAS_MUL_UNIT"
1433
  "// %0 := %1 * %2 (HI->SI)\;MULL %1,%2,%L0\;MULH %1,%2,%U0";
1434
  "TARGET_HAS_MUL_UNIT && reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1435
  [(match_dup 3)
1436
   (match_dup 4)]
1437
  "
1438
{
1439
  rtx op0_high = gen_highpart (HImode, operands[0]);
1440
  rtx op0_low  = gen_lowpart (HImode, operands[0]);
1441
  operands[3] = gen_mulhisi3_mul_lower(op0_low,operands[1],operands[2]);
1442
  operands[4] = gen_mulhisi3_mul_higher(op0_high,operands[1],operands[2]);
1443
}
1444
  "
1445
)
1446
 
1447
(define_insn "mulhisi3_mul_lower"
1448
  [(set (match_operand:HI 0 "register_operand" "=&r")
1449
        (subreg:HI
1450
         (mult:SI
1451
          (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1452
          (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) 0))]
1453
  "TARGET_HAS_MUL_UNIT"
1454
  "MULL %1,%2,%0"
1455
  [(set_attr "length" "3")
1456
   (set_attr "type" "mul")
1457
   (set_attr "longConstant" "false")])
1458
 
1459
(define_insn "mulhisi3_mul_higher"
1460
  [(set (match_operand:HI 0 "register_operand" "=&r")
1461
        (subreg:HI
1462
         (mult:SI
1463
          (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1464
          (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))) 2))]
1465
  "TARGET_HAS_MUL_UNIT"
1466
  "MULH %1,%2,%0"
1467
  [(set_attr "length" "3")
1468
   (set_attr "type" "mul")
1469
   (set_attr "longConstant" "false")])
1470
 
1471
(define_insn_and_split "*mulhisi3_mac"
1472
  [(set (match_operand:SI 0 "register_operand" "=&r")
1473
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
1474
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1475
  "TARGET_HAS_MAC_UNIT"
1476
  "// %0 := %1 * %2 (HI->SI) STAN2\;MUL %1,%2,acc0\;READACC32 acc0,%R0";
1477
  "TARGET_HAS_MAC_UNIT && reload_completed"
1478
  [(match_dup 3)
1479
   (match_dup 4)]
1480
  "
1481
{
1482
    rtx const_rtx = gen_int_mode(0,SImode);
1483
    operands[3] = (gen_multiply_machisi(operands[1], operands[2]));
1484
    operands[4] = (gen_movsi_mac(operands[0],const_rtx));
1485
} "
1486
)
1487
 
1488
;;===========================================================================
1489
;; Widening multiplication (unsigned)
1490
;;===========================================================================
1491
 
1492
(define_expand "umulhisi3"
1493
  [(set (match_operand:SI 0 "register_operand" "=&r")
1494
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1495
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1496
  "TARGET_HAS_MULTIPLY"
1497
  ""
1498
)
1499
 
1500
(define_insn_and_split "*umulhisi3_mul"
1501
  [(set (match_operand:SI 0 "register_operand" "=&r")
1502
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1503
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1504
  "TARGET_HAS_MUL_UNIT"
1505
  "// %0 := %1 * %2 (uHI->uSI Type 1)\;MULUL %1,%2,%L0\n\tMULUH %1,%2,%U0";
1506
  "TARGET_HAS_MUL_UNIT && reload_completed && picochip_schedule_type != DFA_TYPE_NONE"
1507
  [(match_dup 3)
1508
   (match_dup 4)]
1509
  "
1510
{
1511
  rtx op0_high = gen_highpart (HImode, operands[0]);
1512
  rtx op0_low  = gen_lowpart (HImode, operands[0]);
1513
  operands[3] = gen_umulhisi3_mul_lower(op0_low,operands[1],operands[2]);
1514
  operands[4] = gen_umulhisi3_mul_higher(op0_high,operands[1],operands[2]);
1515
}
1516
  "
1517
  )
1518
 
1519
(define_insn "umulhisi3_mul_lower"
1520
  [(set (match_operand:HI 0 "register_operand" "=&r")
1521
        (subreg:HI
1522
         (mult:SI
1523
          (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1524
          (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))) 0))]
1525
  "TARGET_HAS_MUL_UNIT"
1526
  "MULUL %1,%2,%0"
1527
  [(set_attr "length" "3")
1528
   (set_attr "type" "mul")
1529
   (set_attr "longConstant" "false")])
1530
 
1531
(define_insn "umulhisi3_mul_higher"
1532
  [(set (match_operand:HI 0 "register_operand" "=&r")
1533
        (subreg:HI
1534
         (mult:SI
1535
          (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1536
          (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))) 2))]
1537
  "TARGET_HAS_MUL_UNIT"
1538
  "MULUH %1,%2,%0"
1539
  [(set_attr "length" "3")
1540
   (set_attr "type" "mul")
1541
   (set_attr "longConstant" "false")])
1542
 
1543
(define_insn_and_split "*umulhisi3_mac"
1544
  [(set (match_operand:SI 0 "register_operand" "=&r")
1545
        (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1546
                 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1547
  "TARGET_HAS_MAC_UNIT"
1548
  "// %0 := %1 * %2 (uHI->uSI Type 3)\;MULUU %1,%2,acc0\;READACC32 acc0,%R0";
1549
  "TARGET_HAS_MAC_UNIT && reload_completed"
1550
  [(match_dup 3)
1551
   (match_dup 4)]
1552
  "
1553
{
1554
    rtx const_rtx = gen_int_mode(0,SImode);
1555
    operands[3] = (gen_umultiply_machisi(operands[1], operands[2]));
1556
    operands[4] = (gen_movsi_mac(operands[0],const_rtx));
1557
} "
1558
)
1559
 
1560
;;===========================================================================
1561
;; Division (signed)
1562
;;===========================================================================
1563
 
1564
;; Perform a divmod operation as a function call.  This results in some
1565
;; registers being clobbered (r0-6, r12 - ignore r13,14 as these are
1566
;; known not to be affected).
1567
(define_expand "divmodhi4"
1568
  [
1569
   ; Copy the inputs to r0 and r1.
1570
   (set (reg:HI 0) (match_operand:HI 1 "register_operand" ""))
1571
   (set (reg:HI 1) (match_operand:HI 2 "register_operand" ""))
1572
   ; Make the function call - note that r12 (link) is clobbered. Note also
1573
   ; that an explicit call is generated. This ensures that gcc notices that
1574
   ; any function containing a div/mod is not a leaf function.
1575
   (parallel [(match_dup 4)
1576
              (set (reg:HI 0) (div:HI (reg:HI 0) (reg:HI 1)))
1577
              (set (reg:HI 1) (mod:HI (reg:HI 0) (reg:HI 1)))
1578
              (clobber (reg:HI 2))
1579
              (clobber (reg:HI 3))
1580
              (clobber (reg:HI 4))
1581
              (clobber (reg:HI 5))
1582
              (clobber (reg:HI 12))
1583
              (clobber (reg:CC CC_REGNUM))
1584
              ])
1585
   ; Set the quotient (returned in register 0)
1586
   (set (match_operand:HI 0 "register_operand" "") (reg:HI 0))
1587
   ; Set the remainder (returned in register 1)
1588
   (set (match_operand:HI 3 "register_operand" "") (reg:HI 1))]
1589
  ""
1590
{
1591
  rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_divmodhi4");
1592
  operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1593
})
1594
 
1595
; Match a call to divmodhi4.  As this is a call, the link register
1596
; (r12), and registers r0-5 must be clobbered.  Ignore clobbering of
1597
; r13/4 as these aren't used by the divide function).
1598
(define_insn "*divmodhi4_call"
1599
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1600
         (match_operand 1 "const_int_operand" ""))
1601
   (set (reg:HI 0) (div:HI (reg:HI 0) (reg:HI 1)))
1602
   (set (reg:HI 1) (mod:HI (reg:HI 0) (reg:HI 1)))
1603
   (clobber (reg:HI 2))
1604
   (clobber (reg:HI 3))
1605
   (clobber (reg:HI 4))
1606
   (clobber (reg:HI 5))
1607
   (clobber (reg:HI 12))
1608
   (clobber (reg:CC CC_REGNUM))
1609
]
1610
  ""
1611
  "JL (%0)\t// call %0%>"
1612
  [(set_attr "length" "4")
1613
   (set_attr "longConstant" "true")
1614
   (set_attr "type" "call")])
1615
 
1616
;; Perform a udivmod operation as a function call.  This results in some
1617
;; registers being clobbered (r0-6, r12 - ignore r13,14 as these are
1618
;; known not to be affected).
1619
(define_expand "udivmodhi4"
1620
  [
1621
   ; Copy the inputs to r0 and r1.
1622
   (set (reg:HI 0) (match_operand:HI 1 "register_operand" ""))
1623
   (set (reg:HI 1) (match_operand:HI 2 "register_operand" ""))
1624
   ; Make the function call - note that r12 (link) is clobbered. Note also
1625
   ; that an explicit call is generated. This ensures that gcc notices that
1626
   ; any function containing a div/mod is not a leaf function.
1627
   (parallel [(match_dup 4)
1628
              (set (reg:HI 0) (udiv:HI (reg:HI 0) (reg:HI 1)))
1629
              (set (reg:HI 1) (umod:HI (reg:HI 0) (reg:HI 1)))
1630
              (clobber (reg:HI 2))
1631
              (clobber (reg:HI 3))
1632
              (clobber (reg:HI 4))
1633
              (clobber (reg:HI 5))
1634
              (clobber (reg:HI 12))
1635
              (clobber (reg:CC CC_REGNUM))
1636
              ])
1637
   ; Set the quotient (returned in register 0)
1638
   (set (match_operand:HI 0 "register_operand" "") (reg:HI 0))
1639
   ; Set the remainder (returned in register 1)
1640
   (set (match_operand:HI 3 "register_operand" "") (reg:HI 1))]
1641
  ""
1642
{
1643
  rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_udivmodhi4");
1644
  operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1645
})
1646
 
1647
; Match a call to udivmodhi4.  As this is a call, the link register
1648
; (r12), and registers r0-5 must be clobbered.  Ignore clobbering of
1649
; r13/4 as these aren't used by the divide function).
1650
(define_insn "*udivmodhi4_call"
1651
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1652
         (match_operand 1 "const_int_operand" ""))
1653
   (set (reg:HI 0) (udiv:HI (reg:HI 0) (reg:HI 1)))
1654
   (set (reg:HI 1) (umod:HI (reg:HI 0) (reg:HI 1)))
1655
   (clobber (reg:HI 2))
1656
   (clobber (reg:HI 3))
1657
   (clobber (reg:HI 4))
1658
   (clobber (reg:HI 5))
1659
   (clobber (reg:HI 12))
1660
   (clobber (reg:CC CC_REGNUM))]
1661
  ""
1662
  "JL (%0)\t// call %0%>"
1663
  [(set_attr "length" "4")
1664
   (set_attr "longConstant" "true")
1665
   (set_attr "type" "call")])
1666
 
1667
(define_expand "udivmodsi4"
1668
  [
1669
   ; Make the function call
1670
   (set (reg:SI 0) (match_operand:SI 1 "register_operand" ""))
1671
   (set (reg:SI 2) (match_operand:SI 2 "register_operand" ""))
1672
   (parallel [
1673
     (match_dup 4)
1674
     (set (reg:SI 4) (udiv:SI (reg:SI 0) (reg:SI 2)))
1675
     (set (reg:SI 6) (umod:SI (reg:SI 0) (reg:SI 2)))
1676
     (clobber (reg:SI 0))
1677
     (clobber (reg:SI 2))
1678
     (clobber (reg:HI 12))
1679
   (clobber (reg:CC CC_REGNUM))])
1680
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 4))
1681
   (set (match_operand:SI 3 "register_operand" "") (reg:SI 6))]
1682
  ""
1683
{
1684
  rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_udivmodsi4");
1685
  operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1686
})
1687
 
1688
(define_insn "*udivmodsi4_call"
1689
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1690
         (match_operand 1 "const_int_operand" ""))
1691
   (set (reg:SI 4) (udiv:SI (reg:SI 0) (reg:SI 2)))
1692
   (set (reg:SI 6) (umod:SI (reg:SI 0) (reg:SI 2)))
1693
   (clobber (reg:SI 0))
1694
   (clobber (reg:SI 2))
1695
   (clobber (reg:HI 12))
1696
   (clobber (reg:CC CC_REGNUM))]
1697
  ""
1698
  "JL (%0)\t// call %0%>"
1699
  [(set_attr "length" "4")
1700
   (set_attr "longConstant" "true")
1701
   (set_attr "type" "call")])
1702
 
1703
(define_expand "divmodsi4"
1704
  [
1705
   ; Make the function call
1706
   (set (reg:SI 0) (match_operand:SI 1 "register_operand" ""))
1707
   (set (reg:SI 2) (match_operand:SI 2 "register_operand" ""))
1708
   (parallel [
1709
     (match_dup 4)
1710
     (set (reg:SI 4) (div:SI (reg:SI 0) (reg:SI 2)))
1711
     (set (reg:SI 6) (mod:SI (reg:SI 0) (reg:SI 2)))
1712
     (clobber (reg:SI 0))
1713
     (clobber (reg:SI 2))
1714
     (clobber (reg:HI 12))
1715
     (clobber (reg:CC CC_REGNUM))])
1716
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 4))
1717
   (set (match_operand:SI 3 "register_operand" "") (reg:SI 6))]
1718
  ""
1719
{
1720
  rtx fnName = gen_rtx_SYMBOL_REF (HImode, "_divmodsi4");
1721
  operands[4] = gen_call_for_divmod (gen_rtx_MEM (QImode, fnName), GEN_INT(0));
1722
})
1723
 
1724
(define_insn "*divmodsi4_call"
1725
  [(call (mem:QI (match_operand:HI 0 "immediate_operand" "i"))
1726
         (match_operand 1 "const_int_operand" ""))
1727
   (set (reg:SI 4) (div:SI (reg:SI 0) (reg:SI 2)))
1728
   (set (reg:SI 6) (mod:SI (reg:SI 0) (reg:SI 2)))
1729
   (clobber (reg:SI 0))
1730
   (clobber (reg:SI 2))
1731
   (clobber (reg:HI 12))
1732
   (clobber (reg:CC CC_REGNUM))]
1733
  ""
1734
  "JL (%0)\t// call %0%>"
1735
  [(set_attr "length" "4")
1736
   (set_attr "longConstant" "true")
1737
   (set_attr "type" "call")])
1738
 
1739
;;===========================================================================
1740
;; Bitwise AND.  The QI/SI mode instructions are automatically
1741
;; synthesised from the HI mode instruction.
1742
;;===========================================================================
1743
 
1744
(define_insn "andhi3"
1745
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1746
        (and:HI (match_operand:HI 1 "register_operand" "r,r")
1747
                (match_operand:HI 2 "general_operand" "r,n")))
1748
   (clobber (reg:CC CC_REGNUM))]
1749
  ""
1750
  "AND.%# %1,%2,%0 // %0 := %1 AND %2 (HI)"
1751
  [(set_attr "type" "basicAlu,basicAlu")
1752
   (set_attr "longConstant" "false,true")
1753
   (set_attr "length" "3,5")])
1754
 
1755
;; If we peepholed the compare instruction out, we need to make sure the
1756
;; "and" goes in slot 0. This pattern is just to accomplish that.
1757
 
1758
(define_insn "andhi3_with_use_clause"
1759
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1760
        (and:HI (match_operand:HI 1 "register_operand" "r,r")
1761
                (match_operand:HI 2 "general_operand" "r,n")))
1762
   (set (reg:CC CC_REGNUM)
1763
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
1764
                        [(const_int 0)
1765
                         (const_int 0)]))]
1766
  ""
1767
  "AND.0 %1,%2,%0 // %0 := %1 AND %2 (HI)"
1768
  [(set_attr "type" "picoAlu,picoAlu")
1769
   (set_attr "longConstant" "false,true")
1770
   (set_attr "length" "3,5")])
1771
 
1772
;;===========================================================================
1773
;; Bitwise inclusive-OR.  The QI mode instruction is automatically
1774
;; synthesised from the HI mode instruction.
1775
;;===========================================================================
1776
 
1777
(define_insn "iorhi3"
1778
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1779
        (ior:HI (match_operand:HI 1 "register_operand" "r,r")
1780
                (match_operand:HI 2 "register_operand" "r,n")))
1781
   (clobber (reg:CC CC_REGNUM))]
1782
  ""
1783
  "OR.%# %1,%2,%0 // %0 := %1 IOR %2 (HI)"
1784
  [(set_attr "type" "basicAlu,basicAlu")
1785
   (set_attr "longConstant" "false,true")
1786
   (set_attr "length" "3,5")])
1787
 
1788
(define_insn "iorhi3_with_use_clause"
1789
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1790
        (ior:HI (match_operand:HI 1 "register_operand" "r,r")
1791
                (match_operand:HI 2 "general_operand" "r,n")))
1792
   (set (reg:CC CC_REGNUM)
1793
        (match_operator:CC 3 "picochip_peephole_comparison_operator"
1794
                        [(const_int 0)
1795
                         (const_int 0)]))]
1796
  ""
1797
  "OR.0 %1,%2,%0 // %0 := %1 IOR %2 (HI)"
1798
  [(set_attr "type" "picoAlu,picoAlu")
1799
   (set_attr "longConstant" "false,true")
1800
   (set_attr "length" "3,5")])
1801
 
1802
;;===========================================================================
1803
;; Bitwise exclusive-OR.  The QI/SI mode instructions are automatically
1804
;; synthesised from the HI mode instruction.
1805
;;===========================================================================
1806
 
1807
(define_insn "xorhi3"
1808
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1809
        (xor:HI (match_operand:HI 1 "register_operand" "r,r")
1810
                (match_operand:HI 2 "picochip_register_or_immediate_operand" "r,n")))
1811
   (clobber (reg:CC CC_REGNUM))]
1812
  ""
1813
  "XOR.%# %1,%2,%0 // %0 := %1 XOR %2 (HI)"
1814
  [(set_attr "type" "basicAlu,basicAlu")
1815
   (set_attr "longConstant" "false,true")
1816
   (set_attr "length" "3,5")])
1817
 
1818
;;===========================================================================
1819
;; Arithmetic shift left.
1820
;;===========================================================================
1821
 
1822
(define_insn "ashlhi3"
1823
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1824
        (ashift:HI (match_operand:HI 1 "register_operand" "r,r")
1825
                (match_operand:HI 2 "general_operand" "r,J")))]
1826
  ""
1827
  "LSL.%# %1,%2,%0 // %0 := %1 << %2"
1828
  [(set_attr "type" "picoAlu,basicAlu")
1829
   (set_attr "length" "3,3")])
1830
 
1831
;;===========================================================================
1832
;; Arithmetic shift right.
1833
;;===========================================================================
1834
 
1835
(define_insn "builtin_asri"
1836
  [(set (match_operand:HI 0 "register_operand" "=r")
1837
        (ashiftrt:HI (match_operand:HI 1 "register_operand" "r")
1838
                     (match_operand:HI 2 "immediate_operand" "")))
1839
   (clobber (reg:CC CC_REGNUM))]
1840
  ""
1841
  "ASR.%# %1,%2,%0\t// %0 = %1 >>{arith} %2"
1842
  [(set_attr "type" "basicAlu")
1843
   (set_attr "length" "3")])
1844
 
1845
;; The picoChip ISA doesn't have a variable arithmetic shift right, so
1846
;; synthesise it.  Shifts by constants are directly supported.
1847
 
1848
(define_expand "ashrhi3"
1849
  [(match_operand:HI 0 "register_operand" "")
1850
   (match_operand:HI 1 "register_operand" "")
1851
   (match_operand:HI 2 "picochip_register_or_immediate_operand" "")]
1852
  ""
1853
{
1854
  if (GET_CODE(operands[2]) == CONST_INT)
1855
    /* Shift by constant is easy. */
1856
    emit_insn (gen_builtin_asri (operands[0], operands[1], operands[2]));
1857
  else
1858
  {
1859
    /* Synthesise a variable shift. */
1860
 
1861
    rtx tmp1;
1862
    rtx tmp2;
1863
    rtx tmp3;
1864
    rtx minus_one;
1865
    rtx tmp4;
1866
 
1867
    /* Fill a temporary with the sign bits. */
1868
    tmp1 = gen_reg_rtx (HImode);
1869
    emit_insn (gen_builtin_asri (tmp1, operands[1], GEN_INT(15)));
1870
 
1871
    /* Shift the unsigned value. */
1872
    tmp2 = gen_reg_rtx (HImode);
1873
    emit_insn (gen_lshrhi3 (tmp2, operands[1], operands[2]));
1874
 
1875
    /* The word of sign bits must be shifted back to the left, to zero
1876
     * out the unwanted lower bits.  The amount to shift left by is (15 -
1877
     * count). Since the shifts are computed modulo 16 (i.e., only the
1878
     * lower 4 bits of the count are used), the shift amount (15 - count)
1879
     * is equivalent to !count. */
1880
    tmp3 = gen_reg_rtx (HImode);
1881
    minus_one = GEN_INT (-1);
1882
    emit_insn (gen_xorhi3 (tmp3, operands[2], minus_one));
1883
    tmp4 = gen_reg_rtx (HImode);
1884
    emit_insn (gen_ashlhi3 (tmp4, tmp1, tmp3));
1885
 
1886
    /* Combine the sign bits with the shifted value. */
1887
    emit_insn (gen_iorhi3 (operands[0], tmp2, tmp4));
1888
 
1889
  }
1890
  DONE;
1891
})
1892
 
1893
;;===========================================================================
1894
;; Logical shift right.
1895
;;===========================================================================
1896
 
1897
(define_insn "lshrhi3"
1898
  [(set (match_operand:HI 0 "register_operand" "=r,r")
1899
        (lshiftrt:HI (match_operand:HI 1 "register_operand" "r,r")
1900
                (match_operand:HI 2 "general_operand" "r,J")))]
1901
  ""
1902
  "LSR.%# %1,%2,%0 // %0 := %1 >> %2"
1903
  [(set_attr "type" "picoAlu,basicAlu")
1904
   (set_attr "length" "3,3")])
1905
 
1906
;;===========================================================================
1907
;; Negate.
1908
;;===========================================================================
1909
 
1910
;; Negations are performed by subtracting from the constant 0, which
1911
;; is loaded into a register.  By using a register containing 0, the
1912
;; chances of being able to CSE with another 0 value are increased.
1913
 
1914
(define_expand "neghi2"
1915
  [(set (match_dup 2) (match_dup 3))
1916
   (parallel [(set (match_operand:HI 0 "register_operand" "=r")
1917
                   (minus:HI (match_dup 2)
1918
                             (match_operand:HI 1 "register_operand" "r")))
1919
              (clobber (reg:CC CC_REGNUM))])]
1920
  ""
1921
  "operands[2] = gen_reg_rtx(HImode);
1922
   operands[3] = GEN_INT(0x00000000);")
1923
 
1924
(define_expand "negsi2"
1925
  [(set (match_dup 2) (match_dup 3))
1926
   (parallel [(set (match_operand:SI 0 "register_operand" "=r")
1927
                   (minus:SI (match_dup 2)
1928
                             (match_operand:SI 1 "register_operand" "r")))
1929
              (clobber (reg:CC CC_REGNUM))])]
1930
  ""
1931
  "operands[2] = gen_reg_rtx(SImode);
1932
   operands[3] = GEN_INT(0x00000000);")
1933
 
1934
;;===========================================================================
1935
;; Absolute value. Taken from the Hacker's Delight, page 17. The second of the
1936
;; four options given there produces the smallest, fastest code.
1937
;;===========================================================================
1938
 
1939
(define_insn_and_split "abshi2"
1940
  [(set (match_operand:HI 0 "register_operand" "")
1941
   (abs:HI (match_operand:HI 1 "register_operand" "")))]
1942
 ""
1943
 "#"
1944
 ""
1945
 [(parallel [(set (match_dup 2)
1946
                  (plus:HI (ashiftrt:HI (match_dup 1) (const_int 15))
1947
                           (match_dup 1)))
1948
             (clobber (reg:CC CC_REGNUM))])
1949
  (parallel [(set (match_dup 0)
1950
                  (xor:HI (ashiftrt:HI (match_dup 1) (const_int 15))
1951
                          (match_dup 2)))
1952
             (clobber (reg:CC CC_REGNUM))])]
1953
{
1954
  operands[2] = gen_reg_rtx (HImode);
1955
})
1956
 
1957
;;===========================================================================
1958
;; Bitwise complement.  Use auto-synthesised variant for SI mode. Though this
1959
;; internally uses xor, the compiler doesnt automatically synthesize it using
1960
;; xor, if this pattern was removed.
1961
;;===========================================================================
1962
 
1963
(define_insn "one_cmplhi2"
1964
  [(set (match_operand:HI 0 "register_operand" "=r")
1965
        (not:HI (match_operand:HI 1 "register_operand" "0")))
1966
   (clobber (reg:CC CC_REGNUM))]
1967
  ""
1968
  "XOR.%# %1,-1,%0 // %0 := ~%1"
1969
  [(set_attr "type" "basicAlu")
1970
   (set_attr "longConstant" "true")
1971
   (set_attr "length" "5")])
1972
 
1973
;;===========================================================================
1974
;; Count leading zeros. The special sign-bit-count instruction can be used
1975
;; to help us here.
1976
;;    op1:=clz(op1)
1977
;; The code works by checking to see if the top bit is set. If it is,
1978
;; then there are no leading zeros. If the top bit is cleared, then
1979
;; the SBC instruction is used to determine how many more leading
1980
;; zeros are present, and adding one more for the initial zero.
1981
;;===========================================================================
1982
 
1983
(define_insn "clzhi2"
1984
  [(set (match_operand:HI 0 "register_operand" "=&r")
1985
        (clz:HI (match_operand:HI 1 "register_operand" "r")))]
1986
  ""
1987
  "// Count leading zeros\;SBC %1,%0\;ASR.0 %1,15,r15 %| ADD.1 %0,1,%0\;COPYNE 0,%0"
1988
  [(set_attr "length" "11")])
1989
 
1990
;;===========================================================================
1991
;; Count trailing zeros. This can be achieved efficiently by reversing
1992
;; using the bitrev instruction, and then counting the leading zeros as
1993
;; described above.
1994
;;===========================================================================
1995
 
1996
(define_insn "ctzhi2"
1997
  [(set (match_operand:HI 0 "register_operand" "=&r")
1998
        (ctz:HI (match_operand:HI 1 "register_operand" "r")))]
1999
  ""
2000
  "// Count trailing zeros\;BREV %1,%0\;SBC %0,%0\;AND.0 %1,0x0001,r15 %| ADD.1 %0,1,%0\;COPYNE 0,%0"
2001
  [(set_attr "length" "15")])
2002
 
2003
;;===========================================================================
2004
;; Find the first set bit, starting from the least significant bit position.
2005
;; This is very similar to the ctz function, except that the bit index is one
2006
;; greater than the number of trailing zeros (i.e., SBC + 2), and the
2007
;; result of ffs on the zero value is defined.
2008
;;===========================================================================
2009
 
2010
(define_insn "ffshi2"
2011
  [(set (match_operand:HI 0 "register_operand" "=&r")
2012
        (ffs:HI (match_operand:HI 1 "register_operand" "r")))]
2013
  ""
2014
  "// 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"
2015
  [(set_attr "length" "20")])
2016
 
2017
;;===========================================================================
2018
;; Tablejump Instruction.  Jump to an absolute address.
2019
;;===========================================================================
2020
 
2021
(define_insn "tablejump"
2022
  [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "r")] 1))
2023
   (use (label_ref (match_operand 1 "" "")))
2024
   (clobber (match_dup 0))]
2025
  ""
2026
  "JR (%0)\t // Table jump to %0 %>"
2027
  [(set_attr "length" "2")
2028
   (set_attr "type" "realBranch")])
2029
 
2030
;; Given the memory address of a QImode value, and a scratch register,
2031
;; store the memory operand into the given output operand.  The scratch
2032
;; operand will not conflict with either of the operands.  The other
2033
;; two operands may conflict with each other.
2034
 
2035
(define_insn "synthesised_loadqi_unaligned"
2036
  [(set (match_operand:QI 0 "register_operand" "=r")
2037
        (match_operand:QI 1 "memory_operand" "m"))
2038
   (clobber (match_operand:HI 2 "register_operand" "=&r"))
2039
   (clobber (reg:CC CC_REGNUM))]
2040
  ""
2041
  "// 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"
2042
  ; Approximate length only.  Probably a little shorter than this.
2043
  [(set_attr "length" "40")])
2044
 
2045
;; Given a memory operand whose alignment is known (the HImode aligned
2046
;; base is operand 0, and the number of bits by which to shift is in
2047
;; operand 5),
2048
(define_expand "synthesised_storeqi_aligned"
2049
  [; s1 = mem_op
2050
   (set (match_operand:HI 2 "register_operand" "")
2051
        (match_operand:HI 0 "memory_operand" ""))
2052
   ; s1 = s1 and mask
2053
   (parallel [(set (match_dup 2) (and:HI (match_dup 2) (match_dup 5)))
2054
   (clobber (reg:CC CC_REGNUM))])
2055
   ; s2 = source << bitShift
2056
   (set (match_dup 3)
2057
        (ashift:HI (subreg:HI (match_operand:QI 1 "register_operand" "") 0)
2058
                   (match_operand:HI 4 "const_int_operand" "")))
2059
   ; s1 = s1 or s2
2060
   (parallel [(set (match_dup 2) (ior:HI (match_dup 2) (match_dup 3)))
2061
   (clobber (reg:CC CC_REGNUM))])
2062
   ; mem_op = s1
2063
   (set (match_dup 0) (match_dup 2))]
2064
  "!TARGET_HAS_BYTE_ACCESS"
2065
{
2066
  /* Create the byte mask 0xFF00. */
2067
  operands[5] = gen_int_mode(((~0xFF) >> INTVAL (operands[4])), HImode);
2068
})
2069
 
2070
;; Reload instructions.  See picochip_secondary_reload for an
2071
;; explanation of why an SI mode register is used as a scratch.  The
2072
;; memory operand must be stored in a register (i.e., it can't be an
2073
;; offset to another register - this would require another scratch
2074
;; register into which the address of the offset could be computed).
2075
 
2076
(define_expand "reload_inqi"
2077
  [(parallel [(match_operand:QI 0 "register_operand" "=&r")
2078
              (match_operand:QI 1 "memory_operand" "m")
2079
              (match_operand:SI 2 "register_operand" "=&r")])]
2080
  "!TARGET_HAS_BYTE_ACCESS"
2081
{
2082
  rtx scratch, seq;
2083
 
2084
  /* Get the scratch register.  Given an SI mode value, we have a
2085
     choice of two HI mode scratch registers, so we can be sure that at
2086
     least one of the scratch registers will be different to the output
2087
     register, operand[0]. */
2088
 
2089
  if (REGNO (operands[0]) == REGNO (operands[2]))
2090
    scratch = gen_rtx_REG (HImode, REGNO (operands[2]) + 1);
2091
  else
2092
    scratch = gen_rtx_REG (HImode, REGNO (operands[2]));
2093
 
2094
  /* Ensure that the scratch doesn't overlap either of the other
2095
     two operands - however, the other two may overlap each
2096
     other. */
2097
  gcc_assert (REGNO(scratch) != REGNO(operands[0]));
2098
  gcc_assert (REGNO(scratch) != REGNO(operands[1]));
2099
 
2100
  gcc_assert (GET_CODE (operands[1]) == MEM);
2101
 
2102
  if (picochip_word_aligned_memory_reference(XEXP(operands[1], 0)))
2103
  {
2104
    /* Aligned reloads are easy, since they can use word-loads. */
2105
    seq = gen_synthesised_loadqi_aligned(operands[0], operands[1], scratch);
2106
  }
2107
  else
2108
  {
2109
    /* Emit the instruction using a define_insn. */
2110
    seq = gen_synthesised_loadqi_unaligned(operands[0], operands[1], scratch);
2111
  }
2112
  emit_insn (seq);
2113
 
2114
  DONE;
2115
 
2116
})
2117
 
2118
(define_expand "reload_outqi"
2119
  [(parallel [(match_operand 0 "memory_operand" "=m")
2120
              (match_operand:QI 1 "register_operand" "r")
2121
              (match_operand:SI 2 "register_operand" "=&r")])]
2122
  "!TARGET_HAS_BYTE_ACCESS"
2123
{
2124
  rtx scratch1 = gen_rtx_REG(HImode, REGNO(operands[2]));
2125
  rtx scratch2 = gen_rtx_REG(HImode, REGNO(operands[2]) + 1);
2126
  rtx seq;
2127
 
2128
  gcc_assert (GET_CODE (operands[0]) == MEM);
2129
 
2130
  if (picochip_word_aligned_memory_reference(XEXP(operands[0], 0)))
2131
    {
2132
      rtx alignedAddr, bitShift;
2133
 
2134
      /* Convert the address of the known alignment into two operands
2135
       * representing the aligned base address, and the number of shift bits
2136
       * required to access the required value. */
2137
      picochip_get_hi_aligned_mem(operands[0], &alignedAddr, &bitShift);
2138
 
2139
      /* Emit an aligned store of the source, with the given bit offset. */
2140
      seq = gen_synthesised_storeqi_aligned(alignedAddr, operands[1], scratch1, scratch2, bitShift);
2141
 
2142
    }
2143
  else
2144
    {
2145
      /* This isnt exercised at all. Moreover, with new devices, byte access
2146
         is available in all variants. */
2147
      gcc_unreachable();
2148
    }
2149
 
2150
  emit_insn (seq);
2151
  DONE;
2152
 
2153
})
2154
 
2155
;; Perform a byte load of an alignable memory operand.
2156
; op0 = register to load. op1 = memory operand from which to load
2157
; op2 = op1, aligned to HI, op3 = const bit shift required to extract byte,
2158
; op4 = INTVAL(8 - op3)
2159
(define_expand "synthesised_loadqi_aligned"
2160
  [; Load memory operand into register
2161
   (set (match_operand:HI 2 "register_operand" "=r")
2162
        (match_dup 3))
2163
   ; Shift required byte into top byte of word.
2164
   (set (match_dup 2)
2165
        (ashift:HI (match_dup 2)
2166
                   (match_dup 4)))
2167
   ; Arithmetic shift of byte to sign extend, and move to lowest register.
2168
   (parallel[(set (subreg:HI (match_dup 0) 0)
2169
        (ashiftrt:HI (match_dup 2)
2170
                     (const_int 8)))
2171
   (clobber (reg:CC CC_REGNUM))])
2172
   (use (match_operand:QI 1 "picochip_alignable_memory_operand" "g"))]
2173
  "!TARGET_HAS_BYTE_ACCESS"
2174
{
2175
  rtx alignedAddr, bitShift;
2176
 
2177
  /* Convert the address of the known alignment into two operands
2178
   * representing the aligned base address, and the number of shift bits
2179
   * required to access the required value. */
2180
  picochip_get_hi_aligned_mem(operands[1], &alignedAddr, &bitShift);
2181
 
2182
  operands[3] = alignedAddr;
2183
  operands[4] = GEN_INT(8 - INTVAL(bitShift));
2184
})
2185
 
2186
;;============================================================================
2187
;; Special instructions.
2188
;;============================================================================
2189
 
2190
; Count sign-bits.
2191
(define_insn "sbc"
2192
  [(set (match_operand:HI             0 "register_operand" "=r")
2193
        (unspec:HI [(match_operand:HI 1 "register_operand" "r")]
2194
                   UNSPEC_SBC))]
2195
  ""
2196
  "SBC %1,%0\t\t// %0 := SBC(%1)"
2197
  [(set_attr "type" "picoAlu")
2198
   (set_attr "length" "2")])
2199
 
2200
; Bit reversal.
2201
(define_insn "brev"
2202
  [(set (match_operand:HI             0 "register_operand" "=r")
2203
        (unspec:HI [(match_operand:HI 1 "register_operand" "r")]
2204
                   UNSPEC_BREV))]
2205
  ""
2206
  "BREV %1,%0\t\t// %0 := BREV(%1)"
2207
  [(set_attr "length" "2")
2208
   (set_attr "type" "picoAlu")])
2209
 
2210
; Byte swap.
2211
(define_insn "bswaphi2"
2212
  [(set (match_operand:HI             0 "register_operand" "=r")
2213
        (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
2214
  ""
2215
  "BYTESWAP %1,%0\t\t// %0 := ByteSwap(%1)"
2216
  [(set_attr "length" "2")
2217
   (set_attr "type" "picoAlu")])
2218
 
2219
; Read status word.
2220
(define_insn "copysw"
2221
  [(set (match_operand:HI 0 "register_operand" "=r")
2222
        (unspec_volatile:HI [(reg:CC CC_REGNUM)] UNSPEC_COPYSW))]
2223
  ""
2224
  "COPYSW.%# %0\t// %0 := Flags"
2225
  [(set_attr "type" "basicAlu")
2226
   (set_attr "length" "2")])
2227
 
2228
; Saturating addition.
2229
(define_insn "sataddhi3"
2230
  [(set (match_operand:HI             0 "register_operand" "=r")
2231
        (unspec:HI [(match_operand:HI 1 "register_operand" "r")
2232
                    (match_operand:HI 2 "register_operand" "r")]
2233
                   UNSPEC_ADDS))
2234
   (clobber (reg:CC CC_REGNUM))]
2235
  ""
2236
  "ADDS %1,%2,%0\t// %0 := sat(%1 + %2)"
2237
  [(set_attr "type" "picoAlu")
2238
   (set_attr "length" "3")])
2239
 
2240
; Saturating subtraction.
2241
(define_insn "satsubhi3"
2242
  [(set (match_operand:HI             0 "register_operand" "=r")
2243
        (unspec:HI [(match_operand:HI 1 "register_operand" "r")
2244
                    (match_operand:HI 2 "register_operand" "r")]
2245
                   UNSPEC_SUBS))
2246
   (clobber (reg:CC CC_REGNUM))]
2247
  ""
2248
  "SUBS %1,%2,%0\t// %0 := sat(%1 - %2)"
2249
  [(set_attr "type" "picoAlu")
2250
   (set_attr "length" "3")])
2251
 
2252
(define_insn "halt"
2253
  [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "i")]
2254
        UNSPEC_HALT)]
2255
  ""
2256
  "HALT\t// (id %0)"
2257
  [(set_attr "length" "1")
2258
   (set_attr "type" "unknown")])
2259
 
2260
(define_insn "internal_testport"
2261
  [(set (reg:CC CC_REGNUM)
2262
        (unspec_volatile:CC [(match_operand:HI 0 "const_int_operand" "i")]
2263
           UNSPEC_INTERNAL_TESTPORT))]
2264
  ""
2265
  "TSTPORT %0"
2266
  [(set_attr "length" "2")
2267
   (set_attr "longConstant" "false")
2268
   (set_attr "type" "picoAlu")])
2269
 
2270
;;============================================================================
2271
;; Communications builtins.
2272
;;
2273
;; Each builtin comes in two forms: a single port version, which maps
2274
;; to a single instruction, and an array port version.  The array port
2275
;; version is treated as a special type of instruction, which is then
2276
;; split into a number of smaller instructions, if the index of the
2277
;; port can't be converted into a constant.  When the RTL split is
2278
;; performed, a function call is emitted, in which the index of the
2279
;; port to use is used to compute the address of the function to call
2280
;; (i.e., each array port is a function in its own right, and the
2281
;; functions are stored as an array which is then indexed to determine
2282
;; the correct function). The communication function port array is
2283
;; created by the linker if and only if it is required (in a
2284
;; collect2-like manner).
2285
;;============================================================================
2286
 
2287
; Simple scalar get.
2288
(define_insn "commsGet"
2289
  [(set (match_operand:SI             0 "register_operand" "=r")
2290
        (unspec_volatile:SI
2291
         [(match_operand:HI 1 "immediate_operand" "n")]
2292
         UNSPEC_GET))]
2293
  ""
2294
  "GET %1,%R0\t// %R0 := PORT(%1)"
2295
  [(set_attr "type" "comms")
2296
   (set_attr "length" "2")])
2297
 
2298
; Entry point for array get (the actual port index is computed as the
2299
; sum of the index, and the base).
2300
;
2301
; op0 - Destination
2302
; op1 - Requested port index
2303
; op2 - size of port array (constant)
2304
; op3 - base index of port array (constant)
2305
 
2306
(define_expand "commsArrayGet"
2307
  [(parallel
2308
      [(set (reg:SI 0)
2309
            (unspec_volatile:SI [(match_operand:HI 1 "general_operand" "")
2310
                         (match_operand:HI 2 "immediate_operand" "")
2311
                         (match_operand:HI 3 "immediate_operand" "")]
2312
                UNSPEC_CALL_GET_ARRAY))
2313
       (clobber (reg:HI LINK_REGNUM))])
2314
   (set (match_operand:SI 0 "register_operand" "") (reg:SI 0))]
2315
  ""
2316
  "")
2317
 
2318
;; The actual array get instruction. When the array index is a constant,
2319
;; an exact instruction may be generated. When the index is variable,
2320
;; a call to a special function is generated. This code could be
2321
;; split into individual RTL instructions, but it is so rarely
2322
;; used, that we won't bother.
2323
(define_insn "*commsArrayGetInstruction"
2324
  [(set (reg:SI 0)
2325
        (unspec_volatile:SI [(match_operand:HI 0 "general_operand" "r,i")
2326
                     (match_operand:HI 1 "immediate_operand" "")
2327
                     (match_operand:HI 2 "immediate_operand" "")]
2328
                UNSPEC_CALL_GET_ARRAY))
2329
   (clobber (reg:HI LINK_REGNUM))]
2330
  ""
2331
{
2332
  return picochip_output_get_array (which_alternative, operands);
2333
})
2334
 
2335
; Scalar Put instruction.
2336
(define_insn "commsPut"
2337
  [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "")
2338
                     (match_operand:SI 1 "register_operand" "r")]
2339
                    UNSPEC_PUT)]
2340
  ""
2341
  "PUT %R1,%0\t// PORT(%0) := %R1"
2342
  [(set_attr "type" "comms")
2343
   (set_attr "length" "2")])
2344
 
2345
; Entry point for array put. The operands accepted are:
2346
;   op0 - Value to put
2347
;   op1 - Requested port index
2348
;   op2 - size of port array
2349
;   op3 - base index of port array
2350
; The arguments are marshalled into the fixed registers, so that
2351
; the actual put instruction can expand into a call if necessary
2352
; (e.g., if the index is variable at run-time).
2353
 
2354
(define_expand "commsArrayPut"
2355
  [(set (reg:SI 0) (match_operand:SI 0 "general_operand" ""))
2356
   (parallel
2357
      [(unspec_volatile [(match_operand:HI 1 "general_operand" "")
2358
                         (match_operand:HI 2 "immediate_operand" "")
2359
                         (match_operand:HI 3 "immediate_operand" "")]
2360
                UNSPEC_CALL_PUT_ARRAY)
2361
       (use (reg:SI 0))
2362
       (clobber (reg:HI LINK_REGNUM))])]
2363
  ""
2364
  "")
2365
 
2366
;; The actual array put instruction. When the array index is a constant,
2367
;; an exact instruction may be generated. When the index is variable,
2368
;; a call to a special function is generated. This code could be
2369
;; split into individual RTL instructions, but it is so rarely
2370
;; used, that we won't bother.
2371
(define_insn "*commsArrayPutInstruction"
2372
  [(unspec_volatile [(match_operand:HI 0 "general_operand" "r,i")
2373
                     (match_operand:HI 1 "immediate_operand" "")
2374
                     (match_operand:HI 2 "immediate_operand" "")]
2375
                UNSPEC_CALL_PUT_ARRAY)
2376
   (use (reg:SI 0))
2377
   (clobber (reg:HI LINK_REGNUM))]
2378
  ""
2379
{
2380
  return picochip_output_put_array (which_alternative, operands);
2381
})
2382
 
2383
;; Scalar test port instruction.
2384
(define_insn "commsTestPort"
2385
  [(set (match_operand:HI             0 "register_operand" "=r")
2386
        (unspec_volatile:HI [(match_operand:HI 1 "const_int_operand" "")]
2387
                   UNSPEC_TESTPORT))
2388
   (clobber (reg:CC CC_REGNUM))]
2389
  ""
2390
  "// %0 := TestPort(%1)\;COPY.1 0,%0 %| TSTPORT %1\;COPYEQ 1,%0"
2391
  [(set_attr "length" "9")])
2392
 
2393
; Entry point for array tstport (the actual port index is computed as the
2394
; sum of the index, and the base).
2395
;
2396
; op0 - Test value.
2397
; op1 - Requested port index
2398
; op2 - size of port array (constant)
2399
; op3 - base index of port array (constant)
2400
 
2401
(define_expand "commsArrayTestPort"
2402
  [(parallel
2403
      [(set (match_operand:HI 0 "register_operand" "")
2404
            (unspec_volatile:HI [(match_operand:HI 1 "general_operand" "")
2405
                              (match_operand:HI 2 "immediate_operand" "")
2406
                              (match_operand:HI 3 "immediate_operand" "")]
2407
                UNSPEC_CALL_TESTPORT_ARRAY))
2408
       (clobber (reg:HI LINK_REGNUM))])]
2409
  ""
2410
  "")
2411
 
2412
;; The actual array testport instruction. When the array index is a constant,
2413
;; an exact instruction may be generated. When the index is variable,
2414
;; a call to a special function is generated. This code could be
2415
;; split into individual RTL instructions, but it is so rarely
2416
;; used, that we won't bother.
2417
(define_insn "*commsArrayTestportInstruction"
2418
  [(set (match_operand:HI 0 "register_operand" "=r,r")
2419
        (unspec_volatile:HI [(match_operand:HI 1 "general_operand" "r,i")
2420
                          (match_operand:HI 2 "immediate_operand" "")
2421
                          (match_operand:HI 3 "immediate_operand" "")]
2422
                UNSPEC_CALL_TESTPORT_ARRAY))
2423
   (clobber (reg:HI LINK_REGNUM))]
2424
  ""
2425
{
2426
  return picochip_output_testport_array (which_alternative, operands);
2427
})
2428
 
2429
;; Merge a TSTPORT instruction with the branch to which it
2430
;; relates.  Often the TSTPORT function (generated by a built-in), is
2431
;; used to control conditional execution.  The normal sequence of
2432
;; instructions would be:
2433
;;    TSTPORT p
2434
;;    COPYSW temp
2435
;;    AND temp, 0x0008, temp
2436
;;    SUB temp,0,discard
2437
;;    BEQ label
2438
;; This can be made more efficient by detecting the special case where
2439
;; the result of a TSTPORT is used to branch, to allow the following
2440
;; RTL sequence to be generated instead:
2441
;;    TSTPORT p
2442
;;    BEQ label
2443
;; A big saving in cycles and bytes!
2444
 
2445
(define_insn_and_split "tstport_branch"
2446
 [(set (pc)
2447
        (if_then_else
2448
            (match_operator 0 "comparison_operator"
2449
                            [(unspec_volatile:HI
2450
                                [(match_operand:HI 1 "const_int_operand" "")]
2451
                                           UNSPEC_TESTPORT)
2452
                             (const_int 0)])
2453
            (label_ref       (match_operand    2 "" ""))
2454
            (pc)))
2455
   (clobber (reg:CC CC_REGNUM))]
2456
 ""
2457
 "#"
2458
 ""
2459
 [(set (reg:CC CC_REGNUM)
2460
       (unspec_volatile:CC [(match_dup 1)] UNSPEC_INTERNAL_TESTPORT))
2461
  (parallel [(set (pc)
2462
                  (if_then_else
2463
                       (match_op_dup:HI 4 [(reg:CC CC_REGNUM) (const_int 0)])
2464
                                (label_ref (match_dup 2))
2465
                                (pc)))
2466
             (use (match_dup 3))])]
2467
 "{
2468
    /* Note that the sense of the branch is reversed, since we are
2469
     * comparing flag != 0. */
2470
    gcc_assert (GET_CODE(operands[0]) == NE || GET_CODE(operands[0]) == EQ);
2471
    operands[4] = gen_rtx_fmt_ee(reverse_condition(GET_CODE(operands[0])),
2472
                  GET_MODE(operands[0]), XEXP(operands[0], 0), XEXP(operands[0], 1));
2473
    operands[3] = GEN_INT (0);
2474
  }")
2475
 
2476
;;============================================================================
2477
;; Epilogue/Epilogue expansion.
2478
;;============================================================================
2479
 
2480
(define_expand "prologue"
2481
  [(clobber (const_int 0))]
2482
  ""
2483
{
2484
  picochip_expand_prologue ();
2485
  DONE;
2486
})
2487
 
2488
(define_expand "epilogue"
2489
  [(use (const_int 0))]
2490
  ""
2491
{
2492
  picochip_expand_epilogue (FALSE);
2493
  DONE;
2494
})
2495
 
2496
;;============================================================================
2497
;; Trap instruction. This is used to indicate an error. For the
2498
;; picoChip processors this is handled by calling a HALT instruction,
2499
;; which stops the processor.
2500
;;============================================================================
2501
 
2502
(define_insn "trap"
2503
  [(trap_if (const_int 1) (const_int 6))]
2504
  ""
2505
  "HALT\t// (Trap)"
2506
  [(set_attr "length" "2")])
2507
 
2508
;;============================================================================
2509
;; Conditional copy instructions.  Only equal/not-equal comparisons are
2510
;; supported.  All other types of comparison remain as branch
2511
;; sequences.
2512
;;============================================================================
2513
 
2514
;; Define expand seems to consider the resulting two instructions to be
2515
;; independent. With a split, guarded by reload, it works correctly.
2516
(define_expand "movhicc"
2517
   [(set (match_operand:HI 0 "register_operand" "=r,r")
2518
                   (if_then_else:HI (match_operand:HI 1 "" "")
2519
                   (match_operand:HI 2 "register_operand" "0,0")
2520
                   (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))]
2521
  ""
2522
  {if (!picochip_check_conditional_copy (operands))
2523
     FAIL;
2524
  })
2525
 
2526
(define_insn_and_split "*checked_movhicc"
2527
   [(set (match_operand:HI 0 "register_operand" "=r,r")
2528
                   (if_then_else:HI (match_operator 1 "picochip_peephole_comparison_operator"
2529
                          [(match_operand:HI 4 "register_operand" "r,r")
2530
                           (match_operand:HI 5 "picochip_comparison_operand" "r,i")])
2531
                   (match_operand:HI 2 "register_operand" "0,0")
2532
                   (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))]
2533
  ""
2534
  "#"
2535
  "reload_completed"
2536
  [(set (reg:CC CC_REGNUM) (match_dup 1))
2537
   (parallel [(set (match_operand:HI 0 "register_operand" "=r,r")
2538
                   (if_then_else:HI (match_op_dup:HI 1 [(reg:CC CC_REGNUM) (const_int 0)])
2539
                                 (match_operand:HI 2 "picochip_register_or_immediate_operand" "0,0")
2540
                                 (match_operand:HI 3 "picochip_register_or_immediate_operand" "r,i")))
2541
              (use (match_dup 6))])]
2542
  "{
2543
     operands[6] = GEN_INT(GET_CODE(operands[0]));
2544
   }")
2545
 
2546
;; We dont do any checks here. But this pattern is used only when movhicc
2547
;; was checked. Put a "use" clause to make sure.
2548
(define_insn "*conditional_copy"
2549
  [(set (match_operand:HI 0 "register_operand" "=r,r")
2550
        (if_then_else:HI
2551
            (match_operator:HI 4 "picochip_peephole_comparison_operator"
2552
                 [(reg:CC CC_REGNUM) (const_int 0)])
2553
         (match_operand:HI 1 "register_operand" "0,0")
2554
         (match_operand:HI 2 "picochip_register_or_immediate_operand" "r,i")))
2555
   (use (match_operand:HI 3 "const_int_operand" ""))]
2556
  ""
2557
{
2558
 
2559
  gcc_assert (GET_CODE(operands[4]) == EQ || GET_CODE(operands[4]) == NE);
2560
  /* Note that the comparison is reversed as the pattern matches
2561
     the *else* part of the if_then_else */
2562
  switch (GET_CODE(operands[4]))
2563
    {
2564
    case EQ: return "COPYNE %2,%0\t// if (NE) %0 := %2";
2565
    case NE: return "COPYEQ %2,%0\t// if (EQ) %0 := %2";
2566
    default:
2567
      gcc_unreachable();
2568
    }
2569
}
2570
  [(set_attr "length" "2")
2571
   (set_attr "type" "picoAlu,picoAlu")
2572
   (set_attr "longConstant" "false,true")])
2573
 
2574
;;============================================================================
2575
;; Scheduling, including delay slot scheduling.
2576
;;============================================================================
2577
 
2578
(automata_option "v")
2579
(automata_option "ndfa")
2580
 
2581
;; Define each VLIW slot as a CPU resource.  Note the three flavours of
2582
;; branch.  `realBranch' is an actual branch instruction.  `macroBranch'
2583
;; is a directive to the assembler, which may expand into multiple
2584
;; instructions.  `call' is an actual branch instruction, but one which
2585
;; sets the link register, and hence can't be scheduled alongside
2586
;; other instructions which set the link register.  When the DFA
2587
;; scheduler is fixed to prevent it scheduling a JL with an R12
2588
;; setting register, the call type branches can be replaced by
2589
;; realBranch types instead.
2590
 
2591
(define_attr "type"
2592
  "picoAlu,basicAlu,nonCcAlu,mem,call,realBranch,macroBranch,mul,mac,app,comms,unknown"
2593
  (const_string "unknown"))
2594
 
2595
(define_attr "schedType" "none,space,speed"
2596
  (const (symbol_ref "(enum attr_schedType) picochip_schedule_type")))
2597
 
2598
;; Define whether an instruction uses a long constant.
2599
 
2600
(define_attr "longConstant"
2601
  "true,false" (const_string "false"))
2602
 
2603
;; Define three EU slots.
2604
(define_query_cpu_unit "slot0,slot1,slot2")
2605
 
2606
;; Pull in the pipeline descriptions for speed or space scheduling.
2607
(include "dfa_speed.md")
2608
(include "dfa_space.md")
2609
 
2610
; Unknown instructions are assumed to take a single cycle, and use all
2611
; slots.  This enables them to actually output a sequence of
2612
; instructions without any limitation.  For the purposes of
2613
; scheduling, unknown instructions are a pain, and should be removed
2614
; completely.  This means that RTL patterns should always be used to
2615
; reduce complex sequences of instructions to individual instructions.
2616
(define_insn_reservation "unknownInsn" 1
2617
  (eq_attr "type" "unknown")
2618
  "(slot0+slot1+slot2)")
2619
 
2620
; Allow any non-branch instructions to be placed in the branch
2621
; slot. Branch slots are always executed.
2622
(define_delay (eq_attr "type" "realBranch,call")
2623
  [(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.