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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [arm/] [thumb2.md] - Blame information for rev 282

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
;; ARM Thumb-2 Machine Description
2
;; Copyright (C) 2007, 2008 Free Software Foundation, Inc.
3
;; Written by CodeSourcery, LLC.
4
;;
5
;; This file is part of GCC.
6
;;
7
;; GCC is free software; you can redistribute it and/or modify it
8
;; under the terms of the GNU General Public License as published by
9
;; the Free Software Foundation; either version 3, or (at your option)
10
;; any later version.
11
;;
12
;; GCC is distributed in the hope that it will be useful, but
13
;; WITHOUT ANY WARRANTY; without even the implied warranty of
14
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
;; General Public License for more details.
16
;;
17
;; You should have received a copy of the GNU General Public License
18
;; along with GCC; see the file COPYING3.  If not see
19
;; .  */
20
 
21
;; Note: Thumb-2 is the variant of the Thumb architecture that adds
22
;; 32-bit encodings of [almost all of] the Arm instruction set.
23
;; Some old documents refer to the relatively minor interworking
24
;; changes made in armv5t as "thumb2".  These are considered part
25
;; the 16-bit Thumb-1 instruction set.
26
 
27
(define_insn "*thumb2_incscc"
28
  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
29
        (plus:SI (match_operator:SI 2 "arm_comparison_operator"
30
                    [(match_operand:CC 3 "cc_register" "") (const_int 0)])
31
                 (match_operand:SI 1 "s_register_operand" "0,?r")))]
32
  "TARGET_THUMB2"
33
  "@
34
  it\\t%d2\;add%d2\\t%0, %1, #1
35
  ite\\t%D2\;mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
36
  [(set_attr "conds" "use")
37
   (set_attr "length" "6,10")]
38
)
39
 
40
(define_insn "*thumb2_decscc"
41
  [(set (match_operand:SI            0 "s_register_operand" "=r,r")
42
        (minus:SI (match_operand:SI  1 "s_register_operand" "0,?r")
43
                  (match_operator:SI 2 "arm_comparison_operator"
44
                   [(match_operand   3 "cc_register" "") (const_int 0)])))]
45
  "TARGET_THUMB2"
46
  "@
47
   it\\t%d2\;sub%d2\\t%0, %1, #1
48
   ite\\t%D2\;mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
49
  [(set_attr "conds" "use")
50
   (set_attr "length" "6,10")]
51
)
52
 
53
;; Thumb-2 only allows shift by constant on data processing instructions
54
(define_insn "*thumb_andsi_not_shiftsi_si"
55
  [(set (match_operand:SI 0 "s_register_operand" "=r")
56
        (and:SI (not:SI (match_operator:SI 4 "shift_operator"
57
                         [(match_operand:SI 2 "s_register_operand" "r")
58
                          (match_operand:SI 3 "const_int_operand" "M")]))
59
                (match_operand:SI 1 "s_register_operand" "r")))]
60
  "TARGET_THUMB2"
61
  "bic%?\\t%0, %1, %2%S4"
62
  [(set_attr "predicable" "yes")
63
   (set_attr "shift" "2")
64
   (set_attr "type" "alu_shift")]
65
)
66
 
67
(define_insn "*thumb2_smaxsi3"
68
  [(set (match_operand:SI          0 "s_register_operand" "=r,r,r")
69
        (smax:SI (match_operand:SI 1 "s_register_operand"  "0,r,?r")
70
                 (match_operand:SI 2 "arm_rhs_operand"    "rI,0,rI")))
71
   (clobber (reg:CC CC_REGNUM))]
72
  "TARGET_THUMB2"
73
  "@
74
   cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2
75
   cmp\\t%1, %2\;it\\tge\;movge\\t%0, %1
76
   cmp\\t%1, %2\;ite\\tge\;movge\\t%0, %1\;movlt\\t%0, %2"
77
  [(set_attr "conds" "clob")
78
   (set_attr "length" "10,10,14")]
79
)
80
 
81
(define_insn "*thumb2_sminsi3"
82
  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
83
        (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
84
                 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
85
   (clobber (reg:CC CC_REGNUM))]
86
  "TARGET_THUMB2"
87
  "@
88
   cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2
89
   cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %1
90
   cmp\\t%1, %2\;ite\\tlt\;movlt\\t%0, %1\;movge\\t%0, %2"
91
  [(set_attr "conds" "clob")
92
   (set_attr "length" "10,10,14")]
93
)
94
 
95
(define_insn "*thumb32_umaxsi3"
96
  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
97
        (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
98
                 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
99
   (clobber (reg:CC CC_REGNUM))]
100
  "TARGET_THUMB2"
101
  "@
102
   cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2
103
   cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %1
104
   cmp\\t%1, %2\;ite\\tcs\;movcs\\t%0, %1\;movcc\\t%0, %2"
105
  [(set_attr "conds" "clob")
106
   (set_attr "length" "10,10,14")]
107
)
108
 
109
(define_insn "*thumb2_uminsi3"
110
  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
111
        (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
112
                 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
113
   (clobber (reg:CC CC_REGNUM))]
114
  "TARGET_THUMB2"
115
  "@
116
   cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2
117
   cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %1
118
   cmp\\t%1, %2\;ite\\tcc\;movcc\\t%0, %1\;movcs\\t%0, %2"
119
  [(set_attr "conds" "clob")
120
   (set_attr "length" "10,10,14")]
121
)
122
 
123
(define_insn "*thumb2_notsi_shiftsi"
124
  [(set (match_operand:SI 0 "s_register_operand" "=r")
125
        (not:SI (match_operator:SI 3 "shift_operator"
126
                 [(match_operand:SI 1 "s_register_operand" "r")
127
                  (match_operand:SI 2 "const_int_operand"  "M")])))]
128
  "TARGET_THUMB2"
129
  "mvn%?\\t%0, %1%S3"
130
  [(set_attr "predicable" "yes")
131
   (set_attr "shift" "1")
132
   (set_attr "type" "alu_shift")]
133
)
134
 
135
(define_insn "*thumb2_notsi_shiftsi_compare0"
136
  [(set (reg:CC_NOOV CC_REGNUM)
137
        (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
138
                          [(match_operand:SI 1 "s_register_operand" "r")
139
                           (match_operand:SI 2 "const_int_operand"  "M")]))
140
                         (const_int 0)))
141
   (set (match_operand:SI 0 "s_register_operand" "=r")
142
        (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
143
  "TARGET_THUMB2"
144
  "mvn%.\\t%0, %1%S3"
145
  [(set_attr "conds" "set")
146
   (set_attr "shift" "1")
147
   (set_attr "type" "alu_shift")]
148
)
149
 
150
(define_insn "*thumb2_not_shiftsi_compare0_scratch"
151
  [(set (reg:CC_NOOV CC_REGNUM)
152
        (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
153
                          [(match_operand:SI 1 "s_register_operand" "r")
154
                           (match_operand:SI 2 "const_int_operand"  "M")]))
155
                         (const_int 0)))
156
   (clobber (match_scratch:SI 0 "=r"))]
157
  "TARGET_THUMB2"
158
  "mvn%.\\t%0, %1%S3"
159
  [(set_attr "conds" "set")
160
   (set_attr "shift" "1")
161
   (set_attr "type" "alu_shift")]
162
)
163
 
164
;; Thumb-2 does not have rsc, so use a clever trick with shifter operands.
165
(define_insn "*thumb2_negdi2"
166
  [(set (match_operand:DI         0 "s_register_operand" "=&r,r")
167
        (neg:DI (match_operand:DI 1 "s_register_operand"  "?r,0")))
168
   (clobber (reg:CC CC_REGNUM))]
169
  "TARGET_THUMB2"
170
  "negs\\t%Q0, %Q1\;sbc\\t%R0, %R1, %R1, lsl #1"
171
  [(set_attr "conds" "clob")
172
   (set_attr "length" "8")]
173
)
174
 
