"")
;; %%% Kill me once multi-word ops are sane.
-(define_insn "zero_extendsidi2"
+(define_expand "zero_extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
+ ""
+ "if (!TARGET_64BIT)
+ {
+ emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
+ DONE;
+ }
+ ")
+
+(define_insn "zero_extendsidi2_32"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
- (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
(clobber (reg:CC 17))]
- ""
+ "!TARGET_64BIT"
"#"
[(set_attr "mode" "SI")])
+(define_insn "zero_extendsidi2_rex64"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
+ "TARGET_64BIT"
+ "@
+ mov\\t{%k1, %k0|%k0, %k1}
+ #"
+ [(set_attr "type" "imovx,imov")
+ (set_attr "mode" "SI,DI")])
+
+(define_split
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (zero_extend:DI (match_dup 0)))]
+ ""
+ [(set (match_dup 4) (const_int 0))]
+ "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
(clobber (reg:CC 17))]
- "reload_completed"
+ "reload_completed && !TARGET_64BIT"
[(set (match_dup 3) (match_dup 1))
(set (match_dup 4) (const_int 0))]
"split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
+(define_insn "zero_extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+ "TARGET_64BIT"
+ "@
+ movz{wl|x}\\t{%1, %k0|%k0, %1}
+ movz{wq|x}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "SI,DI")])
+
+(define_insn "zero_extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
+ "TARGET_64BIT"
+ "@
+ movz{bl|x}\\t{%1, %k0|%k0, %1}
+ movz{bq|x}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "SI,DI")])
\f
;; Sign extension instructions
-(define_insn "extendsidi2"
+(define_expand "extendsidi2"
+ [(parallel [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (reg:CC 17))
+ (clobber (match_scratch:SI 2 ""))])]
+ ""
+ "
+{
+ if (TARGET_64BIT)
+ {
+ emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
+ DONE;
+ }
+}")
+
+(define_insn "*extendsidi2_1"
[(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
(clobber (reg:CC 17))
(clobber (match_scratch:SI 2 "=X,X,X,&r"))]
- ""
+ "!TARGET_64BIT"
"#")
+(define_insn "extendsidi2_rex64"
+ [(set (match_operand:DI 0 "register_operand" "=*a,r")
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
+ "TARGET_64BIT"
+ "@
+ {cltq|cdqe}
+ movs{lq|x}\\t{%1,%0|%0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "DI")
+ (set_attr "prefix_0f" "0")
+ (set_attr "modrm" "0,1")])
+
+(define_insn "extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
+ "TARGET_64BIT"
+ "movs{wq|x}\\t{%1,%0|%0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "DI")])
+
+(define_insn "extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
+ "TARGET_64BIT"
+ "movs{bq|x}\\t{%1,%0|%0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "DI")])
+
;; Extend to memory case when source register does die.
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
(const_string "0")
(const_string "1")))])
+(define_insn "*extendhisi2_zext"
+ [(set (match_operand:DI 0 "register_operand" "=*a,r")
+ (zero_extend:DI
+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
+ "TARGET_64BIT"
+ "*
+{
+ switch (get_attr_prefix_0f (insn))
+ {
+ case 0:
+ return \"{cwtl|cwde}\";
+ default:
+ return \"movs{wl|x}\\t{%1,%k0|%k0, %1}\";
+ }
+}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "SI")
+ (set (attr "prefix_0f")
+ ;; movsx is short decodable while cwtl is vector decoded.
+ (if_then_else (and (eq_attr "cpu" "!k6")
+ (eq_attr "alternative" "0"))
+ (const_string "0")
+ (const_string "1")))
+ (set (attr "modrm")
+ (if_then_else (eq_attr "prefix_0f" "0")
+ (const_string "0")
+ (const_string "1")))])
+
(define_insn "extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=*a,r")
(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
"movs{bl|x}\\t{%1,%0|%0, %1}"
[(set_attr "type" "imovx")
(set_attr "mode" "SI")])
+
+(define_insn "*extendqisi2_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
+ "TARGET_64BIT"
+ "movs{bl|x}\\t{%1,%k0|%k0, %1}"
+ [(set_attr "type" "imovx")
+ (set_attr "mode" "SI")])
\f
;; Conversions between float and double.
(define_split
[(set (match_operand:DF 0 "push_operand" "")
(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
- "FP_REGNO_P (REGNO (operands[1]))"
+ "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
(set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
+(define_split
+ [(set (match_operand:DF 0 "push_operand" "")
+ (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
+ "FP_REGNO_P (REGNO (operands[1])) && TARGET_64BIT"
+ [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
+ (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
+
(define_insn "*dummy_extendsfxf2"
[(set (match_operand:XF 0 "push_operand" "=<")
(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
(define_split
[(set (match_operand:XF 0 "push_operand" "")
(float_extend:XF (match_operand:SF 1 "register_operand" "")))]
- "FP_REGNO_P (REGNO (operands[1]))"
+ "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
(set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
(define_split
[(set (match_operand:TF 0 "push_operand" "")
(float_extend:TF (match_operand:SF 1 "register_operand" "")))]
- "FP_REGNO_P (REGNO (operands[1]))"
+ "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
+ (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
+
+(define_split
+ [(set (match_operand:TF 0 "push_operand" "")
+ (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
+ "FP_REGNO_P (REGNO (operands[1])) && TARGET_64BIT"
+ [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
+ (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
(define_insn "*dummy_extenddfxf2"
[(set (match_operand:XF 0 "push_operand" "=<")
(define_split
[(set (match_operand:XF 0 "push_operand" "")
(float_extend:XF (match_operand:DF 1 "register_operand" "")))]
- "FP_REGNO_P (REGNO (operands[1]))"
+ "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
- (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
+ (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
(define_insn "*dummy_extenddftf2"
[(set (match_operand:TF 0 "push_operand" "=<")
(define_split
[(set (match_operand:TF 0 "push_operand" "")
(float_extend:TF (match_operand:DF 1 "register_operand" "")))]
- "FP_REGNO_P (REGNO (operands[1]))"
+ "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
(set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
+(define_split
+ [(set (match_operand:TF 0 "push_operand" "")
+ (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
+ "FP_REGNO_P (REGNO (operands[1])) && TARGET_64BIT"
+ [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
+ (set (mem:TF (reg:DI 7)) (float_extend:XF (match_dup 1)))])
+
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_scratch:SI 4 ""))])]
- "TARGET_80387"
+ "TARGET_80387 && !TARGET_64BIT"
"operands[2] = assign_386_stack_local (SImode, 0);
operands[3] = assign_386_stack_local (HImode, 1);")