;; GCC machine description for Renesas H8/300
-;; Copyright (C) 1992-2018 Free Software Foundation, Inc.
+;; Copyright (C) 1992-2020 Free Software Foundation, Inc.
;; Contributed by Steve Chamberlain (sac@cygnus.com),
;; Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
(set_attr "length_table" "*,movl")
(set_attr "cc" "set_zn,set_znv")])
-;; Implement block moves using movmd. Defining movmemsi allows the full
+;; Implement block copies using movmd. Defining cpymemsi allows the full
;; range of constant lengths (up to 0x40000 bytes when using movmd.l).
;; See h8sx_emit_movmd for details.
-(define_expand "movmemsi"
+(define_expand "cpymemsi"
[(use (match_operand:BLK 0 "memory_operand" ""))
(use (match_operand:BLK 1 "memory_operand" ""))
(use (match_operand:SI 2 "" ""))
(use (match_operand:SI 3 "const_int_operand" ""))]
- "TARGET_H8300SX"
+ "TARGET_H8300SX && 0"
{
if (h8sx_emit_movmd (operands[0], operands[1], operands[2], INTVAL (operands[3])))
DONE;
(clobber (match_dup 5))
(set (match_dup 2)
(const_int 0))])]
- "TARGET_H8300SX"
+ "TARGET_H8300SX && 0"
{
operands[4] = copy_rtx (XEXP (operands[0], 0));
operands[5] = copy_rtx (XEXP (operands[1], 0));
(clobber (match_operand:P 1 "register_operand" "=f,f"))
(set (match_operand:HI 2 "register_operand" "=c,c")
(const_int 0))]
- "TARGET_H8300SX"
+ "TARGET_H8300SX && 0"
"@
movmd%m6
#"
(set (match_dup 2)
(const_int 0))]
"TARGET_H8300SX && reload_completed
+ && 0
&& REGNO (operands[4]) != DESTINATION_REG"
[(const_int 0)]
{
[(use (match_operand 0 "register_operand" ""))
(use (match_operand:BLK 1 "memory_operand" ""))
(use (match_operand:BLK 2 "memory_operand" ""))]
- "TARGET_H8300SX"
+ "TARGET_H8300SX && 0"
{
operands[1] = replace_equiv_address
(operands[1], copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
(clobber (match_dup 3))
(clobber (match_dup 4))
(clobber (match_operand 2 "register_operand" ""))])]
- "TARGET_H8300SX"
+ "TARGET_H8300SX && 0"
{
operands[3] = copy_rtx (XEXP (operands[0], 0));
operands[4] = copy_rtx (XEXP (operands[1], 0));
(clobber (match_operand:P 0 "register_operand" "=d,??D"))
(clobber (match_operand:P 1 "register_operand" "=f,f"))
(clobber (match_operand:P 2 "register_operand" "=c,c"))]
- "TARGET_H8300SX"
+ "TARGET_H8300SX && 0"
"@
\n1:\tmovsd\t2f\;bra\t1b\n2:
#"
(clobber (match_operand:P 3 "register_operand" ""))
(clobber (match_operand:P 4 "register_operand" ""))]
"TARGET_H8300SX && reload_completed
+ && 0
&& REGNO (operands[2]) != DESTINATION_REG"
[(const_int 0)]
{
"mov.w\\t%T0,@-r7"
[(set_attr "length" "2")])
-(define_insn "*push1_h8300hs_<mode>"
+(define_insn "*push1_h8300hs_<QHI:mode>"
[(set (mem:QHI
(pre_modify:P
(reg:P SP_REG)
return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0";
else if (which_alternative == 1)
return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0";
+ gcc_unreachable ();
}
[(set_attr "length" "8,*")
(set_attr "length_table" "*,logicb")
;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
;; ----------------------------------------------------------------------
-;; We need a separate pattern here because machines other than the
-;; original H8300 don't have to split the 16-bit operand into a pair
-;; of high/low instructions, so we can accept literal addresses, that
-;; have to be loaded into a register on H8300.
-
-(define_insn "*logical<mode>3_sn"
- [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
- (match_operator:HSI 3 "bit_operator"
- [(match_operand:HSI 1 "h8300_dst_operand" "%0")
- (match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
- "(TARGET_H8300S || TARGET_H8300H) && h8300_operands_match_p (operands)"
-{
- return output_logical_op (<MODE>mode, operands);
-}
- [(set (attr "length")
- (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
- (set (attr "cc")
- (symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
-
(define_insn "*logical<mode>3"
[(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
(match_operator:HSI 3 "bit_operator"
[(match_operand:HSI 1 "h8300_dst_operand" "%0")
(match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
"h8300_operands_match_p (operands)"
-{
- return output_logical_op (<MODE>mode, operands);
-}
+ { return output_logical_op (<MODE>mode, operands); }
[(set (attr "length")
(symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
(set (attr "cc")
;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
-(define_insn "call"
- [(call (match_operand:QI 0 "call_insn_operand" "or")
- (match_operand:HI 1 "general_operand" "g"))]
+(define_expand "call"
+ [(call (match_operand:QI 0 "call_expander_operand" "")
+ (match_operand 1 "general_operand" ""))]
+ ""
+ {
+ if (!register_operand (XEXP (operands[0], 0), Pmode)
+ && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
+ XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
+ })
+
+(define_insn "call_insn_<mode>"
+ [(call (mem:QI (match_operand 0 "call_insn_operand" "Cr"))
+ (match_operand:P 1 "general_operand" "g"))]
""
{
- if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
- && (SYMBOL_REF_FLAGS (XEXP (operands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
- return "jsr\\t@%0:8";
+ rtx xoperands[1];
+ xoperands[0] = gen_rtx_MEM (QImode, operands[0]);
+ gcc_assert (GET_MODE (operands[0]) == Pmode);
+ if (GET_CODE (XEXP (xoperands[0], 0)) == SYMBOL_REF
+ && (SYMBOL_REF_FLAGS (XEXP (xoperands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
+ output_asm_insn ("jsr\\t@%0:8", xoperands);
else
- return "jsr\\t%0";
+ output_asm_insn ("jsr\\t%0", xoperands);
+ return "";
}
[(set_attr "type" "call")
(set (attr "length")
;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
-(define_insn "call_value"
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "call_expander_operand" "")
+ (match_operand 2 "general_operand" "")))]
+ ""
+ {
+ if (!register_operand (XEXP (operands[1], 0), Pmode)
+ && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
+ XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
+ })
+
+(define_insn "call_value_insn_<mode>"
[(set (match_operand 0 "" "=r")
- (call (match_operand:QI 1 "call_insn_operand" "or")
- (match_operand:HI 2 "general_operand" "g")))]
+ (call (mem:QI (match_operand 1 "call_insn_operand" "Cr"))
+ (match_operand:P 2 "general_operand" "g")))]
""
{
- if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
- && (SYMBOL_REF_FLAGS (XEXP (operands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
- return "jsr\\t@%1:8";
+ rtx xoperands[2];
+ gcc_assert (GET_MODE (operands[1]) == Pmode);
+ xoperands[0] = operands[0];
+ xoperands[1] = gen_rtx_MEM (QImode, operands[1]);
+ if (GET_CODE (XEXP (xoperands[1], 0)) == SYMBOL_REF
+ && (SYMBOL_REF_FLAGS (XEXP (xoperands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
+ output_asm_insn ("jsr\\t@%1:8", xoperands);
else
- return "jsr\\t%1";
+ output_asm_insn ("jsr\\t%1", xoperands);
+ return "";
}
[(set_attr "type" "call")
(set (attr "length")
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "general_operand" ""))
+ (match_operand:SI 1 "nonimmediate_operand" ""))
(set (match_dup 0)
(and:SI (match_dup 0)
(const_int 255)))]
(define_peephole2
[(set (match_operand 0 "register_operand" "")
- (match_operand 1 "general_operand" ""))
+ (match_operand 1 "nonimmediate_operand" ""))
(set (match_operand:SI 2 "register_operand" "")
(and:SI (match_dup 2)
(match_operand:SI 3 "const_int_qi_operand" "")))]