175
(define_insn "*thumb2_abssi2"
176
  [(set (match_operand:SI         0 "s_register_operand" "=r,&r")
177
        (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
178
   (clobber (reg:CC CC_REGNUM))]
179
  "TARGET_THUMB2"
180
  "@
181
   cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
182
   eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
183
  [(set_attr "conds" "clob,*")
184
   (set_attr "shift" "1")
185
   ;; predicable can't be set based on the variant, so left as no
186
   (set_attr "length" "10,8")]
187
)
188
 
189
(define_insn "*thumb2_neg_abssi2"
190
  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
191
        (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
192
   (clobber (reg:CC CC_REGNUM))]
193
  "TARGET_THUMB2"
194
  "@
195
   cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
196
   eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
197
  [(set_attr "conds" "clob,*")
198
   (set_attr "shift" "1")
199
   ;; predicable can't be set based on the variant, so left as no
200
   (set_attr "length" "10,8")]
201
)
202
 
203
(define_insn "*thumb2_movdi"
204
  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
205
        (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,r"))]
206
  "TARGET_THUMB2
207
  && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
208
  && !TARGET_IWMMXT"
209
  "*
210
  switch (which_alternative)
211
    {
212
    case 0:
213
    case 1:
214
    case 2:
215
      return \"#\";
216
    default:
217
      return output_move_double (operands);
218
    }
219
  "
220
  [(set_attr "length" "8,12,16,8,8")
221
   (set_attr "type" "*,*,*,load2,store2")
222
   (set_attr "pool_range" "*,*,*,4096,*")
223
   (set_attr "neg_pool_range" "*,*,*,0,*")]
224
)
225
 
226
(define_insn "*thumb2_movsi_insn"
227
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
228
        (match_operand:SI 1 "general_operand"      "rk ,I,K,j,mi,rk"))]
229
  "TARGET_THUMB2 && ! TARGET_IWMMXT
230
   && !(TARGET_HARD_FLOAT && TARGET_VFP)
231
   && (   register_operand (operands[0], SImode)
232
       || register_operand (operands[1], SImode))"
233
  "@
234
   mov%?\\t%0, %1
235
   mov%?\\t%0, %1
236
   mvn%?\\t%0, #%B1
237
   movw%?\\t%0, %1
238
   ldr%?\\t%0, %1
239
   str%?\\t%1, %0"
240
  [(set_attr "type" "*,*,*,*,load1,store1")
241
   (set_attr "predicable" "yes")
242
   (set_attr "pool_range" "*,*,*,*,4096,*")
243
   (set_attr "neg_pool_range" "*,*,*,*,0,*")]
244
)
245
 
246
(define_insn "tls_load_dot_plus_four"
247
  [(set (match_operand:SI 0 "register_operand" "=l,l,r,r")
248
        (mem:SI (unspec:SI [(match_operand:SI 2 "register_operand" "0,1,0,1")
249
                            (const_int 4)
250
                            (match_operand 3 "" "")]
251
                           UNSPEC_PIC_BASE)))
252
   (clobber (match_scratch:SI 1 "=X,l,X,r"))]
253
  "TARGET_THUMB2"
254
  "*
255
  (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
256
                             INTVAL (operands[3]));
257
  return \"add\\t%2, %|pc\;ldr%?\\t%0, [%2]\";
258
  "
259
  [(set_attr "length" "4,4,6,6")]
260
)
261
 
262
;; Thumb-2 always has load/store halfword instructions, so we can avoid a lot
263
;; of the messiness associated with the ARM patterns.
264
(define_insn "*thumb2_movhi_insn"
265
  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
266
        (match_operand:HI 1 "general_operand"      "rI,n,r,m"))]
267
  "TARGET_THUMB2"
268
  "@
269
   mov%?\\t%0, %1\\t%@ movhi
270
   movw%?\\t%0, %L1\\t%@ movhi
271
   str%(h%)\\t%1, %0\\t%@ movhi
272
   ldr%(h%)\\t%0, %1\\t%@ movhi"
273
  [(set_attr "type" "*,*,store1,load1")
274
   (set_attr "predicable" "yes")
275
   (set_attr "pool_range" "*,*,*,4096")
276
   (set_attr "neg_pool_range" "*,*,*,250")]
277
)
278
 
279
(define_insn "*thumb2_movsf_soft_insn"
280
  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
281
        (match_operand:SF 1 "general_operand"  "r,mE,r"))]
282
  "TARGET_THUMB2
283
   && TARGET_SOFT_FLOAT
284
   && (GET_CODE (operands[0]) != MEM
285
       || register_operand (operands[1], SFmode))"
286
  "@
287
   mov%?\\t%0, %1
288
   ldr%?\\t%0, %1\\t%@ float
289
   str%?\\t%1, %0\\t%@ float"
290
  [(set_attr "predicable" "yes")
291
   (set_attr "type" "*,load1,store1")
292
   (set_attr "pool_range" "*,4096,*")
293
   (set_attr "neg_pool_range" "*,0,*")]
294
)
295
 
