* varasm.c (bss_initializer_p): Remove static.
[official-gcc.git] / gcc / config / rs6000 / dfp.md
blob7dd62b7173685891e8b99b8ffd98e473bb4657d7
1 ;; Decimal Floating Point (DFP) patterns.
2 ;; Copyright (C) 2007-2012 Free Software Foundation, Inc.
3 ;; Contributed by Ben Elliston (bje@au.ibm.com) and Peter Bergner
4 ;; (bergner@vnet.ibm.com).
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify it
9 ;; under the terms of the GNU General Public License as published
10 ;; by the Free Software Foundation; either version 3, or (at your
11 ;; option) any later version.
13 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
14 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16 ;; License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
23 ;; UNSPEC usage
26 (define_c_enum "unspec"
27   [UNSPEC_MOVSD_LOAD
28    UNSPEC_MOVSD_STORE
29   ])
32 (define_expand "movsd"
33   [(set (match_operand:SD 0 "nonimmediate_operand" "")
34         (match_operand:SD 1 "any_operand" ""))]
35   "TARGET_HARD_FLOAT && TARGET_FPRS"
36   "{ rs6000_emit_move (operands[0], operands[1], SDmode); DONE; }")
38 (define_split
39   [(set (match_operand:SD 0 "gpc_reg_operand" "")
40         (match_operand:SD 1 "const_double_operand" ""))]
41   "reload_completed
42    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
43        || (GET_CODE (operands[0]) == SUBREG
44            && GET_CODE (SUBREG_REG (operands[0])) == REG
45            && REGNO (SUBREG_REG (operands[0])) <= 31))"
46   [(set (match_dup 2) (match_dup 3))]
47   "
49   long l;
50   REAL_VALUE_TYPE rv;
52   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
53   REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
55   if (! TARGET_POWERPC64)
56     operands[2] = operand_subword (operands[0], 0, 0, SDmode);
57   else
58     operands[2] = gen_lowpart (SImode, operands[0]);
60   operands[3] = gen_int_mode (l, SImode);
61 }")
63 (define_insn "movsd_hardfloat"
64   [(set (match_operand:SD 0 "nonimmediate_operand" "=r,r,m,f,*c*l,!r,*h,!r,!r")
65         (match_operand:SD 1 "input_operand"        "r,m,r,f,r,h,0,G,Fn"))]
66   "(gpc_reg_operand (operands[0], SDmode)
67    || gpc_reg_operand (operands[1], SDmode))
68    && (TARGET_HARD_FLOAT && TARGET_FPRS)"
69   "@
70    mr %0,%1
71    lwz%U1%X1 %0,%1
72    stw%U0%X0 %1,%0
73    fmr %0,%1
74    mt%0 %1
75    mf%1 %0
76    nop
77    #
78    #"
79   [(set_attr "type" "*,load,store,fp,mtjmpr,mfjmpr,*,*,*")
80    (set_attr "length" "4,4,4,4,4,4,4,4,8")])
82 (define_insn "movsd_softfloat"
83   [(set (match_operand:SD 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,r,*h")
84         (match_operand:SD 1 "input_operand" "r,r,h,m,r,I,L,R,G,Fn,0"))]
85   "(gpc_reg_operand (operands[0], SDmode)
86    || gpc_reg_operand (operands[1], SDmode))
87    && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
88   "@
89    mr %0,%1
90    mt%0 %1
91    mf%1 %0
92    lwz%U1%X1 %0,%1
93    stw%U0%X0 %1,%0
94    li %0,%1
95    lis %0,%v1
96    la %0,%a1
97    #
98    #
99    nop"
100   [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*,*")
101    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,4")])
103 (define_insn "movsd_store"
104   [(set (match_operand:DD 0 "nonimmediate_operand" "=m")
105         (unspec:DD [(match_operand:SD 1 "input_operand" "d")]
106                    UNSPEC_MOVSD_STORE))]
107   "(gpc_reg_operand (operands[0], DDmode)
108    || gpc_reg_operand (operands[1], SDmode))
109    && TARGET_HARD_FLOAT && TARGET_FPRS"
110   "stfd%U0%X0 %1,%0"
111   [(set_attr "type" "fpstore")
112    (set_attr "length" "4")])
114 (define_insn "movsd_load"
115   [(set (match_operand:SD 0 "nonimmediate_operand" "=f")
116         (unspec:SD [(match_operand:DD 1 "input_operand" "m")]
117                    UNSPEC_MOVSD_LOAD))]
118   "(gpc_reg_operand (operands[0], SDmode)
119    || gpc_reg_operand (operands[1], DDmode))
120    && TARGET_HARD_FLOAT && TARGET_FPRS"
121   "lfd%U1%X1 %0,%1"
122   [(set_attr "type" "fpload")
123    (set_attr "length" "4")])
125 ;; Hardware support for decimal floating point operations.
127 (define_insn "extendsddd2"
128   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
129         (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
130   "TARGET_DFP"
131   "dctdp %0,%1"
132   [(set_attr "type" "fp")])
134 (define_expand "extendsdtd2"
135   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
136         (float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))]
137   "TARGET_DFP"
139   rtx tmp = gen_reg_rtx (DDmode);
140   emit_insn (gen_extendsddd2 (tmp, operands[1]));
141   emit_insn (gen_extendddtd2 (operands[0], tmp));
142   DONE;
145 (define_insn "truncddsd2"
146   [(set (match_operand:SD 0 "gpc_reg_operand" "=f")
147         (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))]
148   "TARGET_DFP"
149   "drsp %0,%1"
150   [(set_attr "type" "fp")])
152 (define_expand "negdd2"
153   [(set (match_operand:DD 0 "gpc_reg_operand" "")
154         (neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
155   "TARGET_HARD_FLOAT && TARGET_FPRS"
156   "")
158 (define_insn "*negdd2_fpr"
159   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
160         (neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
161   "TARGET_HARD_FLOAT && TARGET_FPRS"
162   "fneg %0,%1"
163   [(set_attr "type" "fp")])
165 (define_expand "absdd2"
166   [(set (match_operand:DD 0 "gpc_reg_operand" "")
167         (abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
168   "TARGET_HARD_FLOAT && TARGET_FPRS"
169   "")
171 (define_insn "*absdd2_fpr"
172   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
173         (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
174   "TARGET_HARD_FLOAT && TARGET_FPRS"
175   "fabs %0,%1"
176   [(set_attr "type" "fp")])
178 (define_insn "*nabsdd2_fpr"
179   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
180         (neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))]
181   "TARGET_HARD_FLOAT && TARGET_FPRS"
182   "fnabs %0,%1"
183   [(set_attr "type" "fp")])
185 (define_expand "movdd"
186   [(set (match_operand:DD 0 "nonimmediate_operand" "")
187         (match_operand:DD 1 "any_operand" ""))]
188   ""
189   "{ rs6000_emit_move (operands[0], operands[1], DDmode); DONE; }")
191 (define_split
192   [(set (match_operand:DD 0 "gpc_reg_operand" "")
193         (match_operand:DD 1 "const_int_operand" ""))]
194   "! TARGET_POWERPC64 && reload_completed
195    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
196        || (GET_CODE (operands[0]) == SUBREG
197            && GET_CODE (SUBREG_REG (operands[0])) == REG
198            && REGNO (SUBREG_REG (operands[0])) <= 31))"
199   [(set (match_dup 2) (match_dup 4))
200    (set (match_dup 3) (match_dup 1))]
201   "
203   int endian = (WORDS_BIG_ENDIAN == 0);
204   HOST_WIDE_INT value = INTVAL (operands[1]);
206   operands[2] = operand_subword (operands[0], endian, 0, DDmode);
207   operands[3] = operand_subword (operands[0], 1 - endian, 0, DDmode);
208 #if HOST_BITS_PER_WIDE_INT == 32
209   operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
210 #else
211   operands[4] = GEN_INT (value >> 32);
212   operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
213 #endif
216 (define_split
217   [(set (match_operand:DD 0 "gpc_reg_operand" "")
218         (match_operand:DD 1 "const_double_operand" ""))]
219   "! TARGET_POWERPC64 && reload_completed
220    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
221        || (GET_CODE (operands[0]) == SUBREG
222            && GET_CODE (SUBREG_REG (operands[0])) == REG
223            && REGNO (SUBREG_REG (operands[0])) <= 31))"
224   [(set (match_dup 2) (match_dup 4))
225    (set (match_dup 3) (match_dup 5))]
226   "
228   int endian = (WORDS_BIG_ENDIAN == 0);
229   long l[2];
230   REAL_VALUE_TYPE rv;
232   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
233   REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
235   operands[2] = operand_subword (operands[0], endian, 0, DDmode);
236   operands[3] = operand_subword (operands[0], 1 - endian, 0, DDmode);
237   operands[4] = gen_int_mode (l[endian], SImode);
238   operands[5] = gen_int_mode (l[1 - endian], SImode);
241 (define_split
242   [(set (match_operand:DD 0 "gpc_reg_operand" "")
243         (match_operand:DD 1 "const_double_operand" ""))]
244   "TARGET_POWERPC64 && reload_completed
245    && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
246        || (GET_CODE (operands[0]) == SUBREG
247            && GET_CODE (SUBREG_REG (operands[0])) == REG
248            && REGNO (SUBREG_REG (operands[0])) <= 31))"
249   [(set (match_dup 2) (match_dup 3))]
250   "
252   int endian = (WORDS_BIG_ENDIAN == 0);
253   long l[2];
254   REAL_VALUE_TYPE rv;
255 #if HOST_BITS_PER_WIDE_INT >= 64
256   HOST_WIDE_INT val;
257 #endif
259   REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
260   REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
262   operands[2] = gen_lowpart (DImode, operands[0]);
263   /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
264 #if HOST_BITS_PER_WIDE_INT >= 64
265   val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
266          | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
268   operands[3] = gen_int_mode (val, DImode);
269 #else
270   operands[3] = immed_double_const (l[1 - endian], l[endian], DImode);
271 #endif
274 ;; Don't have reload use general registers to load a constant.  First,
275 ;; it might not work if the output operand is the equivalent of
276 ;; a non-offsettable memref, but also it is less efficient than loading
277 ;; the constant into an FP register, since it will probably be used there.
278 ;; The "??" is a kludge until we can figure out a more reasonable way
279 ;; of handling these non-offsettable values.
280 (define_insn "*movdd_hardfloat32"
281   [(set (match_operand:DD 0 "nonimmediate_operand" "=!r,??r,m,d,d,m,!r,!r,!r")
282         (match_operand:DD 1 "input_operand" "r,m,r,d,m,d,G,H,F"))]
283   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
284    && (gpc_reg_operand (operands[0], DDmode)
285        || gpc_reg_operand (operands[1], DDmode))"
286   "*
288   switch (which_alternative)
289     {
290     default:
291       gcc_unreachable ();
292     case 0:
293     case 1:
294     case 2:
295       return \"#\";
296     case 3:
297       return \"fmr %0,%1\";
298     case 4:
299       return \"lfd%U1%X1 %0,%1\";
300     case 5:
301       return \"stfd%U0%X0 %1,%0\";
302     case 6:
303     case 7:
304     case 8:
305       return \"#\";
306     }
308   [(set_attr "type" "two,load,store,fp,fpload,fpstore,*,*,*")
309    (set_attr "length" "8,16,16,4,4,4,8,12,16")])
311 (define_insn "*movdd_softfloat32"
312   [(set (match_operand:DD 0 "nonimmediate_operand" "=r,r,m,r,r,r")
313         (match_operand:DD 1 "input_operand" "r,m,r,G,H,F"))]
314   "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
315    && (gpc_reg_operand (operands[0], DDmode)
316        || gpc_reg_operand (operands[1], DDmode))"
317   "#"
318   [(set_attr "type" "two,load,store,*,*,*")
319    (set_attr "length" "8,8,8,8,12,16")])
321 ; ld/std require word-aligned displacements -> 'Y' constraint.
322 ; List Y->r and r->Y before r->r for reload.
323 (define_insn "*movdd_hardfloat64_mfpgpr"
324   [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r,r,d")
325         (match_operand:DD 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F,d,r"))]
326   "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
327    && (gpc_reg_operand (operands[0], DDmode)
328        || gpc_reg_operand (operands[1], DDmode))"
329   "@
330    std%U0%X0 %1,%0
331    ld%U1%X1 %0,%1
332    mr %0,%1
333    fmr %0,%1
334    lfd%U1%X1 %0,%1
335    stfd%U0%X0 %1,%0
336    mt%0 %1
337    mf%1 %0
338    nop
339    #
340    #
341    #
342    mftgpr %0,%1
343    mffgpr %0,%1"
344   [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr")
345    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
347 ; ld/std require word-aligned displacements -> 'Y' constraint.
348 ; List Y->r and r->Y before r->r for reload.
349 (define_insn "*movdd_hardfloat64"
350   [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r")
351         (match_operand:DD 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F"))]
352   "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
353    && (gpc_reg_operand (operands[0], DDmode)
354        || gpc_reg_operand (operands[1], DDmode))"
355   "@
356    std%U0%X0 %1,%0
357    ld%U1%X1 %0,%1
358    mr %0,%1
359    fmr %0,%1
360    lfd%U1%X1 %0,%1
361    stfd%U0%X0 %1,%0
362    mt%0 %1
363    mf%1 %0
364    nop
365    #
366    #
367    #"
368   [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*")
369    (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")])
371 (define_insn "*movdd_softfloat64"
372   [(set (match_operand:DD 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
373         (match_operand:DD 1 "input_operand" "Y,r,r,r,h,G,H,F,0"))]
374   "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
375    && (gpc_reg_operand (operands[0], DDmode)
376        || gpc_reg_operand (operands[1], DDmode))"
377   "@
378    ld%U1%X1 %0,%1
379    std%U0%X0 %1,%0
380    mr %0,%1
381    mt%0 %1
382    mf%1 %0
383    #
384    #
385    #
386    nop"
387   [(set_attr "type" "load,store,*,mtjmpr,mfjmpr,*,*,*,*")
388    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
390 (define_expand "negtd2"
391   [(set (match_operand:TD 0 "gpc_reg_operand" "")
392         (neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
393   "TARGET_HARD_FLOAT && TARGET_FPRS"
394   "")
396 (define_insn "*negtd2_fpr"
397   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
398         (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
399   "TARGET_HARD_FLOAT && TARGET_FPRS"
400   "fneg %0,%1"
401   [(set_attr "type" "fp")])
403 (define_expand "abstd2"
404   [(set (match_operand:TD 0 "gpc_reg_operand" "")
405         (abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
406   "TARGET_HARD_FLOAT && TARGET_FPRS"
407   "")
409 (define_insn "*abstd2_fpr"
410   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
411         (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
412   "TARGET_HARD_FLOAT && TARGET_FPRS"
413   "fabs %0,%1"
414   [(set_attr "type" "fp")])
416 (define_insn "*nabstd2_fpr"
417   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
418         (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d"))))]
419   "TARGET_HARD_FLOAT && TARGET_FPRS"
420   "fnabs %0,%1"
421   [(set_attr "type" "fp")])
423 (define_expand "movtd"
424   [(set (match_operand:TD 0 "general_operand" "")
425         (match_operand:TD 1 "any_operand" ""))]
426   "TARGET_HARD_FLOAT && TARGET_FPRS"
427   "{ rs6000_emit_move (operands[0], operands[1], TDmode); DONE; }")
429 ; It's important to list the Y->r and r->Y moves before r->r because
430 ; otherwise reload, given m->r, will try to pick r->r and reload it,
431 ; which doesn't make progress.
432 (define_insn_and_split "*movtd_internal"
433   [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
434         (match_operand:TD 1 "input_operand"         "d,m,d,r,YGHF,r"))]
435   "TARGET_HARD_FLOAT && TARGET_FPRS
436    && (gpc_reg_operand (operands[0], TDmode)
437        || gpc_reg_operand (operands[1], TDmode))"
438   "#"
439   "&& reload_completed"
440   [(pc)]
441 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
442   [(set_attr "length" "8,8,8,20,20,16")])
444 ;; Hardware support for decimal floating point operations.
446 (define_insn "extendddtd2"
447   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
448         (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))]
449   "TARGET_DFP"
450   "dctqpq %0,%1"
451   [(set_attr "type" "fp")])
453 ;; The result of drdpq is an even/odd register pair with the converted
454 ;; value in the even register and zero in the odd register.
455 ;; FIXME: Avoid the register move by using a reload constraint to ensure
456 ;; that the result is the first of the pair receiving the result of drdpq.
458 (define_insn "trunctddd2"
459   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
460         (float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "d")))
461    (clobber (match_scratch:TD 2 "=d"))]
462   "TARGET_DFP"
463   "drdpq %2,%1\;fmr %0,%2"
464   [(set_attr "type" "fp")])
466 (define_insn "adddd3"
467   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
468         (plus:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
469                  (match_operand:DD 2 "gpc_reg_operand" "d")))]
470   "TARGET_DFP"
471   "dadd %0,%1,%2"
472   [(set_attr "type" "fp")])
474 (define_insn "addtd3"
475   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
476         (plus:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
477                  (match_operand:TD 2 "gpc_reg_operand" "d")))]
478   "TARGET_DFP"
479   "daddq %0,%1,%2"
480   [(set_attr "type" "fp")])
482 (define_insn "subdd3"
483   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
484         (minus:DD (match_operand:DD 1 "gpc_reg_operand" "d")
485                   (match_operand:DD 2 "gpc_reg_operand" "d")))]
486   "TARGET_DFP"
487   "dsub %0,%1,%2"
488   [(set_attr "type" "fp")])
490 (define_insn "subtd3"
491   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
492         (minus:TD (match_operand:TD 1 "gpc_reg_operand" "d")
493                   (match_operand:TD 2 "gpc_reg_operand" "d")))]
494   "TARGET_DFP"
495   "dsubq %0,%1,%2"
496   [(set_attr "type" "fp")])
498 (define_insn "muldd3"
499   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
500         (mult:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
501                  (match_operand:DD 2 "gpc_reg_operand" "d")))]
502   "TARGET_DFP"
503   "dmul %0,%1,%2"
504   [(set_attr "type" "fp")])
506 (define_insn "multd3"
507   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
508         (mult:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
509                  (match_operand:TD 2 "gpc_reg_operand" "d")))]
510   "TARGET_DFP"
511   "dmulq %0,%1,%2"
512   [(set_attr "type" "fp")])
514 (define_insn "divdd3"
515   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
516         (div:DD (match_operand:DD 1 "gpc_reg_operand" "d")
517                 (match_operand:DD 2 "gpc_reg_operand" "d")))]
518   "TARGET_DFP"
519   "ddiv %0,%1,%2"
520   [(set_attr "type" "fp")])
522 (define_insn "divtd3"
523   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
524         (div:TD (match_operand:TD 1 "gpc_reg_operand" "d")
525                 (match_operand:TD 2 "gpc_reg_operand" "d")))]
526   "TARGET_DFP"
527   "ddivq %0,%1,%2"
528   [(set_attr "type" "fp")])
530 (define_insn "*cmpdd_internal1"
531   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
532         (compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d")
533                       (match_operand:DD 2 "gpc_reg_operand" "d")))]
534   "TARGET_DFP"
535   "dcmpu %0,%1,%2"
536   [(set_attr "type" "fpcompare")])
538 (define_insn "*cmptd_internal1"
539   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
540         (compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d")
541                       (match_operand:TD 2 "gpc_reg_operand" "d")))]
542   "TARGET_DFP"
543   "dcmpuq %0,%1,%2"
544   [(set_attr "type" "fpcompare")])
546 (define_insn "floatdidd2"
547   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
548         (float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))]
549   "TARGET_DFP && TARGET_POPCNTD"
550   "dcffix %0,%1"
551   [(set_attr "type" "fp")])
553 (define_insn "floatditd2"
554   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
555         (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
556   "TARGET_DFP"
557   "dcffixq %0,%1"
558   [(set_attr "type" "fp")])
560 ;; Convert a decimal64 to a decimal64 whose value is an integer.
561 ;; This is the first stage of converting it to an integer type.
563 (define_insn "ftruncdd2"
564   [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
565         (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
566   "TARGET_DFP"
567   "drintn. 0,%0,%1,1"
568   [(set_attr "type" "fp")])
570 ;; Convert a decimal64 whose value is an integer to an actual integer.
571 ;; This is the second stage of converting decimal float to integer type.
573 (define_insn "fixdddi2"
574   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
575         (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
576   "TARGET_DFP"
577   "dctfix %0,%1"
578   [(set_attr "type" "fp")])
580 ;; Convert a decimal128 to a decimal128 whose value is an integer.
581 ;; This is the first stage of converting it to an integer type.
583 (define_insn "ftrunctd2"
584   [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
585         (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
586   "TARGET_DFP"
587   "drintnq. 0,%0,%1,1"
588   [(set_attr "type" "fp")])
590 ;; Convert a decimal128 whose value is an integer to an actual integer.
591 ;; This is the second stage of converting decimal float to integer type.
593 (define_insn "fixtddi2"
594   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
595         (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))]
596   "TARGET_DFP"
597   "dctfixq %0,%1"
598   [(set_attr "type" "fp")])