}
+/* Output subtraction of integer registers XOP[0] and XOP[2] and return ""
+
+ XOP[0] = XOP[0] - XOP[2]
+
+ where the mode of XOP[0] is in { HI, PSI, SI }, and the mode of
+ XOP[2] is in { QI, HI, PSI }. When the mode of XOP[0] is larger
+ than the mode of XOP[2], then the latter is zero-extended on the fly.
+ The number of instructions will be the mode size of XOP[0]. */
+
+const char *
+avr_out_minus (rtx *xop)
+{
+ int n_bytes0 = GET_MODE_SIZE (GET_MODE (xop[0]));
+ int n_bytes2 = GET_MODE_SIZE (GET_MODE (xop[2]));
+
+ output_asm_insn ("sub %0,%2", xop);
+
+ for (int i = 1; i < n_bytes0; ++i)
+ {
+ rtx op[2];
+ op[0] = all_regs_rtx[i + REGNO (xop[0])];
+ op[1] = (i < n_bytes2) ? all_regs_rtx[i + REGNO (xop[2])] : zero_reg_rtx;
+
+ output_asm_insn ("sbc %0,%1", op);
+ }
+
+ return "";
+}
+
+
/* Output addition of register XOP[0] and compile time constant XOP[2].
INSN is a single_set insn or an insn pattern.
CODE == PLUS: perform addition by using ADD instructions or
*total = COSTS_N_INSNS (2);
return true;
}
- // *sub<mode>3_zero_extend1
+ // *sub<HISI:mode>3.zero_extend.<QIPSI:mode>
if (REG_P (XEXP (x, 0))
&& GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
{
"sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
[(set_attr "length" "3")])
-(define_insn_and_split "*subpsi3_zero_extend.qi_split"
- [(set (match_operand:PSI 0 "register_operand" "=r")
- (minus:PSI (match_operand:SI 1 "register_operand" "0")
- (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
- ""
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 0)
- (minus:PSI (match_dup 1)
- (zero_extend:PSI (match_dup 2))))
- (clobber (reg:CC REG_CC))])])
-
-(define_insn "*subpsi3_zero_extend.qi"
- [(set (match_operand:PSI 0 "register_operand" "=r")
- (minus:PSI (match_operand:SI 1 "register_operand" "0")
- (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))
- (clobber (reg:CC REG_CC))]
- "reload_completed"
- "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
- [(set_attr "length" "3")])
-
-(define_insn_and_split "*subpsi3_zero_extend.hi_split"
- [(set (match_operand:PSI 0 "register_operand" "=r")
- (minus:PSI (match_operand:PSI 1 "register_operand" "0")
- (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
- ""
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 0)
- (minus:PSI (match_dup 1)
- (zero_extend:PSI (match_dup 2))))
- (clobber (reg:CC REG_CC))])])
-
-(define_insn "*subpsi3_zero_extend.hi"
- [(set (match_operand:PSI 0 "register_operand" "=r")
- (minus:PSI (match_operand:PSI 1 "register_operand" "0")
- (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))
- (clobber (reg:CC REG_CC))]
- "reload_completed"
- "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
- [(set_attr "length" "3")])
(define_insn_and_split "*subpsi3_sign_extend.hi_split"
[(set (match_operand:PSI 0 "register_operand" "=r")
}
[(set_attr "adjust_len" "plus")])
-(define_insn_and_split "*subhi3_zero_extend1_split"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (minus:HI (match_operand:HI 1 "register_operand" "0")
- (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
- ""
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 0)
- (minus:HI (match_dup 1)
- (zero_extend:HI (match_dup 2))))
- (clobber (reg:CC REG_CC))])])
-
-(define_insn "*subhi3_zero_extend1"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (minus:HI (match_operand:HI 1 "register_operand" "0")
- (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
- (clobber (reg:CC REG_CC))]
- "reload_completed"
- "sub %A0,%2\;sbc %B0,__zero_reg__"
- [(set_attr "length" "2")])
(define_insn_and_split "*subhi3.sign_extend2_split"
[(set (match_operand:HI 0 "register_operand" "=r")
}
[(set_attr "adjust_len" "plus")])
-(define_insn_and_split "*subsi3_zero_extend_split"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
- ""
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 0)
- (minus:SI (match_dup 1)
- (zero_extend:SI (match_dup 2))))
- (clobber (reg:CC REG_CC))])])
-(define_insn "*subsi3_zero_extend"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))
- (clobber (reg:CC REG_CC))]
- "reload_completed"
- "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
- [(set_attr "length" "4")
- ])
-
-(define_insn_and_split "*subsi3_zero_extend.hi_split"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
- ""
+;; "*subhi3.zero_extend.qi_split"
+;; "*subpsi3.zero_extend.qi_split" "*subpsi3.zero_extend.hi_split"
+;; "*subsi3.zero_extend.qi_split" "*subsi3.zero_extend.hi_split"
+;; "*subsi3.zero_extend.psi_split"
+(define_insn_and_split "*sub<HISI:mode>3.zero_extend.<QIPSI:mode>_split"
+ [(set (match_operand:HISI 0 "register_operand" "=r")
+ (minus:HISI (match_operand:HISI 1 "register_operand" "0")
+ (zero_extend:HISI (match_operand:QIPSI 2 "register_operand" "r"))))]
+ "GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)"
"#"
"&& reload_completed"
[(parallel [(set (match_dup 0)
- (minus:SI (match_dup 1)
- (zero_extend:SI (match_dup 2))))
+ (minus:HISI (match_dup 1)
+ (zero_extend:HISI (match_dup 2))))
(clobber (reg:CC REG_CC))])])
-(define_insn "*subsi3_zero_extend.hi"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))
+;; "*subhi3.zero_extend.qi"
+;; "*subpsi3.zero_extend.qi" "*subpsi3.zero_extend.hi"
+;; "*subsi3.zero_extend.qi" "*subsi3.zero_extend.hi"
+;; "*subsi3.zero_extend.psi"
+(define_insn "*sub<HISI:mode>3.zero_extend.<QIPSI:mode>"
+ [(set (match_operand:HISI 0 "register_operand" "=r")
+ (minus:HISI (match_operand:HISI 1 "register_operand" "0")
+ (zero_extend:HISI (match_operand:QIPSI 2 "register_operand" "r"))))
(clobber (reg:CC REG_CC))]
- "reload_completed"
- "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
- [(set_attr "length" "4")])
+ "reload_completed
+ && GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)"
+ {
+ return avr_out_minus (operands);
+ }
+ [(set_attr "length" "<HISI:SIZE>")])
+
;******************************************************************************
; mul