296
(define_insn "*thumb2_movdf_soft_insn"
297
  [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
298
        (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
299
  "TARGET_THUMB2 && TARGET_SOFT_FLOAT
300
   && (   register_operand (operands[0], DFmode)
301
       || register_operand (operands[1], DFmode))"
302
  "*
303
  switch (which_alternative)
304
    {
305
    case 0:
306
    case 1:
307
    case 2:
308
      return \"#\";
309
    default:
310
      return output_move_double (operands);
311
    }
312
  "
313
  [(set_attr "length" "8,12,16,8,8")
314
   (set_attr "type" "*,*,*,load2,store2")
315
   (set_attr "pool_range" "1020")
316
   (set_attr "neg_pool_range" "0")]
317
)
318
 
319
(define_insn "*thumb2_cmpsi_shiftsi"
320
  [(set (reg:CC CC_REGNUM)
321
        (compare:CC (match_operand:SI   0 "s_register_operand" "r")
322
                    (match_operator:SI  3 "shift_operator"
323
                     [(match_operand:SI 1 "s_register_operand" "r")
324
                      (match_operand:SI 2 "const_int_operand"  "M")])))]
325
  "TARGET_THUMB2"
326
  "cmp%?\\t%0, %1%S3"
327
  [(set_attr "conds" "set")
328
   (set_attr "shift" "1")
329
   (set_attr "type" "alu_shift")]
330
)
331
 
332
(define_insn "*thumb2_cmpsi_shiftsi_swp"
333
  [(set (reg:CC_SWP CC_REGNUM)
334
        (compare:CC_SWP (match_operator:SI 3 "shift_operator"
335
                         [(match_operand:SI 1 "s_register_operand" "r")
336
                          (match_operand:SI 2 "const_int_operand" "M")])
337
                        (match_operand:SI 0 "s_register_operand" "r")))]
338
  "TARGET_THUMB2"
339
  "cmp%?\\t%0, %1%S3"
340
  [(set_attr "conds" "set")
341
   (set_attr "shift" "1")
342
   (set_attr "type" "alu_shift")]
343
)
344
 
345
(define_insn "*thumb2_cmpsi_neg_shiftsi"
346
  [(set (reg:CC CC_REGNUM)
347
        (compare:CC (match_operand:SI 0 "s_register_operand" "r")
348
                    (neg:SI (match_operator:SI 3 "shift_operator"
349
                             [(match_operand:SI 1 "s_register_operand" "r")
350
                              (match_operand:SI 2 "const_int_operand" "M")]))))]
351
  "TARGET_THUMB2"
352
  "cmn%?\\t%0, %1%S3"
353
  [(set_attr "conds" "set")
354
   (set_attr "shift" "1")
355
   (set_attr "type" "alu_shift")]
356
)
357
 
358
(define_insn "*thumb2_mov_scc"
359
  [(set (match_operand:SI 0 "s_register_operand" "=r")
360
        (match_operator:SI 1 "arm_comparison_operator"
361
         [(match_operand 2 "cc_register" "") (const_int 0)]))]
362
  "TARGET_THUMB2"
363
  "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
364
  [(set_attr "conds" "use")
365
   (set_attr "length" "10")]
366
)
367
 
368
(define_insn "*thumb2_mov_negscc"
369
  [(set (match_operand:SI 0 "s_register_operand" "=r")
370
        (neg:SI (match_operator:SI 1 "arm_comparison_operator"
371
                 [(match_operand 2 "cc_register" "") (const_int 0)])))]
372
  "TARGET_THUMB2"
373
  "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
374
  [(set_attr "conds" "use")
375
   (set_attr "length" "10")]
376
)
377
 
378
(define_insn "*thumb2_mov_notscc"
379
  [(set (match_operand:SI 0 "s_register_operand" "=r")
380
        (not:SI (match_operator:SI 1 "arm_comparison_operator"
381
                 [(match_operand 2 "cc_register" "") (const_int 0)])))]
382
  "TARGET_THUMB2"
383
  "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
384
  [(set_attr "conds" "use")
385
   (set_attr "length" "10")]
386
)
387
 
388
(define_insn "*thumb2_movsicc_insn"
389
  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
390
        (if_then_else:SI
391
         (match_operator 3 "arm_comparison_operator"
392
          [(match_operand 4 "cc_register" "") (const_int 0)])
393
         (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
394
         (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
395
  "TARGET_THUMB2"
396
  "@
397
   it\\t%D3\;mov%D3\\t%0, %2
398
   it\\t%D3\;mvn%D3\\t%0, #%B2
399
   it\\t%d3\;mov%d3\\t%0, %1
400
   it\\t%d3\;mvn%d3\\t%0, #%B1
401
   ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
402
   ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
403
   ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
404
   ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
405
  [(set_attr "length" "6,6,6,6,10,10,10,10")
406
   (set_attr "conds" "use")]
407
)
408
 
409
(define_insn "*thumb2_movsfcc_soft_insn"
410
  [(set (match_operand:SF 0 "s_register_operand" "=r,r")
411
        (if_then_else:SF (match_operator 3 "arm_comparison_operator"
412
                          [(match_operand 4 "cc_register" "") (const_int 0)])
413
                         (match_operand:SF 1 "s_register_operand" "0,r")
414
                         (match_operand:SF 2 "s_register_operand" "r,0")))]
415
  "TARGET_THUMB2 && TARGET_SOFT_FLOAT"
416
  "@
417
   it\\t%D3\;mov%D3\\t%0, %2
418
   it\\t%d3\;mov%d3\\t%0, %1"
419
  [(set_attr "length" "6,6")
420
   (set_attr "conds" "use")]
421
)
422
 
423
(define_insn "*call_reg_thumb2"
424
  [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
425
         (match_operand 1 "" ""))
426
   (use (match_operand 2 "" ""))
427
   (clobber (reg:SI LR_REGNUM))]
428
  "TARGET_THUMB2"
429
  "blx%?\\t%0"
430
  [(set_attr "type" "call")]
431
)
432
 
433
(define_insn "*call_value_reg_thumb2"
434
  [(set (match_operand 0 "" "")
435
        (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
436
              (match_operand 2 "" "")))
437
   (use (match_operand 3 "" ""))
438
   (clobber (reg:SI LR_REGNUM))]
439
  "TARGET_THUMB2"
440
  "blx\\t%1"
441
  [(set_attr "type" "call")]
442
)
443
 
444
(define_insn "*thumb2_indirect_jump"
445
  [(set (pc)
446
        (match_operand:SI 0 "register_operand" "l*r"))]
447
  "TARGET_THUMB2"
448
  "bx\\t%0"
449
  [(set_attr "conds" "clob")]
450
)
451
;; Don't define thumb2_load_indirect_jump because we can't guarantee label
452
;; addresses will have the thumb bit set correctly.
453
 
454
 
455
;; Patterns to allow combination of arithmetic, cond code and shifts
456
 
457
(define_insn "*thumb2_arith_shiftsi"
458
  [(set (match_operand:SI 0 "s_register_operand" "=r")
459
        (match_operator:SI 1 "shiftable_operator"
460
          [(match_operator:SI 3 "shift_operator"
461
             [(match_operand:SI 4 "s_register_operand" "r")
462
              (match_operand:SI 5 "const_int_operand" "M")])
463
           (match_operand:SI 2 "s_register_operand" "r")]))]
464
  "TARGET_THUMB2"
465
  "%i1%?\\t%0, %2, %4%S3"
466
  [(set_attr "predicable" "yes")
467
   (set_attr "shift" "4")
468
   (set_attr "type" "alu_shift")]
469
)
470
 
471
;; ??? What does this splitter do?  Copied from the ARM version
472
(define_split
473
  [(set (match_operand:SI 0 "s_register_operand" "")
474
        (match_operator:SI 1 "shiftable_operator"
475
         [(match_operator:SI 2 "shiftable_operator"
476
           [(match_operator:SI 3 "shift_operator"
477
             [(match_operand:SI 4 "s_register_operand" "")
478
              (match_operand:SI 5 "const_int_operand" "")])
479
            (match_operand:SI 6 "s_register_operand" "")])
480
          (match_operand:SI 7 "arm_rhs_operand" "")]))
481
   (clobber (match_operand:SI 8 "s_register_operand" ""))]
482
  "TARGET_32BIT"
483
  [(set (match_dup 8)
484
        (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
485
                         (match_dup 6)]))
486
   (set (match_dup 0)
487
        (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
488
  "")
489
 
490
(define_insn "*thumb2_arith_shiftsi_compare0"
491
  [(set (reg:CC_NOOV CC_REGNUM)
492
        (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
493
                          [(match_operator:SI 3 "shift_operator"
494
                            [(match_operand:SI 4 "s_register_operand" "r")
495
                             (match_operand:SI 5 "const_int_operand" "M")])
496
                           (match_operand:SI 2 "s_register_operand" "r")])
497
                         (const_int 0)))
498
   (set (match_operand:SI 0 "s_register_operand" "=r")
499
        (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
500
                         (match_dup 2)]))]
501
  "TARGET_32BIT"
502
  "%i1%.\\t%0, %2, %4%S3"
503
  [(set_attr "conds" "set")
504
   (set_attr "shift" "4")
505
   (set_attr "type" "alu_shift")]
506
)
507
 
508
(define_insn "*thumb2_arith_shiftsi_compare0_scratch"
509
  [(set (reg:CC_NOOV CC_REGNUM)
510
        (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
511
                          [(match_operator:SI 3 "shift_operator"
512
                            [(match_operand:SI 4 "s_register_operand" "r")
513
                             (match_operand:SI 5 "const_int_operand" "M")])
514
                           (match_operand:SI 2 "s_register_operand" "r")])
515
                         (const_int 0)))
516
   (clobber (match_scratch:SI 0 "=r"))]
517
  "TARGET_THUMB2"
518
  "%i1%.\\t%0, %2, %4%S3"
519
  [(set_attr "conds" "set")
520
   (set_attr "shift" "4")
521
   (set_attr "type" "alu_shift")]
522
)
523
 
524
(define_insn "*thumb2_sub_shiftsi"
525
  [(set (match_operand:SI 0 "s_register_operand" "=r")
526
        (minus:SI (match_operand:SI 1 "s_register_operand" "r")
527
                  (match_operator:SI 2 "shift_operator"
528
                   [(match_operand:SI 3 "s_register_operand" "r")
529
                    (match_operand:SI 4 "const_int_operand" "M")])))]
530
  "TARGET_THUMB2"
531
  "sub%?\\t%0, %1, %3%S2"
532
  [(set_attr "predicable" "yes")
533
   (set_attr "shift" "3")
534
   (set_attr "type" "alu_shift")]
535
)
536
 
537
(define_insn "*thumb2_sub_shiftsi_compare0"
538
  [(set (reg:CC_NOOV CC_REGNUM)
539
        (compare:CC_NOOV
540
         (minus:SI (match_operand:SI 1 "s_register_operand" "r")
541
                   (match_operator:SI 2 "shift_operator"
542
                    [(match_operand:SI 3 "s_register_operand" "r")
543
                     (match_operand:SI 4 "const_int_operand" "M")]))
544
         (const_int 0)))
545
   (set (match_operand:SI 0 "s_register_operand" "=r")
546
        (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
547
                                                 (match_dup 4)])))]
548
  "TARGET_THUMB2"
549
  "sub%.\\t%0, %1, %3%S2"
550
  [(set_attr "conds" "set")
551
   (set_attr "shift" "3")
552
   (set_attr "type" "alu_shift")]
553
)
554
 
555
(define_insn "*thumb2_sub_shiftsi_compare0_scratch"
556
  [(set (reg:CC_NOOV CC_REGNUM)
557
        (compare:CC_NOOV
558
         (minus:SI (match_operand:SI 1 "s_register_operand" "r")
559
                   (match_operator:SI 2 "shift_operator"
560
                    [(match_operand:SI 3 "s_register_operand" "r")
561
                     (match_operand:SI 4 "const_int_operand" "M")]))
562
         (const_int 0)))
563
   (clobber (match_scratch:SI 0 "=r"))]
564
  "TARGET_THUMB2"
565
  "sub%.\\t%0, %1, %3%S2"
566
  [(set_attr "conds" "set")
567
   (set_attr "shift" "3")
568
   (set_attr "type" "alu_shift")]
569
)
570
 
571
(define_insn "*thumb2_and_scc"
572
  [(set (match_operand:SI 0 "s_register_operand" "=r")
573
        (and:SI (match_operator:SI 1 "arm_comparison_operator"
574
                 [(match_operand 3 "cc_register" "") (const_int 0)])
575
                (match_operand:SI 2 "s_register_operand" "r")))]
576
  "TARGET_THUMB2"
577
  "ite\\t%D1\;mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
578
  [(set_attr "conds" "use")
579
   (set_attr "length" "10")]
580
)
581
 
582
(define_insn "*thumb2_ior_scc"
583
  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
584
        (ior:SI (match_operator:SI 2 "arm_comparison_operator"
585
                 [(match_operand 3 "cc_register" "") (const_int 0)])
586
                (match_operand:SI 1 "s_register_operand" "0,?r")))]
