1;; Decimal Floating Point (DFP) patterns. 2;; Copyright (C) 2007-2013 Free Software Foundation, Inc. 3;; Contributed by Ben Elliston (bje@au.ibm.com) and Peter Bergner 4;; (bergner@vnet.ibm.com). 5 6;; This file is part of GCC. 7 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. 12 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. 17 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/>. 21 22;; 23;; UNSPEC usage 24;; 25 26(define_c_enum "unspec" 27 [UNSPEC_MOVSD_LOAD 28 UNSPEC_MOVSD_STORE 29 ]) 30 31 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; }") 37 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 " 48{ 49 long l; 50 REAL_VALUE_TYPE rv; 51 52 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); 53 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l); 54 55 if (! TARGET_POWERPC64) 56 operands[2] = operand_subword (operands[0], 0, 0, SDmode); 57 else 58 operands[2] = gen_lowpart (SImode, operands[0]); 59 60 operands[3] = gen_int_mode (l, SImode); 61}") 62 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")]) 81 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")]) 102 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")]) 113 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")]) 124 125;; Hardware support for decimal floating point operations. 126 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")]) 133 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" 138{ 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; 143}) 144 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")]) 151 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 "") 157 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")]) 164 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 "") 170 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")]) 177 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")]) 184 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; }") 190 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 " 202{ 203 int endian = (WORDS_BIG_ENDIAN == 0); 204 HOST_WIDE_INT value = INTVAL (operands[1]); 205 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 214}") 215 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 " 227{ 228 int endian = (WORDS_BIG_ENDIAN == 0); 229 long l[2]; 230 REAL_VALUE_TYPE rv; 231 232 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); 233 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l); 234 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); 239}") 240 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 " 251{ 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 258 259 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); 260 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l); 261 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])); 267 268 operands[3] = gen_int_mode (val, DImode); 269#else 270 operands[3] = immed_double_const (l[1 - endian], l[endian], DImode); 271#endif 272}") 273 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 "* 287{ 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 } 307}" 308 [(set_attr "type" "two,load,store,fp,fpload,fpstore,*,*,*") 309 (set_attr "length" "8,16,16,4,4,4,8,12,16")]) 310 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")]) 320 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")]) 346 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")]) 370 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")]) 389 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 "") 395 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")]) 402 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 "") 408 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")]) 415 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")]) 422 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; }") 428 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")]) 443 444;; Hardware support for decimal floating point operations. 445 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")]) 452 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. 457 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")]) 465 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")]) 473 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")]) 481 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")]) 489 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")]) 497 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")]) 505 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")]) 513 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")]) 521 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")]) 529 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")]) 537 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")]) 545 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")]) 552 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")]) 559 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. 562 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")]) 569 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. 572 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")]) 579 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. 582 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")]) 589 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. 592 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")]) 599