(define_mode_iterator P [(HI "Pmode == HImode") (SI "Pmode == SImode")])
(define_mode_iterator QHI [QI HI])
+
+(define_mode_iterator HSI [HI SI])
+
+(define_mode_iterator QHSI [QI HI SI])
+
+(define_mode_iterator QHSIF [QI HI SI SF])
+
+(define_code_iterator shifts [ashift ashiftrt lshiftrt])
\f
;; ----------------------------------------------------------------------
;; MOVE INSTRUCTIONS
[(set_attr "length_table" "mov_imm4,movb")
(set_attr "cc" "set_znv")])
-(define_expand "movqi"
- [(set (match_operand:QI 0 "general_operand_dst" "")
- (match_operand:QI 1 "general_operand_src" ""))]
+(define_expand "mov<mode>"
+ [(set (match_operand:QHSIF 0 "general_operand_dst" "")
+ (match_operand:QHSIF 1 "general_operand_src" ""))]
""
{
- /* One of the ops has to be in a register. */
- if (!TARGET_H8300SX && !h8300_move_ok (operands[0], operands[1]))
- operands[1] = copy_to_mode_reg (QImode, operands[1]);
+ enum machine_mode mode = <MODE>mode;
+ if (TARGET_H8300 && (mode == SImode || mode == SFmode))
+ {
+ /* The original H8/300 needs to split up 32 bit moves. */
+ if (h8300_expand_movsi (operands))
+ DONE;
+ }
+ else if (!TARGET_H8300SX)
+ {
+ /* Other H8 chips, except the H8/SX family can only handle a
+ single memory operand, which is checked by h8300_move_ok.
+
+ We could perhaps have h8300_move_ok handle the H8/SX better
+ and just remove the !TARGET_H8300SX conditional. */
+ if (!h8300_move_ok (operands[0], operands[1]))
+ operands[1] = copy_to_mode_reg (mode, operand1);
+ }
})
(define_insn "movstrictqi"
(set_attr "length" "2,2,*,*,*")
(set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
-(define_expand "movhi"
- [(set (match_operand:HI 0 "general_operand_dst" "")
- (match_operand:HI 1 "general_operand_src" ""))]
- ""
- {
- /* One of the ops has to be in a register. */
- if (!h8300_move_ok (operands[0], operands[1]))
- operands[1] = copy_to_mode_reg (HImode, operand1);
- })
-
(define_insn "movstricthi"
[(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
(match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]
;; movsi
-(define_expand "movsi"
- [(set (match_operand:SI 0 "general_operand_dst" "")
- (match_operand:SI 1 "general_operand_src" ""))]
- ""
- {
- if (TARGET_H8300)
- {
- if (h8300_expand_movsi (operands))
- DONE;
- }
- else if (!TARGET_H8300SX)
- {
- /* One of the ops has to be in a register. */
- if (!h8300_move_ok (operands[0], operands[1]))
- operands[1] = copy_to_mode_reg (SImode, operand1);
- }
- })
-
(define_insn "*movsi_h8300"
[(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
(match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]
(include "mova.md")
-(define_expand "movsf"
- [(set (match_operand:SF 0 "general_operand_dst" "")
- (match_operand:SF 1 "general_operand_src" ""))]
- ""
- {
- if (TARGET_H8300)
- {
- if (h8300_expand_movsi (operands))
- DONE;
- }
- else if (!TARGET_H8300SX)
- {
- /* One of the ops has to be in a register. */
- if (!register_operand (operand1, SFmode)
- && !register_operand (operand0, SFmode))
- {
- operands[1] = copy_to_mode_reg (SFmode, operand1);
- }
- }
- })
-
(define_insn "*movsf_h8300"
[(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
(match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))]
;; ADD INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_expand "addqi3"
- [(set (match_operand:QI 0 "register_operand" "")
- (plus:QI (match_operand:QI 1 "register_operand" "")
- (match_operand:QI 2 "h8300_src_operand" "")))]
+(define_expand "add<mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (plus:QHSI (match_operand:QHSI 1 "register_operand" "")
+ (match_operand:QHSI 2 "h8300_src_operand" "")))]
""
"")
[(set_attr "length_table" "addb")
(set_attr "cc" "set_zn")])
-(define_expand "addhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (plus:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "h8300_src_operand" "")))]
- ""
- "")
-
(define_insn "*addhi3_h8300"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
DONE;
})
-(define_expand "addsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "h8300_src_operand" "")))]
- ""
- "")
(define_insn "*addsi_h8300"
[(set (match_operand:SI 0 "register_operand" "=r,r")
;; SUBTRACT INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_expand "subqi3"
- [(set (match_operand:QI 0 "register_operand" "")
- (minus:QI (match_operand:QI 1 "register_operand" "")
- (match_operand:QI 2 "h8300_src_operand" "")))]
+(define_expand "sub<mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (minus:QHSI (match_operand:QHSI 1 "register_operand" "")
+ (match_operand:QHSI 2 "h8300_src_operand" "")))]
""
- "")
+ {
+ if (TARGET_H8300 && <MODE>mode == SImode)
+ operands[2] = force_reg (SImode, operands[2]);
+ })
(define_insn "*subqi3"
[(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
[(set_attr "length_table" "addb")
(set_attr "cc" "set_zn")])
-(define_expand "subhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (minus:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "h8300_src_operand" "")))]
- ""
- "")
-
(define_insn "*subhi3_h8300"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(minus:HI (match_operand:HI 1 "register_operand" "0,0")
[(set_attr "length_table" "addw")
(set_attr "cc" "set_zn")])
-(define_expand "subsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (minus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "h8300_src_operand" "")))]
- ""
- {
- if (TARGET_H8300)
- operands[2] = force_reg (SImode, operands[2]);
- })
-
(define_insn "*subsi3_h8300"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "register_operand" "0")
[(set_attr "length" "2,8")
(set_attr "cc" "none_0hit,set_znv")])
-(define_expand "andqi3"
- [(set (match_operand:QI 0 "register_operand" "")
- (and:QI (match_operand:QI 1 "register_operand" "")
- (match_operand:QI 2 "h8300_src_operand" "")))]
- ""
- "")
-
-(define_expand "andhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (and:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "h8300_src_operand" "")))]
+(define_expand "and<mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (and:QHSI (match_operand:QHSI 1 "register_operand" "")
+ (match_operand:QHSI 2 "h8300_src_operand" "")))]
""
"")
"or.b\\t%w2,%x0"
[(set_attr "length" "2")])
-(define_expand "andsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (and:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "h8300_src_operand" "")))]
- ""
- "")
-
;; ----------------------------------------------------------------------
;; OR INSTRUCTIONS
;; ----------------------------------------------------------------------
(set_attr "length_table" "*,logicb")
(set_attr "cc" "none_0hit,set_znv")])
-
-(define_expand "iorqi3"
- [(set (match_operand:QI 0 "register_operand" "")
- (ior:QI (match_operand:QI 1 "register_operand" "")
- (match_operand:QI 2 "h8300_src_operand" "")))]
- ""
- "")
-
-(define_expand "iorhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (ior:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "h8300_src_operand" "")))]
- ""
- "")
-
-(define_expand "iorsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (ior:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "h8300_src_operand" "")))]
+(define_expand "ior<mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (ior:QHSI (match_operand:QHSI 1 "register_operand" "")
+ (match_operand:QHSI 2 "h8300_src_operand" "")))]
""
"")
(set_attr "length_table" "*,logicb")
(set_attr "cc" "none_0hit,set_znv")])
-(define_expand "xorqi3"
- [(set (match_operand:QI 0 "register_operand" "")
- (xor:QI (match_operand:QI 1 "register_operand" "")
- (match_operand:QI 2 "h8300_src_operand" "")))]
- ""
- "")
-
-(define_expand "xorhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (xor:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:HI 2 "h8300_src_operand" "")))]
- ""
- "")
-
-(define_expand "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (xor:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "h8300_src_operand" "")))]
+(define_expand "xor<mode>3"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (xor:QHSI (match_operand:QHSI 1 "register_operand" "")
+ (match_operand:QHSI 2 "h8300_src_operand" "")))]
""
"")
;; of high/low instructions, so we can accept literal addresses, that
;; have to be loaded into a register on H8300.
-(define_insn "*logicalhi3_sn"
- [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
- (match_operator:HI 3 "bit_operator"
- [(match_operand:HI 1 "h8300_dst_operand" "%0")
- (match_operand:HI 2 "h8300_src_operand" "rQi")]))]
- "(TARGET_H8300S || TARGET_H8300H) && h8300_operands_match_p (operands)"
-{
- return output_logical_op (HImode, operands);
-}
- [(set (attr "length")
- (symbol_ref "compute_logical_op_length (HImode, operands)"))
- (set (attr "cc")
- (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
-
-(define_insn "*logicalsi3_sn"
- [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
- (match_operator:SI 3 "bit_operator"
- [(match_operand:SI 1 "h8300_dst_operand" "%0")
- (match_operand:SI 2 "h8300_src_operand" "rQi")]))]
+(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 (SImode, operands);
+ return output_logical_op (<MODE>mode, operands);
}
[(set (attr "length")
- (symbol_ref "compute_logical_op_length (SImode, operands)"))
+ (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
(set (attr "cc")
- (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
+ (symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
-(define_insn "*logicalhi3"
- [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
- (match_operator:HI 3 "bit_operator"
- [(match_operand:HI 1 "h8300_dst_operand" "%0")
- (match_operand:HI 2 "h8300_src_operand" "rQi")]))]
+(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 (HImode, operands);
+ return output_logical_op (<MODE>mode, operands);
}
[(set (attr "length")
- (symbol_ref "compute_logical_op_length (HImode, operands)"))
+ (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
(set (attr "cc")
- (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
-
-(define_insn "*logicalsi3"
- [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
- (match_operator:SI 3 "bit_operator"
- [(match_operand:SI 1 "h8300_dst_operand" "%0")
- (match_operand:SI 2 "h8300_src_operand" "rQi")]))]
- "h8300_operands_match_p (operands)"
-{
- return output_logical_op (SImode, operands);
-}
- [(set (attr "length")
- (symbol_ref "compute_logical_op_length (SImode, operands)"))
- (set (attr "cc")
- (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
+ (symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
\f
;; ----------------------------------------------------------------------
;; NEGATION INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_expand "negqi2"
- [(set (match_operand:QI 0 "register_operand" "")
- (neg:QI (match_operand:QI 1 "register_operand" "")))]
+(define_expand "neg<mode>2"
+ [(set (match_operand:QHSIF 0 "register_operand" "")
+ (neg:QHSIF (match_operand:QHSIF 1 "register_operand" "")))]
""
- "")
+ {
+ enum machine_mode mode = <MODE>mode;
+ if (TARGET_H8300)
+ {
+ if (mode == QImode || mode == SFmode)
+ ;
+ else if (mode == HImode)
+ {
+ emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
+ DONE;
+ }
+ else if (mode == SImode)
+ {
+ emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
+ DONE;
+ }
+ }
+ })
(define_insn "*negqi2"
[(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
[(set_attr "length_table" "unary")
(set_attr "cc" "set_zn")])
-(define_expand "neghi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (neg:HI (match_operand:HI 1 "register_operand" "")))]
- ""
- {
- if (TARGET_H8300)
- {
- emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
- DONE;
- }
- })
-
-(define_expand "neghi2_h8300"
+(define_expand "neg<mode>2_h8300"
[(set (match_dup 2)
- (not:HI (match_operand:HI 1 "register_operand" "")))
- (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
- (set (match_operand:HI 0 "register_operand" "")
+ (not:HSI (match_operand:HSI 1 "register_operand" "")))
+ (set (match_dup 2) (plus:HSI (match_dup 2) (const_int 1)))
+ (set (match_operand:HSI 0 "register_operand" "")
(match_dup 2))]
""
{
- operands[2] = gen_reg_rtx (HImode);
+ operands[2] = gen_reg_rtx (<MODE>mode);
})
(define_insn "*neghi2_h8300hs"
[(set_attr "length_table" "unary")
(set_attr "cc" "set_zn")])
-(define_expand "negsi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (neg:SI (match_operand:SI 1 "register_operand" "")))]
- ""
- {
- if (TARGET_H8300)
- {
- emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
- DONE;
- }
- })
-
-(define_expand "negsi2_h8300"
- [(set (match_dup 2)
- (not:SI (match_operand:SI 1 "register_operand" "")))
- (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
- (set (match_operand:SI 0 "register_operand" "")
- (match_dup 2))]
- ""
- {
- operands[2] = gen_reg_rtx (SImode);
- })
-
(define_insn "*negsi2_h8300hs"
[(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
(neg:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
[(set_attr "length_table" "unary")
(set_attr "cc" "set_zn")])
-(define_expand "negsf2"
- [(set (match_operand:SF 0 "register_operand" "")
- (neg:SF (match_operand:SF 1 "register_operand" "")))]
- ""
- "")
-
(define_insn "*negsf2_h8300"
[(set (match_operand:SF 0 "register_operand" "=r")
(neg:SF (match_operand:SF 1 "register_operand" "0")))]
;; NOT INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_expand "one_cmplqi2"
- [(set (match_operand:QI 0 "register_operand" "")
- (not:QI (match_operand:QI 1 "register_operand" "")))]
+(define_expand "one_cmpl<mode>2"
+ [(set (match_operand:QHSI 0 "register_operand" "")
+ (not:QHSI (match_operand:QHSI 1 "register_operand" "")))]
""
"")
[(set_attr "length_table" "unary")
(set_attr "cc" "set_znv")])
-(define_expand "one_cmplhi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (not:HI (match_operand:HI 1 "register_operand" "")))]
- ""
- "")
-
(define_insn "*one_cmplhi2_h8300"
[(set (match_operand:HI 0 "register_operand" "=r")
(not:HI (match_operand:HI 1 "register_operand" "0")))]
[(set_attr "cc" "set_znv")
(set_attr "length_table" "unary")])
-(define_expand "one_cmplsi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (not:SI (match_operand:SI 1 "register_operand" "")))]
- ""
- "")
-
(define_insn "*one_cmplsi2_h8300"
[(set (match_operand:SI 0 "register_operand" "=r")
(not:SI (match_operand:SI 1 "register_operand" "0")))]
;; EXTEND INSTRUCTIONS
;; ----------------------------------------------------------------------
-(define_expand "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
+(define_expand "zero_extendqi<mode>2"
+ [(set (match_operand:HSI 0 "register_operand" "")
+ (zero_extend:HSI (match_operand:QI 1 "general_operand_src" "")))]
""
- "")
+ {
+ if (TARGET_H8300SX)
+ operands[1] = force_reg (QImode, operands[1]);
+ })
(define_insn "*zero_extendqihi2_h8300"
[(set (match_operand:HI 0 "register_operand" "=r,r")
operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
})
-(define_expand "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
- ""
- {
- if (TARGET_H8300SX)
- operands[1] = force_reg (QImode, operands[1]);
- })
(define_insn "*zero_extendqisi2_h8300"
[(set (match_operand:SI 0 "register_operand" "=r,r")
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
-(define_expand "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
+(define_expand "extendqi<mode>2"
+ [(set (match_operand:HSI 0 "register_operand" "")
+ (sign_extend:HSI (match_operand:QI 1 "register_operand" "")))]
""
"")
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
-(define_expand "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
- ""
- "")
-
(define_insn "*extendqisi2_h8300"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
;; ROTATIONS
;; ----------------------------------------------------------------------
-(define_expand "rotlqi3"
- [(set (match_operand:QI 0 "register_operand" "")
- (rotate:QI (match_operand:QI 1 "register_operand" "")
- (match_operand:QI 2 "nonmemory_operand" "")))]
+(define_expand "rotl<mode>3"
+ [(set (match_operand:QHI 0 "register_operand" "")
+ (rotate:QHI (match_operand:QHI 1 "register_operand" "")
+ (match_operand:QI 2 "nonmemory_operand" "")))]
""
{
if (expand_a_rotate (operands))
DONE;
})
-(define_insn "rotlqi3_1"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (rotate:QI (match_operand:QI 1 "register_operand" "0")
- (match_operand:QI 2 "immediate_operand" "")))]
- ""
-{
- return output_a_rotate (ROTATE, operands);
-}
- [(set (attr "length")
- (symbol_ref "compute_a_rotate_length (operands)"))])
-
-(define_expand "rotlhi3"
- [(set (match_operand:HI 0 "register_operand" "")
- (rotate:HI (match_operand:HI 1 "register_operand" "")
- (match_operand:QI 2 "nonmemory_operand" "")))]
- ""
- {
- if (expand_a_rotate (operands))
- DONE;
- })
-
-(define_insn "rotlhi3_1"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (rotate:HI (match_operand:HI 1 "register_operand" "0")
- (match_operand:QI 2 "immediate_operand" "")))]
+(define_insn "rotl<mode>3_1"
+ [(set (match_operand:QHI 0 "register_operand" "=r")
+ (rotate:QHI (match_operand:QHI 1 "register_operand" "0")
+ (match_operand:QI 2 "immediate_operand" "")))]
""
{
return output_a_rotate (ROTATE, operands);