; 11 loadqf_int
; 12 storeqf_int
; 13 Conditional load on overflow
+; 14 push_st
+; 15 pop_st
+; 16 push_dp
+; 17 pop_dp
+; 18 popqi_unspec
+; 19 popqf_unspec
+; 20 andn_st
; 22 rptb_init
;
(define_function_unit "dummy" 1 0 (const_int 0) 2 1)
(define_function_unit "dummy" 1 0 (const_int 0) 3 1)
-;(define_function_unit "ar0" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setar0" "1")
-; (eq_attr "usear0" "1")))
-; 3 1 )
-
-;(define_function_unit "ar0" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ar0" "1")
-; (eq_attr "usear0" "1")))
-; 2 1 )
-
-;(define_function_unit "ar0" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "usear0" "1")
-; (eq_attr "readar0" "1")))
-; 2 1 )
-
; The attribute setar0 is set to 1 for insns where ar0 is a dst operand.
; Note that the attributes unarycc and binarycc do not apply
; if ar0 is a dst operand (only loading an ext. prec. reg. sets CC)
(const_int 1) (const_int 0))]
(const_int 0)))
-;(define_function_unit "ar1" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setar1" "1")
-; (eq_attr "usear1" "1")))
-; 3 1 )
-
-;(define_function_unit "ar1" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ar1" "1")
-; (eq_attr "usear1" "1")))
-; 2 1 )
-
-;(define_function_unit "ar1" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "usear1" "1")
-; (eq_attr "readar1" "1")))
-; 2 1 )
-
(define_attr "setar1" ""
(cond [(eq_attr "type" "unary,binary")
(if_then_else (match_operand 0 "ar1_reg_operand" "")
(const_int 1) (const_int 0))]
(const_int 0)))
-;(define_function_unit "ar2" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setar2" "1")
-; (eq_attr "usear2" "1")))
-; 3 1 )
-
-;(define_function_unit "ar2" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ar2" "1")
-; (eq_attr "usear2" "1")))
-; 2 1 )
-
-;(define_function_unit "ar2" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "usear2" "1")
-; (eq_attr "readar2" "1")))
-; 2 1 )
-
(define_attr "setar2" ""
(cond [(eq_attr "type" "unary,binary")
(if_then_else (match_operand 0 "ar2_reg_operand" "")
(const_int 1) (const_int 0))]
(const_int 0)))
-;(define_function_unit "ar3" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setar3" "1")
-; (eq_attr "usear3" "1")))
-; 3 1 )
-
-;(define_function_unit "ar3" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ar3" "1")
-; (eq_attr "usear3" "1")))
-; 2 1 )
-
-;(define_function_unit "ar3" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "usear3" "1")
-; (eq_attr "readar3" "1")))
-; 2 1 )
-
(define_attr "setar3" ""
(cond [(eq_attr "type" "unary,binary")
(if_then_else (match_operand 0 "ar3_reg_operand" "")
(const_int 1) (const_int 0))]
(const_int 0)))
-;(define_function_unit "ar4" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setar4" "1")
-; (eq_attr "usear4" "1")))
-; 3 1 )
-
-;(define_function_unit "ar4" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ar4" "1")
-; (eq_attr "usear4" "1")))
-; 2 1 )
-
-;(define_function_unit "ar4" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "usear4" "1")
-; (eq_attr "readar4" "1")))
-; 2 1 )
-
(define_attr "setar4" ""
(cond [(eq_attr "type" "unary,binary")
(if_then_else (match_operand 0 "ar4_reg_operand" "")
(const_int 1) (const_int 0))]
(const_int 0)))
-;(define_function_unit "ar5" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setar5" "1")
-; (eq_attr "usear5" "1")))
-; 3 1 )
-
-;(define_function_unit "ar5" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ar5" "1")
-; (eq_attr "usear5" "1")))
-; 2 1 )
-
-;(define_function_unit "ar5" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "usear5" "1")
-; (eq_attr "readar5" "1")))
-; 2 1 )
-
(define_attr "setar5" ""
(cond [(eq_attr "type" "unary,binary")
(if_then_else (match_operand 0 "ar5_reg_operand" "")
(const_int 1) (const_int 0))]
(const_int 0)))
-;(define_function_unit "ar6" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setar6" "1")
-; (eq_attr "usear6" "1")))
-; 3 1 )
-
-;(define_function_unit "ar6" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ar6" "1")
-; (eq_attr "usear6" "1")))
-; 2 1 )
-
-;(define_function_unit "ar6" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "usear6" "1")
-; (eq_attr "readar6" "1")))
-; 2 1 )
-
(define_attr "setar6" ""
(cond [(eq_attr "type" "unary,binary")
(if_then_else (match_operand 0 "ar6_reg_operand" "")
(const_int 1) (const_int 0))]
(const_int 0)))
-;(define_function_unit "ar7" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setar7" "1")
-; (eq_attr "usear7" "1")))
-; 3 1 )
-
-;(define_function_unit "ar7" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ar7" "1")
-; (eq_attr "usear7" "1")))
-; 2 1 )
-
-;(define_function_unit "ar7" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "usear7" "1")
-; (eq_attr "readar7" "1")))
-; 2 1 )
-
(define_attr "setar7" ""
(cond [(eq_attr "type" "unary,binary")
(if_then_else (match_operand 0 "ar7_reg_operand" "")
(const_int 1) (const_int 0))]
(const_int 0)))
-;(define_function_unit "ir0" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setir0" "1")
-; (eq_attr "useir0" "1")))
-; 3 1 )
-
-;(define_function_unit "ir0" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ir0" "1")
-; (eq_attr "useir0" "1")))
-; 2 1 )
-
(define_attr "setir0" ""
(cond [(eq_attr "type" "unary,binary")
(if_then_else (match_operand 0 "ir0_reg_operand" "")
(const_int 1) (const_int 0))]
(const_int 0)))
-;(define_function_unit "ir1" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setir1" "1")
-; (eq_attr "useir1" "1")))
-; 3 1 )
-
-;(define_function_unit "ir1" 1 0
-; (and (eq_attr "cpu" "c4x")
-; (and (eq_attr "setlda_ir1" "1")
-; (eq_attr "useir1" "1")))
-; 2 1 )
-
(define_attr "setir1" ""
(cond [(eq_attr "type" "unary,binary")
(if_then_else (match_operand 0 "ir1_reg_operand" "")
; Let's ignore functional groups 2 and 3 for now, since they are not
; so important.
-;(define_function_unit "group1" 1 0
-; (and (eq_attr "cpu" "c3x")
-; (and (eq_attr "setgroup1" "1")
-; (eq_attr "usegroup1" "1")))
-; 3 1)
-
-;(define_function_unit "group1" 1 0
-; (and (eq_attr "cpu" "c3x")
-; (and (eq_attr "usegroup1" "1")
-; (eq_attr "readarx" "1")))
-; 2 1)
-
(define_attr "setgroup1" ""
(cond [(eq_attr "type" "lda,unary,binary")
(if_then_else (match_operand 0 "group1_reg_operand" "")
"* return (TARGET_C3X) ? \"ldp\\t%A1\" : \"ldpk\\t%A1\";"
[(set_attr "type" "ldp")])
+(define_insn "set_ldp_prologue"
+ [(set (match_operand:QI 0 "dp_reg_operand" "=z")
+ (high:QI (match_operand:QI 1 "" "")))]
+ "TARGET_SMALL && TARGET_PARANOID"
+ "* return (TARGET_C3X) ? \"ldp\\t@data_sec\" : \"ldpk\\t@data_sec\";"
+ [(set_attr "type" "ldp")])
+
(define_insn "set_high"
[(set (match_operand:QI 0 "std_reg_operand" "=c")
(high:QI (match_operand:QI 1 "symbolic_address_operand" "")))]
}")
+; As far as GCC is concerned, the moves are performed in parallel
+; thus it must be convinced that there is no aliasing.
+; It also assumes that the input operands are simultaneously loaded
+; and then the output operands are simultaneously stored.
+; With the C4x, if there are parallel stores to the same address
+; both stores are executed.
+; If there is a parallel load and store to the same address,
+; the load is performed first.
+; The problem with this pattern is that reload can spoil
+; the show when it eliminates a reference to the frame pointer.
+; This can invalidate the memory addressing mode, i.e., when
+; the displacement is greater than 1.
(define_insn "movqi_parallel"
[(set (match_operand:QI 0 "parallel_operand" "=q,S<>!V,q,S<>!V")
(match_operand:QI 1 "parallel_operand" "S<>!V,q,S<>!V,q"))
;
; PUSH/POP
;
-(define_insn "*pushqi"
+(define_insn "pushqi"
[(set (mem:QI (pre_inc:QI (reg:QI 20)))
(match_operand:QI 0 "reg_operand" "r"))]
""
"push\\t%0"
[(set_attr "type" "push")])
-(define_insn "*popqi"
+(define_insn "push_st"
+ [(set (mem:QI (pre_inc:QI (reg:QI 20))) (unspec:QI [(reg:QI 21)] 14))
+ (use (reg:QI 21))]
+ ""
+ "push\\tst"
+ [(set_attr "type" "push")])
+
+(define_insn "push_dp"
+ [(set (mem:QI (pre_inc:QI (reg:QI 20))) (unspec:QI [(reg:QI 16)] 16))
+ (use (reg:QI 16))]
+ ""
+ "push\\tdp"
+ [(set_attr "type" "push")])
+
+(define_insn "popqi"
[(set (match_operand:QI 0 "reg_operand" "=r")
(mem:QI (post_dec:QI (reg:QI 20))))
(clobber (reg:CC 21))]
"pop\\t%0"
[(set_attr "type" "pop")])
+(define_insn "pop_st"
+ [(set (unspec:QI [(reg:QI 21)] 15) (mem:QI (post_dec:QI (reg:QI 20))))
+ (clobber (reg:CC 21))]
+ ""
+ "pop\\tst"
+ [(set_attr "type" "pop")])
+
+(define_insn "pop_dp"
+ [(set (unspec:QI [(reg:QI 16)] 17) (mem:QI (post_dec:QI (reg:QI 20))))
+ (clobber (reg:CC 16))]
+ ""
+ "pop\\tdp"
+ [(set_attr "type" "pop")])
+
+(define_insn "popqi_unspec"
+ [(set (unspec:QI [(match_operand:QI 0 "reg_operand" "=r")] 18)
+ (mem:QI (post_dec:QI (reg:QI 20))))
+ (clobber (match_dup 0))
+ (clobber (reg:CC 21))]
+ ""
+ "pop\\t%0"
+ [(set_attr "type" "pop")])
+
;
; ABSI
;
[(set_attr "type" "binary,binary,binary,binary")
(set_attr "data" "not_uint16,uint16,int16,uint16")])
+(define_insn "andn_st"
+ [(set (unspec:QI [(reg:QI 21)] 20)
+ (and:QI (unspec:QI [(reg:QI 21)] 20)
+ (match_operand:QI 0 "" "N")))
+ (use (match_dup 0))
+ (use (reg:CC 21))
+ (clobber (reg:CC 21))]
+ ""
+ "@
+ andn\\t%N0,st"
+ [(set_attr "type" "misc")
+ (set_attr "data" "not_uint16")])
+
(define_split
[(set (match_operand:QI 0 "std_reg_operand" "")
(and:QI (match_operand:QI 1 "src_operand" "")
;
; PUSH/POP
;
-(define_insn "*pushqf"
+(define_insn "pushqf"
[(set (mem:QF (pre_inc:QI (reg:QI 20)))
(match_operand:QF 0 "reg_operand" "f"))]
""
"pushf\\t%0"
[(set_attr "type" "push")])
-(define_insn "*popqf"
+(define_insn "popqf"
[(set (match_operand:QF 0 "reg_operand" "=f")
(mem:QF (post_dec:QI (reg:QI 20))))
(clobber (reg:CC 21))]
"popf\\t%0"
[(set_attr "type" "pop")])
+(define_insn "popqf_unspec"
+ [(set (unspec:QF [(match_operand:QF 0 "reg_operand" "=f")] 19)
+ (mem:QF (post_dec:QI (reg:QI 20))))
+ (clobber (match_dup 0))
+ (clobber (reg:CC 21))]
+ ""
+ "popf\\t%0"
+ [(set_attr "type" "pop")])
;
; ABSF
""
"@
ldiv\\t%1,%0"
- [(set_attr "type" "binary")])
+ [(set_attr "type" "unary")])
; Move operand 2 to operand 0 if condition (operand 1) is true
; else move operand 3 to operand 0.
force_reg (Pmode, XEXP (operands[0], 0)));
}")
+(define_insn "nodb_call"
+ [(call (mem:QI (match_operand:QI 0 "call_address_operand" "Ur"))
+ (const_int 0))]
+ ""
+ "call%U0\\t%C0"
+ [(set_attr "type" "call")])
+
(define_insn "*callv_c3x"
[(set (match_operand 0 "" "=r")
(call (mem:QI (match_operand:QI 1 "call_address_operand" "Ur"))
"rets"
[(set_attr "type" "rets")])
+(define_insn "return_from_epilogue"
+ [(return)]
+ "reload_completed && ! c4x_interrupt_function_p ()"
+ "rets"
+ [(set_attr "type" "rets")])
+
+(define_insn "return_from_interrupt_epilogue"
+ [(return)]
+ "reload_completed && c4x_interrupt_function_p ()"
+ "reti"
+ [(set_attr "type" "rets")])
+
(define_insn "*return_cc"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
(set (match_dup 0)
(plus:QI (match_dup 0)
(const_int -1)))
+ (use (reg:QI 20))
(clobber (reg:CC_NOOV 21))]
"TARGET_DB && TARGET_LOOP_UNSIGNED"
"*
(set (match_dup 0)
(plus:QI (match_dup 0)
(const_int -1)))
+ (use (reg:QI 20))
(clobber (reg:CC_NOOV 21))]
"reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED"
[(parallel [(set (pc)
(set (match_dup 0)
(plus:QI (match_dup 0)
(const_int -1)))
+ (use (reg:QI 20))
(clobber (reg:CC_NOOV 21))]
"TARGET_DB && (find_reg_note (insn, REG_NONNEG, 0) || TARGET_LOOP_UNSIGNED)"
"*
(set (match_dup 0)
(plus:QI (match_dup 0)
(const_int -1)))
+ (use (reg:QI 20))
(clobber (reg:CC_NOOV 21))]
"reload_completed && TARGET_DB && TARGET_LOOP_UNSIGNED"
[(parallel [(set (pc)
"nop")
; Default to misc type attr.
+(define_expand "prologue"
+ [(const_int 1)]
+ ""
+ "c4x_expand_prologue (); DONE;")
+
+(define_expand "epilogue"
+ [(const_int 1)]
+ ""
+ "c4x_expand_epilogue (); DONE;")
;
; RPTB
(const_int -1)))
(use (reg:QI 25))
(use (reg:QI 26))
+ (use (reg:QI 20))
(clobber (reg:CC_NOOV 21))]
""
"*
(use (match_operand:QI 4 "const_int_operand" ""))
(use (reg:QI 25))
(use (reg:QI 26))
+ (use (reg:QI 20))
(clobber (reg:CC_NOOV 21))]
"reload_completed"
[(parallel [(set (pc)
;
; PUSH/POP
;
-(define_insn "*pushhf"
+(define_insn "pushhf"
[(set (mem:HF (pre_inc:QI (reg:QI 20)))
(match_operand:HF 0 "reg_operand" "h"))]
""
[(set_attr "type" "push")])
; we can not use this because the popf will destroy the low 8 bits
-;(define_insn "*pophf"
+;(define_insn "pophf"
; [(set (match_operand:HF 0 "reg_operand" "=h")
; (mem:HF (post_dec:QI (reg:QI 20))))
; (clobber (reg:CC 21))]
""
"@
popf\\t%0"
- [(set_attr "type" "unary")])
+ [(set_attr "type" "pop")])
;
; FIX
c4x_compare_op1 = operands[1];
DONE;")
+(define_insn "*cmphi_cc"
+ [(set (reg:CC 21)
+ (compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>")
+ (match_operand:HI 1 "src_operand" "R,rS<>")))]
+ "valid_operands (COMPARE, operands, HImode)"
+ "#"
+ [(set_attr "type" "multi")])
+
+(define_insn "*cmphi_cc_noov"
+ [(set (reg:CC_NOOV 21)
+ (compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>")
+ (match_operand:HI 1 "src_operand" "R,rS<>")))]
+ "valid_operands (COMPARE, operands, HImode)"
+ "#"
+ [(set_attr "type" "multi")])
+
; This works only before reload because we need 2 extra registers.
; Use unspec to avoid recursive split.
(define_split
"")
; This is normally not used. The define splits above are used first.
+(define_split
+ [(set (reg:CC 21)
+ (compare:CC (match_operand:HI 0 "src_operand" "")
+ (match_operand:HI 1 "src_operand" "")))]
+ "reload_completed"
+ [(parallel [(set (reg:CC 21)
+ (compare:CC (match_dup 0) (match_dup 1)))
+ (use (reg:QI 20))])]
+ "")
+
+(define_split
+ [(set (reg:CC_NOOV 21)
+ (compare:CC_NOOV (match_operand:HI 0 "src_operand" "")
+ (match_operand:HI 1 "src_operand" "")))]
+ "reload_completed"
+ [(parallel [(set (reg:CC_NOOV 21)
+ (compare:CC_NOOV (match_dup 0) (match_dup 1)))
+ (use (reg:QI 20))])]
+ "")
+
(define_insn "*cmphi"
[(set (reg:CC 21)
(compare:CC (match_operand:HI 0 "src_operand" "rR,rS<>")
- (match_operand:HI 1 "src_operand" "R,rS<>")))]
+ (match_operand:HI 1 "src_operand" "R,rS<>")))
+ (use (reg:QI 20))]
"valid_operands (COMPARE, operands, HImode)"
"*
{
(define_insn "*cmphi_noov"
[(set (reg:CC_NOOV 21)
(compare:CC_NOOV (match_operand:HI 0 "src_operand" "rR,rS<>")
- (match_operand:HI 1 "src_operand" "R,rS<>")))]
+ (match_operand:HI 1 "src_operand" "R,rS<>")))
+ (use (reg:QI 20))]
"valid_operands (COMPARE, operands, HImode)"
"*
{
(set (match_dup 0)
(plus:QI (match_dup 0)
(const_int -1)))
+ (use (reg:QI 20))
(clobber (reg:CC_NOOV 21))])]
"! c4x_label_conflict (insn, operands[2], operands[1])"
"db%I3\\t%0,%l1\\n\\tb%3\\t%l2"