587
  "TARGET_THUMB2"
588
  "@
589
   it\\t%d2\;orr%d2\\t%0, %1, #1
590
   ite\\t%D2\;mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
591
  [(set_attr "conds" "use")
592
   (set_attr "length" "6,10")]
593
)
594
 
595
(define_insn "*thumb2_compare_scc"
596
  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
597
        (match_operator:SI 1 "arm_comparison_operator"
598
         [(match_operand:SI 2 "s_register_operand" "r,r")
599
          (match_operand:SI 3 "arm_add_operand" "rI,L")]))
600
   (clobber (reg:CC CC_REGNUM))]
601
  "TARGET_THUMB2"
602
  "*
603
    if (operands[3] == const0_rtx)
604
      {
605
        if (GET_CODE (operands[1]) == LT)
606
          return \"lsr\\t%0, %2, #31\";
607
 
608
        if (GET_CODE (operands[1]) == GE)
609
          return \"mvn\\t%0, %2\;lsr\\t%0, %0, #31\";
610
 
611
        if (GET_CODE (operands[1]) == EQ)
612
          return \"rsbs\\t%0, %2, #1\;it\\tcc\;movcc\\t%0, #0\";
613
      }
614
 
615
    if (GET_CODE (operands[1]) == NE)
616
      {
617
        if (which_alternative == 1)
618
          return \"adds\\t%0, %2, #%n3\;it\\tne\;movne\\t%0, #1\";
619
        return \"subs\\t%0, %2, %3\;it\\tne\;movne\\t%0, #1\";
620
      }
621
    if (which_alternative == 1)
