rtl.h (emit_clobber, [...]): Declare.
[official-gcc.git] / gcc / config / arm / vfp.md
blob23aa202778f33d16fc0267f6203f84d646ebdfd0
1 ;; ARM VFP coprocessor Machine Description
2 ;; Copyright (C) 2003, 2005, 2006, 2007 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.
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.
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 ;; <http://www.gnu.org/licenses/>.  */
21 ;; Additional register numbers
22 (define_constants
23   [(VFPCC_REGNUM 127)]
26 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27 ;; Pipeline description
28 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30 (define_automaton "vfp11")
32 ;; There are 3 pipelines in the VFP11 unit.
34 ;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from
35 ;;   fourth stage for simple operations.
37 ;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns.
38 ;;   These insns also uses first execute stage of FMAC pipeline.
40 ;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from
41 ;;   second memory stage for loads.
43 ;; We do not model Write-After-Read hazards.
44 ;; We do not do write scheduling with the arm core, so it is only necessary
45 ;; to model the first stage of each pipeline
46 ;; ??? Need to model LS pipeline properly for load/store multiple?
47 ;; We do not model fmstat properly.  This could be done by modeling pipelines
48 ;; properly and defining an absence set between a dummy fmstat unit and all
49 ;; other vfp units.
51 (define_cpu_unit "fmac" "vfp11")
53 (define_cpu_unit "ds" "vfp11")
55 (define_cpu_unit "vfp_ls" "vfp11")
57 (define_cpu_unit "fmstat" "vfp11")
59 (exclusion_set "fmac,ds" "fmstat")
61 ;; The VFP "type" attributes differ from those used in the FPA model.
62 ;; ffarith      Fast floating point insns, e.g. abs, neg, cpy, cmp.
63 ;; farith       Most arithmetic insns.
64 ;; fmul         Double precision multiply.
65 ;; fdivs        Single precision sqrt or division.
66 ;; fdivd        Double precision sqrt or division.
67 ;; f_flag       fmstat operation
68 ;; f_load[sd]   Floating point load from memory.
69 ;; f_store[sd]  Floating point store to memory.
70 ;; f_2_r        Transfer vfp to arm reg.
71 ;; r_2_f        Transfer arm to vfp reg.
72 ;; f_cvt        Convert floating<->integral
74 (define_insn_reservation "vfp_ffarith" 4
75  (and (eq_attr "generic_vfp" "yes")
76       (eq_attr "type" "ffarith"))
77  "fmac")
79 (define_insn_reservation "vfp_farith" 8
80  (and (eq_attr "generic_vfp" "yes")
81       (eq_attr "type" "farith,f_cvt"))
82  "fmac")
84 (define_insn_reservation "vfp_fmul" 9
85  (and (eq_attr "generic_vfp" "yes")
86       (eq_attr "type" "fmul"))
87  "fmac*2")
89 (define_insn_reservation "vfp_fdivs" 19
90  (and (eq_attr "generic_vfp" "yes")
91       (eq_attr "type" "fdivs"))
92  "ds*15")
94 (define_insn_reservation "vfp_fdivd" 33
95  (and (eq_attr "generic_vfp" "yes")
96       (eq_attr "type" "fdivd"))
97  "fmac+ds*29")
99 ;; Moves to/from arm regs also use the load/store pipeline.
100 (define_insn_reservation "vfp_fload" 4
101  (and (eq_attr "generic_vfp" "yes")
102       (eq_attr "type" "f_loads,f_loadd,r_2_f"))
103  "vfp_ls")
105 (define_insn_reservation "vfp_fstore" 4
106  (and (eq_attr "generic_vfp" "yes")
107       (eq_attr "type" "f_stores,f_stored,f_2_r"))
108  "vfp_ls")
110 (define_insn_reservation "vfp_to_cpsr" 4
111  (and (eq_attr "generic_vfp" "yes")
112       (eq_attr "type" "f_flag"))
113  "fmstat,vfp_ls*3")
115 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
116 ;; Insn pattern
117 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
119 ;; SImode moves
120 ;; ??? For now do not allow loading constants into vfp regs.  This causes
121 ;; problems because small constants get converted into adds.
122 (define_insn "*arm_movsi_vfp"
123   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
124       (match_operand:SI 1 "general_operand"        "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
125   "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
126    && (   s_register_operand (operands[0], SImode)
127        || s_register_operand (operands[1], SImode))"
128   "*
129   switch (which_alternative)
130     {
131     case 0: case 1:
132       return \"mov%?\\t%0, %1\";
133     case 2:
134       return \"mvn%?\\t%0, #%B1\";
135     case 3:
136       return \"movw%?\\t%0, %1\";
137     case 4:
138       return \"ldr%?\\t%0, %1\";
139     case 5:
140       return \"str%?\\t%1, %0\";
141     case 6:
142       return \"fmsr%?\\t%0, %1\\t%@ int\";
143     case 7:
144       return \"fmrs%?\\t%0, %1\\t%@ int\";
145     case 8:
146       return \"fcpys%?\\t%0, %1\\t%@ int\";
147     case 9: case 10:
148       return output_move_vfp (operands);
149     default:
150       gcc_unreachable ();
151     }
152   "
153   [(set_attr "predicable" "yes")
154    (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores")
155    (set_attr "pool_range"     "*,*,*,*,4096,*,*,*,*,1020,*")
156    (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
159 (define_insn "*thumb2_movsi_vfp"
160   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m,*t,r, *t,*t, *Uv")
161       (match_operand:SI 1 "general_operand"        "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
162   "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
163    && (   s_register_operand (operands[0], SImode)
164        || s_register_operand (operands[1], SImode))"
165   "*
166   switch (which_alternative)
167     {
168     case 0: case 1:
169       return \"mov%?\\t%0, %1\";
170     case 2:
171       return \"mvn%?\\t%0, #%B1\";
172     case 3:
173       return \"movw%?\\t%0, %1\";
174     case 4:
175       return \"ldr%?\\t%0, %1\";
176     case 5:
177       return \"str%?\\t%1, %0\";
178     case 6:
179       return \"fmsr%?\\t%0, %1\\t%@ int\";
180     case 7:
181       return \"fmrs%?\\t%0, %1\\t%@ int\";
182     case 8:
183       return \"fcpys%?\\t%0, %1\\t%@ int\";
184     case 9: case 10:
185       return output_move_vfp (operands);
186     default:
187       gcc_unreachable ();
188     }
189   "
190   [(set_attr "predicable" "yes")
191    (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
192    (set_attr "pool_range"     "*,*,*,*,4096,*,*,*,*,1020,*")
193    (set_attr "neg_pool_range" "*,*,*,*,   0,*,*,*,*,1008,*")]
197 ;; DImode moves
199 (define_insn "*arm_movdi_vfp"
200   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
201         (match_operand:DI 1 "di_operand"              "rIK,mi,r,r,w,w,Uvi,w"))]
202   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
203    && (   register_operand (operands[0], DImode)
204        || register_operand (operands[1], DImode))"
205   "*
206   switch (which_alternative)
207     {
208     case 0: 
209       return \"#\";
210     case 1:
211     case 2:
212       return output_move_double (operands);
213     case 3:
214       return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
215     case 4:
216       return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
217     case 5:
218       return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
219     case 6: case 7:
220       return output_move_vfp (operands);
221     default:
222       gcc_unreachable ();
223     }
224   "
225   [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_loadd,f_stored")
226    (set_attr "length" "8,8,8,4,4,4,4,4")
227    (set_attr "pool_range"     "*,1020,*,*,*,*,1020,*")
228    (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
231 (define_insn "*thumb2_movdi_vfp"
232   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
233         (match_operand:DI 1 "di_operand"              "rIK,mi,r,r,w,w,Uvi,w"))]
234   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
235   "*
236   switch (which_alternative)
237     {
238     case 0: case 1: case 2:
239       return (output_move_double (operands));
240     case 3:
241       return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
242     case 4:
243       return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
244     case 5:
245       return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
246     case 6: case 7:
247       return output_move_vfp (operands);
248     default:
249       abort ();
250     }
251   "
252   [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
253    (set_attr "length" "8,8,8,4,4,4,4,4")
254    (set_attr "pool_range"     "*,4096,*,*,*,*,1020,*")
255    (set_attr "neg_pool_range" "*,   0,*,*,*,*,1008,*")]
259 ;; SFmode moves
260 ;; Disparage the w<->r cases because reloading an invalid address is
261 ;; preferable to loading the value via integer registers.
263 (define_insn "*movsf_vfp"
264   [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t  ,Uv,r ,m,t,r")
265         (match_operand:SF 1 "general_operand"      " ?r,t,Dv,UvE,t, mE,r,t,r"))]
266   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
267    && (   s_register_operand (operands[0], SFmode)
268        || s_register_operand (operands[1], SFmode))"
269   "*
270   switch (which_alternative)
271     {
272     case 0:
273       return \"fmsr%?\\t%0, %1\";
274     case 1:
275       return \"fmrs%?\\t%0, %1\";
276     case 2:
277       return \"fconsts%?\\t%0, #%G1\";
278     case 3: case 4:
279       return output_move_vfp (operands);
280     case 5:
281       return \"ldr%?\\t%0, %1\\t%@ float\";
282     case 6:
283       return \"str%?\\t%1, %0\\t%@ float\";
284     case 7:
285       return \"fcpys%?\\t%0, %1\";
286     case 8:
287       return \"mov%?\\t%0, %1\\t%@ float\";
288     default:
289       gcc_unreachable ();
290     }
291   "
292   [(set_attr "predicable" "yes")
293    (set_attr "type"
294      "r_2_f,f_2_r,farith,f_loads,f_stores,load1,store1,ffarith,*")
295    (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
296    (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
299 (define_insn "*thumb2_movsf_vfp"
300   [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t  ,Uv,r ,m,t,r")
301         (match_operand:SF 1 "general_operand"      " ?r,t,Dv,UvE,t, mE,r,t,r"))]
302   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
303    && (   s_register_operand (operands[0], SFmode)
304        || s_register_operand (operands[1], SFmode))"
305   "*
306   switch (which_alternative)
307     {
308     case 0:
309       return \"fmsr%?\\t%0, %1\";
310     case 1:
311       return \"fmrs%?\\t%0, %1\";
312     case 2:
313       return \"fconsts%?\\t%0, #%G1\";
314     case 3: case 4:
315       return output_move_vfp (operands);
316     case 5:
317       return \"ldr%?\\t%0, %1\\t%@ float\";
318     case 6:
319       return \"str%?\\t%1, %0\\t%@ float\";
320     case 7:
321       return \"fcpys%?\\t%0, %1\";
322     case 8:
323       return \"mov%?\\t%0, %1\\t%@ float\";
324     default:
325       gcc_unreachable ();
326     }
327   "
328   [(set_attr "predicable" "yes")
329    (set_attr "type"
330      "r_2_f,f_2_r,farith,f_load,f_store,load1,store1,ffarith,*")
331    (set_attr "pool_range" "*,*,*,1020,*,4092,*,*,*")
332    (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
336 ;; DFmode moves
338 (define_insn "*movdf_vfp"
339   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w  ,Uv,w,r")
340         (match_operand:DF 1 "soft_df_operand"              " ?r,w,Dv,mF,r,UvF,w, w,r"))]
341   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
342    && (   register_operand (operands[0], DFmode)
343        || register_operand (operands[1], DFmode))"
344   "*
345   {
346     switch (which_alternative)
347       {
348       case 0:
349         return \"fmdrr%?\\t%P0, %Q1, %R1\";
350       case 1:
351         return \"fmrrd%?\\t%Q0, %R0, %P1\";
352       case 2:
353         return \"fconstd%?\\t%P0, #%G1\";
354       case 3: case 4:
355         return output_move_double (operands);
356       case 5: case 6:
357         return output_move_vfp (operands);
358       case 7:
359         return \"fcpyd%?\\t%P0, %P1\";
360       case 8:
361         return \"#\";
362       default:
363         gcc_unreachable ();
364       }
365     }
366   "
367   [(set_attr "type"
368      "r_2_f,f_2_r,farith,f_loadd,f_stored,load2,store2,ffarith,*")
369    (set_attr "length" "4,4,4,8,8,4,4,4,8")
370    (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
371    (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")]
374 (define_insn "*thumb2_movdf_vfp"
375   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w  ,Uv,w,r")
376         (match_operand:DF 1 "soft_df_operand"              " ?r,w,Dv,mF,r,UvF,w, w,r"))]
377   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
378   "*
379   {
380     switch (which_alternative)
381       {
382       case 0:
383         return \"fmdrr%?\\t%P0, %Q1, %R1\";
384       case 1:
385         return \"fmrrd%?\\t%Q0, %R0, %P1\";
386       case 2:
387         return \"fconstd%?\\t%P0, #%G1\";
388       case 3: case 4: case 8:
389         return output_move_double (operands);
390       case 5: case 6:
391         return output_move_vfp (operands);
392       case 7:
393         return \"fcpyd%?\\t%P0, %P1\";
394       default:
395         abort ();
396       }
397     }
398   "
399   [(set_attr "type"
400      "r_2_f,f_2_r,farith,load2,store2,f_load,f_store,ffarith,*")
401    (set_attr "length" "4,4,4,8,8,4,4,4,8")
402    (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*")
403    (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")]
407 ;; Conditional move patterns
409 (define_insn "*movsfcc_vfp"
410   [(set (match_operand:SF   0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
411         (if_then_else:SF
412           (match_operator   3 "arm_comparison_operator"
413             [(match_operand 4 "cc_register" "") (const_int 0)])
414           (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
415           (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
416   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
417   "@
418    fcpys%D3\\t%0, %2
419    fcpys%d3\\t%0, %1
420    fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
421    fmsr%D3\\t%0, %2
422    fmsr%d3\\t%0, %1
423    fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
424    fmrs%D3\\t%0, %2
425    fmrs%d3\\t%0, %1
426    fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
427    [(set_attr "conds" "use")
428     (set_attr "length" "4,4,8,4,4,8,4,4,8")
429     (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
432 (define_insn "*thumb2_movsfcc_vfp"
433   [(set (match_operand:SF   0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
434         (if_then_else:SF
435           (match_operator   3 "arm_comparison_operator"
436             [(match_operand 4 "cc_register" "") (const_int 0)])
437           (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
438           (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
439   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
440   "@
441    it\\t%D3\;fcpys%D3\\t%0, %2
442    it\\t%d3\;fcpys%d3\\t%0, %1
443    ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
444    it\\t%D3\;fmsr%D3\\t%0, %2
445    it\\t%d3\;fmsr%d3\\t%0, %1
446    ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
447    it\\t%D3\;fmrs%D3\\t%0, %2
448    it\\t%d3\;fmrs%d3\\t%0, %1
449    ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
450    [(set_attr "conds" "use")
451     (set_attr "length" "6,6,10,6,6,10,6,6,10")
452     (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
455 (define_insn "*movdfcc_vfp"
456   [(set (match_operand:DF   0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
457         (if_then_else:DF
458           (match_operator   3 "arm_comparison_operator"
459             [(match_operand 4 "cc_register" "") (const_int 0)])
460           (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
461           (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
462   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
463   "@
464    fcpyd%D3\\t%P0, %P2
465    fcpyd%d3\\t%P0, %P1
466    fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
467    fmdrr%D3\\t%P0, %Q2, %R2
468    fmdrr%d3\\t%P0, %Q1, %R1
469    fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
470    fmrrd%D3\\t%Q0, %R0, %P2
471    fmrrd%d3\\t%Q0, %R0, %P1
472    fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
473    [(set_attr "conds" "use")
474     (set_attr "length" "4,4,8,4,4,8,4,4,8")
475     (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
478 (define_insn "*thumb2_movdfcc_vfp"
479   [(set (match_operand:DF   0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
480         (if_then_else:DF
481           (match_operator   3 "arm_comparison_operator"
482             [(match_operand 4 "cc_register" "") (const_int 0)])
483           (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
484           (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
485   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
486   "@
487    it\\t%D3\;fcpyd%D3\\t%P0, %P2
488    it\\t%d3\;fcpyd%d3\\t%P0, %P1
489    ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
490    it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2
491    it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1
492    ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
493    it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2
494    it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1
495    ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
496    [(set_attr "conds" "use")
497     (set_attr "length" "6,6,10,6,6,10,6,6,10")
498     (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
502 ;; Sign manipulation functions
504 (define_insn "*abssf2_vfp"
505   [(set (match_operand:SF         0 "s_register_operand" "=t")
506         (abs:SF (match_operand:SF 1 "s_register_operand" "t")))]
507   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
508   "fabss%?\\t%0, %1"
509   [(set_attr "predicable" "yes")
510    (set_attr "type" "ffarith")]
513 (define_insn "*absdf2_vfp"
514   [(set (match_operand:DF         0 "s_register_operand" "=w")
515         (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
516   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
517   "fabsd%?\\t%P0, %P1"
518   [(set_attr "predicable" "yes")
519    (set_attr "type" "ffarith")]
522 (define_insn "*negsf2_vfp"
523   [(set (match_operand:SF         0 "s_register_operand" "=t,?r")
524         (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))]
525   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
526   "@
527    fnegs%?\\t%0, %1
528    eor%?\\t%0, %1, #-2147483648"
529   [(set_attr "predicable" "yes")
530    (set_attr "type" "ffarith")]
533 (define_insn_and_split "*negdf2_vfp"
534   [(set (match_operand:DF         0 "s_register_operand" "=w,?r,?r")
535         (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
536   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
537   "@
538    fnegd%?\\t%P0, %P1
539    #
540    #"
541   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
542    && arm_general_register_operand (operands[0], DFmode)"
543   [(set (match_dup 0) (match_dup 1))]
544   "
545   if (REGNO (operands[0]) == REGNO (operands[1]))
546     {
547       operands[0] = gen_highpart (SImode, operands[0]);
548       operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
549     }
550   else
551     {
552       rtx in_hi, in_lo, out_hi, out_lo;
554       in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
555                            GEN_INT (0x80000000));
556       in_lo = gen_lowpart (SImode, operands[1]);
557       out_hi = gen_highpart (SImode, operands[0]);
558       out_lo = gen_lowpart (SImode, operands[0]);
560       if (REGNO (in_lo) == REGNO (out_hi))
561         {
562           emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
563           operands[0] = out_hi;
564           operands[1] = in_hi;
565         }
566       else
567         {
568           emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
569           operands[0] = out_lo;
570           operands[1] = in_lo;
571         }
572     }
573   "
574   [(set_attr "predicable" "yes")
575    (set_attr "length" "4,4,8")
576    (set_attr "type" "ffarith")]
580 ;; Arithmetic insns
582 (define_insn "*addsf3_vfp"
583   [(set (match_operand:SF          0 "s_register_operand" "=t")
584         (plus:SF (match_operand:SF 1 "s_register_operand" "t")
585                  (match_operand:SF 2 "s_register_operand" "t")))]
586   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
587   "fadds%?\\t%0, %1, %2"
588   [(set_attr "predicable" "yes")
589    (set_attr "type" "farith")]
592 (define_insn "*adddf3_vfp"
593   [(set (match_operand:DF          0 "s_register_operand" "=w")
594         (plus:DF (match_operand:DF 1 "s_register_operand" "w")
595                  (match_operand:DF 2 "s_register_operand" "w")))]
596   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
597   "faddd%?\\t%P0, %P1, %P2"
598   [(set_attr "predicable" "yes")
599    (set_attr "type" "farith")]
603 (define_insn "*subsf3_vfp"
604   [(set (match_operand:SF           0 "s_register_operand" "=t")
605         (minus:SF (match_operand:SF 1 "s_register_operand" "t")
606                   (match_operand:SF 2 "s_register_operand" "t")))]
607   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
608   "fsubs%?\\t%0, %1, %2"
609   [(set_attr "predicable" "yes")
610    (set_attr "type" "farith")]
613 (define_insn "*subdf3_vfp"
614   [(set (match_operand:DF           0 "s_register_operand" "=w")
615         (minus:DF (match_operand:DF 1 "s_register_operand" "w")
616                   (match_operand:DF 2 "s_register_operand" "w")))]
617   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
618   "fsubd%?\\t%P0, %P1, %P2"
619   [(set_attr "predicable" "yes")
620    (set_attr "type" "farith")]
624 ;; Division insns
626 (define_insn "*divsf3_vfp"
627   [(set (match_operand:SF         0 "s_register_operand" "+t")
628         (div:SF (match_operand:SF 1 "s_register_operand" "t")
629                 (match_operand:SF 2 "s_register_operand" "t")))]
630   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
631   "fdivs%?\\t%0, %1, %2"
632   [(set_attr "predicable" "yes")
633    (set_attr "type" "fdivs")]
636 (define_insn "*divdf3_vfp"
637   [(set (match_operand:DF         0 "s_register_operand" "+w")
638         (div:DF (match_operand:DF 1 "s_register_operand" "w")
639                 (match_operand:DF 2 "s_register_operand" "w")))]
640   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
641   "fdivd%?\\t%P0, %P1, %P2"
642   [(set_attr "predicable" "yes")
643    (set_attr "type" "fdivd")]
647 ;; Multiplication insns
649 (define_insn "*mulsf3_vfp"
650   [(set (match_operand:SF          0 "s_register_operand" "+t")
651         (mult:SF (match_operand:SF 1 "s_register_operand" "t")
652                  (match_operand:SF 2 "s_register_operand" "t")))]
653   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
654   "fmuls%?\\t%0, %1, %2"
655   [(set_attr "predicable" "yes")
656    (set_attr "type" "farith")]
659 (define_insn "*muldf3_vfp"
660   [(set (match_operand:DF          0 "s_register_operand" "+w")
661         (mult:DF (match_operand:DF 1 "s_register_operand" "w")
662                  (match_operand:DF 2 "s_register_operand" "w")))]
663   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
664   "fmuld%?\\t%P0, %P1, %P2"
665   [(set_attr "predicable" "yes")
666    (set_attr "type" "fmul")]
670 (define_insn "*mulsf3negsf_vfp"
671   [(set (match_operand:SF                  0 "s_register_operand" "+t")
672         (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
673                  (match_operand:SF         2 "s_register_operand" "t")))]
674   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
675   "fnmuls%?\\t%0, %1, %2"
676   [(set_attr "predicable" "yes")
677    (set_attr "type" "farith")]
680 (define_insn "*muldf3negdf_vfp"
681   [(set (match_operand:DF                  0 "s_register_operand" "+w")
682         (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
683                  (match_operand:DF         2 "s_register_operand" "w")))]
684   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
685   "fnmuld%?\\t%P0, %P1, %P2"
686   [(set_attr "predicable" "yes")
687    (set_attr "type" "fmul")]
691 ;; Multiply-accumulate insns
693 ;; 0 = 1 * 2 + 0
694 (define_insn "*mulsf3addsf_vfp"
695   [(set (match_operand:SF                   0 "s_register_operand" "=t")
696         (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
697                           (match_operand:SF 3 "s_register_operand" "t"))
698                  (match_operand:SF          1 "s_register_operand" "0")))]
699   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
700   "fmacs%?\\t%0, %2, %3"
701   [(set_attr "predicable" "yes")
702    (set_attr "type" "farith")]
705 (define_insn "*muldf3adddf_vfp"
706   [(set (match_operand:DF                   0 "s_register_operand" "=w")
707         (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
708                           (match_operand:DF 3 "s_register_operand" "w"))
709                  (match_operand:DF          1 "s_register_operand" "0")))]
710   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
711   "fmacd%?\\t%P0, %P2, %P3"
712   [(set_attr "predicable" "yes")
713    (set_attr "type" "fmul")]
716 ;; 0 = 1 * 2 - 0
717 (define_insn "*mulsf3subsf_vfp"
718   [(set (match_operand:SF                    0 "s_register_operand" "=t")
719         (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
720                            (match_operand:SF 3 "s_register_operand" "t"))
721                   (match_operand:SF          1 "s_register_operand" "0")))]
722   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
723   "fmscs%?\\t%0, %2, %3"
724   [(set_attr "predicable" "yes")
725    (set_attr "type" "farith")]
728 (define_insn "*muldf3subdf_vfp"
729   [(set (match_operand:DF                    0 "s_register_operand" "=w")
730         (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
731                            (match_operand:DF 3 "s_register_operand" "w"))
732                   (match_operand:DF          1 "s_register_operand" "0")))]
733   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
734   "fmscd%?\\t%P0, %P2, %P3"
735   [(set_attr "predicable" "yes")
736    (set_attr "type" "fmul")]
739 ;; 0 = -(1 * 2) + 0
740 (define_insn "*mulsf3negsfaddsf_vfp"
741   [(set (match_operand:SF                    0 "s_register_operand" "=t")
742         (minus:SF (match_operand:SF          1 "s_register_operand" "0")
743                   (mult:SF (match_operand:SF 2 "s_register_operand" "t")
744                            (match_operand:SF 3 "s_register_operand" "t"))))]
745   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
746   "fnmacs%?\\t%0, %2, %3"
747   [(set_attr "predicable" "yes")
748    (set_attr "type" "farith")]
751 (define_insn "*fmuldf3negdfadddf_vfp"
752   [(set (match_operand:DF                    0 "s_register_operand" "=w")
753         (minus:DF (match_operand:DF          1 "s_register_operand" "0")
754                   (mult:DF (match_operand:DF 2 "s_register_operand" "w")
755                            (match_operand:DF 3 "s_register_operand" "w"))))]
756   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
757   "fnmacd%?\\t%P0, %P2, %P3"
758   [(set_attr "predicable" "yes")
759    (set_attr "type" "fmul")]
763 ;; 0 = -(1 * 2) - 0
764 (define_insn "*mulsf3negsfsubsf_vfp"
765   [(set (match_operand:SF                     0 "s_register_operand" "=t")
766         (minus:SF (mult:SF
767                     (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
768                     (match_operand:SF         3 "s_register_operand" "t"))
769                   (match_operand:SF           1 "s_register_operand" "0")))]
770   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
771   "fnmscs%?\\t%0, %2, %3"
772   [(set_attr "predicable" "yes")
773    (set_attr "type" "farith")]
776 (define_insn "*muldf3negdfsubdf_vfp"
777   [(set (match_operand:DF                     0 "s_register_operand" "=w")
778         (minus:DF (mult:DF
779                     (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
780                     (match_operand:DF         3 "s_register_operand" "w"))
781                   (match_operand:DF           1 "s_register_operand" "0")))]
782   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
783   "fnmscd%?\\t%P0, %P2, %P3"
784   [(set_attr "predicable" "yes")
785    (set_attr "type" "fmul")]
789 ;; Conversion routines
791 (define_insn "*extendsfdf2_vfp"
792   [(set (match_operand:DF                  0 "s_register_operand" "=w")
793         (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
794   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
795   "fcvtds%?\\t%P0, %1"
796   [(set_attr "predicable" "yes")
797    (set_attr "type" "f_cvt")]
800 (define_insn "*truncdfsf2_vfp"
801   [(set (match_operand:SF                  0 "s_register_operand" "=t")
802         (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
803   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
804   "fcvtsd%?\\t%0, %P1"
805   [(set_attr "predicable" "yes")
806    (set_attr "type" "f_cvt")]
809 (define_insn "*truncsisf2_vfp"
810   [(set (match_operand:SI                 0 "s_register_operand" "=t")
811         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
812   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
813   "ftosizs%?\\t%0, %1"
814   [(set_attr "predicable" "yes")
815    (set_attr "type" "f_cvt")]
818 (define_insn "*truncsidf2_vfp"
819   [(set (match_operand:SI                 0 "s_register_operand" "=t")
820         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
821   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
822   "ftosizd%?\\t%0, %P1"
823   [(set_attr "predicable" "yes")
824    (set_attr "type" "f_cvt")]
828 (define_insn "fixuns_truncsfsi2"
829   [(set (match_operand:SI                 0 "s_register_operand" "=t")
830         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
831   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
832   "ftouizs%?\\t%0, %1"
833   [(set_attr "predicable" "yes")
834    (set_attr "type" "f_cvt")]
837 (define_insn "fixuns_truncdfsi2"
838   [(set (match_operand:SI                 0 "s_register_operand" "=t")
839         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
840   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
841   "ftouizd%?\\t%0, %P1"
842   [(set_attr "predicable" "yes")
843    (set_attr "type" "f_cvt")]
847 (define_insn "*floatsisf2_vfp"
848   [(set (match_operand:SF           0 "s_register_operand" "=t")
849         (float:SF (match_operand:SI 1 "s_register_operand" "t")))]
850   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
851   "fsitos%?\\t%0, %1"
852   [(set_attr "predicable" "yes")
853    (set_attr "type" "f_cvt")]
856 (define_insn "*floatsidf2_vfp"
857   [(set (match_operand:DF           0 "s_register_operand" "=w")
858         (float:DF (match_operand:SI 1 "s_register_operand" "t")))]
859   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
860   "fsitod%?\\t%P0, %1"
861   [(set_attr "predicable" "yes")
862    (set_attr "type" "f_cvt")]
866 (define_insn "floatunssisf2"
867   [(set (match_operand:SF           0 "s_register_operand" "=t")
868         (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))]
869   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
870   "fuitos%?\\t%0, %1"
871   [(set_attr "predicable" "yes")
872    (set_attr "type" "f_cvt")]
875 (define_insn "floatunssidf2"
876   [(set (match_operand:DF           0 "s_register_operand" "=w")
877         (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
878   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
879   "fuitod%?\\t%P0, %1"
880   [(set_attr "predicable" "yes")
881    (set_attr "type" "f_cvt")]
885 ;; Sqrt insns.
887 (define_insn "*sqrtsf2_vfp"
888   [(set (match_operand:SF          0 "s_register_operand" "=t")
889         (sqrt:SF (match_operand:SF 1 "s_register_operand" "t")))]
890   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
891   "fsqrts%?\\t%0, %1"
892   [(set_attr "predicable" "yes")
893    (set_attr "type" "fdivs")]
896 (define_insn "*sqrtdf2_vfp"
897   [(set (match_operand:DF          0 "s_register_operand" "=w")
898         (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
899   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
900   "fsqrtd%?\\t%P0, %P1"
901   [(set_attr "predicable" "yes")
902    (set_attr "type" "fdivd")]
906 ;; Patterns to split/copy vfp condition flags.
908 (define_insn "*movcc_vfp"
909   [(set (reg CC_REGNUM)
910         (reg VFPCC_REGNUM))]
911   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
912   "fmstat%?"
913   [(set_attr "conds" "set")
914    (set_attr "type" "f_flag")]
917 (define_insn_and_split "*cmpsf_split_vfp"
918   [(set (reg:CCFP CC_REGNUM)
919         (compare:CCFP (match_operand:SF 0 "s_register_operand"  "t")
920                       (match_operand:SF 1 "vfp_compare_operand" "tG")))]
921   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
922   "#"
923   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
924   [(set (reg:CCFP VFPCC_REGNUM)
925         (compare:CCFP (match_dup 0)
926                       (match_dup 1)))
927    (set (reg:CCFP CC_REGNUM)
928         (reg:CCFP VFPCC_REGNUM))]
929   ""
932 (define_insn_and_split "*cmpsf_trap_split_vfp"
933   [(set (reg:CCFPE CC_REGNUM)
934         (compare:CCFPE (match_operand:SF 0 "s_register_operand"  "t")
935                        (match_operand:SF 1 "vfp_compare_operand" "tG")))]
936   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
937   "#"
938   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
939   [(set (reg:CCFPE VFPCC_REGNUM)
940         (compare:CCFPE (match_dup 0)
941                        (match_dup 1)))
942    (set (reg:CCFPE CC_REGNUM)
943         (reg:CCFPE VFPCC_REGNUM))]
944   ""
947 (define_insn_and_split "*cmpdf_split_vfp"
948   [(set (reg:CCFP CC_REGNUM)
949         (compare:CCFP (match_operand:DF 0 "s_register_operand"  "w")
950                       (match_operand:DF 1 "vfp_compare_operand" "wG")))]
951   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
952   "#"
953   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
954   [(set (reg:CCFP VFPCC_REGNUM)
955         (compare:CCFP (match_dup 0)
956                        (match_dup 1)))
957    (set (reg:CCFP CC_REGNUM)
958         (reg:CCFPE VFPCC_REGNUM))]
959   ""
962 (define_insn_and_split "*cmpdf_trap_split_vfp"
963   [(set (reg:CCFPE CC_REGNUM)
964         (compare:CCFPE (match_operand:DF 0 "s_register_operand"  "w")
965                        (match_operand:DF 1 "vfp_compare_operand" "wG")))]
966   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
967   "#"
968   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
969   [(set (reg:CCFPE VFPCC_REGNUM)
970         (compare:CCFPE (match_dup 0)
971                        (match_dup 1)))
972    (set (reg:CCFPE CC_REGNUM)
973         (reg:CCFPE VFPCC_REGNUM))]
974   ""
978 ;; Comparison patterns
980 (define_insn "*cmpsf_vfp"
981   [(set (reg:CCFP VFPCC_REGNUM)
982         (compare:CCFP (match_operand:SF 0 "s_register_operand"  "t,t")
983                       (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
984   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
985   "@
986    fcmps%?\\t%0, %1
987    fcmpzs%?\\t%0"
988   [(set_attr "predicable" "yes")
989    (set_attr "type" "ffarith")]
992 (define_insn "*cmpsf_trap_vfp"
993   [(set (reg:CCFPE VFPCC_REGNUM)
994         (compare:CCFPE (match_operand:SF 0 "s_register_operand"  "t,t")
995                        (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
996   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
997   "@
998    fcmpes%?\\t%0, %1
999    fcmpezs%?\\t%0"
1000   [(set_attr "predicable" "yes")
1001    (set_attr "type" "ffarith")]
1004 (define_insn "*cmpdf_vfp"
1005   [(set (reg:CCFP VFPCC_REGNUM)
1006         (compare:CCFP (match_operand:DF 0 "s_register_operand"  "w,w")
1007                       (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1008   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1009   "@
1010    fcmpd%?\\t%P0, %P1
1011    fcmpzd%?\\t%P0"
1012   [(set_attr "predicable" "yes")
1013    (set_attr "type" "ffarith")]
1016 (define_insn "*cmpdf_trap_vfp"
1017   [(set (reg:CCFPE VFPCC_REGNUM)
1018         (compare:CCFPE (match_operand:DF 0 "s_register_operand"  "w,w")
1019                        (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1020   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1021   "@
1022    fcmped%?\\t%P0, %P1
1023    fcmpezd%?\\t%P0"
1024   [(set_attr "predicable" "yes")
1025    (set_attr "type" "ffarith")]
1029 ;; Store multiple insn used in function prologue.
1031 (define_insn "*push_multi_vfp"
1032   [(match_parallel 2 "multi_register_push"
1033     [(set (match_operand:BLK 0 "memory_operand" "=m")
1034           (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
1035                       UNSPEC_PUSH_MULT))])]
1036   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1037   "* return vfp_output_fstmd (operands);"
1038   [(set_attr "type" "f_stored")]
1042 ;; Unimplemented insns:
1043 ;; fldm*
1044 ;; fstm*
1045 ;; fmdhr et al (VFPv1)
1046 ;; Support for xD (single precision only) variants.
1047 ;; fmrrs, fmsrr