OSDN Git Service

PR target/49781
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
index 245ee54..9dc5c85 100644 (file)
   [(SF "ss") (DF "sd")
    (V8SF "ps") (V4DF "pd")
    (V4SF "ps") (V2DF "pd")
-   (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
-   (V8SI "si")])
+   (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")])
 
 ;; SSE vector suffix for floating point modes
 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
 
 (define_insn "*push<mode>2"
   [(set (match_operand:DWI 0 "push_operand" "=<")
-       (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
+       (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
   ""
-  "#")
+  "#"
+  [(set_attr "type" "multi")
+   (set_attr "mode" "<MODE>")])
 
 (define_split
   [(set (match_operand:TI 0 "push_operand" "")
 
 (define_insn "*movdi_internal_rex64"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-         "=r,r  ,r,m ,!m,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
+         "=r,r  ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
        (match_operand:DI 1 "general_operand"
          "Z ,rem,i,re,n ,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
        (const_string "orig")))
    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
 
+;; Reload patterns to support multi-word load/store
+;; with non-offsetable address.
+(define_expand "reload_noff_store"
+  [(parallel [(match_operand 0 "memory_operand" "=m")
+              (match_operand 1 "register_operand" "r")
+              (match_operand:DI 2 "register_operand" "=&r")])]
+  "TARGET_64BIT"
+{
+  rtx mem = operands[0];
+  rtx addr = XEXP (mem, 0);
+
+  emit_move_insn (operands[2], addr);
+  mem = replace_equiv_address_nv (mem, operands[2]);
+
+  emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
+  DONE;
+})
+
+(define_expand "reload_noff_load"
+  [(parallel [(match_operand 0 "register_operand" "=r")
+              (match_operand 1 "memory_operand" "m")
+              (match_operand:DI 2 "register_operand" "=r")])]
+  "TARGET_64BIT"
+{
+  rtx mem = operands[1];
+  rtx addr = XEXP (mem, 0);
+
+  emit_move_insn (operands[2], addr);
+  mem = replace_equiv_address_nv (mem, operands[2]);
+
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
+  DONE;
+})
+
 ;; Convert impossible stores of immediate to existing instructions.
 ;; First try to get scratch register and go through it.  In case this
 ;; fails, move by 32bit parts.
 ;; only once, but this ought to be handled elsewhere).
 
 (define_insn "*pushxf_nointeger"
-  [(set (match_operand:XF 0 "push_operand" "=X,X")
+  [(set (match_operand:XF 0 "push_operand" "=<,<")
        (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
   "optimize_function_for_size_p (cfun)"
 {
    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
 
+(define_insn "*pushdf_rex64"
+  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
+       (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,Y2"))]
+  "TARGET_64BIT"
+{
+  /* This insn should be already split before reg-stack.  */
+  gcc_unreachable ();
+}
+  [(set_attr "type" "multi")
+   (set_attr "unit" "i387,*,*")
+   (set_attr "mode" "DF,DI,DF")])
+
 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
 ;; Size of pushdf using integer instructions is 2+2*memory operand size
 ;; On the average, pushdf using integers can be still shorter.
 (define_insn "*pushdf"
   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
        (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,Y2"))]
-  ""
+  "!TARGET_64BIT"
 {
   /* This insn should be already split before reg-stack.  */
   gcc_unreachable ();
 }
   [(set_attr "type" "multi")
    (set_attr "unit" "i387,*,*")
-   (set_attr "mode" "DF,SI,DF")])
+   (set_attr "mode" "DF,DI,DF")])
 
 ;; %%% Kill this when call knows how to work this out.
 (define_split
 
 (define_insn "*movdf_internal_rex64"
   [(set (match_operand:DF 0 "nonimmediate_operand"
-               "=f,m,f,?r,?m,?r,!m,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
+               "=f,m,f,?r,?m,?r,!o,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
        (match_operand:DF 1 "general_operand"
                "fm,f,G,rm,r ,F ,F ,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
 
 (define_insn "*lea_1"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
-       (match_operand:SWI48 1 "no_seg_address_operand" "p"))]
+       (match_operand:SWI48 1 "lea_address_operand" "p"))]
   ""
   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
 (define_insn "*lea_1_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
-         (match_operand:SI 1 "no_seg_address_operand" "p")))]
+         (match_operand:SI 1 "lea_address_operand" "p")))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %k0|%k0, %a1}"
   [(set_attr "type" "lea")
 
 (define_insn "*lea_2"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
+       (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %0|%0, %a1}"
   [(set_attr "type" "lea")
 (define_insn "*lea_2_zext"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
-         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
+         (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))]
   "TARGET_64BIT"
   "lea{l}\t{%a1, %k0|%k0, %a1}"
   [(set_attr "type" "lea")