622
      output_asm_insn (\"cmn\\t%2, #%n3\", operands);
623
    else
624
      output_asm_insn (\"cmp\\t%2, %3\", operands);
625
    return \"ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
626
  "
627
  [(set_attr "conds" "clob")
628
   (set_attr "length" "14")]
629
)
630
 
631
(define_insn "*thumb2_cond_move"
632
  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
633
        (if_then_else:SI (match_operator 3 "equality_operator"
634
                          [(match_operator 4 "arm_comparison_operator"
635
                            [(match_operand 5 "cc_register" "") (const_int 0)])
636
                           (const_int 0)])
637
                         (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
638
                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
639
  "TARGET_THUMB2"
640
  "*
641
    if (GET_CODE (operands[3]) == NE)
642
      {
643
        if (which_alternative != 1)
644
          output_asm_insn (\"it\\t%D4\;mov%D4\\t%0, %2\", operands);
645
        if (which_alternative != 0)
646
          output_asm_insn (\"it\\t%d4\;mov%d4\\t%0, %1\", operands);
647
        return \"\";
648
      }
649
    switch (which_alternative)
650
      {
651
      case 0:
652
        output_asm_insn (\"it\\t%d4\", operands);
653
        break;
654
      case 1:
655
        output_asm_insn (\"it\\t%D4\", operands);
656
        break;
657
      case 2:
658
        output_asm_insn (\"ite\\t%D4\", operands);
659
        break;
660
      default:
661
        abort();
662
      }
663
    if (which_alternative != 0)
664
      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
665
    if (which_alternative != 1)
666
      output_asm_insn (\"mov%d4\\t%0, %2\", operands);
667
    return \"\";
668
  "
669
  [(set_attr "conds" "use")
670
   (set_attr "length" "6,6,10")]
671
)
672
 
673
(define_insn "*thumb2_cond_arith"
674
  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
675
        (match_operator:SI 5 "shiftable_operator"
676
         [(match_operator:SI 4 "arm_comparison_operator"
677
           [(match_operand:SI 2 "s_register_operand" "r,r")
678
            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
679
          (match_operand:SI 1 "s_register_operand" "0,?r")]))
680
   (clobber (reg:CC CC_REGNUM))]
681
  "TARGET_THUMB2"
682
  "*
683
    if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
684
      return \"%i5\\t%0, %1, %2, lsr #31\";
685
 
686
    output_asm_insn (\"cmp\\t%2, %3\", operands);
687
    if (GET_CODE (operands[5]) == AND)
688
      {
689
        output_asm_insn (\"ite\\t%D4\", operands);
690
        output_asm_insn (\"mov%D4\\t%0, #0\", operands);
691
      }
692
    else if (GET_CODE (operands[5]) == MINUS)
693
      {
694
        output_asm_insn (\"ite\\t%D4\", operands);
695
        output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
696
      }
697
    else if (which_alternative != 0)
698
      {
699
        output_asm_insn (\"ite\\t%D4\", operands);
700
        output_asm_insn (\"mov%D4\\t%0, %1\", operands);
701
      }
702
    else
703
      output_asm_insn (\"it\\t%d4\", operands);
704
    return \"%i5%d4\\t%0, %1, #1\";
705
  "
706
  [(set_attr "conds" "clob")
707
   (set_attr "length" "14")]
708
)
709
 
710
(define_insn "*thumb2_cond_sub"
711
  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
712
        (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
713
                  (match_operator:SI 4 "arm_comparison_operator"
714
                   [(match_operand:SI 2 "s_register_operand" "r,r")
715
                    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
716
   (clobber (reg:CC CC_REGNUM))]
717
  "TARGET_THUMB2"
718
  "*
719
    output_asm_insn (\"cmp\\t%2, %3\", operands);
720
    if (which_alternative != 0)
721
      {
722
        output_asm_insn (\"ite\\t%D4\", operands);
723
        output_asm_insn (\"mov%D4\\t%0, %1\", operands);
724
      }
725
    else
726
      output_asm_insn (\"it\\t%d4\", operands);
727
    return \"sub%d4\\t%0, %1, #1\";
728
  "
729
  [(set_attr "conds" "clob")
730
   (set_attr "length" "10,14")]
731
)
732
 
733
(define_insn "*thumb2_negscc"
734
  [(set (match_operand:SI 0 "s_register_operand" "=r")
735
        (neg:SI (match_operator 3 "arm_comparison_operator"
736
                 [(match_operand:SI 1 "s_register_operand" "r")
737
                  (match_operand:SI 2 "arm_rhs_operand" "rI")])))
738
   (clobber (reg:CC CC_REGNUM))]
739
  "TARGET_THUMB2"
740
  "*
741
  if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
742
    return \"asr\\t%0, %1, #31\";
743
 
744
  if (GET_CODE (operands[3]) == NE)
745
    return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0\";
746
 
747
  output_asm_insn (\"cmp\\t%1, %2\", operands);
748
  output_asm_insn (\"ite\\t%D3\", operands);
749
  output_asm_insn (\"mov%D3\\t%0, #0\", operands);
750
  return \"mvn%d3\\t%0, #0\";
751
  "
752
  [(set_attr "conds" "clob")
753
   (set_attr "length" "14")]
754
)
755
 
756
(define_insn "*thumb2_movcond"
757
  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
758
        (if_then_else:SI
759
         (match_operator 5 "arm_comparison_operator"
760
          [(match_operand:SI 3 "s_register_operand" "r,r,r")
761
           (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
762
         (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
763
         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
764
   (clobber (reg:CC CC_REGNUM))]
765
  "TARGET_THUMB2"
766
  "*
767
  if (GET_CODE (operands[5]) == LT
768
      && (operands[4] == const0_rtx))
769
    {
770
      if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
771
        {
772
          if (operands[2] == const0_rtx)
773
            return \"and\\t%0, %1, %3, asr #31\";
774
          return \"ands\\t%0, %1, %3, asr #32\;it\\tcc\;movcc\\t%0, %2\";
775
        }
776
      else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
777
        {
778
          if (operands[1] == const0_rtx)
779
            return \"bic\\t%0, %2, %3, asr #31\";
780
          return \"bics\\t%0, %2, %3, asr #32\;it\\tcs\;movcs\\t%0, %1\";
781
        }
782
      /* The only case that falls through to here is when both ops 1 & 2
783
         are constants.  */
784
    }
785
 
786
  if (GET_CODE (operands[5]) == GE
787
      && (operands[4] == const0_rtx))
788
    {
789
      if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
790
        {
791
          if (operands[2] == const0_rtx)
792
            return \"bic\\t%0, %1, %3, asr #31\";
793
          return \"bics\\t%0, %1, %3, asr #32\;it\\tcs\;movcs\\t%0, %2\";
794
        }
795
      else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
796
        {
797
          if (operands[1] == const0_rtx)
798
            return \"and\\t%0, %2, %3, asr #31\";
799
          return \"ands\\t%0, %2, %3, asr #32\;it\tcc\;movcc\\t%0, %1\";
800
        }
801
      /* The only case that falls through to here is when both ops 1 & 2
802
         are constants.  */
803
    }
804
  if (GET_CODE (operands[4]) == CONST_INT
805
      && !const_ok_for_arm (INTVAL (operands[4])))
806
    output_asm_insn (\"cmn\\t%3, #%n4\", operands);
807
  else
808
    output_asm_insn (\"cmp\\t%3, %4\", operands);
809
  switch (which_alternative)
810
    {
811
    case 0:
812
      output_asm_insn (\"it\\t%D5\", operands);
813
      break;
814
    case 1:
815
      output_asm_insn (\"it\\t%d5\", operands);
816
      break;
817
    case 2:
818
      output_asm_insn (\"ite\\t%d5\", operands);
819
      break;
820
    default:
821
      abort();
822
    }
823
  if (which_alternative != 0)
824
    output_asm_insn (\"mov%d5\\t%0, %1\", operands);
825
  if (which_alternative != 1)
826
    output_asm_insn (\"mov%D5\\t%0, %2\", operands);
827
  return \"\";
828
  "
829
  [(set_attr "conds" "clob")
830
   (set_attr "length" "10,10,14")]
831
)
832
 
833
;; Zero and sign extension instructions.
834
 
835
(define_insn_and_split "*thumb2_zero_extendsidi2"
836
  [(set (match_operand:DI 0 "s_register_operand" "=r")
837
        (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
838
  "TARGET_THUMB2"
839
  "mov%?\\t%Q0, %1\;mov%?\\t%R0, #0"
840
  "&& reload_completed"
841
  [(set (match_dup 0) (match_dup 1))]
842
  "
843
  {
844
    rtx lo_part = gen_lowpart (SImode, operands[0]);
845
    if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
846
      emit_move_insn (lo_part, operands[1]);
847
    operands[0] = gen_highpart (SImode, operands[0]);
848
    operands[1] = const0_rtx;
849
  }
850
  "
851
  [(set_attr "length" "8")
852
   (set_attr "ce_count" "2")
853
   (set_attr "predicable" "yes")]
854
)
855
 
856
(define_insn_and_split "*thumb2_zero_extendhidi2"
857
  [(set (match_operand:DI                 0 "s_register_operand"  "=r,r")
858
        (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
859
  "TARGET_THUMB2"
860
  "@
861
   uxth%?\\t%Q0, %1\;mov%?\\t%R0, #0
862
   ldr%(h%)\\t%Q0, %1\;mov%?\\t%R0, #0"
863
  "&& reload_completed"
864
  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
865
   (set (match_dup 2) (match_dup 3))]
866
  "
867
  {
868
    operands[2] = gen_highpart (SImode, operands[0]);
869
    operands[0] = gen_lowpart (SImode, operands[0]);
870
    operands[3] = const0_rtx;
871
  }
872
  "
873
  [(set_attr "length" "8")
874
   (set_attr "ce_count" "2")
875
   (set_attr "predicable" "yes")
876
   (set_attr "type" "*,load_byte")
877
   (set_attr "pool_range" "*,4092")
878
   (set_attr "neg_pool_range" "*,250")]
879
)
880
 
881
(define_insn_and_split "*thumb2_zero_extendqidi2"
882
  [(set (match_operand:DI                 0 "s_register_operand"  "=r,r")
883
        (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
884
  "TARGET_THUMB2"
885
  "@
886
   uxtb%?\\t%Q0, %1\;mov%?\\t%R0, #0
887
   ldr%(b%)\\t%Q0, %1\;mov%?\\t%R0, #0"
888
  "&& reload_completed"
889
  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
890
   (set (match_dup 2) (match_dup 3))]
891
  "
892
  {
893
    operands[2] = gen_highpart (SImode, operands[0]);
894
    operands[0] = gen_lowpart (SImode, operands[0]);
895
    operands[3] = const0_rtx;
896
  }
897
  "
898
  [(set_attr "length" "8")
899
   (set_attr "ce_count" "2")
900
   (set_attr "predicable" "yes")
901
   (set_attr "type" "*,load_byte")
902
   (set_attr "pool_range" "*,4092")
903
   (set_attr "neg_pool_range" "*,250")]
904
)
905
 
906
(define_insn_and_split "*thumb2_extendsidi2"
907
  [(set (match_operand:DI 0 "s_register_operand" "=r")
908
        (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
909
  "TARGET_THUMB2"
910
  "mov%?\\t%Q0, %1\;asr?\\t%R0, %1, #31"
911
  "&& reload_completed"
912
  [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
913
  {
914
    rtx lo_part = gen_lowpart (SImode, operands[0]);
915
 
916
    if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
917
      emit_move_insn (lo_part, operands[1]);
918
    operands[0] = gen_highpart (SImode, operands[0]);
919
  }
920
  [(set_attr "length" "8")
921
   (set_attr "ce_count" "2")
922
   (set_attr "shift" "1")
923
   (set_attr "predicable" "yes")]
924
)
925
 
926
(define_insn_and_split "*thumb2_extendhidi2"
927
  [(set (match_operand:DI                 0 "s_register_operand"  "=r,r")
928
        (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
929
  "TARGET_THUMB2"
930
  "@
931
   sxth%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
932
   ldrsh%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
933
  "&& reload_completed"
934
  [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
935
   (set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
936
  "
937
  {
938
    operands[2] = gen_highpart (SImode, operands[0]);
939
    operands[0] = gen_lowpart (SImode, operands[0]);
940
  }
941
  "
942
  [(set_attr "length" "8")
943
   (set_attr "ce_count" "2")
944
   (set_attr "predicable" "yes")
945
   (set_attr "type" "*,load_byte")
946
   (set_attr "pool_range" "*,4092")
947
   (set_attr "neg_pool_range" "*,250")]
948
)
949
 
950
(define_insn_and_split "*thumb2_extendqidi2"
951
  [(set (match_operand:DI                 0 "s_register_operand"  "=r,r")
952
        (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
953
  "TARGET_THUMB2"
954
  "@
955
   sxtb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
956
   ldrsb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
957
  "&& reload_completed"
958
  [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
959
   (set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
960
  "
961
  {
962
    operands[2] = gen_highpart (SImode, operands[0]);
963
    operands[0] = gen_lowpart (SImode, operands[0]);
964
  }
965
  "
966
  [(set_attr "length" "8")
967
   (set_attr "ce_count" "2")
968
   (set_attr "predicable" "yes")
969
   (set_attr "type" "*,load_byte")
970
   (set_attr "pool_range" "*,4092")
971
   (set_attr "neg_pool_range" "*,250")]
972
)
973
 
974
;; All supported Thumb2 implementations are armv6, so only that case is
975
;; provided.
976
(define_insn "*thumb2_extendqisi_v6"
977
  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
978
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
979
  "TARGET_THUMB2 && arm_arch6"
980
  "@
981
   sxtb%?\\t%0, %1
982
   ldr%(sb%)\\t%0, %1"
983
  [(set_attr "type" "alu_shift,load_byte")
984
   (set_attr "predicable" "yes")
985
   (set_attr "pool_range" "*,4096")
986
   (set_attr "neg_pool_range" "*,250")]
987
)
988
 
989
(define_insn "*thumb2_zero_extendhisi2_v6"
990
  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
991
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
992
  "TARGET_THUMB2 && arm_arch6"
993
  "@
994
   uxth%?\\t%0, %1
995
   ldr%(h%)\\t%0, %1"
996
  [(set_attr "type" "alu_shift,load_byte")
997
   (set_attr "predicable" "yes")
998
   (set_attr "pool_range" "*,4096")
999
   (set_attr "neg_pool_range" "*,250")]
1000
)
1001
 
1002
(define_insn "*thumb2_zero_extendqisi2_v6"
1003
  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1004
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1005
  "TARGET_THUMB2 && arm_arch6"
1006
  "@
1007
   uxtb%(%)\\t%0, %1
1008
   ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
1009
  [(set_attr "type" "alu_shift,load_byte")
1010
   (set_attr "predicable" "yes")
1011
   (set_attr "pool_range" "*,4096")
1012
   (set_attr "neg_pool_range" "*,250")]
1013
)
1014
 
1015
(define_insn "thumb2_casesi_internal"
1016
  [(parallel [(set (pc)
1017
               (if_then_else
1018
                (leu (match_operand:SI 0 "s_register_operand" "r")
1019
                     (match_operand:SI 1 "arm_rhs_operand" "rI"))
1020
                (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
1021
                                 (label_ref (match_operand 2 "" ""))))
1022
                (label_ref (match_operand 3 "" ""))))
1023
              (clobber (reg:CC CC_REGNUM))
1024
              (clobber (match_scratch:SI 4 "=&r"))
1025
              (use (label_ref (match_dup 2)))])]
1026
  "TARGET_THUMB2 && !flag_pic"
1027
  "* return thumb2_output_casesi(operands);"
1028
  [(set_attr "conds" "clob")
1029
   (set_attr "length" "16")]
1030
)
1031
 
1032
(define_insn "thumb2_casesi_internal_pic"
1033
  [(parallel [(set (pc)
1034
               (if_then_else
1035
                (leu (match_operand:SI 0 "s_register_operand" "r")
1036
                     (match_operand:SI 1 "arm_rhs_operand" "rI"))
1037
                (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
1038
                                 (label_ref (match_operand 2 "" ""))))
1039
                (label_ref (match_operand 3 "" ""))))
1040
              (clobber (reg:CC CC_REGNUM))
1041
              (clobber (match_scratch:SI 4 "=&r"))
1042
              (clobber (match_scratch:SI 5 "=r"))
1043
              (use (label_ref (match_dup 2)))])]
1044
  "TARGET_THUMB2 && flag_pic"
1045
  "* return thumb2_output_casesi(operands);"
1046
  [(set_attr "conds" "clob")
1047
   (set_attr "length" "20")]
1048
)
1049
 
1050
(define_insn_and_split "thumb2_eh_return"
1051
  [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
1052
                    VUNSPEC_EH_RETURN)
1053
   (clobber (match_scratch:SI 1 "=&r"))]
1054
  "TARGET_THUMB2"
1055
  "#"
1056
  "&& reload_completed"
1057
  [(const_int 0)]
1058
  "
1059
  {
1060
    thumb_set_return_address (operands[0], operands[1]);
1061
    DONE;
1062
  }"
1063
)
1064
 
1065
;; Peepholes and insns for 16-bit flag clobbering instructions.
1066
;; The conditional forms of these instructions do not clobber CC.
1067
;; However by the time peepholes are run it is probably too late to do
1068
;; anything useful with this information.
1069
(define_peephole2
1070
  [(set (match_operand:SI          0 "low_register_operand" "")
1071
        (match_operator:SI 3 "thumb_16bit_operator"
1072
         [(match_operand:SI 1  "low_register_operand" "")
1073
          (match_operand:SI 2 "low_register_operand" "")]))]
1074
  "TARGET_THUMB2
1075
   && (rtx_equal_p(operands[0], operands[1])
1076
       || GET_CODE(operands[3]) == PLUS
1077
       || GET_CODE(operands[3]) == MINUS)
1078
   && peep2_regno_dead_p(0, CC_REGNUM)"
1079
  [(parallel
1080
    [(set (match_dup 0)
1081
          (match_op_dup 3
1082
           [(match_dup 1)
1083
            (match_dup 2)]))
1084
     (clobber (reg:CC CC_REGNUM))])]
1085
  ""
1086
)
1087
 
1088
(define_insn "*thumb2_alusi3_short"
1089
  [(set (match_operand:SI          0 "s_register_operand" "=l")
1090
        (match_operator:SI 3 "thumb_16bit_operator"
1091
         [(match_operand:SI 1 "s_register_operand" "0")
1092
          (match_operand:SI 2 "s_register_operand" "l")]))
1093
   (clobber (reg:CC CC_REGNUM))]
1094
  "TARGET_THUMB2 && reload_completed
1095
   && GET_CODE(operands[3]) != PLUS
1096
   && GET_CODE(operands[3]) != MINUS"
1097
  "%I3%!\\t%0, %1, %2"
1098
  [(set_attr "predicable" "yes")
1099
   (set_attr "length" "2")]
1100
)
1101
 
1102
;; Similarly for 16-bit shift instructions
1103
;; There is no 16-bit rotate by immediate instruction.
1104
(define_peephole2
1105
  [(set (match_operand:SI   0 "low_register_operand" "")
1106
        (match_operator:SI  3 "shift_operator"
1107
         [(match_operand:SI 1 "low_register_operand" "")
1108
          (match_operand:SI 2 "low_reg_or_int_operand" "")]))]
1109
  "TARGET_THUMB2
1110
   && peep2_regno_dead_p(0, CC_REGNUM)
1111
   && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
1112
       || REG_P(operands[2]))"
1113
  [(parallel
1114
    [(set (match_dup 0)
1115
          (match_op_dup 3
1116
           [(match_dup 1)
1117
            (match_dup 2)]))
1118
     (clobber (reg:CC CC_REGNUM))])]
1119
  ""
1120
)
1121
 
1122
(define_insn "*thumb2_shiftsi3_short"
1123
  [(set (match_operand:SI   0 "low_register_operand" "=l")
1124
        (match_operator:SI  3 "shift_operator"
1125
         [(match_operand:SI 1 "low_register_operand"  "l")
1126
          (match_operand:SI 2 "low_reg_or_int_operand" "lM")]))
1127
   (clobber (reg:CC CC_REGNUM))]
1128
  "TARGET_THUMB2 && reload_completed
1129
   && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
1130
       || REG_P(operands[2]))"
1131
  "* return arm_output_shift(operands, 2);"
1132
  [(set_attr "predicable" "yes")
1133
   (set_attr "shift" "1")
1134
   (set_attr "length" "2")
1135
   (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
1136
                      (const_string "alu_shift")
1137
                      (const_string "alu_shift_reg")))]
1138
)
1139
 
1140
;; 16-bit load immediate
1141
(define_peephole2
1142
  [(set (match_operand:QHSI 0 "low_register_operand" "")
1143
        (match_operand:QHSI 1 "const_int_operand" ""))]
1144
  "TARGET_THUMB2
1145
   && peep2_regno_dead_p(0, CC_REGNUM)
1146
   && (unsigned HOST_WIDE_INT) INTVAL(operands[1]) < 256"
1147
  [(parallel
1148
    [(set (match_dup 0)
1149
          (match_dup 1))
1150
     (clobber (reg:CC CC_REGNUM))])]
1151
  ""
1152
)
1153
 
1154
(define_insn "*thumb2_mov_shortim"
1155
  [(set (match_operand:QHSI 0 "low_register_operand" "=l")
1156
        (match_operand:QHSI 1 "const_int_operand" "I"))
1157
   (clobber (reg:CC CC_REGNUM))]
1158
  "TARGET_THUMB2 && reload_completed"
1159
  "mov%!\t%0, %1"
1160
  [(set_attr "predicable" "yes")
1161
   (set_attr "length" "2")]
1162
)
1163
 
1164
;; 16-bit add/sub immediate
1165
(define_peephole2
1166
  [(set (match_operand:SI 0 "low_register_operand" "")
1167
        (plus:SI (match_operand:SI 1 "low_register_operand" "")
1168
                 (match_operand:SI 2 "const_int_operand" "")))]
1169
  "TARGET_THUMB2
1170
   && peep2_regno_dead_p(0, CC_REGNUM)
1171
   && ((rtx_equal_p(operands[0], operands[1])
1172
        && INTVAL(operands[2]) > -256 && INTVAL(operands[2]) < 256)
1173
       || (INTVAL(operands[2]) > -8 && INTVAL(operands[2]) < 8))"
1174
  [(parallel
1175
    [(set (match_dup 0)
1176
          (plus:SI (match_dup 1)
1177
                   (match_dup 2)))
1178
     (clobber (reg:CC CC_REGNUM))])]
1179
  ""
1180
)
1181
 
1182
(define_insn "*thumb2_addsi_short"
1183
  [(set (match_operand:SI 0 "low_register_operand" "=l,l")
1184
        (plus:SI (match_operand:SI 1 "low_register_operand" "l,0")
1185
                 (match_operand:SI 2 "low_reg_or_int_operand" "lPt,Ps")))
1186
   (clobber (reg:CC CC_REGNUM))]
1187
  "TARGET_THUMB2 && reload_completed"
1188
  "*
1189
    HOST_WIDE_INT val;
1190
 
1191
    if (GET_CODE (operands[2]) == CONST_INT)
1192
      val = INTVAL(operands[2]);
1193
    else
1194
      val = 0;
1195
 
1196
    /* We prefer eg. subs rn, rn, #1 over adds rn, rn, #0xffffffff.  */
1197
    if (val < 0 && const_ok_for_arm(ARM_SIGN_EXTEND (-val)))
1198
      return \"sub%!\\t%0, %1, #%n2\";
1199
    else
1200
      return \"add%!\\t%0, %1, %2\";
1201
  "
1202
  [(set_attr "predicable" "yes")
1203
   (set_attr "length" "2")]
1204
)
1205
 
1206
(define_insn "divsi3"
1207
  [(set (match_operand:SI         0 "s_register_operand" "=r")
1208
        (div:SI (match_operand:SI 1 "s_register_operand"  "r")
1209
                (match_operand:SI 2 "s_register_operand"  "r")))]
1210
  "TARGET_THUMB2 && arm_arch_hwdiv"
1211
  "sdiv%?\t%0, %1, %2"
1212
  [(set_attr "predicable" "yes")
1213
   (set_attr "insn" "sdiv")]
1214
)
1215
 
1216
(define_insn "udivsi3"
1217
  [(set (match_operand:SI          0 "s_register_operand" "=r")
1218
        (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
1219
                 (match_operand:SI 2 "s_register_operand"  "r")))]
1220
  "TARGET_THUMB2 && arm_arch_hwdiv"
1221
  "udiv%?\t%0, %1, %2"
1222
  [(set_attr "predicable" "yes")
1223
   (set_attr "insn" "udiv")]
1224
)
1225
 
1226
(define_insn "*thumb2_subsi_short"
1227
  [(set (match_operand:SI 0 "low_register_operand" "=l")
1228
        (minus:SI (match_operand:SI 1 "low_register_operand" "l")
1229
                  (match_operand:SI 2 "low_register_operand" "l")))
1230
   (clobber (reg:CC CC_REGNUM))]
1231
  "TARGET_THUMB2 && reload_completed"
1232
  "sub%!\\t%0, %1, %2"
1233
  [(set_attr "predicable" "yes")
1234
   (set_attr "length" "2")]
1235
)
1236
 
1237
;; 16-bit encodings of "muls" and "mul".  We only use these when
1238
;; optimizing for size since "muls" is slow on all known
1239
;; implementations and since "mul" will be generated by
1240
;; "*arm_mulsi3_v6" anyhow.  The assembler will use a 16-bit encoding
1241
;; for "mul" whenever possible anyhow.
1242
(define_peephole2
1243
  [(set (match_operand:SI 0 "low_register_operand" "")
1244
        (mult:SI (match_operand:SI 1 "low_register_operand" "")
1245
                 (match_dup 0)))]
1246
  "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
1247
  [(parallel
1248
    [(set (match_dup 0)
1249
           (mult:SI (match_dup 0) (match_dup 1)))
1250
     (clobber (reg:CC CC_REGNUM))])]
1251
  ""
1252
)
1253
 
1254
(define_peephole2
1255
  [(set (match_operand:SI 0 "low_register_operand" "")
1256
        (mult:SI (match_dup 0)
1257
                 (match_operand:SI 1 "low_register_operand" "")))]
1258
  "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
1259
  [(parallel
1260
    [(set (match_dup 0)
1261
           (mult:SI (match_dup 0) (match_dup 1)))
1262
     (clobber (reg:CC CC_REGNUM))])]
1263
  ""
1264
)
1265
 
1266
(define_insn "*thumb2_mulsi_short"
1267
  [(set (match_operand:SI 0 "low_register_operand" "=l")
1268
        (mult:SI (match_operand:SI 1 "low_register_operand" "%0")
1269
                 (match_operand:SI 2 "low_register_operand" "l")))
1270
   (clobber (reg:CC CC_REGNUM))]
1271
  "TARGET_THUMB2 && optimize_size && reload_completed"
1272
  "mul%!\\t%0, %2, %0"
1273
  [(set_attr "predicable" "yes")
1274
   (set_attr "length" "2")
1275
   (set_attr "insn" "muls")])
1276
 
1277
(define_insn "*thumb2_mulsi_short_compare0"
1278
  [(set (reg:CC_NOOV CC_REGNUM)
1279
        (compare:CC_NOOV
1280
         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1281
                  (match_operand:SI 2 "register_operand" "l"))
1282
         (const_int 0)))
1283
   (set (match_operand:SI 0 "register_operand" "=l")
1284
        (mult:SI (match_dup 1) (match_dup 2)))]
1285
  "TARGET_THUMB2 && optimize_size"
1286
  "muls\\t%0, %2, %0"
1287
  [(set_attr "length" "2")
1288
   (set_attr "insn" "muls")])
1289
 
1290
(define_insn "*thumb2_mulsi_short_compare0_scratch"
1291
  [(set (reg:CC_NOOV CC_REGNUM)
1292
        (compare:CC_NOOV
1293
         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1294
                  (match_operand:SI 2 "register_operand" "l"))
1295
         (const_int 0)))
1296
   (clobber (match_scratch:SI 0 "=l"))]
1297
  "TARGET_THUMB2 && optimize_size"
1298
  "muls\\t%0, %2, %0"
1299
  [(set_attr "length" "2")
1300
   (set_attr "insn" "muls")])
1301
 
1302
(define_insn "*thumb2_cbz"
1303
  [(set (pc) (if_then_else
1304
              (eq (match_operand:SI 0 "s_register_operand" "l,?r")
1305
                  (const_int 0))
1306
              (label_ref (match_operand 1 "" ""))
1307
              (pc)))
1308
   (clobber (reg:CC CC_REGNUM))]
1309
  "TARGET_THUMB2"
1310
  "*
1311
  if (get_attr_length (insn) == 2)
1312
    return \"cbz\\t%0, %l1\";
1313
  else
1314
    return \"cmp\\t%0, #0\;beq\\t%l1\";
1315
  "
1316
  [(set (attr "length")
1317
        (if_then_else
1318
            (and (ge (minus (match_dup 1) (pc)) (const_int 2))
1319
                 (le (minus (match_dup 1) (pc)) (const_int 128))
1320
                 (eq (symbol_ref ("which_alternative")) (const_int 0)))
1321
            (const_int 2)
1322
            (const_int 8)))]
1323
)
1324
 
1325
(define_insn "*thumb2_cbnz"
1326
  [(set (pc) (if_then_else
1327
              (ne (match_operand:SI 0 "s_register_operand" "l,?r")
1328
                  (const_int 0))
1329
              (label_ref (match_operand 1 "" ""))
1330
              (pc)))
1331
   (clobber (reg:CC CC_REGNUM))]
1332
  "TARGET_THUMB2"
1333
  "*
1334
  if (get_attr_length (insn) == 2)
1335
    return \"cbnz\\t%0, %l1\";
1336
  else
1337
    return \"cmp\\t%0, #0\;bne\\t%l1\";
1338
  "
1339
  [(set (attr "length")
1340
        (if_then_else
1341
            (and (ge (minus (match_dup 1) (pc)) (const_int 2))
1342
                 (le (minus (match_dup 1) (pc)) (const_int 128))
1343
                 (eq (symbol_ref ("which_alternative")) (const_int 0)))
1344
            (const_int 2)
1345
            (const_int 8)))]
1346
)
1347
 
1348
;; 16-bit complement
1349
(define_peephole2
1350
  [(set (match_operand:SI 0 "low_register_operand" "")
1351
        (not:SI (match_operand:SI 1 "low_register_operand" "")))]
1352
  "TARGET_THUMB2
1353
   && peep2_regno_dead_p(0, CC_REGNUM)"
1354
  [(parallel
1355
    [(set (match_dup 0)
1356
          (not:SI (match_dup 1)))
1357
     (clobber (reg:CC CC_REGNUM))])]
1358
  ""
1359
)
1360
 
1361
(define_insn "*thumb2_one_cmplsi2_short"
1362
  [(set (match_operand:SI 0 "low_register_operand" "=l")
1363
        (not:SI (match_operand:SI 1 "low_register_operand" "l")))
1364
   (clobber (reg:CC CC_REGNUM))]
1365
  "TARGET_THUMB2 && reload_completed"
1366
  "mvn%!\t%0, %1"
1367
  [(set_attr "predicable" "yes")
1368
   (set_attr "length" "2")]
1369
)
1370
 
1371
;; 16-bit negate
1372
(define_peephole2
1373
  [(set (match_operand:SI 0 "low_register_operand" "")
1374
        (neg:SI (match_operand:SI 1 "low_register_operand" "")))]
1375
  "TARGET_THUMB2
1376
   && peep2_regno_dead_p(0, CC_REGNUM)"
1377
  [(parallel
1378
    [(set (match_dup 0)
1379
          (neg:SI (match_dup 1)))
1380
     (clobber (reg:CC CC_REGNUM))])]
1381
  ""
1382
)
1383
 
1384
(define_insn "*thumb2_negsi2_short"
1385
  [(set (match_operand:SI 0 "low_register_operand" "=l")
1386
        (neg:SI (match_operand:SI 1 "low_register_operand" "l")))
1387
   (clobber (reg:CC CC_REGNUM))]
1388
  "TARGET_THUMB2 && reload_completed"
1389
  "neg%!\t%0, %1"
1390
  [(set_attr "predicable" "yes")
1391
   (set_attr "length" "2")]
1392
)
1393
 
1394
(define_insn "orsi_notsi_si"
1395
  [(set (match_operand:SI 0 "s_register_operand" "=r")
1396
        (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1397
                (match_operand:SI 1 "s_register_operand" "r")))]
1398
  "TARGET_THUMB2"
1399
  "orn%?\\t%0, %1, %2"
1400
  [(set_attr "predicable" "yes")]
1401
)
1402
 
1403
(define_insn "*thumb_orsi_not_shiftsi_si"
1404
  [(set (match_operand:SI 0 "s_register_operand" "=r")
1405
        (ior:SI (not:SI (match_operator:SI 4 "shift_operator"
1406
                         [(match_operand:SI 2 "s_register_operand" "r")
1407
                          (match_operand:SI 3 "const_int_operand" "M")]))
1408
                (match_operand:SI 1 "s_register_operand" "r")))]
1409
  "TARGET_THUMB2"
1410
  "orn%?\\t%0, %1, %2%S4"
1411
  [(set_attr "predicable" "yes")
1412
   (set_attr "shift" "2")
1413
   (set_attr "type" "alu_shift")]
1414
)
1415
 
1416
(define_insn_and_split "*thumb2_iorsi3"
1417
  [(set (match_operand:SI         0 "s_register_operand" "=r,r,r")
1418
        (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1419
                (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1420
  "TARGET_THUMB2"
1421
  "@
1422
   orr%?\\t%0, %1, %2
1423
   orn%?\\t%0, %1, #%B2
1424
   #"
1425
  "TARGET_THUMB2
1426
   && GET_CODE (operands[2]) == CONST_INT
1427
   && !(const_ok_for_arm (INTVAL (operands[2]))
1428
        || const_ok_for_arm (~INTVAL (operands[2])))"
1429
  [(clobber (const_int 0))]
1430
  "
1431
  arm_split_constant  (IOR, SImode, curr_insn,
1432
                       INTVAL (operands[2]), operands[0], operands[1], 0);
1433
  DONE;
1434
  "
1435
  [(set_attr "length" "4,4,16")
1436
   (set_attr "predicable" "yes")]
1437
)

powered by: WebSVN 2.1.0

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